iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >MySQL 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些
  • 548
分享到

MySQL 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些

2024-04-02 19:04:59 548人浏览 薄情痞子
摘要

这篇文章给大家分享的是有关Mysql 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来

这篇文章给大家分享的是有关Mysql 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。

以下讨论sync_binlog参数在5.7中的作用


一、sync_binlog参数设置在源码中的表示


这个参数大家都知道控制着binlog的刷盘时机,但是在5.7中其还有另外一个功能,我这里将解释他的两个功能。我摘取了源码中说明问题的部分进行展示如下:


flush阶段:
flush_error= process_flush_stage_queue(&total_bytes, &do_rotate,&wait_queue);//进行binlog的从binlog buffer或者临时文件写入到binlog文件(注意是写到kernel buffer还没做fsync),同时触发innodb的组提交逻辑,innodb组提交的逻辑代码是阿里的印风兄写的,我请教过他。
update_binlog_end_pos_after_sync= (get_sync_period() == 1);//sync_binlog参数 如果为1则为真如果不为1则为假
    if (!update_binlog_end_pos_after_sync)//如果sync_binlog=1则 这里不发信号给dump 如果不是1则发信号进行dump
      update_binlog_end_pos();
其中get_sync_period()函数返回就是sync_binlog的设置,这里能够清晰看到如果sync_binlog != 1才会 在flush阶段发送信号给dump线程


sync阶段
if (flush_error == 0 && total_bytes > 0) //这里进行sync binlog,
  {
    DEBUG_SYNC(thd, "before_sync_binlog_file");
    std::pair<bool, bool> result= sync_binlog_file(false);
    sync_error= result.first;
  }


  if (update_binlog_end_pos_after_sync) //如果sync_binlog = 1 这里才发送信号给dump线程通知进行发送binlog
  {
    THD *tmp_thd= final_queue;


    while (tmp_thd->next_to_commit != NULL)
      tmp_thd= tmp_thd->next_to_commit;
    if (flush_error == 0 && sync_error == 0)
      update_binlog_end_pos(tmp_thd->get_trans_pos());
  }
如果我们翻开sync_binlog_file函数的逻辑会发现这样一个逻辑:


