レプリケーションのソースおよびターゲットテーブルは同じである必要はありません。マスター上のテーブルのカラム数が、テーブルのスレーブコピーのものより多くても少なくてもかまいません。また、マスターおよびスレーブ上の対応するテーブルカラムが、一定の条件が適用されますが、異なるデータ型を使用していてもかまいません。
ソースおよびターゲットテーブルの定義が同じでない場合でも、データベースおよびテーブルの名前はマスターとスレーブの両方で同じである必要があります。次の 2 つのセクションで、追加条件について例を示して説明します。
マスターとスレーブコピーでテーブルのカラム数が異なる場合でも、次の条件に従って、テーブルをマスターからスレーブに複製できます。
-
両方のバージョンのテーブルに共通するカラムは、マスターとスレーブで同じ順番に定義する必要があります。
(これは、両方のテーブルのカラム数が同じ場合でも当てはまります。)
-
両方のバージョンのテーブルに共通するカラムは、追加カラムの前に定義する必要があります。
これは、スレーブで
ALTER TABLE
ステートメントを実行して、新しいカラムが両方のテーブルに共通するカラムの範囲内にテーブルに挿入される場合は、次の例で示すように、レプリケーションが失敗することを意味します。テーブル
t
がマスターおよびスレーブ上に存在し、次のCREATE TABLE
ステートメントで定義されているとします。CREATE TABLE t ( c1 INT, c2 INT, c3 INT );
ここで示す
ALTER TABLE
ステートメントがスレーブで実行されるとします。ALTER TABLE t ADD COLUMN cnew1 INT AFTER c3;
上記の
ALTER TABLE
はスレーブ上で許可されます。テーブルt
の両方のバージョンに共通するカラムc1
、c2
、およびc3
が両方のバージョンのテーブルでまとまったままであり、共通しないカラムはそのあとに来るためです。しかし、次の
ALTER TABLE
ステートメントをスレーブ上で実行すると、レプリケーションは必ず失敗します。ALTER TABLE t ADD COLUMN cnew2 INT AFTER c2;
ここで示す
ALTER TABLE
ステートメントをスレーブ上で実行すると、新しいカラムcnew2
が両方のバージョンのt
に共通するカラムの間に来るため、レプリケーションは失敗します。 -
カラム数の多いバージョンのテーブルの「追加」カラムごとに、デフォルト値が必要です。
カラムのデフォルト値は、その型、
DEFAULT
オプションで定義されているかどうか、NULL
として宣言されているかどうか、作成時に有効であったサーバー SQL モードなど、いくつかの要因で決まります。詳細については、セクション11.6「データ型デフォルト値」を参照してください)。
また、テーブルのスレーブコピーがマスターのコピーよりカラム数が多いときは、テーブルに共通する各カラムは両方のテーブルで同じデータ型を使用する必要があります。
例 次の例は、有効および無効なテーブル定義をいくつか示します。
マスターのカラム数が多い 次のテーブル定義は有効で、正しく複製されます。
master> CREATE TABLE t1 (c1 INT, c2 INT, c3 INT);
slave> CREATE TABLE t1 (c1 INT, c2 INT);
次のテーブル定義は、両方のバージョンのテーブルに共通するカラムの定義がスレーブ上とマスター上とで順番が異なるため、エラー 1532 (ER_BINLOG_ROW_RBR_TO_SBR
) が発生します。
master> CREATE TABLE t1 (c1 INT, c2 INT, c3 INT);
slave> CREATE TABLE t1 (c2 INT, c1 INT);
次のテーブル定義でも、両方のバージョンのテーブルに共通するカラムの定義の前に、マスター上の追加カラムの定義があるため、エラー 1532 が発生します。
master> CREATE TABLE t1 (c3 INT, c1 INT, c2 INT);
slave> CREATE TABLE t1 (c1 INT, c2 INT);
スレーブのカラム数が多い 次のテーブル定義は有効で、正しく複製されます。
master> CREATE TABLE t1 (c1 INT, c2 INT);
slave> CREATE TABLE t1 (c1 INT, c2 INT, c3 INT);
次の定義では、両方のバージョンのテーブルに共通するカラムが、マスターとスレーブの両方で同じ順序で定義されていないため、エラー 1532 が発生します。
master> CREATE TABLE t1 (c1 INT, c2 INT);
slave> CREATE TABLE t1 (c2 INT, c1 INT, c3 INT);
次のテーブル定義でも、両方のバージョンのテーブルに共通のするカラムの定義の前に、スレーブバージョンのテーブルの追加カラムの定義があるため、エラー 1532 が発生します。
master> CREATE TABLE t1 (c1 INT, c2 INT);
slave> CREATE TABLE t1 (c3 INT, c1 INT, c2 INT);
次のテーブル定義は、スレーブバージョンのテーブルはマスターバージョンに比べてカラム数が多く、2 つのバージョンのテーブルに共通するカラム c2
が使用するデータ型が異なっているため、失敗します。
master> CREATE TABLE t1 (c1 INT, c2 BIGINT);
slave> CREATE TABLE t1 (c1 INT, c2 INT, c3 INT);
同じテーブルのマスターコピーとスレーブコピー上の対応するカラムは、理想的には同じデータ型であるべきです。ただし MySQL 5.1.21 以降では、一定の条件が満たされるかぎり、これは必ずしも厳密に適用されません。
ほかのすべてのことが等しい場合、あるデータ型のカラムから、同じ型、同じサイズまたは幅 (該当する場合は、それより大きい) の別のカラムに複製することは常に可能です。たとえば、CHAR(10)
カラムから別の CHAR(10)
に、または CHAR(10)
カラムから CHAR(25)
カラムに、問題なく複製できます。場合によっては、あるデータ型を持つカラム (マスター上) から異なるデータ型を持つカラム (スレーブ上) に複製できることもあります。マスターバージョンのカラムのデータ型が、同じサイズまたはそれより大きい型に昇格されるとき、これは属性昇格と呼ばれます。
属性昇格は、ステートメントベースおよび行ベースレプリケーションで使用でき、マスターまたはスレーブで使用されるストレージエンジンに依存しません。ただし、ロギング形式の選択は許可される型変換に影響します。詳細は、このセクションで後述します。
ステートメントベースまたは行ベースのどちらのレプリケーションを使用するときでも、属性昇格を使用する場合はテーブルのスレーブコピーのカラム数をマスターコピーより多くすることはできません。
ステートメントベースのレプリケーション
ステートメントベースレプリケーションを使用するときに従うべき簡単な経験則は、「マスター上で実行されるステートメントがスレーブ上でも正常に実行される場合は、複製も成功するはず」ということです。つまり、スレーブ上のあるカラムの型と互換性のある値をステートメントが使用する場合、そのステートメントは複製できます。たとえば、TINYINT
カラムに適合する値を BIGINT
カラムにも挿入できます。これは、テーブルのスレーブコピー内の TINYINT
カラムの型を BIGINT
に変更する場合でも、マスター上で成功するそのカラムへの挿入は、スレーブ上でも成功するはずである、ということに従っています (BIGINT
カラムを越えるほど大きな、正当な TINYINT
値を持つことができないため)。
MySQL 5.6.10 より前では、ステートメントベースレプリケーションを使用するときに、AUTO_INCREMENT
カラムはマスターとスレーブの両方で同じである必要がありました。そうでない場合、スレーブ上の間違ったテーブルに更新が適用される可能性がありました (Bug #12669186)
行ベースレプリケーション: 属性の昇格と降格 MySQL 5.6 の行ベースレプリケーションは、小さなデータ型と大きなデータ型の間の属性昇格および降格をサポートします。このセクションで後述するように、降格されるカラム値の不可逆 (切り捨て) または非不可逆変換を許可するかどうかを指定することもできます。
不可逆および非不可逆変換 ターゲット型が挿入される値を表現できない場合、変換をどのように扱うかについての決定が必要になります。変換を許可するけれども、ターゲットカラムで「適合」を実現するためにソース値を切り捨てる (または変更する) 場合、不可逆変換と呼ばれることを行います。ソースカラム値をターゲットカラムに適合させるために切り捨てまたは同様の変更を必要としない変換は、非不可逆変換です。
型変換モード (slave_type_conversions 変数)
slave_type_conversions
グローバルサーバー変数の設定は、スレーブで使用される型変換モードを制御します。この変数は次の表 (スレーブの型変換動作に対する各モードの影響を示す) からの値セットを取ります。
モード | 影響 |
---|---|
ALL_LOSSY |
このモードでは、情報の損失を意味する型変換が許可されます。
これは非不可逆変換が許可されることを暗示せず、不可逆変換を必要とするまたは変換をまったく必要としないケースのみが許可されることだけを暗示します。たとえば、このモードのみを有効にした場合、 |
ALL_NON_LOSSY |
このモードは、ソース値の切り捨てまたは特別処理を必要とない変換を許可します。すなわち、ターゲット型の範囲がソース型より広い変換を許可します。
このモードを設定することは、不可逆変換が許可されるかどうかに関係ありません。これは |
ALL_LOSSY,ALL_NON_LOSSY |
このモードが設定されると、サポートされるすべての型変換が、不可逆変換かどうかにかかわらず、許可されます。 |
ALL_SIGNED |
昇格される整数型を符号付き値として扱います (デフォルト動作)。 |
ALL_UNSIGNED |
昇格される整数型を符号なし値として扱います。 |
ALL_SIGNED,ALL_UNSIGNED |
昇格される整数型を、可能な場合符号付きとして、そうでない場合は符号なしとして扱います。 |
[empty] |
このモードがデフォルトです。 |
整数型が昇格されるときに、符号ありか符号なしかは保持されません。デフォルトでは、スレーブはこのような値をすべて符号付きとして扱います。MySQL 5.6.13 以降では、ALL_SIGNED
、ALL_UNSIGNED
、またはその両方を使用してこの動作を制御できます。(Bug#15831300) ALL_SIGNED
は昇格されるすべての整数型を符号付きとして扱うようにスレーブに指示します。ALL_UNSIGNED
はこれらを符号なしとして扱うように指示します。両方を指定すると、スレーブは、可能な場合は値を符号付きとして扱い、そうでない場合は符号なしとして扱います。リストされている順序は重要ではありません。少なくとも ALL_LOSSY
または ALL_NONLOSSY
のいずれかが使用されていない場合は、ALL_SIGNED
も ALL_UNSIGNED
も効果を持ちません。
型変換モードを変更するには、新しい slave_type_conversions
設定でスレーブを再起動する必要があります。
サポートされる変換 違うけれども似ているデータ型の間でサポートされる変換を次のリストに示します。
-
整数型
TINYINT
、SMALLINT
、MEDIUMINT
、INT
、およびBIGINT
のいずれかの間。これには、これらの型の符号付きおよび符号なしバージョンの間の変換が含まれます。
不可逆変換は、ソース値をターゲットカラムで許可される最大値 (または最小値) に切り捨てることで行われます。符号なしから符号付き型への非不可逆変換を保証するには、ターゲットカラムがソースカラム内の値の範囲を受け入れるのに十分な大きさである必要があります。たとえば、
TINYINT UNSIGNED
は、非不可逆にSMALLINT
に降格できますが、TINYINT
にはできません。 -
小数点型
DECIMAL
、FLOAT
、DOUBLE
、およびNUMERIC
のいずれかの間。FLOAT
からDOUBLE
へは非不可逆変換です。DOUBLE
からFLOAT
へは不可逆にしか扱えません。DECIMAL(
からM
,D
)DECIMAL(
への変換 (M'
,D'
)
およびD'
>=D
(
-M'
-D'
) >= (M
D
)) は非不可逆です。
、M'
<M
、またはその両方の場合、不可逆変換だけを行うことができます。D'
<D
いずれかの小数点型の場合、格納される値をターゲット型に適合させることができない場合は、このマニュアルのほかの場所でサーバーに定義される丸めルールに従って値が切り捨てられます。小数点型でこれがどのように実行されるかについては、セクション12.20.4「丸め動作」を参照してください。
-
文字列型
CHAR
、VARCHAR
、およびTEXT
のいずれかの間 (異なる幅の間での変換を含む)。CHAR
、VARCHAR
、またはTEXT
から、同じまたはそれより大きいサイズのCHAR
、VARCHAR
、またはTEXT
カラムへの変換は、決して不可逆ではありません。不可逆変換は、スレーブ上の文字列の最初のN
文字だけを挿入することで処理されます。ここで、N
はターゲットカラムの幅です。重要異なる文字セットを使用するカラム間のレプリケーションはサポートされません。
-
バイナリデータ型
BINARY
、VARBINARY
、およびBLOB
のいずれかの間 (異なる幅の間での変換を含む)。BINARY
、VARBINARY
、またはBLOB
から、同じまたはそれより大きいサイズのBINARY
、VARBINARY
、またはBLOB
カラムへの変換は、決して不可逆ではありません。不可逆変換は、スレーブ上の文字列の最初のN
バイトだけを挿入することで扱われます。ここで、N
はターゲットカラムの幅です。 -
任意の 2 つのサイズの任意の 2 つの
BIT
カラムの間。BIT(
カラムからの値をM
)BIT(
カラムに挿入するときは (M'
)
)、M'
>M
BIT(
カラムの最上位ビットがクリアされ (ゼロに設定され)、M'
)BIT(
値のM
)M
ビットがBIT(
カラムの最下位ビットとして設定されます。M'
)ソース
BIT(
カラムからの値をターゲットM
)BIT(
カラムに挿入するときは (M'
)
)、M'
<M
BIT(
カラムの可能な最大値が割り当てられます。つまり、「すべてが設定された」値がターゲットカラムに割り当てられます。M'
)
前のリストにない型の間の変換は許可されません。
MySQL 5.5.3 以前でのレプリケーション型変換
MySQL 5.5.3 より前は、行ベースバイナリロギングで、TINYINT
から BIGINT
へなど、異なる INT
サブ型の間で複製することはできませんでした。行ベースロギングを使用するときは、これらの型のカラムへの変更が、バイナリログ内で互いに異なる方法で表現されていたためです。(ただし、行ベースレプリケーションを使用して BLOB
から TEXT
に複製することはできました。BLOB
および TEXT
カラムへの変更がバイナリログ内で同じ形式を使用して表現されていたためです。)
MySQL 5.5.3 より前の行ベースレプリケーションを使用するときに、属性昇格でサポートされる変換を次の表に示します。
変換前 (マスター) | 変換後 (スレーブ) |
---|---|
BINARY |
CHAR |
BLOB |
TEXT |
CHAR |
BINARY |
DECIMAL |
NUMERIC |
NUMERIC |
DECIMAL |
TEXT |
BLOB |
VARBINARY |
VARCHAR |
VARCHAR |
VARBINARY |
すべてのケースで、スレーブ上のカラムのサイズまたは幅は、マスター上のカラムのもの以上にする必要があります。たとえば、マスター上の CHAR(10)
カラムから、スレーブ上の BINARY(10)
または BINARY(25)
を使用するカラムに複製できましたが、マスター上の CHAR(10)
カラムからスレーブ上の BINARY(5)
カラムに複製することはできませんでした。
プリフィクスを持つ一意インデックス (主キーを含む) は、マスターとスレーブの両方で同じ長さのプリフィクスを使用する必要があります。このような場合、異なるプリフィクス長は許可されません。プリフィクス長がマスターとスレーブで異なる一意でないインデックスを使用することは可能ですが、これによって重大なパフォーマンス問題が発生する場合があります (特に、マスター上で使用されるプリフィクスの方が長いとき)。これは、ある長さの 2 つの一意プリフィクスが、長さが短くなると一意でなくなる場合があるという事実によります。たとえば、単語 catalogue と catamount は、それぞれ 5 文字のプリフィクス catal と catam を持ちますが、4 文字の同じプリフィクス (cata) を共有します。これにより、このようなインデックスを使用するクエリーが、同じインデックスのスレーブ定義でマスター上のものより短いプリフィクスが使用されるときに、スレーブ上での実行効率が低下する可能性があります。
DECIMAL
および NUMERIC
カラムの場合、仮数 (M) と小数以下の桁数 (D) の両方が、マスターに比べてスレーブ上で同じまたはそれより大きいサイズである必要があります。たとえば、NUMERIC(5,4)
から DECIMAL(6,4)
へのレプリケーションは機能しましたが、NUMERIC(5,4)
から DECIMAL(5,3)
へのレプリケーションはしませんでした。
MySQL 5.5.3 より前は、行ベースレプリケーションを使用するときに、MySQL レプリケーションは次のデータ型とほかのデータ型との間で属性昇格をサポートしませんでした。
-
INT
(TINYINT
、SMALLINT
、MEDIUMINT
、BIGINT
を含む)。INT
サブ型間の昇格 (たとえば、SMALLINT
からBIGINT
へ) も、MySQL 5.5.3 より前はサポートされませんでした。 SET
またはENUM
。FLOAT
またはDOUBLE
。日付、時間、またはその両方に関連するデータ型のすべて:
DATE
、TIME
、DATETIME
、TIMESTAMP
、およびYEAR
。