领先的免费Web技术教程,涵盖HTML到ASP.NET

网站首页 > 知识剖析 正文

一条sql语句的更新流程(sql语言中更新数据的语句)

nixiaole 2025-03-29 20:27:24 知识剖析 22 ℃

sql语句的更新流程图:

在MySQL中,不管采用什么执行引擎(Memory的除外),最终都是需要将数据保存到磁盘上的。当我们在操作数据的时候也需要将数据从磁盘中区出来,放在内存中进行操作。针对这种频繁的从磁盘中获取数据后,操作完在写入磁盘的操作。在大量业务中很容易出现性能问题效率也极低。为了解决这个问题,mysql 在Innodb中引入了buffer pool 缓存的概念。


1.先判断内存中是否有数据,有的话则直接去操作数据,没有的话再从磁盘中获取数据放到内存中。

2.对数据进行操作,直接操作buffer pool 中的数据,InnoDB会有一个后台线程专门的区进行刷盘的操作。

对于从磁盘中获取数据这个操作,我们知道磁盘的操作一般是要比内存操作慢很多的(特别是机械硬盘)。但是这个每次获取数据获取多少呢?一般内存的数据读取通常是以页为单位区读取,再操作系统中一页一般是4k的大小,每次最少可以读取4k的数据。由于我们mysql中的页的是16K,如果按照这种读取,会出现从内存中读取的数据不够一页的数据。这样显然页不行,所以我们在读取数据的时候一般是读取16k的数据加载到buffer pool中。

另外数据读取的时候还有一个重要原则是局部性原理,分为时间局部性和空间局部性。时间局部性指的是如果一个数据被访问过,那么在不久的将来它可能再次被访问(例如循环访问数组)。空间局部性指的是如果一个数据被访问过,那么其相邻的数据也可能被访问到。MySQL中的预读机制也是基于这种空间局部性区依次区读取磁盘上的数据。

数据何时刷盘:

buffer pool中的数据修改成功后,一般什么时候可以刷盘。这种刷盘怎么保证修改的数据成功刷盘到磁盘呢? 因为我们只想被修改了的数据能够成功刷盘即可,对于没有变更的数据没有必要进行刷新。如果刷盘失败了怎么办,总会有那么几个特殊的情况。

在innodb 中对于每次修改的数据,都会存储在一个redo Log 的日志中(事务日志)。他主要保证我们在内存修改成功了后,数据不会丢失的问题。当数据库宕机时,一旦数据没有被刷盘到磁盘中,再重启服务后会从redo log 中读取数据到内存,从而实现数据的回复,保证事务的持久性。

redo log的刷盘机制,innodb提供了一个可选参数配置
innodb_flush_log_at_trx_commit
控制事务提交时日志刷新的行为,有三种可能的取值

  1. innodb_flush_log_at_trx_commit = 1: 每次事务提交时,InnoDB 引擎都会将事务日志强制写入磁盘,以确保事务的持久性(即使数据库崩溃,事务也不会丢失)。
  2. innodb_flush_log_at_trx_commit = 0: 每次事务提交时,InnoDB 引擎将事务日志写入操作系统的缓冲区,而不是直接写入磁盘。这提高了性能,但在数据库崩溃时可能会导致最后一个事务丢失。
  3. innodb_flush_log_at_trx_commit = 2: 每次事务提交时,InnoDB 引擎将事务日志写入操作系统的缓冲区,并且每秒钟将事务日志刷新到磁盘一次。这个选项在性能和安全之间提供了一种折衷。

Tags:

最近发表
标签列表