MySQL日志分类
注意:
设置系统参数方式修改,需要重新连接一个会话,如mysql重启即失效,如果要永久存在则需要修改配置文件。
如果想要当前会话生效通过set sesison进行设置。
日志分类
Mysql有7种日志文件,分别是:
1)errorlog(错误日志)
2)generallog(普通日志)
3)slow query log(慢查询日志)
4)binlog(二进制日志)
5)relaylog(中继日志)
6)redolog(重做日志)
7)undolog(回滚日志)
重要日志
slow query log:慢查询日志
undolog-redolog:事务日志(innoDB存储引擎日志)
binlog:二进制日志(server层日志)
relaylog:中继日志(主从复制)
error log(错误日志)
定义
error log 是 MySQL 的错误日志。
主要记录 MySQL 服务实例每次启动,停止的详细信息,以及 MySQL 实例运行过程中产生的警告或者错误信息。
和其他的日志不同,MySQL的error日志必须开启,无法关闭。
注意:默认情况下,错误日志的文件名为:主机名.err。 但 error 日志并不会记录所有的错误信息,只有MySQL服务实例运行过程中发声的关键错误(critical)才会被记录下来。
设置错误日志
查看当前的错误日志文件
没有设置错误日志文件,默认指定了一个的错误日志文件
1 | mysql> show variables like 'log_error'; |
命令:
1 | show variables like 'log_error'; #查看当前的错误日志文件,如果没有指定,默认有一个错误日志文件 |
修改配置文件:
修改 my.cnf 文件,在 [mysqld] 下增加或修改参数
1 | [mysqld] |
当前通过修改配置文件指定错误配置文件,重启服务配置生效
可以看到当启动服务后,打印出Starting MySQL.Logging to ‘/var/lib/mysql/error.log’
这代表设置成功!
1 | [root@VM-16-4-centos mysql]# service mysql stop |
查看错误日志文件:
发现 mysql 实例启动的日志【验证了错误日志会记录实例每次启动,停止的详细信息】
1 | [root@VM-16-4-centos mysql]# cat /var/lib/mysql/error.log |
general log(普通日志)
定义
general log 是 MySQL 的普通日志。
主要记录 MySQL 服务实例所有的操作,如:select,update,insert,delete等操作,无论操作是否成功执行都会记录。还记录 MySQL 客户端与 MySQL 服务端连接及断开的相关信息,无论连接成功还是失败。
注意:由于普通日志几乎记录了MySQL的所有操作,对于数据访问频繁的数据库服务器而言,
如果开启MySQL的普通查询日志将会大幅度的降低数据库的性能,因此建议关闭普通查询日志。
只有在特殊时期,如需要追踪某些特殊的查询日志,可以临时打开普通的查询日志。
相关参数
普通日志相关参数:
- general_log:是否开启普通日志
- general_log_file:普通日志文件的存放路径
开启普通日志
查看普通日志的当前配置
1 | mysql> show variables like '%general_log%'; |
命令:
1 | show variables like '%general_log%'; #查看普通日志是否开启 |
修改配置文件:(永久开启)
修改 my.cnf 文件,在 [mysqld] 下增加或修改参数
1 | [mysqld] |
当前通过修改配置文件指定普通日志配置,重启服务后查看普通日志。
结论:可以看到,普通日志记录了客户端登录,查询数据库,查询表的所有操作。
1 | [root@VM-16-4-centos mysql]# cat /var/lib/mysql/general.log |
普通日志文件处理
//TODO
slow query log(慢查询日志)
定义
slow query log 是 MySQL 的慢查询日志。
主要记录 MySQL 中【响应时间超过阀值的sql语句】 或【没有使用索引】的查询语句。
注意:慢查询日志与普通查询日志不同,区别在于:慢查询日志只包含成功执行过的查询语句。
相关参数
以下是慢查询日志相关的参数:
- slow_query_log:慢查询日志是否开启
- slow_query_log_file:慢查询日志文件的存放路径,如果没有指定参数slow_query_log_file的话,系统默认会给一个缺省的文件host_name-slow.log。
- long_query_time:设置慢查询的时间阈值,默认阈值是10s。
- log_quries_not_using_indexes:是否将不适用索引的查询语句记录到慢查询日志中,无论查询速度有多快。
- slow_queries:记录当前慢查询sql条数
开启慢查询日志
查看慢查询日志的当前配置.
默认情况下slow_query_log的值为OFF,表示慢查询日志是禁用的。
1 | mysql> show variables like '%slow_query_log%'; |
命令:
1 | show variables like '%slow_query_log%'; #查看是否开启 |
修改配置文件:(永久开启)
修改 my.cnf 文件,在 [mysqld] 下增加或修改参数
1 | [mysqld] |
什么 sql 会被记录到慢查询日志
问:开启慢查询日志后,什么 sql 会被记录到慢查询日志里面呢?
答:慢查询日志主要记录【响应时间超过阀值的sql语句】或【没有使用索引】的查询语句。
记录响应时间超过阀值的sql语句
时间阈值是由 long_query_time 控制的.
long_query_time:设置慢查询的时间阈值,默认阈值是10s。可以使用命令修改,也可以在my.cnf参数里面修改。
命令:
1 | show variables LIKE 'long_query_time%'; #查看long_query_time的值 |
修改配置文件:(永久开启)
修改 my.cnf 文件,在 [mysqld] 下增加或修改参数
1 | [mysqld] |
记录没有使用索引的查询语句
log_quries_not_using_indexes:是否将不使用索引的查询语句记录到慢查询日志中,无论查询速度有多快。
命令:
1 | show variables like '%log_queries_not_using_indexes%'; #查看值 |
修改配置文件:(永久开启)
修改 my.cnf 文件,在 [mysqld] 下增加或修改参数
1 | log_queries_not_using_indexes=1 |
慢查询 sql 案例
1 | set global slow_query_log=1; #设置开启慢查询日志 |
去mysql的data目录下找到慢查询日志文件:
我没有去配置日志文件名,所以是一个默认的文件名:localhost-slow.log
可以看到当前慢查询日志中会记录查询超过了阈值的sql,我们刚刚的select sleep(4)就在当中,而且可以明确的看到当前sql,当前查询时间,锁的时间,一共有多少数据。
日志查询分析器(mysqldumpslow)
日志查询分析器的体现:
在生产环境中,如果要手工分析日志,查找、分析SQL,显然是个体力活,MySQL提供了日志分析工具mysqldumpslow。
mysqldumpslow –help 查看mysqldumpslow的帮助信息
- s:表示按照何种方式排序
- c:访问次数
- l:锁定时间
- r:返回记录
- t:查询时间
- al:平均锁定时间
- ar:平均返回记录数
- at:平均查询时间
- t:即为返回前面多少条数据
- g:后边搭配一个正则匹配模式,大小写不敏感。
分析器常用的方式:
1 | #得到返回数据集最多的10个SQL |
bin log(二进制日志)
定义
bin log 是 MySQL 的二进制文件,也叫归档日志,是Mysql Server层记录的。
主要记录 MySQL 数据库中的所有更新操作,如:use,insert,delete,update,create,alter,drop等操作。不改变数据的sql不会记录,比如 select 语句一般不会被记录,因为他们不会对数据产生任何改动。
用一句更简介易懂的话概况就是:所有涉及数据变动的操作,都会记录到二进制日志文件中。
应用场景
1)数据恢复
做数据恢复。因为binlog详细的记录了所有修改数据的sql,在某个时间段因操作导致数据出现问题,或数据库党纪数据丢失,那么就可以通过binlog来恢复历史数据。
2)mysql主从复制
做数据备份和读写分离。在 master 端开启 bin log,master 把它的二进制日志传递给 slaves 来达到master-slave数据一致的目的。
二进制日志文件常用操作命令
1)查看是否启动bin log 日志
show variables like ‘log_bin’;
1 | mysql> show variables like 'log_bin'; |
2)查看binlog的目录
show global variables like “%log_bin%”;
3)查看主库的日志文件,以及position信息
show master logs;
1 | mysql> show master logs; |
4)查看master状态,即最后(最新)一个bin log日志的编号名称,及其最后一个操作事件pos结束点(Position)值。
show master status;
1 | mysql> show master status; |
5)flush 刷新log日志,自此刻开始产生一个新编号的bin log日志文件;
flush logs;
注意:每当mysqld服务重启时,会自动执行此命令,刷新bin log日志;在mysqlddump备份数据时加-F选项也会刷新bin log日志;
6)重置(清空)所有bin log日志;
reset master;
开启bin log
注意:mysql 8.0 版本之前,默认不开启,建议开启。
查看二进制日志的当前配置:
可以看到,二进制日志默认是不开启的
1 | mysql> show variables like 'log_bin'; |
修改配置文件:(永久开启)
修改 my.cnf 文件,在 [mysqld] 下增加或修改参数
1 | [mysqld] |
修改配置文件后,重启服务配置生效
查看 bin log 日志文件
bin log 的写入时机
对支持事务的引擎如InnoDB而言,必须要提交了事务才会记录binlog。binlog 什么时候刷新到磁盘跟参数 sync_binlog 相关。
sync_binlog参数讲解:
1)如果设置为0,则表示MySQL不控制binlog的刷新,由文件系统去控制它缓存的刷新;
2)如果设置为不为0的值,则表示每 sync_binlog 次事务,MySQL调用文件系统的刷新操作刷新binlog到磁盘中。
3)设为1是最安全的,在系统故障时最多丢失一个事务的更新,但是会对性能有所影响。
如果 sync_binlog=0 或 sync_binlog大于1,当发生电源故障或操作系统崩溃时,可能有一部分已提交但其binlog未被同步到磁盘的事务会被丢失,恢复程序将无法恢复这部分事务。
在MySQL 5.7.7之前,默认值 sync_binlog 是0,MySQL 5.7.7和更高版本使用默认值1,这是最安全的选择。一般情况下会设置为1或者0,牺牲一定的一致性来获取更好的性能。
bin log 文件以及扩展
二进制日志包含两种文件:
- 二进制日志索引文件(文件名后缀.index),用于记录索引的二进制文件
- 二进制日志文件(文件名后缀为.00000*)记录数据库所有的DDL和DML语句事件
binlog是一个二进制文件集合,每个binlog文件以一个4字节的魔数开头,接着是一组Events:
- 魔数:0xfe62696e对应的是0xfebin;
- Event:每个Event包含header和data两个部分;header提供了Event的创建时间,哪个服务器等信息,data部分提供的是针对该* Event的具体信息,如具体数据的修改;
- 第一个Event用于描述binlog文件的格式版本,这个格式就是event写入binlog文件的格式;
- 其余的Event按照第一个Event的格式版本写入;
- 最后一个Event用于说明下一个binlog文件;
- binlog的索引文件是一个文本文件,其中内容为当前的binlog文件列表
当遇到以下3种情况时,MySQL会重新生成一个新的日志文件,文件序号递增:
- MySQL服务器停止或重启时
- 使用 flush logs 命令;
- 当 binlog 文件大小超过 max_binlog_size 变量的值时;
max_binlog_size 的最小值是4096字节,最大值和默认值是 1GB (1073741824字节)。事务被写入到binlog的一个块中,所以它不会在几个二进制日志之间被拆分。因此,如果你有很大的事务,为了保证事务的完整性,不可能做切换日志的动作,只能将该事务的日志都记录到当前日志文件中,直到事务结束,你可能会看到binlog文件大于 max_binlog_size 的情况。
注意:bin log与数据库文件在同目录中。
bin log 的日志格式
记录在二进制日志中的事件的格式取决于二进制记录格式。支持三种格式类型:
- STATEMENT:基于SQL语句的复制(statement-based replication, SBR)
- ROW:基于行的复制(row-based replication, RBR)
- MIXED:混合模式复制(mixed-based replication, MBR)
注意:在 MySQL 5.7.7 之前,默认的格式是 STATEMENT,在 MySQL 5.7.7 及更高版本中,默认值是 ROW。日志格式通过 binlog-format 指定,如 binlog-format=STATEMENT、binlog-format=ROW、binlog-format=MIXED。
Statement
每一条会修改数据的sql都会记录在binlog中
优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO, 提高了性能。
缺点:由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行的时候相同的结果。另外mysql的复制,像一些特定函数的功能,slave与master要保持一致会有很多相关问题。
Row
5.1.5版本的MySQL才开始支持 row level 的复制,它不记录sql语句上下文相关信息,仅保存哪条记录被修改。
优点: binlog中可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以row的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,或function,以及trigger的调用和触发无法被正确复制的问题.
缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。
注:将二进制日志格式设置为ROW时,有些更改仍然使用基于语句的格式,包括所有DDL语句,例如CREATE TABLE, ALTER TABLE,或 DROP TABLE。
Mixed
从5.1.8版本开始,MySQL提供了Mixed格式,实际上就是Statement与Row的结合。
在Mixed模式下,一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。
bin log企业模式的选择
互联网公司使用MySQL的功能较少(不用存储过程、触发器、函数),选择默认的Statement level;
用到MySQL的特殊功能(存储过程、触发器、函数)则选择Mixed模式;
用到MySQL的特殊功能(存储过程、触发器、函数),又希望数据最大化一直则选择Row模式;
查看二进制日志文件
bin log是二进制文件,普通文件查看器cat、more、vim等都无法打开,必须使用自带的 mysqlbinlog 命令查看。
mysqlbinlog 工具查看
mysqlbinlog 是 MySQL 中自带的工具,具体位置在 MySQL 的 bin 目录下。
在Mysql5.5以下版本使用mysqlbinlog命令时如果报错,就加上”–no-defaults”选项
mysqlbinlog 使用语法:
1 | # mysqlbinlog 的执行格式 |
查看二进制日志文件:mysqlbinlog -v –base64-output=decode-rows mysql-bin.000002
1 | # at 391 |
解释:
- position: 位于文件中的位置,即第一行的(# at 391),说明该事件记录从文件第391个字节开始
- timestamp: 事件发生的时间戳,即第二行的(#210622 17:06:40)
- server id: 服务器标识(1)
- end_log_pos 表示下一个事件开始的位置(即当前事件的结束位置+1)
- thread_id: 执行该事件的线程id (thread_id=2)
- exec_time: 事件执行的花费时间
- error_code: 错误码,0意味着没有发生错误
- type:事件类型Query
命令查看
mysqlbinlog 查看取出 bin log 日志的全文内容比较多,不容易分辨查看到pos点信息
介绍一种更为方便的查询命令 show bin log events
命令解析 show bin log events [IN ‘log_name’] [FROM pos] [LIMIT [offset,] row_count];
参数解析:
a、IN ‘log_name’:指定要查询的bin log文件名(不指定就是第一个bin log文件
b、FROM pos:指定从哪个pos起始点开始查起(不指定就是从整个文件首个pos点开始算)
c、LIMIT【offset】:偏移量(不指定就是0)
d、row_count :查询总条数(不指定就是所有行)
show bin log events查询:
1 | mysql> show bin log events in'mysql-bin.000002'; |
利用二进制日志恢复数据
// TODO
relay log(中继日志)
定义
// TODO
MySQL 事务日志(redolog & undolog)
请看MySQL事务日志分析博客