percona-toolkit 之 【pt-archiver】

背景:

        工做上須要刪除或則歸檔一張大表,這時候用pt-archiver能夠很好的知足要求,其不只能夠歸檔數據,還有刪除、導出到文件等功能。而且在主從架構當中,能夠兼顧從庫(一個或則多個)進行歸檔,避免歸檔、刪除數據時候壓力太大,形成從庫的延遲。該工具的目標是一個低影響,從表中剔除舊數據,而不會影響OLTP查詢。也能夠將數據插入到另外一個表中,該表沒必要位於同一服務器上。html

使用方法:

pt-archiver [OPTIONS] --source DSN --where WHERE

1)將全部行從oltp_server歸檔到olap_server並歸檔到文件:git

pt-archiver --source h=oltp_server,D=test,t=tbl --dest h=olap_server \
  --file '/var/log/archive/%Y-%m-%d-%D.%t'                           \
  --where "1=1" --limit 1000 --commit-each

2)從子表中刪除行:數據庫

pt-archiver --source h=host,D=db,t=child --purge \
  --where 'NOT EXISTS(SELECT * FROM parent WHERE col=child.col)'

參數說明:注意:至少須要指定--dest,--file,--purge 其中的一個。

1:--source :指定要歸檔表的信息,兼容DSN選項。 服務器

a:執行查詢時要使用的數據庫。
b:若是爲true,則使用SQL_LOG_BIN禁用binlog。
h:鏈接的MySQL主機名或IP地址。
D:鏈接時使用的默認數據庫,能夠在運行時使用不一樣的數據庫。
t:要被歸檔、刪除、導出的表。
i:進行歸檔、刪除、導出時,被指定使用的索引。
p:鏈接時使用的MySQL密碼。
P:鏈接時使用的MySQL端口。
S:用於鏈接的MySQL套接字文件(在Unix系統上)。
u:鏈接時使用的MySQL用戶名。
L:啓用LOAD DATA LOCAL INFILE。
A:鏈接MySQL的默認字符集(SET NAMES)。
F:經過配置文件讀取用戶名和密碼,如配置了〜/ .my.cnf,就會自動鏈接工具而無需用戶名或密碼。格式爲:
[client]
user=your_user_name
pass=secret

2:--dest:指定要歸檔到的表,兼容DSN選項。架構

此項指定一個表,pt-archiver將在其中插入從--source歸檔的行。 它使用與--source相同的參數格式。 大多數缺失值默認爲與--source相同的值,所以沒必要重複--source和--dest中相同的選項。若是--source和--dest的用戶名密碼不同,須要單獨各自指定,而且注意F和S參數。socket

3:--analyze:在--source或--dest上運行ANALYZE TABLE。字母's',將分析來源。 若是它包含'd',則將分析目的地。 您能夠指定其中一個或兩個工具

--analyze=ds

4:--ascend-first:升序索引優化,提供最左索引(多列主鍵)的升序。性能

5:--no-ascend:  不要使用升序索引優化。注意多列主鍵索引。測試

6:--ask-pass:鏈接MySQL時提示輸入密碼。優化

7:--buffer:緩衝區輸出到--file並在提交時刷新,每次事務提交禁止刷寫到磁盤,有操做系統決定刷寫。該參數能夠提升刷寫到文件的性能,但崩潰可能會有數據丟失。

8:--commit-each:控制事務大小,每次提取、歸檔就提交。禁用--txn-size。

9:--config:以逗號分隔的配置文件列表; 若是指定,則必須是命令行上的第一個選項。

10:--database:D,鏈接時使用的默認數據庫。

11:--delayed-insert:在insert後面添加delayed,延遲寫入。

12:--dry-run:打印查詢並退出而不作任何事情。

13:--file:要歸檔到的文件,使用以SELECT INTO OUTFILE相同的格式。如:--file '/var/log/archive/%Y-%m-%d-%D.%t'

%d    Day of the month, numeric (01..31)
%H    Hour (00..23)
%i    Minutes, numeric (00..59)
%m    Month, numeric (01..12)
%s    Seconds (00..59)
%Y    Year, numeric, four digits
%D    Database name
%t    Table name

14:--for-update:在每一個select語句後面加入for update。

15:--header:在--file頂部打印列標題。若是文件存在,不寫,能夠用LOAD DATA INFILE保存文件。

16:--high-priority-select:在每一個select語句上加入HIGH_PRIORITY。

17:--host:鏈接的MySQL地址。

18:--ignore:insert語句加入ignore。

19:--local:添加NO_WRITE_TO_BINLOG參數,OPTIMIZE 和 ANALYZE不寫binlog。

20:--low-priority-delete:每一個delete語句加入LOW_PRIORITY。

21:--low-priority-insert:每隔insert和replace語句加入LOW_PRIORITY。

