Ubuntu20.04でPostgreSQL12を使用して継続的なアーカイブを設定し、ポイントインタイムリカバリを実行する方法
著者は、 Diversity in Tech Fund を選択して、 Write forDOnationsプログラムの一環として寄付を受け取りました。
序章
PostgreSQL は、ACIDトランザクションをサポートする広く使用されているリレーショナルデータベースです。 頭字語ACIDは、原子性、一貫性、分離、および耐久性を表します。 これらは、データベース内のデータの永続性と有効性を確保するためにPostgreSQLがサポートするデータベーストランザクションの4つの主要なプロパティです。
PostgreSQLがACIDプロパティを維持するために使用する1つの方法は、先行書き込みログ(WAL)です。 PostgreSQLは、データベースクラスタのデータファイルに変更を書き込む前に、まずデータベース上のすべてのトランザクションをWALログファイルに記録します。
継続的なアーカイブでは、WALファイルがセカンダリストレージにコピーされます。これにはいくつかの利点があります。 たとえば、セカンダリデータベースクラスタは、レプリケーションの目的でアーカイブされたWALファイルを使用できますが、ファイルを使用してポイントインタイムリカバリ(PITR)を実行することもできます。 つまり、事故が発生した場合に、ファイルを使用してデータベースクラスターを望ましいポイントにロールバックできます。
このチュートリアルでは、Ubuntu20.04でPostgreSQL12クラスターを使用して継続的なアーカイブを設定し、クラスターでPITRを実行します。
前提条件
このチュートリアルを完了するには、次のものが必要です。
- Ubuntu20.04を実行している単一のマシン。 初期サーバーセットアップガイドでは、適切な権限を持つ非ルートユーザーを含むサーバーのセットアップについて説明します。
- マシン上で実行されているPostgreSQL12。 Ubuntu20.04にPostgreSQLをインストールして使用する方法チュートリアルのステップ1は、Ubuntu20.04へのPostgreSQL12のインストールについて説明しています。
ステップ1—データベースクラスターでの継続的なアーカイブの構成
この最初のステップでは、クラスターのデータディレクトリとは別のディレクトリにクラスターのWALファイルをアーカイブするようにPostgreSQL12クラスターを構成する必要があります。 これを行うには、最初にWALファイルをアーカイブするための新しいディレクトリをどこかに作成する必要があります。
次のように新しいディレクトリを作成します。
mkdir database_archive
ここで、デフォルトのPostgreSQLユーザーpostgres
にこのディレクトリへの書き込み権限を与える必要があります。 これを実現するには、chown
コマンドを使用してディレクトリの所有権を変更します。
sudo chown postgres:postgres database_archive
クラスタにWALファイルをアーカイブするためのディレクトリが設定されたので、デフォルトで/etc/postgresql/12/main/
ディレクトリにあるpostgresql.conf
構成ファイルでアーカイブを有効にする必要があります。
テキストエディタで設定ファイルを開きます。
sudo nano /etc/postgresql/12/main/postgresql.conf
ファイルを開いたら、行の先頭から#
を削除して、archive_mode
変数が含まれている行のコメントを解除します。 また、次のようにarchive_mode
の値をon
に変更します。
/etc/postgresql/12/main/postgresql.conf
. . . archive_mode = on . . .
また、クラスターがファイルをアーカイブするために使用するコマンドも指定します。 PostgreSQLは、このチュートリアルで機能するアーカイブコマンドを提供します。これについては、公式のPostgreSQLドキュメントで読むことができます。 archive_command
変数のコメントを解除し、次のコマンドを追加します。
/etc/postgresql/12/main/postgresql.conf
. . . archive_command = 'test ! -f /path/to/database_archive/%f && cp %p /path/to/database_archive/%f' . . .
ここでのarchiveコマンドは、最初にWALファイルがアーカイブにすでに存在するかどうかを確認し、存在しない場合はWALファイルをアーカイブにコピーします。
/path/to/database_archive
を、前に作成したdatabase_archive
ディレクトリへのパスに置き換えます。 たとえば、これをホームディレクトリに作成した場合:~/database_archive
。
最後に、wal_level
変数を構成する必要があります。 wal_level
は、PostgreSQLがログに書き込む情報の量を示します。 継続的なアーカイブの場合、これは少なくともreplyに設定する必要があります。
/etc/postgresql/12/main/postgresql.conf
. . . #wal_level = replica . . .
これはすでにPostgreSQL12のデフォルト値であるため、変更する必要はありませんが、この変数を変更する場合は覚えておく必要があります。
これで、ファイルを保存して終了できます。
データベースクラスター構成ファイルへの変更を実装するには、次のようにクラスターを再起動する必要があります。
sudo systemctl restart postgresql@12-main
PostgreSQLが正常に再起動すると、クラスターはすべてのWALファイルがいっぱいになるとアーカイブします。 デフォルトでは、各WALファイルは16MBです。
トランザクションをすぐにアーカイブする必要がある場合は、クラスターで次のコマンドを実行することにより、データベースクラスターに現在のWALファイルを変更してアーカイブさせることができます。
sudo -u postgres psql -c "SELECT pg_switch_wal();"
データベースクラスタがWALファイルをアーカイブに正常にコピーすると、データベースクラスタのデータファイルの物理バックアップを実行できるようになります。
ステップ2—PostgreSQLクラスターの物理バックアップを実行する
最悪の事態が発生した場合にデータ損失を軽減するために、データベースの定期的なバックアップを取ることが重要です。 PostgreSQLでは、データベースクラスターの論理バックアップと物理バックアップの両方を作成できます。 ただし、PITRの場合は、データベースクラスターの物理バックアップを作成する必要があります。 つまり、PostgreSQLのデータディレクトリにあるすべてのデータベースのファイルのコピーを作成する必要があります。 デフォルトでは、PostgreSQL12のデータディレクトリは/var/lib/postgresql/12/main/
です。
注:クラスターで次のコマンドを実行して、データディレクトリの場所を見つけることもできます。
sudo -u postgres psql -c "SHOW data_directory;"
前の手順では、アーカイブされたすべてのWALファイルを格納するディレクトリdatabase_archive
を作成しました。 このステップでは、database_backup
という別のディレクトリを作成して、作成する物理バックアップを保存する必要があります。
もう一度、ディレクトリを作成します。
mkdir database_backup
次に、所有権を変更して、postgres
ユーザーにディレクトリへの書き込み権限があることを確認します。
sudo chown postgres:postgres database_backup
バックアップ用のディレクトリができたので、データベースクラスタのデータファイルの物理バックアップを実行する必要があります。 幸い、PostgreSQLにはすべてを実行するpg_basebackup
コマンドが組み込まれています。 postgres
ユーザーとしてコマンドを実行します。
sudo -u postgres pg_basebackup -D /path/to/database_backup
/path/to/
をディレクトリへのパスに置き換えます。
このデータベースクラスターの物理バックアップを使用すると、クラスターでポイントインタイムリカバリを実行できるようになります。
ステップ3—データベースクラスタでポイントインタイムリカバリを実行する
データベースの物理バックアップが少なくとも1つあり、WALファイルをアーカイブしているので、データベースを以前の状態にロールバックする必要がある場合は、PITRを実行できます。
まず、データベースがまだ実行中の場合は、データベースをシャットダウンする必要があります。 これを行うには、systemctl stop
コマンドを実行します。
sudo systemctl stop postgresql@12-main
データベースが実行されなくなったら、PostgreSQLのデータディレクトリにあるすべてのファイルを削除する必要があります。 ただし、最初に、pg_wal
ディレクトリを別の場所に移動する必要があります。これには、リカバリに重要なアーカイブされていないWALファイルが含まれている可能性があるためです。 mv
コマンドを使用して、pg_wal
ディレクトリを次のように移動します。
sudo mv /var/lib/postgresql/12/main/pg_wal ~/
これで、/var/lib/postgresql/12/main
ディレクトリを完全に削除して、次のように再作成できます。
sudo rm -rf /var/lib/postgresql/12/main
に続く:
sudo mkdir /var/lib/postgresql/12/main
ここで、前の手順で作成した物理バックアップから新しい空のデータディレクトリにすべてのファイルをコピーする必要があります。 これはcp
で実行できます。
sudo cp -a /path/to/database_backup/. /var/lib/postgresql/12/main/
また、データディレクトリに所有者としてpostgres
ユーザーと適切な権限があることを確認する必要があります。 次のコマンドを実行して、所有者を変更します。
sudo chown postgres:postgres /var/lib/postgresql/12/main
そして、権限を更新します。
sudo chmod 700 /var/lib/postgresql/12/main
物理バックアップからコピーされたpg_wal
ディレクトリ内のWALファイルは古く、役に立たない。 一部のファイルはサーバーを停止する前にアーカイブされていない可能性があるため、PostgreSQLのデータディレクトリを空にする前にコピーしたpg_wal
ディレクトリ内のWALファイルに置き換える必要があります。
次のように、/var/lib/postgresql/12/main
ディレクトリのpg_wal
ファイルを削除します。
sudo rm -rf /var/lib/postgresql/12/main/pg_wal
次に、データディレクトリをクリアする前に、保存したpg_wal
ディレクトリからファイルをコピーします。
sudo cp -a ~/pg_wal /var/lib/postgresql/12/main/pg_wal
データディレクトリが正しく復元されたら、データベースサーバーがアーカイブされたWALファイルを正しく回復するように回復設定を構成する必要があります。 リカバリ設定は、/etc/postgresql/12/main/
ディレクトリのpostgresql.conf
構成ファイルにあります。
構成ファイルを開きます。
sudo nano /etc/postgresql/12/main/postgresql.conf
ファイルを開いたら、restore_command
変数を見つけて、行の先頭から#
文字を削除します。 最初のステップでarchive_command
を使用した場合と同様に、PostgreSQLがWALファイルを回復する方法を指定する必要があります。 archive
コマンドはファイルをアーカイブにコピーするだけなので、restore
コマンドはファイルをコピーして戻します。 restore_command
変数は次のようになります。
/etc/postgresql/12/main/postgresql.conf
. . . restore_command = 'cp /path/to/database_archive/%f %p' . . .
/path/to/database_archive/
をアーカイブディレクトリへのパスに置き換えることを忘れないでください。
次に、リカバリターゲットを指定するオプションがあります。 これは、データベースクラスタがリカバリモードを終了する前にリカバリを試みるポイントです。 リカバリターゲットは、タイムスタンプ、トランザクションID、ログシーケンス番号、pg_create_restore_point()
コマンドで作成された復元ポイントの名前、またはデータベースが一貫性のある状態に達したときはいつでもかまいません。 リカバリターゲットが指定されていない場合、データベースクラスタはアーカイブ内のWALファイルのログ全体を読み取ります。
recovery_target
変数のオプションの完全なリストについては、PostgreSQLの公式ドキュメントを参照してください。
注:リカバリターゲットは、使用している物理バックアップが作成された後の時点である必要があります。 以前のポイントに戻る必要がある場合は、データベースの以前のバックアップを使用する必要があります。
restore_command
とrecovery_target
を設定したら、ファイルを保存して終了します。
データベースクラスタを再起動する前に、リカバリモードで起動する必要があることをPostgreSQLに通知する必要があります。 これを実現するには、クラスターのデータディレクトリにrecovery.signal
という空のファイルを作成します。 ディレクトリに空のファイルを作成するには、touch
コマンドを使用します。
sudo touch /var/lib/postgresql/12/main/recovery.signal
これで、次のコマンドを実行してデータベースクラスタを再起動できます。
sudo systemctl start postgresql@12-main
データベースが正常に起動すると、リカバリモードになります。 データベースクラスターがリカバリターゲットに到達すると、recovery.signal
ファイルが削除されます。
データベースクラスターを目的の状態に正常に回復したので、通常のデータベース操作を開始できます。 別の時点に回復したい場合は、この手順を繰り返すことができます。
結論
このチュートリアルでは、PostgreSQL 12データベースクラスターをセットアップしてWALファイルをアーカイブしてから、アーカイブされたWALファイルを使用してポイントインタイムリカバリを実行しました。 事故が発生した場合に、データベースクラスターを望ましい状態にロールバックできるようになりました。
継続的なアーカイブとポイントインタイムリカバリの詳細については、docsをご覧ください。
PostgreSQLのその他のチュートリアルについては、PostgreSQLトピックページをご覧ください。