Ubuntu20.04でPostgreSQL12を使用して継続的なアーカイブを設定し、ポイントインタイムリカバリを実行する方法

提供:Dev Guides
移動先:案内検索

著者は、 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_commandrecovery_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トピックページをご覧ください。