Application use¶
ユーザーの観点からPGDアプリケーションについて学びます。
アプリケーションの動作¶
PGDは、あるノードで行われた変更の他のノードへの複製をサポートしています。
PGDは、デフォルトで、ソースノードから他のノードへのINSERT、UPDATE、DELETEおよびTRUNCATE操作によるすべての変更をレプリケートします。すべてのトリガーとルールが処理された後、最終的な変更のみが送信されます。たとえば、
INSERT ... ON CONFLICT UPDATE
は、オリジンで何が発生したかに応じて、挿入または更新のいずれかを送信します。更新または削除がゼロ行に影響する場合、変更は送信されません。
前提条件なしで INSERT をレプリケートできます。
他のノードでレプリケートする更新と削除の場合、PGDは、影響を受ける一意の行を識別できる必要があります。 PGDでは、テーブルにPRIMARY KEYが定義されていること、UNIQUE制約、または特定の列に定義されている明示的なREPLICA IDENTITYが必要です。これらのいずれかが定義されていない場合、警告が生成され、後の更新または削除は明示的にブロックされます。 REPLICA IDENTITY FULLがテーブルに定義されている場合、ユニークインデックスは必要ありません。その場合、更新と削除が許可され、ライブ、有効、遅延されておらず、式またはWHERE句を持たない最初の非一意のインデックスを使用します。それ以外の場合は、シーケンシャルスキャンが使用されます。
定義されたレプリケーションIDがなくてもTRUNCATEを使用できます。 TRUNCATEコマンドのレプリケーションはサポートされていますが、外部キーで接続されたテーブルのグループを切り捨てる場合は注意してください。切り捨てアクションをレプリケートする場合、サブスクライバーは、レプリケーションセットが定義されている場合を除き、オリジンで切り捨てられたのと同じテーブルグループを切り捨てます。詳細と例については、
Replication sets を参照してください。影響を受けるすべてのテーブルが同じサブスクリプションの一部である場合、これは正しく機能します。ただし、サブスクライバーで切り捨てるテーブルの一部に、同じ(または任意の)レプリケーションセットの一部ではないテーブルへの外部キーリンクがある場合、サブスクライバーに切り捨てアクションを適用すると失敗します。
INSERT、UPDATE、およびDELETEコマンドによって暗黙的に取得される行レベルのロックは、変更が行われるとレプリケートされます。
INSERT、UPDATE、DELETE、およびTRUNCATEコマンドによって暗黙的に取得されたテーブルレベルのロックもレプリケートされます。ユーザーセッションによる明示的な行レベルロック(SELECT ... FOR UPDATE/FOR SHARE
)は複製されず、勧告ロックも複製されません。
SERIALIZABLEモードで実行されているトランザクションによって保存された情報は、他のノードにレプリケートされません。
SERIALIAZABLEのトランザクション分離レベルはサポートされていますが、マルチプルのノードで同時トランザクションが存在する場合、トランザクションはノード間でシリアル化されません。
- DMLが複数のノードで同時に実行され、非同期レプリケーションで実行すると競合が発生する可能性があります。これらを処理するか、回避する必要があります。
CRDTデータ型を使用した列の競合の処理 で説明されているさまざまな回避メカニズムが可能です。
bdr.シーケンス で説明されている、シーケンスには特別な処理が必要です。
BYTEA列のバイナリデータは正常に複製されるため、最大1 GBのデータの「ブロブ」が許可されます。 PGDでは、PostgreSQLの「ラージオブジェクト」機能の使用はサポートされていません。
ルールは起点ノードでのみ実行されるため、レプリカに対して有効になっている場合でも、適用中には実行されません。
実表から実表へのレプリケーションのみ可能です。つまり、サブスクリプション側のソースとターゲットのテーブルは、ビュー、マテリアライズドビュー、または外部テーブルではなく、テーブルである必要があります。実テーブル以外のテーブルをレプリケートしようとすると、エラーが発生します。更新可能なビューを介して行われるDML変更は、オリジンの実表に解決され、ターゲットの同じ実表名に適用されます。
PGDはパーティションテーブルを透過的にサポートします。つまり、パーティションテーブルをレプリケーションセットに追加し、パーティションを含む変更をダウンストリームに複製できます。
デフォルトでは、トリガーはオリジンノードでのみ実行されます。たとえば、
INSERT
トリガーはオリジンノードで実行され、ターゲットノードに変更を適用しても無視されます。
ALTER TABLE ... ENABLE ALWAYS TRIGGER
を使用して、実行時にオリジンノードと複製時(「適用時」)にターゲットの両方で実行するトリガーを指定できます。または、
REPLICA
オプションを使用して、適用時にのみ実行します:ALTER TABLE ... ENABLE REPLICA TRIGGER
。
一部の種類のトリガーは、テーブルに存在し、現在有効になっている場合でも、適用時に実行されません。実行されないトリガータイプは次のとおりです。
ステートメントレベルのトリガー (
FOR EACH STATEMENT)カラムごとのUPDATEトリガー (
UPDATE OF column_name [, ...])
PGDレプリケーションの適用は、システムレベルのデフォルトのsearch_pathを使用します。レプリカトリガー、ストリームトリガー、およびインデックス式関数は、他のsearch_path設定を想定できますが、適用時に実行すると失敗します。これが発生しないようにするには、次のいずれかの手法を使用します。
デフォルトのsearch_pathのみを使用して、オブジェクト参照を明確に解決します。
常にオブジェクトへの完全修飾参照を使用します。例、 schema.objectname。
影響を受ける関数に
ALTER FUNCTION ... SET search_path = ...を使用して、関数の検索パスを設定します。
PGDは、テキストまたはその他の照合可能なデータ型に関連する問題がないことを前提としています。 つまり、使用中のすべての照合はすべてのノードで使用でき、デフォルトの照合はすべてのノードで同じです。変更のレプリケートでは、等式検索を使用してレプリカID値を特定するため、一致しない照合修飾子で一意のインデックスが明示的に定義されている場合を除き、これは効果がありません。照合可能な式が使用された場合、行フィルターは照合の違いの影響を受ける可能性があります。
PostgreSQLでの非常に長い「トースト」データのPGD処理は、ユーザーには透過的です。 TOASTの「chunkid」値は、異なるノードの同じ行の間で異なる可能性がありますが、問題は発生しません。
レプリカID列が外部としてマークされている場合、PGDは正しく動作しません。
PostgreSQLは、揮発性関数を含むCHECK()制約を許可します。 PGDは適用時にCHECK()制約を再実行するため、以前と同じ結果を返さない後続の再実行により、データの相違が発生します。
PGDは外部キーの使用を制限しません。 FKのカスケードが許可されます。
複製されないステートメント¶
次のユーザーコマンドはPGDによって複製されないため、効果はローカル/オリジンノードでのみ発生します。
カーソル操作(DECLARE、CLOSE、FETCH)
実行コマンド(DO、CALL、PREPARE、EXECUTE、EXPLAIN)
セッション管理(DEALLOCATE、DISCARD、LOAD)
パラメータコマンド(SET、SHOW)
制約操作(SET CONSTRAINTS)
ロックコマンド(LOCK)
テーブルメンテナンスコマンド(VACUUM、ANALYZE、CLUSTER、REINDEX)
非同期操作(NOTIFY、LISTEN、UNLISTEN)
NOTIFY SQLコマンドとpg_notify()
関数は複製されないため、フェールオーバーが発生した場合の通知は信頼できません。これは、サーバーがクラッシュしたときにトランザクションがコミットされた場合、フェールオーバー時に通知が簡単に失われる可能性があることを意味します。
LISTEN
を実行しているアプリケーションは、フェイルオーバー時に通知を逃す場合があります。
これは標準のPostgreSQLレプリケーションにも当てはまり、PGDはまだこれを改善していません。
CAMOおよびEager Replicationオプションでは、 NOTIFY
SQLコマンドまたはpg_notify() 関数は許可されません。
DMLおよびDDLレプリケーション¶
PGDはDMLステートメントをレプリケートしません。 DMLステートメントによって引き起こされた変更をレプリケートします。たとえば、2つの行を変更したUPDATEは2つの変更をレプリケートしますが、行を削除しなかったDELETEは何もレプリケートしません。これは、 volatileステートメントの実行結果がレプリケートされることを意味し、ステートメントベースのレプリケーションで発生する可能性のあるノード間の相違がないことを保証します。
DDLレプリケーションの動作はDMLとは異なります。 DDLの場合、 PGD
はステートメントを複製し、すべてのノードで実行します。したがって、
DROP TABLE IF EXISTS
はローカルノードで何も複製しない場合がありますが、
DDLレプリケーションが有効になっている場合、ステートメントは実行のために他のノードに送信されます。詳細は
DMLおよびDDLレプリケーション で説明されています。
PGDは、混在したDMLステートメントとDDLステートメントが同じトランザクション内でも正しく機能するように機能します。
異なるリリースレベル間の複製¶
PGDは、PostgreSQLのメジャーバージョンが異なるノード間で複製するように設計されています。この機能は、ダウンタイムなしでメジャーバージョンをアップグレードできるように設計されています。
PGDは、PGDソフトウェアのバージョンが異なるノード間で複製するようにも設計されています。この機能は、ダウンタイムなしでバージョンのアップグレードとメンテナンスを行えるように設計されています。
ただし、クラスター内のメジャーバージョンのノードに参加することはできますが、クラスターが新しいプロトコルバージョンを使用している場合、マイナーバージョンのノードを追加することはできません。これを行うと、エラーが返されます。
- これらの機能はどちらも、特定の制限の影響を受ける可能性があります。既知の非互換性については、
EDB Postgres Distributed Release notes を参照してください。
差分のあるノード間のレプリケーション¶
- デフォルトでは、 DDLはすべてのノードに自動的に送信されます。
DMLおよびDDLレプリケーション で説明されているように、これを手動で制御でき、それを使用してノード全体のデータベーススキーマ間の違いを作成できます。
PGDは、ノード間のわずかな違いがあってもレプリケーションを継続できるように設計されています。これらの機能は、ダウンタイムなしでアプリケーションスキーマを移行できるように、またはロジカルスタンバイノードでレポートまたはテストを行えるように設計されています。
現在、レプリケーションにはすべてのノードで同じテーブル名が必要です。将来の機能では、異なるテーブル名間のマッピングが許可される可能性があります。
- ターゲット上のパーティションを変更する更新のサポートを含む、パーティションテーブルにレプリケートする通常のテーブルであるソースなど、異なるパーティション定義を持つテーブル間でレプリケートすることが可能です。動的パーティションルーティングは適用時に実行する必要がないため、ソースとターゲットでパーティション定義が同じである場合、より高速になります。詳細は、
Replication sets を参照してください。
デフォルトでは、すべての列が複製されます。
PGDは、列名に基づいてデータ列を複製します。列の名前は同じでデータ型が異なる場合、PGDはソース型からターゲット型にキャストしようとします(それを許可するキャストが定義されている場合)。
PGDは、列数が異なるテーブル間の複製をサポートしています。
ターゲットにソースから欠落している列がある場合、PGDはtarget_column_missing
conflictを発生させます。デフォルトの競合リゾルバーはignore_if_null
です。これにより、非NULL値が到着するとエラーがスローされます。または、
ignore
の競合リゾルバーでノードを構成することもできます。この設定はエラーをスローしませんが、追加の列を静かに無視します。
ターゲットにソースレコードにない追加の列がある場合、PGDはsource_column_missing
conflictを発生させます。デフォルトの競合リゾルバーはuse_default_value
です。追加の列にNULL(NULL可能な場合)またはデフォルトの式のデフォルトがある場合、レプリケーションは続行されます。エラーをスローし、そうでない場合はレプリケーションを停止します。
変換トリガーをテーブルで使用して、デフォルト値を提供したり、適用前にさまざまな方法で着信データを変更したりできます。
ソースとターゲットに異なる制約がある場合、レプリケーションが試行されますが、ソースからの行をターゲットに適用できない場合、失敗する可能性があります。ここで行フィルターが役立ちます。
あるスキーマからよりリラックスしたスキーマにデータをレプリケートしても、エラーは発生しません。スキーマからより制限の厳しいスキーマにデータをレプリケートすると、潜在的な障害の原因になる可能性があります。これを解決する正しい方法は、よりリラックスした側に制約を配置して、悪いデータを入力できないようにすることです。こうすれば、レプリケーションによって不良データが到着することはないため、より制限の厳しいスキーマへの変換が失敗することはありません。たとえば、あるスキーマにTEXT型の列があり、別のスキーマが同じ列をXMLとして定義している場合、 TEXT列にCHECK制約を追加して、テキストがXMLであることを強制します。
- 各ノードで異なるインデックスを持つテーブルを定義できます。デフォルトでは、インデックス定義は複製されます。
DMLおよびDDLレプリケーション を参照して、ノードのサブセットのみまたはローカルにインデックスを作成する方法を指定します。
fillfactor やtoast_tuple_target
などの記憶域パラメーターは、テーブルのノード間で問題なく異なる場合があります。その例外は、テーブルの記憶域パラメーター
user_catalog_table
の値がすべてのノードで同一でなければならないことです。
レプリケートされるテーブルは、各ノードで同じユーザー/ロールが所有する必要があります。さらなる議論については Security and roles を参照してください。
- ロールは、ノードごとに接続用に異なるパスワードを持つことができますが、デフォルトではロールの変更は各ノードに複製されます。ノードのサブセットのみまたはローカルでロールのパスワードを変更する方法を指定するには、
DMLおよびDDLレプリケーション を参照してください。
差分のあるノード同士の比較¶
LiveCompareは、データベース上のデータをPGDノードおよび非PGDノードと比較するためのツールです。比較して最終結果に到達するには、少なくとも2つの接続が必要です。
LiveCompare 1.3以降、 all_bdr_nodes
setで設定できます。この設定により、クラスター内の個別のノードごとに関連するすべてのDSNを明確にする手間が省けます。
EDB Postgres分散クラスターには、接続情報を持つN個のノードがありますが、
LiveCompare
1.3+がジョブを完了するために必要なのは初期接続と出力接続のみです。
logical_replication_mode
を設定すると、すべてのノードがどのように通信しているかが示されます。
たとえば、すべての構成はbdrLC.ini という名前の.ini
ファイルで行われます。 /etc/2ndq-livecompare/
でこの構成ファイルのテンプレートを見つけます。
LiveCompareの実行中、N+1個の進行状況バーが表示されます。 Nはプロセスの数です。すべてのテーブルのソースが取得されると、1秒あたりのトランザクション数(tps)が測定された時間が表示されます。これは時間をカウントし続け、見積もりを提供し、最後に合計実行時間を提供します。
このツールは、テーブル、スキーマ、replication_setsなど、多くのカスタマイズとフィルターを提供します。 LiveCompareはコンテキスト情報を失うことなくstop-startを使用できるため、都合の良いときに実行できます。比較後、サマリーとDMLスクリプトが生成されるため、確認できます。 DMLを適用して、見つかった違いを修正します。
アプリケーションの一般的なルール¶
- PGDはレプリカのID値を使用して、変更する行を識別します。アプリケーションで同じ一意の識別子を挿入、削除、および後で再利用すると、問題が発生する可能性があります。これは
ABA problem と呼ばれます。
PGDは、行が現在の行、最後の行、またはそれよりずっと古い行であるかを知ることができません。
同様に、PGDはテーブル名を使用して変更が再生されるテーブルを識別するため、同じオブジェクト名を作成、削除、および後で再利用するアプリケーションにも同様のABA問題が存在します。
これらの問題により、アプリケーションが従うべきいくつかの簡単なルールが発生します。
行に一意の識別子を使用します(INSERT)。
一意の識別子(UPDATE)の変更を避けます。
削除された一意の識別子の再利用は避けてください。
ドロップされたオブジェクト名の再利用を避けます。
一般的な場合、これらのルールを破ると、データの異常や発散につながる可能性があります。特定の条件が満たされる限り、アプリケーションはこれらのルールを破ることができますが、注意してください。異常が発生する可能性は低いですが、不可能ではありません。たとえば、ダウンしたノードを含むすべてのノードでDELETEがリプレイされている限り、行の値を再利用できます。これは通常1秒以内に発生する可能性がありますが、1つのノードで重大な問題が発生して正常に再起動できない場合、数日かかる場合があります。
タイミングの考慮事項と同期レプリケーション¶
デフォルトでは非同期であるため、ピアノードは遅れる場合があり、クライアントが複数のPGDノードに接続したり、それらを切り替えたりして、古いデータを読み取ることができます。
- このような古い読み取りを防ぐために、クライアントまたはプロキシに
queue wait function が提供されます。
Postgresの同期レプリケーション機能は、PGDでも利用できます。さらに、PGDは、より同期的なレプリケーションのために複数のバリアントを提供します。利用可能なすべてのバリアントとそのさまざまなモードの概要と比較については、 Durability and performance options を参照してください。
アプリケーションテスト¶
他の手法に加えて、次のプログラムを使用して、PGDアプリケーションをテストできます。
信頼できるPostgresアーキテクト¶
信頼できるPostgresアーキテクト は、 EDB Postgres
Distributedベースのものを含むリファレンスアーキテクチャを展開するためにEDBが使用するシステムです。
Trusted Postgres Architectには、各リファレンスアーキテクチャのテストスイートが含まれています。また、次のような構文を使用して、TPAクラスターに対して実行するテストのローカルコレクションの作成と管理が簡単になります。
tpaexec test mycluster mytest
開発者は、アプリケーションの主な予想されるプロパティを検証するTrusted Postgres Architectテストの独自のマルチノードスイートを作成することを強くお勧めします。
CAMO/failoverオプションを使用したpgbench¶
EDB Postgres Extendedでは、pgbenchが拡張され、ユーザーがCAMOまたは通常のPGDデプロイメントを使用しながらフェイルオーバーテストを実行できるようになりました。次のオプションが追加されました。
- m, --mode=regular|camo|failover
mode in which pgbench should run (default: regular)
- -retry
retry transactions on failover
これらのオプションに加えて、 DSN formにフェールオーバー用のピアノードの接続情報を指定する必要があります。
-m camoまたは-m failoverを使用して、pgbenchのモードを指定します。-m failover仕様を使用して、通常のPGD展開でのフェールオーバーをテストできます。--retryを使用して、-m failoverモードでフェイルオーバーが発生したときにトランザクションをリトライするかどうかを指定します。このオプションは、-m camoモードではデフォルトで有効になっています。
CAMO環境の例を次に示します。
pgbench -m camo -p $node1_port -h $node1_host bdrdemo \
"host=$node2_host user=postgres port=$node2_port dbname=bdrdemo"
このコマンドはCAMOモードで実行されます。 node1に接続し、テストを実行します。 node1への接続が失われると、pgbenchはnode2に接続します。 node2に問い合わせて、進行中のトランザクションのステータスを取得します。中止および飛行中のトランザクションは、迷彩モードで再試行されます。
フェイルオーバーモードで--retry
を指定すると、進行中のトランザクションが再試行されます。このシナリオでは、進行中のトランザクションのステータスを見つける方法はありません。
マルチノードアクセスを備えたisolationtester¶
isolationtester
が拡張され、ユーザーが複数のセッションおよび複数のノードでテストを実行できるようになりました。このツールは、内部PGDテストに使用されますが、ユーザーアプリケーションテストで使用することもできます。
$ isolationtester \
--outputdir=./iso_output \
--create-role=logical \
--dbname=postgres \
--server d1=dbname=node1 \
--server d2=dbname=node2 \
--server d3=dbname=node3
分離テストは、PostgreSQLの同時動作を検査するための一連のテストです。これらのテストでは、相互作用する複数のトランザクションを実行する必要があります。これには、複数の同時接続を管理する必要があるため、通常のpg_regress
プログラムを使用してテストすることはできません。
「分離」という名前は、当初の動機がシリアライズ可能な分離レベルをテストすることであったという事実に由来します。他の種類の同時動作のテストも追加されました。
PGXSを外部モジュールとして使用して構築されています。インストール時に、
isolationtester
バイナリファイルを作成します。これはpg_isolation_regress
によって実行され、同時リグレッションテストを実行し、結果を観察します。
pg_isolation_regress はpg_regress に似たツールですが、
psqlを使用してテストを実行する代わりに、isolationtesterを使用します。
pg_regress
と同じコマンドライン引数をすべて受け入れます。複数のホストをパラメーターとして受け入れるように変更されました。次に、ホストconninfoをサーバー名とともにisolationtester
バイナリに渡します。分離テスターは、これらのサーバー名とスペックファイルの各セッションで指定された名前を比較し、それぞれのサーバーで指定されたテストを実行します。
トランザクションが重複するテストを定義するには、カスタム構文でテスト仕様ファイルを使用します。新しいテストを追加するには、specファイルをspecs/
サブディレクトリに配置し、予想される出力をexpected/
サブディレクトリに追加して、テストの名前をmakefileに追加します。
Isolationtesterは、libpqを使用してマルチプルの接続を開き、specファイルで指定されたテストを実行するプログラムです。 libpq接続文字列は、接続するサーバーとデータベースを指定します。それ以外の場合は、環境変数から派生したデフォルトが使用されます。
仕様は5つの部分で構成され、次の順序でテストされます。
server "<name>"
この部分は、セッションを実行するサーバーの名前を定義します。ゼロ個以上のサーバー"<name>"
仕様があります。名前に対応するconninfoは、 isolationtester
を実行するコマンドによって提供されます。これはquickstart_isolationtest.md
で説明されています。この部分はオプションです。
setup { <SQL> }
指定されたSQLブロックは、テストを実行する前に、1つのセッションでのみ1回実行されます。ここでテストテーブルまたはその他の必要なオブジェクトを作成します。この部分はオプションです。必要に応じて、複数のセットアップブロックが許可されます。それぞれは、指定された順序で個別に実行されます。複数のセットアップブロックを許可する理由は、各ブロックが単一のPQexecサブミッションとして実行され、 VACUUMなどの一部のステートメントをそのようなブロック内の他のステートメントと組み合わせることができないためです。
teardown { <SQL> }
ティアダウンSQLブロックは、テストが終了した後に1回実行されます。この部分を使用して、セットアップで作成されたテストテーブルの削除など、次の置換に備えてクリーンアップします。この部分はオプションです。
session "<name>"
通常、スペックファイルにはいくつかの「セッション」部分があります。各セッションは、独自の接続で実行されます。セッションパートは、セットアップ、ティアダウン、および1つ以上の「ステップ」の3つのパートで構成されています。セッションごとのセットアップとティアダウンの部分は、テストごとのセットアップとティアダウンと同じ構文ですが、セッションごとに実行されます。セットアップ部分には、通常、トランザクションを開始するためのBEGINコマンドが含まれています。
セッション部分もconnect_to
仕様で構成され、このセッションが実行されるサーバーを示す最初に指定されたサーバー名をポイントします。
connect_to "<name>"
各ステップの構文は次のとおりです。
step "<name>" { <SQL> }
<name> はこのステップを識別する名前であり、
SQLはステップで実行されるSQLステートメント(またはセミコロンで区切られたステートメント)です。ステップ名は、スペックファイル全体で一意である必要があります。
permutation "<step name>"
置換行は、その順序で実行されるステップのリストを指定します。置換線はいくつでも表示できます。置換行が指定されていない場合、テストプログラムは各セッションのステップの可能な順序をすべて自動的に生成します(1つのセッションのステップを順番に実行します)。手動で指定された「置換」行のステップのリストは、実際には使用可能なステップの置換である必要はありません。たとえば、いくつかの手順を複数回繰り返したり、他の手順を省略したりできます。
”#”で始まる行はコメントです。
セッションステップの順列(これらがスペックファイルで手動で指定されたか、自動的に生成されたかにかかわらず)ごとに、分離テスターが実行されます。
1.メインセットアップ部
セッションごとのセットアップパーツ
1.選択されたセッションステップ
1.セッションごとのティアダウン
1.メインのティアダウンスクリプト
選択された各ステップは、そのセッションに関連付けられた接続に送信されます。
前提条件となるすべてのmakeコマンドを実行したPGD環境で分離テストを実行するには、次の手順を実行します。
make isolationcheck-installを実行してisolationtesterサブモジュールをインストールします。bdr-privateリポジトリから次のコマンドのいずれかを使用して、分離リグレッションテストを実行できます。
make isolationcheck-installcheck make isolationcheck-makecheck
isolationcheck-installcheck
を実行するには、2つ以上のpostgresqlサーバーを実行している必要があります。各サーバーのconninfoをPGD
makefileのpg_isolation_regress
に渡します。例:pg_isolation_regress --server 'd1=host=myhost dbname=mydb port=5434' --server 'd2=host=myhost1 dbname=mydb port=5432'
次に、 bdr-private/ リポジトリのspecs/isolation
ディレクトリにテストを含む.spec ファイルを追加します。
bdr-private/ リポジトリのexpected/isolation
ディレクトリに.out ファイルを追加します。
次に、次を実行します。
make isolationcheck-installcheck
Isolationcheck-makecheck
は現在、複数のデータベース間でPGDを設定することにより、単一のインスタンスでの分離テストの実行をサポートしています。
次のように、適切なデータベース名とbdrインスタンスのconninfoをPGD
makefileのpg_isolation_regress
に渡す必要があります。pg_isolation_regress --dbname=db1,db2 --server 'd1=dbname=db1' --server 'd2=dbname=db2'
次に、次を実行します。
make isolationcheck-makecheck
各ステップには、さらにアクションが実行されるまでブロックするコマンドを含めることができます。ほとんどの場合、他のセッションが、ブロックを解除するかデッドロックを引き起こすステップを実行します。この機能を使用するテストでは、有効な順列、つまり、ブロックされたセッションがコマンドを実行することを想定していない順列を手動で指定する必要があります。テストがそのルールに従わない場合、
isolationtester
は300秒後にキャンセルします。キャンセルが機能しない場合、
isolationtester
は375秒の待機時間後にクリーンに終了します。無効な順列のテストは避けてください。分離テストの実行に非常に時間がかかり、有用なテスト目的を果たさないためです。
isolationtester は、 pg_locks
ビューで待機中として表示されているかどうかを確認することにより、コマンドがブロックされたことを認識します。したがって、重量ロックのブロックのみが検出されます。
パフォーマンステストとチューニング¶
PGDを使用すると、複数のマスターノードに書き込みトランザクションを発行できます。これらの書き込みを各ノードに戻すと、パフォーマンスが低下します。
まず、別のノードからの変更の再生にはCPUコスト、I / Oコストがあり、WALレコードを生成します。 SQLを再実行する必要がないためCPUオーバーヘッドが少ないため、リソース使用は通常元のトランザクションよりも少なくなります。 UPDATEおよびDELETEトランザクションの場合、データがキャッシュされていない場合、再生時にI/Oコストが発生する場合があります。
第二に、変更をリプレイすると、ローカルワークロードに対して競合を引き起こす可能性のあるテーブルレベルおよび行レベルのロックが保持されます。競合のないレプリケートデータ型(CRDT)と列レベルの競合検出(CLCD)機能により、同時更新でも正しい答えが得られますが、通常のロックオーバーヘッドが削除されるわけではありません。ロックの競合が発生した場合は、更新の競合を避けるか、トランザクションをできるだけ短くしてください。大規模なトランザクションで頻繁に更新される行は、そのトランザクションのパフォーマンスにボトルネックを引き起こします。複雑なアプリケーションでは、スケーラビリティを維持するためにある程度の配慮が必要です。
パフォーマンスに問題があると思われる場合は、ベンチマークツールを使用してパフォーマンステストを開発してください。 pgbenchを使用すると、ユースケースに固有のカスタムテストスクリプトを作成できるため、 SQLのオーバーヘッドを理解し、同時実行の影響を測定できます。
PGDの実行が遅い場合は、次のことをお勧めします。
1.本番システムの問題ケースに可能な限り近づけて、pgbenchのカスタムテストスクリプトを作成します。
1つのノードでスクリプトを実行して、ベースラインの数値を取得します。
1つのノードで実行したのと同じ合計数のセッションを使用して、実稼働で発生するのと同じ数のノードでスクリプトを実行します。このテクニックは、マルチプルのノードに移動した場合の効果を示しています。
4.これら2つのテストのセッション数を増やして、アプリケーションでの競合の増加の影響をプロットできるようにします。
5.テストがレプリケーションの遅延を考慮に入れるのに十分な長さであることを確認します。
6.テスト中にレプリケーションの遅延が拡大していないことを確認します。
通常のPostgresチューニング機能をすべて使用して、アプリケーションの重要な部分の速度を向上させます。
PGDでのテーブルアクセスメソッド(TAM)の使用¶
PGD 5.0は、 EDB Postgres 15.0でリリースされた2つのテーブルアクセス方法をサポートしています。これら2つのテーブルアクセス方法は、PGD 5.0で認定および許可されています。
※オートクラスター※参考データ
他のTAMは、EDBによって認定されるまで制限されます。テーブルでテーブルアクセス方法のいずれかを使用する予定がある場合は、PGDクラスター内の各参加ノードでそのTAMを構成する必要があります。自動クラスターまたは参照データTAMを構成するには、各ノードで次の手順に従います。
postgresql.confを更新して、shared_preload_librariesパラメーターにTAMautoclusterまたはrefdataを指定します。
1.サーバーを再起動し、 CREATE EXTENSION autocluster;
またはCREATE EXTENSION refdata; を実行します。
拡張機能を作成した後、TAMでCREATE TABLE test USING autocluster;
またはCREATE TABLE test USING refdata;
を使用してテーブルを作成できます。これは、すべてのPGDノードに複製されます。これらのテーブルアクセス方法の詳細については、
テーブルを作成する を参照してください。