当前位置: 首页 > news >正文

vs网站开发教程中建材建设有限公司网站

vs网站开发教程,中建材建设有限公司网站,安装wifi需要多少钱,温州建设集团网站原文:https://jin-yang.github.io/post/mysql-group-commit.html组提交 (group commit) 是为了优化写日志时的刷磁盘问题#xff0c;从最初只支持 InnoDB redo log 组提交#xff0c;到 5.6 官方版本同时支持 redo log 和 binlog 组提交#xff0c;大大提高了 MySQL 的事务处…原文:https://jin-yang.github.io/post/mysql-group-commit.html组提交 (group commit) 是为了优化写日志时的刷磁盘问题从最初只支持 InnoDB redo log 组提交到 5.6 官方版本同时支持 redo log 和 binlog 组提交大大提高了 MySQL 的事务处理性能。下面将以 InnoDB 存储引擎为例详细介绍组提交在各个阶段的实现原理。简介自 5.1 之后binlog 和 innodb 采用类似两阶段提交的方式不过不支持 group commit在 5.6 中将 binlog 的 commit 阶段分为三个阶段flush stage、sync stage 以及 commit stage。这三个阶段中每个阶段都会去维护一个队列各个列表的定义如下。Mutex_queue m_queue[STAGE_COUNTER];如上每个阶段都在维护一个队列第一个进入该队列的作为 leader 线程否则作为 follower 线程leader 线程会收集 follower 的事务并负责做 syncfollower 线程等待 leader 通知操作完成。尽管维护了三个队列但队列中所有的 THD 实际上都是通过 next_to_commit 连接起来。binlog 在事务提交阶段也就是在 MYSQL_BIN_LOG::ordered_commit() 函数中开始 3 个阶段的流程。接下来看看 MySQL 中事务是如何提交的。事务提交接下来看看 InnoDB 和 binlog 提交的流程。二阶段提交详细介绍下二阶段提交的过程。未开启binlog时InnoDB 通过 redo 和 undo 日志来恢复数据库 (safe crash recovery)当数据恢复时通过 redo 日志将所有已经在存储引擎内部提交的事务应用 redo log 恢复所有已经 prepared 但是没有 commit 的事务则会通过 undo log 做回滚。然后客户端连接时就能看到已经提交的数据存在数据库内未提交被回滚地数据需要重新执行。开启binlog时为了保证存储引擎和 MySQL 的 binlog 保持一致引入二阶段提交 (two phase commit, 2pc) 。因为备库通过 binlog 重放主库提交的事务假设主库存储引擎已经提交而 binlog 没有保持一致则会使备库数据丢失造成主备数据不一致。二阶段提交如下是二阶段提交流程。详细执行流程为InnoDB 的事务 Prepare 阶段即 SQL 已经成功执行并生成 redo 和 undo 的内存日志binlog 提交通过 write() 将 binlog 内存日志数据写入文件系统缓存fsync() 将 binlog 文件系统缓存日志数据永久写入磁盘InnoDB 内部提交commit 阶段在存储引擎内提交通过 innodb_flush_log_at_trx_commit 参数控制使 undo 和 redo 永久写入磁盘。开启 binlog 的 MySQL 在崩溃恢复 (crash recovery) 时在 prepare 阶段崩溃恢复时该事务未写入 binlog 且 InnoDB 未提交该事务直接回滚在 binlog 已经 fsync() 永久写入 binlog但 InnoDB 未来得及 commit 时崩溃恢复时将会从 binlog 中获取提交的信息重做该事务并提交使 InnoDB 和 binlog 始终保持一致。以上提到单个事务的二阶段提交过程能够保证 InnoDB 和 binlog 保持一致但是在并发的情况下怎么保证存储引擎和 binlog 提交的顺序一致当并发提交的时如果两者不一致会造成什么影响组提交异常首先看看对于上述的问题当并发提交的时如果两者不一致会造成什么影响如上所示事务按照 T1、T2、T3 顺序开始执行并依相同次序按照写入 binlog 日志文件系统缓存调用 fsync() 进行一次组提交将日志文件永久写入磁盘。但是存储引擎提交的顺序为 T2、T3、T1当 T2、T3 提交事务之后做了一个 On-line 的备份程序新建一个 slave 来做复制而搭建备库时CHANGE MASTER TO 的日志偏移量在 T3 事务之后。那么事务 T1 在备机恢复 MySQL 数据库时发现 T1 未在存储引擎内提交那么在恢复时T1 事务就会被回滚此时就会导致主备数据不一致。结论需要保证 binlog 的写入顺序和 InnoDB 事务提交顺序一致用于 xtrabackup 备份恢复。早期解决方案早期使用 prepare_commit_mutex 保证顺序只有当上一个事务 commit 后释放锁下个事务才可以进行 prepara 操作并且在每个事务过程中 binlog 没有 fsync() 的调用。由于内存数据写入磁盘的开销很大如果频繁 fsync() 把日志数据永久写入磁盘数据库的性能将会急剧下降。为此提供 sync_binlog 参数来设置多少个 binlog 日志产生的时候调用一次 fsync() 把二进制日志刷入磁盘来提高整体性能该参数的设置作用为sync_binlog0二进制日志 fsync() 的操作基于系统自动执行。sync_binlog1每次事务提交都会调用 fsync()最大限度保证数据安全但影响性能。sync_binlogN当数据库崩溃时可能会丢失 N-1 个事务。prepare_commit_mutex 的锁机制会严重影响高并发时的性能而且 binlog 也无法执行组提交。改进方案接下来看看如何保证 binlog 写入顺序和存储引擎提交顺序是一致的并且能够进行 binlog 的组提交5.6 引入了组提交并将提交过程分成 Flush stage、Sync stage、Commit stage 三个阶段。这样事务提交时分为了如下的阶段InnoDB, PrepareSQL已经成功执行并生成了相应的redo和undo内存日志Binlog, Flush Stage所有已经注册线程都将写入binlog缓存Binlog, Sync Stagebinlog缓存将sync到磁盘sync_binlog1时该队列中所有事务的binlog将永久写入磁盘InnoDB, Commit stageleader根据顺序调用存储引擎提交事务每个 Stage 阶段都有各自的队列从而使每个会话的事务进行排队提高并发性能。如果当一个线程注册到一个空队列时该线程就做为该队列的 leader后注册到该队列的线程均为 follower后续的操作都由 leader 控制队列中 follower 行为。leader 同时会带领当前队列的所有 follower 到下一个 stage 去执行当遇到下一个 stage 为非空队列时leader 会变成 follower 注册到此队列中注意follower 线程绝不可能变成 leader 。配置参数与 binlog 组提交相关的参数主要包括了如下两个参数。binlog_max_flush_queue_time单位为微妙用于从 flush 队列中取事务的超时时间这主要是防止并发事务过高导致某些事务的 RT 上升详细的内容可以查看函数 MYSQL_BIN_LOG::process_flush_stage_queue() 。注意该参数在 5.7 之后已经取消了。binlog_order_commits当设置为 0 时事务可能以和 binlog 不同的顺序提交其性能会有稍微提升但并不是特别明显.源码解析binlog 的组提交是通过 Stage_manager 管理其中比较核心内容如下。class Stage_manager {public:enum StageID { // binlog的组提交包括了三个阶段FLUSH_STAGE,SYNC_STAGE,COMMIT_STAGE,STAGE_COUNTER};private:Mutex_queue m_queue[STAGE_COUNTER];};组提交 (Group Commit) 三阶段流程详细实现如下。MYSQL_BIN_LOG::ordered_commit() ← 执行事务顺序提交binlog group commit的主流程||-######### ← 进入Stage_manager::FLUSH_STAGE阶段|-change_stage(..., LOCK_log)| |-stage_manager.enroll_for() ← 将当前线程加入到m_queue[FLUSH_STAGE]中| || | ← (follower)返回true| |-mysql_mutex_lock() ← (leader)对LOCK_log加锁并返回false||-finish_commit() ← (follower)对于follower则直接返回| |-ha_commit_low()||-process_flush_stage_queue() ← (leader)对于follower则直接返回| |-fetch_queue_for() ← 通过stage_manager获取队列中的成员| | |-fetch_and_empty() ← 获取元素并清空队列| |-ha_flush_log()| |-flush_thread_caches() ← 对于每个线程做该操作| |-my_b_tell() ← 判断是否超过了max_bin_log_size如果是则切换binlog文件||-flush_cache_to_file() ← (follower)将I/O Cache中的内容写到文件中|-RUN_HOOK() ← 调用HOOK函数也就是binlog_storage-after_flush()||-######### ← 进入Stage_manager::SYNC_STAGE阶段|-change_stage()|-sync_binlog_file()| |-mysql_file_sync()| |-my_sync()| |-fdatasync() ← 调用系统API写入磁盘也可以是fsync()||-######### ← 进入Stage_manager::COMMIT_STAGE阶段|-change_stage() ← 该阶段会受到binlog_order_commits参数限制|-process_commit_stage_queue() ← 会遍厉所有线程然后调用如下存储引擎接口| |-ha_commit_low()| |-ht-commit() ← 调用存储引擎handlerton-commit()| | ← ### 注意实际调用如下的两个函数| |-binlog_commit()| |-innobase_commit()|-process_after_commit_stage_queue() ← 提交之后的后续处理例如semisync| |-RUN_HOOK() ← 调用transaction-after_commit||-stage_manager.signal_done() ← 通知其它线程事务已经提交||-finish_commit()在 enroll_for() 函数中刚添加的线程如果是队列的第一个线程就将其设置为 leader 线程否则就是 follower 线程此时线程会睡眠直到被 leader 唤醒 (m_cond_done) 。注意binlog_max_flush_queue_time 参数已经取消。commit stage如上所述commit 阶段会受到参数 binlog_order_commits 的影响当该参数关闭时会直接释放 LOCK_sync 各个 session 自行进入 InnoDB commit 阶段这样不会保证 binlog 和事务 commit 的顺序一致。当然如果你不关注两者的一致性那么可以关闭这个选项来稍微提高点性能当打开了上述的参数才会进入 commit stage 。
http://www.sadfv.cn/news/299106/

相关文章:

  • 大气宽屏网站模板企业源码带后台石家庄正定网站建设
  • 电子商务网站建设与维护题库wordpress时间中文版
  • 百度推广手机网站做网站的公司现在还 赚钱吗
  • 网站版面布局结构图宝山专业做网站
  • 天通苑网站建设1 分析seo做的不好的网站
  • 在线代理浏览器网站营销与策划
  • 做网站的图片房产网站建设的类型
  • 新开传奇网站超变wordpress的文章调用
  • 盐山建网站wordpress 宕机原因
  • 烟台做网站电话自己怎么创建小程序
  • 乐昌门户网站新开传奇手游
  • 大网络公司做网站企业为什么要建设电子商务网站
  • 平台建设网站郑州市城乡建设规划网站
  • 宁波网站优化软件乔拓云微信小程序官网
  • 舟山网站网站建设后台网站开发文档
  • 地方网站程序wordpress页面模板怎么做
  • 做金融必看网站网站开发项目流程设计
  • 现在市面网站做推广好旅游网页设计模板图及代码
  • 明年做哪个网站致富wordpress如何制作网页
  • 网站建设知识论文简历设计网官网
  • 低面效果在哪个网站做建立公司网站多少钱
  • 蓝色系网站优化wordpress访问速度
  • 直播网站建设模板网页设计提升班
  • 做网站费用需要分摊吗舞蹈培训东莞网站建设
  • 芙蓉区营销型网站建设定制优秀网页设计网站
  • 网站建设话术开场白网站排名怎么弄
  • 网站建设不用虚拟主机夜狼seo
  • wordpress 股票主题搜索引擎优化的核心及内容
  • 杭州网站建设公司联系方式php怎么做搭建网站
  • 网站制作教程手机如何在各个购物网站之间做差价