mysql|mysql日志文件总结

前言 之前简单了解了下mysql,一直总结下自己学习成果,但就是一直拖,现在就简单实现自己一个小愿望,其实还有一个错误日志,但看了下就不加入,后面再补进去,主要是redo,undo,binlog。
redo 日志 概念
重做日志,用于记录事务操作变化,记录的是数据被修改之后的值
组成

  1. 内存中的重做日志缓冲(redo log buffer)
  2. 重做日志文件(redo log file)
持久化
每次数据更新会先更新 redo log buffer,然后根据 innodb_flush_log_at_trx_commit 来控制 redo log buffer 更新到 redo log file 的时机。innodb_flush_log_at_trx_commit 有三个值可选:
  1. 0:事务提交时,在事务提交时,每秒触发一次 redo log buffer 写磁盘操作,并调用操作系统 fsync 刷新 IO 缓存。
  2. 1:事务提交时,InnoDB 立即将缓存中的 redo 日志写到日志文件中,并调用操作系统 fsync 刷新 IO 缓存;(默认:1)
  3. 2:事务提交时,InnoDB 立即将缓存中的 redo 日志写到日志文件中,但不是马上调用 fsync 刷新 IO 缓存,而是每秒只做一次磁盘 IO 缓存刷新操作
mysql|mysql日志文件总结
文章图片

innodb_flush_log_at_trx_commit三种持久化选项的优劣势
mysql|mysql日志文件总结
文章图片

补充
  1. 预写日志方式(WAL): 数据落盘前,需要先写日志,比如说当一个事务开始时,会记录该事物的LSN(日志序列号),当事务执行的时候,会往日志缓存中插入事务日志,提交的时候将日志缓存落盘, 这种方式称为预写日志方式
  2. checkpoint:checkpoint是为了定期将db buffer的内容刷新到data file。当遇到内存不足、db buffer已满等情况时,需要将db buffer中的内容/部分内容(特别是脏数据)转储到data file中。在转储时,会记录checkpoint发生的”时刻“。在故障回复时候,只需要redo/undo最近的一次checkpoint之后的操作
Undo 日志 概念
Undo: 逻辑日志(回滚日志),将数据库逻辑地恢复到原来的样子,所有修改都被逻辑地取消了。Undo存在数据库内部的一个特殊的段(undo 段)中,undo段位于共享表空间内。
原理
undo日志一般被称为回滚日志,一般执行ROLLBACK时,会将数据恢复到事务开始的状态。注意我们这里并不是将数据库物理的恢复到执行语句或事务之前的样子,而是我们操作一步就会生成一个相反的操作放入undo 段中。比如说:当我们insert一条记录的时候,那么undo段中也会生成对应delete 一条记录。
作用
  1. 日志回滚
  2. 实现MVCC
binlog 概念
二进制日志(binlog)记录了所有的 DDL(数据定义语句)和 DML(数据操纵语句),但是不包括 select 和 show 操作
作用
  1. 恢复:某些数据的恢复需要二进制日志,如当一个数据库全备文件恢复后,我们可以通过二进制日志进行point-in-time的恢复
  2. 复制:通过复制和执行二进制日志使的一台远程的mysql数据库(salve或standby)与一台mysql数据库(master或primary)进行实时同步
启动binlog
二进制日志文件默认的情况下是没有启动的,我们需要手动配置log-bin[=name]进行启动二进制日志。如果我们不指定name,则默认二进制日志文件名为主机名,后缀名为二进制日志的序列号。虽然开启二进制日志会对mysql数据库性能有所影响,但是这个影响是有限的,相对于可以使用复制和point-in-time的恢复,这些性能可以接受。
注意:
  1. 根据mysql官方手册的测试表名,开启二进制日志会使得性能下降1%
  2. SHOW VARIABLES LIKE "datadir"可以查看数据库所在目录
