> 文章列表 > MySQL 日志

MySQL 日志

MySQL 日志

错误日志(error log):

error log 主要记录 MySQL 在启动、关闭或者运行过程中的错误i西南西,在MySQL 的配置文件 my.cnf 中,可以通过 log-error=/var/log/mysqld.log 执行 mysql 错误日志的位置

慢查询日志(slow query log):

  • MySQL 的慢查询日志是 MySQL 提供的一种日志记录,它用来记录在MySQL 中相应时间超过阈值的语句,具体指运行时间超过 long_query_time 值的SQL,则会被记录到慢查询日志中
  • long_query_time 的默认值是10,意思是运行10秒以上的语句
  • 由他来查看哪些SQL 超出了我们的最大忍耐时间值,比如一条sql 执行超过5秒钟,我们就算慢SQL,希望能收集超过5秒的sql,结合之前 explain 进行全面分析
  • 默认情况下,MySQL 数据库没有开启慢查询日志,需要我们手动来设置这个参数
  • 当然,如果不是调优需要的化,一般不建议启动该参数,因为开启慢查询日志会或多或少带来一定的性能影响。慢查询日志支持将日志记录写入文件
  • 在生产环境中,如果要手工分析日志,查找,分析SQL,显示是个体力活, MySQL 提供了日志分析工具 mysqldumpslow.

一般查询日志(general log):

  • 记录客户端连接信息以及执行的SQL语句信息,通过 MySQL 的命令

二进制日志(bin log):

  • MySQL 的 bin log 日志是用来记录MySQL 中增删改的记录日志。
  • 当你的一条SQL 操作对数据库中的内容进行了更新,就会增加一条 bin log 日志。查询操作不会记录到bin log 中
  • bin log 最大的用处就是主从复制,以及数据库的恢复

重写日志(redo log):

  • redo log 是一种基于磁盘的数据结构,用来在MySQL 宕机情况下将不完整的事务执行数据纠正, redo 日志记录事务执行后的状态。
  • 当事务开始后, redo log 就开始产生,并且随着事务的执行不断写入 redo log file 中。 redo log file 中记录了 xxx 页做了 xx 修改的信息,我们都知道数据库的更新操作会在内存中先执行,最后刷入磁盘
  • redo log 就是为了恢复更新了内存但是由于宕机等愿您没有刷入磁盘中的那部分数据

回滚日志(undo log):

  • undo log 主要用来回滚到某一版本,是一种逻辑日志
  • undo log 记录的是修改之前的数据,比如:delete 一条记录时,undo log 会记录一条对应的 insert 记录,从而保证能恢复到数据修改之前。在执行事务回滚的时候,就可以通过 undo log 中的记录内容以此进行回滚
  • undo log 还提供了多版本并发控制下的读取(MVCC)

bin log 写入策略:

  • sync_binlog = 0 的时候,表示每次提交事务 bin log 不会马上写入磁盘,而是先写到page cache,相对于磁盘写入来说写 page cache 要快得多,不过在 MySQL 崩溃的时候会有丢失日志的风险
  • sync_binlog = 1 的时候,表示每次提交事务都会执行 fsync 写入到磁盘
  • sync_binlog 的值大于 1的时候,表示每次提交事务都先写到page cache, 只有等到累积了 N 个事务之后才 fsync 写入到磁盘,同样在此设置下MySQL 崩溃的时候会有丢失 N个事务日志的风险

innodb_flush_log_at_trx_commit:

  • 取值0:每秒(一秒钟内提交的事务)写入磁盘 每秒触发一次缓存日志回写磁盘操作,并调用操作系统 fsync 刷新 I/O 缓存
  • 取值1: 有事务提交就立即刷盘,每次提交事务都立即调用操作系统 fsync 刷新 I/O 缓存
  • 取值2: 每次事务提交 都写给操作系统,由操作系统接管什么时候写入磁盘,每次都把redo log 写道系统的 page cache中,由系统接管什么时候写入磁盘

日志刷盘时机顺序:

  1. 开启事务
  2. 查询数据库中需要更新的字段,加载到内存中形成数据脏页
  3. 记录undo log 到内存缓冲区(用于回滚和mvcc) 并关联 redo log
  4. 记录 redo log 到内存缓冲区(用于失败重放) 准备提交事务
  5. 修改内存中的脏页数据
  6. 提交事务触发 redo log 刷盘
  7. undo log 和 脏页刷盘
  8. 事务成功

redo log 和 bin log 的两阶段提交:

  • prepare: redolog 写入 log buffer,并 fsync 持久化到磁盘,在 redo log 事务中记录 2PC 的 XID,在 redolog 事务打上 prepare 表示
  • commit: binlog 写入 logbuffer, 并 fsync 持久化到磁盘,在bin log 事务中记录 2PC的 XID,同时在 redo log 事务打上 commit 标识

 MySQL 的 bin log 有几种录入格式:

  • binlog_format=STATEMENT(默认): 数据操作的时间,同步时不一致。每一条会修改数据的sql 语句会记录到 bin log 中。有点是并不需要记录每一条 sql语句和每一行的数据变化,减少了 bin log 日志量,节约 I/O, 提高性能。缺点是某些情况下会导致 master-slave 中的数据不一致(如 sleep() 函数, last_insert_id(),以及 user_defined functions(udf) 等会出现问题)
  • binlog_format=ROW: 批量数据操作时,效率低。 不记录每条 sql 语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样子。而且不会出现某些特定情况下的存储过程、或 function、或trigger 的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table 的时候会让日志暴涨
  • binlog_format=MIXED: 是以上两种 level 的混合适用,有函数用 ROW,没函数用 STATEMENT,但是无法识别系统变量

MySQL 集群同步为什么适用 Bin log:

  • bin log 是 mysql 提供的日志,所有存储引擎都可用
  • 支持增量同步
  • bin log 还可以供其他中间件读取,比如同步到hdfs中

如果复制表数据:

  • 不支持某个阶段回放
  • 直接复制数据过程一旦中断复制(比如断网),很难确定复制的 offset