if (force || (sync_period && ++sync_counter >= sync_period))
  {
    sync_counter= 0;
很显然这里有一个计数器sync_counter,如果当sync_binlog>1的时候才,等到sync_counter大于你设置的sync_binlog的值的时候才会触发fsync binlog(注意这里是++sync_counter 先自增再比较),这里也解释了sync_binlog>1的时候代表的是什么值,代表是组提交的次数。


二、sync_binlog参数在5.7中作用的总结


sync_binlog=0:binlog不FSYNC刷盘,依赖于OS刷盘机制,同时dump线程会在flush阶段后进行binlog传输
sync_binlog=1:binlog进行FSYNC刷盘,同时dump线程会在sync阶段后进行binlog传输
sync_binlog>1:binlog将在指定次数组提交后FSYNC刷盘,同时dump线程会在flush阶段后进行binlog传输
三、为什么这么修改


这也是一个朋友问我的问题,如果主库异常重启后,从库是否有比主库多事物的风险,实际上这个问题就是到底在什么阶段后dump线程进行传输binlog的问题。实际上如果在flush阶段过后传输确实可能出现这个问题,而在sync阶段后传输这个时候binlog已经落盘了,就不会有这种风险了。如果出现这种错误会报错如下,这个错误也是有朋友遇到过的:


ER_SLAVE_HAS_MORE_GTIDS_THAN_MASTER 
"Slave has more GTIDs than the master has, using the master's SERVER_UUID. This may indicate that the end of the binary log was truncated or that the last binary log file was lost, e.g., after a power or disk failure when sync_binlog != 1. The master may or may not have rolled back transactions that were already replicated to the slave. Suggest to replicate any transactions that master has rolled back from slave to master, and/or commit empty transactions on master to account for transactions that have been committed on master but are not included in GTID_EXECUTED." 
下面开始讨论半同步中after_commit和after_sync的区别,这个问题一直也是大家讨论的重点。


四、从一个问题出发讨论


也是有很多朋友问我,其中一个问题如下:


半同步:after_sync模式
测试:超时时间设置为1个小时不让主库切换异步,同时停掉slave的I/O线程,
主库:
session1:插入一条数据hang住
session2:插入一条数据hang住
session3:插入一条数据hang住
其中session1状态为等待ACK,其他session状态为query end
问为什么其他session状态不是等待ACK而是query end。如果是after_commit模式则全部是等待ACK状态


实际上拿到这位朋友的pstack后大概就能确认大概是什么问题如下:


等待ACK线程:
Thread 7 (Thread 0x7f44607aa700 (LWP 24897)):
#0  0x00007f4475b02a5e in pthread_cond_timedwait@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#1  0x00007f44603e35d3 in ReplSemiSyncMaster::commitTrx(char const*, unsigned long long) () from /usr/local/mysql/lib/plugin/semisync_master.so
#2  0x0000000000c8197a in Binlog_storage_delegate::after_sync(THD*, char const*, unsigned long long) ()
#3  0x0000000000edd46b in call_after_sync_hook(THD*) ()
#4  0x0000000000eed935 in MYsql_BIN_LOG::ordered_commit(THD*, bool, bool) ()
#5  0x0000000000eedf55 in MYSQL_BIN_LOG::commit(THD*, bool) ()
#6  0x000000000081e494 in ha_commit_trans(THD*, bool, bool) ()
#7  0x0000000000dce032 in trans_commit_stmt(THD*) ()
#8  0x0000000000d134e7 in mysql_execute_command(THD*, bool) ()
等待LOCK_commit mutex线程
Thread 6 (Thread 0x7f4460769700 (LWP 25017)):
#0  0x00007f4475b05334 in __lll_lock_wait () from /lib64/libpthread.so.0
#1  0x00007f4475b0060e in _L_lock_995 () from /lib64/libpthread.so.0
#2  0x00007f4475b00576 in pthread_mutex_lock () from /lib64/libpthread.so.0
#3  0x0000000000eed31f in MYSQL_BIN_LOG::change_stage(THD*, Stage_manager::StageID, THD*, st_mysql_mutex*, st_mysql_mutex*) ()
#4  0x0000000000eed5e8 in MYSQL_BIN_LOG::ordered_commit(THD*, bool, bool) ()
#5  0x0000000000eedf55 in MYSQL_BIN_LOG::commit(THD*, bool) ()
#6  0x000000000081e494 in ha_commit_trans(THD*, bool, bool) ()
#7  0x0000000000dce032 in trans_commit_stmt(THD*) ()
这里就很明显其他提交事物(这里指的是 Thread 6)堵塞在了MYSQL_BIN_LOG::change_stage函数上,其作用正是获取某个阶段的Mutex。而本线程(这里指的是 Thread 7)则是在ReplSemiSyncMaster::commitTrx上堵塞在某个Mutex上。


五、after_commit和after_sync的代码位置和区别


这里直接用代码说明进行给出,当然我只是提取了说明问题的代码片段:


commit阶段:
1、 change_stage(thd, Stage_manager::COMMIT_STAGE,final_queue, leave_mutex_before_commit_stage,&LOCK_commit))//持有LOCK_commit mutext进入commit阶段
2、 sync_error= call_after_sync_hook(commit_queue);//这里调用after sync hook 其在LOCK_commit保护下 此时还没有做引擎层commit
3、 process_commit_stage_queue(thd, commit_queue);//进行引擎层提交操作,具体细节以后在研究
4、 mysql_mutex_unlock(&LOCK_commit);//这里提交完成解队列
5、 stage_manager.signal_done(final_queue); //这里唤醒全部本组堵塞在 flush阶段的follower线程 分别做提交 但是如果是order commit 提交已经做完 这里什么都不需要做了
6、 (void) finish_commit(thd); //finish_commit会调用 atfer commit hook 其不在LOCK_commit保护下
如果抛开代码总结如下:


1、leader 持有LOCK_commit 锁 进入 commit阶段。
2、如果是设置after_sync,使用after sync 挂钩来确认ack 。
3、进行引擎层提交,完成后解锁LOCK_commit 锁。
4、唤醒所有 follwer线程。
5、如果设置是after_commit,使用after commit 挂钩来确认ack 。
这里我们可以清楚的看到,他们的区别,实际上正如其名字一样就是说到底在那个步骤进行日志传输完成的确认,是在实际引擎层提交之前还是之后,如果是在之前则在mutex LOCK_commit的保护下,如果是在之后则不需要持有LOCK_commit mutex,这也是为什么会出现上面那个堵塞案例的原因。在5.7中默认是after_sync设置为after_sync后显然更加安全,如果是after_commit极端情况下可能引擎层已经提交完成,事物对主库可见,但是从库还没有传输完成如果从库奔溃可能出现少事物的情况。

