歡迎轉(zhuǎn)載,但請在開頭或結(jié)尾注明原文出處【blog.chaosjohn.com】
前言
今年五月下旬的時候,公司某線上數(shù)據(jù)庫遭遇表被刪事件,對,沒錯,就是那種 刪庫 事件。
不過不是惡意刪庫事件,是某開發(fā)童鞋的不小心,而且他也沒有跑路。
在發(fā)現(xiàn)表被刪的第一時間,我就插手處理(假設(shè)表名為 sample):
- 先把被刪的表結(jié)構(gòu)重建起來,先爭取線上相關(guān)業(yè)務(wù)接口不再報
502錯誤 - 再從阿里云那邊下載當(dāng)日早些時候的完整數(shù)據(jù)庫備份
- 創(chuàng)建本地 MySQL 環(huán)境,將被刪表從完整備份中恢復(fù)到本地
- 等到業(yè)務(wù)高峰過去后,短暫下線
sample表相關(guān)的服務(wù),即服務(wù)降級 - 將線上
sample表的數(shù)據(jù)導(dǎo)出到CSV文件(包含了從刪庫后重建表開始到服務(wù)降級之間的所有數(shù)據(jù)) - 從
CSV中合并增量數(shù)據(jù)到本地sample表(追加在尾部) - 將線上
sample表備份后刪除,將本地sample表復(fù)制到線上 - 恢復(fù)服務(wù)
完美收工?。?!
只不過第二天做投放的小伙伴告訴我,后臺數(shù)據(jù)有錯亂。我一檢查,發(fā)現(xiàn)上述的 步驟6 出了紕漏。合并增量數(shù)據(jù)的時候,CSV 的列與 sample 表的列沒對齊,即有兩列交換了位置。
解決
所以,解決目標(biāo)就是,對于數(shù)據(jù)表里出問題的行,要將該兩列交換回來。
方案一
利用臨時變量 temp,適用場景:x 與 y 必須都不為 NULL
UPDATE sample SET x=y, y=@temp WHERE (@temp:=x) IS NOT NULL;
方案二(筆者選用的方案)
同樣利用臨時變量 temp,但是 x 與 y 沒有不為 NULL 的限制
UPDATE sample SET x=(@temp:=x), x=y, y=@temp;
方案三
s1 得到更新,而 s2 則用來拉取老數(shù)據(jù)(注:該方案要求表必須有主鍵id)
UPDATE sample s1, sample s2 SET s1.x=s1.y, s1.y=s2.x WHERE s1.id=s2.id;
方案四(如果 x 與 y 都是數(shù)值型)
UPDATE sample SET x=x+y,y=x-y,x=x-y;