加粗样式前言
日志文件记录了影响MySQL数据库的各种类型活动,MySQL数据库中常见的日志文件有错误日志,二进制日志,慢查询日志和查询日志。
下面分别对他们进行介绍。
错误日志
错误日志文件对MySQL的启动,运行,关闭过程进行了记录。
mysql> show variables like 'log_error';
+---------------+---------------------+
| Variable_name | Value |
+---------------+---------------------+
| log_error | /var/log/mysqld.log |
+---------------+---------------------+
1 row in set (0.03 sec)
可以看到错误日志的路径和文件名,默认情况下错误文件的文件名为服务器的主机名,即:hostname.err。
只不过我这里设置的是/var/log/mysqld.log,修改错误日志地址可以在/etc/my.cnf中添加
# Recommended in standard MySQL setup
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
当出现MySQL数据库不能正常启动时,第一个必须查找的文件就是错误日志文件,该文件记录了出错信息,能够帮助我们找到问题。
慢查询日志
慢查询日志用来记录响应时间超过阈值的SQL语句,所以我们可以设置一个阈值,将运行时间超过该值的所有SQL语句都记录到慢查询日志文件中。该阈值可以通过参数 long_query_time 来设置,默认为10秒。
**
启动慢查询日志**
默认情况下,MySQL数据库并不启动慢查询日志,需要手动将这个参数设为ON,然后启动
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 | OFF |
| slow_query_log_file | /var/lib/mysql/iz2zeaf3cg1099kiidi06mz-slow.log |
+---------------------------+-------------------------------------------------+
5 rows in set (0.00 sec)
mysql> set global slow_query_log='ON';
Query OK, 0 rows affected (0.00 sec)
mysql> show variables like "slow_query_log";
+---------------------------+-------------------------------------------------+
| Variable_name | Value |
+---------------------------+-------------------------------------------------+ |
| slow_query_log | ON |
| slow_query_log_file | /var/lib/mysql/iz2zeaf3cg1099kiidi06mz-slow.log |
+---------------------------+-------------------------------------------------+
2 rows in set (0.00 sec)
但是使用 set global slow_query_log=‘ON’ 开启慢查询日志,只是对当前数据库有效,如果MySQL数据库重启后就会失效。所以如果要永久生效,就要修改配置文件 my.cnf (其他系统变量也是如此),如下:
[mysqld]
slow_query_log=1
然后重启MySQL就可以让慢查询日志记录开启了,至于日志文件的路径就是上面slow_query_log_file对应的路径。
设置阈值
mysql> show variables like 'long_query_time';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set (0.00 sec)
阈值默认为10秒,我们可以修改阈值大小,比如(当然这还是对当前数据库有效):
mysql> set global long_query_time=0.05;
Query OK, 0 rows affected (0.00 sec)
设置long_query_time这个阈值之后,MySQL数据库会记录运行时间超过该值的所有SQL语句,但对于运行时间正好等于 long_query_time 的情况,并不会被记录下。
而设置 long_query_time为0来捕获所有的查询
参数log_queries_not_using_indexes
另一个和慢查询日志有关的参数是 log_queries_not_using_indexes,
如果运行的SQL语句没有使用索引,则MySQL数据库同样会将这条SQL语句记录到慢查询日志文件。
首先确认打开了log_queries_not_using_indexes;
mysql> show variables like 'log_queries_not_using_indexes';
+-------------------------------+-------+
| Variable_name | Value |
+-------------------------------+-------+
| log_queries_not_using_indexes | ON |
+-------------------------------+-------+
1 row in set (0.12 sec)
例子,没有用到索引进行查询:
mysql> explain select * from vote_record_memory where vote_id = 323;
+----+-------------+--------------------+------+---------------+------+---------+------+--------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------------------+------+---------------+------+---------+------+--------+-------------+
| 1 | SIMPLE | vote_record_memory | ALL | NULL | NULL | NULL | NULL | 149272 | Using where |
+----+-------------+--------------------+------+---------------+------+---------+------+--------+-------------+
1 row in set (1.56 sec)
可以看到是进行了全表扫描;然后去log日志文件中查看这条SQL已经被标记为慢SQL,因为它没有使用索引。
# Time: 180817 11:42:59
# User@Host: root[root] @ [117.136.86.151] Id: 2625
# Query_time: 0.016542 Lock_time: 0.000112 Rows_sent: 142 Rows_examined: 149272
SET timestamp=1534477379;
select * from vote_record_memory where vote_id = 323;
将日志记录放入表中
MySQL5.1开始可以将慢查询的日志记录放入一张表中,在mysql数据库下,名为slow_log
| slow_log | CREATE TABLE `slow_log` (
`start_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
`user_host` mediumtext NOT NULL,
`query_time` time NOT NULL,
`lock_time` time NOT NULL,
`rows_sent` int(11) NOT NULL,
`rows_examined` int(11) NOT NULL,
`db` varchar(512) NOT NULL,
`last_insert_id` int(11) NOT NULL,
`insert_id` int(11) NOT NULL,
`server_id` int(10) unsigned NOT NULL,
`sql_text` mediumtext NOT NULL,
`thread_id` bigint(21) unsigned NOT NULL
) ENGINE=CSV DEFAULT CHARSET=utf8 COMMENT='Slow log' |
参数log_output指定了慢查询输出的格式,默认为file,可以将它设置成table,将变成了上面的slow_log中
mysql> show variables like "log_output";
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output | FILE |
+---------------+-------+
1 row in set (0.19 sec)
但是多数情况下这样做没什么必要,这不但对性能有较大影响,而且 MySQL 5.1 在将慢查询记录到文件中时已经支持微秒级别的信息,然而将慢查询记录到表中会导致时间粒度退化为只能到秒级,而秒级别的慢查询日志没有太大的意义
慢查询日志分析工具
mysqldumpslow命令
当越来越多的SQL查询被记录到慢查询日志文件中,这时候直接看日志文件就不容易了,MySQL提供了mysqldumpslow 命令解决:
[root@iz2zeaf3cg1099kiidi06mz mysql]# mysqldumpslow iz2zeaf3cg1099kiidi06mz-slow.log
Reading mysql slow query log from iz2zeaf3cg1099kiidi06mz-slow.log
Count: 1 Time=60.02s (60s) Lock=0.00s (0s) Rows=149272.0 (149272), root[root]@[117.136.86.151]
select * from vote_record_memory
Count: 1 Time=14.85s (14s) Lock=0.00s (0s) Rows=0.0 (0), root[root]@[117.136.86.151]
CALL add_vote_memory(N)
Count: 1 Time=1.72s (1s) Lock=0.00s (0s) Rows=0.0 (0), root[root]@[117.136.86.151]
INSERT into vote_record SELECT * from vote_record_memory
Count: 1 Time=0.02s (0s) Lock=0.00s (0s) Rows=142.0 (142), root[root]@[117.136.86.151]
select * from vote_record_memory where vote_id = N