寫在前面mysql
調研一件工具以前,在內心必定要明白,本身要實現的是什麼功能,帶着本身的問題,去找尋答案才能學到新的知識點!sql
需求背景數據庫
1)線上數據庫有一類ip表,用來記錄天天用戶對網站的訪問記錄狀況,而後將其按照時間段整合到一塊兒,作數據分析工做,整合的時間不一樣,最後造成的數據表大小亦是不一樣,小點千萬級,大點可能億級,現有需求將半年前的用戶記錄刪除,如何安全刪除?vim
2)系統作了升級,現要將原來的數據遷移至新服務器上同名數據庫中,如何保證安全遷移,而不形成導入時造成大量I/O,致使系統負載太高,用戶、研發等部門能夠正常使用,特別是在業務高峯期間?
安全
pt-archiver簡介服務器
數據庫歸檔和清理工具,能夠實現的功能有ide
一、清理線上過時數據 工具
二、清理過時數據,並把數據歸檔到本地歸檔表中,或者遠端歸檔服務器 fetch
三、兩張表之間的數據不徹底相同,但願合併。此時加--ignore --replace選項,能夠輕鬆實現 網站
四、導出線上數據,到線下數據做處理
根據個人需求,調研此工具能夠實現所需功能,這也正是本文始點:帶着問題找答案,但做者只用到了一、2的功能,至於三、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) . ")";
這些都是做者在工做中遇到的實際工做後引起的一些思考,並作的相關實踐,對於其中理解不到位或者根本就是錯誤之處,望請下方留言,不勝感激!