03-MySQL-更新SQL是怎样执行的?

在数据库里面,update操作包括了更新、插入、删除操作

1 缓存冲  Buffer Pool

  首先,对于InnoDB 存储引擎来说,数据都是放在磁盘上的,存储引擎要操作数据必须先把磁盘里面的数据加载到内存里面才可以操作。
这里就有个问题,是不是我们需要的数据多大,我们就一次从磁盘加载多少数据到内存呢?比如我要读6个字节
  磁盘 I/0 的读写相对于内存的操作来说是很慢的。如果我们需要的数据分散在磁盘的不同的地方,那就意味着会产生很多次的 I/O 操作。
  所以,无论是操作系统也好,还是存储引擎也好,都有一个预读取的概念。也就是说,当磁盘上的一块数据被读取的时候,很有可能它附近的位置也会马上被读取到,这个就叫做局部性原理。那么这样,我们干脆每次多读取一点,而不是用多少读多少。InnoDB 设定了一个存储引擎从磁盘读取数据到内存的最小的单位,叫做页。操作系统也有页的概念。操作系统的页大小一般是 4K,而在InnoDB 里面,这个最小的单位默认是 16KB 大小。如果要修改这个值的大小,需要清空数据重新初始化服务。

我们要操作的数据就是在这样的页里面,数据所在的页叫数据页。

如果我们每次操作数据的时候,每次都要从磁盘读取到内存,在返回给server,这样的效率会很低,所以呢在Innodb中会有一个内存缓冲区,将最热的数据放在里面缓存起来;所以我们在读取数据的时候,会先判断这块内存区域中是否存在,如果是就直接读取,然后操作,不用再次从磁盘加载,如果不是,读取后就写到这个内存的缓冲区。

 修改数据的时候,也是先写入到buffer pool,而不是直接写到磁盘。这样就会导致内存的数据页和磁盘数据不一致的事后,这种就称之为脏页。那脏页什么时候才能同步到磁盘呢?
   Innodb里面有专门后台的线程把Buffer Pool的数据写入到磁盘,每隔一段时间就一次性地把多个修改写入磁盘,这个动作就叫做刷脏。
  Buffer Pool的作用是为了提高读写的效率

2  Redo log

        如果Buffer Pool里面的脏页还没有刷入磁盘时,数据库宕机或者重启,就会导致数据的丢失。为了解决这样的问题,所以内存的数据必须要有一个持久化的措施。
        为了避免这个问题,InnoDB 把所有对页面的修改操作专门写入一个日志文件。
        如果有未同步到磁盘的数据,数据库在启动的时候,会从这个日志文件进行恢复操作(实现 crash-safe)。我们说的事务的 ACID 里面 D(持久性),就是用它来实现的。

这个日志文件就是磁盘的redo log(叫做重做日志)。
       既然都是写数据,为什么不直接写入到db file里面去,为什么先写日志再写磁盘?
        写日志文件和写到数据文件有什么区别?
        写日志文件是一个顺序IO、写入到数据文件则是一个随机IO,磁盘寻址时间长。随机IO读取数据速度较慢,顺序IO当我们找到第一块数据,并且其他所需的数据就在这一块数据后边,那么就不需要重新寻址,可以依次拿到数据,读取数据速度较快。
        刷盘是随机 I/0,而记录日志是顺序1/0(连续写的),顺序I/0 效率更高,本质上是数据集中存储和分散存储的区别。因此先把修改写入日志文件,在保证了内存数据的安全性的情况下,可以延迟刷盘时机,进而提升系统吞吐。
redo log 位于/var/lib/mysql/目录下的ib logfile0 和 ib logfile1,默认 2 个文件每个 48M。

show variables like 'innodb_log%';
参数含义
innodb_log_file_size指定每个文件的大小,默认 48M
innodb_log_files_in_ group指定文件的数量,默认为2
innodb_log_group _home_dir指定文件所在路径,相对或绝对。如果不指定,则为datadir 路径。

这个 redo log 有什么特点?
1、redo log是InnoDB 存储引擎实现的,并不是所有存储引擎都有。支持崩溃恢复是 InnoDB 的一个特性。
2、redo log不是记录数据页更新之后的状态,而是记录的是“在某个数据页上做了什么修改”。属于物理日志
3、redolog 的大小是固定的,前面的内容会被覆盖,一旦写满,就会触发 buffer pool到磁盘的同步,以便腾出空间记录后面的修改。
除了 redo log 之外,还有一个跟修改有关的日志,叫做 undo log。redo log 和 undolog 与事务密切相关,统称为事务日志,

3 Undo log

        undo log(撤销日志或回滚日志)记录了事务发生之前的数据状态,分为insert undolog 和 update undo log。如果修改数据时出现异常,可以用 undo log 来实现回滚操作(保持原子性)。
        可以理解为 undo log 记录的是反向的操作,比如 insert 会记录 delete,update会记录 update 原来的值,跟 redolog 记录在哪个物理页面做了什么操作不同,所以叫做逻辑格式的日志。

show global variables like '%undo%';
参数含义
innodb_undo_directory

undo文件的路径

innodb_max_undo_log_size

如果innodb_undo_log_truncate设置为1,超过这个大小的时候会触发 truncate回收(收缩)动作,如果page大小是16KB, truncate后空间 缩小到10Mo默认1073741824字节二1G

innodb_logs

回滚段的数量,默认128,这个参数已经过时。

innodb_undo_log_truncate

设置为1,即开启在线回收(收缩;undo log 0志文件

innodb_undo_tablespaces

设置undo独立表空间个数,范围为0-95,默认为0,。表示表示不 开启独立undo表仝间 且undo日志存储在ibdata文件中。这个参数 已经

redo Logundo Log与事务密切相关,统称为事务日志。 

4 更新过程

有了这些日志之后,我们来总结一下一个更新操作的流程,这是一个简化的过程。 name 原值是 Hello
update user set name = 'Bonnie' where id=1;
1、    事务开始,从内存(buffer pool)或磁盘(data file)取到包含这条数据的数据
页,返回给Server的执行器;
2、    Server的执行器修改数据页的这一行数据的值为Bonnie;
3、    记录 name=Hello到undo log; (事务回滚)
4、    记录 name=Bonnie到redo log; (事务奔溃恢复)
5、    调用存储引擎接口,记录数据页到Buffer Pool (修改name=Bonnie);
6、    事务提交。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值