Application use

ユーザの観点からアプリケーションについて学びます。

アプリケーションの動作

BDRは、あるノードで行われた変更の他のノードへの複製をサポートしています。

BDRは、デフォルトで、ソースノードから他のノードへのINSERT、UPDATE、DELETEおよびTRUNCATE操作によるすべての変更をレプリケートします。すべてのトリガーとルールが処理された後、最終的な変更のみが送信されます。例、 INSERT ... ON CONFLICT UPDATE は、オリジンで何が発生したかに応じて、挿入または更新を送信します。更新または削除がゼロ行に影響する場合、変更は送信されません。

INSERTは前提条件なしで複製できます。

他のノードで複製更新と削除については、影響を受ける一意の行を特定できる必要があります。 BDRでは、テーブルに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データ型を使用した列の競合の処理 で説明されているさまざまな回避メカニズムが可能です。

:ref:``bdr.sequences`<bdr.sequences>` で説明されている、シーケンスには特別なハンドリングが必要です。

BYTEA列のバイナリデータは正常にレプリケートされるため、最大ギガバイトのデータの「ブロブ」が許可されます。 PostgreSQLの「ラージオブジェクト」機能の使用は、 BDRでサポートされていません。

ルールはオリジンノードでのみ実行されるため、レプリカに対して有効になっている場合でも、適用中には実行されません。

実表から実表へのみレプリケーションできます。つまり、サブスクリプション側のソースとターゲットのテーブルは、ビュー、マテリアライズドビュー、または外部テーブルではなく、テーブルである必要があります。実テーブル以外のテーブルをレプリケートしようとすると、エラーが発生します。更新可能ビューを介して行われたDML変更は、オリジンの実表に解決されてから、ターゲットの同じベーステーブルに適用され名前。

BDRはテーブルパーティションを透過的にサポートします。つまり、パーティションテーブルをレプリケーションセットに追加し、パーティションを含む変更をダウンストリームに複製します。

デフォルトでは、トリガーはオリジンノードでのみ実行されます。例、 INSERT トリガーはオリジンノードで実行され、ターゲットノードに変更を適用しても無視されます。 ALTER TABLE ... ENABLE ALWAYS TRIGGER を使用して、実行時にオリジンノードとターゲットで複製されたとき(「適用時」)の両方で実行トリガーを指定できます。または、 REPLICA オプションを使用して適用時にのみ実行します:ALTER TABLE ... ENABLE REPLICA TRIGGER 。

一部の種類のトリガーは、テーブルに存在し、現在有効になっている場合でも、適用時に実行されません。実行されないトリガーの種類は次のとおりです。

  • ステートメントレベルのトリガー (FOR EACH STATEMENT )

  • カラムごとのUPDATEトリガー (UPDATE OF column_name [, ...] )

BDRレプリケーションの適用は、システムレベルのデフォルトのsearch_pathを使用します。レプリカトリガー、ストリームトリガー、およびインデックス式関数は、他のsearch_path設定を想定できますが、適用時に実行されます。これを防ぐには、デフォルトのsearch_pathのみを使用してオブジェクト参照を明確に解決するか、常にオブジェクトへの完全修飾参照( スキーマ .objectnameなど)を使用するか、影響を受ける関数にALTER FUNCTION ... SET search_path = ... を使用してファンクションの検索パスを設定します。

BDRは、テキストまたはその他の照合可能なデータ型に関連する問題がないことを前提としています。つまり、使用中のすべての照合はすべてのノードで使用でき、デフォルトの照合順序はすべてのノードで同じです。変更のレプリケーションは等値検索を使用してレプリカID値を見つけるため、一致しない照合順序修飾子で一意性インデックスが明示的に定義されている場合を除き、これは効果がありません。照合可能な式が使用された場合、行フィルターは照合の違いの影響を受ける可能性があります。

PostgreSQLでの非常に長い「トースト」データのBDRハンドリングは、ユーザに対して透過的です。 TOASTの「chunkid」値は、異なるノードの同じ行でも異なる可能性がありますが、問題は発生しません。

