2. Mysql的日志系统
Mysql有2个重要的日志模块,redo log(重做日志)和bin log(归档日志)。
Mysql如果每次跟新操作都需要写入磁盘,然后磁盘找到对应的记录,然后再跟新记录,整个过程IO成本,查找成本都很高。为了解决这个问题,mysql采用了WAL(Write Ahead Logging)技术,它的关键点就是先写日志,再写磁盘。当有一条记录需要跟新时,InnoDB引擎就会先把记录写到redo log中,并跟新内存,数据跟新就算完成了,同时,InnoDB会在系统比较空闲的时候,再将操作记录跟新到磁盘里面。
为了最大程度避免数据写入时io瓶颈带来的性能问题,MySQL采用了这样一种缓存机制:当query修改数据库内数据时,InnoDB先将该数据从磁盘读取到内存中,修改内存中的数据拷贝,并将该修改行为持久化到磁盘上的事务日志(先写redo log buffer,再定期批量写入),而不是每次都直接将修改过的数据记录到硬盘内,等事务日志持久化完成之后,内存中的脏数据可以慢慢刷回磁盘,称之为Write-Ahead Logging。事务日志采用的是追加写入,顺序io会带来更好的性能优势。
Binlog有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。
两种日志的不同点:
1. redo log是InnoDB引擎特有的功能,bin log(归档日志)是mysql的server层实现的,所有的搜索引擎都可以使用。
2. redo log是物理log,记录的是“某个数据页上做了什么修改”;binlog是逻辑日志,记录了sql语句的原始逻辑。
3. redo log是循环写的,空间固定,会用完;bin log是可以追加写入的,不会覆盖以前的log。
update语句的执行流程:
update语句执行流程redo log用于保证crash-safe能力。innodb_flush_log_at_trx_commit这个参数设置为1的时候,表示每次事务的redo log都直接持久化到磁盘,建议设置为1。
sync_binlog这个参数设置为1的时候,表示每次事务的binlog都持久化到磁盘,建议设置为1。