msql的存储引擎又分为多种,常见的有InnoDB、MyISAM、Memery,InnoDB最为常见
1、InnoDB的重要内存结构:缓冲池(Buffer Pool)
InnoDB存储引擎中有一个非常重要的放在内存里的组件,就是缓冲池(Buffer Pool),便于查询数据,如果内存缓冲池里有数据,可以直接冲缓冲池取数,不需要去查磁盘
对数据进行修改的时候,会对此条数据加入独占锁,避免修改的时候其他人修改。
例如:id=10,name=‘Lucky’
2、undu日志文件:更新的数据写入undo log
修改之前会将‘id=10’这条数据存入undu log,避免数据出错,利于回滚
3、更新Buffer Pool中的缓存数据
然后在缓冲池中更新数据,将id=10数据修改为name=‘Kieran’,此时的数据为‘脏’数据,与磁盘中name=‘Lucky’不一样
4、缓冲池的数据写入redo log
更新之前的数据写入undo log,更新之后的数据写入redo log
例如:id=10的这行数据name的值修改为Lucky
5、没有提交事务,MySQL宕机
在数据库中,执行一条sql语句,其实也可以是一个独立的事务,当提交事务后,sql语句才算执行结束,如果还没有提交事务,此时MySQL奔溃,必然导致内存里Buffer Pool中修改的数据都丢失,同时写入Redo Log Buffer中的redo日志也会丢失,如图所示
此时MySQL宕机导致内存里的数据都丢失,但是磁盘中的数据还是以前的数据id=10,name=Lucuy,当MySQL重启后,数据并没有任何变化
6、提交事务的时候将redo日志写入磁盘
提交事务,根据一定的策略把redo log从redo log buffer刷入到磁盘文件中,这个策略由innodb_flush_log_at_trx_commit来配置
当innodb_flush_log_at_trx_commit为0时,系统奔溃,数据丢失,提交事务没有将redo log刷入磁盘
当innodb_flush_log_at_trx_commit为1时,提交事务强制将redo log从内存刷入磁盘
此时redo 日志一定在磁盘文件
如果此刻mysql奔溃,内存中的name=Kirean虽然会丢失,但是redo日志中已经记录,将id=10的数据name修改为Kieran,MySQL重启之后,可以根据redo日志去恢复之前做过的修改,如下图所示: