[PostgreSQL]PostgreDBのメンテナンスまとめ

PostgreSQL

こんにちは、PSCのともはるです。
いきなりですが、みなさんはPostgreDBのメンテナンスをされているでしょうか。
今回はPostgreDBのメンテナンスに使われるコマンドについて、業務で学んだことを自分なりに調べたのでそれについてまとめていきたいと思います。

PostgreDBが遅くなる仕組み

コマンドを紹介する前に、まずはPostgreDBが何故遅くなるのかについて紹介します。
例えばテーブルにレコードが5件あるとします。このテーブルの2番目のレコードを更新した場合どうなるでしょうか。

テーブルの一番下に新しいレコードが追加されますが、元々のデータは削除されず残ってしまいます不要領域)。またINDEXも同様です。

上記は以降6行目を2行目として扱ってくれるので、DBとしては問題なく機能します。ただ、頻繁な更新や大量レコードの一括更新などあると大量の不要なレコードが残り続けるため、速度劣化することが簡単に想像できますね。
また更新だけでなく削除でも同様にデータが残ります

上記はあくまで一例ですが、このようにTABLEINDEXが不完全な状態になります。

VACUUM

前節で説明した通り、更新や削除を実行すると論理削除となり、物理データは残ったままになります。その残ったデータを削除するのがVACUUMです。使い方としては下記になります。

-- テーブルに対してVACUUMを実施する
VACUUM <テーブル名>;

大量のデータを削除する、または頻繁に更新処理があるテーブルなどに有効です。また自動でVACUUMを行うautovacuumも存在します。

REINDEX

REINDEXインデックスを再構築するコマンドです。使い方としては下記になります。

-- テーブルのインデックス再構築
REINDEX TABLE <テーブル名>;
-- INDEX単位でのインデックス再構築
REINDEX INDEX <インデックス名>;

REINDEXの注意点としては、インデックスの再構築が完了するまでテーブルの書き込みにロックがかかります(読み込みはロックされない)。そのため更新が多いテーブルに実施する場合は実行する時間帯に気を付けるなど必要になります。

ANARIZE

ANARIZE統計情報を最新化します。統計情報はアクセスを早くするための情報みたいなものです。使い方としては下記になります。

-- テーブルに対して統計情報を最新化する
ANALYZE <テーブル名>;

大規模のレコード追加や更新を行った場合、統計情報が実データと大きく異なることが予想されます。
レコードへのアクセスには統計情報が使われるのですが、統計情報と実データの不一致によりアクセス速度が劣化してしまうため、大規模のレコード変更などを行った場合はANARIZEコマンドの実行が必要です。
またAUTOVACUUMを実施している場合はVACUUMの後にANARIZEが実行されるため最新の統計情報を保つことができます。

おまけ:レコードロックしないREINDEX

REINDEXの説明では、REINDEX中はレコードロックがかかるという話でした。
しかし、postgreSQL12からCONCURRENTLYオプションを付けることでレコードをロックせずにREINDEXコマンドが実行できるようになりました。記述は下記のとおりです。

REINDEX TABLE CONCURRENTLY <テーブル名>;

これにより、サービスの稼働中でも気にせずにREINDEXコマンドを実行できるようになります。
ただし、対象のテーブルのインデックスに対して実行されるトランザクションが完了するまでREINDEXが停止するため、CONCURRENTLYオプションを付けない時より実行時間が大きくなります。

まとめ

PostgreDBのメンテナンスに使われるコマンドについてまとめてみましたがいかがでしょうか。
普段何気なく使っているDBですが、業務で実際にメンテナンスのコマンドを利用するまで、DBにメンテナンスが必要なんて知りませんでした。
今回は簡単にコマンドについて説明しましたが、実際にメンテナンスするとなるとどのタイミングで実施するか、どこのテーブルに実施するかなど他にも気にしないといけないところがいくつかあると思います。自分1人でメンテナンスが出来るようになるまで先が長そうですね...
もし1人でDBを立ち上げてメンテナンスすることがあれば、その時はより詳細なメンテナンス方法についてブログを書いてみたいと思います!それでは失礼しました。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です