System Compleat.

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 로 뽑는 툴을 만들어야 하니.. ㅋ


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