Azure Database for PostgreSQL - フレキシブル サーバーで pg_repack を使用した完全なバキューム
適用対象: Azure Database for PostgreSQL - フレキシブル サーバー
この記事では、pg_repack
を使用して肥大化を取り除き、Azure Database for PostgreSQL フレキシブル サーバーのパフォーマンスを向上させる方法について説明します。 肥大化は、頻繁な更新と削除のためにテーブルとインデックスに蓄積される不要なデータで生じます。 肥大化によって、データベースのサイズが想定よりも大きくなり、一部のクエリのパフォーマンスに大きく影響する可能性があります。 pg_repack
を使用すると、無駄な領域を回収して、データをより効率的に再構成できます。
pg_repack とは
pg_repack
は、テーブルとインデックスから肥大化を取り除き、より効率的に再構成する PostgreSQL の拡張機能です。 pg_repack
は、ターゲット テーブルまたはインデックスの新しいコピーを作成し、そのプロセスの間に発生したすべての変更を適用してから、古いおよび新しいバージョンをアトミックに入れ替えて機能します。 pg_repack
では、操作の開始時と終了時の短い時間を除き、処理されたテーブルまたはインデックスでのダウンタイムや排他アクセス ロックは不要です。 pg_repack
を使用して、Azure Database for PostgreSQL フレキシブル サーバー データベース内の任意のテーブルやインデックスを最適化できます。
pg_repack の使用方法
pg_repack
を使用するには、Azure Database for PostgreSQL フレキシブル サーバー データベースに拡張機能をインストールしてから、最適化するテーブル名またはインデックスを指定して pg_repack
コマンドを実行する必要があります。 拡張機能では、最適化の進行中に他の操作が実行されないように、テーブルまたはインデックスのロックを取得します。 これにより肥大化が取り除かれ、データをより効率的に再構成されます。
完全なテーブルの再パックのしくみ
この拡張機能では、次のステップに従って、完全なテーブルの再パックを実行します。
- 元のテーブルに加えられた変更を記録するログ テーブルを作成します。
- トリガーを元のテーブルに追加して、INSERT、UPDATE、DELETE をログ テーブルにログします。
- 元のテーブルのすべての行を含む新しいテーブルを作成します。
- 新しいテーブルにインデックスを作成します。
- ログ テーブルに記録されたすべての変更を新しいテーブルに適用します。
- インデックスや TOAST テーブルなど、元のテーブルや新しいテーブルを入れ替えます。
- 元のテーブルを削除します。
これらのステップの間、pg_repack
では初期セットアップ (ステップ 1 と 2) と最後のスワップ アンド ドロップ フェーズ (ステップ 6 と 7) の間の短い時間だけ排他アクセス ロックを保持します。 残りの時間には、pg_repack
では元のテーブルに対して共有アクセス ロックを保持するだけで済み、INSERT、UPDATE、DELETE を通常どおりに続行できます。
制限事項
pg_repack
には、使用する前に注意する必要のあるいくつかの制限があります。
- 操作を成功させるには、ターゲット テーブルで NOT NULL 列に PRIMARY KEY または UNIQUE インデックスのどちらが必要です。
pg_repack
の実行中は、VACUUM と ANALYZE を除き、ターゲット テーブルに対してデータ定義言語 (DDL) コマンドを実行することはできません。 これらの制限が確実に適用されるように、pg_repack
では、完全なテーブルの再パック中にターゲット テーブルに対して共有アクセス ロックを保持します。
セットアップ
前提条件
pg_repack クライアント アプリケーションを構築する
この拡張機能を使用するには、構築して Ubuntu のインスタンスにインストールできる、クライアント アプリケーションが必要です。
バージョン 1.4.7 の pg_repack
をインストールするには、Ubuntu マシン上で次の Bash スクリプトを実行します。
# Create the file repository configuration
sudo sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# Import the repository signing key
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
# Update the package lists
sudo apt-get update
# Install required packages to build the code
sudo apt-get install -y postgresql-server-dev-14 unzip make gcc libssl-dev liblz4-dev zlib1g-dev libreadline-dev libzstd-dev
# Download compressed version of build tree for version 1.4.7 of pg_repack
wget 'https://api.pgxn.org/dist/pg_repack/1.4.7/pg_repack-1.4.7.zip'
# Uncompress build tree
unzip pg_repack-1.4.7.zip
# Set current directory to where build tree was uncompressed
cd pg_repack-1.4.7
# Build code
sudo make
# Copy resulting binaries to /usr/local/bin
sudo cp bin/pg_repack /usr/local/bin
# Run pg_repack to check its version
pg_repack --version
pg_repack を使用する
次に使用するコマンドは、エンドポイント pgserver.postgres.database.azure.com、ユーザー名 azureuser、データベース foo を使って、Azure Database for PostgreSQL フレキシブル サーバー インスタンス内のパブリック スキーマの info という名前のテーブルに対して pg_repack
を実行する方法の例です。
お好みのクライアントを使用して、Azure Database for PostgreSQL フレキシブル サーバー インスタンスに接続します。 この例では、psql を使用します。
psql "host=<server>.postgres.database.azure.com port=5432 dbname=<database> user=<user> password=<password> sslmode=require"
データベースにインストールされている
pg_repack
拡張機能のバージョンを探します。SELECT installed_version FROM pg_available_extensions WHERE name = 'pg_repack';
拡張機能のバージョンは、クライアント アプリケーションのバージョンと一致している必要があり、次のコマンドを実行することで確認できます。
azureuser@azureuser:~$ pg_repack --version
データベース foo にある info と呼ばれるテーブルに対して
pg_repack
クライアントを実行します。pg_repack --host=<server>.postgres.database.azure.com --username=<user> --dbname=<database> --table=info --jobs=2 --no-kill-backend --no-superuser-check
pg_repack のオプション
運用環境のワークロード向けの pg_repack
の有用なオプションは次のとおりです。
-k
、--no-superuser-check
: クライアントでスーパーユーザーの検査をスキップします。 この設定は、Azure Database for PostgreSQL フレキシブル サーバー インスタンスなど、非スーパーユーザーとしての実行をサポートするプラットフォームでpg_repack
を使うのに役立ちます。-j
、--jobs
: Azure Database for PostgreSQL フレキシブル サーバーに対して指定した数の追加接続を作成し、これらの追加接続を使って、各テーブルでのインデックスの再構築を並列化します。 並列インデックス構築は、テーブル全体の再パックでのみサポートされています。--index
または--only
インデックス オプション: Azure Database for PostgreSQL フレキシブル サーバー インスタンスで追加のコアとディスク I/O を利用できる場合、このオプションを使用すると、pg_repack
の高速化に役立つ可能性があります。-D
、--no-kill-backend
:--wait-timeout
で指定されている時間が経過してもロックを取得できない場合は、ブロックしているクエリを実行しているバックエンド クライアントを強制終了する代わりに、テーブルの再パックをスキップします。 既定では--wait-timeout
は 60 秒に設定されています。 このパラメーターの既定値はfalse
です。-E LEVEL
、--elevel=LEVEL
: 出力メッセージ レベルをDEBUG
、INFO
、NOTICE
、WARNING
、ERROR
、LOG
、FATAL
、PANIC
から選択します。 既定値は、INFO
です。
すべてのオプションを把握するには、pg_repack のドキュメントを参照してください。
よく寄せられる質問
pg_repack は拡張機能なのでしょうか、それとも psql や pg_dump のようなクライアント側の実行可能ファイルなのでしょうか?
pg_repack は実際にはその両方です。 pg_repack/lib は拡張機能のコードを保持します。これには、拡張機能によって作成されるスキーマおよび SQL 成果物と、それらの複数の関数のコードを実装する C ライブラリが含まれます。
一方、pg_repack/bin にはクライアント アプリケーションのコードがあります。このコードは、拡張機能に実装されたプログラミング要素と対話する方法を認識します。 このクライアント アプリケーションは、サーバー側拡張機能によって表示されるさまざまなインターフェイスとの対話の複雑さを軽減することを目的としています。 ユーザーにわかりやすいコマンドライン オプションをいくつか提供します。 ポイントしているデータベースに拡張機能が作成されていないクライアント アプリケーションは、有用ではありません。 サーバー側拡張機能はそれ自体で完全に機能しますが、複雑な対話パターンをユーザーが理解する必要があります。 そのパターンは、拡張機能によって実装された関数への入力として使用されるデータを取得するためのクエリの実行などから構成されます。