MySQL一共有四种日志:错误日志,二进制日志,查询日志,慢查询日志。本文介绍这几种日志的作用及详细用法。
错误日志记录了当MySQL启动和停止时, 以及服务器在运行过程中发生任何严重错误时的相关信息。
可以用--log-error[=file_name]
选项指定mysqld(MySQL服务器)保存错误日志文件的位置。
如果没有指定file_name值,mysqld使用错误日志名为host_name.err(host_name为主机名)并默认在参数DATADIR(数据目录)指定的目录中写入日志文件。
查看日志位置
show variables like 'log_error%';
mysql> show variables like 'log_error%';
+---------------------+-----------------------------+
| Variable_name | Value |
+---------------------+-----------------------------+
| log_error | ./localhost.localdomain.err |
+---------------------+-----------------------------+
[root@localhost data]# head -n 20 localhost.localdomain.err
2020-10-18T12:43:00.677490Z 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use --explicit_defaults_for_timestamp server option (see documentation for more details).
2020-10-18T12:43:00.677587Z 0 [Note] --secure-file-priv is set to NULL. Operations related to importing and exporting data are disabled
2020-10-18T12:43:00.677616Z 0 [Note] /usr/local/mysql/bin/mysqld (mysqld 5.7.24) starting as process 2419 ...
2020-10-18T12:43:00.686051Z 0 [Note] InnoDB: PUNCH HOLE support available
2020-10-18T12:43:00.686097Z 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
2020-10-18T12:43:00.686107Z 0 [Note] InnoDB: Uses event mutexes
2020-10-18T12:43:00.686114Z 0 [Note] InnoDB: GCC builtin __sync_synchronize() is used for memory barrier
2020-10-18T12:43:00.686121Z 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
2020-10-18T12:43:00.686127Z 0 [Note] InnoDB: Using Linux native AIO
2020-10-18T12:43:00.686364Z 0 [Note] InnoDB: Number of pools: 1
2020-10-18T12:43:00.686572Z 0 [Note] InnoDB: Using CPU crc32 instructions
2020-10-18T12:43:00.691127Z 0 [Note] InnoDB: Initializing buffer pool, total size = 128M, instances = 1, chunk size = 128M
2020-10-18T12:43:00.710621Z 0 [Note] InnoDB: Completed initialization of buffer pool
2020-10-18T12:43:00.714513Z 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
2020-10-18T12:43:00.725569Z 0 [Note] InnoDB: Highest supported file format is Barracuda.
2020-10-18T12:43:00.742604Z 0 [Note] InnoDB: Creating shared tablespace for temporary tables
2020-10-18T12:43:00.742758Z 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
2020-10-18T12:43:00.759331Z 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
2020-10-18T12:43:00.760107Z 0 [Note] InnoDB: 96 redo rollback segment(s) found. 96 redo r
二进制日志(BINLOG)记录了所有的DDL语句和DML语句,不包括查询语句。语句以“事件”的形式保存。它描述了数据的更改过程,对于灾难是的数据恢复有重要作用。
二进制日志,默认情况下是没有开启的,需要到MySQL的配置文件中开启,并配置MySQL日志的格式。
配置文件位置 : /usr/my.cnf
日志存放位置 : 配置时,给定了文件名但是没有指定路径,日志默认写入MySQL的DATA目录
-- 在my.cnf中配置
#配置开启binlog日志, 日志的文件前缀为 mysqlbin
# 生成的文件名如 :mysqlbin.000001,mysqlbin.000002
[mysqld]
server-id=1 -- 这里要配上,不然启动不起来
log-bin=mysqlbin
binlog-format=STATEMENT
STATEMENT
该日志格式在日志文件中记录的都是SQL语句(statement),每一条对数据进行修改的SQL都会记录在日志文件中,通过Mysql提供的mysqlbinlog工具,可以清晰的查看到每条语句的文本。主从复制的时候,从库(slave)会将日志解析为原文本,并在从库重新执行一次。
这种格式的日志记录清晰易读、日志量少,对I/O影响较小。
ROW
该日志格式在日志文件中记录的是每一行的数据变更,而不是记录SQL语句。比如,执行SQL语句 : update tb_book set status='1'
, 如果是STATEMENT 日志格式,在日志中会记录一行SQL文件; 如果是ROW,由于是对全表进行更新,也就是每一行记录都会发生变更,ROW 格式的日志中会记录每一行的数据变更。
这种模式的特点是数据日志量大,I/O影响大。记录细节完整。
MIXED
这是目前MySQL默认的日志格式,即混合了STATEMENT 和 ROW两种格式。默认情况下采用STATEMENT,但是在一些特殊情况下采用ROW来进行记录。MIXED 格式能尽量利用两种模式的优点,而避开他们的缺点。
用mysqlbinlog工具来查看,语法如下 :
mysqlbinlog log-file;
查看STATEMENT格式日志:
INSERT INTO `tb_contact` (`id`, `index_code`, `surname`, `name`, `mobile_code`,`created`, `updated`) VALUES (null, 'Z', 'zhang', 'san', '13911111111', now(), now());
[root@localhost data]# mysqlbinlog mysqlbin.000001
...
/*!*/;
# at 1659
#210218 23:50:58 server id 1 end_log_pos 1724 CRC32 0x53758b3f Anonymous_GTID last_committed=3 sequence_number=4 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ANONYMOUS'/*!*/;
# at 1724
#210218 23:50:58 server id 1 end_log_pos 1811 CRC32 0x6910e189 Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1613721058/*!*/;
SET @@session.time_zone='SYSTEM'/*!*/;
BEGIN
/*!*/;
# at 1811
# at 1843
#210218 23:50:58 server id 1 end_log_pos 1843 CRC32 0x0466baf1 Intvar
SET INSERT_ID=9/*!*/;
#210218 23:50:58 server id 1 end_log_pos 2089 CRC32 0x840367bf Query thread_id=4 exec_time=0 error_code=0
SET TIMESTAMP=1613721058/*!*/;
INSERT INTO `tb_contact` (`id`, `index_code`, `surname`, `name`, `mobile_code`,`created`, `updated`) VALUES (null, 'Z', 'zhang', 'san', '13911111111', now(), now())
/*!*/;
# at 2089
#210218 23:50:58 server id 1 end_log_pos 2120 CRC32 0x06474f15 Xid = 196
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
查看ROW格式日志
mysqlbinlog -vv mysqlbin.000002
方式一:
通过 Reset Master 指令删除全部 binlog 日志,删除之后,日志编号,将从 xxxx.000001重新开始 。
mysql> reset master;
Query OK, 0 rows affected, 1 warning (0.01 sec)
方式二:
执行指令 purge master logs to ‘mysqlbin.******’ ,该命令将删除 ****** 编号之前的所有日志。
方式三:
执行指令 purge master logs before ‘yyyy-mm-dd hh24:mi:ss’ ,该命令将删除日志为 “yyyy-mm-ddhh24:mi:ss” 之前产生的所有日志 。
方式四:
设置参数 --expire-logs-days=# ,此参数的含义是设置日志的过期天数, 过了指定的天数后日志将会被自动删除,这样将有利于减少DBA 管理日志的工作量。
[mysqld]
server-id=1
log-bin=mysqlbin
binlog-format=STATEMENT
expire-logs-days=3
查询日志中记录了客户端的所有操作语句,而二进制日志不包含查询数据的SQL语句。
默认情况下, 查询日志是未开启的。如果需要开启查询日志,可以设置以下配置
[mysqld]
server-id=1
log-bin=mysqlbin
binlog-format=STATEMENT
expire-logs-days=3
# 开启查询日志:0关闭,1 开启
general_log=1
# 配置查询日志的文件名
general_log_file=mysql_query.log
执行查询操作
select * from tb_contact;
查看日志
[root@localhost data]# cat mysql_query.log
/usr/local/mysql/bin/mysqld, Version: 5.7.24-log (MySQL Community Server (GPL)). started with:
Tcp port: 0 Unix socket: (null)
Time Id Command Argument
2021-02-19T08:06:44.238892Z 2 Connect root@localhost on db01 using Socket
2021-02-19T08:06:44.243325Z 2 Query show databases
2021-02-19T08:06:44.245387Z 2 Query show tables
2021-02-19T08:06:44.245837Z 2 Field List Sheet1
2021-02-19T08:06:44.246430Z 2 Field List productionSchedule
2021-02-19T08:06:44.246777Z 2 Field List tb_contact
2021-02-19T08:06:44.259305Z 2 Field List user
2021-02-19T08:06:44.259858Z 2 Query select * from tb_contact
2021-02-19T08:06:49.836888Z 2 Query select * from user
2021-02-19T08:07:09.018301Z 2 Query select Sheet
2021-02-19T08:07:21.768690Z 2 Query select * from Sheet
慢查询日志记录了所有执行时间超过参数 long_query_time
设置值并且扫描记录数不小于min_examined_row_limit
的所有的SQL语句的日志。long_query_time
默认为 10 秒,最小为 0, 精度可以到微秒。
慢查询日志默认是关闭的 。可以通过两个参数来控制慢查询日志 :
# 该参数用来控制慢查询日志是否开启, 可取值: 1 和 0 , 1 代表开启, 0 代表关闭
slow_query_log=1
# 该参数用来指定慢查询日志的文件名
slow_query_log_file=slow_query.log
# 该选项用来配置查询的时间限制, 超过这个时间将认为值慢查询, 将需要进行日志记录, 默认10s
long_query_time=10
mysql> show variables like 'long%';
+-----------------+-----------+
| Variable_name | Value |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
和错误日志、查询日志一样,慢查询日志记录的格式也是纯文本,可以被直接读取。
本篇主要介绍了MySQL四种日志的作用,配置,和查看,方便日常开发使用。