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_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 로 뽑는 툴을 만들어야 하니.. ㅋ
눈 멋지게 오는데 이게 무슨짓이람 ㅋ