Documentation Home
MySQL 5.6 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 26.8Mb
PDF (A4) - 26.9Mb
HTML Download (TGZ) - 7.2Mb
HTML Download (Zip) - 7.2Mb


MySQL 5.6 リファレンスマニュアル  /  ...  /  テーブル定義が異なるマスターとスレーブでのレプリケーション

17.4.1.9 テーブル定義が異なるマスターとスレーブでのレプリケーション

レプリケーションのソースおよびターゲットテーブルは同じである必要はありません。マスター上のテーブルのカラム数が、テーブルのスレーブコピーのものより多くても少なくてもかまいません。また、マスターおよびスレーブ上の対応するテーブルカラムが、一定の条件が適用されますが、異なるデータ型を使用していてもかまいません。

ソースおよびターゲットテーブルの定義が同じでない場合でも、データベースおよびテーブルの名前はマスターとスレーブの両方で同じである必要があります。次の 2 つのセクションで、追加条件について例を示して説明します。

17.4.1.9.1 マスターまたはスレーブでカラムが多い場合のレプリケーション

マスターとスレーブコピーでテーブルのカラム数が異なる場合でも、次の条件に従って、テーブルをマスターからスレーブに複製できます。

  • 両方のバージョンのテーブルに共通するカラムは、マスターとスレーブで同じ順番に定義する必要があります。

    (これは、両方のテーブルのカラム数が同じ場合でも当てはまります。)

  • 両方のバージョンのテーブルに共通するカラムは、追加カラムの前に定義する必要があります。

    これは、スレーブで 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 の両方のバージョンに共通するカラム c1c2、および 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);
17.4.1.9.2 データ型が異なるカラムのレプリケーション

同じテーブルのマスターコピーとスレーブコピー上の対応するカラムは、理想的には同じデータ型であるべきです。ただし 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

このモードでは、情報の損失を意味する型変換が許可されます。

これは非不可逆変換が許可されることを暗示せず、不可逆変換を必要とするまたは変換をまったく必要としないケースのみが許可されることだけを暗示します。たとえば、このモードのみを有効にした場合、INT カラムが TINYINT に変換されること (不可逆変換) は許可されますが、TINYINT カラムが INT カラムに変換されること (非不可逆) は許可されません。このケースで後者の変換を試みると、レプリケーションがスレーブ上のエラーで停止します。

ALL_NON_LOSSY

このモードは、ソース値の切り捨てまたは特別処理を必要とない変換を許可します。すなわち、ターゲット型の範囲がソース型より広い変換を許可します。

このモードを設定することは、不可逆変換が許可されるかどうかに関係ありません。これは ALL_LOSSY モードで制御されます。ALL_NON_LOSSY だけが設定され、ALL_LOSSY はされない場合、データが損失する変換を試みると (INT から TINYINT へ、CHAR(25) から VARCHAR(20) へなど)、スレーブはエラーで停止します。

ALL_LOSSY,ALL_NON_LOSSY

このモードが設定されると、サポートされるすべての型変換が、不可逆変換かどうかにかかわらず、許可されます。

ALL_SIGNED

昇格される整数型を符号付き値として扱います (デフォルト動作)。

ALL_UNSIGNED

昇格される整数型を符号なし値として扱います。

ALL_SIGNED,ALL_UNSIGNED

昇格される整数型を、可能な場合符号付きとして、そうでない場合は符号なしとして扱います。

[empty]

slave_type_conversions が設定されていなときは、属性の昇格または降格は許可されません。これは、ソースおよびターゲットテーブル内のすべてのカラムが同じ型である必要があることを意味します。

このモードがデフォルトです。

