营销型网站建设公司哪里有做农村网站多少钱
2026/5/19 19:11:22 网站建设 项目流程
营销型网站建设公司哪里有,做农村网站多少钱,全国备案查询系统,报个计算机培训班多少钱MySQL的InnoDB引擎下更新操作时事务的执行过程 MySQL数据库在InnoDB中一次update的操作过程基本如下#xff1a;首先将数据加载到Buffer Pool里#xff1a;当InnoDB需要更新一条记录时#xff0c;首先会在Buffer Pool中查找该记录是否在内存中。若没在内存中#xff0c;则从…MySQL的InnoDB引擎下更新操作时事务的执行过程MySQL数据库在InnoDB中一次update的操作过程基本如下首先将数据加载到Buffer Pool里当InnoDB需要更新一条记录时首先会在Buffer Pool中查找该记录是否在内存中。若没在内存中则从磁盘读取该页到Buffer Pool中。记录UndoLog:在修改操作前InnoDB会在Undo Log中记录修改前的数据。Undo Log是用来保证事务原子性和一致性的一种机制用于在发生事务回滚等情况时将修改操作回滚到修改前的状态以达到事务的原子性和一致性。Undo Log 首先写入内存中的 Undo 缓冲区随后由后台线程定期刷盘无需等待事务提交。。在Buffer Pool中更新数据:当执行update语句时InnoDB会先更新已经读取到Buffer Pool中的数据而不是直接写入磁盘。同时InnoDB会将修改后的数据页状态设置为脏页DirtyPage状态表示该页已经被修改但尚未写入磁盘。记录RedoLog Buffer:InnoDB在Buffer Pool中记录修改操作的同时InnoDB会先将修改操作写入到Redo Log Buffer 中。提交事务:在执行完所有修改操作后事务被提交。在提交事务时InnoDB会将Redo Log写入磁盘以保证事务持久性commit 时会保证 writefsync但 log buffer 中的内容可能在 prepare 阶段就已被后台线程提前刷盘。写入磁盘:在提交后InnoDB会将Buffer Pool中的脏页写入磁盘以保证数据的持久性。但是这个写入过程并不是立即执行的是有一个后台线程异步执行的所以可能会延迟写入总之MySQL会选择合适的时机把数据写入磁盘做持久化。记录Binlog:在提交过程中MySQL Server层将事务提交的信息记录到Binlog中。Binlog是MySQL用来实现主从复制的一种机制用于将主库上的事务同步到从库上。在Binlog中记录的信息包括:事务开始的时间、数据库名、表名、事务ID、SQL语句等。什么是脏读、幻读、不可重复读在整个事务的执行过程中当出现并发、以及兼顾性能等情况会出现一系列的问题但是针对不同的情况MySQL 也给出了针对性方案。下面就针对脏读、幻读、不可重复读三种异常情况来说明一下。脏读脏读是指读到了其他事务还没提交的数据。脏读产生的过程是当一个事务正在访问数据并且对数据进行了修改而这种修改还没有提交(commit)到数据库中这时另外一个事务也访问这个数据然后使用了这个数据。因为这个数据是还没有提交的数据那么另外一个事务读到的这个数据是脏数据依据脏数据所做的操作可能是不正确的。不可重复读不可重复读是指在对某数据进行读取过程中有其他事务对数据进行了修改(UPDATE、DELETE)导致第二次读取的结果不同。不可重复读的发生过程在数据库访问中一个事务范围内两个相同的查询却返回了不同数据。这是由于查询时系统中其他事务修改的提交而引起的。比如事务T1读取某一数据事务T2读取并修改了该数据T1为了对读取值进行检验而再次读取该数据便得到了不同的结果。幻读幻读是指事务在做范围查询过程中有另外一个事务对范围内新增了记录(INSERT)导致范围查询的结果条数不一致。幻读也常被看作不可重复读在‘范围查询’场景下的特殊表现例如第一个事务对一个表中的数据进行了修改比如这种修改涉及到表中符合条件的的“全部数据行”。同时第二个事务也修改这个表中的数据这种修改是向表中插入一行新数据。那么以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行就好象发生了幻觉一样。MySQL中的事务隔离级别脏读、幻读、不可重复读这三种异常情况产生的主要原因还是由于数据库支持多个事务同时执行时互相操作相同的数据。那么事务之间能看到哪些数据呢这就是由数据库的事务隔离级别来决定的。事务隔离级别主要用于定义事务处理过程中不同事务之间可见性和相互影响程度的一套标准。业内标准SQL-92也叫 SQL2是 ANSI/ISO 在 1992 年发布的第二版 SQL 标准它对 1986 年的 SQL-86 做了大幅扩充奠定了今天主流关系数据库Oracle、DB2、SQL Server、PostgreSQL、MySQL 等所支持的核心功能。SQL-92定义了4种隔离级别来解决脏读、幻读、不可重复读等这些异常情况从高到底依次为:可串行化(Serializable)、可重复读(Repeatable reads)、读已提交(Read committed)、读未提交(Read uncommitted)。读未提交(Read uncommitted)最低级的隔离级别就是说这种隔离级别下一个事务可以读取到另一个事务未提交的数据。这种事务隔离级别下会产生脏读、幻读、不可重复读。读已提交(Read committed)这种的事务隔离级别下一个事务如果在修改数据还未提交事务其他事务是不能够读取该数据的。因此这种事务隔离级别可以防止脏读。可重复读(Repeatable reads)这种事务隔离级别下比读已提交更严谨不但可以防止脏读还能够防止不可重复读但是没办法彻底解决幻读问题。可串行化(Serializable)这种事务隔离级别下所有的事务都是按照顺序串行执行但是事务并发执行速度也是最慢的。此隔离级别可以防止脏读、幻读、不可重复读。以上是SQL-92标准中对事务隔离级别的定义但是不同的数据库在实际实现的过程中是有一些细微差异的。MySQL的InnoDB引擎是如何解决脏读、幻读、不可重复读解决脏读脏读是在一个事务中读取到了另一个事务中未提交的数据在【读已提交】隔离级别下事务只能读取到其他事务已经提交的数据版本。这就是靠MVCC多版本并发控制来实现的。InnoDB下系统会检查每个数据行的版本只有当该版本是由已提交事务修改的才对当前事务可见。当事务在【读已提交】隔离级别下执行读取操作时InnoDB获取当前最新的全局事务ID这个ID表示在当前时刻所有已提交事务的最新状态。InnoDB会检查每个数据行的版本如果该版本是由一个小于或等于当前事务ID的事务修改的并且该事务已提交则这个版本是可见的。这保证了事务只能看到在它开始之前已经提交的数据版本。实现原理通过行的隐藏字段如DB_TRX_ID事务ID和ReadView来判断数据版本的可见性。DB_TRX_ID6字节是全局事务ID记录最后修改该行的事务ID。DB_ROLL_PTR7字节回滚指针指向undo log中的历史版本DB_ROW_ID6字节行ID当表没有主键时使用ReadViewReadView是 InnoDB 用来实现MVCC多版本并发控制的核心数据结构它相当于事务在执行 快照读普通 SELECT 时生成的一张“瞬时照片”记录了当前系统中所有活跃事务已开启但未提交的 ID 列表从而决定当前事务能看到哪些版本的数据。ReadView的结构/* by 01022.hk - online tools website : 01022.hk/zh/huoxingwen.html */ struct read_view_t{ trx_id_t low_limit_id; /*! 大于等于此ID的事务不可见 */ trx_id_t up_limit_id; /*! 小于此ID的事务可见 */ trx_id_t* trx_ids; /*! 创建时的活跃事务ID列表 */ trx_id_t creator_trx_id; /*! 创建该ReadView的事务ID */ };例如/* by 01022.hk - online tools website : 01022.hk/zh/huoxingwen.html */ trx_ids [20,28,34,40); low_limit_id 40; up_limit_id 20; creator_trx_id 38上面这种情况下trx_id 20说明改trx_id的事务在这个ReadView生成前已提交那么该事务的结果是可见的trx_id 20 trx_id 40说明该trx_id的事务在这个ReadView生成时是活跃状态那么这个记录对于当前事务创建ReadView的事务来说不可见。trx_id ≥ 41未来事务对于创建ReadView的事务来说不可见。不同隔离级别下ReadView 的行为隔离级别ReadView 创建时机是否复用READ UNCOMMITTED读未提交不创建 ReadView直接读最新版本-READ COMMITTED读已提交每次执行 SELECT 时都创建一个新的 ReadView不复用REPEATABLE READ可重复读事务中第一次 SELECT时创建 ReadView之后整个事务复用复用SERIALIZABLE串行化退化为加锁机制不依赖 MVCC-解决不可重复读不可重复读在同一事务中多次读取同一数据返回的结果不同。解决方案InnoDB主要是通过MVCC和ReadView机制解决不可重复读问题。核心实现在【可重复读】REPEATABLE READ这种事务隔离级别下当使用快照读读取数据时只会在第一次读取的时候生成一个ReadView后续事务中所有快照读都用同一个快照这样就不会发生不可重复读的问题了。即使其他事务修改了数据并提交当前事务仍然看到原来的版本。解决幻读幻读在事务的范围查询中多次查询出来的数量不一致。解决方案InnoDB的RR隔离级别可重复读通过MVCC 间隙锁Next-Key Lock的组合机制解决幻读问题。这种方式只是在一定程度上解决了幻读但是并没有完全避免当一个事务中对同一段范围查询既有快照读又有当前读时可能出现“先快照、后当前”导致的幻读需要业务层注意。分场景来说明是如何解决幻读的快照读场景MVCC机制普通SELECT语句使用快照读基于ReadView机制可以避免幻读实现原理事务只能看到ReadView创建之前存在的数据新插入的数据对当前事务不可见。当前读场景Next-Key Lock机制对于SELECT ... FOR UPDATE、UPDATE、DELETE等当前读操作技术细节不仅锁定读取到的记录还会锁定记录之间的间隙Gap Lock防止其他事务在查询范围内插入新数据。通过锁定索引记录和记录之间的间隙来避免幻读。总结MySQL InnoDB 的 UPDATE 语句看似一条简单命令背后却要走完“加载→写 Undo→改内存→写 Redo→两阶段提交→Binlog→异步刷脏”整条链路其中 Redo 保证崩溃恢复Binlog 保证主从复制Undo 提供回滚与 MVCC 多版本。SQL-92 的 4 种隔离级别在 InnoDB 里被细化为 MVCC 锁的混合方案READ UNCOMMITTED 直接读最新版可能脏读READ COMMITTED 每次新建 ReadView解决脏读REPEATABLE READ 复用首次 ReadView解决不可重复读并用 Next-Key Lock 在当前读场景下堵住幻读SERIALIZABLE 退化为纯加锁彻底串行。理解这套“日志先行、MVCC 多版本、锁补边界”的设计才能在业务开发中正确选择隔离级别、合理使用当前读与索引避免“锁等待”或“幻读”带来的意外结果。作者纪莫欢迎任何形式的转载但请务必注明出处。限于本人水平如果文章和代码有表述不当之处还请不吝赐教。欢迎扫描二维码关注公众号Jimoer文章会同步到公众号上面大家一起成长共同提升技术能力。声援博主如果您觉得文章对您有帮助可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询