web-dev-qa-db-ja.com

PostgreSQLベース+ WALバックアップが正しく復元されたことを確認する方法

同僚は、バージョン9.1のホットスタンバイで作成されたバックアップからPostgreSQLデータベースコピーを抽出しようとしましたが、信頼性がありませんでした。毎日実行していましたが、通常、コピーに対してクエリを実行しているときにさまざまなエラーが発生しました。

悲しいことに、私はなぜウェブ上にあるのかについて明確な答えを見つけることができず、PostgreSQL IRCチャネルで親切に心を動かしました-そのようなバックアップを取るそのバージョンでは、スタンバイはそのままではサポートされていません。

したがって、同じ問題に遭遇してそれをグーグルしようとする他の人のために、私は以下の回答にメモを書きます。

4
Josip Rodin

答えには2つのセクションが含まれます。1つ目は、復元後にログで確認できるもの、2つ目は、そうでないもののいくつかの例です。最初のセクションはかなり確定的である必要がありますが、2番目のセクションは基本的に、問題が発生したことを示す、何が起こったかをランダムに組み合わせたものです。

許容できるログ出力

開始時:

_2015-07-23 06:51:24 UTC LOG: database system was interrupted; last known up at 2015-07-23 02:10:42 UTC
_

復元するPostgreSQLがいつ最後に起動したかを知っていることを確認することが重要です。チェックポイントから始まるということなので、そうだと思います。

xlog最小リカバリ要求...は現在のポイントを過ぎています

最初に、これらのいくつかが発生する可能性があります:

_2015-07-23 06:51:30 UTC WARNING:  xlog min recovery request 1027/B0A28D98 is past current point 1027/2BE36DA8
2015-07-23 06:51:30 UTC CONTEXT:  writing block 0 of relation base/117264/9551898_vm
       xlog redo insert: rel 1663/117264/8310261; tid 68622/40
_

しかし http://www.postgresql.org/message-id/CAB7nPqTd43hqpuC+M8fo+xkqHv1WtFe_16NUttu1pHcBtZhZmw@mail.gmail.com によると、これは無害です

致命的:データベースシステムが起動しています

これらはいくつでも発生する可能性があります。

_2015-07-23 06:51:24 UTC FATAL:  the database system is starting up
_

私たちの場合、スクリプトがPostgreSQLの準備ができていることを確認するために実行する自動化された_SELECT 1_ pingのようなクエリの結果であったため、これは実際には無害です。

予期しないpageaddr ...ログファイル...、セグメント...、オフセット...

最後に、これがあります:

_2015-07-23 06:52:21 UTC LOG:  restored log file "0000000100001027000000B2" from archive
2015-07-23 06:52:21 UTC LOG:  consistent recovery state reached at 1027/B2F8F2F8
sh: 1: cannot open ../../../wal_backup/0000000100001027000000B3: No such file
2015-07-23 06:52:21 UTC LOG:  unexpected pageaddr 1027/AA000000 in log file 4135, segment 179, offset 0
2015-07-23 06:52:21 UTC LOG:  redo done at 1027/B2F8F2F8
2015-07-23 06:52:21 UTC LOG:  last completed transaction was at log time 2015-07-23 02:17:33.842307+00
_

しかし http://www.postgresql.org/message-id/CAGrpgQ-BbXUNErrAtToYhRyUef9_GdUQz1T3CXbpTMLTnuKANQ@mail.gmail.com によると、これも無害です

それ以降は、WALの復元がさらに増える可能性があることに注意してください。

_2015-07-23 06:52:21 UTC LOG:  restored log file "0000000100001027000000B2" from archive
_

これは単に、_recovery.conf_経由で必要以上に多くのWALファイルを提供したことを意味します。

00000002.history:そのようなファイルはありません

WALの展開プロセスの最後には、次のようなものがあります。

_sh: 1: cannot open ../../../wal_backup/00000002.history: No such file
2015-07-23 06:52:21 UTC LOG:  selected new timeline ID: 2
sh: 1: cannot open ../../../wal_backup/00000001.history: No such file
2015-07-23 06:52:21 UTC LOG:  archive recovery complete
_

