1 mysql日志类型
1.1 重做日志(redo log)
- 作用:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。
- 内容:物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中去的。
- 产生:事务开始之后就产生redo log,redo log的落盘并不是随着事务的提交才写入的,而是在事务的执行过程中,便开始写入redo log文件中。
- 释放:当对应事务的脏页写入到磁盘之后,redo log的使命也就完成了,重做日志占用的空间就可以重用(被覆盖)。
- 写盘:重做日志的写盘,并不一定是随着事务的提交才写入重做日志文件的,而是随着事务的开始,逐步开始的。
- Master Thread 每秒一次执行刷新Innodb_log_buffer到重做日志文件。
- 每个事务提交时会将重做日志刷新到重做日志文件。
- 当重做日志缓存可用空间 少于一半时,重做日志缓存被刷新到重做日志文件
1.2 回滚日志(undo log)
- 作用:保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读
- 内容:逻辑格式的日志,在执行undo的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于redo log的。
- 产生:事务开始之前,将当前是的版本生成undo log,undo 也会产生 redo 来保证undo log的可靠性
- 释放:当事务提交之后,undo log并不能立马被删除,而是放入待清理的链表,由purge线程判断是否由其他事务在使用undo段中表的上一个事务之前的版本信息,决定是否可以清理undo log的日志空间。
1.3 二进制日志(binlog)
- 作用:用于复制,在主从复制中,从库利用主库上的binlog进行重播,实现主从同步;用于数据库的基于时间点的还原;
- 内容:逻辑格式的日志,可以简单认为就是执行过的事务中的sql语句。但又不完全是sql语句这么简单,而是包括了执行的sql语句(增删改)反向的信息,也就意味着delete对应着delete本身和其反向的insert;update对应着update执行前后的版本的信息;insert对应着delete和insert本身的信息。
- 产生:事务提交的时候,一次性将事务中的sql语句(一个事物可能对应多个sql语句)按照一定的格式记录到binlog中。
- 释放:binlog的默认是保持时间由参数expire_logs_days配置,也就是说对于非活动的日志文件,在生成时间超过expire_logs_days配置的天数之后,会被自动删除。
1.4 错误日志(errorlog)
- 作用:用于记录和分析启动、运行或停止mysqld时出现的问题
- 内容:记录了MySQL Server每次启动和关闭的详细信息以及运行过程中所有较为严重的警告和错误信息。
- 默认:开启
1.5 慢查询日志(slow query log)
- 作用:运行时间超过long_query_time值的SQL,则会被记录到慢查询日志中(日志可以写入文件或者数据库表,如果对性能要求高的话,建议写文件),用于分析慢查询语句
- 内容:慢查询日志信息
- 默认:关闭
1.6 一般查询日志(general log)
- 作用:用来记录MySQL服务器做了哪些事情,当客户端连接至MySQL服务器时,日志会记录来自客户端的查询语句
- 内容:包括客户端的连接类型,例如:TCP/IP,SSL(经过加密的TCP/IP),SOCKET(UNIX socket 文件通信)等等。需要注意的一点,日志里面的内容是按照从客户端接收的语句顺序记录,而不是按照实际执行的顺序记录,这一点与二进制日志有很大的不同
- 默认:关闭
- 受binlog模式影响
- 当binlog采用基于语句的格式(STATEMENT)时,主从复制的情况下,从机会记录所有接收的执行语句。并且,当连接主机的客户端使用了mysql binlog工具对日志里面的事件进行读取,该语句也会计入主机的一般查询日志
- 当binlog采用基于数据行的格式(ROW)时,更新操作会发送实际的数据行进行,而不是使用查询语句,因此,一般查询日志里不会记录该部分的查询语句
- 当binlog采用混合格式(MIX)时,会有部分语句无法记录到一般查询日志
1.7 中继日志(relay log)
- 作用:中继日志是连接mastert和slave的信息,它是复制的核心,I/O线程将来自master的事件存储到中继日志中,中继日志充当缓冲,这样master不必等待slave执行完成就可以发送下一个事件
- 内容:中继日志和binlog的结构差不多,只不过是多了一些文件,中继日志维护两个文件来跟踪复制的进度,即中继日志信息文件和master日志信息文件
2 binlog三种模式
2.1 Statement Level(默认)
每一条会修改数据的sql都会记录到master的bin-log中。slave在复制的时候sql进程会解析成和原来master端执行过的相同的sql来再次执行
- 优点:statement level下的优点首先就是解决了row level下的缺点,不需要记录每一行数据的变化,减少bin-log日志量,节约IO,提高性能,因为它只需要在Master上锁执行的语句的细节,以及执行语句的上下文的信息。
- 缺点:由于只记录语句,所以,在statement level下 已经发现了有不少情况会造成MySQL的复制出现问题,主要是修改数据的时候使用了某些定的函数或者功能的时候会出现。
- 场景:MySQL的存储过程、触发器、函数等功能使用相对少
1.2 Row Level 行模式
日志中会记录每一行数 据被修改的形式,然后在slave端再对相同的数据进行修改。5.1.5版本才开始支持Row Level模式。
- 优点:在row level模式下,bin-log中可以不记录执行的sql语句的上下文相关的信息,仅仅只需要记录那一条被修改。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。不会出现某些特定的情况下的存储过程或function,以及trigger的调用和触发无法被正确复制的问题
- 缺点:row level,所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,会产生大量的日志内容。
1.3 Mixed 自动模式
在Mixed模式下,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志格式,也就是在Statement和Row之间选择一种。如果sql语句确实就是update或者delete等修改数据的语句,那么还是会记录所有行的变更。
优点:避免了Statement Levle和Row Level的缺点
场景:MySQL的存储过程、触发器、函数等功能使用相对多
1.4 Statement Level和Row Level区别举例
test表中有1万条记录,执行:delete * from test
- Statement Level只需要1条删除记录
- Row Level需要1万条删除记录。
参考