Application Usage¶
この章では、アプリケーションまたはユーザの観点からBDRを検討します。
ノードのセットアップについては、後の章で説明しますDDLのレプリケーションや、レプリケーションを制御するためのさまざまなオプションについても同様です。
アプリケーションの動作¶
BDRは、1つのノードで行われた変更を他のノードに複製することをサポートします。
デフォルトでは、 BDRはINSERT、UPDATE、DELETE、TRUNCATEからのすべての変更をソースノードから他のノードに複製します。すべてのトリガーとルールが処理された後、最終的な変更のみが送信されます。例、INSERT … ON CONFLICT UPDATEは、オリジンで発生した内容に応じてINSERTまたはUPDATEを送信します。 UPDATEまたはDELETEがゼロ行に影響する場合、変更は送信されません。
INSERTは、前提条件なしで複製できます。
UPDATEおよびDELETEを他のノードに複製するには、影響を受ける一意の行を識別できる必要があります。 BDRでは、テーブルにPRIMARY KEYが定義されているか、UNIQUE制約があるか、特定の列で明示的なREPLICA IDENTITYが定義されている必要があります。それらのいずれかが定義されていない場合、警告が生成され、後でUPDATEまたはDELETEが明示的にブロックされます。テーブルにREPLICA IDENTITY FULLが定義されている場合、一意インデックスは不要です。その場合、UPDATEおよびDELETEは許可されます。そして、ライブで、有効で、遅延ず、式またはWHERE句を持たない最初の非ユニークインデックスを使用します。そうでない場合は、シーケンシャルスキャンが使用されます。
TRUNCATEは、定義されたレプリケーションIDがなくても使用できます。TRUNCATEコマンドのレプリケーションはサポートされていますが、外部キーで接続されたテーブルのグループを切り捨てるときは注意が必要です。切り捨てアクションを複製する場合、サブスクライバーは、レプリケーションセットが定義されている場合を除き、明示的に指定またはCASCADEを介して暗黙的に収集された、オリジンで切り捨てられた同じテーブルグループを切り捨てます。詳細と例については、章を参照してください。影響を受けるすべてのテーブルは、同じサブスクリプションのパートです。ただし、サブスクライバーで切り捨てられるテーブルに、同じ(またはいずれかの)レプリケーションセットのパートではないテーブルへの外部キーリンクがある場合、サブスクライバーでの切り捨てアクションの適用は失敗します。
INSERT、UPDATE、およびDELETEコマンドによって暗黙的に取得された行レベルのロックは、変更が行われると複製されます。INSERT、UPDATE、DELETE、およびTRUNCATEコマンドによって暗黙的に取得されたテーブルレベルのロックも複製されます明示的行レベルロック(SELECT … FOR UPDATE / FOR SHARE)はユーザセッションによって複製されず、アドバイザリロックも複製されません。 SERIALIZABLEモードで実行されているトランザクションによって保存された情報は、他のノードに複製されません。 SERIALIAZABLEのトランザクション隔離レベルはサポートされていますが、マルチプルのノードで同時トランザクションが存在する場合、トランザクションはノード間でシリアル化されません。
DMLがマルチプルのノードで同時に実行される場合、非同期レプリケーションで実行する場合、潜在的な競合が発生する可能性があり、これらを処理または回避する必要があります。さまざまな回避メカニズムが可能です。Conflictsの章でも説明されています。
シーケンスには、Sequenceschapterで説明されている特別なハンドリングが必要です。
BYTEA列のバイナリデータは通常どおり複製され、最大1GBのデータの「ブロブ」が許可されます。 PostgreSQLの「ラージオブジェクト」機能の使用は、 BDRではサポートされていません。
ルールはオリジンノードでのみ実行されるため、レプリカに対して有効になっている場合でも、適用中には実行されません。
レプリケーションは、ベーステーブルからベーステーブルにのみ可能です。つまり、サブスクリプション側のソースおよびターゲットのテーブルは、ビュー、マテリアライズドビュー、または外部テーブルではなく、テーブルでなければなりません。ベーステーブル以外のテーブルをレプリケートしようとすると、エラーが発生します。更新可能ビューを介して行われたDML変更は、オリジンのtobaseテーブルを介して解決され、ターゲットの同じベーステーブル名前に適用されます。
BDRはテーブルパーティションを透過的にサポートします。つまり、パーティションテーブルをレプリケーションセットに追加でき、パーティションに関係する変更がダウンストリームにレプリケートされます。
デフォルトでは、トリガーはオリジンノードでのみ実行されます。例、INSERTtriggerはオリジンノードで実行され、ターゲットノードで変更を適用すると無視されます。
ALTER TABLE ... ENABLE ALWAYS TRIGGERを使用して、トリガーを実行時の起点ノードとターゲット(レプリケート時)の両方で実行するように指定するか、REPLICAオプションを使用して、適用時のみALTER TABLE ... ENABLE REPLICA TRIGGERを実行できます。
一部のタイプのトリガーは、atableに存在し、現在有効になっている場合でも、適用時に実行されません。実行されないトリガータイプは
ステートメントレベルのトリガー(FOR EACH STATEMENT)
列ごとのUPDATEトリガー(UPDATE OF column_name [、…])
BDRレプリケーションの適用では、システムレベルのデフォルトのsearch_pathが使用されます。
Replicatriggers、ストリームトリガー、およびインデックス式関数は、適用時に実行と失敗する他のスキーマデフォルトを前提と保証場合があります。
、または影響を受ける関数のALTER FUNCTION ... SET search_path = ...を使用してファンクションの検索パスを設定します。
BDRは、テキストまたはその他のデフォルト可能なデータ型に関連する問題がないことを前提としていることに注意して照合順序。変更のレプリケーションでは、等値検索を使用してレプリカID値を特定します。したがって、一致しない照合順序修飾子で一意性インデックスが明示的に定義されている場合を除き、これは効果がありません。照合可能な式が使用されている場合、行フィルターは照合の違いの影響を受ける可能性があります。
PostgreSQL内の非常に長い「トースト」データのBDRハンドリングは、ユーザに対して透過的です。 TOASTの「chunkid」値は、異なるノードの同じ行で異なる可能性が高いことに注意してください。ただし、問題は発生しません。
レプリカID列が「外部」としてマークされている場合、 BDRは正しく機能できません。
PostgreSQLは、volatile関数を含むCHECK()コンストレインを許可します。 BDRは適用時にCHECK()コンストレインを再実行するため、以前と同じ結果を結果ない後続の再実行はデータの相違を引き起こします。
BDRは外部キーの使用を制限しません。カスケードFKは許可されます。
BDRは現在、非ASCIIスキーマまたはリレーション名の使用をサポートしていません。後のバージョンではこの制約がなくなります。
複製されていないステートメント¶
以下のユーザコマンドはいずれもBDRによって複製されないため、それらの影響はローカル/オリジンノードでのみ発生します。
カーソル操作(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()関数はレプリケートされないため、フェイルオーバーの場合、通知は信頼できないことになります。これは、サーバーがクラッシュした時点でトランザクションがコミットされた場合、フェイルオーバーオーバーで通知が簡単に失われる可能性があることを意味しますフェイルオーバーの場合に通知を見逃す可能性があります。これは標準のPostgreSQLレプリケーションでは残念ながら真実であり、
BDRはまだこれを改善していません。
CAMOおよびEagerレプリケーションオプションは、NOTIFY
SQLコマンドまたはpg_notify()ファンクションを許可しません。
DMLおよびDDLレプリケーション¶
BDRはDMLステートメントを複製せず、DMLステートメントによって引き起こされた変更を複製することに注意してください。したがって、例、2つの行を変更したUPDATEは2つの変更を複製しますが、行を削除しなかったDELETEは何も複製しません。これは、揮発性ステートメントの実行結果が複製されることを意味し、ステートメントベースのレプリケーションで発生する可能性のあるノード間の相違がないことを保証します。
DDLレプリケーションの動作はDMLとは異なります。 DDLの場合、 BDRはステートメントを複製し、それがすべてのノードで実行されます。そのため、DROP TABLE IF EXISTSはローカルノードで何も複製しない場合がありますが、 DDLレプリケーションが有効になっている場合、ステートメントはまだ他のノードに送信されて実行DDLレプリケーションます。
BDRは、同じトランザクション内であっても、混合されたDMLおよびDDLステートメントが正しく機能することを保証に非常に長くなります。
異なるリリースレベル間の複製¶
BDRは、異なるメジャーバージョンのPostgreSQLを持つノード間で複製するように設計されています。これは、ダウンタイムなしでメジャーバージョンをアップグレードできるように設計された機能です。
BDRは、異なるバージョンのBDRソフトウェアを持つノード間で複製するようにも設計されています。これは、ダウンタイムなしでバージョンをアップグレードおよびメンテナンスできるように設計された機能です。
ただし、クラスター内のノードをメジャーバージョンに結合させることは可能ですが、クラスターが新しいプロトコルバージョンを使用している場合、マイナーバージョンのノードを追加することはできません。これはエラーを結果ます。
上記の機能は両方とも特定の制限の影響を受ける可能性があります。既知の非互換性については、リリースノートで説明します。
相違点のあるノード間の複製¶
デフォルトでは、 DDLはすべてのノードに自動的に送信されます。これは、DDL Replicationで説明されているように、手動で制御できます。これは、ノード間でデータベーススキーマの違いを作成するために使用できます。 BDRは、ノード間にわずかな違いがある場合でもレプリケーションを続行できるように設計されています。これらの機能は、ダウンタイムなしでアプリケーションスキーマを移行したり、レポートまたはテスト用に論理スタンバイノードを許可したりするように設計されています。
現在、レプリケーションでは、すべてのノードで同じテーブル名前が必要です。 futurefeatureは、異なるテーブル名間のマッピングを許可するかもしれません。
ターゲットのパーティションを変更する更新のサポートを含む、分割されたテーブルに複製する通常のテーブルであるソースなど、異なるパーティション定義を持つテーブル間で複製することが可能です。ソースとターゲットのパーティショニング定義が同じ場合、適用時に動的パーティションルーティングを実行する必要がないため、高速になります。詳細については、レプリケーションセットの章を参照してください。
デフォルトでは、すべての列が複製されます。 BDRは、列名前に基づいてデータ列を複製します。列の名前が同じでデータ型が異なる場合、それを許可するキャストが定義されていれば、ソース型からターゲット型にキャストしようとします。
BDRは、列の数が異なるテーブル間の複製をサポートしています。
ターゲットにソースからの列が欠落している場合、 BDRはtarget_column_missingの競合を発生させます。この競合については、デフォルトの競合がignore_if_nullを解決します。 NULL以外の値が到着した場合、これはERRORをスローします。または、ノードは競合リゾルバignoreを使用して構成することもできます。この設定はERRORをスローせず、単に追加列を無視します。
ターゲットにソースレコードにない追加の列がある場合、 BDRはsource_column_missingの競合を発生させます。この競合のデフォルトの競合はuse_default_valueです。追加の列にデフォルト、NULL(null可能の場合)またはデフォルト 式がある場合、レプリケーションは続行しますが、そうでない場合はエラーをスローし、レプリケーションを停止します。
また、変換トリガーをテーブルで使用して、デフォルトを提供したり、適用前にさまざまな方法で受信データを変更したりできます。
ソースとターゲットのコンストレインが異なる場合、レプリケーションが試行されますが、ソースからの行をターゲットに適用できない場合は失敗する可能性があります。ここで行フィルターがヘルプ場合があります。
あるスキーマからより緩和されたスキーマにデータを複製してもエラーは発生しません。スキーマからより制約的なスキーマにデータを複製すると、潜在的な障害のソースになります。したがって、不正なデータが入力されることはありません。これにより、レプリケーションを介して不正なデータが届くことはないため、より制限的なスキーマへの変換に失敗することはありません。例、あるスキーマにTEXT型の列があり、別のスキーマにXMLと同じ列が定義されている場合、テキストがXMLであることを強制するCHECK制約をTEXT列に追加します。
テーブルは、各ノードで異なるインデックスを使用して定義できます。デフォルトでは、インデックス定義が複製されます。 DDL Replicationを参照して、ノードのサブセットのみで、またはローカルでのみインデックスを作成する方法を指定します。
fillfactorやtoast_tuple_targetなどのストレージパラメータは、テーブルのノード間で問題なく異なる場合があります。例外は、テーブルのストレージパラメータuser_catalog_tableの値がすべてのノードで同一でなければならないことです。
複製されるテーブルは、各ノードの同じユーザ/ロールが所有する必要があります。詳細については、Security and Rolesを参照してください。
デフォルトでは、ロールの変更は各ノードに複製されますが、ロールには各ノードの接続用に異なるパスワードが設定されている場合があります。 DDL Replicationを参照して、ノードのサブセットのみで、またはローカルでのみロールパスワードを変更する方法を指定します。
違いのあるノード間の比較¶
Livecompareは、 BDRおよび非BDRノードに対するデータベースのデータ比較に使用されるツール。比較し、最終結果を得るには、最低2つの接続がニーズです。
Livecompare
1.3から、all_bdr_nodesを設定して構成できました。これにより、クラスター内の各ノードに関連するすべてのDSNを明確にする必要がなくなります。
BDRクラスターには、接続情報を持つ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を適用してください。
アプリケーションの一般規則¶
上記で説明したように、 BDRはレプリカアイデンティティ値を使用して、変更する行を識別します。アプリケーションは、同じ一意の識別子を挿入、削除し、後で再利用すると問題を引き起こす可能性があります。これはABA問題と呼ばれます。 BDRは、行が現在の行、最後の行、またははるかに古い行であるかどうかを知ることができません。< https://en.wikipedia.org/ wiki/ ABA_problemを参照してください。
同様に、 BDRは変更をリプレイするテーブルを識別するためにテーブル名を使用するため、同じオブジェクト名を作成してからドロップし、後で再利用するアプリケーションにも同様のABA問題が存在します。
これらの問題により、アプリケーションが従うべきいくつかのシンプルルールが生じます。
1.行に一意の識別子を使用します(INSERT)2。一意の識別子の変更を避ける(更新)3。削除された一意の識別子の再利用を避ける4。ドロップされたオブジェクト名の再利用を避ける
一般的な場合、これらの規則を破ると、データの異常と相違が生じる可能性があります。特定の条件が満たされている限り、アプリケーションはこれらの規則に違反する可能性がありますが、注意が必要です。異常が発生することはほとんどありませんが、不可能ではありません。例、DELETEがダウンノードを含むすべてのノードで再生されている限り、行の値を再利用できます。これは通常1秒未満で発生する可能性がありますが、1つのノードで重大な問題が発生して正常に再起動できない場合、潜在的に数日かかる可能性があります。
タイミングの考慮事項と同期複製¶
デフォルトでは非同期であるため、同等なは、マルチプルのBDRノードに接続されているクライアントや、それらの間で切り替えて古いデータを読み取ることができるようにするために遅れることがあります。
queue wait functionは、そのような古い読み取りを防ぐために、クライアントまたはプロキシに提供されます。
Postgresの同期レプリケーション機能は、BDRasでも利用できます。さらに、 BDRは、より多くの同期複製のためにマルチプルのバリアントを提供します。利用可能なすべてのバリアントとその異なるモードの概要と比較については、Durability & Performance Optionschapterを参照してください。
アプリケーションのテスト¶
BDRアプリケーションは、他の手法に加えて、次のプログラムを使用してテストできます。
[CAMO / Failoverオプション付きのpgbench]
[マルチノードアクセスのアイソレーションテスター]
TPAexec¶
TPAexecは、Postgres- BDRに基づくものを含むリファレンスTPAarchitecturesを展開するためにEDBによって使用されるシステムです。
TPAexecには、各リファレンスアーキテクチャのテストスイートが含まれています。また、次の例のような構文を使用して、TPAクラスターに対して実行されるテストのローカルコレクションの作成と管理を簡素化します。
tpaexec test mycluster mytest
開発者は、アプリケーションの主要な期待されるプロパティを検証するTPAexecテストの独自のマルチノードスイートを作成することを強くお勧めします。
CAMO /フェイルオーバーオプションを備えたpgbench¶
pgbenchが拡張れ、CAMOまたは通常のBDR展開を使用しながら、ユーザーがフェイルオーバーテストを実行できるようになりました。次の新しいオプションが追加されました。
- m, --mode=regular|camo|failover
mode in which pgbench should run (default: regular)
--retry
retry transactions on failover
上記のオプションに加えて、フェイルオーバーのピアノードに関するノード情報をDSNformで指定する必要があります。
-m camoまたは-m failoverを使用して、pgbenchのモードを指定します。-m failover仕様を使用して、フェイルオーバーをテストできます。 通常のBDR展開。--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をクエリーして、実行中のトランザクションのステータスを取得します。中止および実行中のトランザクションは、camoモードで再試行されます。
failoverモードでは、--retryが指定されている場合、実行中のトランザクションが再試行されます。このシナリオでは、処理中のトランザクションのステータスを見つける方法はありません。
マルチノードアクセスの分離テスター¶
isolationtesterは、ユーザーが複数のセッションとマルチプルのノードでテストを実行できるように拡張ました。これは内部BDRテストに使用されますが、ユーザアプリケーションテストで使用することもできます。
$ 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を使用して構築されます。インストール時に、bypg_isolation_regressによって実行されるisolationtesterバイナリファイルを作成し、並行リグレッションテストを実行して結果を観察します。
pg_isolation_regressはpg_regressに似たツールが、psqlを使用してテストを実行代わりに、isolationtesterを使用します。
pg_regressと同じコマンドライン引数をすべて受け入れます。複数のホストをパラメーターとして受け入れるように変更されました。次に、これらのホストconninfoをサーバー名とともにisolationtesterバイナリに渡します。分離テスターは、これらのサーバー名をspecファイルの各セッションで指定された名前と比較し、指定されたテストを各サーバーで実行します。
重複するトランザクションでテストを定義するには、次のセクションで説明するカスタム構文のテスト仕様ファイルを使用します。新しいテストを追加するには、specs /サブディレクトリにspecファイルを配置し、expected /サブディレクトリにexpectedoutputを追加し、 メークファイルにテストの名前を追加します。
Isolationtesterは、 libpqを使用してマルチプルの接続を開き、specファイルで指定されたテストを実行するプログラムです。 libpq接続文字列は、接続するサーバーとデータベースを指定します。それ以外の場合は、環境変数から派生したデフォルトが使用されます。
仕様は、次のオーダーでテストされた5つの部分で構成されています。
server "<name>"
これは、セッションが実行されるサーバーの名前を定義します。サーバー
<name>の指定は0個以上存在できます。名前に対応するconninfoは、isolationtesterを実行するコマンドを介して提供されます。これはquickstart_isolationtest.mdで説明されています。このパートはオプショナル。
setup { <SQL> }
指定されたSQLブロックは、テストを実行する前に、1つのセッションでのみ1回実行されます。ここでテストテーブルまたはその他の必要なオブジェクトを作成します。このパートはオプショナル。必要に応じて、複数のセットアップブロックを使用できます。それぞれは、指定されたオーダーで個別に実行されます。 (マルチプルのセットアップブロックを許可する理由は、各ブロックが単一のPQexec送信として実行され、VACUUMなどの一部のステートメントがそのようなブロック内の他のステートメントと結合できないためです。)
teardown { <SQL> }
分解SQLブロックは、テストの終了後に1回実行されます。これを使用して、セットアップによって作成されたテストテーブルを削除するなど、次の順列に備えてクリーンアップします。このパートはオプショナル。
session "<name>"
通常、specファイルにはいくつかの「セッション」部分があります。各セッションは、独自の接続で実行されます。セッションパートは、セットアップ、分解、および1つ以上の「ステップ」の3つの部分で構成されます。セッションごとのセットアップとティアダウンの部分の構文は、上記のテストごとのセットアップとティアダウンと同じですが、各セッションで実行されます。通常、セットアップパートには、トランザクションを開始するための「BEGIN」コマンドが含まれています。
さらに、セッションパートも
connect_to仕様で構成されます。これは、このセッションが実行されるサーバーを示す最初に指定されたサーバー名前を指します。connect_to "<name>"各ステップには構文があります
step "<name>" { <SQL> }ここで、
<name>はこのステップを識別する名前であり、 SQLはステップで実行されるSQLステートメント(またはセミコロンで区切られたステートメント)です。ステップ名は、specファイル全体で一意である必要があります。
permutation "<step name>"
順列行は、そのオーダーで実行されるステップのリストを指定します。順列行はいくつでも表示できます。順列が指定されていない場合、テストプログラムは各セッションからステップの可能なすべての順序付けを自動的に生成します(1つのセッションのステップをオーダーに実行します)。手動で指定された「順列」行のステップのリストは、実際には使用可能なステップの順列である必要はないことに注意してください。インスタンス、いくつかの手順を複数回繰り返したり、他の手順を省略したりできます。
#で始まる行はコメントと見なされます。
セッションステップの順列(仕様ファイルで手動で指定されるか、自動生成されるか)ごとに、isolationtesterはメインセットアップパート、セッションごとのセットアップパート、選択されセッションステップ、セッションごとの分解を実行します。 mainteardownスクリプト。選択された各ステップは、そのセッションに関連付けられた接続に送信されます。
すべての前提条件makeコマンドを実行したBDR3環境で分離テストを実行するには、次の手順に従います。
make isolationcheck-installを実行してisolationtesterサブモジュールをインストールしますbdr-privateリポジトリから次のコマンドのいずれかを使用して、アイソレーションリグレッションテストを実行できます。
`make isolationcheck-installcheck` `make isolationcheck-makecheck`
A.
isolationcheck-installcheckを実行するには、2つ以上のpostgresqlserversを実行する必要があります。サーバーのconninfoをBDR
3.0
メークファイルのpg_isolation_regressに渡します。例:pg_isolation_regress --server 'd1=host=myhost dbname=mydb port=5434' --server 'd2=host=myhost1 dbname=mydb port=5432'
ここで、テストを含む.specファイルをbdr-private / repoのspecs / isolationディレクトリに追加します。 bdr-private / repoのexpected / isolationディレクトリに.outファイルを追加します。
次に、make isolationcheck-installcheckを実行します
B. Isolationcheck-makecheckは現在、マルチプルのデータベース間でBDRを設定することにより、単一インスタンスでの分離テストの実行をサポートしています。
適切なデータベース名、bdrインスタンスのconninfosを次のようにBDR
メークファイルのpg_isolation_regressに渡す必要があります。pg_isolation_regress --dbname=db1,db2 --server 'd1=dbname=db1' --server 'd2=dbname=db2'
次に、make isolationcheck-makecheckを実行します
各ステップには、さらにアクションが実行されるまでブロックするコマンドが含まれる場合があります(おそらく、他のセッションはブロックを解除するかデッドロックを引き起こすステップを実行します)。この機能を使用するテストでは、有効な置換、つまりブロックされたセッションがコマンドを実行ことを期待しないものを手動で指定する必要があります。テストがそのルールに従わない場合、isolationtesterは300秒後にキャンセルします。キャンセルが機能しない場合、合計375秒の待機時間の後、isolationtesterは異常終了します。無効な置換のテストは、分離テストの実行に非常に長い時間がかかる可能性があり、有用なテスト目的に役立たないmake、避ける必要があります。
isolationtesterは、pg_locksビューでコマンドが待機中として表示されているかどうかを確認することで、コマンドがブロックされたことを認識することに注意してください。したがって、重いロックのブロックのみが検出されます。
パフォーマンスのテストとチューニング¶
BDRを使用すると、マルチプルのマスタノードに書き込みトランザクションを発行できコスト。これらの書き込みを各ノードに戻すと、パフォーマンスが低下することに注意してください。
最初に、別のノードから変更をリプレイすると、CPUコスト、I / Oコストが発生し、WALレコードが生成されます。 SQLを再実行する必要がないため、CPUオーバーヘッドが低くなるため、通常、リソースの使用量はオリジナルのトランザクションより少なくなります。 UPDATEおよびDELETEトランザクションの場合、データがキャッシュされていない場合、リプレイにI / Oコストがかかる場合があります。
次に、変更を再生すると、ローカルワークロードに対する競合を引き起こす可能性のあるテーブルレベルおよび行レベルロックが保持されます。 CRDT(競合のないレプリケートされたデータ型)およびCLCD(列レベルの競合検出)機能により、同時更新でも正しい答えが得られますが、通常のロックオーバーヘッドは削除されません。ロックの競合が発生する場合は、更新の競合を回避するか、トランザクションをできるだけ短くしてください。大きなトランザクション内で頻繁に更新される行は、そのトランザクションのパフォーマンスにボトルネックを引き起こします。複雑なアプリケーションでは、スケーラビリティを維持するためにいくつかの考えが必要です。
パフォーマンスに問題があると思われる場合は、上記のベンチマークツールを使用してパフォーマンステストを開発することをお勧めします。 pgbenchを使用すると、ユースケースに固有のカスタムテストスクリプトを記述できますSQLのオーバーヘッドを理解し、同時実行の影響を測定できます。
したがって、「BDRの実行速度が遅い」場合は、次のことをお勧めします。
pgbenchのカスタムテストスクリプトを、稼動システムの問題caseにできる限り近づけてmakeします。 1つのノードでスクリプトを実行して、ベースラインの図を取得します。 1つのノードで行ったのと同じ数のセッションを使用して、稼動で発生する数のノードでスクリプトを実行します。これにより、マルチプルのノードに移動した場合の効果が表示されます。上記2つのテストのセッション数を増やして、競合の増加がアプリケーションに与える影響をプロットできるようにします。テストがレプリケーションの遅延をアカウントするのに十分な長さであることを確認します。テスト中にレプリケーションの遅延が増大しないようにしてください。
通常のPostgresチューニング機能をすべて使用して、アプリケーションの重要な部分の速度を向上させます。
適合性の評価¶
BDRはPostgreSQLと互換性がありますが、すべてのPostgreSQLアプリケーションが分散データベースでの使用に適しているわけではありません。ほとんどのアプリケーションはすでに、または簡単に変更してBDR準拠にすることができます。ユーザーは、自分のアプリケーションをBDR対応セットアップに向けることができる評価アクティビティを実行できます。 BDRは、評価期間中に設定できるいくつかのノブを提供します。これらは、 BDR対応環境でのアプリケーションの適合性を判断するプロセスを支援します。
主キー/レプリカIDの更新の評価¶
現在、 BDRは、PRIMARY KEYがUPDATEオペレーションによって変更される場合、競合解決を実行できません。プライマリキーを更新することは許可されていますが、既存の値と競合しないようにする必要があります。
EDB Postgres Extendedで実行する場合、 BDRは次の構成パラメーターを提供して、テーブルのプライマリキー/レプリカアイデンティティが更新操作の対象となる頻度を評価します。
これらの構成パラメーターは、評価のみに使用する必要があることに注意してください。これらは単一ノードBDRインスタンスで使用できますが、2つ以上のノードが相互に複製されているproductionBDRクラスターでは使用しないでください。実際、評価パラメーターのいずれかがIGNORE以外に設定されている場合、ノードのスタートに失敗するか、新しいノードがクラスターに結合できません。
bdr.assess_update_replica_identity = IGNORE (default) | LOG | WARNING | ERROR
評価期間中にこのパラメータを有効にすると、行のキー/レプリカアイデンティティ値の更新を記録できログ。必要に応じて、このような更新をブロックすることもできます。例えば
CREATE TABLE public.test(g int primary key, h int);
INSERT INTO test VALUES (1, 1);
SET bdr.assess_update_replica_identity TO 'error';
UPDATE test SET g = 4 WHERE g = 1;
ERROR: bdr_assess: update of key/replica identity of table public.test
適用ワーカープロセスは、このパラメータの設定を常に無視します。
テーブルまたはSELECTクエリでのLOCKの使用の評価¶
BDRライタプロセスは通常のユーザセッションとほとんど同じように動作するため、行とテーブルのロックに関する通常のルールにサブジェクトます。これにより、 BDRライタプロセスがユーザトランザクションによって、または相互に保持されているロックを待機する場合があります。
EDB Postgres Extendedで実行する場合、 BDRは次の構成パラメータを提供して、アプリケーションが明示的なロックを取得しているかどうかを評価します。
bdr.assess_lock_statement = IGNORE (default) | LOG | WARNING | ERROR
追跡できるロックには次の2種類があります。
ユーザセッションによる明示的なテーブルレベルロック(LOCK TABLE …)
ユーザセッションによる明示的な行レベルロック(SELECT … FOR UPDATE / FOR SHARE)
評価期間中にこのパラメータを有効にすると、このような明示的なロックアクティビティを追跡(またはブロック)できます。例えば
CREATE TABLE public.test(g int primary key, h int);
INSERT INTO test VALUES (1, 1);
SET bdr.assess_lock_statement TO 'error';
SELECT * FROM test FOR UPDATE;
ERROR: bdr_assess: "SELECT FOR UPDATE" invoked on a BDR node
SELECT * FROM test FOR SHARE;
ERROR: bdr_assess: "SELECT FOR SHARE" invoked on a BDR node
SET bdr.assess_lock_statement TO 'warning';
LOCK TABLE test IN ACCESS SHARE MODE;
WARNING: bdr_assess: "LOCK STATEMENT" invoked on a BDR node