Aurora PostgreSQLのスナップショットを検証環境や別アカウントへ復元したあと、pg_stat_user_tablesを見るとlast_analyzeがNULL、n_live_tupが0になっています。一方でAWSの公式ドキュメントには、メジャーバージョンアップグレードでは統計情報が転送されないという記述があります。この2つが結びつくと「スナップショット復元でも統計情報は失われたのではないか」という推測が生まれ、復元手順書に「全テーブルANALYZE」が入り込みます。設計レビューで繰り返し出てくる論点です。
この記事は要約版です。復元直後に流す確認クエリ3本と切り分けの順序、強制終了からの自動リカバリ検証ログ、復元手順書と監視への落とし込みは、ブログの完全版にまとめています: Auroraスナップショット復元と統計情報|ANALYZEは必要か
結論と、統計情報が2種類あるという前提
同一エンジンバージョンでのスナップショット復元では、オプティマイザが使う統計情報は保持されます。DBクラスタースナップショットはストレージボリューム全体の物理バックアップで、ANALYZEの結果を格納するpg_statisticも同じボリューム上のカタログテーブルだからです。ユーザーテーブルのブロックだけを保存してpg_statisticのブロックを除外する、という状態は構造的に起こりません。
リセットされるのは別系統の統計です。pg_stat_user_tablesが持つn_live_tupやlast_analyzeは累積カウンターで、PostgreSQL 15以降は共有メモリ、それ以前は統計コレクターとファイルで管理されます。この累積統計はクラッシュセーフではないため、正常にシャットダウンされなかった場合は破棄されます。復元されたクラスターはREDO適用を経て起動するので、強制終了後の再起動と同じ状態になります。pg_statisticはWALで保護されるヒープ上のデータ、累積カウンターは実行時のメトリクスという設計の差です。
ANALYZEが必要になるのは、ボリュームをそのままコピーしない経路を通ったときです。メジャーバージョンアップグレードでは統計情報が転送されないため、全データベース・全テーブルのANALYZEが必要になります。pg_dump/pg_restoreやDMSによる論理移行も、カタログの統計情報を運ぶ経路がないため同様です。
まず見るべきは pg_stats
復元直後に実行計画の品質を気にしているなら、確認先はpg_stat_user_tablesではなくpg_statsです。
SELECT tablename, attname, null_frac, n_distinct, most_common_vals FROM pg_stats WHERE tablename = '<テーブル名>';
行が返り、n_distinctやmost_common_valsに値が入っていれば、そのテーブルの統計情報は保持されています。WHERE句やJOIN条件でよく使う列を含むテーブルから確認してください。
判断軸を「復元したからANALYZE」ではなく「データを変えたからANALYZE」「統計が古いからANALYZE」に置き換えると、手順書の記述が安定します。復元後にマスキングや大量投入・削除を行うなら、その処理の後工程としてANALYZEを置く形になります。
完全版で扱っている内容
- なぜ保持されるのかの構造解説。
pg_statsのnull_frac、n_distinct、most_common_vals、histogram_bounds、correlationが等値条件や範囲検索の選択率推定にどう使われるか - 復元直後に実行する3つの確認クエリと、
EXPLAINのrows=で統計情報が実際に使われているかを最終判断する手順。取得元クラスターとの比較方法も含む - コミュニティ版PostgreSQL 16のDocker環境で、プロセス強制終了から自動リカバリさせた検証ログ。
pg_statsとpg_stat_user_tablesの前後比較、この検証で言えること・言えないことの整理 - よくある誤解3つの整理。メジャーバージョンアップグレードの記述を復元に当てはめてしまう理由、復元後のAutoAnalyze判定がゼロ起点になる影響、パラメータグループやインスタンスクラスの差で計画が変わるときの切り分け順序
- 復元手順書を経路ごとに書き分ける方針、復元直後に保存しておくと切り分けが楽になる情報、
auto_explainやlog_temp_files、待機イベントを使った実行計画劣化の検知
Auroraスナップショット復元と統計情報|ANALYZEは必要か
Aurora PostgreSQLの仕様やパラメータのデフォルト値は変更されることがあります。手順を確定させる前に、AWSおよびPostgreSQLの公式ドキュメントで対象バージョンの記述を確認してください。