整数型が昇格されるときに、符号ありか符号なしかは保持されません。デフォルトでは、スレーブはこのような値をすべて符号付きとして扱います。MySQL 5.6.13 以降では、ALL_SIGNEDALL_UNSIGNED、またはその両方を使用してこの動作を制御できます。(Bug#15831300) ALL_SIGNED は昇格されるすべての整数型を符号付きとして扱うようにスレーブに指示します。ALL_UNSIGNED はこれらを符号なしとして扱うように指示します。両方を指定すると、スレーブは、可能な場合は値を符号付きとして扱い、そうでない場合は符号なしとして扱います。リストされている順序は重要ではありません。少なくとも ALL_LOSSY または ALL_NONLOSSY のいずれかが使用されていない場合は、ALL_SIGNEDALL_UNSIGNED も効果を持ちません。

型変換モードを変更するには、新しい slave_type_conversions 設定でスレーブを再起動する必要があります。

サポートされる変換  違うけれども似ているデータ型の間でサポートされる変換を次のリストに示します。

  • 整数型 TINYINTSMALLINTMEDIUMINTINT、および BIGINT のいずれかの間。

    これには、これらの型の符号付きおよび符号なしバージョンの間の変換が含まれます。

    不可逆変換は、ソース値をターゲットカラムで許可される最大値 (または最小値) に切り捨てることで行われます。符号なしから符号付き型への非不可逆変換を保証するには、ターゲットカラムがソースカラム内の値の範囲を受け入れるのに十分な大きさである必要があります。たとえば、TINYINT UNSIGNED は、非不可逆に SMALLINT に降格できますが、TINYINT にはできません。

  • 小数点型 DECIMALFLOATDOUBLE、および NUMERIC のいずれかの間。

    FLOAT から DOUBLE へは非不可逆変換です。DOUBLE から FLOAT へは不可逆にしか扱えません。DECIMAL(M,D) から DECIMAL(M',D') への変換 (D' >= D および (M'-D') >= (M-D)) は非不可逆です。M' < MD' < D、またはその両方の場合、不可逆変換だけを行うことができます。

    いずれかの小数点型の場合、格納される値をターゲット型に適合させることができない場合は、このマニュアルのほかの場所でサーバーに定義される丸めルールに従って値が切り捨てられます。小数点型でこれがどのように実行されるかについては、セクション12.20.4「丸め動作」を参照してください。

  • 文字列型 CHARVARCHAR、および TEXT のいずれかの間 (異なる幅の間での変換を含む)。

    CHARVARCHAR、または TEXT から、同じまたはそれより大きいサイズの CHARVARCHAR、または TEXT カラムへの変換は、決して不可逆ではありません。不可逆変換は、スレーブ上の文字列の最初の N 文字だけを挿入することで処理されます。ここで、N はターゲットカラムの幅です。

    重要

    異なる文字セットを使用するカラム間のレプリケーションはサポートされません。

  • バイナリデータ型 BINARYVARBINARY、および BLOB のいずれかの間 (異なる幅の間での変換を含む)。

    BINARYVARBINARY、または BLOB から、同じまたはそれより大きいサイズの BINARYVARBINARY、または 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 つの一意プリフィクスが、長さが短くなると一意でなくなる場合があるという事実によります。たとえば、単語 cataloguecatamount は、それぞれ 5 文字のプリフィクス catalcatam を持ちますが、4 文字の同じプリフィクス (cata) を共有します。これにより、このようなインデックスを使用するクエリーが、同じインデックスのスレーブ定義でマスター上のものより短いプリフィクスが使用されるときに、スレーブ上での実行効率が低下する可能性があります。

DECIMAL および NUMERIC カラムの場合、仮数 (M) と小数以下の桁数 (D) の両方が、マスターに比べてスレーブ上で同じまたはそれより大きいサイズである必要があります。たとえば、NUMERIC(5,4) から DECIMAL(6,4) へのレプリケーションは機能しましたが、NUMERIC(5,4) から DECIMAL(5,3) へのレプリケーションはしませんでした。

MySQL 5.5.3 より前は、行ベースレプリケーションを使用するときに、MySQL レプリケーションは次のデータ型とほかのデータ型との間で属性昇格をサポートしませんでした。

  • INT (TINYINTSMALLINTMEDIUMINTBIGINT を含む)。

    INT サブ型間の昇格 (たとえば、SMALLINT から BIGINT へ) も、MySQL 5.5.3 より前はサポートされませんでした。

  • SET または ENUM

  • FLOAT または DOUBLE

  • 日付、時間、またはその両方に関連するデータ型のすべて: DATETIMEDATETIMETIMESTAMP、および YEAR