postgresqlリクエストの監視についてはすでに話しましたが 、その瞬間、postgresqlがさまざまなサーバーリソースでどのように機能するかを完全に理解したように思えました。
postgresリクエストに関する統計を絶えず作業することで、いくつかの異常に気づき始めました。 私は理解するようになりましたが、同時に、postgresのソースコードの理解しやすさを改めて賞賛しました)
katの下で、postgresqlの明白でない動作についての短い話。
「ダーティ」ページを選択します
つまり、SELECTを実行すると、postgresがディスクに書き込む一部のレコードが変更されます。
まず、トランザクションの整合性を確保するためにpostgresで使用されるMVCCメカニズムの簡単な説明から始めます。
データベース内のすべての変更はトランザクション中に発生し、各トランザクションには識別番号txid(int32)があります。
Postgresは、いわゆるタプル(タプル)の形式でテーブルデータを操作します。 タプルは、テーブル内の特定の行のデータと、このデータに関連付けられているメタデータを直接運びます。
画像:www.interdb.jp
xminは、このタプルが作成したトランザクション番号です
xmax-このタプルを削除済みとしてマークしたトランザクション番号
- テーブルでINSERTを実行すると、新しいタプルが作成されます(xmin = txid)
- DELETE-条件に一致するダミーを削除済みとしてマークします(xmax = txid)
- UPDATEは、条件付きでDELETE + INSERTを実行します。
SELECTを実行すると、テーブルからデータを直接検索して選択することに加えて、可視性チェックも実行されます。
非常に単純化された、条件が満たされた場合、txid1という番号のトランザクションはこのtuplを「見る」。
xmin < txid1 < xmax
ただし、タプルの変更はすぐに発生し、トランザクションには長い時間がかかる可能性があるため、可視性チェック中に、xmin、xmax番号のトランザクションが完了している場合、どのステータスで完了しているかを確認する必要があります。 Postgresは、各トランザクションの現在の状態に関する情報をCLOG(コミットログ)に保存します。
CLOGで多数のトランザクションのステータスをチェックすることはリソースによって非常にコストがかかるため、開発者はこの情報をtuplaのヘッダーに直接「キャッシュ」することを決定しました。 つまり、たとえば、xminが完了したことをSELECTが認識すると、いわゆるヒントビット(トランザクション状態xminおよびxmaxが書き込まれる情報マスクの上の構造)に保存されます。
読書中にダミーの変更はどのように発生するのか、私たちは理解しましたが、「ページ」が何であり、なぜ「ダーティ」であるのかを覚えておく必要があります)
実際、メモリ内およびディスク上のデータの処理は、ほとんどの場合、大きなブロックよりも効率的です。 postgresのこのようなブロックは「ページ」であり、一定数の青写真とそれらに関するメタ情報が含まれています。 少なくとも1つのページタプルを変更すると、そのすべてが「ダーティ」としてマークされます。つまり、ディスク上の状態が異なり、同期する必要があります。 さらに、データベースプロセスの異常終了後にデータの整合性を復元できるように、ほとんどの場合、変更もWALに書き込まれます。
SELECTはディスクへの同期書き込みを引き起こす可能性があります
ご存じのように、pg内のデータの処理はすべてバッファキャッシュを介して行われます。必要なデータが存在しない場合、postgresは(OSページキャッシュを使用して)ディスクからデータを読み取り、キャッシュに入れます。
同時に、キャッシュに場所がない場合、最も要求の少ないページがキャッシュからプッシュされます。 最後に、プリエンプティブな候補ページが汚れている場合は、同時にディスクに書き込む必要があります。
FrozenTransactionId
記事の冒頭で、postgresのトランザクションカウンターは32ビットである、つまり20億トランザクションごとにリセットされることを説明しました。
トランザクションカウンターのリセット時に可視性チェックがカボチャにならないように、特別なプロセスがあります-ラップアラウンドバキューム。
バージョン9.4より前では、このプロセスはダミーのxminを特別な値FrozenTransactionId = 2に置き換えました。 この番号のトランザクションは、他のトランザクションよりも古いと見なされました。 9.4では、xminが「フリーズ」されていることを示すフラグがタプルに追加され、xmin自体は変更されません。
最も注意深い場合:特別な定数BootstrapTransactionId = 1があり、これも他のすべてのトランザクションよりも古いです)
合計
(奇妙な)(フィリピンの意見では)postgres動作のほとんどの場合、パフォーマンスの最適化が原因です。
postgresをいじくり回していると、素晴らしい本「The Internals of PostgreSQL 」を見つけました。