postgresqlクラスタ全体の参照クエリが重くなった話し

レプリケーション構成中のpostgresqlマスタ、スレープ全台のある特定の参照クエリが重くなった話し

  • 重いのは特定のクエリのみ
  • indexは正しく使われており、実行計画上重いものではなさそう
  • なのに速度が出ない
  • 1プロセスあたりのcpu使用率が高い。サチるような処理ではないはず。
  • 昨日の状況と比べてみてもcpu使用率が異常値となっている

解決編

  • テーブルごとのデッドタプルを確認
select n_dead_tup from pg_stat_user_tables ;
  • 巨大なデッドタプルを持つテーブルを確認
  • autovacuumしてしているんだけどな
  • autovacuum設定値はデフォルトのautovacuum_vacuum_scale_factor=0.2 (20%)
  • 結論としてはこれがまずかった。
  • 1,000万レコードあるテーブルでは200万デッドタプルがautovacuumのトリガとなる
  • ユーザ操作上、大量のデータを更新できる機能があり、一気に80万ほどの更新が走り巨大なデッドタプルが生まれたが、20%の閾値以下なので、autovacuumが走らなかった
  • マスタ側DBで対象のテーブルを手動vacuumすることで対応

ある程度の規模のテーブルになるとautovacuum_vacuum_scale_factor=0.2が最適な閾値とはならない可能性が出てくるので、autovacuum運用する時はレコードサイズに注意しておこう。という話し。