レプリカ ID 列が外部としてマークされている場合、 BDRは正しく動作しません。

PostgreSQLは、揮発性関数を含むCHECK()コンストレインを許可します。 BDRは適用時にCHECK()コンストレインを再実行するため、以前と同じ結果が結果れない後続の再実行によりデータが発散します。

BDRは外部キーの使用を制限しません。カスケード FK は許可されます。

レプリケートされないステートメント

次のユーザコマンドはいずれも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() 関数は複製されないため、フェイルオーバーの場合の通知は信頼できません。これは、サーバーがクラッシュしたときにトランザクションがコミットされた場合、フェイルオーバー時に通知が簡単に失われることを意味します。 LISTEN を実行しているアプリケーションは、フェイルオーバーの場合に通知を逃す場合があります。これは標準のPostgreSQLレプリケーションにも当てはまり、 BDRはまだこれを改善していません。 CAMOおよびEager Replicationオプションでは、 NOTIFY SQLコマンドまたはpg_notify() ファンクションは許可されません。

DMLおよびDDLレプリケーション

BDRはDMLステートメントを複製しません。 DMLステートメントによる変更をレプリケートします。例、2つの行を変更したUPDATEは2つの変更を複製しますが、行を削除しなかったDELETEは何も複製しません。これは、 volatile ステートメントの実行結果が複製されることを意味し、ステートメントベースのレプリケーションで発生する可能性のあるノード間の相違がありません。

DDLレプリケーションはDMLとは異なります。 DDLの場合、 BDRはステートメントを複製し、すべてのノードで実行します。したがって、 DROP TABLE IF EXISTS はローカルノードで何も複製しない場合がありますが、 DDLレプリケーションが有効になっている場合、ステートメントは実行のために他のノードに送信されます。詳細については、

DMLおよびDDLレプリケーション を参照してください。

BDRは、混合したDMLステートメントとDDLステートメントが同じトランザクションでも正しく機能する保証に機能します。

異なるリリースレベル間の複製

BDRは、 PostgreSQLのメジャーバージョンが異なるノード間で複製するように設計されています。この機能は、ダウンタイムなしでメジャーバージョンをアップグレードできるように設計されています。

BDRは、 BDRソフトウェアのバージョンが異なるノード間で複製するようにも設計されています。この機能は、ダウンタイムなしでバージョンアップとメンテナンスを行えるように設計されています。

ただし、クラスター内のメジャーバージョンのノードに結合することはできますが、クラスターが新しいプロトコルバージョンを使用している場合、マイナーバージョンのノードを追加することはできません。これはエラーを返します。

これらの機能は両方とも、特定の制限の影響を受ける可能性があります。既知の非互換性については、

Release Notes を参照してください。

違いのあるノード間の複製

デフォルトでは、 DDLはすべてのノードに自動的に送信されます。

DMLおよびDDLレプリケーション で説明されているように、これを手動で制御でき、それを使用してノード全体のデータベーススキーマ間の違いを作成できます。

BDRは、ノード間のマイナー違いでもレプリケーションを続行できるように設計されています。これらの機能は、ダウンタイムなしでアプリケーションスキーマを移行できるように、またはロジカルスタンバイノードでレポートまたはテストを行えるように設計されています。

現在、レプリケーションにはすべてのノードで同じテーブル名前が必要です。将来の機能では、異なるテーブル名間のマッピングが許可される可能性があります。

ターゲット上のパーティションを変更する更新のサポートを含め、パーティションテーブルに複製する通常のテーブルであるソースなど、異なるパーティショニング定義を持つテーブル間で複製できます。動的パーティションルーティングは適用時に実行必要がないため、ソースとターゲットでパーティショニング定義が同じである場合、より高速になります。詳細については、

Replication Sets を参照してください。

