PostgreSQLをより効果的に使用する方法

オンラインゲームの記事データベースと特にそれに関するコメントを読んだ後、多くの開発者がプロ​​ジェクトのデータベースを変更し、このシフトの問題を解決しようとしているが、交換可能なデータベースによって提供されるすべての可能性を使い果たしていないという考えに腹を立てました。 私はデータベースの特徴があるプロジェクトの研究に参加しています:



歴史的な理由により、彼らが言うように、基地全体は、これまでシャーディングなしで1つの基地であり、多くの問題を解決することができました。 より深刻なのは、PostgreSQLの機能に正確に合ったソリューションを見つけることです。 わずかな血液で実装できるソリューション。



私たちが直面するいくつかの問題と適用される解決策について説明します。 誰かがそれを有用だと思うなら、神のために。 誰かがそれを修正したら、使用されているアプローチの脆弱性を発見し、データベースの効率を上げるだけです。 説明は、データベーススキーマを変更するだけで、アプリケーションロジックを妨げることなく適用できます。



PostgreSQL 9.2についてです(9.3はまだテストされていません)。 そして、はい、構成の最適な構成に関する管理上のヒントはありません-それらを正しくシャープにする方法を知ってうれしいです。



「適切なインデックスを作成する」などのキャプテンの推奨事項もありません。 これらのナノテクノロジーは表面にあると思います。



大きなテーブルとインデックスのサイズ



データベースの書き込みが集中的になればなるほど、サンプルの平均速度が低下し、データベースが「バカ」になり始めるのは周知の事実です。 これは、データベースのトランザクションの性質に直接関連しています。 文字列(タプル)はバージョン管理されているため、特定の文字列の値を変更するときに、この値を以前の値の代わりに取得して書き込むことはできません。 代わりに、PostgreSQLは行を複製し、その新しい修正バージョンを個別に書き込みます。 つまり、大まかに言うと、1GBのテーブルを使用して、1回の操作で任意のフィールドにUPDATEを実行すると、テーブルのサイズが「突然」2GBに増加します。 インデックスでもほぼ同じことが起こります。 データベースのサイズを大きくすると、クエリの実行速度にすぐに影響します。



もちろん、AUTOVACUUMは定期的に(設定されている場合)動作しますが、必要に応じて手でVACUUMを起動することもできます。



問題を軽減するために何ができますか?




遅いサンプル





トランザクションカウンターを超えました



MVCCメカニズムの操作は、トランザクションカウンターが存在しないと不可能でした。 このカウンタがまだ32ビットである理由は謎ですが、私たちが持っているのは、カウンタの末尾の20億トランザクションごとにリセットされることになっています。 取り返しのつかない事態が発生しないようにするには、この時点でデータベース内のすべての行のトランザクション番号をリセットする必要があります。 より正確には、特定の予約済みFrozenXIDがこれらの行に割り当てられます。 通常、AUTOVACUUMおよび手動VACUUMはFrozenXIDを設定せず、トランザクションカウンターが特定の構成値に達すると、通常のデータベース操作に対して、自動バキュームは「ラップアラウンドを防ぐため」という素晴らしいコメントで開始します。 大きなテーブル(数十GB)の場合、このプロセスには時間がかかり、その間、読み取りにも書き込みにもテーブルにアクセスできなくなります。



(私にとって)アプリケーションのロジックとアーキテクチャに影響を与えずにここで何もすることはできません。 トランザクションの数を減らしてトランザクションを拡大する(他の問題になる可能性があり、一般に効果がない)か、データベースを断片に分割する必要がありますが、これも問題を解決する運用方法につながりません。



長い取引



これはかなり明白ですが、念のために言及しておきます。



これは、長いトランザクション自体に関するものではなく、バグのためにアプリケーションがトランザクションを閉じずにさらに処理を続けた状況(たとえば、数日間ハングする可能性があるバックグラウンドタスクハンドラー)に関するものです。 アクティブなPostgreSQLプロセスのリストでは、このような接続は「idle in transaction」ステータスでハングします。 定期的にVACUUMを実行すると、削除または編集が実行されたトランザクションの数に応じて、古いバージョンの文字列(編集または削除後に残る)によって占有されていたスペースが解放されます。 大まかに言って、トランザクション1および2によって削除された行があり、現在開いているトランザクションの最小数が3である場合、これら2つの行は「実際に」削除できます。 現在開いているトランザクションの範囲内にはありません。 中断されたトランザクションの場合、VACUUMはこのトランザクションの開始後に編集された単一の行を削除できません。その結果、データベースは数時間で大きく成長する可能性があります。



唯一のアドバイスがあります-現在のプロセスを監視し、「トランザクションのアイドル」で悪役を捕まえることです。



長いブロッキングバックアップ



レプリケーションは、その魅力をすべて備えており、たとえば、パッチが曲がっているなど、ベースが破られた状況からは救いません。 彼らはそこにオブジェクトをリンクするためのパッチを作成し、すべての良いものが複製されました-そしてこんにちは。 したがって、何と言ってもバックアップが必要です。 大きなベースは約1時間バックアップされます。 ほぼすべての期間、プロジェクトは非アクティブです。 ここで、率直に言って、私は何もアドバイスすることはできません。 それどころか、この状況に誰がどのように対処しているかを聞いてうれしいです。 唯一の考えは、データの一貫性を維持する方法を考えて、断片化して断片化してバックアップすることです。



バージョン9.3では、プレゼンテーションで顕著な作業が行われました。これにより、データベースでの作業を最適化することもできますが、これは別のトピックです。



All Articles