感谢各位的阅读!关于“MySQL 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,让大家可以学到更多知识,如果觉得文章不错,可以把它分享出去让更多的人看到吧!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些

本文链接: https://www.lsjlt.com/news/63103.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些
    这篇文章给大家分享的是有关MySQL 5.7中sync_binlog参数和半同步中after_commit和after_sync的区别有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来...
    99+
    2024-04-02
  • ajax同步和异步的区别有哪些
    这篇文章主要讲解了“ajax同步和异步的区别有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“ajax同步和异步的区别有哪些”吧! ...
    99+
    2024-04-02
  • java同步和异步的区别有哪些
    Java中同步(Synchronous)和异步(Asynchronous)的区别主要体现在程序的执行方式和处理结果上。1. 执行方式...
    99+
    2023-08-09
    java
  • mysql中:=和=有哪些区别
    这篇文章主要介绍了mysql中:=和=有哪些区别,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。:=和=的区别= 只有在set和update时...
    99+
    2024-04-02
  • word排版中全角和半角有哪些区别
    全角和半角是一种字符宽度的表示方式,主要在中文排版中使用。1. 宽度:全角字符占两个字符宽度,而半角字符只占一个字符宽度。2. 字符...
    99+
    2023-09-16
    Word
  • navicat数据传输和数据同步有哪些区别
    这篇文章将为大家详细讲解有关navicat数据传输和数据同步有哪些区别,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。我们使用Navicat管理MySQL数据库的时候,使用...
    99+
    2024-04-02
  • mysql中in和or的区别有哪些
    这篇文章主要讲解了“mysql中in和or的区别有哪些”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql中in和or的区别有哪些”吧! ...
    99+
    2024-04-02
  • mysql中clob和blob的区别有哪些
    本篇内容介绍了“mysql中clob和blob的区别有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • mysql中om.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver的区别有哪些
    这篇文章将为大家详细讲解有关mysql中om.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver的区别有哪些,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文...
    99+
    2024-04-02
  • mysql中before和after的区别有哪些
    这篇文章主要介绍了mysql中before和after的区别有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。触发器(trigger):监...
    99+
    2024-04-02
  • mysql中char和varchar的区别有哪些
    本篇内容主要讲解“mysql中char和varchar的区别有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“mysql中char和varchar的区别有哪些...
    99+
    2024-04-02
  • MySQL中REGEXP和LIKE的区别有哪些
    这篇文章主要介绍MySQL中REGEXP和LIKE的区别有哪些,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!MySQL中,REGEXP经常使用,用于某种模式去匹配某个字符串的一个方式,Like关键字我们也是经常使用,...
    99+
    2023-06-14
  • Mysql中myisam和innodb的区别有哪些
    这篇文章给大家分享的是有关Mysql中myisam和innodb的区别有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。 (1)5点不同 1. 存储结构 &nb...
    99+
    2024-04-02
  • mysql中or和and有哪些区别
    这篇文章将为大家详细讲解有关mysql中or和and有哪些区别,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。 区别:1、本身含义上有差异,or...
    99+
    2024-04-02
  • mysql中5.6和5.5有哪些区别
    本篇内容介绍了“mysql中5.6和5.5有哪些区别”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成! ...
    99+
    2024-04-02
  • mysql中blob和text有哪些区别
    本文小编为大家详细介绍“mysql中blob和text有哪些区别”,内容详细,步骤清晰,细节处理妥当,希望这篇“mysql中blob和text有哪些区别”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,...
    99+
    2024-04-02
  • mysql中redo log和binlog的区别有哪些
    这篇文章给大家分享的是有关mysql中redo log和binlog的区别有哪些的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。想跟大家聊聊关于 mysql 中的两个小的知识点:redo log 和 bi...
    99+
    2023-06-29
  • mysql中的delete,drop和truncate有哪些区别
    这篇文章主要讲解了“mysql中的delete,drop和truncate有哪些区别”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“mysql中的delete,drop和trunca...
    99+
    2023-07-02
  • MySQL中update set和and的区别有哪些
    这篇文章主要介绍了MySQL中update set和and的区别有哪些,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。问题描述最近接到一个奇怪的咨询,update 语...
    99+
    2023-06-14
  • MySQL 5.6中timestamp和datetime区别有哪些
    小编给大家分享一下MySQL 5.6中timestamp和datetime区别有哪些,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作