Appearance
Mysql
Mysql 是一个关系型数据库管理系统
问题
慢 SQL 查询日志如何调优?
慢查询日志用来记录响应时间超过指定阈值的 SQL 语句,阈值使用 long_query_time 设置,默认 10 秒,超过该值则会记录到慢查询日志中,另默认情况下,数据库没有开启慢查询日志开关 slow_query_log
开启慢查询日志
- 方式1:修改 my.cnf 配置文件,增加如下参数
my.cnf
# 开启慢查询日志开关(1 或 ON,0 或 OFF)
slow_query_log=ON
# 慢查询日志目录和文件名(默认存储到 MySQL 数据库的数据文件夹下,文件名为 hostname-slow.log)
slow_query_log_file=/var/lib/mysql/mysql-slow.log
# 设置执行时间阈值为3秒,超出此值的 SQL 会被记录到慢查询日志中
long_query_time=3
# 日志输出格式,一种是输出到文件 FILE 中,一种是写入数据表格 TABLE 中,会保存到数据库的 slow_log 表中
log_output=FILE
# 最少记录数,超过该值且查询时间超过 long_query_time 则会记录到慢日志中(默认0)
min_examined_row_limit
# 慢查询中记录 bytes_received 和 bytes_sent,默认未开启
log_slow_extra=OFF
# 开启慢查询日志开关(1 或 ON,0 或 OFF)
slow_query_log=ON
# 慢查询日志目录和文件名(默认存储到 MySQL 数据库的数据文件夹下,文件名为 hostname-slow.log)
slow_query_log_file=/var/lib/mysql/mysql-slow.log
# 设置执行时间阈值为3秒,超出此值的 SQL 会被记录到慢查询日志中
long_query_time=3
# 日志输出格式,一种是输出到文件 FILE 中,一种是写入数据表格 TABLE 中,会保存到数据库的 slow_log 表中
log_output=FILE
# 最少记录数,超过该值且查询时间超过 long_query_time 则会记录到慢日志中(默认0)
min_examined_row_limit
# 慢查询中记录 bytes_received 和 bytes_sent,默认未开启
log_slow_extra=OFF
- 方式2:使用命令进行设置(重开连接生效,重启后失效)
sql
# 查看慢查询日志开关、执行时间阈值、最少记录数、慢查询额外字段
show variables like '%slow_query_log%';
show variables like '%long_query_time%';
show variables like '%min_examined_row_limit %';
show variables like '%log_slow_extra %';
# 打开慢查询日志开关并设置阈值为1秒
set global slow_query_log='ON';
set global long_query_time = 1;
# 查看慢查询日志开关、执行时间阈值、最少记录数、慢查询额外字段
show variables like '%slow_query_log%';
show variables like '%long_query_time%';
show variables like '%min_examined_row_limit %';
show variables like '%log_slow_extra %';
# 打开慢查询日志开关并设置阈值为1秒
set global slow_query_log='ON';
set global long_query_time = 1;
记录未使用索引的 SQL
- log-queries-not-using-indexes 记录未使用索引的 SQL,默认未开启
- log_throttle_queries_not_using_indexes 限制每分钟写入慢日志中的不走索引的 SQL 语句个数,默认0,不做条数限制
查询当前系统的慢 SQL 条数
sql
show global status like '%Slow_queries%';
show global status like '%Slow_queries%';
慢 SQL 分析工具
开启慢查询后可通过语句 select sleep(5);
测试是否正常记录慢日志
- Mysql 自带分析调优工具 mysqldumpslow
sql
mysqldumpslow -s t /var/lib/mysql/mysql-slow.log
mysqldumpslow -s t /var/lib/mysql/mysql-slow.log
- Mysql 自带高级分析调优工具 show profile,默认关闭
sql
# 查看 show profile
show variables like 'profiling%';
# 查看最近15次的运行结果
show profiles;
# 诊断 SQL
SHOW PROFILE cpu,block io FOR QUERY query id;
# 查看 show profile
show variables like 'profiling%';
# 查看最近15次的运行结果
show profiles;
# 诊断 SQL
SHOW PROFILE cpu,block io FOR QUERY query id;
- Percona Toolkit(DBAs 高级开源命令行工具集) 中的 pt-query-digest,分析慢查询的一个工具
sql
pt-query-digest /var/log/mysql/mysql-slow.log > report.txt
pt-query-digest /var/log/mysql/mysql-slow.log > report.txt
删除慢查询日志文件
- 手动删除文件
- 使用命令 mysqladmin -u root -p flush-logs
死锁如何处理?
死锁指的是在两个或两个以上不同的进程或线程中,因争夺资源而造成的一种互相等待的现象
死锁查看
sql
# 查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX
# 查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
# 查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
# 查询是否锁表
SHOW OPEN TABLES where In_use > 0;
# 查看最近死锁的日志
show engine innodb status
# 查看正在进行中的事务
SELECT * FROM information_schema.INNODB_TRX
# 查看正在锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCKS;
# 查看等待锁的事务
SELECT * FROM INFORMATION_SCHEMA.INNODB_LOCK_WAITS;
# 查询是否锁表
SHOW OPEN TABLES where In_use > 0;
# 查看最近死锁的日志
show engine innodb status
解除死锁
sql
# 查看所有进程
show processlist
# 杀死进程
kill id
# 查看所有进程
show processlist
# 杀死进程
kill id
为什么开启慢查询后没有记录日志?
前提确保已开启慢查询,再判断具体原因
配置目录及文件不存在
markdown
创建目录及文件
创建目录及文件
配置目录及文件权限不足
shell
chmod 777 mysql-slow.log
chmod 777 mysql-slow.log