ApsaraDB RDS for PostgreSQLはpg_squeeze拡張機能をサポートしています。 拡張機能は、ApsaraDB RDS for PostgreSQLインスタンスのオンライン読み取りおよび書き込み操作に影響を与えることなく、テーブル内のデータを再編成してクリーンアップします。 これにより、テーブルとインデックスによって占有されるディスク領域が削減され、領域使用量が改善されます。
前提条件
次のパラメーターが設定されています。 詳細については、「ApsaraDB RDS For PostgreSQLインスタンスのパラメーターの変更」をご参照ください。
wal_levelパラメーターはlogicalに設定されています。
pg_squeezeがshared_preload_librariesパラメーターの値に追加されます。 このように、pg_squeeze拡張をプリロードできます。
ディスク容量は十分です。 pg_squeeze拡張機能が肥大化したテーブルとインデックスを縮小する場合、追加のディスク領域が必要です。
テーブル全体を縮小すると、使用可能なディスク容量は、テーブルとそのインデックスの合計サイズの少なくとも2倍になります。 たとえば、縮小するテーブルとそのインデックスの合計サイズが1 GBの場合、さらに2 GBのディスク領域が必要になります。
RDSインスタンスは、20240229以降のマイナーエンジンバージョンを実行します。 RDSインスタンスのマイナーエンジンバージョンを表示および更新する方法の詳細については、「マイナーエンジンバージョンの更新」をご参照ください。
背景情報
PostgreSQLは、マルチバージョン同時実行制御 (MVCC) を使用して、複数のトランザクションが競合することなく同じデータに同時にアクセスできるようにします。 MVCCは、データが更新または削除されたときに、元のデータを直接上書きまたは削除しません。 MVCCは、元のデータをデッドタプルとしてマークします。 デッドタプルは新しいトランザクションには見えませんが、ディスクスペースを占有し続けます。 その結果、テーブルは肥大化します。
autovacuum
などの方法を使用して、死んだタプルをクリーンアップできます。 しかし、この方法は、デッドタプルによって以前に占められていたスペースがすぐには再利用されないので、テーブルブラートを完全には除去しない。 これはまた、未使用スペースの量が大きいときにテーブル膨張をもたらす。 PostgreSQLは、未使用領域を再利用するためのVACUUM FULL
ステートメントを提供します。 ただし、VACUUM FULL
ステートメントでは、各テーブルに対してPostgreSQLで最も制限の厳しいロックであるAccess Exclusive Lockが必要です。 その結果、真空引きプロセス中にテーブルにアクセスできなくなります。
機能の説明
pg_squeeze拡張は、元のテーブルの新しいコピーを作成することによってテーブルを再構築します。 これにより、未使用のディスク領域がテーブルから再利用され、次の利点が得られます。
テーブルはオンラインでクリーンアップでき、読み取りおよび書き込み操作はブロックされません。
クライアントを使用しなくても、SQL文を直接実行できます。
シナリオ
データが頻繁に更新または削除されるテーブルは、テーブル膨張率が高くなります。
次のSQL文を使用して、テーブルの膨張率を推定できます。
CREATE EXTENSION pgstattuple; --create extension
select *, 1.0 - tuple_len::numeric / table_len as bloat from pgstattuple('your_relation');
テーブル膨張率は、テーブル内の未使用スペースと総スペースの比率であり、次の式を使用して計算されます。
1-ライブタプルスペース /テーブルの総スペース
。上記のステートメントを実行すると、テーブル全体のスキャンがトリガーされます。
使用上の注意
クリーンアップするテーブルには、一意のキーが必要です。
クリーンアッププロセス中に大量のI/Oリソースが消費されます。 オフピーク時にテーブルをクリーンアップすることをお勧めします。
拡張機能の作成または削除
次のステートメントを実行して、拡張子を作成します。
CREATE EXTENSION pg_squeeze;
説明複数のデータベースのテーブルをクリーンアップする場合は、各データベースに拡張機能を作成する必要があります。
次のステートメントを実行して、拡張子を削除します。
DROP EXTENSION pg_squeeze;
例
テーブルをクリーンアップする前に、ターゲットデータベースに拡張機能を作成する必要があります。
一時的にテーブルを片付ける
次の例では、パブリックスキーマのbar
テーブルがクリーンアップされています。
SELECT squeeze.squeeze_table('public', 'bar');
テーブルを自動的に検出してクリーンアップする
自動クリーンアップタスクを作成します。
次の例では、毎週水曜日と金曜日の22:30にパブリックスキーマの
foo
テーブルをクリーンアップするように拡張機能が設定されています。説明自動クリーンアップタスクの作成に使用される構文の詳細については、「pg_squeeze」をご参照ください。
現在のデータベース内のテーブルのみをクリーンアップできます。
INSERT INTO squeeze.tables (tabschema, tabname, schedule) VALUES ('public', 'foo', ('{30}', '{22}', NULL, NULL, '{3, 5}'));
自動クリーンアップタスクを有効にします。
自動クリーンアップタスクを手動で有効にします。
次のSQL文を実行して、自動クリーンアップタスクを手動で有効にします。 現在のデータベース内のテーブルのみをクリーンアップできます。
SELECT squeeze.start_worker(); -- Enable
自動クリーンアップタスクを無効にします。
SELECT squeeze.stop_worker(); -- Disable
自動クリーンアップタスクを自動的に有効にします。
ApsaraDB RDSコンソールでパラメーターを設定し、データベースを再起動して、クリーンアップタスクを自動的に有効にします。 詳細については、「ApsaraDB RDS For PostgreSQLインスタンスのパラメーターの変更」をご参照ください。
次の例では、
database1
およびdatabase2
データベースはrds_superuserアカウントを使用してクリーンアップされます。 rds_superuserは特権アカウントである必要があります。説明クリーンアップタスクが実行される前に、pg_squeeze拡張は
database1
とdatabase2
データベースに別々に作成されます。 詳細については、「拡張機能の作成と削除」をご参照ください。squeeze.worker_autostart = 'database1 database2' squeeze.worker_role = rds_superuser
関連ドキュメント
詳細については、「pg_squeeze」をご参照ください。