一個DDL導致MySQL主從停止問題及解決

DBA同學報一個bug,線上一個DDL語句導致主從停止,問題簡化描述如下。 描述: 簡化的操作步驟如下: 1.Create table tb(c varchar(1000))engine=innodb; 2. 3.Create table tc as select cast(c as signed integer) from tb; 4. 5.Show create table tc; 6. 7

DBA同學報一個bug,線上一個DDL語句導致主從停止,問題簡化描述如下。

描述:

簡化的操作步驟如下:

1.Create table tb(c varchar(1000))engine=innodb;???
2.?
3.Create table tc as select cast(c as signed integer) from tb;??? 4.?
5.Show create table tc;??? 6.?
7.CREATE TABLE `tc`??? 8.( `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中

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享