一.簡介
Percona Toolkit簡稱pt工具,PT-Tools是Percona公司開發用於管理MySQL的工具,功能包括檢查主從復制的數據一致性、檢查重復索引、定位IO占用高的表文件、在線DDL等,DBA熟悉掌握后將極大提高工作效率。下載地址為: https://www.percona.com/downloads/percona-toolkit/LATEST/,percona的網站國內有時打不開,可以訪問國內的清華鏡像,目前最新的版本是https://mirrors.cnnic.cn/percona/tools/yum/release/latest/RPMS/x86_64/percona-toolkit-3.2.1-1.el6.x86_64.rpm。
使用wget下載到本地wget --no-check-certificate https://mirrors.cnnic.cn/percona/tools/yum/release/latest/RPMS/x86_64/percona-toolkit-3.2.1-1.el6.x86_64.rpm
,執行yum install percona-toolkit-3.2.1-1.el6.x86_64.rpm
會自動安裝perl依賴包和percona-toolkit工具,默認安裝路徑在/usr/bin/
路徑,幫助文檔路徑/usr/share/man/man1/
,可以通過man 命名
直接獲取幫助文檔。
shell>pt
pt-align pt-fifo-split pt-kill pt-pmp pt-slave-restart pt-variable-advisor
pt-archiver pt-find pt-mext pt-query-digest pt-stalk pt-visual-explain
ptaskset pt-fingerprint pt-mongodb-query-digest pt-secure-collect pt-summary ptx
pt-config-diff pt-fk-error-logger pt-mongodb-summary pt-show-grants pt-table-checksum
pt-deadlock-logger pt-heartbeat pt-mysql-summary pt-sift pt-table-sync
pt-diskstats pt-index-usage pt-online-schema-change pt-slave-delay pt-table-usage
pt-duplicate-key-checker pt-ioprofile pt-pg-summary pt-slave-find pt-upgrade
pt工具主要包含如上命令,今天主要介紹幾個DBA必會的pt命令。
二.使用介紹
1.pt-archive
pt-archive是MySQL的在線歸檔工具,無影響生產,用此命令操作的表必須有主鍵。它實現的功能包括:
- 歸檔歷史數據
- 在線刪除大批量數據
- 數據導出和備份
- 數據遠程歸檔
- 數據清理
常用參數說明:
--limit 10000 每次取1000行數據用pt-archive處理
--txn-size 1000 設置1000行為一個事務提交一次
--where 'id<3000' 設置操作條件
--progress 5000 每處理5000行輸出一次處理信息
--statistics 輸出執行過程及最后的操作統計(只要不加上--quiet,默認情況下pt- archive都會輸出執行過程的)
--charset=UTF8 指定字符集為UTF8 這個最好加上不然可能出現亂碼。
--bulk-delete 批量刪除source上的舊數據(例如每次1000行的批量刪除操作)
使用示例:
- 歸檔,不刪除原表數據(--no-delete)
pt-archiver --source h=源ip,P=源端口,u=用戶,p=密碼,D=庫名,t=表名 --dest h=目標IP,P=端口,u=用戶,p=密碼,D=庫名,t=表名 --no-check-charset --where 'ID<100' --progress 5000 --no-delete --limit=10000 –statistics
- 歸檔, 刪除原表記錄(不用加no-delete)
pt-archiver --source h=源ip,P=源端口,u=用戶,p=密碼,D=庫名,t=表名 --dest h=目標IP,P=端口,u=用戶,p=密碼,D=庫名,t=表名 --no-check-charset --where 'ID<100' --progress 5000 --limit=10000 –statistics
- 加上字符
pt-archiver --charset 'utf8' --source h=源ip,P=源端口,u=用戶,p=密碼,D=庫名,t=表名 --dest h=目標IP,P=端口,u=用戶,p=密碼,D=庫名,t=表名 --no-check-charset --where 'ID<100' --progress 5000 --limit=10000 –statistics
- 直接刪除,不歸檔
pt-archiver --source h=127.0.0.1,P=端口,u=root,p=‘密碼',D=源庫,t=源表 --where 'ID<100' --purge --limit=5000 --no-check-charset --statistics --progress 5000
2.pt-kill
pt-kill 是一個優秀的kill MySQL連接的一個工具,是percona toolkit的一部分,這個工具可以kill掉你想Kill的任何語句,特別出現大量的阻塞,死鎖,某個有問題的sql導致mysql負載很高的情況。
常用參數說明:
--daemonize 放在后台以守護進程的形式運行
--interval 多久運行一次,單位可以是s,m,h,d等默認是s –不加這個默認是5秒
--victims 默認是oldest,只殺最古老的查詢。這是防止被查殺是不是真的長時間運行的查詢,他們只是長期等待,這種匹配按時間查詢,殺死一個時間最高值
--all 殺掉所有滿足的線程
--kill-query 只殺掉連接執行的語句,但是線程不會被終止
--print 打印滿足條件的語句
--busy-time 批次查詢已運行的時間超過這個時間的線程
--idle-time 殺掉sleep 空閑了多少時間的連接線程,必須在--match-command sleep時才有效—也就是匹配使用
--ignore-command 忽略相關的匹配
--match-command 匹配相關的語句 (這兩個搭配使用一定是ignore-command在前,match-command在后)
--match-db 匹配哪個庫
match-command:Query,Sleep,Binlog Dump,Connect,Delayed insert,Execute,Fetch,Init DB,Kill,Prepare,Processlist,Quit,Reset stmt,Table Dump
match-State:Locked,login,copy to tmp table,Copying to tmp table,Copying to tmp table on disk,Creating tmp table,executing,Reading from net,Sending data,Sorting for order,Sorting result,Table lock,Updating
使用示例:
- 殺掉空閑連接sleep60秒的SQL
/usr/bin/pt-kill --host=127.0.0.1 --user=用戶 --password=密碼 --port=端口 --match-command Sleep --idle-time 60 --victim all --interval 5 --kill --daemonize --pid=/tmp/ptkill.pid --print --log=/tmp/pt-kill.log &
- 查詢SELECT超過1分鍾的SQL
/usr/bin/pt-kill --host=127.0.0.1 --user=用戶 --password=密碼 --port=端口 --match-info "SELECT|select" --busy-time 60 --victim all --interval 5 --kill --daemonize --pid=/tmp/ptkill.pid --print --log=/home/pt-kill.log &
- kill掉state是Locked的SQL
/usr/bin/pt-kill --host=127.0.0.1 --user=用戶 --password=密碼 --port=端口 --victims all --match-state='Locked' --interval 5 --kill --daemonize --pid=/tmp/ptkill.pid --print --log=/home/pt-kill.log &
- 指定用戶進行kill
/usr/bin/pt-kill --host=127.0.0.1 --user=用戶 --password=密碼 --port=端口 --victims all --match-user='root' --interval 5 --kill --daemonize --pid=/tmp/ptkill.pid --print --log=/home/pt-kill.log &
- 指定某個庫和host地址進行kill
/usr/bin/pt-kill --host=127.0.0.1 --user=用戶 --password=密碼 --port=端口 --victims all --match-db='test' --match-host='10.0.0.51' --interval 10 --kill --daemonize --pid=/tmp/ptkill.pid --print --log=/home/pt-kill.log &
- 將kill掉的SQL插入到表中
/usr/bin/pt-kill --host=127.0.0.1 --user=root --password=‘密碼' --port=3306 --log-dsn D=庫名,t=表名 --create-log-table --busy-time=60 --victims all --kill-query --match-info "SELECT|select" --print &
3.pt-online-schema-change
pt-online-schema-change簡稱pt-osc在線更改表結構,可以實現在線加減字段、索引、修改字段屬性等功能。pt-osc模仿MySQL內部的改表方式進行改表,但整個改表過程是通過對原始表的拷貝來完成的,即在改表過程中原始表不會被鎖定,並不影響對該表的讀寫操作。
首先,osc創建與原始表相同的不包含數據的新表(下划線開頭)並按照需求進行表結構的修改,然后將原始表中的數據按逐步拷貝到新表中,當拷貝完成后,會自動同時修改原始表和新表的名字並默認將原始表刪除。有兩個注意點:被操作的表如果有 觸發器,或外鍵用不了。要特別注意(標准規范MySQL是不建議用外鍵與觸發器的)如果有,要把外鍵與觸發器去掉再操作。
工作原理:
- 創建一個和要執行 alter 操作的表一樣的新的空表結構(是alter之前的結構)
- 在新表執行alter table 語句(速度應該很快)
- 在原表中創建觸發器3個觸發器分別對應insert,update,delete操作
- 以一定塊大小從原表拷貝數據到臨時表,拷貝過程中通過原表上的觸發器在原表進行的寫操作都會更新到新建的臨時表
- Rename 原表到old表中,在把臨時表Rename為原表
- 如果有參考該表的外鍵,根據alter-foreign-keys-method參數的值,檢測外鍵相關的表,做相應設置的處理
- 默認最后將舊原表刪除,如果執行失敗了,或手動停止了,需要手動刪除下划線開頭的表(_表名)及三個觸發器
常用參數說明:
--max-load 默認為Threads_running=25。每個chunk拷貝完后,會檢查SHOW GLOBAL STATUS的內容,檢查指標是否超過了指定的閾值。如果超過,則先暫停。這里可以用逗號分隔,指定多個條件,每個條件格式: status指標=MAX_VALUE或者status指標:MAX_VALUE。如果不指定MAX_VALUE,那么工具會這只其為當前值的120%。
--critical-load 默認為Threads_running=50。用法基本與--max-load類似,如果不指定MAX_VALUE,那么工具會這只其為當前值的200%。如果超過指定值,則工具直接退出,而不是暫停。
--user: -u,連接的用戶名
--password: -p,連接的密碼
--database: -D,連接的數據庫
--port -P,連接數據庫的端口
--host: -h,連接的主機地址
--socket: -S,連接的套接字文件
--statistics 打印出內部事件的數目,可以看到復制數據插入的數目。
--dry-run 創建和修改新表,但不會創建觸發器、復制數據、和替換原表。並不真正執行,可以看到生成的執行語句,了解其執行步驟與細節。--dry-run與--execute必須指定一個,二者相互排斥。和--print配合最佳。
--execute 確定修改表,則指定該參數。真正執行。--dry-run與--execute必須指定一個,二者相互排斥。
--print 打印SQL語句到標准輸出。指定此選項可以讓你看到該工具所執行的語句,和--dry-run配合最佳。
--progress 復制數據的時候打印進度報告,二部分組成:第一部分是百分比,第二部分是時間。
--quiet -q,不把信息標准輸出。
使用示例:
- 添加索引
pt-online-schema-change --user=root --password='密碼' --port=端口 --host=127.0.0.1 --critical-load Threads_running=100 --alter "ADD INDEX index_name (column_name)" D=庫名,t=表名 --print --execute
- 添加列
pt-online-schema-change --user=root --password='密碼' --port=端口 --host=127.0.0.1 --critical-load Threads_running=200 --alter "ADD COLUMN column_name int(10)" D=庫名,t=表名 --print –execute
- 刪除列
pt-online-schema-change --user=root --password='密碼' --port=端口 --host=127.0.0.1 --critical-load Threads_running=200 --alter "drop column column_name" D=庫名,t=表名 --print –execute
- 列與索引同時添加操作
pt-online-schema-change --user=root --password='密碼' --port=6006 --host=127.0.0.1 --critical-load Threads_running=200 --alter "ADD COLUMN column_name int(10)" --alter "ADD INDEX index_name (column_name)" D=庫名,t=表名 --print --execute
4.pt-query-digest
pt-query-digest,用來進行慢查詢Log的分析,常用參數說明:
--create-review-table 當使用--review參數把分析結果輸出到表中時,如果沒有表就自動創建
--create-history-table 當使用--history參數把分析結果輸出到表中時,如果沒有表就自動創建
--filter 對輸入的慢查詢按指定的字符串進行匹配過濾后再進行分析
--limit限制輸出結果百分比或數量,默認值是20,即將最慢的20條語句輸出,如果是50%則按總響應時間占比從大到小排序,輸出到總和達到50%位置截止
--host mysql服務器地址
--host mysql服務器地址
--user mysql用戶名
--password mysql用戶密碼
--history 將分析結果保存到表中,分析結果比較詳細,下次再使用--history時,如果存在相同的語句,且查詢所在的時間區間和歷史表中的不同,則會記錄到數據表中,可以通過查詢同一CHECKSUM來比較某類型查詢的歷史變化
--review 將分析結果保存到表中,這個分析只是對查詢條件進行參數化,一個類型的查詢一條記錄,比較簡單。當下次使用--review時,如果存在相同的語句分析,就不會記錄到數據表中
--output 分析結果輸出類型,值可以是report(標准分析報告)、slowlog(Mysql slow log)、json、json-anon,一般使用report,以便於閱讀。
--since 從什么時間開始分析,值為字符串,可以是指定的某個”yyyy-mm-dd [hh:mm:ss]”格式的時間點,也可以是簡單的一個時間值:s(秒)、h(小時)、m(分鍾)、d(天),如12h就表示從12小時前開始統計
--until 截止時間,配合—since可以分析一段時間內的慢查詢
使用示例:
- 指定時間段的慢查詢
pt-query-digest /home/mysql/log/slow.log --since 'yyyy-mm-dd [hh:mm:ss]' --until 'yyyy-mm-dd [hh:mm:ss]'
- 把查詢保存到query_review表
pt-query-digest --user=root –password=密碼 --review h=localhost,D=test,t=query_review--create-review-table slow.log
- 分析指含有select語句的慢查詢
pt-query-digest --filter '$event->{fingerprint} =~ m/^select/i' /home/mysql/log/slow.log > slow_report.log
- 針對某個用戶的慢查詢
pt-query-digest --filter '($event->{user} || "") =~ m/^root/i' /home/mysql/log/slow.log > slow_report.log
5.pt-table-checksum & pt-table-sync
pt-table-checksum & pt-table-sync,檢查主從是否一致性,檢查主從不一致之后用這個工具進行處理,這兩個一搬是搭配使用。
常用參數介紹:
replicate=test.checksum:主從不一致的結果放到哪一張表中,一般我放在一個既有的數據庫中,這個checksum表由pt-table-checksum工具自行建立
databases=testdb:我們要檢測的數據庫有哪些,這里是testdb數據庫,如果想檢測所有數據庫那么就不要寫這個參數了,如果有多個數據庫,我們用逗號連接就可以了
host='127.0.0.1':主庫的IP地址或者主機名
user=dba :主機用戶名(確定此用戶可以訪問主從數據庫)
port=6006:主庫端口號
recursion-method=hosts :主庫探測從庫的方式
empty-replicate-table:清理上一次的檢測結果后開始新的檢測
no-check-bin-log-format:不檢查二進制日志格式,鑒於目前大多數生產數據庫都將二進制日志設置為“ROW”格式,而我們的pt-table-checksum會話會自行設定使用“STATEMENT”格式,所以這個選項請務必加上
使用示例:
pt-table-checksum --nocheck-replication-filters --no-check-binlog-format --replicate=test.checksums --recursion-method=hosts --databases=log_manage h=localhost,u=用戶,p=密碼,P=端口
檢測DIFF有異常時,立刻到從庫去看,通過在從庫中查詢replicate參數指定的test.checksum表得出:
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks FROM test.checksums WHERE ( master_cnt <> this_cnt OR master_crc <> this_crc OR ISNULL(master_crc) <> ISNULL(this_crc)) GROUP BY db, tbl;
檢測有差異之后到從庫上執行一下修復,前提是此表必須要有主鍵或唯一索引:
pt-table-sync --sync-to-master --replicate=test.checksums h=127.0.0.1,u=用戶,P=端口,p=密碼 --print
6.pt-find
pt-find,找出幾天之前建立的表,使用示例:
- 找出大於10G的表
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口 --tablesize +10G
- 30分鍾之修改過的表
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口 --mmin -30
- 沒有數據的表
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口 --empty
- 找出1天以前的表,存儲引擎是MyISAM
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口--ctime +1 --engine MyISAM
- 找出存儲引擎為MyISAM的表修改為InnoDB
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口 --engine MyISAM --exec "ALTER TABLE %D.%N ENGINE=InnoDB"
- 找出test1,test2庫里的空表並刪除
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口 --empty test1 test2 --exec-plus "DROP TABLE %s"
- 找到所有的表,根據數據和索引總大小,從大到小排序
/usr/bin/pt-find --socket=/tmp/mysqld.sock --user=root --password=密碼 --port=端口 --printf "%T\t%D.%N\n" | sort -rn
7.pt-mysql-summary
pt-mysql-summary,打印出來MySQL的描述信息,包括:版本信息,數據目錄,命令的統計,用戶,數據庫以及復制等信息還包括各個變量(status、variables)信息和各個變量的比例信息,還有配置文件等信息。
pt-mysql-summary --user=root --password=密碼 --host=127.0.0.1 --port=端口
8.Pt-summary
Pt-summary,打印出來的信息包括:CPU、內存、硬盤、網卡等信息,還包括文件系統、磁盤調度和隊列大小、LVM、RAID、網絡鏈接信息、netstat 的統計,以及前10的負載占用信息和vmstat信息。
9.pt-align
pt-align常用於列格式化輸出,功能單一,但是實用性極強。
示例文件如下:
DATABASE TABLE ROWS
foo bar 100
long_db_name table 1
another long_name 500
經過pt-align處理
DATABASE TABLE ROWS
foo bar 100
long_db_name table 1
another long_name 500
10.pt-config-diff
pt-config-diff,比較MySQL配置文件的不同
參數說明:
h:數據庫主機
P:端口號
u:用戶名
p:密碼
使用示例:
- 比較host1和host2配置文件不同
pt-config-diff h=host1 h=host2
- 比較[mysqld]標簽和host1不同
pt-config-diff /etc/my.cnf h=host1
輸出結果如下:
pt-config-diff /etc/my-small.cnf /etc/my-large.cnf
2 config differences
Variable my.master.cnf my.slave.cnf
========================= =============== ===============
datadir /tmp/12345/data /tmp/12346/data
port 12345 12346
11.pt-deadlock-logger
pt-deadlock-logger可以記錄MySQL中的死鎖信息到指定的地方,便於集中分析。
使用示例:
將host1主機產生的死鎖信息保存在host2主機test庫下面的deadlocks表中,--create-dest-table表示
pt-deadlock-logger h=host1,P=端口,u=用戶,p=密碼 --dest h=host2,P=端口,u=用戶,p=密碼,D=test,t=deadlocks --create-dest-table --log=/home/mysql/deadlock.log --daemonize --interval 5 --run-time 2m --iterations 4