MySQL隱式轉換問題修復

一、背景
某業務一條UPDATE SQL where條件中存在隱式轉換,預期要更新1條數據,實際由於隱式轉換更新了80W條數據,更新後數據異常。

二、問題SQL
UPDATE `xm_user` SET `status`=0 WHERE `user_number`=0;

三、表結構
表數據有一千多萬;user_number爲用戶的唯一標識,其中有M159632/45841315兩種格式的數據;

CREATE TABLE `xm_user` (
  `user_number` varchar(20) NOT NULL COMMENT '主鍵;用戶唯一標識',
  `status` int(11) unsigned NOT NULL COMMENT '0:不可使用;1:可使用',
  PRIMARY KEY (`user_number`),
  KEY `idx_status` (`status`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='用戶基本信息表'

四、查詢執行 
select count(0)from `xm_user`  WHERE `user_number`=0; 查出80多萬數據;
select count(0)from `xm_user`  WHERE `user_number`='0'; 查詢0條數據;

五、SQL_MODE避免
當sql_mode設置爲嚴格模式(STRICT_TRANS_TABLES)時,更新將會報錯:ERROR 1292 (22007): Truncated incorrect DOUBLE value: 'xxxxxx'。
查看配置:show global variables like '%sql_mode%';
sql_mode加上嚴格模式限制set sql_mode='STRICT_TRANS_TABLES,ALLOW_INVALID_DATES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'

六、數據修復
1)找到第一次異常更新的binlog 起始和截止postion,用binlog2sql生成回滾語句
2) 由於等於0的數據進行了多次更新,導致字段的時間戳發生了變化,binlog2sql生成的語句where條件包含所有字段,所以無法匹配。另外生成的回滾json當做where條件也匹配不到數據。
3)去掉其他where條件,只保留主鍵進行更新。awk -F"AND" '{print $1"AND"$6}'|awk '{for(i=1;i<=NF-3;i++){printf $i" ";}{print $NF";";}}'

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章