Skip to content

Instantly share code, notes, and snippets.

@kmikmy
Last active January 29, 2016 03:32
Show Gist options
  • Save kmikmy/4fea0db5a1b3edfa7a42 to your computer and use it in GitHub Desktop.
Save kmikmy/4fea0db5a1b3edfa7a42 to your computer and use it in GitHub Desktop.
postgresのリカバリに関するメモ

リカバリの種類

以下より引用 http://lets.postgresql.jp/documents/technical/backup/

クラッシュリカバリ

WALを用いてデータベースを障害のある状態を復元する。

論理バックアップ

バックアップ方法

サーバを起動したままSQLとして保存(pg_dump, pg_dumpall)

リストア方法

SQLを再投入(pg_restore, psql)

物理バックアップ

オフラインバックアップ

バックアップ方法

サーバを停止して、ファイル($PGDATA)をコピー。

リストア方法

サーバを停止状態で、ファイル($PGDATA)をコピー。

オンラインバックアップ

バックアップ方法

ベースバックアップ+WALのアーカイブ

ベースバックアップの方法はサーバを起動したままファイル($PGDATA)をコピー(pg_basebackup -x(ベースバックアップにWALを含めるオプション))

WALは元来チェックポイント間でデータベースがクラッシュしたときに自動リカバリを行うために作られているもののため、 何もしないと不要になったWALは捨てられる。 postgres.confのarchive_modeがONになっていると、WALが捨てられる際にこれを別な場所に保存する。

リストア方法

サーバ停止状態でファイルをコピーして、WALで任意時点までリカバリ。

設定

論理的な話

18.5. ログ先行書き込み(WAL)

チューニングパラメータの話 http://www.postgresql.jp/document/9.4/html/runtime-config-wal.html

29.1. 信頼性

postgresがどのように信頼性を担保しているかという話

http://www.postgresql.jp/document/9.4/html/wal-reliability.html

本当に書き込まれたこと(syncされたこと)を保証する方法について

バッテリバックアップされた書き込みキャッシュを持たないコントローラの使用は避けてください。
装置レベルでは、もし装置が停止前にデータが書き出されることを保証できないのであれば、write-backキャッシュを無効にしてください。
もしSSDを使っている場合、多くのドライブはデフォルトでキャッシュ書き出しコマンドを無視することに注意して下さい。

full_page_writesの必要性について

ディスクプラッタの書き込み操作自体によってもデータ損失が発生することがあります。
ディスクプラッタは、通常512バイトのセクタに分割されています。 
物理的な読み込み操作、書き込み操作はすべて、セクタ全体を処理します。
書き込み要求がディスクに達した時、その要求は512バイトの倍数になるでしょう
(PostgreSQLでは大抵一度に8192バイトすなわち16セクタを書き込みます)。
そして電源断により、任意のタイミングで書き込み処理が失敗することがありえます。
これは一部の512バイトのセクタに書き込みが行なわれたのに、残りのセクタには書き込みが行なわれていない状況を意味します。
こうした問題の対策として、PostgreSQLは、ディスク上の実際のページを変更する前に定期的にページ全体のイメージを
永続的なWAL格納領域に書き出します。
これにより、PostgreSQLはクラッシュリカバリ時に部分的に書き出されたページをWALから復旧させることができます。
もし、部分的なページ書き込みを防止できるファイルシステムソフトウェア(例えばZFS)を使うのであれば、
full_page_writesを無効にしてページイメージ作成を無効にすることができます。

重要な記述は以下の部分

PostgreSQLは、ディスク上の実際のページを変更する前に定期的にページ全体のイメージを永続的なWAL格納領域に書き出します。 これにより、PostgreSQLはクラッシュリカバリ時に部分的に書き出されたページをWALから復旧させることができます。

29.2. ログ先行書き込み(WAL)

WALの基本的な話

http://www.postgresql.jp/document/9.4/html/wal-intro.html

##(29.3. 非同期コミット)

非同期コミットの有用性と危険性についての話

http://www.postgresql.jp/document/9.4/html/wal-async-commit.html

29.4. WALの設定

WALのパラメータチューニングについて

  • commit_delay:グループコミットの間隔を設定する
  • checkpoint_segments, checkpoint_timeout:check_point_segments WALセグメントが消費された時、あるいは、指定したcheckpoint_timeout秒が経過した時、このどちらかが発生するとすぐに、チェックポイントが完了するように調整される。
普通、古いセグメントファイルが不要になった時、
それらは再利用(つまり、番号付けられるシーケンスにおいての将来のセグメントとなるように名前が変更)されます。

http://www.postgresql.jp/document/9.4/html/wal-configuration.html

29.5. WALの内部

WALログがどのように保存されるか、リカバリがどのように行われるかについて

http://www.postgresql.jp/document/9.4/html/wal-internals.html

WALログは、データディレクトリ以下のpg_xlogディレクトリに、通常16メガバイトのサイズを持つセグメントファイルの集合として
格納されています(ただし、このサイズはサーバ構築時の--with-wal-segsizeというconfigureオプションで変更できます)。
各セグメントは通常8キロバイトのページに分割されます(このサイズは--with-wal-blocksizeというconfigureオプションで変更できます)。
ログレコード用のヘッダはaccess/xlog.hに記述されています。 レコードの内容は、ログの対象となる事象の種類によって異なります。
セグメントファイルは名前として000000010000000000000000から始まる、常に増加する数が与えられています。
数字は巡回しませんが、利用可能な数字を使い尽くすには非常に長い時間がかかるはずです。 
チェックポイントが実行され、ログが吐き出された後、チェックポイントの位置はpg_controlに保存されます。
したがって、リカバリの開始の際は、サーバはまずpg_controlを読み、次にチェックポイントレコードを読みます。
そして、チェックポイントレコード内で示されたログの位置から前方をスキャンすることでREDO処理を行います。
データページの内容全体は、チェックポイント後の最初のページ変更時にログ内に保存されますので
(full_page_writesパラメータが無効にされていないという前提です)、
そのチェックポイント以降に変更された全てのページは一貫した状態に復旧されます。 

24.3. 継続的アーカイブとポイントインタイムリカバリ(PITR)

WALの継続的アーカイブとアーカイブを用いたPITRについて

http://www.postgresql.jp/document/9.4/html/continuous-archiving.html

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment