複数のマスターが関与するレプリケーションセットアップを使用する場合(循環レプリケーションを含みます),異なるマスターが,異なるデータを持つスレーブ上の同じ行を更新しようとする可能性があります。mysql clusterレプリケーションでの競合解決は、特定のマスター上の更新をスレーブで適用すべきかどうかを判断するために使用されるユーザー定義の解決カラムを許可することで、このような競合を解決できます。
MySQL集群でサポートされる競合解決のいくつかのタイプ(旧NDB $ ()
那ndb $ max()
那NDB MAX_DELETE_WIN美元()
)は,このユーザー定义カラムを「时间戳」カラムとして実装ししいます(ただし,このセクションの后半で明するように,このタイプは时间戳
になり得ません)。このタイプの競合解決は、常に、トランザクションごとではなく、行ごとに適用されます。エポックベースの競合解決関数NDB $ epoch()
およびNDB EPOCH_TRANS美元()
は,エポックが複製された順番を比較します(このため,これらの関数はトランザクション型です)。このセクションの後半で説明するように、競合が発生したときにスレーブで解決カラム値を比較するために、さまざまな方法を使用できます。使用する方法はテーブルごとに設定できます。
更新を適用するかどうかを判断するときに解決関数で適切な選択を行えるように,解決カラムに適切な値で正しく移入されることを確認することは,アプリケーションの責任になります。
要件競合解決の準備は,マスターとスレーブの両方で行う必要があります。これらのタスクは次のリストで説明します。
バイナリログを书记マスターマスター,どのどの(すべてすべてカラム,または更新されたカラム送るか指定する必要が.mysql serverでこれを行うは,全,繁体的にはmysqld起
——ndb-log-updated-only
(このセクションの後半で説明します)を適用し,テーブル単位にはmysql.ndb_replication
テーブルのエントリによって実行します(ndb_replicationシステムテーブルを参照してください)。注記非常に大きなカラム(
文本
や斑点
カラムなど)を持つテーブルを复制复制する合书,——ndb-log-updated-only
ははマスターとスレーブスレーブのバイナリログのサイズを减らし,max_allowed_packet.
を超えたことによって可能性のレプリケーション障害回避たりたりする场に役立つことがありありありこの问题に关键词,セクション17.4.1.20”レプリケーションとmax_allowed_packet”を参照してください。
スレーブでは,どのタイプのの合(「最後のタイムスタンプが優先」那「同じタイムスタンプが優先」那「プライマリが優先」那「プライマリが优先し,トランザクションを完结する」,またはまたは何もしないないをするかを指定ががありありこれががありありありはがありありありははははははは
mysql.ndb_replication
システムテーブルを使用して,テーブルごとに行われます(ndb_replicationシステムテーブルを参照してください)。MySQL Cluster NDB 7.4.1以降は読み取り読み取り検出をサポートしています。すなわち,あるクラスタの特のの読み取りと,别のクラスタ同じ行の新闻またはとののののを検出ますの。これには,スレーブで
ndb_log_exclusive_reads
を1に設定することで取得される排他的読み取りロックが必要です。競合している読み取りによって読み取られたすべての行のログが,例外テーブルに記録されます。詳細は,読み取り结合の検出と解决を参照してください。
タイムスタンプベースの競合解決に関数旧NDB $ ()
那ndb $ max()
,およびNDB MAX_DELETE_WIN美元()
をを用する综合,更新を「タイムスタンプ」カラムとして指定するために使用されるカラムを参照するのが一般的です。ただし,このカラムのデータ型は时间戳
にしないでください。このデータ型はINT
(整数
)または长整型数字
にしてください。また,「时间戳」カラムは无符号
および非空
にしてください。
このセクションの後半で説明するNDB $ epoch()
およびNDB EPOCH_TRANS美元()
関数は,プライマリおよびセカンダリMySQL集群で適用されるレプリケーションエポックの相対順序を比較することで機能し,タイプスタンプを利用しません。
マスターカラムの制御「前」のイメージおよび「后」のイメージ(すなわち,更新がが用されるとと后のテーブル状态のののて,更新の作品をできます。一流的に主キーでテーブルを更するをををするする。「前」のイメージはそれほど問題はありません。ただし,更新ごとにレプリケーションスレーブで更新された値を使用するかどうかを指定する必要がある場合は,両方のイメージがマスターのバイナリログに書き込まれることを確認する必要があります。このセクションの後半で説明するように,これはmysqldの——ndb-log-update-as-write
オプションで実行されます。
行全体のロギングを行うか,更新されたカラムだけのロギングを行うかは,MySQLサーバーが起動されたときに決まり,オンラインでは変更できません。異なるロギングオプションを使用して,mysqldを再再动词,新闻mysqldインスタンスを动弹する必要があります。
すべてまたは一部の行のロギング(——ndb-log-updated-onlyオプション)
コマンド行形式 | ——ndb-log-updated-only |
---|---|
システム変数 | ndb_log_updated_only |
スコープ | グローバル |
动词的 | はい |
型 | ブール |
デフォルト | 在 |
競合解決のために,行のログを取る基本的な方法は2つあり,その方法はmysqldの——ndb-log-updated-only
オプションを設定すると指定されます。
行胸部のログをを取得ます
更新されたカラムデータ(すなわち,値が设定されたカラムカラムカラムを取りますこの値が実际変更されかどうかにははません。
通常,更新されたカラムのみのログを取るだけで十分(しかも效率的)です。ただし,すべての行のログを取る必要がある场合,——ndb-log-updated-only
を0.
または从
に設定すると,これを実行できます。
--ndb-log-update-as-writesオプション:変更されたデータを新としてログを取得
コマンド行形式 | ——ndb-log-update-as-write |
---|---|
システム変数 | ndb_log_update_as_write |
スコープ | グローバル |
动词的 | はい |
型 | ブール |
デフォルト | 在 |
MySQL Serverの.——ndb-log-update-as-write
オプションの设定で,ロギングが「前」のイメージがある状態で実行されるか,ない状態で実行されるかを指定します。競合解決はMySQL服务器の更新ハンドラで行われるため,更新は更新であって書き込みではないようにマスターでのロギングを制御する必要があります。すなわち,更新は,新しい行の書き込みではなく,(更新が既存の行を置き換える場合でも)既存の行の変更として処理されます。このオプションはデフォルトではオンです。つまり,更新は書き込みとして処理されます。(つまりデフォルトでは、更新はupdate_row
イベントとしてではなく,write_row
イベントとしてバイナリログに書き込まれます)。
オプションオプションをオフににするに,マスターマスターmysqldを--ndb-log-update-as-write = 0
または——ndb-log-update-as-write =了
详细は,これは,これは,NDBから別のストレージエンジンへのレプリケーションおよびNDBから非トランザクションストレージエンジンへのレプリケーションを参照してください。
競合解決の制御通常,競合解決は競合が発生する可能性のあるサーバーで有効になっています。ロギング方法の選択と同様に,mysql.ndb_replication
テーブルテーブルのエントリによってによって效されます。
ndb_replicationシステムテーブル综合解决を有象ににはは,竞合出のタイプ,および使使解决のによって,スレーブ,またはまたは両のmysql.
システムデータベースにndb_replication.
テーブルテーブル,ロギングは,ロギングととするこのさ,レプリケーションれ,レプリケーション,れ,れ持ち,但れれ,レプリケーションテーブル持ちこのテーブル単位テーブル持ち。ndb_replication.
が作成され,竞合を解决すべきサーバー上の制御情报が格纳されます。スレーブでローカルにデータを変更することもできる単纯なマスタースレーブのセットアップでは,一般的にこれはスレーブになります。より复雑なマスターマスター(2方向)レプリケーションレプリケーションキーマで,これこれ关键词すべてのマスターなります。mysql.ndb_replication
の各行はされるに対応し,対象テーブルに対するログログ取得方法(すなわち,もしもし合)(すなわち,もし含合物発したに,どの结合相关有关部を使か)mysql.ndb_replication
テーブルテーブルの定义はは次のとおりとおり
mysql创建表。ndb_replication.(dbVARBINARY(63), table_name VARBINARY(63), server_id INT UNSIGNED, binlog_type INT UNSIGNED, conflict_fn VARBINARY(128), PRIMARY KEY USING HASH (db, table_name, server_id) ) ENGINE=NDB PARTITION BY KEY(db,table_name);
このこのテーブルのカラム,次次のいくつかのパラグラフで明します。
db複製されるテーブルを含むデータベースの名前です。ワイルドカード_
と%
のどちらか,またはそのその方を,データベース名の一部としてでき。マッチングは,喜欢
演算子に対して実装されたマッチングに似ています。
table_name.复制されるテーブルテーブル名前。テーブル名に,ワイルドカード_
と%
のどちらか,またはその両方を含めることができます。マッチングは,喜欢
演算子に対して実装されたマッチングに似ています。
server_idテーブルが存在するMySQLインスタンス(SQLノード)の一意のサーバーIDです。
binlog_type使用されるバイナリロギングのタイプです。これは,次の表に示すように指定されます。
値 | 内部値 | 说明 |
---|---|---|
0. | NBT_DEFAULT |
サーバーのデフォルトを使用します |
1 | NBT_NO_LOGGING |
バイナリログにこのテーブルの记录行いません |
2 | NBT_UPDATED_ONLY |
更新された属性のみが記録されます |
3. | NBT_FULL |
更新されない場合でも,行全体を記録します(MySQLサーバーのデフォルトの動作) |
4. | nbt_use_update. |
(nbt_updated_only_use_update. およびnbt_full_use_update. の値の生成のみを行い,単独では使用しません) |
5. | [不曾用过] | --- |
6. | nbt_updated_only_use_update. (nbt_updated_only |nbt_use_update. に相当) |
値が変更されててないないないでも,更新された属性を使し |
7. | nbt_full_use_update. (nbt_full |nbt_use_update. に相当) |
値が変更されていない場合でも,行全体を使用します |
冲突_FN.適用される競合解決関数です。この関数は那次のリストに示されたいずれかの関数として指定する必要があります。
これらの关节,次次のいくつかのので说说しし
NDB老美元(column_name)column_name
の値がマスターとスレーブで同じである場合,更新が適用されます。同じでないと,更新はスレーブに適用されず,例外がログに書き込まれます。これは,次の擬似コードで説明します。
如果 (master_old_column_value==.slave_current_column_value) apply_update ();其他log_exception ();
この関数は「同じ値が优先」结合解决に使ますますますますのの解决で,误っ误っマスターから更でがスレーブ适适适れれ。
マスターの「前」のイメージのカラム値がこの関数で使用されます。
ndb $ max(column_name)マスターからの特价の行の「タイムスタンプ」カラム値がスレーブでの値より高い场合は,适用されます。高くない场合は,スレーブで适用されません。これは,次の拟似コードで说明します。
如果 (master_new_column_value.>slave_current_column_value) apply_update ();
この関数は「もっとも大きいタイムスタンプが優先」競合解決に使用できます。このタイプの競合解決では、競合が発生した場合、最後に更新された行のバージョンが存続するバージョンになります。
マスターの「后」のイメージからのカラム値が关键词关键词。
NDB MAX_DELETE_WIN美元(column_name)これはndb $ max()
のバリエーションです。タイムスタンプは削除操作に使用できないため、ndb $ max()
を使用する削除は,実際には美元NDB老
として処理されます。ただしユースケースによっては,これは最適ではありません。NDB MAX_DELETE_WIN美元()
の場合,マスターから既存の行を追加または更新する特定行の「タイムスタンプ」カラム値が,スレーブでの値より大きい場合に適用されます。ただし,削除操作は常に値が高いものとして処理されます。これは,次の擬似コードで説明します。
如果((master_new_column_value.>slave_current_column_value) | |operation.type= =“删除”)apply_update ();
この関数は「もっとも大厦タイムスタンプ,削除が优先」競合解決に使用できます。このタイプの競合解決では、競合が発生した場合、削除された行のバージョン、または (そうでなければ) 最後に更新された行のバージョンが存続するバージョンになります。
ndb $ max()
とと同様,マスターマスター「后」のイメージからのカラム値が,この関数で使用される値です。
NDB时代()美元およびNDB EPOCH_TRANS美元()NDB $ epoch()
关数は,复制されたエポックが,スレーブで発生した変更に关连してスレーブのMySQL集群で适用される顺番を追迹します。この相対的な顺番は,スレーブで発生した変更が,ローカルに発生した変更と同时に起こっかかかかどうどうどうが生物する可能性あるかをを判断にに使れするににれれれ。
NDB $ epoch()
の説明で従う内容のほとんどは,NDB EPOCH_TRANS美元()
にも適用されます。例外は本文に記載されています。
NDB $ epoch()
は非対象であり2つのクラスタの循環レプリケーション構成の一方のMySQL集群で動作します(「アクティブアクティブ」レプリケーションと呼ぶこともありありますここ,プライマリプライマリ动作すると,セカンダリとして动作するもうのクラスタの言及します検出クラスタスレーブ竞ます検出検出を担いの。一方を担います。一方,セカンダリのスレーブは。结合の検出またはまたはには关键词。
プライマリのスレーブが競合を検出すると,競合を相殺するためにスレーブ自身のバイナリログにイベントを挿入します。これにより,最終的にセカンダリのMySQL集群はプライマリに合うように再調整され,プライマリとセカンダリの不一致が回避されます。この補正と再調整のメカニズムには,プライマリのMySQL集群がセカンダリとの競合に常に勝る必要があります。つまり,競合が発生した場合,セカンダリからの変更ではなく,プライマリの変更が常に使用される必要があります。この「プライマリが常に胜つ」ルールには次の意味が込められています。
プライマリでいったんコミットさと,データを変更する操作用は,整合の検出と解决取り消さたりたり,ロールバックされししませませませませませ
プライマリから読み取られたデータには一貫性があります。プライマリでコミットされた変更(ローカルまたはスレーブから)は,あとで取り消せません。
セカンダリでデータを変更する操作は,競合が発生しているとプライマリが判断した場合,あとで取り消される可能性があります。
セカンダリで読み取られた各行は,常に自己矛盾がなく,各行は,セカンダリでコミットされた状态,またはプライマリでコミットされた状态のいずれかを常に反映しています。
NDB EPOCH_TRANS美元()
の结合,これは一时的な状态,NDB $ epoch()
の場合は,永続的な状態となることがあります。十分な期間,競合が発生しないと,セカンダリのMySQL集群のすべてのデータは(最終的に)プライマリのデータに一致します。
NDB $ epoch()
およびNDB EPOCH_TRANS美元()
では,競合を検出するためにユーザースキーマを修正したり,アプリケーションを変更したりする必要はありません。ただし,システム全体が指定された制限内で動作することを検証するために,使用するスキーマ,および使用するアクセスパターンを考慮する必要があります。
NDB $ epoch()
およびNDB EPOCH_TRANS美元()
関数はオプションのパラメータを取ることができます。これはエポックの下位 32 ビットを表すために使用されるビット数であり、次の値以上に設定してください。
CEIL(LOG2(timebetweenglobalcheckpoint / TimeBetweenEpochs), 1)
これらの構成パラメータがデフォルト値(それぞれ,2000および100ミリ秒)である場合,値は5バイトになり,デフォルト値(6)で十分です。ただし,ほかの値がTimeBetweenGlobalCheckpoints
那TimeBetweenEpochs
,またはまたは両方针使される场を除きますががなる性とますと値大厦すぎると,値値大大すぎると,データベース内になスペースが可以
このセクションの別のところで説明するように,例外テーブルが同じ例外テーブルのスキーマルールに従って定義された場合,NDB $ epoch()
とNDB EPOCH_TRANS美元()
の両方はははしいる行ののを关键词NDB老美元(column_name)を参照してください)。例外テーブルを使用するテーブルを作成する前に、例外テーブルを作成する必要があります。
NDB $ epoch()
およびNDB EPOCH_TRANS美元()
は,このセクションで説明したほかの競合検出関数と同様に,mysql.ndb_replication
テーブルに关键词するを含めることで起起起されれ(ndb_replicationシステムテーブルをを参照してくださいくださいシナリオででのプライマリととセカンダリのののclusterclusterのロール,mysql.ndb_replication
テーブルのエントリによってすべて決定されます。
NDB $ epoch()
およびNDB EPOCH_TRANS美元()
で使使されるれるれる検出は非同であるであるである,プライマリスレーブプライマリスレーブセカンダリスレーブのserver_id
エントリで异なる値を使使必要がます。
MySQL集群NDB 7.3.6より前では,删除
操作間の競合は更新
操作物综合とと同様同様さ处さ,同じ同じエポック内のははししていると见なされいましたたたましまし.mysql群体NDB 7.3.6以降では,删除
操作間の競合だけではNDB $ epoch()
またはNDB EPOCH_TRANS美元()
を使用して競合を起動するには十分でなく,エポック内の相対的な配置は重要ではありません。(错误“18454499)
NDB时代()美元およびNDB EPOCH_TRANS美元()ステータス変数NDB $ epoch()
およびNDB EPOCH_TRANS美元()
の競合検出をモニターするために,いくつかのステータス変数を使用できます。このスレーブがNdb_conflict_fn_epoch
システムステータス変数の现处于のの値で最后にに再再再されたNDB $ epoch()
によって競合中であると検出された行数がわかります。
ndb_conflict_fn_poch_trans.
はNDB EPOCH_TRANS美元()
によって競合中であると直接検出された行数を示します。実際に再構成された行数(行のメンバーシップ,またはほかの競合する行と同じトランザクションの依存関係によって影響を受ける行を含みます)は,ndb_conflict_trans_row_reject_count.
によって取得されます。
详细については,セクション18.3.4.4“MySQL集群のステータス変数”を参照してください。
NDB $ epoch()の制约NDB $ epoch()
をを用してて合并検出実する场合金,在次の制约适适ますれます。
TimeBetweenEpochs
(デフォルト:100ミリ秒)に比例する精度で,競合がMySQL集群のエポック境界を使用して検出されます。最小競合ウィンドウは,両方のクラスタの同じデータへの並列更新が常に競合を報告する最小時間です。これは,常にゼロでない時間であり,2 *(延迟+排队+时间间隔)
ににほぼ比例しこれこれ,TimeBetweenEpochs
にデフォルトを仮定し,またクラスタ间の待机时间(およびおよびイング遅延)を无视して,最小结合ウィンドウ约约この秒であることを意味ししします最ウィンドウウィンドウはしします最ウィンドウウィンドウはしますます秒ウィンドウははししさ秒ウィンドウはは「競争」パターンを調べるときに考慮してください。NDB $ epoch()
およびNDB EPOCH_TRANS美元()
关数を使用するテーブルには,追加ストレージが必要です。关数に渡される値によって,1行当たり1ビットから32ビットのスペースが必要です。削除操作の競合は,プライマリとセカンダリの間の相違につながる可能性があります。行が両方のクラスタ上で同時に削除される場合,競合は検出できますが,行が削除されるために競合は記録されません。すなわち,後続の再編成操作の伝播中にさらなる競合は検出されず,不一致になる可能性があります。
削除は外部シリアライズか,1つのクラスタだけにルーティングしてくださいください。また,行の削除の间ののを追迹ように,このような削除削除削除続くでトランザクションごとに个々の插入トランザクションしてください。これこれは,アプリケーションの変更が必要となる合。
競合の検出に
NDB $ epoch()
またはNDB EPOCH_TRANS美元()
を使用する場合,循環「アクティブアクティブ」構成のMySQL集群が2つの場合のみがサポートされています。斑点
または文本
カラムを持つテーブルは,現在NDB $ epoch()
またはNDB EPOCH_TRANS美元()
ではサポートされていません。
NDB EPOCH_TRANS美元()NDB EPOCH_TRANS美元()
はNDB $ epoch()
关关を张したものです。「プライマリがすべてに优先」ルール(NDB时代()美元およびNDB EPOCH_TRANS美元()を参照してください)を使用する同じ方法で竞合が検出され,处理されますが,竞合が発生した同じトランザクションで更新されたその他の行も竞合していると见なす,という条件が追加されます。つまり,NDB $ epoch()
がセカンダリの競合している各行を再編成するのに対して,NDB EPOCH_TRANS美元()
は结合しているトランザクションを再成します。
また,競合しているトランザクションへの依存が検出されたトランザクションも競合していると見なされ,これらの依存関係はセカンダリクラスタのバイナリログの内容によって判断されます。バイナリログにはデータ変更操作だけ(挿入,更新,削除)が含まれるため,重複するデータの変更だけがトランザクション間の依存関係の判断に使用されます。
NDB EPOCH_TRANS美元()
はNDB $ epoch()
とと同じ条件とと制约に,さらにバージョン2のバイナリログ行イベント使され(——log-bin-use-v1-row-events
は0に等しい)。これにより,バイナリログ内のイベント当たり2バイトのストレージオーバーヘッドが加わります。また,すべてのトランザクションIDをセカンダリのバイナリログに記録する必要があり(--ndb-log-transaction-id
オプション),このため,可変のヘッド(行为大大13バイト)がが加入ます。
NDB时代()美元およびNDB EPOCH_TRANS美元()を参照してください。
零対応するテーブルに競合解決を使用しないことを示します。
ステータス杂记サーバーステータス変数ndb_conflict_fn_max.
は,mysqldが最后にに起されてから,「もっとも大きいタイムスタンプが優先」競合解決によって現在のSQLノードに行が適用されなかった回数のカウントを示します。
指定されたmysqldが最後に再起動されたあとに「同じタイムスタンプが優先」競合解決の結果として行が挿入されなかった回数は,グローバルステータス変数Ndb_conflict_fn_old
によって取得されます。Ndb_conflict_fn_old
をインクリメントすること以外に,このセクションの後半の説明のように,使用されなかった行の主キーは例外テーブルに挿入されます。
综合解决の外テーブル旧NDB $ ()
结合解决关关数を使に,このタイプのの解决解决される各NDB
テーブルに対応する例外テーブルも作成する必要があります。これは,NDB $ epoch()
またはNDB EPOCH_TRANS美元()
をを使するするに当てはまります。このこのの名前,竞合出が适はさテーブル名前$前
(たとえば,元のテーブルの名前がmytable
であるである合,対応する户外テーブル名前はmytable $前
になります)MySQL集群NDB 7.4.1より前では,このテーブルは次のように作成されます。
创建表original_table$ ex(server_id int unsigned,master_server_id int unsigned,master_epoch bigint unsigned,count int unsigned,Original_table_pk_columns., (additional_columns,] PRIMARY KEY(server_id, master_server_id, master_epoch, count)
MySQL集群NDB 7.4.1以降では,例外のタイプ,原因,および元のトランザクションに関する情報を提供するオプションカラムを含む,拡張した例外テーブル定義をサポートしています。これらのバージョンでは,例外テーブルを作成する構文は次のとおりです。
Create Table Original_Table $ EX([NDB $] server_id int unsigned,[ndb $] master_server_id int unsigned,[ndb $] master_epoch bigint unsigned,[ndb $] count int unsigned,[ndb $ op_type enum('write_row','update_row','delete_row','refresh_row','read_row')不是null,] [ndb $ cft_cause enum('row_does_not_exist','row_already_exist','data_in_confligt','trans_in_conflict'),'trans_in_conflict')不是null,] [ndb $ odor_transid bigint unsigned不是null,]Original_table_pk_columns., (orig_table_column|orig_table_column$旧|orig_table_column新的美元][additional_columns,]主键([NDB$]server_id, [NDB$]master_server_id, [NDB$]master_epoch, [NDB$]count)引擎=NDB;
最初の4つのカラムが必須です。最初の4つのカラムの名前,および元のテーブルの主キーカラムに一致するカラムの名前は重要ではありません。ただし,わかりやすさと一貫性のため,server_id
那master_server_id
那master_poch.
,および数
のカラムについてはここで示した名前を使用し,元のテーブルの主キーのカラムに一致するカラムについては元のテーブルと同じ名前を使用することをお勧めします。
MySQL Cluster NDB 7.4.1以降では,户外テーブルがこのセクションの后半说明したたのオプションNDB OP_TYPE美元
那NDB CFT_CAUSE美元
,またはNDB ORIG_TRANSID美元
を使用している場合,各必須カラムもプリフィクスNDB美元
を使使て名前付ける必要があり。必要に応じて,オプションカラムを定义しないないでもNDB美元
ただしこの场场をの付けるを付けるをを付ける付ける付ける付けるますありますますますますますますますますますありありますますますますありますますますありますますますますますますますありますありますありありますありががありますますありますますますますますががありますますますますがありますががががますありありががががががます必要ありますありありありありありありありありありありあり
このカラムに続き,元のテーブルの主キーを構成するカラムは,元のテーブルの主キーの定義に使用される順番でコピーをしてください。元のテーブルの主キーカラムを複製するカラムのデータ型は,元のカラムと同じ(または大きい)データ型にしてください。MySQL集群NDB 7.3以前では,例外テーブルの主キーはカラム対カラムで再作成する必要があります。MySQL集群NDB 7.4.1以降では,主キーカラムのサブセットを使用することも可能です。
使用するmysql集群のバージョンにかかわらず,户外テーブルはNDB
ストレージエンジンを使用する必要があります。(例外テーブルで旧NDB $ ()
を使用する例は,このセクションの後半で示します)。
オプションで,コピーされる主キーカラムのあとに追加カラムを定义できますが,その前に追加カラムを定义することはできません。このような追加カラムは非空
にはできません.mysql群体ndb 7.4.1以降では,事前定义の3つの追カラムNDB OP_TYPE美元
那NDB CFT_CAUSE美元
,およびNDB ORIG_TRANSID美元
(次のいくつかのパラグラフで説明します)をサポートしています。
NDB OP_TYPE美元
:このカラムは,复合の原因となるの种类をするためできます。
Ndb $ op_type enum (' write_row ', ' update_row ', ' delete_row ', ' refresh_row ', ' read_row ') not null
write_row.
那update_row.
,およびdelete_row.
作者:王莹莹,王莹,骁勇善战REFRESH_ROW
作者王莹,王莹,美联储杂志read_row.
操作业,排他的行ロックを,ユーザー定义される,ユーザーユーザー定义される追迹。
NDB CFT_CAUSE美元
:登録された競合の原因を示すオプションカラムNDB CFT_CAUSE美元
を定義できます。このカラムは那使用する場合、ここで示すように定義されます。
NDB $ CFT_CAUSE ENUM( 'ROW_DOES_NOT_EXIST', 'ROW_ALREADY_EXISTS', 'DATA_IN_CONFLICT', 'TRANS_IN_CONFLICT')NOT NULL
ROW_DOES_NOT_EXIST
はupdate_row.
およびwrite_row.
操作の原因として報告できます。row_already_exists.
はwrite_row.
イベントに対して報告できます。DATA_IN_CONFLICT
は,行ベースの综合关关节综合ををししたたにににににににににTRANS_IN_CONFLICT
は,トランザクション结合关关数が全体にに属するすべてのの操拒否するする场ににれれれれれれれれれ
NDB ORIG_TRANSID美元
:NDB ORIG_TRANSID美元
カラムは,使用する場合,元のトランザクションのIDを格納します。このカラムは次のように定義されます。
ndb $ odor_transid bigint unsigned not null
NDB ORIG_TRANSID美元
はNDB
によって生成される64ビットの値です。この値は,同じまたは异なる例外テーブルから同じ竞合トランザクションに属する复数の例外テーブルのエントリを相互に关连付けるために使用されます。
MySQL Cluster Ndb 7.4.1以降では,更新および削除の作用(すなわち,delete_row.
イベントを含む含む作品です,元のテーブルの主キーのではないではない追参照名前を
またはcolname
$旧
。colname
新的美元
参照の古い値にますます。colname
$旧
は插入および更新の作用(言い换えると,colname
新的美元write_row.
イベント,update_row.
イベント,または両方のタイプのイベントを使用する操作です)で新しい値の参照に使用できます。竞合中の操作は特定の非主キー参照カラムに値は指定されませんが,例外テーブルの行には零
またはまたはそのカラムに対して定义されたデフォルト値のいずれ格式されます。
mysql.ndb_replication
テーブルは,データデータがレプリケーションにセットアップされたに読み取られる,复制されるテーブルにする,复制されるががは,复制されるがが作物前にmysql.ndb_replication
に挿入する必要があります。
例
この例では,セクション18.6.5”レプリケーションのためのMySQL集群の準備”および「18.6.6「MYSQL群集レプリケーションの起起动(レプリケーションチャネルが1つ)」〖mysql集群〗,すでにmysql集群レプリケーションレプリケーション正式に机能してものものししします。
ndb $ max()の例「タイムスタンプ」としてカラムmycol
を使用して,テーブルtest.t1.
で「もっとも大きいタイムスタンプが優先」競合解決を有効にするものとします。これは,次のステップで実行できます。
——ndb-log-update-as-write =了
でマスターのmysqldを起動したことを確認します。マスターで,
插
ステートメントを実行します。插入mysql。ndb_replication.VALUES ('test', 't1', 0, NULL, 'NDB$MAX(mycol)');
server_id
に0を挿入すると,このテーブルにアクセスするすべてのSQLノードが競合解決を使用します。特定のmysqldだけだけ综合性解决使する合并は,実际のサーバーidをし。binlog_type
カラムに零
をを插入する,0(NBT_DEFAULT
)の挿入と同じ効果があり,サーバーのデフォルトが使用されます。test.t1.
テーブルを作物成し。创建表test.t1(列mycol INT无符号,列)引擎= NDB;
これで,このテーブルに更新が行われる,整合解决が适适,
mycol
のもっとも大厦値をのバージョンバージョンスレーブに书架れます。
ほかのbinlog_type
オプション(nbt_updated_only_use_update.
など)は,コマンド行オプションを使する,ndb_replication.
テーブルを使用してマスターでロギングを制御するために使用してください。
NDB老()美元の例NDB
テーブル(ここで定義されたテーブルなど)が複製中であり,このテーブルへの更新に「同じタイムスタンプが優先」競合解決を有効にするものとします。
创建表test.t2(一个int unsigned not null,b char(25)没有null,列, mycol INT UNSIGNED NOT NULL,列,主键PK(A,B))引擎= NDB;
ここで示す順番で,次のステップが必要です。
まず(
test.t2
を作物成前に),ここで示すようにmysql.ndb_replication
テーブルに行を挿入する必要があります。插入mysql。ndb_replication.VALUES ('test', 't2', 0, NULL, 'NDB$OLD(mycol)');
binlog_type
カラムに可能な値は,このセクションの前半に示しています。値“美元NDB老(mycol)”
を冲突_FN.
カラムに插入してください。test.t2
に対応する户外テーブルをしで示すテーブル作物ステートメントすべての必须カラムを含み,テーブルのカラムのと,テーブルの主キーの前,加加カラムカラムする必要ににがありあり。CREATE TABLE test.t2 $ EX(SERVER_ID SMALLINT UNSIGNED,master_server_id INT UNSIGNED,master_epoch BIGINT UNSIGNED,算上BIGINT UNSIGNED,一个INT UNSIGNED NOT NULL,B CHAR(25)NOT NULL,[additional_columns,] PRIMARY KEY(server_id, master_server_id, master_epoch, count)
MySQL Cluster NDB 7.4.1以降では,特点ののに対するタイプ,原因,および元のトランザクショントランザクション关键词ののををことができますにテーブルのの主キーカラムにするするカラムを提供する必要もこれらありのバージョンで,次のようでは,次のように户。
create table test.t2 $ ex(ndb $ server_id smallint unsigned,ndb $ master_server_id int unsigned,ndb $ master_epoch bigint unsigned,ndb $ count bigint unsigned,一个int unsigned not null,ndb $ op_type enum('write_row','update_row''update_row','delete_row','refresh_row','read_row')不是null,ndb $ cft_cause enum('row_does_not_exist','row_already_exist','data_in_conflic','trans_in_conflict'),'trans_in_conflict')不是null,ndb $ odor_transid bigint unsigned not null,[additional_columns,]主键(NDB$server_id, NDB$master_server_id, NDB$master_epoch, NDB$count) ENGINE=NDB;
少なくとも1つのカラム
NDB OP_TYPE美元
那NDB CFT_CAUSE美元
,またはNDB ORIG_TRANSID美元
をテーブル定義に含めたため,4つの必須カラムにNDB美元
プリフィクスが必要です。前に示したように,テーブル
test.t2
を作成します。
旧NDB $ ()
をのステップに必要ありありようなごとに。このようなテーブルに。mysql.ndb_replication
に対応する行があり,複製されているテーブルと同じデータベースに例外テーブルがある必要があります。
読み取り结合の検出と解决MySQL Cluster NDB 7.4.1以降では,読み取り読み取り作品のをサポートしいます。これにより,あるクラスタの特征のの読み取り,别のクラスタ同じ同じの新闻削除とのででをまたはことが,循环レプリケーションセットアップで可になります。この例では,员工
および部门
テーブルを使用してシナリオをモデル化します。このシナリオでは、ある従業員がある部門から別の部門にマスタークラスタ (以降、クラスタ一种と呼びます)上行动弹し,一方,スレーブクラスタ(以降,B.
データテーブルは次のsqlステートメントで作用成さました。
#员工表创建表员工(ID INT主键,名称varchar(2000),dept int not null)引擎= ndb;#部门表创建表部(ID INT主键,名称varchar(2000),成员int)引擎= ndb;
2つのテーブルの内容,次の选择
ステートメントの出力(一)部に示される行を含みます。
mysql> SELECT id, name, dept FROM employee;+---------------+------+ | id | |部门名称 | +------+--------+------+ ...| 998 | Mike | 3 | | 999 | Joe | 3 | | 1000 | Mary | 3 |…+------+--------+------+ mysql >选择id、名称、部门成员;+-----+-------------+---------+ | id | |成员名称 | +-----+-------------+---------+ ...| 3 |老项目| 24 |…+-----+-------------+---------+
4つの必须カラム(これらはこのテーブルの主キーに使用されます),操作タイプと原因用のオプションカラム,および元のテーブルの主キーカラムを含んだ,ここで示したSQLステートメントで作成された例外テーブルをを使用ししいるいるものします。
创建表employee$EX (NDB$server_id INT UNSIGNED, NDB$master_server_id INT UNSIGNED, NDB$master_epoch BIGINT UNSIGNED, NDB$count INT UNSIGNED, NDB$OP_TYPE ENUM('WRITE_ROW','UPDATE_ROW', 'DELETE_ROW', 'REFRESH_ROW','READ_ROW') NOT NULL, NDB$CFT_CAUSE ENUM('ROW_DOES_NOT_EXIST', 'ROW_ALREADY_EXISTS', 'DATA_IN_CONFLICT','TRANS_IN_CONFLICT') NOT NULL, id INT NOT NULL, PRIMARY KEY(NDB$server_id, NDB$master_server_id, NDB$master_epoch, NDB$count)) ENGINE=NDB;
2つのクラスタ上で同時に2つのトランザクションが発生するものとします。クラスタ一种では,新しい部门を作品成して,従业主番号999をその部门に移ます。次のsqlステートメントを使使。
开始;INSERT INTO department VALUES(4, "新项目",1);UPDATE员工SET dept = 4 WHERE id = 999;提交;
同時にクラスタB.では,次に示すよう,别のトランザクションが员工
から読み取ります。
开始;查询id = 999的员工的姓名更新部门设置成员=成员 - 1 ID = 3;犯罪;
结合しているは,通常は结合解决で検出ささませんません検出は,结合が読み取り(选择
)と更新作品のでで生している.mysql群体NDB 7.4.1以降では,スレーブスレーブで放
ndb_log_exclusive_reads
= 1
を実行することで,この问题を回避できます。この方法で排他的読み取りロックを取得すると,マスターでの行の読み取りに,スレーブクラスタで竞合解决が必要であることを示すフラグが付きます。これらのトランザクションのロギングの前にこの方法で排他排他をををににとととするするするするB.での読み取りが追跡され,解決のためにクラスタ一种に送られます。企业员の行ののがされ,クラスタB.でのトランザクションは中止されます。
競合は,ここで示すように(クラスタ一种にある)例外テーブルにread_row.
操作业として登录れます(操作タイプの明については,综合解决の外テーブルを参照してください)。
mysql> SELECT id, NDB$OP_TYPE, NDB$CFT_CAUSE FROM employee$EX;+-------+-------------+-------------------+ | id | NDB OP_TYPE美元| NDB CFT_CAUSE美元 | +-------+-------------+-------------------+ ...| 999 | READ_ROW | TRANS_IN_CONFLICT | +-------+-------------+-------------------+
読み取り在操操検出れたすなわち,ここで示すに,クラスタ一种B.での复数行の読み取りとの间で竞合の影响を调べることで,例外テーブルに同じ竞合に起因する复数の行のログが取られる场合があります。ここで,クラスタ一种で実行されるトランザクションを示します。
开始;INSERT INTO department VALUES(4, "新项目",0);更新员工设置部门= 4其中Dept = 3;SELECT COUNT(*) INTO @count FROM employee WHERE dept = 4;UPDATE department SET members = @count WHERE id = 4;提交;
同時に,ここで示すステートメントを含むトランザクションがクラスタB.で実行されます。
SET ndb_log_exclusive_reads = 1;#如果没有启用,必须设置…开始;SELECT COUNT(*) INTO @count FROM employee WHERE dept = 3 FOR UPDATE;UPDATE department SET members = @count WHERE id = 3;提交;
この结合,ここで示すよう,2番目のトランザクションの选择
の中の在哪里
条件に一流する3つすべての行がれ,户外テーブルでフラグが付けられます。
mysql> SELECT id, NDB$OP_TYPE, NDB$CFT_CAUSE FROM employee$EX;+-------+-------------+-------------------+ | id | NDB OP_TYPE美元| NDB CFT_CAUSE美元 | +-------+-------------+-------------------+ ...| 998 | read_row | trans_in_conflict | | 999 | read_row | trans_in_conflict | | 1000 | read_row | trans_in_conflict |…+-------+-------------+-------------------+
読み取りの追跡は,存在する行だけに基づいて行われます。特定条件の追跡に基づく読み取りは,検出された行だけと竞合し,インターリーブされたトランザクションで插入された行とは竞合しません。これは,MySQL集群の1つのインスタンスで排他的行ロックが実行される方法に类似しています。