デフォルトでは、すべての列が複製されます。 BDRは、列名前に基づいてデータ列を複製します。列の名前は同じでデータ型が異なる場合、それを可能にするキャストが定義されている場合、ソース型からターゲット型にキャストしようとします。

BDRは、列の数が異なるテーブル間の複製をサポートしています。

ターゲットにソースからの列が欠落している場合、 BDRはtarget_column_missing conflictを発生させます。デフォルトの競合リゾルバはignore_if_null です。これにより、NULL以外の値が到着するとエラーがスローされます。または、 ignore の競合リゾルバでノードを構成することもできます。この設定はエラーをスローしませんが、追加の列を黙って無視します。

ターゲットにソースレコードにない追加の列がある場合、 BDRは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は、データベース上のデータをBDRノードおよび非BDRノードと比較するためのツール。比較して最終結果に到達するには、少なくとも2つの接続がニーズです。

LiveCompare 1.3以降、all_bdr_nodes setで設定できます。これにより、クラスター内の個別のノードに関連するすべての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 problem と呼ばれます。

BDRは、行が現在の行、最後の行、またはそれよりも古い行であるかを知ることができません。

同様に、 BDRはテーブル名を使用して変更が再生されるテーブルを識別するため、同じオブジェクト名を作成、削除、および後で再利用するアプリケーションにも同様のABA問題が存在します。

これらの問題により、アプリケーションが従うべきいくつかのシンプルルールが発生します。

  • 行に一意の識別子を使用します(INSERT)。

  • 一意の識別子を変更しないでください(UPDATE)。

  • 削除された一意の識別子を再利用しないでください。

  • ドロップされたオブジェクト名の再利用を避けます。

一般的に、これらのルールを破ると、データの異常や発散につながる可能性があります。アプリケーションは、特定の条件が満たされている限り、これらのルールを破ることができますが、注意してください。異常が発生する可能性は低いですが、不可能ではありません。例、ダウンしたノードを含むすべてのノードでDELETEが再生された限り、行の値を再利用できます。これは通常 1 秒より小さいに発生しますが、1 つのノードで重大な問題が発生して正常に再起動できない場合は、数日かかる場合があります。

タイミングの考慮事項と同期レプリケーション

デフォルトでは非同期であるため、同等なは遅れる場合があり、クライアントがマルチプルのBDRノードに接続したり、それらを切り替えたりして古いデータを読み取ることができます。

このような古い読み取りを防ぐために、クライアントまたはプロキシに

queue wait function が提供されます。

Postgresの同期レプリケーション機能はBDRでも利用できます。さらに、 BDRは、より同期レプリケーションのためのマルチプルのバリアントを提供します。利用可能なすべてのバリアントとそのさまざまなモードの概要と比較については、

Durability and performance options を参照してください。

アプリケーションテスト

他の手法に加えて、次のプログラムを使用してBDRアプリケーションをテストできます。

TPAexec

TPAexecは、Postgres- BDRベースのものを含むリファレンスTPAアーキテクチャを展開するためにEDBが使用するシステムです。

TPAexecには、各リファレンスアーキテクチャのテストスイートが含まれています。また、次のような構文を使用して、TPAクラスターに対して実行するテストのローカルコレクションの作成と管理が簡単になります。

tpaexec test mycluster mytest

開発者は、アプリケーションで想定される主なプロパティを検証する独自のマルチノード スイートの TPAexec テストを作成することを強くお勧めします。

CAMO/フェイルオーバーオプションを使用したpgbench

EDB Postgres Extendedでは、ユーザーがCAMOまたは通常のBDRデプロイメントの使用中にフェイルオーバーテストを実行できるようにpgbenchが拡張ました。次のオプションが追加されました。

- m, --mode=regular|camo|failover
mode in which pgbench should run (default: regular)

- -retry
retry transactions on failover

これらのオプションに加えて、 ノードにフェイルオーバーの同等なの接続情報を指定する必要があります。

  • -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"

