MySQL日志详细说明

这片博文我们会详细说明MySQL本身的日志,不包含重做日志和undo日志(这两个日志是innodb存储引擎的日志)。

MySQL本身的日志有以下几种(MySQL5.7版本):

  • 错误日志
  • 慢查询日志
  • 通用日志
  • 二进制日志

错误日志

默认情况下,错误日志是无法被禁止;错误日志的位置及日志名使用log_error参数指定,若是没有指定,则默认错误日志名为hostname.err(错误日志是以.err为后缀的)。yum安装的MySQL错误日志默认路径是在/var/log/mysqld.log下的!

在MySQL的官方文档中还介绍了可以把MySQL的错误日志写入到系统日志中,但是如果这样的话,查看会不太方便,不再细说给出官方链接: https://dev.mysql.com/doc/refman/5.7/en/error-log-syslog.html

log_error_verbosity:系统变量控制服务器记录错误日志的详细性,以便将错误,警告和注释信息写入错误日志。其有三个取值,1:仅限错误;2:错误和警告;3:错误,警告和注释,默认数值是3。如果该值大于2,则服务器将记录中止的连接以及新连接尝试的拒绝访问错误。

log_timestamps:系统变量控制写入错误日志(以及常规查询日志和慢速查询日志文件)的消息中时间戳的时区。允许的值为UTC(默认值)和系统(本地系统时区)。

刷新错误日志和重命名:

如果使用flush error logs、flush logs或mysqladmin flush-logs刷新日志,服务器将关闭并重新打开它正在写入的任何错误日志文件。要重命名错误日志文件,请在刷新之前手动执行此操作。刷新日志,然后打开一个具有原始文件名的新文件。

[root@mgt01 mysql]# ll -h mgt01.err                      #当前错误日志
-rw-r----- 1 mysql mysql 2.1M Jan  5 15:05 mgt01.err
[root@mgt01 mysql]# mv mgt01.err mgt01.bak               #更改当前错误日志的名字
[root@mgt01 mysql]# mysqladmin flush-logs                #执行刷新日志操作,就会重新打开一个以原错误日志名命名的新文件。
[root@mgt01 mysql]# ll -h mgt01.err mgt01.bak 
-rw-r----- 1 mysql mysql 2.1M Jan  5 15:06 mgt01.bak
-rw-r----- 1 mysql mysql  489 Jan  5 15:09 mgt01.err

慢查询日志

慢查询日志由执行时间超过long_query_time指定的秒数的SQL语句组成,并且要求至少检查min_examined_row_limit行。慢速查询日志可用于查找执行时间较长的查询,因此是优化的候选查询。

开启慢查询日志,可以把sql语句执行时间较长的语句写入慢查询日志中,以便查看。

慢查询日志的参数

在MySQL默认情况下,禁用慢查询日志。若开启慢查询日志可以使用slow_query_log参数,把其设置为1或on。

使用slow_query_log_file指定慢查询日志的文件格式,文件名,文件位置。默认文件在数据库目录下面的,文件名为host-name-slow.log。

long_query_time: 设置慢查询日志的时间限制,默认值是10s,最小值是0.该值可以指定为微妙的分辨率。(MySQL5.7版本)

默认情况下,不记录管理语句,也不记录不使用索引进行查找的语句。

要在慢查询日志中记录管理语句,则启用log_slow_admin_statements系统变量。管理语句包含ALTER TABLE, ANALYZE TABLE, CHECK TABLE, CREATE INDEX, DROP INDEX, OPTIMIZE TABLE,和 REPAIR TABLE。

要在慢查询日志的语句中包含不使用索引进行查询的语句,则使用log_queries_not_using_indexes系统变量。(即使启用了该变量,服务器也不会记录由于表少于两行而不使用索引的查询);开启这个参数后,慢查询日志会比较快的增长,因此引入了log_throttle_queries_not_using_indexes参数,这个参数设定每分钟记录到日志的未使用索引的语句数目,超过这个数目后只记录语句数量和花费的总时间。

log_slow_slave_statements:记录从库上的慢查询语句。

log_output: 参数指定慢查询日志输出到文件或者记录在数据库的表中。

一个实例如下:

slow_query_log=ON
long_query_time=3
slow_query_log_file=                   #不指定,默认是在当前数据库目录下面,以当前主机名命名的hostname-slow.log语句。
log_output=FILE
log_queries_not_using_indexes
mysql> select sleep(5);
+----------+
| sleep(5) |
+----------+
|        0 |
+----------+
1 row in set (5.00 sec)

[root@mgt01 mysql]# mysqldumpslow  mgt01-slow.log       #查看慢查询日志

