MYSQL难面试
Mysql的存储引擎
1.InnoDB:事务的完整性,并发条件的一致性很高
2.MyISAM: 读多写少,对事务的完整性,并发条件的一致性不高---现在用mongdb
3.MEMORY: 作为缓存(注意缓存)---redis
为什么又binlog了还要redolog?
虽然 binlog 能记录变更,但它是逻辑日志,不能用于崩溃恢复。而 redo log 是物理日志,能在崩溃后恢复未刷盘的数据页,两者配合通过两阶段提交机制,保证数据的一致性和持久性。
- 历史原因,MyISAM不支持崩溃恢复,而InnoDB在加入MySQL前就已经支持崩溃恢复了
- InnoDB使用的是WAL技术,事务提交后,写完内存和日志,就算事务完成了,脏页有没有落盘不在乎!没有redo的情况下,奔溃恢复后如果binlog是残缺的,说明事务没成功,可以通过undo回滚;如果binlog是完整的,却并不能确定崩溃前脏页有没有落盘,这就无法以binlog是否完整判断事务在数据库崩溃前是否已经持久化、脏页是否落盘,而引入redo后,配合两阶段提交,加上redo是物理日志,就可以进行崩溃恢复了。而且binlog本身因为内容格式的原因,并不适合做崩溃恢复,更适合主从同步或备份恢复。
能不能只用redo,不用binlog:
不考虑主从集群、备份恢复,只从崩溃恢复和高效写WAL角度考虑的话,可以把binlog关闭。binlog本身默认就是关闭的
为什么 binlog cache 是每个线程自己维护的,而 redo log buffer 是全局共用的:
binlog 是不能“被打断的”。一个事务的 binlog 必须连续写(主从同步要求,不然可能会出错),因此要整个事务完成后,再一起写到文件里。而 redo log 并没有这个要求(redo用于崩溃恢复,物理日志,先修改哪个后修改哪个无所谓),中间有生成的日志可以写到 redo log buffer 中。redo log buffer 中的内容还能“搭便车”,其他事务提交的时候可以被一起写到磁盘中。
Double write (mysql俩次写)
当MySQL要把内存中的脏页刷入磁盘时,有一个潜在风险:
如果崩溃刚好发生在写数据页的过程中,只写了一半,可能导致磁盘上的数据页损坏,恢复时无法读取。
而数据页是16KB,如果你只写成功了前8KB,系统崩了,磁盘上这个页就坏了,RedoLog也救不了你
Double Write Buffer 写入流程:
1。将一批脏页(通常1MB,包含多个16KB 页)写入 Double Write Buffer(位置在共享表空间 ibdata
文件中);
2. fsync 确保刷盘成功;
3.再将这些页写入对应的数据文件.ibd中;
4。如果数据库崩溃,只要Double Write 区没坏,就能从这里恢复出完整的页,避免页损坏。
面试答题模板:
Double Write Buffer 是InnoDB 防止页损坏的一种机制。InnoDB 在将脏页写入磁盘前,会先将其写入
一个中间区域(DoubleWriteBuffer),确认写成功后再写入数据文件。如果在写入过程中系统崩溃,
可以从中间区域恢复完整页,避免数据页部分写入造成损坏。这是InnoDB数据可靠性设计中的重要一
环,与事务的WAL两次写机制互补。