web-dev-qa-db-ja.com

MySQLレプリケーションクエリ-主キーの必要性

MySQLレプリケーション(マスター-スレーブ)については、いくつか疑問があります。レプリケーションが適切に機能するためには、テーブルがプライマリクエリを持つことが必須ですか?

参照 このPerconaリンク 上記の質問について言及しているように主キーまたは一意のキーが定義されていない場合、INSERTが再実行され、同じデータを持つ複数の行を取得します–これもマスターと矛盾するデータがあることを意味します

ただし、ストレージエンジンとしてInnoDBを使用すると、テーブルにプライマリクエリまたは一意のクエリが定義されていない場合、エンジン自体が行ID値を含む合成列に非表示のクラスター化インデックスを作成しますに従って Jeremy Coleのブログ

したがって、プライマリまたは一意が存在しない場合でも、レプリケーションは影響を与えないはずです。レプリケーション自体がクラスター化インデックスを作成し、レプリケーションがスムーズで正しいことを保証する必要がありますか?この部分はわかりません。

マスタースレーブレプリケーションのセットアップで主キーの必要性に誰かが光を当てることができれば素晴らしいでしょう。

3
tesla747

あなたの仮定は正しくありません。

ここでは、サーバーがそのインデックスを使用してレプリケーションに必要な方法で行を見つけることができないため、非表示のクラスター化インデックスは役に立ちません。

これにより、マスターがSTATEMENTモードでログを記録するときにいくつかの問題が発生し、ROWモードでさまざまな問題が発生し、MIXEDモードですべての問題が組み合わされます。これが最大の落とし穴に関するtl; drです。

SQLインターフェースを介してアクセス可能な値を持つ主キーまたは一意キーのないテーブルに対するすべてのレプリケーションイベントは、レプリケートされる各行に対してフルテーブルスキャンを必要とする可能性があります。

SQLレイヤーへの非表示のクラスター化インデックスにアクセスできないため、そのインデックスは使用から除外されます...非表示にされていなくても、値はサーバー間で決定的ではないため、その値は決してないため、役に立ちません。 binlogに書き込まれます。

簡単に言うと...アクセス可能な主キーなしでテーブルを作成するべきではありません。それは悪いデザインです。

有効なテーブルには2つの同一の行を含めることはできません。すべてのリレーションには、定義上、少なくとも1つの候補キーがあり、候補キーも定義上、一意である必要があります。 1つを選択してプライマリにするか、サロゲート(自動インクリメント)を作成して表示します。一意の制約がある場合、それらをコードで強制するだけでなく、スキーマで定義する必要があります。

5