System Compleat.

'YZCerberos'에 해당되는 글 231건

  1. postgresql 이야기.. 2
  2. Y.Z. 의 블로그를 오픈했어요.
  3. 허어.. 에어프랑스에서 항공권 행사..
  4. postgresql 이야기.
  5. 남해 일출 2

postgresql 이야기.. 2

Techs

주로 장애처리를 하다 보니까 글 내용도 그쪽으로 많이 치중되는것 같다.

일단 오늘은

/home/postgresql/bin/pg_dump -Uec_user -f bienworks.sql -n bienworks mall -p5432
pg_dump: schema with OID 5231294 does not exist

이따위 경우에 대해 당해 본적 있는가 해서 끄적거린다.

좀 뒤벼 보자면

=# select oid, * from pg_namespace where oid='5231294';
oid | nspname | nspowner | nspacl
-----+---------+----------+--------
(0 rows)

읍다.  써글..

=# select oid, * from pg_namespace where nspname='bienworks';
oid | nspname | nspowner | nspacl
---------+--------------+----------+--------
1489275   | bienworks   | 16384 |

근데 얜 있다..


이거이 어찌된 일인고..   bienworks 스키마의 테이블 또는 인덱스 또는 role 또는 type 또는 관련 pg_toast
등에 대한 oid가 분실되어 덤프받을 수 없음을 의미 한다.

문제는 이게 pg_catalog 의 index가 쫑나서 발생하는 경우가 상당히 빈번하다는 것.

득단의 조치를 내리게 된다 ㅡㅡ;;

reindexdb -U user -d database -p 9999 -s 

리인덱싱이 끝나고도 고대로 덤프 안되고 나를 약올려 버리는 써글 pg_dump.

찾아야 한다.  pg_dump 가 참조하는 이 써글놈의 oid가 어디서 읽혀지는지.



oid를 찾기 위해 삽질고투중.

select typname,typnamespace from pg_type where typnamespace=5231294;
        typname         | typnamespace
------------------------+--------------
 member_group           |      5231294
 category_access_group  |      5231294
 member                 |      5231294
 member_addr_seq        |      5231294
 member_addr            |      5231294
 regist_config          |      5231294
 mileage_access_log_seq |      5231294
 mileage_access_log     |      5231294
(8 rows)


# select relname,relnamespace from pg_class where relnamespace=5231294;
           relname            | relnamespace
------------------------------+--------------
 member_group_pk              |      5231294
 member_group                 |      5231294
 category_access_group_pk     |      5231294
 category_access_group        |      5231294
 category_access_group_index1 |      5231294
 member_pk                    |      5231294
 member                       |      5231294
 member_ssn_key               |      5231294
 member_index1                |      5231294
 member_index2                |      5231294
 member_index3                |      5231294
 member_addr_seq              |      5231294
 member_addr_pk               |      5231294
 member_addr                  |      5231294
 member_addr_index1           |      5231294
 regist_config                |      5231294
 mileage_access_log_seq       |      5231294
 mileage_access_log_pk        |      5231294
 mileage_access_log           |      5231294
(19 rows)



=# select conname, connamespace from pg_constraint where connamespace=5231294;
         conname          | connamespace
--------------------------+--------------
 member_group_pk          |      5231294
 category_access_group_pk |      5231294
 member_pk                |      5231294
 member_ssn_key           |      5231294
 member_addr_pk           |      5231294
 mileage_access_log_pk    |      5231294
(6 rows)


몇군데서 찾아 내었다 써글놈

모두 delete 조치 후 다시 dump 시도.
아, 물론 서비스 서버에서 한건 아니다.  당연히 온라인 백업으로 wal 복구 한 서버에서 작업.

Grrrrrrrrrrr...  안된다.

어디가 잘 못된 것일까...

모든 스키마에서 참조하는 oid라..

생각보다 답이 간단할거 같은데 커피에 취한 내머리는 굴러갈 생각을 않는다.... 써글


일단 노가다. ㅡㅡ;;
해당 DB 전부 reindex 중..  물론!!  테스트 서버에서. ㅡ0ㅡ;

------------------------------------------------------------


8시간 후...

reindex 는 엄했다. ㅡㅡ;;  역시 catalog가 꼬인게야...