このコマンドはカモモードで実行されモード。 node1に接続してテストを実行します。 node1への接続が失われた場合、pgbenchはnode2に接続します。 node2に照会して、進行中のトランザクションのステータスを取得します。中断された処理中のトランザクションは、迷彩モードで再試行されます。

フェイルオーバーモードで --retry が指定されている場合、進行中のトランザクションが再試行されます。このシナリオでは、進行中のトランザクションのステータスを見つける方法はありません。

マルチノードアクセスを備えたisolationtester

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を外部モジュールとして使用して構築されています。インストール時に、 isolationtester バイナリファイルを作成します。これはpg_isolation_regress によって実行され、同時リグレッションテストを実行し、結果を観察します。

pg_isolation_regress はpg_regress に似たツールが、 psqlを使用してテストを実行代わりに、isolationtesterを使用します。 pg_regress と同じコマンドライン引数をすべて受け入れます。マルチプルのホストをパラメーターとして受け入れるように変更されました。次に、ホストconninfoをサーバー名とともにisolationtester バイナリに渡します。分離テスターは、これらのサーバー名を仕様ファイルの各セッションで指定された名前と比較し、それぞれのサーバーで指定されたテストを実行します。

トランザクションが重複するテストを定義するには、カスタム構文のテスト仕様ファイルを使用します。新しいテストを追加するには、仕様ファイルを specs/ サブディレクトリ、予想される出力を expected/ サブディレクトリに追加し、テストの名前をmakefileに追加します。

Isolationtesterは、 libpqを使用してマルチプルの接続を開き、スペックファイルで指定されたテストを実行するプログラムです。 libpq接続文字列は、接続するサーバーとデータベースを指定します。それ以外の場合は、環境変数から派生したデフォルトが使用されます。

仕様は5つの部分で構成され、次のオーダーでテストされます。

server "<name>"

これは、セッションを実行するサーバーの名前を定義します。 0個以上のサーバー"<name>" 指定があります。名前に対応するconninfoは、isolationtesterを実行するコマンドによって提供されます。これはquickstart_isolationtest.md で説明されています。このパートはオプショナル。

setup { <SQL> }

指定されたSQLブロックは、テストを実行する前に、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. セッションごとのセットアップパーツ

  2. 選択されセッションのステップ

1.セッションごとのティアダウン

1.メインの分解スクリプト

選択された各ステップは、そのセッションに関連付けられた接続に送信されます。

前提条件となるすべてのmakeコマンドを実行したBDR環境で分離テストを実行するには、次の手順を実行します。

  1. make isolationcheck-install を実行してisolationtesterサブモジュールをインストールします。

  2. bdr-privateリポジトリから次のコマンドのいずれかを使用して、分離リグレッションテストを実行できます。

make isolationcheck-installcheck make isolationcheck-makecheck

isolationcheck-installcheck を実行するには、2つ以上のpostgresqlサーバーを実行している必要があります。各サーバーのconninfoをBDR makefileの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/ リポジトリのspecs/isolation ディレクトリに追加します。 nbdr-private/ リポジトリのexpected/isolation ディレクトリに.out ファイルを追加します。

次に、 make isolationcheck-installcheck を実行します

Isolationcheck-makecheck は現在、マルチプルのデータベース間でBDRを設定することにより、単一のインスタンスでの分離テストの実行をサポートしています。

次のように、適切なデータベース名とbdrインスタンスのconninfoをBDR makefileのpg_isolation_regress に渡す必要があります。

次に、 make isolationcheck-makecheck を実行します

各ステップには、さらにアクションが実行されるまでブロックするコマンドを含めることができます(ほとんどの場合、他のセッションがブロックを解除するか、デッドロックを発生させます)。この機能を使用するテストでは、有効な順列、つまり、ブロックされたセッションがコマンドを実行しないことを手動で指定する必要があります。テストがそのルールに従わない場合、isolationtesterは300秒後にキャンセルします。キャンセルが機能しない場合、isolationtesterは375秒の待機時間後にクリーンに終了します。無効な順列のテストは避けてmake。分離テストの実行に非常に時間がかかり、有用なテスト目的を果たさないためです。

isolationtesterは、 pg_locks ビューで待機中と表示されているかどうかを確認することにより、コマンドがブロックされたことを認識します。したがって、重量ロックのブロックのみが検出されます。

パフォーマンスのテストとチューニング

BDRを使用すると、マルチプルのマスタノードに書き込みトランザクションを発行できます。これらの書き込みを各ノードに戻すと、パフォーマンスが低下しコスト。

まず、別のノードからの変更を再生するには CPUコスト、 I/Oコスト、およびWALレコードを生成します。 SQLを再実行する必要がないためCPUオーバーヘッドが低いため、リソースの使用は通常オリジナルのトランザクションより小さいます。 UPDATE および DELETE トランザクションの場合、データがキャッシュされていない場合、リプレイ時に I/O コストが発生する場合があります。

次に、変更を再生すると、ローカルのワークロードに対して競合が発生する可能性のあるテーブルレベルおよび行レベルロックが保持されます。競合のないレプリケートデータ型(CRDT)と列レベルの競合検出(CLCD)機能保証、同時更新でも正しい答えが得られますが、通常のロックオーバーヘッドは削除されません。ロックの競合が発生した場合は、更新の競合を回避するか、トランザクションをできるだけ短くしてください。大規模なトランザクションで頻繁に更新される行は、そのトランザクションのパフォーマンスにボトルネックを引き起こします。複雑なアプリケーションでは、スケーラビリティを維持するための配慮が必要です。

パフォーマンスに問題があると思われる場合は、ベンチマーク ツールを使用してパフォーマンステストを開発します。 pgbenchを使用すると、ユースケースに固有のカスタムテストスクリプトを作成できるため、 SQLのオーバーヘッドを理解し、同時実行のインパクトを測定できます。

BDRの実行が遅い場合は、次のことをお勧めします。

1.稼動システムの問題ケースにできるmake近づけて、pgbenchのカスタムテストスクリプトを作成します。

  1. 1つのノードでスクリプトを実行して、ベースラインの数値を取得します。

  2. 1つのノードで実行したのと同じ合計数のセッションを使用して、稼動で発生するのと同じ数のノードでスクリプトを実行します。これは、マルチプルのノードに移動した結果を示しています。

  3. これら2つのテストのセッション数を増やして、アプリケーションでの競合の増加の影響をプロットできるようにします。

  4. テストがレプリケーションの遅延をアカウントに入れるのに十分な長さであることを確認します。

6.テスト中にレプリケーションの遅延が増大していないことを確認します。

通常のPostgresチューニング機能をすべて使用して、アプリケーションの重要な部分の速度を向上させます。

適合性の評価

BDRはPostgreSQLと互換性がありますが、すべてのPostgreSQLアプリケーションが分散データベースでの使用に適しているわけではありません。ほとんどのアプリケーションは、既に、または簡単に変更してBDRに準拠しています。アプリケーションをBDR対応のセットアップにポイントできる評価アクティビティを行うことができます。 BDRは、評価期間中に設定できるいくつかのノブを提供します。これらは、 BDR対応環境でのアプリケーションの適合性を判断するプロセスに役立ちます。

プライマリキー/レプリカアイデンティティの更新の評価

BDRは現在、 UPDATEオペレーションによって PRIMARY KEY が変更された場合の競合解決を実行できません。プライマリキーは更新できますが、既存の値との競合が発生しないことを保証必要があります。

BDRは、テーブルのプライマリキー/レプリカアイデンティティが更新操作の対象となる頻度を評価するための次の設定パラメータを提供します。

これらの構成パラメーターは評価にのみ使用します。単一ノードのBDRインスタンスで使用できますが、2つ以上のノードが相互にレプリケートする稼動BDRクラスターでは使用しないでください。実際、評価パラメーターのいずれかが 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ライタプロセスがユーザトランザクションまたは相互に保持されているロックで待機する場合があります。

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