復元されたデータベース(クローン)が新しい人生(タイムライン)を開始する場所であるため、これは明らかに/うまくいけば無関係です。

許容できないログ出力

開始時:

_2015-07-20 12:38:31 UTC LOG: database system was interrupted while in recovery at log time 2015-07-20 01:41:22 UTC
_

これは重要です-pg_start_backup(...)チェックポイントの後で、バックアッププロセスが適切なタイミングで開始されなかったことを意味します。むしろ、データベースは正常に機能していて、ランダムなポイントにありました。つまり、この復元はクラッシュしたデータベースの復元に似ています。

pg_toastにチャンクがありません...

これは、復元が正しくなかったことを示します。簡単な修正として、 http://postgresql.nabble.com/select-table-indicate-missing-chunk-number-0-for-toast-value-96635-in-pg- toast-2619-td5682176.html

_mydb=# vacuum analyze mytable; -- trigger the error to see the problem toast
ERROR:  missing chunk number 0 for toast value 13044178 in pg_toast_2619
mydb=# reindex table pg_toast.pg_toast_2619;
REINDEX
_

これにより、テーブルが正常な状態に戻ることもありますが、その効果がない場合もあります。その後、もう少し調べてみたところ、使い捨てのpg_statisticだけだと思いました。

_mydb=# reindex table pg_statistic;
ERROR:  could not create unique index "pg_statistic_relid_att_inh_index"
DETAIL:  Key (starelid, staattnum, stainherit)=(884792, 34, f) is duplicated.
mydb=# delete from pg_statistic;
DELETE 188540
mydb=# reindex table pg_statistic;
REINDEX
mydb=# vacuum analyze mytable;
VACUUM
_

右兄弟の左リンクが一致しません

_CREATE TABLE "myschema"."mytable" ( ... )
ERROR: right sibling's left-link doesn't match: block 27 links to 21379 instead of expected 21393 in index "pg_depend_reference_index"
_

私たちはこれをすばやく回避しようとしました:

_mydb=# set zero_damaged_pages=on;
SET
mydb=# reindex table pg_depend;
REINDEX
mydb=# set zero_damaged_pages=off;
SET
_

ファイル内のブロックを読み取れませんでした...

_2015-05-12 13:32:53 UTC ERROR:  could not read block 76408 in file "pg_tblspc/4606764/PG_9.1_201105231/117264/4614269": read only 0 of 8192 bytes
_

これは明らかにつらいことでした。私たちはこれを回避する方法を素早くハックすることができませんでした:

_mydb=# select cl.relfilenode, nsp.nspname as schema_name, cl.relname, cl.relkind from pg_class cl join pg_namespace nsp on cl.relnamespace = nsp.oid where relfilenode = 4614269;
 relfilenode | schema_name | relname | relkind
-------------+-------------+---------+---------
     4614269 | myschema    | mytable | r
(1 row)

mydb=# select pg_relation_filepath('myschema.mytable');
               pg_relation_filepath
---------------------------------------------------
 pg_tblspc/4606764/PG_9.1_201105231/117264/4614269
(1 row)

% Sudo ls -lah /var/lib/postgresql/9.1/main/pg_tblspc/4606764/PG_9.1_201105231/117264/4614269
-rw------- 1 postgres postgres 597M May 11 19:22 /var/lib/postgresql/9.1/main/pg_tblspc/4606764/PG_9.1_201105231/117264/4614269
_

これは、大量のデータが「失われた」ことを示す良い指標でした。

重複するキー値が一意の制約「pg_type_typname_nsp_index」に違反しています

これは、復元が壊れたことを示すもう1つの指標でした。

_CREATE TABLE "myschema"."mytable" ( ... )
ERROR: duplicate key value violates unique constraint "pg_type_typname_nsp_index" DETAIL: Key (typname, typnamespace)=(mytable_mycolumn_seq, 3780903) already exists.
_

このための簡単なハックは、シーケンスの位置を移動することでした。

_SELECT setval('mytable_id_seq', (SELECT MAX(id) FROM mytable));
_
8
Josip Rodin