Upload
kuronuko
View
687
Download
1
Embed Size (px)
Citation preview
PostgreSQL~テーブルメンテナンス~
Situa&on
@テーブルに不要領域が大量に残っているケース
PostgreSQLのデータ構造は追記型。非常にシンプルにMVCCモデルを実現しているが、不要領域を定期的に削除するための処理を実行する必要がある。
それが、VACUUM処理...!
@おさらい(MySQL(+(InnoDBの場合)(1/2
複数テーブルのレコードデータ並びにインデックスデータをまとめて、テーブルスペースと呼ぶデータファイル内に格納する構成。よってテーブル内のレコード件数が増加すると、テーブルスペース用のデータファイルの容量が増加。ただし、レコード件数が増加するたびにファイルサイズが徐々に大きくなる仕組みではない。
@おさらい(MySQL(+(InnoDBの場合)(2/2
設定した一定サイズのファイルを作成しておき、容量が不足した時にはじめてファイルサイズを大きくする仕組みになっている。ただし、レコード件数が増加するたびにファイルサイズが徐々に大きくなる仕組みではなく、設定した一定サイズのファイルを作成しておき、容量が不足した時にはじめてファイルサイズを大きくする仕組み。(MyISAMはテーブル単位のファイルという意味で少し似てる)
VACCUM処理
@What's(that?
• 不要領域の再利用
• トランザクションID周回問題の回避
不要領域の再利用
@VACCUMの内部処理 1/2
1.各テーブルのページを先頭から走査
2. VMをチェックして不要行を含むページなら3.に、不要行がなければ次のページを走査※VM(Visibility*Map)*.*テーブルの可視性の判断に利用する補助データ。テーブル1ページの状態を1bitで管理
3.対象ページの全行を走査し、不要行の情報を抽出
@VACCUMの内部処理 2/2
4"全ページ走査後、不要行が抽出されていれば対象テーブルのインデックスメンテナンスを行い。不要行の削除5"削除した行の情報をもとにFSMを更新
@VMとFSMによる恩恵• VMの情報をもとに処理を行うべきページを絞るので、負荷の軽減が期待される
• FSMによって、行が効率よく再利用されるようになる。これによってテーブルの物理的な肥大化を抑え、データベースのパフォーマンスを維持できる
XID周回問題の回避
@What's(that?
• テーブルにデータを格納する際、実行されたトランザクションを区別できるように、XIDが行ヘッダ(xmin)として格納される
• 実行中のトランザクションは、自身が持つXIDと行ヘッダのXID(xmin)の比較をし、可視or不可視の判断をする仕組み
@XID周回問題が起こるケースXIDは32bit(=約40億)で管理されているので、周回を繰り返す。周回したトランザクションIDを持つトランザクションから既存のデータを見ると、可視判定により全てのデータが見えなくなる現象が起こる。
意図的にメンテナンス?なんか、面倒なイメージ...
しかし!
PostgreSQL+8.3以降から、VACCUMメンテナンスは自動化!ただし...
@Demerit
• 自動バキュームの設定だけでは完全に制御できない。テーブルが肥大化し、性能に影響を及ぼす可能性あり※自動バキュームは、ALTER&TABLEで対象外にできる。(テーブルオプション変更)
VACCUM&FULL
@What's(that?
VACCUMによるメンテナンスが想定通りに機能しなかった場合の対処策。(VACCUMとVACCUM'FULLは別物なので注意)
LongTransac*onが存在している場合、VACCUMは機能しないので、そういう時にこれを使用。※LongTransac*onについては、p211参照
@important*point• VACUUM'FULLは、実行中は排他ロック。
@Summary• VACCUMは大事
• VACCUMが有効にならないケースがある事を理解し、その上で対処策を検討する必要あり
• 基本的には、自動バキュームor定期的な手動バキュームを正常に行えば、問題はない
PostgreSQL~indexメンテナンス~
@インデックスへのアクセス性能が低下する場合の原因• 肥大化
• 断片化
• クラスタ性の欠落
@肥大化について• indexファイルが肥大化すると、テーブルの肥大化と比例して有効データが少量でも多くのページが利用される
• それによって無駄なI/Oが発行されるので性能の低下につながる
• 傾向は、pg_classのrelpages列、reltuples列で確認することができる
@肥大化の予防策やはりVACCUMの出番。VACCUMにより完全に空となり、再利用可能となったindexページは再利用され、肥大化を防ぐ。定期的にVACCUNが機能していれば、あまり意識する必要は無い
@断片化について• B#treeインデックス固有の事象
• キャッシュヒット効率が悪化し、性能に影響を及ぼす可能性がある
• 傾向は、contribモジュールのpgsta0upleに含まれるpgstaindex
関数で確認する。(leaf_fragmenta8onを見る)※この調査方法は、比較的サーバへの負荷が高いので、考えて使用すること
@断片化の予防策自動バキュームでも、全てのindexがきれいに再利用できる状況が続くとは限らない。断片化によりindexファイルのサイズが増加する場合は、REINDEXによるindexの再定義を行う。
@クラスタ性の欠落について• 運用している間にテーブルデータの物理的な配置順序が、頻繁に利用されるindexの並び順と乖離している状態になること
• インデックススキャンを行っても、必要なデータを取得するために複数のページを参照しなければならないので、I/Oが増加し性能に影響を及ぼす
• 傾向は、pg_statsビューのcorrela1onを確認する(p2185表1471参照)
@クラスタ性の欠落の予防策CLUSTERを行う。実行時には、VACCUM+FULLと同様に次の点に注意• 一時的に対象テーブル/indexと同程度の容量が必要になる
• CLUSTER実行時にも排他ロックを取得する※CLUSTER実行時にはREINDEXも実施されるので、断片化とクラスタ性の改善を同時に実施したい場合はCLUSTERのみ実施すれば問題無い
Index&Only&Scan
@What's(that?• Index'Only'Scanは、indexのみを検索して結果を返却する仕組み
• テーブルデータではなく、VMを確認する形で実現されている
• PostgreSQL9.2から導入された
@important*point
• 特定の条件でしか効果が発揮できないので、使用すること自体難しい(詳細はp223参照)
• VMを更新したり、可能な限りVACCUMが実行されるような工夫をする必要がある
@Summary• 運用を続けることでindexに起こる問題を理解する
• 一連の流れとしては、VACUUMによる再利用を効果的に行い、性能への影響が著しい時にメンテナンス期間を設けて、REINDEXとCLUSTERでindexをメンテナンスする
Thank&you!