如何高效的批量刪除億級大表數據


 正文前先來一波福利推薦:

 福利一:

百萬年薪架構師視頻,該視頻可以學到很多東西,是本人花錢買的VIP課程,學習消化了一年,為了支持一下女朋友公眾號也方便大家學習,共享給大家。

福利二:

畢業答辯以及工作上各種答辯,平時積累了不少精品PPT,現在共享給大家,大大小小加起來有幾千套,總有適合你的一款,很多是網上是下載不到。

獲取方式:

微信關注 精品3分鍾 ,id為 jingpin3mins,關注后回復   百萬年薪架構師 ,精品收藏PPT  獲取雲盤鏈接,謝謝大家支持!

-----------------------正文開始---------------------------

 

最新項目一直出現線上問題,定位原因看到是由於表數據過大導致的,現在有個登錄表,登錄游戲玩家每次登錄的信息,久而久之,這幾個表的數據量達到了兩億多條。每天都在上報,采集,由於沒有定期刪除,數據大量累積。大概有一年左右的數據,一個表的數據已經達到億級別的。這樣算下來,一個表的數據至少是幾十GB了。因此需要刪除過期的數據,暫時保留近三個月的統計數據。

解決方案:

基本每個表都有個字段叫create_time或者collect_time的字段,只要刪除這個字段三個月之前的數據就ok了

delete from table_name where create_time < '2017-04-06'

只要執行這句SQL應該就可以了

遇到的問題:

The total number of locks exceeds the lock table size in MySQL

因為需要刪除的數據太大,mysql給的buffer好像只有8MB左右(網上搜到的)

后面找到DBA幫忙看,問這個表建了索引沒有

show index from table_name

通過查看索引,我們在create_time和collect_time上是建了索引的,索引類型是BTree,ASC。這里我們用的Mysql引擎是InnoDb

delete from table_name where create_time < '2017-07-06' order by create_time asc limit 10000

接着,我想用order by + limit實現刪除,還是出現了上面的錯誤

后面DBA提示我說,為啥不用ID刪除,說按id刪除,速度和按索引列刪除,不是一個數量級的

接着我想到了拆分一下。

最終解決方案:

找出符合條件的create_time和collect_time的最大ID

select max(id) from table_name where create_time < '2017-04-06'

這里千萬左右的數據大概需要10多秒

接着按id刪除,一次刪除10k,循環刪除

delete from table_name where id < maxId limit 10000

直到把過期的時間刪除完成

這里我沒有msyql服務器的權限,通過java客戶端連接刪除,使用的spring jdbcTemplate這個接口

另外,這里一次刪除10k還有個原因是,事務太大,影響其他服務的運行

還用到的技術,就是使用線程池來執行sql刪除,實現異步刪除。和同事吃飯的時候,同事也提供了一個解決方案,每次刪一秒的數據,這樣一次次的刪。看了一下數據,一秒的數據基本在幾十萬,左右,這樣不太好控制數據量大小。還是通過主鍵id + limit 10k這里穩妥一點。

還有一點就是,為了怕壓到mysql服務器,這里線程池刪除的時候回sleep(1000),阻塞1s再刪除,減輕mysql服務器的壓力

今天搞了一下數據刪除這一點東西,感覺mysql水很深,比如一個select count(*)的執行過程,select from table_name order by id limit 的過程,索引,各種連接,引擎的工作原理。走的時候還有點沒有調完,明天應該可以搞定這些了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM