diff --git a/mysql/mysql文档/mysql_事务.md b/mysql/mysql文档/mysql_事务.md index 8b86978..f690bcd 100644 --- a/mysql/mysql文档/mysql_事务.md +++ b/mysql/mysql文档/mysql_事务.md @@ -636,7 +636,13 @@ binlog机制mysql上层的,和存储引擎无关,而redo log机制是和存 在slave机器上发生recovery时,如果binlog存在空洞,slave将会直接跳过空洞,从而导致slave中事务缺失。 +为了解决该问题,innodb补充了`prepare_commit_mutex`,当对事务进行prepare时,该mutex将会被获取;并且在事务commit时被释放。故而,在多事务场景下,一个事务`prepare-write-flush-commit`流程中不会插入其他操作,binlog写入事务的顺序和innodb存储引擎中事务提交的顺序是一致的。 + +> `prepare_commit_mutex`会将执行`prepare-write-commit`操作的事务串行化,由于将binlog写入到文件比较耗时,故而引入prepare_commit_mutext会造成bin log写入较慢。 + ##### binary log group commit +为了在`保证事务写binlog顺序和innodb存储引擎提交顺序一致`的基础上提高性能,故而不应采用`prepare_commit_mutex`,而是采用了如下设计。 + `binary log group commit`实现将commit过程拆分为了如下图所示的多个阶段: @@ -651,7 +657,7 @@ leader可能会注册到一个非空queue中,即leader可以决定成为一个 当leader进入到stage后,会一次性将queue抓取并依次处理queue中排队的session。当queue被抓取后,当leader在处理old queue时,其余的session又可以被注册到stage。 -- `Flush Stage`: 在flush stage,所有注册到queue的session都会将其cache写入到binlog中。 +- `Flush Stage`: 在flush stage,所有注册到queue的session都会将其cache写入到binlog中。`(实际将内容刷新到系统缓冲区中,但并不实际调用fsync,fsync的调用发生在sync stage)` - `sync stage`:在sync stage,会根据`sync_binlog`的设置将binary log同步到磁盘中。如果`sync_binlog`值为1,所有被flushed的session都会被同步到磁盘中 - `commit stage`:在commit stage,所有session将会按照其register的顺序在engine中进行提交,该步骤由stage leader完成。由于在commit procedure中,每个stage都保留了顺序,那么binlog中写入事务的顺序和引擎中事务的提交顺序是一致的。 @@ -659,3 +665,9 @@ leader可能会注册到一个非空queue中,即leader可以决定成为一个 由于leader注册到下一个stage时可能变为follower,最慢的stage可能会积累最多的工作。通常情况下,sync stage会积累最多的工作。但是,向flush阶段填充尽可能多的事务是至关重要的,flush stage会被单独处理。 +在flush stage,leader将会逐个扫描flush queue中的sessions,扫描过程在满足下列任一条件时终止: +- 当queue为空时,leader将会立即进入下一阶段,并且将所有sessions注册到sync stage中 +- 如果`从第一个任务被unqueue起`已经超过时长限制`binlog_max_flush_queue_time`,那么整个queue都会被抓取,并且sessions的transaction cache都会被flushed(处理流程和未超时场景下一致)。之后leader再回进入到下一阶段。 + +> 通过将sessions在stage queue进行排队,在write、sync、commit多个阶段都能进行group处理。这样能够提高多事务场景下的事务提交性能,通过binary log group commit也能大大减少fsync的磁盘写入次数。 +