그토록 수많은 삽질 끝에...

dump 중 나오는 oid 를  pg_type, pg_class, pg_constraint 이 세개의 테이블에서 지워준다.
일단 덤프는 된다 ㅡㅡ;;


delete  from pg_type where typnamespace=5274363;
delete  from pg_class where relnamespace=5274363;
delete  from pg_constraint where connamespace=5274363;

pg_conversion
pg_opclass
pg_operator
pg_proc

5234792
5276285
5261129
5268899
5274363


요점은, pg_namespace 에  해당 스키마가 없는데, pg_type 에 올라가 있는 oid는 delete 해준다..
또는 그 반대의 경우도 마찬가지. 라고 보면 된다.


역으로 pg_dump.c 의 소스를 쫒아 가는 방법도 있겠지.


/* subquery used to convert user ID (eg, datdba) to user name */
static const char *username_subquery;

findNamespace(Oid nsoid, Oid objoid)
{
        int                     i;
        if (g_fout->remoteVersion >= 70300)
        {
                for (i = 0; i < g_numNamespaces; i++)
                {
                        NamespaceInfo *nsinfo = &g_namespaces[i];

                        if (nsoid == nsinfo->dobj.catId.oid)
                                return nsinfo;
                }
                write_msg(NULL, "schema with OID %u does not exist\n", nsoid);
                exit_nicely();
       
       
       
       
"SELECT tableoid, oid, nspname, "
                                          "(%s nspowner) as rolname, "
                                          "nspacl FROM pg_namespace",
                                          username_subquery);
                                         
Binary file ./pg_dump matches
./pg_dump.c:static const char *username_subquery;
./pg_dump.c:            username_subquery = "SELECT rolname FROM pg_catalog.pg_roles WHERE oid =";
./pg_dump.c:            username_subquery = "SELECT usename FROM pg_catalog.pg_user WHERE usesysid =";
./pg_dump.c:            username_subquery = "SELECT usename FROM pg_user WHERE usesysid =";                                         


잘 찾아 보시게나 들..  오늘은 이만 하고  내일은 SELECT 로 뽑는 툴을 만들어야 하니.. ㅋ


눈 멋지게 오는데 이게 무슨짓이람 ㅋ



Y.Z. 의 블로그를 오픈했어요.

News
사용자 삽입 이미지

시스템에 대한 이야기,
여행에 대한 이야기,
사진에 대한 이야기,


그리고 하는 일, 했던일에 대한 이야기

제일 중요한 사람 사귀는 이야기.


색안경 없이 옳다고 생각하는 관념을 가지고
두서 없이 끄적 거려 보고 싶어

기술 백서라고 하기엔 너무 조악하며
일기장이라기엔 너무 공개적이고
여행기나 수필이라기엔 너무 조리없는

그런 글과 그림마당.

허어.. 에어프랑스에서 항공권 행사..

Stories
사용자 삽입 이미지


무심코 MSN 하단부에 뜨는 광고글을 봤는데  "유럽 70만원 부터 - 에어프랑스 " 
개눈엔 X만 보인다고...  클릭해 버렸다.

꼭 가야 손해를 무지하게 안볼것 같다는 생각이 드는건 나 뿐인걸까.

postgresql 이야기.

Techs
postgresql -  http://www.postgresql.org

오픈소스 진영의 막강한 RDBMS.

항상 막강한 말이 붙는 소프트 웨어를 웹질을 하면서 많이 만나게 된다.
회사를 옮기고 생소하게 접했던 pgsql.

약 일년여간 다루어 오면서 느낀건 정말 손 많이 가는 데이터베이스라는거다.
회사 사용목적의 특성상 스키마를 잘근잘근 쪼개서 보통 900여개, 많으면 1800여개 까지 만들어대는데
한개의 DB에 특정 tablespace 지정없이 이런식으로 개념없이 계속 스키마를 생성하다 보면
디렉토리 하나에 파일이 70만개.

일단 파일시스템 성능에도 문제가 있고..  data 디렉토리를 왕창 압축해서 한 파일에 몰아 넣는건 별 문제가
되진 않지만 이걸 다시 풀어 버리는데는.... 끔찍했다.

실례로 16시간동안 압축이 해제 되는걸 보고만 있어야 했다는.  주말이었다.

실제 서비스 하는 서버의 사정상 각 스키마별로 tablespace를 재지정 한다는건 개발팀이나 시스템에서도
난색을 표하는( 한차례 schema별 덤프를 받아야 했는데 이건 이틀짜리다 ) 일이어서 결국
파일 시스템 레벨에서 해결을 하기로 했다.

답은...

tune2fs /dev/sdxN -O dir_index

일단 data디렉토리를 백업, archive를 압축 해 두고 나서 파일 제대로 있는지 꼭 확인 한 후에
위의 옵션을 ext3 에 추가 해 주고
시스템을 리붓 하던가 아니면 언마운트 하고 fsck 를 돌려버린다.

아, 물론 새로운 디스크에 해당 옵션을 걸고 미러링을 하는것이 더 안정성 높은 좋은 방법이다.

물론 한 디렉토리 안에 무지막지한 파일 갯수의 문제는 남아있게 되지만...
뭐, 어쩌겠는가  디비 구조 변경 당장 못하겠다는데..

사용중 하나의 스키마에만 문제가 발생해도 복구할때는 전체 압축파일을 다 풀어버려야 한다.
이건 정말 고역이어서..  WAL 백업 프로세스에 들어가게 되면.. dir_index 가 걸려있지 않은 상황에서는
해당 wal 백업과 online 백업 전체를 옮겨서 준비가 된 서버에서 작업을 해주어야 하는..
dir_index 도 좋지만 보다 좋은 성능을 내는건... 훗훗
보시라.

일단 메모리가 32기가 정도 되는 서버를 준비해서
data 디렉토리 사이즈만큼 크기를 할당하고 ( dd if=/dev/zero of=/dev/ram0 bs=1k count=니맘대로 )
파일 시스템을 생성 ( mkreiserfs -f /dev/ram0 ) 하고
loopback으로 마운트 한 다음에 ( mount -t reiserfs -o loop  /dev/ram0  니맘대로 )
여기다가 online 백업을 풀어버리는거다.

12기가의 파일 50만개 정도를 8분에 풀어버렸다. ( 듀얼코어 옵테론 270 X 4 , sata 디스크 )
여기서 덤프는 그다지 빠르진 않지만, 기타 다른 seq scan 이나 sort 등  tmp table 생성이 요구되는
여러가지 작업에서 db 성능은 매우 비약적으로 향상된다.

하지만 돈 많이 든다는거...


또 하나의 문제가 있는데.

어디, 스키마를 만들어 내기만 하는게 아니다.
지우기도 하지 않는가?

여기서 MVCC 의 문제가 발생해 버린다.

postgresql 의 pg_catalog 하위 테이블중 pg_class 및 관련 attribute 등의 해당 db system catalog 들에
문제가 발생한다.  일례로 pg_class 테이블 및 인덱스 파일 사이즈가 1기가가 넘어버리는 사태가 발생하기도
했지만... 
역시 디비 구조 변경은 당분간 불가 합니다 라는 말이므로 어쩌겠는가...
data 디렉토리 크기는 날이 갈 수록 커지지.. 스키마 추가, 삭제의 반복.. 그리고 각 스키마 별로 들어있는
엉망 구조의 게시판 테이블 구조...

vacuumdb -az, reindex -S  등을 열심히 돌려주었다.  가끔 대규모 drop 이나 대규모 insert 가 발생한 경우엔
vacuumdb -azf .

백업에 대해 문제가 발생할 소지도 있어서 참 난감 했다.
vacuum 전 백업, vacuum -avz 로 로그를 뽑아 내어 행여나 잘못된 테이블이나 인덱스때문에 vacuum 이 죽어버
리게 되면..

아무튼... 이런 저런 문제 끝에 지금은 여러가지 절차적, 구조적 수정을 감행하여 실제 서비스에 큰 무리 없도록
하고 있긴 하지만...  언제 터질지 모르는 폭탄같아 좀 무섭긴 하다.



남해 일출

Hobbies

사용자 삽입 이미지

남해 환상의커플 촬영지



 너무 피곤했어..  하지만 그만큼의 가치가 있었던 곳.