pt-archiver數據平滑刪除、平滑遷移利器!

  • 寫在前面

調研一件工具之前,在心裏一定要明白,自己要實現的是什麼功能,帶着自己的問題,去找尋答案才能學到新的知識點!

  • 需求背景

1)線上數據庫有一類ip表,用來記錄每天用戶對網站的訪問記錄情況,然後將其按照時間段整合到一起,做數據分析工作,整合的時間不同,最後形成的數據表大小亦是不同,小點千萬級,大點可能億級,現有需求將半年前的用戶記錄刪除,如何安全刪除?

2)系統做了升級,現要將原來的數據遷移至新服務器上同名數據庫中,如何保證安全遷移,而不造成導入時形成大量I/O,導致系統負載過高,用戶、研發等部門可以正常使用,特別是在業務高峯期間?


  • pt-archiver簡介

數據庫歸檔和清理工具,可以實現的功能有

1、清理線上過期數據

2、清理過期數據,並把數據歸檔到本地歸檔表中,或者遠端歸檔服務器

3、兩張表之間的數據不完全相同,希望合併。此時加--ignore --replace選項,可以輕鬆實現

4、導出線上數據,到線下數據作處理


根據我的需求,調研此工具可以實現所需功能,這也正是本文始點:帶着問題找答案,但作者只用到了1、2的功能,至於3、4的功能在這裏只做一個記錄,待之後有需求後,再做使用


  • 需求實現

1.1直接刪除

DELETE FROM `ip_limit_20170701_bak` WHERE id>1000

最簡單的方式,但如果數據表很大,可能造成大量的磁盤I/O、系統負載等,如果還存在slave,還會造成嚴重的從庫延遲等問題


1.2按照索引條件批量刪除

DELETE FROM `ip_limit_20170701_bak` WHERE id>1000 LIMIT 10000

較安全的刪除方式,可以保證磁盤I/O、系統負載、從庫延遲等處於可控範圍內,但數據量巨大,手動操作較爲繁瑣


1.3使用工具刪除

[root@backup home]# pt-archiver --version   [pt工具請自行安裝]

pt-archiver 3.0.10

[root@backup ~]# time

pt-archiver --source u=root,p=123456,S=/tmp/mysql.sock,P=3306,D=test,t=ip_limit_20170701_bak --no-check-charset --progress 10000 --where 'id BETWEEN 1000 AND 494731' --limit 10000 --txn-size 1000 --bulk-delete --sleep 5 --purge --statistics

解釋:刪除test庫,ip_limit_20170701_bak表數據,不做字符集檢查,刪除條件是 id BETWEEN 1000 AND 494731,每次取出10000行進行處理,每處理1000行則進行一次提交,每次處理10000行後顯示處理信息,每完成一次處理sleep 5s


2.1mysqldump方式

第一種:將源數據庫dump成sql文件,傳輸到目標服務器,再進行數據導入

第二種:直接在目標服務器dump源數據庫的sql,再進行數據導入

但,無論採用哪種方式數據遷移,數據表越大,在數據傳輸的東西,都會對帶寬造成極大的消耗,在查看流量監控圖的時候,可以清楚的看到毛尖;再者,在數據導入的時候,勢必會造成巨大的I/O消耗,系統負載也會飆升,對數據庫也會造成巨大的衝擊


2.2使用工具刪除

遷移數據時保留源數據:

[root@backup ~]#time pt-archiver --source u=root,p=123456,S=/tmp/mysql.sock,P=3306,D=test,t=ip_limit_20170701 --dest u=root,p=root,h=192.168.32.199,P=3306,D=ceshi,t=ip_limit_20170701 --charset=utf8 --progress 10000 --where 'id>=1' --limit 10000 --txn-size 1000 --sleep 5 --no-delete --bulk-insert --statistics

遷移數據時不保留源數據:

[root@backup ~]#time pt-archiver --source u=root,p=123456,S=/tmp/mysql.sock,P=3306,D=test,t=ip_limit_20170701 --dest u=root,p=root,h=192.168.32.199,P=3306,D=ceshi,t=ip_limit_20170701 --charset=utf8 --progress 10000 --where 'id>=1' --limit 10000 --txn-size 1000 --sleep 5  --bulk-delete --statistics


  • 常用參數

--source=d                 DSN specifying the table to archive from (required)    目標節點

--where=s                  WHERE clause to limit which rows to archive (required)

--purge                    Purge instead of archiving; allows omitting --file and --dest    刪除source數據庫的相關匹配記錄

--progress=i               Print progress information every X rows    每處理多少行顯示一次信息

--limit=i                  Number of rows to fetch and archive per statement (default 1)    每次取出多少行處理

--[no]check-charset        Ensure connection and table character sets are the same (default yes)    不檢查字符集

--txn-size=i               Number of rows per transaction (default 1)    每多少行提交一次

--bulk-delete              Delete each chunk with a single statement (implies --commit-each)    並行刪除

--statistics               Collect and print timing statistics    結束後輸出統計信息


  • 最後一條數據不刪除/不遷移BUG問題

平滑刪除、遷移數據時,最後一條數據都不會被刪除/遷移,已被證明爲pt-archiver BUG,需要修改下pt-archiver代碼

[root@backup ~]# vim /usr/bin/pt-archiver

原代碼:

6401       $first_sql .= " AND ($col < " . $q->quote_val($val) . ")";

修改後:

6401       $first_sql .= " AND ($col <= " . $q->quote_val($val) . ")";


這些都是作者在工作中遇到的實際工作後引發的一些思考,並做的相關實踐,對於其中理解不到位或者根本就是錯誤之處,望請下方留言,不勝感激!








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