8千萬的大表只保留500萬的數據?推薦一個高效且不影響線上方案

2019-09-25     波波說運維

概述

如果大家需要定期去清理mysql資料庫大表,可以參考以下楊大師的實現方案進行,建議先進行測試。下面以我的實際情況做一下實驗演示。

前提:

1、數據類型為流水型業務,不涉及事務處理。

2、數據流程不會修改歷史數據,僅參考近N天數據

3、操作時機不是業務高峰期

4、能夠接受秒級的數據寫入閃斷。


思路

從處理方式來看,基本就是做了rename,把原來表的數據轉置到一個中間庫裡面,然後補錄數據,對於日誌型的數據表來說是很有必要的。

要實現這個目標,我們需要儘可能保證中轉表的數據要儘可能完整,而且要保證數據切換能夠高效完成。

那麼我們處理的思路就是增量疊代,即最後的切換階段耗時最短,我們可以提前複製需要補錄的數據,同時對當天的數據進行增量的補錄,然後開始切換。

注意考慮主鍵自增的影響。


實現方式

1、創建同樣結構的表,包括索引,一個表是做備份,一個是作為中轉。

create table lcp_mq_record_arch like lcp_mq_record;
create table lcp_mq_record_arch_new like lcp_mq_record;

說明:

create..as 用來創建相同表結構並複製源表數據。

create..like 用來創建完整表結構和全部索引。

2、需要把近一個月的數據表現存放到中轉表log_new裡面,為了提高效率,先保證當天的數據有效。

--當前時間大於11:00:00,但是間隔不大
insert into lcp_mq_record_arch_new select * from lcp_mq_record where last_update_date between '2019-09-16' and '2019-09-19 11:00:00';

如果比較多數據,注意分段insert,完成增量數據的補錄,直到增量數據的補錄時長控制在秒級(數據集越小,處理時長越短)

3、切換表

RENAME TABLE lcp_mq_record TO lcp_mq_record_arch,lcp_mq_record_arch_new TO lcp_mq_record;

整個切換過程是很快的。

4、歷史數據的補錄

為了儘可能降低對線上環境的影響,我們需要縮小補錄的時間範圍,比如按照如下的方式來進行補錄:

insert into lcp_mq_record select * from lcp_mq_record_arch where last_update_date>'2019-09-19 11:00:00';

因為結果集相對小一些,處理過程對已有的數據處理線程的效率影響最小,可以避免大結果集導致服務阻塞的情況。

當然關鍵的部分是整個流程梳理完善後固定下來,我們可以把它轉換成一個腳本,這樣後續的操作我們只需要輸入表名,保留的時間範圍即可完成這個看起來略微複雜的需求了。


覺得有用的朋友多幫忙轉發哦!後面會分享更多devops和DBA方面的內容,感興趣的朋友可以關注下~

文章來源: https://twgreatdaily.com/zh-cn/9gUXZW0BJleJMoPMxTvq.html