これは、PostgreSQL Advent Calendar 2020の22日目の記事となります。
昨日の記事は @tom-satoさんのPgpool-II 4.2 で何がどう変わったか?でした。
私は開発エンジニアとしてPostgresqlを利用しているのですが、
悩みごとをPostgresqlのコミュニティに相談させていただいた時に教えていただいたツールpg-repack
を紹介させてもらいます。
pg-repackとは
pg-repack
はテーブルの再編成を行えるPostgreSQLの拡張ツールです。
PostgreSQL Advent Calendar 2015で既に一度、中の人が直々に書かれた記事 運用で役立つツールpg_repackのご紹介もあるのですが、
最近の状況も含め、改めて紹介できればと思います。
テーブルの再編成を行う方法としてVACUUM FULL
コマンドなどがありますが、テーブルのに排他ロックがかかり、しかも実行に長い時間がかかるなど、リリース時の対応に頭を悩ませることになります。
私の場合、データクリーニングのために稼働中のDBに大量のUPDATEをかけた結果、不要領域が一度に増えすぎてパフォーマンスが低下したことがありました。
大量のUPDATE・DELETEがもたらす影響についてはPostgreSQLアンチパターン:UPDATEの濫用が分かりやすくまとまっています。
不要領域が著しく増えた時にはVACUUM FULL
コマンドでテーブルの再編成を行う方法がありますが、長時間の排他ロックがかかるためリリース時の対応に頭を悩ませることになります。
その点pg-repack
はごく短い間しか排他ロックをかけないため、稼働中のサービスに対するリリース戦略として有効な手段となります。
リリース状況
2020年12月時点でのバージョン情報です。
公式サイトURL | https://reorg.github.io/pg_repack/ |
---|---|
最新バージョン | pg_repack 1.4.6 |
Postgresql対応バージョン | PostgreSQL 9.4, 9.5, 9.6, 10, 11, 12, 13 |
最新バージョンのリリース日付は2020年9月30日と、着々と開発が進んでいるようです。
また、公式サイトを日本語訳ページで見ると、対応バージョンが9.6までしか表示されない点に注意です(上記reorg
の原文ページのReleaseで対応状況が確認可能)。
pg_repackの再編成の種類
既に何度か書きましたが、pg_repackはテーブルの再編成を行うツールです。
ただ、再編成の方法についてはいくつかバリエーションがあります。
・オンラインCLUSTER(テーブルデータを物理的にINDEX順で並び替え)
・指定カラムでレコードを並び替える
・オンラインVACUUM FULL (レコードのすきまを詰める)
・指定テーブルのインデックス再構築・再配置
コマンド実例
コマンドはpg_repack...[SCHEMA_NAME]
の形式で、
...
の部分にオプションをつけることで再編成の方法や対象テーブルを指定できます。
・スキーマ全体にCLUSTER
・VACUUM FULL
を実行
(クラスター化テーブルへはCLUSTER
,非クラスターテーブルへはVACUUM FULL
を実行)
pg_repack test_schema
・カラムを指定してレコードを並び替え(カラム指定のCLUSTER
)
# -o 整列に使うINDEXカラム指定
pg_repack -o role_id -t user test_schema
# カラムは複数指定可能
pg_repack -o role_id,id -t user test_schema
・テーブルを指定してVACUUM FULL
を実行
# -n VACUUM FULL指定オプション
pg_repack -n -t foo test_schema
# 複数テーブルを指定することも可能
pg_repack -n -t foo -t bar test_schema
・指定したテーブルのインデックス再編成
# -x
pg_repack -x -t users test_schema
・コマンドを実行内容を確認したい(Dry Run)
# -N 実施内容をメッセージとして出力
pg_repack -N test_schema
注意点
・再編成にはテーブルとインデックスを合わせたデータサイズ2倍の空き領域が必要
・pg_repackを実行できるのはスーパーユーザのみ
・再編成の内容によっては対象テーブルに主キーorNOT NULL+ユニーク制約をもつインデックスが存在している必要あり
まとめ
本来ならハンズオン的な内容を書きたかったのですが・・・、
恥ずかしながら、インストールでつまづいてしまい、試したことを書くことができませんでした。
今後、試した結果を記事にできたらと思います!
また、レベルの高い記事にビビリつつも、なんとか投稿する勇気がなくなる前に記事を投稿することができました。
これもPostgresqlコミュニティの温かさのお陰です。
明日はsawada_masahikoさんの投稿です!