1、InnoDB 更新数据得总体架构mysql
每一个组件的做用说明:面试
用一条更新数据来讲明每一个主键得做用:sql
update student set name = 'zhangsan' where id = 10缓存
1. innodb得重要内存接口:缓冲池(Buffer Pool)架构
innodb存储引擎中有一个重要得放在内存中得组件,就是缓冲池(Buffer Pool),这里面会缓存不少得数据,以便于之后查询数据得时候,若是在内存缓冲中有数据,就能够直接从内存返回不须要查询磁盘加载到内存缓冲中。sqlserver
若是InnoDB存储引擎须要执行一条更新语句得时候,好比上面那条数 id = 10 这条数据时候,首先会在缓冲中是否存在 id = 10 这条数据,若是不存在就直接从磁盘中把该条数据加载到缓冲里来,并且会对这条数据加独占锁。优化
2. undo 日志文件:保证更新后的数据能够回滚ui
假设 id = 10 这行数据的name原来是 zhangsan, 如今须要更新为 lisi,那么此时须要先把更新的原来的值 name = 'zhangsan' 和 id = 10 这些信息,写入到undo日志文件中,若是在后面的操做出现异常,须要作回滚数据就会从undo日志文件中加载回滚。线程
3. 更新Buffer Pool中的缓冲数据日志
当咱们把要更新的那行数据从磁盘文件加载到缓冲池,同时对该行数据枷锁后把更新前的旧值写入到undo日志文件以后,旧能够正式开始更新这行记录了,先更新缓冲池中的记录,此时这行数据是脏数据。由于磁盘上的依旧是 name 的值是zhangsan,内存中的已是lisi因此说是脏数据。
4. Redo Log buffer:防止Mysql服务宕机后,保证数据不被丢失。
在buffer pool 中修改了数据后,咱们必须把对内存所做的修改写入到一个Redo Log Buffer的内存缓冲区中,这个缓冲区是用于存放redo日志的。所谓的redo日志,就是记录下来对数据作了什么修改,好比对 id = 10 这行记录修改了name字段的值为lisi,这就是一条日志。
在提交事物的时候会将redo日志写入到磁盘中(顺序写入),有一下集中方式写入:
innodb_flush_log_at_trx_commit = 1:不写入磁盘
innodb_flush_log_at_trx_commit = 2:提交事务的时候刷盘
innodb_flush_log_at_trx_commit = 3:写入系统的os再定时刷入磁盘
通常使用的是第二种。
5. binglong日志
binglog日志是mysql server 服务的日志,叫作归档日志,他里面记录的是逻辑行的日志,相似于 对 srtudent 表中的 id = 10 这行数据作了更新操做,更新后的值是什么。
在提交事务的时候须要binglog日志写入到磁盘中,写入的策略以下:
sync_binglog = 0:提交事务时写入系统缓冲在定时刷入磁盘
sync_binglog = 1:提交事务时写入磁盘。
总结innodb存储引擎作一次跟新的架构原理:
你们经过一次更新数据的流程,就能够清晰地看到,InnoDB存储引擎主要就是包含了一些buffer pool redo log buffer等内存里的缓存数据,同时还包含了一些undo日志文件,redo日志文件等东西,同时mysqlserver本身还有binlog日志文件
在你执行更新的时候,每条SQL语句,都会对应修改buffer pool里的缓存数据、写undo日志、写redo log buffer几个步骤
可是当你提交事务的时候,必定会把redolog刷入磁盘,binloq刷入磁盘,完成redolog中的事务commit标记;最后后台的1O线程会随机的把buffer pool里的脏数据刷入磁盘里去
面试题:
1. 执行更新操做的时候,为何不精细修改磁盘上的数据?
2. 若是保证msyql服务宕机后数据更新后的数据不丢失?