1024程序員節的驚喜——清理數據導致的容量爆滿

大清早,看到關於1024程序員節的消息,心想今天會不會有什麼驚喜呢?小期待~

在這裏插入圖片描述

看客們且耐心聽我講故事,有乾貨,血淋淋的教訓換來的經驗。

吃完飯,打開郵箱看看

在這裏插入圖片描述
心想: 呆膠布,百分之八十而已,問題不大,數據庫裏百分之80%的數據都是從沒分析過的日誌,只寫不讀不更新,估計500萬行了吧,刪了前400萬行就好了,今天又是成就感滿滿的充實一天呢。
在這裏插入圖片描述

於是打算開始操作,流利的打開了Navicat Premium

1. 看了看有多少數據

SELECT max(id),min(id) FROM tb_log1;

在這裏插入圖片描述
不出所料,接近500W條日誌記錄,久遠的日誌不需要調取了,刪個400萬條就能出來大量空間了。

2. 開始刪

DELETE FROM tb_log1 WHERE id< 40000000;

忽然一想,delete操作不會釋放空間,truncate纔會嘛,那萬一刪這些數據導致磁盤空間直接從80%漲到100%,那不就坑大發了,佔到100%會不會崩潰?。於是我研究了一下下,得知我使用的InnoDB引擎,在進行刪除是是標記爲刪除,然後在寫入數據時纔會利用刪掉的空間。
標記400W條數據爲刪除,剩餘的20%空間等於8G,不可能讓用8G,減去2G和內存一樣的體積,再除以二,假設用3G空間用來標記這400W條記錄爲刪除,相當於 310241024*1024 byte空間,存4000000個刪除標誌,每個刪除標誌能有800byte大,不至於吧,穩得很。
對於這樣的刪除,需要加一句optimize table table_name就能立刻釋放空間。

3. 繼續開始刪

DELETE FROM tb_log1 WHERE id< 40000000;
OPTIMIZE TABLE tb_log1;

業務早高峯期,狗命要緊啊,這萬一刪這400萬條數據,能把tb_log表鎖定一兩個小時,那又該怎麼辦???於是謹慎的我又研究了一下:

  • 網上別人刪除十幾萬條數據20G需要十幾秒,心想,那還好,十幾秒而已,40W條也就一分鐘,以爲是網絡卡頓就過去了。
  • 謹慎的我再看了看目前CPU和RAM的利用率,還好還好,也就百分之幾和百分之30,幾十個連接,性能佔用百分之10都不到,應該卡不了多久。
  • 還是感覺哪裏有問題,再想想,這樣的刪除要寫入400W次,好像還蠻恐怖的呢,SSD硬盤一秒鐘能寫入1000次的話,那要寫4000秒,再快一個量級400秒也不行啊,投訴電話肯定要被打爆。…emmm還真是一兩個小時,看來網上說法不一定靠譜。
    在這裏插入圖片描述

4. 那怎麼辦?

  • 方案一:這些日誌反正從沒分析過,也沒用到過,要不troncate一下全刪了算了,萬一發現有用,阿里雲還有鏡像,恢復一個新的實例來分析就行了,不過備份的鏡像存不了幾天,恢復來研究太麻煩了。
  • 方案二:把有用的少量數據寫到一個新的表裏,然後刪除舊錶,再把新的表名字改回舊的表,這樣應該會很快,也比較保險。
  • 那就這麼定了,採取方案二,於是流利的寫出了sql語句,我果然是專業的呀。
    在這裏插入圖片描述

5. 繼續開始刪

-- 複製部分數據並創建新表
INSERT INTO tb_log2 SELECT * FROM tb_log1 WHERE id>4500000 ; -- 十分之一的日誌應該不會導致數據庫炸掉
-- 同時給兩個表命名
RENAME TABLE tb_log1 TO tb_log2, tb_log2 TO tb_log1; 
-- 刪除數據多的表
DROP TABLE tb_log2;

這下應該完美了吧,就算慢也應該不會超過一分鐘,客戶來不及打投訴電話就恢復了,用戶體驗都被狗吃了,滑稽笑
不,萬一代碼有錯誤呢!!於是建了小表,弄了點數據進去,這麼執行沒問題。

6. 墨跡了半天,終於要執行代碼了

緊張又雞凍。
在這裏插入圖片描述
然鵝,艾迪魔力轉圈圈…圈圈轉了幾圈後,提醒連接斷掉了。
在這裏插入圖片描述
執行查詢時失去了連接。。。,那到底刪成功沒刪成功?
按照第一步看了看,數據還是那些,沒刪成功啊。

7. 退而求其次,全部刪了算了

 TRUNCATE TABLE tb_log1;

在這裏插入圖片描述
然鵝,艾迪魔力轉圈圈…圈圈轉了幾圈後,提醒連接斷掉了。
在這裏插入圖片描述
執行查詢時失去了連接。。。,那到底刪成功沒刪成功?
按照第一步看了看,數據還是那些,沒刪成功啊。