22:--max-lag:默認1s,由--check-slave-lag給出的從延遲。獲取行時查看從庫,若是slave的延遲大於選項的值,或者slave沒有運行(所以它的滯後爲NULL),則pt-table-checksum會休眠--check-interval seconds,而後再次查看滯後。 它會一直重複,直到slave小於該參數,而後繼續獲取並歸檔該行。

23:--no-delete:不要刪除存檔的行,默認會刪除。不容許--no-ascend,由於啓用它們都會致使無限循環。

24:--optimize:在--source或--dest上運行以後OPTIMIZE TABLE。

25:--output-format:與--file一塊兒使用以指定輸出格式,格式至關於FIELDS TERMINATED BY','OPTIONALLY ENCLOSED BY'''。

26:--password:-p,鏈接MySQL時使用的密碼。 若是密碼包含逗號,則必須使用反斜槓進行轉義。

27:--pid:建立給定的PID文件。 若是PID文件已存在而且其包含的PID與當前PID不一樣,則該工具將不會啓動。 可是,若是PID文件存在且其包含的PID再也不運行,則該工具將使用當前PID覆蓋PID文件。 退出工具時會自動刪除PID文件。

28:--port:-P,鏈接MySQL時的端口。

29:--primary-key-only僅限主鍵列。用於指定具備主鍵列的--columns的快捷方式,當DELETE語句只須要主鍵列時,它能夠避免獲取整行。

30:--progress:每多少行打印進度信息:打印當前時間,已用時間以及每X行存檔的行數。

31:--purge:清除而不是歸檔; 容許省略--file和--dest。若是隻想清除行,請考慮使用--primary-key-only指定表的主鍵列。 這樣能夠防止平白無故地從服務器獲取全部列。

32:--quick-delete:delete語句裏添加quick。

33:--quite:-q,不打印任何輸出,包括--statistics的輸出,對--why-quit的輸出無效。

34:--replace:replace into代替insert into。

35:--retries:每次超時或死鎖的重試次數,默認1。

36:--run-time:退出前的時間。可選後綴s =秒,m =分鐘,h =小時,d =天; 默認s

37:--[no]safe-auto-increment:不要使用最大AUTO_INCREMENT歸檔行,默認yes。防止在服務器從新啓動時從新使用AUTO_INCREMENT值。

38:--sentinel:優雅的退出操做。指定的文件的存在將致使pt-archiver中止存檔並退出。 默認值爲/tmp/pt-archiver-sentinel。

39:--slave-user:鏈接從庫的用戶。用戶必須存在於全部從屬服務器上

40:--slave-password:鏈接從庫的密碼。用戶的密碼在全部從站上必須相同。

41:--set-vars:逗號分隔的variable = value對列表中設置MySQL變量。如:--set-vars wait_timeout = 500

42:--share-lock:在SELECT語句裏添加LOCK IN SHARE MODE。

43:--skip-foreign-key-checks:使用SET FOREIGN_KEY_CHECKS = 0禁用外鍵檢查。

44:--sleep:指定SELECT語句之間的休眠時間。 默認不sleep。 未提交事務,而且在休眠以前不會刷新--file文件。若是指定了--commit-each,則在休眠以前發生提交和刷新。

45:--sleep-coef:pt-archiver將在最後一次SELECT乘以指定係數的查詢時間內休眠。在每一個SELECT之間休眠不一樣的時間,具體取決於SELECT所花費的時間。

46:--socket:-S,用於鏈接的套接字文件。

47:--statistics:收集並打印時間統計信息。

Started at 2008-07-18T07:18:53, ended at 2008-07-18T07:18:53
Source: D=db,t=table
SELECT 4
INSERT 4
DELETE 4
Action         Count       Time        Pct
commit            10     0.1079      88.27
select             5     0.0047       3.87
deleting           4     0.0028       2.29
inserting          4     0.0028       2.28
other              0     0.0040       3.29


前兩行(或三行)顯示時間以及源表和目標表。接下來的三行顯示了提取,插入和刪除的行數。

其他行顯示計數和時間。列是操做,操做計時的總次數,花費的總時間以及程序總運行時間的百分比。行按照總時間降低的順序排序。最後一行是剩餘的時間沒有明確歸因於任何東西。操做將根據命令行選項而有所不一樣。

若是給出了--why-quit,它的行爲會略有改變。此選項使其打印退出的緣由,即便只是由於沒有更多的行。

48:--stop:經過建立sentinel文件中止運行實例。

49:--txn-size:每一個事務的行數,默認1。指定每一個事務的大小(行數)。0徹底禁用事務。在pt-archiver處理這麼多行以後,若是指定該參數,它會提交--source和--dest,並刷新--file給出的文件。

此參數對性能相當重要。若是要從實時服務器(例如正在執行大量OLTP工做)進行存檔,則須要在事務大小和提交開銷之間選擇良好的平衡。較大的事務會產生更多的鎖爭用和死鎖,但較小的事務會致使更頻繁的提交開銷,若是沒有從事務存儲引擎進行歸檔,則可能須要禁用事務。

50:--user:-u,鏈接MySQL時的用戶。

51:--version:查看版本號。

52:--[no]version-check:不檢查版本號,默認yes。適用於RDS。

53:--where:指定WHERE子句以限制存檔的行。 子句裏不要包含單詞WHERE,不須要WHERE子句,請使用--where 1=1。如:

--where 'ts < current_date - interval 90 day'

54:--limit:限制檢索要歸檔的行的SELECT語句返回的行數,默認是1。這可能會致使與其餘查詢的更多爭用,具體取決於存儲引擎,事務隔離級別和--for-update等選項。

55:--bulk-delete:使用單個DELETE語句批量刪除每一個行塊。該語句刪除塊的第一行和最後一行之間的每一行,隱含--commit-each。

56:--[no]bulk-delete-limit:添加--limit到--bulk-delete語句,默認yes。

57:--bulk-insert:使用LOAD DATA LOCAL INFILE插入每一個行塊。 比使用INSERT語句一次插入行快得多。 經過爲每一個行塊建立一個臨時文件,並將行寫入此文件而不是插入它來實現的。此選項會強制使用批量刪除。

58:--charset:-A,設置默認字符集。

59:--[no]check-charset:不檢查字符集, 禁用此檢查可能會致使文本被錯誤地從一個字符集轉換爲另外一個字符集。進行字符集轉換時,禁用此檢查可能有用。

60:--[no]check-columns:檢查--source和--dest具備相同的列,默認yes。它不檢查列順序,數據類型等。它只檢查源中的全部列是否存在於目標中。存在差別則退出。不檢查則用參數–no-check-columns。

61:--columns:指定歸檔的列,以逗號分隔的列的列表以獲取寫入文件並插入目標表。 若是指定,將忽略其餘列,除非它須要將它們添加到SELECT語句以提高索引或刪除行。

62:--check-slave-lag:暫停歸檔,直到指定的DSN的slave延遲小於--max-lag。能夠屢次指定此選項以檢查多個從庫。

63:--check-interval:檢查從庫延遲的間隔時間,默認1s。或則每100行執行一次檢查。

64:--why-quit:除非行耗盡,不然打印退出緣由。

注意:下面幾個參數都是互斥的,只能選其一:

"--ignore" and "--replace" are mutually exclusive. 
"--txn-size" and "--commit-each" are mutually exclusive.
"--low-priority-insert" and "--delayed-insert" are mutually exclusive.
"--share-lock" and "--for-update" are mutually exclusive.
"--analyze" and "--optimize" are mutually exclusive.
"--no-ascend" and "--no-delete" are mutually exclusive.

使用場景 

注意: 歸檔的表大小寫敏感,表必須至少有一個索引(Cannot find an ascendable index in table )。

①:導出到文件,不刪除源數據(--no-delete,默認刪除):

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc --file=/tmp/%Y-%m-%d-%D.%t --where="1=1" --no-delete --no-safe-auto-increment --progress=1000 --statistics 

 

分析:從general_log裏看到的流程是:source服務器讀取一條,file寫入一條,能夠經過--txn-size進行指定行數的提交。這裏須要注意的是,根據自增id進行歸檔的話,默認最大的id不會進行歸檔,須要添加參數:--no-safe-auto-increment 才能對最大id進行處理。

②:刪除,不導出和遷移:

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc --purge --where="1=1" --no-safe-auto-increment --progress=100 --statistics

分析: 從general_log裏看到的流程是:source服務器讀取一條再刪除一條提交,能夠加上--txn-size進行多個刪除放到一個事務提交。

③:全表歸檔(遷移),源表不刪除,非批量

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="1=1" --progress=1000 --statistics --no-delete

分析:從general_log裏看到的流程是:source服務器讀取一條,dest服務器寫入一條並commit,source再delete並commit(若是刪除源數據)。

④:全表歸檔(遷移),源表不刪除,批量插入

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="1=1" --progress=1000 --limit=1000 --statistics --bulk-insert --txn-size=1000 --no-delete

分析:從general_log裏看到的流程是:source服務器讀取一個範圍【FORCE INDEX(`PRIMARY`) WHERE (1=1) AND (`id` < '4999') AND ((`id` > '2733'))】,dest服務器經過【LOAD DATA LOCAL INFILE】進行批量插入。

⑤:全表歸檔(遷移),源表刪除,批量插入,批量刪除

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="1=1" --progress=1000 --limit=1000 --statistics --bulk-insert --bulk-delete --txn-size=1000

分析:從general_log裏看到的流程是:source服務器讀取一個範圍【FORCE INDEX(`PRIMARY`) WHERE (1=1) AND (`id` < '4999') AND ((`id` > '2733'))】,dest服務器經過【LOAD DATA LOCAL INFILE】進行批量插入,source再delete【WHERE (((`id` >= '1'))) AND (((`id` <= '2733'))) AND (1=1) LIMIT 1000】並commit。這裏須要注意的是,根據自增id進行歸檔的話,默認最大的id不會進行歸檔,須要添加參數:--no-safe-auto-increment 才能對最大id進行處理。

⑥:指定條件歸檔,源表刪除,批量(每1000個插入提交一次),若是源表不刪除,加上--no-delete便可。

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="id<=49999" --progress=1000 --statistics --bulk-insert --bulk-delete --txn-size=1000 --limit=1000

⑦:指定索引的歸檔,不走自增主鍵索引。參數:i

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc,i=idx_age --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="age >=80000 and age<100000" --progress=1000 --statistics --bulk-insert --bulk-delete --txn-size=1000 --limit=1000 --no-delete 

⑧:有從庫的歸檔,從庫延遲大於1s就暫停歸檔:--check-slave-lag

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc,i=idx_age --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="age >=100000 and age<150000" --progress=1000 --statistics --bulk-insert --bulk-delete --txn-size=1000 --limit=1000 --no-delete --max-lag=1 --check-slave-lag u=root,p=dba,h=10.24.35.181,P=16500 

當從庫延遲小於--max-lag設置的時間以後,繼續歸檔。要是有多個從庫的話,繼續指定--check-slave-lag參數,該參數能夠重複指定多個從庫。

⑨:不作任何操做,只打印要執行的查詢語句

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc,i=idx_age --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --where="age >=80000 and age<100000" --progress=1000 --statistics  --replace --txn-size=1000 --limit=1000 --no-delete  --dry-run

⑩:經常使用的命令:歸檔到另外一個數據庫,源表刪除,批量刪除和插入,每1000次修改進行提交。跳過錯誤而且指定字符集鏈接。

pt-archiver --source u=root,p=dba,h=100.47.47.47,P=16500,D=sbtest,t=abc,i=idx_age --dest u=root,p=dba,h=100.47.47.47,P=17500,D=sbtest,t=ABC --no-version-check --charset=UTF8 --where="age >=100000 and age<500000" --ignore --txn-size=1000 --limit=1000 --bulk-delete --bulk-insert --progress=5000 --statistics --why-quit

能夠根據本身的實際狀況,進行相關參數的調整。另外其餘相關參數說明:

--ignore或則--replace:歸檔衝突記錄跳過或則覆蓋,批量插入的時候由於是load data,索引看不到主鍵衝突記錄的報錯。要是非批量插入,則須要添加。

--sleep:指定兩次SELECT語句的sleep時間.默認是沒有sleep的。

--why-quit:打印退出的緣由,歸檔數據正常完成的除外。

--charset=UTF8:指定字符集。

--analyze:結束歸檔後,優化表空間。 

經常使用的參數:

--where 'id<3000' 設置操做條件
--limit 10000 每次取1000行數據給pt-archive處理
--txn-size 1000 設置1000行爲一個事務提交一次
--progress 5000 每處理5000行輸出一次處理信息
--statistics 結束的時候給出統計信息:開始的時間點,結束的時間點,查詢的行數,歸檔的行數,刪除的行數,以及各個階段消耗的總的時間和比例,便於以此進行優化。只要不加上--quiet,默認狀況下pt-archive都會輸出執行過程的
--charset=UTF8 指定字符集爲UTF8
--no-delete 表示不刪除原來的數據,注意:若是不指定此參數,全部處理完成後,都會清理原表中的數據
--bulk-delete 批量刪除source上的舊數據
--bulk-insert 批量插入數據到dest主機 (看dest的general log發現它是經過在dest主機上LOAD DATA LOCAL INFILE插入數據的)
--purge 刪除source數據庫的相關匹配記錄
--local 不把optimize或analyze操做寫入到binlog裏面(防止形成主從延遲巨大)
--analyze=ds 操做結束後,優化表空間(d表示dest,s表示source)
默認狀況下,pt-archiver操做結束後,不會對source、dest表執行analyze或optimize操做,由於這種操做費時間,而且須要你提早預估有足夠的磁盤空間用於拷貝表。通常建議也是pt-archiver操做結束後,在業務低谷手動執行analyze table用以回收表空間

注意:批量操做和單條操做提交性能有近10倍的差距。

總結

      pt-archiver實現的功能很簡單,工具也很輕量,能很是好的對數據進行低影響的歸檔和刪除,支持大部分場景。須要注意的是,畢竟是操做生產數據,使用以前還得多測試,根據實際狀況進行參數的調整優化。

相關文章
相關標籤/搜索