binlog配置
  1. max_binlog_size:单个二进制日志文件的最大值(mysql5.0开始默认1G),超过该值就产生新的日志文件,后缀名+1,并记录到.index文件
  2. binlog_cache_size:当一个线程开始一个事务的时候,mysql会自动分配一个大小为binlog_cache_size(默认32KB)的缓存,等到事务提交的时候直接将缓冲中的二进制日志写入二进制日志文件中。另外如果事务记录大于binlog_cache_size时,mysql会将缓冲中的日志写入一个临时文件中。为了更好的设置binlog_cache_size值的大小,可以通过SHOW GLOBAL STATUS查看binlog_cache_use, binlog_cache_disk_use来判断当前的的设置是否合理
  3. binlog_cache_use: 记录使用缓冲写二进制日志的次数
  4. binlog_cache_disk_use:记录了使用临时文件写二进制日志的次数
  5. sync_binlog:表示每写缓冲多少次就同步到磁盘中:
    sync_binlog=0:表示每次提交事务都只write,不fsync sync_binlog=1:表示每次提交事务都会执行fsync; sync_binlog=N(N>1):表示每次提交事务都write,累积N个事务后才fsync 。注意:当sync_binlog=1时,使用innodb存储引擎时,在一个事务发出commit动作之前,由于sync_binlog=1,因此会立即将二进制日志文件写入磁盘。如果这时已经写入二进制日志,但没有提交,并且此时发生宕机,那么下次数据库启动时候,因commit操作没有发生,所以这个事务会被回滚,但是二进制日志已经记录了该事务信息,不能回滚。这个问题可以通过将参数innodb_support_xa设为1解决。

  6. binlog-do-db:需要写入哪些库的日志
  7. binlog-ignore-db:忽略写入哪些库的日志
  8. binlog_format:记录二进制日志的格式(5.1版本后引入)
    1- STATEMENT:记录的是日志的逻辑sql语句 2- ROW:记录表的行更改情况3- MIXED:默认采用STATEMENT格式进行二进制文件的记录,但是在一些情况下会使用ROW,情况有: 1) 表的存储引擎为NDB,这时对于表的DML操作都会以ROW格式记录 2) 使用了UUID(), USER(),CURRENT_USER(),FOUND_ROWS(),ROW_COUNT()等不确定函数 3) 使用了INSERT DELAY语句 4) 使用了用户定义函数 (UDF) 5) 使用了临时表


binlog和redo日志的区别
(1)作用不同:redo log是用于crash recovery的,保证MySQL宕机也不会影响持久性;binlog是用于point-in-time recovery的,保证服务器可以基于时间点恢复数据,此外binlog还用于主从复制。
(2)层次不同:redo log是InnoDB存储引擎实现的,而binlog是MySQL的服务器层(可以参考文章前面对MySQL逻辑架构的介绍)实现的,同时支持InnoDB和其他存储引擎。
(3)内容不同:redo log是物理日志,内容基于磁盘的Page;binlog的内容是二进制的,根据binlog_format参数的不同,可能基于sql语句、基于数据本身或者二者的混合。
(4)写入时机不同:binlog在事务提交时写入;redo log的写入时机相对多元:
  • 前面曾提到:当事务提交时会调用fsync对redo log进行刷盘;这是默认情况下的策略,修改innodb_flush_log_at_trx_commit参数可以改变该策略,但事务的持久性将无法保证。
  • 除了事务提交时,还有其他刷盘时机:如master thread每秒刷盘一次redo log等,这样的好处是不一定要等到commit时刷盘,commit速度大大加快。
慢查日志 概念
通过long_query_time设置一个阈值(默认10秒),将运行时间超过该值的所有sql语句都记录到对应的日志文件中,这个日志文件就叫做慢查询日志
配置
  1. long_query_time: 设置阈值,超出这个阈值的就会记录到慢查询日志文件中(等于这个阈值是不会记录)
  2. log_queries_not_usinf_indexes:开启后,没有使用sql语句会记录到日志文件中
查看慢查询日志
  1. 可以通过mysqldumpslow查看,比如说查看时间最长的10条sql语句: mysqldumpslow-sal -n 10 日志文件
  2. 我们可以通过设置慢查询输出到表中。通过SHOW VARIABLES LIKE "log_output" 查看当前是输入file还是表,通过 set global log_output ="TABLE"设置输入表中查看
查询日志 概念
查询日志是关于 mysqld 正在做什么的通用记录。当客户端连接或断开连接时,服务器将信息写入日志,并记录从客户端接收的每个 SQL 语句
配置
  1. 启用查询日志文件: SET GLOBAL general_log = 'ON';
  2. 禁用查询日志文件: SET GLOBAL general_log = 'OFF';
  3. 查询查询日志当前状态: show variables like 'general_log'
  4. 查询查询日志输出格式: SHOW VARIABLES LIKE "log_output"
  5. 设置以表格式输出:set global log_output ="TABLE"
寄语 其实看起来很简单,但是写起来还是有点麻烦,知识点为了证实和弄懂,还是花了点时间。其实有时间还是看看书,看看官方文档(源码就要点基础)。写博客就主要是为了督促自己吧,至少有时候用一个东西大概了解为什么。
参考地址:
Mysql技术内幕-Innodb存储引擎
MySQL的万字总结(缓存,索引,Explain,事务,redo日志等)
mysql5.6官方文档
【mysql|mysql日志文件总结】深入学习MySQL事务

    推荐阅读