DDLが原因でMySQLの主従停止問題と解決


DBA学友は1つのバグを報告して、線上の1つのDDL文は主従が停止することを招いて、問題は簡略化して以下のように説明します.
 
説明:
簡単な手順は次のとおりです.
 
Create table tb(c varchar(1000))engine=innodb; 

Create table tc as select cast(c as signed integer) from tb; 

Show create table tc; 

CREATE TABLE `tc` 
( `cast(c as signed integer)` bigint(1000) DEFAULT NULL ) ENGINE=InnoDB DEFAULT CHARSET=gbk 


 
 
以上の結果から,tcテーブルのこのフィールドはbigint(1000)として定義されている.この操作はメインライブラリでは問題ありませんが、binlogがスレーブライブラリでapplyを実行すると、同期が停止することがわかります.errno 1439.
 
ぶんせき
実はMasterでこの文を単独で実行していることがわかりました
CREATE TABLE `tc` (
  `cast(c as signed integer)` bigint(1000) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk,
MySQLで定義するbigintとintの表示幅が255を超えないため、実行できません.しかし、この制限は解析時に判断される.
例の場合、tcという表はbigintの表示幅を明確に表していませんが、内部変換時に、こんなに長く算出されます.binlogは、この算出結果を記録し、ライブラリから直接この文を実行した場合、エラーを報告します.
 
単純な解決
実際に表示幅も1000ほど使う必要はないので、MySQLがこの制限をするのは妥当ではありません.したがって、解析だけでなく、文を実際に実行するときに、整数フィールドの表示幅が255を超える場合、255に統一的に設定すればよいと判断する必要があります.
これにより、ライブラリから実行される文はbigint(255)であり、この文は正しく実行される.
もちろんこのエラーメッセージはwarningに提示されています.
 
patchダウンロード(Percona 5.5.18ベース)
 
注意:この問題はRow basedのbinlogでのみ存在します.ありがとうございます@Mr_Mableviリマインダ