8. 有種不祥的感覺

於是打開了我們的軟件,登錄不上了,抓包看一眼,媽耶,請求沒反應,大事不好了,用戶端估計要瘋了,市場部這回估計得炸了。
急忙登錄阿里雲RDS後臺,看看咱的數據庫咋地啦。
這時老闆的電話打來了,喜聞樂見,意料之中,肉牛滿面,果斷掛了沒接。

  • 打開RDS控制檯,滿眼的喜慶色(當時忘了截圖了),就是說IO上天了,每秒鐘2000:
    在這裏插入圖片描述
    WTF? truncate需要如此多的IO操作?

  • 連接總數也上天了,1500個連接。
    在這裏插入圖片描述
    這就更理解不了了,我的PHP沒那麼高的併發啊,難道是數據庫阻塞導致的?一定是!!

  • 存儲空間當時達到了120%(這是後來恢復正常後的狀況,當時只有40G容量)。
    在這裏插入圖片描述
    這就更出乎意料了,存儲空間怎麼會激增十幾G呢???我在做夢???還是我學了假的數據庫???

  • 再看RDS控制面板,紅色字顯示[磁盤使用率超出限制,鎖定中],鎖定什麼意思???
    那Navicat點看一個表,能打開呢,沒鎖啊,能用啊。

  • 再去登錄我們的網站並抓包,等不了,錯誤變成了500,切換測試狀態,數據庫報錯提示鎖定中,只讀狀態。

  • 爲什麼截斷表磁盤使用率會激增??而不會釋放容量??想不通,沒辦法,只好花錢買擴量,流利的加了幾百塊錢擴容。

在這裏插入圖片描述

  • 擴容操作進行十幾分鍾了還沒反應,一直顯示[鎖定中],沒有任何有效信息顯示擴容請求已受理或者正在進行擴容,這個真讓人頭大。
    在這裏插入圖片描述
  • 只好發起工單,工單發起大概過了十分鐘
    電話來了,熟悉的號碼95187,熟悉的聲音,阿里雲客戶經理告訴我我的工單已經第一時間轉發給相關工程師了,然後…
    開始推銷數據庫了,我說時態緊急,沒空聽你的推銷,然後他說不是推銷,聊聊數據庫的情況。
    我心想:“哦,你個市場部的人能懂數據庫運維?”
    果不其然,對方沒說幾句,就說道:“您的業務應該是處於增長期,數據量會變得比較大,有沒有考慮用關係型數據庫,我們平臺提供…”
    然後我就掛了電話,心想: 這個問題不解決好,不是公司倒閉,就是我損失大筆的錢,沒心思理會“靈堂賣片”行爲。
    在這裏插入圖片描述
  • 我注意到在數據庫面板[鎖定中]紅字附近,有個小小的問號
    在這裏插入圖片描述
    把鼠標放上去,會提醒:升級mysql8.0可以通過truncate、delete from table等操作自行釋放空間
    言外之意阿里雲RDS mysql8.0之前的版本,像我前面那樣的想法來釋放空間,就是個笑話?
  • 什麼也操作不了,沒法刪數據,沒法重啓實例,只能等,就算老闆現在衝到我面前,把刀駕到我的脖子上,讓我解決問題,我也只能等了。

9. 最後怎麼好的?

  • 掛了客服的電話,大概又過了十來分鐘,恢復了,不知道是工單那邊的工程師給解除了鎖定,還是我擴容操作完成了,所以好了。
    從登不上,到再次能登陸上,大概過了能有一個小時,這一個小時市場部的兄弟估計被罵的不是人了。
  • 升級8.0一來要錢,二來不兼容,感覺被阿里雲安排的明明白白,不加錢就別想有空間用的意思。
    比如8.0的mysql一個表裏不能用兩處current_timestamp,我的表大多數都是:
create_time timestamp default current_timestamp,
update_time timestamp on update current_timestamp

升級了就運行不了了
在這裏插入圖片描述

血淋淋的教訓和經驗

  1. 風險大的操作,一定要捨得花錢,做好萬全準備。
  2. 風險大的操作,一定要等在線用戶少的時候,比如半夜三四點時。
  3. 數據量一大或者用戶一多,不確定因素就會多,比如連接過程中阻塞個十幾秒後,主要業務的請求就堆積起來了。
  4. 要深入理解理解數據庫的緩存、日誌、磁盤等機制,知其然不知其所以然會出問題。
  5. 不要盲目自信。
  6. 日誌在實現時就考慮好定期清理,比如超過三個月的定時刪除,在操作時先關掉日誌的寫,以避免阻塞。

以上就是1024程序員節我收到的驚喜,啊呸,驚嚇!
在這裏插入圖片描述

另外,祝廣大的程序員1024節日快樂!

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