使用 pt-query-digest 分析 RDS MySQL 慢查询日志
- 2019-10-05
本文字数:25965 字
阅读完需:约 85 分钟
前言
本文主要讲述如何使用 pt-query-digest 工具对 RDS MySQL 的 slow log 进行分析。
关于 RDS MySQL
MySQL 是世界上最流行的开源关系数据库,而 Amazon RDS 让你能够在云中轻松设置、操作和扩展 MySQL 部署。借助 Amazon RDS ,您可以在几分钟内快速部署可扩展的 MySQL 服务器,不仅经济实惠,还可以根据需要随时调整硬件容量的大小。
Amazon RDS for MySQL 可以管理备份、软件修补、监控、扩展和复制等耗时的数据库管理任务,让你能专注于应用程序开发和提供业务竞争力。
Amazon RDS 目前支持 5.5、5.6、5.7 和 8.0 版 MySQL Community Edition。
关于 pt-query-digest
对于数据库的日常管理工作,性能管理肯定会是占比最大的一块,“工欲善其事必先利其器”,一个好的性能分析工具会极大的提高数据库性能管理的效率,而 pt-query-digest 就是专门针对 MySQL 数据库慢查询日志的一个强力分析工具,相比于 mysqldumpslow ,其分析结果更加具体和完善。
pt-query-digest 属于 Percona Toolkit 工具集中最常用的一种,号称 MySQL DBA 必备工具之一,其能够分析 MySQL 数据库的 slow log 、 general log 、 binary log 文件,同时也可以使用 show processlist 或从 tcpdump 抓取的 MySQL 协议数据来进行分析。
安装 Percona Toolkit
安装最新的 percona release package
[root@ip-172-31-36-44 ~]# yum install https://repo.percona.com/yum/percona-release-latest.noarch.rpm
Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
percona-release-latest.noarch.rpm | 16 kB 00:00:00
Examining /var/tmp/yum-root-jxf0g4/percona-release-latest.noarch.rpm: percona-release-1.0-9.noarch
Marking /var/tmp/yum-root-jxf0g4/percona-release-latest.noarch.rpm to be installed
Resolving Dependencies
--> Running transaction check
---> Package percona-release.noarch 0:1.0-9 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=================================================================================================================================================================================
Package Arch Version Repository Size
=================================================================================================================================================================================
Installing:
percona-release noarch 1.0-9 /percona-release-latest.noarch 18 k
Transaction Summary
=================================================================================================================================================================================
Install 1 Package
Total size: 18 k
Installed size: 18 k
Is this ok [y/d/N]: y
Downloading packages:
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : percona-release-1.0-9.noarch 1/1
* Enabling the Percona Original repository
<*> All done!
The percona-release package now contains a percona-release script that can enable additional repositories for our newer products.
For example, to enable the Percona Server 8.0 repository use:
percona-release setup ps80
Note: To avoid conflicts with older product versions, the percona-release setup command may disable our original repository for some products.
For more information, please visit:
https://www.percona.com/doc/percona-repo-config/percona-release.html
Verifying : percona-release-1.0-9.noarch 1/1
Installed:
percona-release.noarch 0:1.0-9
Complete!
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# ls -ltr /etc/yum.repos.d/
total 24
-rw-r--r--. 1 root root 8679 Mar 18 03:32 redhat-rhui.repo
-rw-r--r--. 1 root root 90 Mar 18 03:32 rhui-load-balancers.conf
-rw-r--r--. 1 root root 607 Mar 18 03:32 redhat-rhui-client-config.repo
-rw-r--r--. 1 root root 780 Mar 18 03:55 percona-original-release.repo
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# rpm -aq|grep percona
percona-release-1.0-9.noarch
percona-toolkit-3.0.13-1.el7.x86_64
[root@ip-172-31-36-44 ~]#
安装 percona toolkit
[root@ip-172-31-36-44 ~]# yum install percona-toolkit
Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
Resolving Dependencies
--> Running transaction check
---> Package percona-toolkit.x86_64 0:3.0.13-1.el7 will be installed
--> Processing Dependency: perl(DBI) >= 1.13 for package: percona-toolkit-3.0.13-1.el7.x86_64
--> Processing Dependency: perl(DBD::mysql) >= 1.0 for package: percona-toolkit-3.0.13-1.el7.x86_64
--> Processing Dependency: perl(IO::Socket::SSL) for package: percona-toolkit-3.0.13-1.el7.x86_64
--> Processing Dependency: perl(Digest::MD5) for package: percona-toolkit-3.0.13-1.el7.x86_64
--> Processing Dependency: perl(Term::ReadKey) for package: percona-toolkit-3.0.13-1.el7.x86_64
--> Running transaction check
---> Package perl-DBD-MySQL.x86_64 0:4.023-6.el7 will be installed
---> Package perl-DBI.x86_64 0:1.627-4.el7 will be installed
--> Processing Dependency: perl(RPC::PlClient) >= 0.2000 for package: perl-DBI-1.627-4.el7.x86_64
--> Processing Dependency: perl(RPC::PlServer) >= 0.2001 for package: perl-DBI-1.627-4.el7.x86_64
--> Processing Dependency: perl(Data::Dumper) for package: perl-DBI-1.627-4.el7.x86_64
---> Package perl-Digest-MD5.x86_64 0:2.52-3.el7 will be installed
--> Processing Dependency: perl(Digest::base) >= 1.00 for package: perl-Digest-MD5-2.52-3.el7.x86_64
---> Package perl-IO-Socket-SSL.noarch 0:1.94-7.el7 will be installed
--> Processing Dependency: perl(IO::Socket::IP) >= 0.20 for package: perl-IO-Socket-SSL-1.94-7.el7.noarch
--> Processing Dependency: perl(Net::SSLeay) >= 1.21 for package: perl-IO-Socket-SSL-1.94-7.el7.noarch
--> Processing Dependency: perl-Net-SSLeay >= 1.55-5 for package: perl-IO-Socket-SSL-1.94-7.el7.noarch
--> Processing Dependency: perl(Mozilla::CA) for package: perl-IO-Socket-SSL-1.94-7.el7.noarch
--> Processing Dependency: perl(Net::LibIDN) for package: perl-IO-Socket-SSL-1.94-7.el7.noarch
--> Processing Dependency: perl(Net::SSLeay) for package: perl-IO-Socket-SSL-1.94-7.el7.noarch
---> Package perl-TermReadKey.x86_64 0:2.30-20.el7 will be installed
--> Running transaction check
---> Package perl-Data-Dumper.x86_64 0:2.145-3.el7 will be installed
---> Package perl-Digest.noarch 0:1.17-245.el7 will be installed
---> Package perl-IO-Socket-IP.noarch 0:0.21-5.el7 will be installed
---> Package perl-Mozilla-CA.noarch 0:20130114-5.el7 will be installed
---> Package perl-Net-LibIDN.x86_64 0:0.12-15.el7 will be installed
---> Package perl-Net-SSLeay.x86_64 0:1.55-6.el7 will be installed
---> Package perl-PlRPC.noarch 0:0.2020-14.el7 will be installed
--> Processing Dependency: perl(Net::Daemon) >= 0.13 for package: perl-PlRPC-0.2020-14.el7.noarch
--> Processing Dependency: perl(Compress::Zlib) for package: perl-PlRPC-0.2020-14.el7.noarch
--> Processing Dependency: perl(Net::Daemon::Log) for package: perl-PlRPC-0.2020-14.el7.noarch
--> Processing Dependency: perl(Net::Daemon::Test) for package: perl-PlRPC-0.2020-14.el7.noarch
--> Running transaction check
---> Package perl-IO-Compress.noarch 0:2.061-2.el7 will be installed
--> Processing Dependency: perl(Compress::Raw::Bzip2) >= 2.061 for package: perl-IO-Compress-2.061-2.el7.noarch
--> Processing Dependency: perl(Compress::Raw::Zlib) >= 2.061 for package: perl-IO-Compress-2.061-2.el7.noarch
---> Package perl-Net-Daemon.noarch 0:0.48-5.el7 will be installed
--> Running transaction check
---> Package perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.el7 will be installed
---> Package perl-Compress-Raw-Zlib.x86_64 1:2.061-4.el7 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=================================================================================================================================================================================
Package Arch Version Repository Size
=================================================================================================================================================================================
Installing:
percona-toolkit x86_64 3.0.13-1.el7 percona-release-x86_64 7.4 M
Installing for dependencies:
perl-Compress-Raw-Bzip2 x86_64 2.061-3.el7 rhui-REGION-rhel-server-releases 32 k
perl-Compress-Raw-Zlib x86_64 1:2.061-4.el7 rhui-REGION-rhel-server-releases 57 k
perl-DBD-MySQL x86_64 4.023-6.el7 rhui-REGION-rhel-server-releases 140 k
perl-DBI x86_64 1.627-4.el7 rhui-REGION-rhel-server-releases 802 k
perl-Data-Dumper x86_64 2.145-3.el7 rhui-REGION-rhel-server-releases 47 k
perl-Digest noarch 1.17-245.el7 rhui-REGION-rhel-server-releases 23 k
perl-Digest-MD5 x86_64 2.52-3.el7 rhui-REGION-rhel-server-releases 30 k
perl-IO-Compress noarch 2.061-2.el7 rhui-REGION-rhel-server-releases 260 k
perl-IO-Socket-IP noarch 0.21-5.el7 rhui-REGION-rhel-server-releases 36 k
perl-IO-Socket-SSL noarch 1.94-7.el7 rhui-REGION-rhel-server-releases 114 k
perl-Mozilla-CA noarch 20130114-5.el7 rhui-REGION-rhel-server-releases 11 k
perl-Net-Daemon noarch 0.48-5.el7 rhui-REGION-rhel-server-releases 51 k
perl-Net-LibIDN x86_64 0.12-15.el7 rhui-REGION-rhel-server-releases 28 k
perl-Net-SSLeay x86_64 1.55-6.el7 rhui-REGION-rhel-server-releases 286 k
perl-PlRPC noarch 0.2020-14.el7 rhui-REGION-rhel-server-releases 36 k
perl-TermReadKey x86_64 2.30-20.el7 rhui-REGION-rhel-server-releases 31 k
Transaction Summary
=================================================================================================================================================================================
Install 1 Package (+16 Dependent packages)
Total download size: 9.4 M
Installed size: 12 M
Is this ok [y/d/N]: y
Downloading packages:
(1/17): perl-Compress-Raw-Bzip2-2.061-3.el7.x86_64.rpm | 32 kB 00:00:00
(2/17): perl-Compress-Raw-Zlib-2.061-4.el7.x86_64.rpm | 57 kB 00:00:00
(3/17): perl-DBD-MySQL-4.023-6.el7.x86_64.rpm | 140 kB 00:00:00
(4/17): perl-Data-Dumper-2.145-3.el7.x86_64.rpm | 47 kB 00:00:00
(5/17): perl-DBI-1.627-4.el7.x86_64.rpm | 802 kB 00:00:00
(6/17): perl-Digest-1.17-245.el7.noarch.rpm | 23 kB 00:00:00
(7/17): perl-Digest-MD5-2.52-3.el7.x86_64.rpm | 30 kB 00:00:00
(8/17): perl-IO-Compress-2.061-2.el7.noarch.rpm | 260 kB 00:00:00
(9/17): perl-IO-Socket-IP-0.21-5.el7.noarch.rpm | 36 kB 00:00:00
(10/17): perl-IO-Socket-SSL-1.94-7.el7.noarch.rpm | 114 kB 00:00:00
(11/17): perl-Mozilla-CA-20130114-5.el7.noarch.rpm | 11 kB 00:00:00
(12/17): perl-Net-Daemon-0.48-5.el7.noarch.rpm | 51 kB 00:00:00
(13/17): perl-Net-LibIDN-0.12-15.el7.x86_64.rpm | 28 kB 00:00:00
(14/17): perl-PlRPC-0.2020-14.el7.noarch.rpm | 36 kB 00:00:00
(15/17): perl-Net-SSLeay-1.55-6.el7.x86_64.rpm | 286 kB 00:00:00
(16/17): perl-TermReadKey-2.30-20.el7.x86_64.rpm | 31 kB 00:00:00
(17/17): percona-toolkit-3.0.13-1.el7.x86_64.rpm | 7.4 MB 00:00:03
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Total 2.4 MB/s | 9.4 MB 00:00:03
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : perl-Digest-1.17-245.el7.noarch 1/17
Installing : perl-Digest-MD5-2.52-3.el7.x86_64 2/17
Installing : perl-Compress-Raw-Bzip2-2.061-3.el7.x86_64 3/17
Installing : perl-Net-LibIDN-0.12-15.el7.x86_64 4/17
Installing : 1:perl-Compress-Raw-Zlib-2.061-4.el7.x86_64 5/17
Installing : perl-IO-Compress-2.061-2.el7.noarch 6/17
Installing : perl-Net-SSLeay-1.55-6.el7.x86_64 7/17
Installing : perl-IO-Socket-IP-0.21-5.el7.noarch 8/17
Installing : perl-Data-Dumper-2.145-3.el7.x86_64 9/17
Installing : perl-TermReadKey-2.30-20.el7.x86_64 10/17
Installing : perl-Net-Daemon-0.48-5.el7.noarch 11/17
Installing : perl-PlRPC-0.2020-14.el7.noarch 12/17
Installing : perl-DBI-1.627-4.el7.x86_64 13/17
Installing : perl-DBD-MySQL-4.023-6.el7.x86_64 14/17
Installing : perl-Mozilla-CA-20130114-5.el7.noarch 15/17
Installing : perl-IO-Socket-SSL-1.94-7.el7.noarch 16/17
Installing : percona-toolkit-3.0.13-1.el7.x86_64 17/17
Verifying : perl-Mozilla-CA-20130114-5.el7.noarch 1/17
Verifying : perl-Net-Daemon-0.48-5.el7.noarch 2/17
Verifying : perl-TermReadKey-2.30-20.el7.x86_64 3/17
Verifying : perl-Data-Dumper-2.145-3.el7.x86_64 4/17
Verifying : perl-Digest-MD5-2.52-3.el7.x86_64 5/17
Verifying : perl-IO-Socket-IP-0.21-5.el7.noarch 6/17
Verifying : percona-toolkit-3.0.13-1.el7.x86_64 7/17
Verifying : perl-DBD-MySQL-4.023-6.el7.x86_64 8/17
Verifying : perl-PlRPC-0.2020-14.el7.noarch 9/17
Verifying : perl-Net-SSLeay-1.55-6.el7.x86_64 10/17
Verifying : 1:perl-Compress-Raw-Zlib-2.061-4.el7.x86_64 11/17
Verifying : perl-Net-LibIDN-0.12-15.el7.x86_64 12/17
Verifying : perl-Compress-Raw-Bzip2-2.061-3.el7.x86_64 13/17
Verifying : perl-Digest-1.17-245.el7.noarch 14/17
Verifying : perl-DBI-1.627-4.el7.x86_64 15/17
Verifying : perl-IO-Compress-2.061-2.el7.noarch 16/17
Verifying : perl-IO-Socket-SSL-1.94-7.el7.noarch 17/17
Installed:
percona-toolkit.x86_64 0:3.0.13-1.el7
Dependency Installed:
perl-Compress-Raw-Bzip2.x86_64 0:2.061-3.el7 perl-Compress-Raw-Zlib.x86_64 1:2.061-4.el7 perl-DBD-MySQL.x86_64 0:4.023-6.el7 perl-DBI.x86_64 0:1.627-4.el7
perl-Data-Dumper.x86_64 0:2.145-3.el7 perl-Digest.noarch 0:1.17-245.el7 perl-Digest-MD5.x86_64 0:2.52-3.el7 perl-IO-Compress.noarch 0:2.061-2.el7
perl-IO-Socket-IP.noarch 0:0.21-5.el7 perl-IO-Socket-SSL.noarch 0:1.94-7.el7 perl-Mozilla-CA.noarch 0:20130114-5.el7 perl-Net-Daemon.noarch 0:0.48-5.el7
perl-Net-LibIDN.x86_64 0:0.12-15.el7 perl-Net-SSLeay.x86_64 0:1.55-6.el7 perl-PlRPC.noarch 0:0.2020-14.el7 perl-TermReadKey.x86_64 0:2.30-20.el7
Complete!
[root@ip-172-31-36-44 ~]#
验证 pt-queyr-digest 是否可以使用
[root@ip-172-31-36-44 ~]# pt-query-digest --help
pt-query-digest analyzes MySQL queries from slow, general, and binary log files.
It can also analyze queries from C<SHOW PROCESSLIST> and MySQL protocol data
from tcpdump. By default, queries are grouped by fingerprint and reported in
descending order of query time (i.e. the slowest queries first). If no C<FILES>
are given, the tool reads C<STDIN>. The optional C<DSN> is used for certain
options like L<"--since"> and L<"--until">. For more details, please use the
--help option, or try 'perldoc /bin/pt-query-digest' for complete documentation.
Usage: pt-query-digest [OPTIONS] [FILES] [DSN]
Options:
--ask-pass Prompt for a password when connecting to MySQL
--attribute-aliases=a List of attribute|alias,etc (default db|Schema)
--attribute-value-limit=i A sanity limit for attribute values (default 0)
--charset=s -A Default character set
--config=A Read this comma-separated list of config files;
if specified, this must be the first option on
the command line
--[no]continue-on-error Continue parsing even if there is an error (
default yes)
--[no]create-history-table Create the --history table if it does not exist (
default yes)
--[no]create-review-table Create the --review table if it does not exist (
default yes)
--daemonize Fork to the background and detach from the shell
--database=s -D Connect to this database
--defaults-file=s -F Only read mysql options from the given file
--embedded-attributes=a Two Perl regex patterns to capture pseudo-
attributes embedded in queries
--expected-range=a Explain items when there are more or fewer than
expected (default 5,10)
--explain=d Run EXPLAIN for the sample query with this DSN
and print results
--filter=s Discard events for which this Perl code doesn't
return true
--group-by=A Which attribute of the events to group by (
default fingerprint)
--help Show help and exit
--history=d Save metrics for each query class in the given
table. pt-query-digest saves query metrics (
query time, lock time, etc.) to this table so
you can see how query classes change over time
--host=s -h Connect to host
--ignore-attributes=a Do not aggregate these attributes (default arg,
cmd, insert_id, ip, port, Thread_id, timestamp,
exptime, flags, key, res, val, server_id,
offset, end_log_pos, Xid)
--inherit-attributes=a If missing, inherit these attributes from the
last event that had them (default db,ts)
--interval=f How frequently to poll the processlist, in
seconds (default .1)
--iterations=i How many times to iterate through the collect-
and-report cycle (default 1)
--limit=A Limit output to the given percentage or count (
default 95%:20)
--log=s Print all output to this file when daemonized
--max-hostname-length=i Trim host names in reports to this length. 0=Do
not trim host names (default 10)
--max-line-length=i Trim lines to this length. 0=Do not trim lines (
default 74)
--order-by=A Sort events by this attribute and aggregate
function (default Query_time:sum)
--outliers=a Report outliers by attribute:percentile:count (
default Query_time:1:10)
--output=s How to format and print the query analysis
results (default report)
--password=s -p Password to use when connecting
--pid=s Create the given PID file
--port=i -P Port number to use for connection
--preserve-embedded-numbers Preserve numbers in database/table names when
fingerprinting queries
--processlist=d Poll this DSN's processlist for queries, with --
interval sleep between
--progress=a Print progress reports to STDERR (default time,
30)
--read-timeout=m Wait this long for an event from the input; 0 to
wait forever (default 0). Optional suffix s=
seconds, m=minutes, h=hours, d=days; if no
suffix, s is used.
--[no]report Print query analysis reports for each --group-by
attribute (default yes)
--report-all Report all queries, even ones that have been
reviewed
--report-format=A Print these sections of the query analysis
report (default rusage,date,hostname,files,
header,profile,query_report,prepared)
--report-histogram=s Chart the distribution of this attribute's
values (default Query_time)
--resume=s If specified, the tool writes the last file
offset, if there is one, to the given filename
--review=d Save query classes for later review, and don't
report already reviewed classes
--run-time=m How long to run for each --iterations. Optional
suffix s=seconds, m=minutes, h=hours, d=days; if
no suffix, s is used.
--run-time-mode=s Set what the value of --run-time operates on (
default clock)
--sample=i Filter out all but the first N occurrences of
each query
--set-vars=A Set the MySQL variables in this comma-separated
list of variable=value pairs
--show-all=H Show all values for these attributes
--since=s Parse only queries newer than this value (parse
queries since this date)
--slave-password=s Sets the password to be used to connect to the
slaves
--slave-user=s Sets the user to be used to connect to the slaves
--socket=s -S Socket file to use for connection
--timeline Show a timeline of events
--type=A The type of input to parse (default slowlog)
--until=s Parse only queries older than this value (parse
queries until this date)
--user=s -u User for login if not current user
--variations=A Report the number of variations in these
attributes' values
--version Show version and exit
--[no]version-check Check for the latest version of Percona Toolkit,
MySQL, and other programs (default yes)
--[no]vertical-format Output a trailing "\G" in the reported SQL
queries (default yes)
--watch-server=s This option tells pt-query-digest which server
IP address and port (like "10.0.0.1:3306") to
watch when parsing tcpdump (for --type tcpdump);
all other servers are ignored
Option types: s=string, i=integer, f=float, h/H/a/A=comma-separated list, d=DSN, z=size, m=time
Rules:
This tool accepts additional command-line arguments. Refer to the SYNOPSIS and usage information for details.
DSN syntax is key=value[,key=value...] Allowable DSN keys:
KEY COPY MEANING
=== ==== =============================================
A yes Default character set
D yes Default database to use when connecting to MySQL
F yes Only read default options from the given file
P yes Port number to use for connection
S yes Socket file to use for connection
h yes Connect to host
p yes Password to use when connecting
t no The --review or --history table
u yes User for login if not current user
If the DSN is a bareword, the word is treated as the 'h' key.
Options and values after processing arguments:
--ask-pass FALSE
--attribute-aliases db|Schema
--attribute-value-limit 0
--charset (No value)
--config /etc/percona-toolkit/percona-toolkit.conf,/etc/percona-toolkit/pt-query-digest.conf,/root/.percona-toolkit.conf,/root/.pt-query-digest.conf
--continue-on-error TRUE
--create-history-table TRUE
--create-review-table TRUE
--daemonize FALSE
--database (No value)
--defaults-file (No value)
--embedded-attributes (No value)
--expected-range 5,10
--explain (No value)
--filter (No value)
--group-by fingerprint
--help TRUE
--history (No value)
--host (No value)
--ignore-attributes arg,cmd,insert_id,ip,port,Thread_id,timestamp,exptime,flags,key,res,val,server_id,offset,end_log_pos,Xid
--inherit-attributes db,ts
--interval .1
--iterations 1
--limit 95%:20
--log (No value)
--max-hostname-length 10
--max-line-length 74
--order-by Query_time:sum
--outliers Query_time:1:10
--output report
--password (No value)
--pid (No value)
--port (No value)
--preserve-embedded-numbers FALSE
--processlist (No value)
--progress time,30
--read-timeout 0
--report TRUE
--report-all FALSE
--report-format rusage,date,hostname,files,header,profile,query_report,prepared
--report-histogram Query_time
--resume (No value)
--review (No value)
--run-time (No value)
--run-time-mode clock
--sample (No value)
--set-vars
--show-all
--since (No value)
--slave-password (No value)
--slave-user (No value)
--socket (No value)
--timeline FALSE
--type slowlog
--until (No value)
--user (No value)
--variations
--version FALSE
--version-check TRUE
--vertical-format TRUE
--watch-server (No value)
[root@ip-172-31-36-44 ~]#
安装及配置 AWSCLI
这里安装 awscli 主要是为了后续可以使用 awscli 下载 RDS MySQL 的 slow log 文件到本地,供 pt-query-digest 进行分析。
安装 awscli
curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
./awscli-bundle/install
echo "export PATH=$PATH:/root/.local/lib/aws/bin" >> ~/.bash_profile
source ~/.bash_profile
cat ~/.bash_profile
配置 awscli
[root@ip-172-31-36-44 ~]# aws configure
AWS Access Key ID [None]: AKIAXXXXXXXX6PPVDJKQ
AWS Secret Access Key [None]: BhlGgQLOjEcxxxxx/w3JxxxxxxUCI4IAra92ZJ
Default region name [None]: cn-northwest-1
Default output format [None]:
[root@ip-172-31-36-44 ~]#
安装 MySQL 客户端
这里安装 MySQL 客户端主要是为了后续可以使用 mysql 命令进行相关 sql 语句的执行,以获取 RDS MySQL 的 slow log 文件到本地,供 pt-query-digest 进行分析。
[root@ip-172-31-36-44 ~]# yum install mariadb.x86_64 -y
Loaded plugins: amazon-id, rhui-lb, search-disabled-repos
Resolving Dependencies
--> Running transaction check
---> Package mariadb.x86_64 1:5.5.60-1.el7_5 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
=================================================================================================================================================================================
Package Arch Version Repository Size
=================================================================================================================================================================================
Installing:
mariadb x86_64 1:5.5.60-1.el7_5 rhui-REGION-rhel-server-releases 8.6 M
Transaction Summary
=================================================================================================================================================================================
Install 1 Package
Total download size: 8.6 M
Installed size: 49 M
Downloading packages:
mariadb-5.5.60-1.el7_5.x86_64.rpm | 8.6 MB 00:00:00
Running transaction check
Running transaction test
Transaction test succeeded
Running transaction
Installing : 1:mariadb-5.5.60-1.el7_5.x86_64 1/1
Verifying : 1:mariadb-5.5.60-1.el7_5.x86_64 1/1
Installed:
mariadb.x86_64 1:5.5.60-1.el7_5
Complete!
[root@ip-172-31-36-44 ~]#
使用 pt-query-digest 分析 slow log
前面我们已经完成了所有的准备工作,现在看看如何来使用 pt-query-digest 工具分析 RDS MySQL 的 slow log 文件。
如果要分析 slow log,第一步就是先要获取到 slow log 文件,由于 RDS MySQL 是托管数据库,我们无法登录到 MySQL 所在服务器,那么应该如何来获取 slow log 文件呢?
根据 MySQL slow log 的相关配置,我们知道 slow log 的存在形式一共有两种: table 或 file ,由 log_output 参数进行控制:
TABLE (默认) – 将一般查询写入 general_log 表,将慢速查询写入 mysql.slow_log 表;
FILE – 将一般查询日志和慢速查询日志写入文件系统;
NONE – 禁用日志记录;
针对不同形式的 slow log,我们有不同的方法将其下载到本地:
TABLE :由于这是将慢查询记录存放在 MySQL 的数据表里,这里我们可以使用 sql 命令将其输出到本地的一个文件;
FILE :慢查询日志存放在 RDS MySQL 托管主机上,我们可以利用 awscli 提供的 RDS API download-db-log-file-portion 将 slow log 下载到本地;
具体实现形式请参加后续对应部分的内容。
使用 sql 脚本获取 slow log
获取整个 slow log
mysql> show variables like 'log_output';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | TABLE |
+---------------+-------+
1 row in set (0.03 sec)
mysql>
[root@ip-172-31-36-44 ~]# mysql -h mysql.xxxxxxxxxxxx.rds.cn-northwest-1.amazonaws.com.cn -u root -p -P13306 -D mysql -s -r -e "SELECT CONCAT( '# Time: ', DATE_FORMAT(start_time, '%y%m%d %H%i%s'), '\n', '# User@Host: ', user_host, '\n', '# Query_time: ', TIME_TO_SEC(query_time), ' Lock_time: ', TIME_TO_SEC(lock_time), ' Rows_sent: ', rows_sent, ' Rows_examined: ', rows_examined, '\n', sql_text, ';' ) FROM mysql.slow_log" > /tmp/mysql_slow_log.log
Enter password:
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# ls -l /tmp/mysql_slow_log.log
-rw-r--r--. 1 root root 14211651 Mar 19 02:57 /tmp/mysql_slow_log.log
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# more /tmp/mysql_slow_log.log
# Time: 190130 145734
# User@Host: root[root] @ [60.223.227.126]
# Query_time: 20 Lock_time: 0 Rows_sent: 0 Rows_examined: 48413563
select * from unit_value where FT121_SET <> null
LIMIT 0, 10000;
# Time: 190130 153530
# User@Host: root[root] @ 42-2-128-026.static.netvigator.com [42.2.128.26]
# Query_time: 96 Lock_time: 0 Rows_sent: 20099504 Rows_examined: 68517265
select PT111_VALUE from unit_value WHERE PT111_VALUE <> 0 and PT111_VALUE < 1.3 ORDER by UNITNAME DESC;
# Time: 190130 153802
# User@Host: root[root] @ 42-2-128-026.static.netvigator.com [42.2.128.26]
# Query_time: 31 Lock_time: 0 Rows_sent: 579105 Rows_examined: 49576551
select DISTINCT UNITNAME,PT111_VALUE from unit_value WHERE PT111_VALUE <> 0 and PT111_VALUE < 1.3 ORDER by UNITNAME DESC;
# Time: 190130 154215
# User@Host: root[root] @ [60.223.227.126]
# Query_time: 45 Lock_time: 0 Rows_sent: 1580250 Rows_examined: 50026401
select
UNITNAME
,first_value(PT111_VALUE) over (partition by UNITNAME order by UNITTIME)
from unit_value;
获取指定时间段的 slow log
[root@ip-172-31-36-44 ~]# mysql -h mysql.xxxxxxxxxxxx.rds.cn-northwest-1.amazonaws.com.cn -u root -p -P13306 -D mysql -s -r -e "SELECT CONCAT( '# Time: ', DATE_FORMAT(start_time, '%y%m%d %H%i%s'), '\n', '# User@Host: ', user_host, '\n', '# Query_time: ', TIME_TO_SEC(query_time), ' Lock_time: ', TIME_TO_SEC(lock_time), ' Rows_sent: ', rows_sent, ' Rows_examined: ', rows_examined, '\n', sql_text, ';' ) FROM mysql.slow_log where DATE_FORMAT(start_time, '%Y%m%d %H:%i:%s') between '20190328 10:00:00' and '20190328 11:00:00' " > /tmp/slow.log.10-11.log
Enter password:
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# ls -l /tmp/mysql_slow_log1.log
-rw-r--r--. 1 root root 10874816 Mar 19 04:33 /tmp/mysql_slow_log1.log
[root@ip-172-31-36-44 ~]#
使用 awscli 获取 MySQL slow log
mysql> show variables like '%output%';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| innodb_status_output | OFF |
| innodb_status_output_locks | OFF |
| log_output | FILE |
+----------------------------+-------+
3 rows in set (0.05 sec)
mysql>
mysql> show variables like '%slow%';
+---------------------------+----------------------------------------------+
| Variable_name | Value |
+---------------------------+----------------------------------------------+
| log_slow_admin_statements | OFF |
| log_slow_slave_statements | OFF |
| slow_launch_time | 2 |
| slow_query_log | ON |
| slow_query_log_file | /rdsdbdata/log/slowquery/mysql-slowquery.log |
+---------------------------+----------------------------------------------+
5 rows in set (2.07 sec)
mysql>
[root@ip-172-31-36-44 ~]# aws rds download-db-log-file-portion --db-instance-identifier mysql --log-file-name slowquery/mysql-slowquery.log --starting-token 0 --output text> mysql-slowquery.log
[root@ip-172-31-36-44 ~]# ls -l mysql-slowquery.log
-rw-r--r--. 1 root root 15970 Mar 19 04:41 mysql-slowquery.log
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# more mysql-slowquery.log
# Time: 2019-03-19T04:40:56.629552Z
# User@Host: root[root] @ ec2-52-82-53-253.cn-northwest-1.compute.amazonaws.com.cn [52.82.53.253] Id: 249635335
# Query_time: 5.087165 Lock_time: 0.000052 Rows_sent: 0 Rows_examined: 1496709
use yuci;
SET timestamp=1552970456;
SELECT tagout_value.tagtime AS tagout_value_tagtime, tagout_value.tagname AS tagout_value_tagname, tagout_value.tagvalue AS tagout_value_tagvalue
FROM tagout_value
WHERE tagout_value.tagname = 'COV122_OUTPAR_134' ORDER BY tagout_value.tagtime DESC
LIMIT 1;
# Time: 2019-03-19T04:40:56.819594Z
# User@Host: root[root] @ ec2-52-82-59-190.cn-northwest-1.compute.amazonaws.com.cn [52.82.59.190] Id: 249635331
# Query_time: 5.274261 Lock_time: 0.000053 Rows_sent: 0 Rows_examined: 1496709
SET timestamp=1552970456;
SELECT tagout_value.tagtime AS tagout_value_tagtime, tagout_value.tagname AS tagout_value_tagname, tagout_value.tagvalue AS tagout_value_tagvalue
FROM tagout_value
WHERE tagout_value.tagname = 'COV122_OUTPAR' ORDER BY tagout_value.tagtime DESC
LIMIT 1;
实际案例
这里描述一个实际的案例,在 RDS MySQL 碰到性能问题时,我们如何通过 pt-query-digest 工具来分析性能,找到其中的问题所在。
发现问题
某一天突然发现 RDS MySQL CPU 利用率高达 100%,平时正常运行几乎都在 40%以下,怀疑 MySQL 数据库之前运行了一些问题 SQL 语句导致了 CPU 资源的飙升。
分析问题
这里我们首先来获取 13:00-14:00 这一个小时范围内的 RDS MySQL slow log ,然后再使用我们前面部署的 pt-query-digest 工具来分析一下,看是否可以发现一些端倪。
[root@ip-172-31-36-44 ~]# mysql -h mysql. xxxxxxxxxxxx.rds.cn-northwest-1.amazonaws.com.cn -u root -p -P13306 -D mysql -s -r -e "SELECT CONCAT( '# Time: ', DATE_FORMAT(start_time, '%y%m%d %H%i%s'), '\n', '# User@Host: ', user_host, '\n', '# Query_time: ', TIME_TO_SEC(query_time), ' Lock_time: ', TIME_TO_SEC(lock_time), ' Rows_sent: ', rows_sent, ' Rows_examined: ', rows_examined, '\n', sql_text, ';' ) FROM mysql.slow_log where DATE_FORMAT(start_time, '%Y%m%d %H:%i:%s') between '20190328 13:00:00' and '20190328 14:00:00' " > /tmp/slow.log.1314.log
Enter password:
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# pt-query-digest --report /tmp/slow.log.1314.log> /tmp/report.1314.log
[root@ip-172-31-36-44 ~]#
[root@ip-172-31-36-44 ~]# cat /tmp/report.1314.log
# 220ms user time, 30ms system time, 27.48M rss, 221.73M vsz
# Current date: Thu Mar 28 06:03:53 2019
# Hostname: ip-172-31-36-44.cn-northwest-1.compute.internal
# Files: /tmp/slow.log.1314.log
# Overall: 255 total, 4 unique, 0 QPS, 0x concurrency ____________________
# Attribute total min max avg 95% stddev median
# ============ ======= ======= ======= ======= ======= ======= =======
# Exec time 9360s 5s 62s 37s 49s 8s 35s
# Lock time 0 0 0 0 0 0 0
# Rows sent 3.12k 0 266 12.52 0 54.70 0
# Rows examine 1.85G 1.88M 12.99M 7.45M 9.30M 1.35M 6.94M
# Query size 2.42M 78 114.10k 9.72k 79.83k 28.60k 212.52
# Time 46.29M 185.87k 185.87k 185.87k 185.87k 0 185.87k
# Profile
# Rank Query ID Response time Calls R/Call V/M
# ==== ============================== =============== ===== ======= =====
# 1 0x582C46632FB388ABE5D178303... 7913.0000 84.5% 216 36.6343 1.57 SELECT MLModel?_ecgw_a_pred
# 2 0x0E39F3F13EDA325B4E53D0244... 971.0000 10.4% 25 38.8400 2.04 INSERT slph_adjust_his
# 3 0x3FC5160B3B25069FA843DC222... 466.0000 5.0% 12 38.8333 1.53 SELECT MLModel?_jd_pred unit_info MLModel?_jd_pred
# MISC 0xMISC 10.0000 0.1% 2 5.0000 0.0 <1 ITEMS>
# Query 1: 0 QPS, 0x concurrency, ID 0x582C46632FB388ABE5D178303E079908 at byte 420282
# This item is included in the report because it matches --limit.
# Scores: V/M = 1.57
# Attribute pct total min max avg 95% stddev median
# ============ === ======= ======= ======= ======= ======= ======= =======
# Count 84 216
# Exec time 84 7913s 20s 57s 37s 49s 8s 35s
# Lock time 0 0 0 0 0 0 0 0
# Rows sent 0 0 0 0 0 0 0 0
# Rows examine 79 1.48G 7.01M 7.02M 7.02M 6.94M 0 6.94M
# Query size 1 47.02k 222 223 222.89 212.52 0 212.52
# Time 84 39.21M 185.87k 185.87k 185.87k 185.87k 0 185.87k
# String:
# Hosts 172.31.39.23 (120/55%), 172.31.46.35 (36/16%)... 3 more
# Users root
# Query_time distribution
# 1us
# 10us
# 100us
# 1ms
# 10ms
# 100ms
# 1s
# 10s+ ################################################################
# Tables
# SHOW TABLE STATUS LIKE 'MLModel6_ecgw_a_pred'\G
# SHOW CREATE TABLE `MLModel6_ecgw_a_pred`\G
# EXPLAIN /*!50100 PARTITIONS*/
SELECT * FROM MLModel6_ecgw_a_pred
where unitname = 395 and forecast48hr >= now()
and forecast48hr < NOW() + INTERVAL 1 HOUR
order by predTime desc
limit 1\G
# Query 2: 0 QPS, 0x concurrency, ID 0x0E39F3F13EDA325B4E53D0244F2E9A23 at byte 210412
..............
..............
..............
从上面我们可以看到排在第一位的 SQL 语句在本次分析中总的时间占比高达 84%,且单次调用耗时在 36 秒。接下来我们看看 SQL 语句的情况:
mysql> SELECT * FROM MLModel6_ecgw_a_pred
-> where unitname = 395 and forecast48hr >= now()
-> and forecast48hr < NOW() + INTERVAL 1 HOUR
-> order by predTime desc
-> limit 1
-> ;
Empty set (39.59 sec)
mysql> explain SELECT * FROM MLModel6_ecgw_a_pred
-> where unitname = 395 and forecast48hr >= now()
-> and forecast48hr < NOW() + INTERVAL 1 HOUR
-> order by predTime desc
-> limit 1;
+----+-------------+----------------------+------------+-------+---------------+---------+---------+------+------+----------+----------------------------------+
| id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra |
+----+-------------+----------------------+------------+-------+---------------+---------+---------+------+------+----------+----------------------------------+
| 1 | SIMPLE | MLModel6_ecgw_a_pred | NULL | index | idx_un | idx_un1 | 15 | NULL | 325 | 0.03 | Using where; Backward index scan |
+----+-------------+----------------------+------------+-------+---------------+---------+---------+------+------+----------+----------------------------------+
1 row in set, 1 warning (0.02 sec)
mysql> show index from MLModel6_ecgw_a_pred;
+----------------------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| Table | Non_unique | Key_name | Seq_in_index | Column_name | Collation | Cardinality | Sub_part | Packed | Null | Index_type | Comment | Index_comment | Visible | Expression |
+----------------------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
| MLModel6_ecgw_a_pred | 0 | PRIMARY | 1 | id | A | 6899295 | NULL | NULL | | BTREE | | | YES | NULL |
| MLModel6_ecgw_a_pred | 1 | idx_un | 1 | forecast48hr | A | 60106 | NULL | NULL | YES | BTREE | | | YES | NULL |
| MLModel6_ecgw_a_pred | 1 | idx_un | 2 | UNITNAME | A | 352164 | NULL | NULL | YES | BTREE | | | YES | NULL |
| MLModel6_ecgw_a_pred | 1 | idx_un1 | 1 | predTime | A | 112492 | NULL | NULL | YES | BTREE | | | YES | NULL |
| MLModel6_ecgw_a_pred | 1 | idx_un1 | 2 | UNITNAME | A | 162489 | NULL | NULL | YES | BTREE | | | YES | NULL |
+----------------------+------------+----------+--------------+--------------+-----------+-------------+----------+--------+------+------------+---------+---------------+---------+------------+
5 rows in set (0.10 sec)
mysql>
从上面我们不难看出,此 SQL 语句使用了错误的索引 idx_un1 ,实际上使用 idx_un 索引选择性会更好,执行效率会更高。
解决问题
强制此 SQL 语句使用正确的索引,不到 1 秒就执行完毕:
mysql> SELECT * FROM MLModel6_ecgw_a_pred force index(idx_un)
-> where unitname = 395 and forecast48hr >= now()
-> and forecast48hr < NOW() + INTERVAL 1 HOUR
-> order by predTime desc
-> limit 1
-> ;
Empty set (0.03 sec)
mysql>
后续就是具体的优化工作,至于是优化索引设置,还是去调整 SQL 语句,可以根据实际情况来进行即可。
总结
pt-query-digest 是一个针对 MySQL slow log 进行分析的工具,可以获得更友好、易读、更人性化的 SQL 性能汇总及分析报告;
RDS MySQL 由于是托管的数据库,我们可以使用 awscli RDS API 或者以 MySQL sql 脚本来分别将 FILE 和 TABLE 形式的慢查询日志获取到本地,然后再使用 pt-query-digest 进行分析;
Percona Toolkit 是业界比较知名的 MySQL 工具集,里面包含多种可以提升效率的管理工具,除了 pt-query-digest 使用较多之外,还有 pt-online-schema-change 、 pt-mysql-summary 、 pt-summary 等工具被广泛使用,推荐有兴趣的同学可以尝试使用;
作者介绍:
闫静
AWS 专业服务团队咨询顾问、云架构师。具有 10 年以上大型数据库维护管理及架构设计经验,目前主要专注于企业客户数据库上云、整体上云架构方面的规划/设计及实施。热衷于云基础架构规划、云端数据库架构设计、大数据架构部署等领域的研究和学习。
本文转载自 AWS 技术博客。
原文链接:
https://amazonaws-china.com/cn/blogs/china/pt-query-digest-rds-mysql-slow-searchnew/
更多内容推荐
MySQL 查询优化必备
查询优化本就不是一蹴而就的,需要学会使用对应的工具、借鉴别人的经验来对SQL进行优化,并且提升自己。
2021-04-08
GreatSQL 社区月报 | 2023.03
GreatSQL 是一个开源的 MySQL 技术路线数据库社区,社区致力于通过开放的社区合作,构建国内自主 MySQL 版本及开源数据库技术,推动中国开源数据库及应用生态繁荣发展。
2023-04-10
玩转 MySQL 表之间的各种连接查询
为什么要进行连接查询?
2022-11-12
云数据库时代,DBA 将走向何方?
伴随云计算的迅猛发展,数据库也进入了云时代。云数据库不断涌现,产品越来越成熟和智能,作为数据库管理员的DBA将面临哪些机遇和挑战?又应该具备什么能力,才能应对未来的不确定性?
2022-11-03
营销 MM 让我讲 MySQL 日志顺序读写及数据文件随机读写原理
摘要:你知道吗,MySQL在实际工作时候的两种数据读写机制?
2022-02-09
5、SQL 调优 - 索引、Limit、子查询、ShowProfile
2023-09-27
阿里云 ECS 之 MySQL 基础操作
讲述Linux服务器下MySQL基本命令操作
2022-08-18
架构实战营模块八作业
每个消息队列对应一个 MySQL 表。
2022-07-31
MySQL DeadLock -- 二级索引导致的死锁
MySQL死锁是指两个或多个事务相互等待对方占用的资源而无法继续执行的情况。在MySQL中,当多个事务同时访问同一数据行时,如果它们都持有锁并且试图获取对方持有的锁,则可能会发生死锁
2023-06-18
GreatSQL 社区月报 | 2023.04
GreatSQL 是一个开源的 MySQL 技术路线数据库社区,社区致力于通过开放的社区合作,构建国内自主 MySQL 版本及开源数据库技术,推动中国开源数据库及应用生态繁荣发展。
2023-05-12
《MySQL 自传》
撰写本文查阅了大量参考资料,也得到很多朋友的指点帮助,特别感谢:
2022-09-05
数据库中间件 MyCat 实战笔记(第一步),arm 架构 linux 系统
A). 卸载 centos 中预安装的 mysql rpm -qa | grep -i mysql rpm -e mysql-libs-5.1.71-1.el6.x86_64 --nodeps B). 上传 mysql 的安装包 alt + p -------> put E:/test/MySQL-5.6.22-1.el6.i686.rpm-bundle.tar C). 解压 mysql 的安装包 mkdir m
2021-10-30
数据库的两个好帮手:pagehack 和 pg_xlogdump
摘要:pagehack和pg_xlogdump可以帮助我们在数据库故障定位中,解析各种文件的页面头和xlog日志。
2021-02-20
带你看懂 MySQL 执行计划
前面文章,我们学习了 MySQL 慢日志相关内容,当我们筛选得到具体的慢 SQL 后,就要想办法去优化啦。优化 SQL 的第一步应该是读懂 SQL 的执行计划。本篇文章,我们一起来学习下 MySQL explain 执行计划相关知识。
2021-05-31
31|项目实战与部署:如何实现接口部署与访问?
在企业应用当中,把项目部署到服务器上,不但能让前端访问接口,也能供更多用户使用我们的平台。
2023-07-03
3、MySQL 日志文件与数据文件详解
2023-09-27
8. Redis 分布式锁:singleflight 优化、面试要点与总结
2023-09-27
1、什么是 MongoDB
2023-09-28
《零基础》MySQL 连接的使用 (二十),springcloud 开发教程
我们在RUNOOB数据库中有两张表 tcount_tbl 和 runoob_tbl。两张数据表数据如下:
2021-11-10
14. TableAPI 和 SQL 的基本介绍
2023-09-08
暂无签名
推荐阅读
数据库安全运维是什么意思?数据库安全运维系统用哪家好?
2023-10-18
克服 ClickHouse 运维难题:ByteHouse 水平扩容功能上线
2023-07-13
PostgreSQL 基于 Patroni 方案的高可用启动流程分析
2023-10-26
24|提示语工程(六):超越智能,让你的 AI 系统成为全知超人
2023-10-13
基础篇|课后题答疑
2024-12-11
34|工具:学会使用从内存分析到性能测试等各种常用工具
2023-11-15
VLDB2024 部分论文学习分享
数据库
电子书
大厂实战PPT下载
换一换 张柳青 | 百度 资深研发工程师
肖然 | Thoughtworks 全球数字化转型专家
丁杰 | Thoughtworks 企业架构与云事业部总监咨询师
评论