02 SQL更新语句是如何执行的

binlog

1.为什么需要binlog?
binlog时Mysql的Server层的日志,是所有引擎都能用的。功能是数据归档也就是备份。但是不具备crash-safe的能力。

redolog

1.为什么需要redolog
每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。
2.redolog是怎么发挥作用的
其实就是 MySQL 里经常说到的 WAL 技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘

当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log里面,并更新内存(数据),这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面(更新表数据到磁盘)。

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB。是循环写的,从头开始写,写到末尾又回到开头开始写。
redolog有缓存,事务执行时先把redolog写到redolog buffer,事务完成了再统一写到磁盘
3.redolog的crash-safe能力
有了redolog就能保证数据库异常重启的情况,之前已提交的记录都不会丢失。因为redolog记录的是未更新到磁盘的数据操作。
4.redolog的checkpoint什么情况下会推进
(1)有一个线程一致在做将redolog的操作更新到磁盘的表数据的操作
(2)redolog满了就需要停下来推进checkpoint [TODO]

好问题

1.redolog将数据记录更新到磁盘的过程,也就是推进checkpoint的过程
在系统不忙的时候,将数据从磁盘读取到内存(如果要刷盘的数据页不在内存),然后用redolog里的记录更新内存,然后写入到磁盘
2.为什么说MyISAM没有crash-safe的能力,binlog不能用来做崩溃恢复吗?
[TODO] 异常重启后,MyISAM是放着不管的,下次使用数据的时候提示“表损坏,需要恢复”,不能恢复的原因见第15篇
3.binlog逻辑日志和redolog物理日志有啥区别
[TODO] 见第15篇和23篇
4.commit后做了两个动作,把WAL文件持久化到磁盘,然后更新数据库(磁盘记录)。是否是完成WAL持久化到磁盘,然后才将更新数据库和索引的记录到磁盘?
是。并且更新的数据写到磁盘是后台操作。
5.为什么使用WAL能解决直接更新数据到磁盘IO成本高的问题?
使用WAL,事务commit直接写数据到磁盘比写日志的顺序IO成本高,WAL顺序IO性能高一些。
6.如果用binlog做断电恢复,没写log的不提交,回滚操作用undolog实现,redolog是否没必要存在
[TODO] undolog是依赖redolog来恢复的,没有redolog,undolog就不完整。见第3篇
7.2PC的过程如果binlog写完后Mysql故障重启了,binlog和redolog是否就不一致了,会导致用binlog恢复的数据库数据和当前数据库不同?
不会,这种情况重启后会提交事务。redolog记录里有事务id,如果在binlog里能找到对应的事务,redolog就提交
8.在一个大事物或长事物里,一边执行sql一边写redo log吗?未提交的事物也会写到redo log file吗?
会先写一块内存,叫做log_buffer里面,在提交的时候再一次性写到磁盘
9.innodb结构为内存池和后台线程 , 其中内存池里存在redo日志缓冲 和 缓冲池,其中缓冲池以页为单位缓冲磁盘数据 。
(1)更新语句时执行器调用innodb存储引擎先从内存读数据,指的就是从innodb缓存池中读取数据,没有的话就去读取磁盘找, 找到后再同步到缓冲池。
(2)Server层的查询缓存和innodb的缓冲池不是一个东西
10.备份也是有锁的,特别是myisam引擎
[TODO] 见第6篇
11.高并发地插入数据,有哪些情况下会导致数据库插入变慢。
(1)redolog和binlog会有影响
(2)[TODO] 锁的影响大一些
12.redolog和binlog是在内存中还是在磁盘中?如果在内存和在磁盘上都有怎么保证突然断电时的一致性?
[TODO] redolog有redolog buffer,binlog有binlog cache。保持数据可以看第15篇和第23篇
13.两阶段提交是原子性的吗?
不是。如果是原子性的就不用两阶段提交了。
14.如果更新语句涉及到索引,索引是什么时候被更新的,是否跟数据一样,都是先更新内存,再更新磁盘?
索引也是数据的一部分,是一样的策略
15.事务失败回滚是否也会写redolog和binlog,回滚涉及索引更细的话,如何更新索引?
会写redolog,打上回滚标签,binlog直接丢弃。[TODO] 回滚都是直接把没用的内存版本删除。
16.如果redolog写满,需要停下来将数据写入磁盘。这时候整个数据库处于阻塞状态吗?当有大量数据涌入,存在数据丢失的风险吗?
更新会被堵住。但是不算数据丢失,因为事务提交不了。数据丢失的定义是本该存在的数据没了,但是这时候并没有告知客户端事务成功,就不算丢失。
17.update是先写redolog,再把数据写内存,那么写入的这条数据在内存中的驻留时间是怎么处理的?是redo log写入磁盘后从内存中删除吗?
不会删除,除非内存不够用,不过在从内存删除之前会保证持久化到磁盘。这里说的应该是redolog buffer
数据在内存中的驻留时间涉及到innodb buffer pool的设计,不活跃的数据页可能被淘汰。
18.2PC的过程,如果redolog 处于prepared状态时数据库崩溃后恢复,存储引擎发现写了redolog,但是没写binlog,存储引擎会把事务回滚。
如果一个更新语句,写到存储引擎的redolog,而且状态是已提交,还没来得及同步到磁盘数据区。
这时,如果来一个查询,此条数据,是会查询出来的对吧。 那么这时候的查询流程是什么样子的,每次会先到redolog里查询下,有没有数据,因为redolog也是磁盘文件,这是效率会高吗?
这条数据大概率还在innodb的buffer pool,直接从内存返回。[TODO] 如果内存页已经被淘汰,执行的流程是什么样的?猜测是从磁盘读出来并更新内存,然后应用redolog到对应的记录。
19.2PC的过程,redolog处于prepared的状态时数据库故障重启了,数据是一致的吗
重启回来之后这个事务会回滚。binlog中没有这条记录的操作,用binlog恢复的数据和原数据库是一致的。
20.2PC的过程,binlog写入了,redolog未提交,此时我断开连接,这个事务应该是失败的。按照上面的说法,恢复的时候binlog这一条记录存在了,所以这条记录应该存在。这是mysql的bug?
此时你主动断开连接,这个事务就是“异常”,而不是“失败”。异常的事务,状态可能是提交,也可能是未提交,所以记录存在,是合理状态的一种
21.innodb_flush_log_at_trx_commit 和 sync_binlog 都设置成1,那么都是每个事务结束直接写磁盘,那是不是就浪费了WAL的作用,这样每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。
wal可以提升事务提交的性能,因为是顺序写。
22.2PC在redologprepared已经把redolog刷到磁盘了
23.异常重启过程redolog是怎么发挥作用的?
[TODO]
24.数据页指的是什么?
MySQL的记录是以“页”为单位存取的,默认大小16K。也就是说,你要访问磁盘中一个记录,不会只读这个记录,而会把它所在的16K数据一起读入内存
25.为什么binlog没有crash-safe的能力呢?不是写磁盘了吗?可以在重启后把宕机前的binlog中记录下来的事务sql语句执行一遍?
一开始没这么设计,实际上现在的binlog也不够,崩溃恢复需要日志和引擎内存状态配合的

你可能感兴趣的:(MySQL,sql,数据库)