データベースで UPDATE 文または DELETE 文を実行した後、削除されたデータは非表示としてラベル付けされますが、データページ上に穴として残ります。その結果、穴もスキャンされるため、データのスキャンに多くの時間がかかります。データの読み取り効率を向上させるために、テーブルストレージを定期的に再利用できます。
ストレージ再利用の方法
次の VACUUM 文を実行して、テーブルデータを再配置し、テーブルストレージを再利用して、データの読み取りパフォーマンスを向上させることができます。
VACUUM [FULL] [FREEZE] [VERBOSE] [table];VACUUM:すべてのテーブルに対して VACUUM 操作を実行します。VACUUM [table]:特定のテーブルに対して VACUUM 操作を実行し、ダーティデータをクリーンアップして、列指向テーブルのダーティデータのストレージ、または行指向テーブルの末尾にある穴を解放します。この操作は、テーブルに対する読み取りおよび書き込み操作をブロックしません。VACUUM FULL [table]:特定のテーブルに対して VACUUM FULL 操作を実行し、テーブル内のダーティデータのすべてのストレージを解放します。この操作は、排他ロックを適用して、テーブルに対する読み取りおよび書き込み操作をブロックします。VACUUM FREEZE [table]:特定のテーブルに対して VACUUM FREEZE 操作を実行し、テーブルの XID の経過時間を短縮します。この操作は、テーブルに対する読み取りおよび書き込み操作をブロックしません。VACUUM VERBOSE [table]:VACUUM 操作中のダーティデータクリーンアップのログを表示します。
使用上の注意
デフォルトでは、AnalyticDB for PostgreSQL インスタンスでは、自動バキューム機能が有効になっています。システムは自動的にダーティデータをクリーンアップし、XID の経過時間を短縮します。
テーブルに対して多数の更新または削除操作を実行した後、
VACUUM FULL文を実行して、テーブル内のダーティデータのすべてのストレージを解放できます。重要VACUUM FULL文は、テーブルに対する読み取りおよび書き込み操作をブロックするために排他ロックを適用します。VACUUM文は、初期アカウント、または RDS_SUPERUSER 権限を持つ特権アカウント を使用してのみ実行できます。必要な権限がない場合、VACUUM文は有効になりません。
VACUUM 操作が必要なテーブルのクエリ
AnalyticDB for PostgreSQL は、インテリジェントデータ膨張診断 機能を提供します。この機能は、膨張したテーブルを見つけて、VACUUM 操作が必要なテーブルをクエリするのに役立ちます。
AnalyticDB for PostgreSQL は、gp_bloat_diag というビューを使用して、実際のページと予想されるページの比率を測定します。ANALYZE TABLE 文を実行して統計を収集し、gp_bloat_diag ビューを確認できます。
SELECT * FROM gp_toolkit.gp_bloat_diag;次の結果には、中程度または重大なデータ膨張が発生しているテーブルが含まれています。VACUUM FULL 文を実行して、膨張したテーブルのストレージを再利用できます。
bdirelid | bdinspname | bdirelname | bdirelpages | bdiexppages | bdidiag
----------+------------+------------+-------------+-------------+---------------------------------------
21488 | public | t1 | 97 | 1 | significant amount of bloat suspected
(1 row)実際のページと予想されるページの比率(bdirelpages / bdiexppages)が 4 より大きく 10 未満の場合、テーブルは中程度のデータ膨張が発生していると見なされます。比率が 10 より大きい場合、テーブルは重大なデータ膨張が発生していると見なされます。
ストレージ再利用中の読み取り可能性
テーブルに対して多数の更新または削除操作を実行した後は、VACUUM FULL 文を実行して、テーブル内のダーティデータのすべてのストレージを解放できます。ただし、VACUUM FULL 文は、排他ロックを適用して、テーブルに対する読み取りおよび書き込み操作をブロックします。これはオンラインビジネスに影響を与えます。この問題を解決するために、次のセクションでは、ストレージ再利用中にテーブルの読み取り可能性を維持するためのクリーンアップ方法を提供します。
仕組み
この方法の本質は、テーブルのデータ再配布を使用してストレージ再利用を実現することです。システムは、バックグラウンドで元のテーブルと同じスキーマを持つ一時テーブルを作成し、元のテーブルから一時テーブルにすべてのデータを書き込み、2 つのテーブルのメタデータをスワップしてから、一時テーブルを削除します。データは完全に書き換えられるため、新しいデータに穴は存在しません。このようにして、ストレージが効果的に再利用されます。
シナリオ
ロック生成メカニズムが原因で、自動バキューム機能 がテーブルストレージをタイムリーに再利用できない場合があります。この場合、アクティブなメンテナンスが必要です。
重大なデータ膨張が発生している大きなテーブルに対して
VACUUM FULL文を実行すると、排他ロックが長期間存在し、テーブルに対する読み取りおよび書き込み操作がブロックされます。これはオンラインビジネスに影響を与えます。
使用上の注意
この方法は、ストレージ再利用中にデータレプリカを生成するため、短時間でディスク使用量が増加する可能性があります。
この方法は、バックグラウンドでインデックスを再構築するため、この期間中も読み取りおよび書き込み操作がブロックされます。したがって、この方法は、ベクターインデックスなどの大きなインデックスを持つテーブルには適していません。
手順
データベースに次の関数を作成します。
CREATE OR REPLACE FUNCTION reorganize_table(table_name regclass) RETURNS void AS $$ DECLARE distribution_policy text; alter_sql text; BEGIN SELECT pg_get_table_distributedby(table_name) INTO distribution_policy; alter_sql := format('ALTER TABLE ONLY %s SET WITH (REORGANIZE=true) %s READABLE', table_name, distribution_policy); EXECUTE alter_sql; END; $$ LANGUAGE plpgsql;関数を呼び出して、ダーティデータを再利用します。
SELECT reorganize_table('schema_name.table_name');