Reading mysql slow query log from mgt01-slow.log
Count: 1  Time=5.00s (5s)  Lock=0.00s (0s)  Rows=1.0 (1), root[root]@localhost
  select sleep(N)
Usage: mysqldumpslow [ OPTS... ] [ LOGS... ]

Parse and summarize the MySQL slow query log. Options are

  --verbose    verbose
  --debug      debug
  --help       write this text to standard output

  -v           verbose
  -d           debug
  -s ORDER     what to sort by (al, at, ar, c, l, r, t), 'at' is default
                al: average lock time
                ar: average rows sent
                at: average query time
                 c: count
                 l: lock time
                 r: rows sent
                 t: query time  
  -r           reverse the sort order (largest last instead of first)
  -t NUM       just show the top n queries
  -a           don't abstract all numbers to N and strings to 'S'
  -n NUM       abstract numbers with at least n digits within names
  -g PATTERN   grep: only consider stmts that include this string
  -h HOSTNAME  hostname of db server for *-slow.log filename (can be wildcard),
               default is '*', i.e. match all
  -i NAME      name of server instance (if using mysql.server startup script)
  -l           don't subtract lock time from total time
mysqldumpslow的选项

上面的实例时把慢查询日志写入了文件,下面修改log_output值为table,把慢查询日志写入到表中。

log_output=TABLE

#然后再mysql数据库下面生成slow_log表。
mysql> desc slow_log;
+----------------+---------------------+------+-----+----------------------+--------------------------------+
| Field          | Type                | Null | Key | Default              | Extra                          |
+----------------+---------------------+------+-----+----------------------+--------------------------------+
| start_time     | timestamp(6)        | NO   |     | CURRENT_TIMESTAMP(6) | on update CURRENT_TIMESTAMP(6) |
| user_host      | mediumtext          | NO   |     | NULL                 |                                |
| query_time     | time(6)             | NO   |     | NULL                 |                                |
| lock_time      | time(6)             | NO   |     | NULL                 |                                |
| rows_sent      | int(11)             | NO   |     | NULL                 |                                |
| rows_examined  | int(11)             | NO   |     | NULL                 |                                |
| db             | varchar(512)        | NO   |     | NULL                 |                                |
| last_insert_id | int(11)             | NO   |     | NULL                 |                                |
| insert_id      | int(11)             | NO   |     | NULL                 |                                |
| server_id      | int(10) unsigned    | NO   |     | NULL                 |                                |
| sql_text       | mediumblob          | NO   |     | NULL                 |                                |
| thread_id      | bigint(21) unsigned | NO   |     | NULL                 |                                |
+----------------+---------------------+------+-----+----------------------+--------------------------------+
12 rows in set (0.00 sec)

mysql>

在查看慢查询日志的时候,除了使用自带的mysqldumpslow工具外,还可以使用percona的pt-query-digest工具。

常规查询日志

The general query log is a general record of what mysqld is doing. The server writes information to this log when clients connect or disconnect,
and it logs each SQL statement received from clients. The general query log can be very useful when you suspect an error in a client and want
to know exactly what the client sent to mysqld. #常规查询日志是mysqld所做工作的常规记录。当客户端连接或断开连接时,服务器将信息写入此日志,并记录从客户端接收的每个SQL语句。当您怀疑客户机中存在错误并想确切知道客户
#机发送给mysqld的内容时,常规查询日志非常有用。

常规查询日志记录的内容比较详细,并且会记录执行的每条语句,因此常用于审计的时候使用。开启常规查询语句,对数据库的性能会有一定的影响。默认是关闭的。

general_log: 用于开启常规查询日志,当为0时,关闭常规查询日志。

general_log_file: 用于指定常规查询日志的文件名,文件位置。默认文件名为hostname.log.

log_output: 指定日志输出到文件或者表中。和上面的一样。

mysql> set global general_log=ON;            #开启常规查询日志(常规查询日志可以动态修改)
Query OK, 0 rows affected (0.01 sec)
mysql> show variables like "log_output"; #设置常规查询日志输出到表中
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| log_output    | TABLE |
+---------------+-------+
1 row in set (0.01 sec)
mysql
> use mysql; #会在mysql下面生成general_log表。 Database changed mysql> select * from general_log;

可以关闭当前会话的常规查询日志如下:

mysql> set sql_log_off=ON;
Query OK, 0 rows affected (0.01 sec)

二进制日志

二进制日志包含描述数据库更改(如表创建操作或表数据更改)的“事件”。二进制日志主要有两个功能:

对于select语句,和show语句,因为不修改数据库中的数据,因此不会记录到二进制日志中;若是想要记录这种不修改数据的语句,可以使用常规查询日志。

与二进制日志有关的参数:

log-bin=    
#MySQL默认不起用二进制日志,这个参数指定二进制的位置,文件名。默认是以主机名命名的(强烈不推荐使用)。使用主机名命名的二进制日志,在迁移到别的主机时会报错。
#二进制文件名以filename.number的形式存在,number的格式是从00001开始的6位数,依次递增。还会生成一个filename.index文件,这个文件存储所有二进制日志文件名的清单。

log_bin_index= #指定上面提到的二进制日志索引文件名。这个文件不需要手动编辑,可以直接默认即可!

max_binlog_size: 设置二进制的最大大小,超出这个值时,二进制日志会自动轮换下一个。默认是1G。

binlog_cache_szie:  在事务没有提交的时候使用的缓冲大小(基于会话的),如果缓存大于这个数值则会使用临时文件。可以使用show global status来查看使用临时文件的次数。
             默认是32KB。

mysql> show global status like 'binlog_cache_%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| Binlog_cache_disk_use | 0     | #使用临时文件的次数
| Binlog_cache_use      | 0     | #缓冲使用的次数。
+-----------------------+-------+
2 rows in set (0.02 sec)

mysql>

max_binlog_cache_size: (默认为4GB,也是最大值)可用于限制用于缓存多语句事务的总大小。如果事务大于这个字节数,它将失败并回滚。最小值为4096。

binlog_error_action:如果服务器无法写入二进制日志、刷新二进制日志文件或将二进制日志同步到磁盘,则复制主服务器上的二进制日志可能会不一致,复制从服务器可能会失去与
            主服务器的同步。binlog_error_action系统变量控制在二进制日志遇到此类错误时采取的操作。
   默认设置是abort_server: ABORT_SERVER使服务器暂停二进制日志记录并关闭。此时,您可以识别并更正错误原因。重新启动时,恢复将按意外服务器暂停的情况继续进行.
ignore_error:提供与旧版本MySQL向后兼容。使用此设置,服务器继续正在进行的事务并记录错误,然后暂停二进制日志记录,但继续执行更新。要恢复二进制日志记录,必须重启服务器。
binlog_format:指定二进制日志的格式,有三种选择:
  STATEMENT: 基于语句,把数据库执行的每条语句记录下来。
ROW:   基于行的,主服务器把事件写入二进制日志,以指示各个表行的影响方式。线上标配一般是RC+ROW.
  mixed: 混合日志记录,对于混合日志记录。默认情况下使用基于语句的日志记录,但在某些情况下,日志记录模式会自动切换到基于行的记录。使用混合记录时,
        服务器会在以下条件时,使用基于行的记录。https://dev.mysql.com/doc/refman/5.7/en/binary-log-mixed.html
binlog-row-event-max-size: 在使用基于行的格式时,二进制日志文件中记录的是事件,这个参数表示事件的最大大小。这个value必须是256的倍数,默认是8192.

expire_logs_days: 表示二进制的保留时间,超过这个时间的二进制会被自动删除。单位是天,数值类型为整型。
MySQL提供一个sync_binlog参数来控制数据库的binlog刷到磁盘上去。

默认,sync_binlog=0,表示MySQL不控制binlog的刷新,由文件系统自己控制它的缓存的刷新。这时候的性能是最好的,但是风险也是最大的。因为一旦系统Crash,在binlog_cache中的所有binlog信息都会被丢失。

如果sync_binlog>0,表示每sync_binlog次事务提交,MySQL调用文件系统的刷新操作将缓存刷下去。最安全的就是sync_binlog=1了,表示每次事务提交,MySQL都会把binlog刷下去,是最安全但是性能损耗最大的设置。这样的话,在数据库所在的主机操作系统损坏或者突然掉电的情况下,系统才有可能丢失1个事务的数据。但是binlog虽然是顺序IO,但是设置sync_binlog=1,多个事务同时提交,同样很大的影响MySQL和IO性能。虽然可以通过group commit的补丁缓解,但是刷新的频率过高对IO的影响也非常大。对于高并发事务的系统来说,“sync_binlog”设置为0和设置为1的系统写入性能差距可能高达5倍甚至更多。

所以很多MySQL DBA设置的sync_binlog并不是最安全的1,而是100或者是0。这样牺牲一定的一致性,可以获得更高的并发和性能。
sync_binlog参数设置

上面说明了与二进制有关的一些参数,下面我们来说明二进制的一些管理以及二进制内容的格式。

猜你喜欢

转载自www.cnblogs.com/wxzhe/p/10225475.html