MySQL中的日志

Posted Java后端进阶指南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL中的日志相关的知识,希望对你有一定的参考价值。

mysql中有两类非常重要的日志,一类是redo log(重做日志),一类是bin log(归档日志)

redo log

重做日志利用的,是MySQL中,常见的WAL技术,WAL技术的全程是:Write-Ahead-Logging,它的关键点就是先写日志,再写磁盘。
在我们的MySQL中,当有一条记录需要更新的时候,InnoDB引擎就会将记录先写到redo log里,并且更新内存,这个时候这次更新操作就已经结束了,InnoDB引擎会在适当的时候,将这个操作记录到磁盘里,这个更新通常情况是在系统比较空闲的时候做的。
InnoDB的redo log是大小固定的,比如可以一次配置一组4个文件每个文件的大小是1GB,那么整个redo log的大小就是4GB。redo log的写入过程是循环写入,从头开始写,写到末尾后,就会又从头开始写(可以想象成一个环状)
有了redo log,InnoDB就可以保证数据库发生异常重启后,之前提交的记录不会丢失。这个能力称为crash-safe。
这里有两个问题。
1. 写日志和直接写数据库有什么差别吗?
写日志的时候,可以看做是一个追加操作,即顺序写。而写数据库则是随机写。在机械硬盘中,顺序写的速度要远大于随机写。(kafka对硬盘的操作也是顺序的,所以即使是机械硬盘,速度也不会太慢)
2. 使用redo log,刷入数据的操作,会不会影响SQL执行效率?
将redo log中的数据刷入磁盘的操作,是一个阻塞的操作。在之行SQL语句的时候,如果伴随着数据脏页的刷入,会就导致MySQL会突然抖一下,执行时间变长。

bin log

bin log被称为归档日志,它是Service层的日志。bin log属于逻辑日志,记录的是语句的原始逻辑,比如将ID等于2一行数据删除。bin log是一种非常重要的日志,他可以用于数据库的读写分离,主从复制等功能(从机读取主机的bin log,通过SQL-Thread执行SQL语句,实现同步),具体如何实现同步,会在日后的博客中讲解。

两段式提交

MySQL在执行一条修改语句时的逻辑如下:

update t set c = c + 1 where id = 5
  1. 执行器先从存储引擎中,找到id=5的这条数据,由于id是主键,所以引擎会执行使用索引树搜索,找到 id=5这一行数据,如果这一条数据已经存在于内存的数据页中,则执行返回给执行器。否则将会从磁盘中将数据页读到内存,再返回。
  2. 执行器拿到id=5的这一行数据,找到c 这一列,c+1得到新数据,再调用引擎层的接口,将新值写入。
  3. 引擎层将这一条新的数据更新到内存中,同时将这个更新操作,记录到redo log里,此时redo log处于prepare状态,通知执行器,语句已经执行成功,随时可以提交事务。
  4. 执行器生成此次操作的bin log,将bin log写入磁盘
  5. 执行器调用提交事务接口,将处于redo log的prepare状态修改成commit状态。

两段式提交的意义,是保证bin log 和redo log的数据一致性。

以上是关于MySQL中的日志的主要内容,如果未能解决你的问题,请参考以下文章

常用python日期日志获取内容循环的代码片段

我的Android进阶之旅NDK开发之在C++代码中使用Android Log打印日志,打印出C++的函数耗时以及代码片段耗时详情

MySQL触发器

Android:RecyclerView 不显示片段中的列表项

使用 json rereiver php mysql 在片段中填充列表视图

片段中的空指针异常