PostgreSQL의 매개 변수 zero 이해하기damaged_pages

이 BLOG를 쓰는 것은 우리의 가상 테스트기에서 이상이 생겼기 때문에 다음과 같은 오류 정보를 보고한 것이다.
invalid page header in block 59640 of relation base/175812/1077620; zeroing out page.
보시다시피 PostgreSQL의 숨겨진 시스템 매개 변수,zerodamaged_페이지, 공식 문서에 이렇게 설명되어 있습니다.
zero_damaged_pages (boolean)
Detection of a damaged page header normally causes PostgreSQL to report an error, aborting the current transaction. Setting zero_damaged_pages to on causes the system to instead report a warning, zero out the damaged page in memory, and continue processing. This behavior will destroy data, namely all the rows on the damaged page. However, it does allow you to get past the error and retrieve rows from any undamaged pages that might be present in the table. It is useful for recovering data if corruption has occurred due to a hardware or software error. You should generally not set this on until you have given up hope of recovering data from the damaged pages of a table. Zeroed-out pages are not forced to disk so it is recommended to recreate the table or the index before turning this parameter off again. The default setting is off, and it can only be changed by a superuser.

이 매개 변수는 시스템이 디스크 페이지의 손상을 감지하면postgresql 데이터가 현재 업무를 취소하고 오류 보고 정보를 제출한다는 뜻입니다.이 매개 변수는 bool 형식입니다. 기본값은off입니다. 시스템이 디스크, 메모리 등 하드웨어로 인한 문제에 부딪히면 이런 오류 알림을 줍니다. 우리가 on으로 설정하면 오류 보고서를 무시하고 손상된 데이터를 지울 수 있습니다. 영향을 받지 않은 데이터는 정상입니다.
이 매개 변수는 손상된 데이터를 지우는 심각한 단점이 있다. 좋은 점도 있다. 오류 정보를 무시하고 스캔할 때 오류 블록을 뛰어넘어 데이터베이스를 정상적으로 사용할 수 있도록 하는 것이다.따라서 데이터의 완전성을 고려하기 위해 이 파라미터를 켜는 것을 권장하지 않습니다. 데이터베이스가 정말 열리지 않고 다운될 때만 데이터베이스를 복구할 희망이 없을 때 이 파라미터를 사용하십시오.우리는 빅데이터를 회수할 때 다음과 같은 고장이 발생했다.
----         

test_db=# select lo_unlink(oid) from pg_largeobject_metadata where lomowner = 17305 limit 20000;
ERROR:  invalid page header in block 45736 of relation base/175812/1077620
----         pg_dump,pg_dumpall              ,     vacuum full     

test_db=# vacuum full analyze verbose pg_largeobject;
INFO:  vacuuming "pg_catalog.pg_largeobject"
ERROR:  invalid page header in block 45736 of relation base/175812/1077620

이 대형 대상 데이터는 일부 테스트 단일 로그인 정보, 비사용자 정보를 보존하고 있기 때문에 정리할 수 있다. 생산에 있어서 백업을 하고 관련 파일을 복사해야 한다. 이번 처리는 다음과 같다.
4
test_db=# show zero_damaged_pages ;
zero_damaged_pages
--------------------
off
(1 row)
test_db=# SET zero_damaged_pages = on;
SET
test_db=# show zero_damaged_pages ;
zero_damaged_pages 
--------------------
on
(1 row) 

test_db=# vacuum full analyze verbose pg_largeobject;
WARNING:  invalid page header in block 59640 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59641 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59642 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59643 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59644 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59645 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59646 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59647 of relation base/175812/1077620; zeroing out page
...........
WARNING:  invalid page header in block 59703 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59703 of relation base/175812/1077620; zeroing out page
WARNING:  invalid page header in block 59704 of relation base/175812/1077620; zeroing out page
INFO:  "pg_largeobject": found 2 removable, 3650 nonremovable row versions in 59711 pages
DETAIL:  0 dead row versions cannot be removed yet.CPU 0.45s/0.28u sec elapsed 7.22 sec.
INFO:  analyzing "pg_catalog.pg_largeobject"
INFO:  "pg_largeobject": scanned 205 of 205 pages, containing 3650 live rows and 0 dead rows; 3650 rows in sample, 3650 estimated total rows
VACUUM
이로써 데이터베이스는 일시적으로 복구되었다. 그러나 이것은 임시적인 것이다. 만약에 디스크 파일 시스템이 고장나면 머지않아 이 문제가 재현될 것이다. 나중에 다시 복구하자.
4
1.reboot       
2.umount          
3.fsck -v -t -p /dev/sda1
4.reboot
한동안 복구한 후에 잠시 이 오류를 만나지 않았습니다.
관련 소스 코드 파일은 src/backend/storage/buffer/bufmgr에 있습니다.c,src/backend/storage/smgr/smgr.c 그중에 관건적인 부분이 있는데 논리적으로 보면 매우 상쾌하다
 /* check for garbage data */                        if (!PageIsVerified((Page) bufBlock, blockNum))                         {                                 if (mode == RBM_ZERO_ON_ERROR || zero_damaged_pages)                                 {                                         ereport(WARNING,                                                         (errcode(ERRCODE_DATA_CORRUPTED),                                                          errmsg("invalid page in block %u of relation %s; zeroing out page",                                                                         blockNum,                                                                         relpath(smgr->smgr_rnode, forkNum))));                                         MemSet((char *) bufBlock, 0, BLCKSZ);                                 }                                 else                                         ereport(ERROR,                                                         (errcode(ERRCODE_DATA_CORRUPTED),                                                          errmsg("invalid page in block %u of relation %s",                                                                         blockNum,                                                                         relpath(smgr->smgr_rnode, forkNum))));                         }

좋은 웹페이지 즐겨찾기