WAL 机制
在计算机科学中,预写式日志(Write-Ahead Logging,缩写 WAL)是关系数据库系统中用于提供原子性和持久性的技术。
在 MySQL 中,为了提高数据库的性能,MySQL 采用了 WAL 机制,即客户端在修改数据的过程后,并不会立马对硬盘中的数据进行更新。
这样做的原因在于,如果每次客户端进行数据更改后,立马对磁盘中的数据进行更改的话,那么磁盘的压力是非常大的。
WAL 机制,主要的操作是先写日志,先在一个日志中记录了 MySQL 要对硬盘中的存储 MySQL 数据的数据页中的数据进行什么样的更改,等到 MySQL 空闲的时候再进行同步操作到硬盘中。
可能有人会疑惑,同样是操作磁盘,为什么写日志比直接改数据会更加高效?
因为写日志是顺序写,而直接改磁盘是随机写。
在磁盘进行随机写入时,需要不断寻找空闲的磁盘块进行数据写入。这个过程需要多次定位和移动磁头,因此会产生大量的磁盘寻道时间,降低磁盘的性能。而顺序写入则可以利用磁盘的预读功能,将相邻的数据一起读入内存,减少寻道时间。
所以同样是写,写日志和直接改磁盘的速度有着天壤之别。
MySQL 常见日志分类
- 错误日志(errorlog):错误日志记录着 mysqld 启动和停止,以及服务器在运行过程中发生的错误及警告相关信息。当数据库意外宕机或发生其他错误时,我们应该去排查错误日志。
- 慢查询日志(slow query log):慢查询日志是用来记录执行时间超过 long_query_time 这个变量定义的时长的查询语句。通过慢查询语句,可以查找出哪些查询语句的执行效率很低,一便进行优化。
- 一般查询日志(general log):一般查询日志又称通用查询日志,是 MySQL 中记录最详细的日志,该日志会记录 mysqld 所有相关操作,当 clients 连接或断开连接时,服务器将信息写入此日志,并记录从 clients 收到的每个 SQL 语句。当你怀疑 client 中的错误并想要确切知道 client 发送给 mysqld 的内容时,通用查询日志非常有用。
- 二进制日志(binlog):它记录了数据库所有执行的 DDL 和 DML 语句,以事件形式记录并保存在二进制文件中。常用于数据恢复和主从复制。
- 中继日志(relay_log):中继日志用于主从复制架构中的从服务器上,从服务器的 slave 进程从主服务器处获取二进制日志的内容并写入中继日志,然后由 SQL 进程读取并执行中继日志中的语句。
- 重做日志(redo log):确保事务的持久性。redo 日志记录事务执行后的状态,用来恢复未写入data file 的已成功事务更新的数据。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启 mysql 服务的时候,根据 redo log 进行重做,从而达到事务的持久性这一特性。
- 回滚日志(undo log):报纸数据的原子性,当事务对数据库进行修改,InnoDB 引擎不仅会记录 redo log,还会生成对应的 undo log 日志;如果事务执行失败或调用了 rollback,导致事务需要回滚,就可以利用 undo log 中的信息将数据回滚到修改之前的样子。