• linkedu视频
  • 平面设计
  • 电脑入门
  • 操作系统
  • 办公应用
  • 电脑硬件
  • 动画设计
  • 3D设计
  • 网页设计
  • CAD设计
  • 影音处理
  • 数据库
  • 程序设计
  • 认证考试
  • 信息管理
  • 信息安全
菜单
linkedu.com
  • 网页制作
  • 数据库
  • 程序设计
  • 操作系统
  • CMS教程
  • 游戏攻略
  • 脚本语言
  • 平面设计
  • 软件教程
  • 网络安全
  • 电脑知识
  • 服务器
  • 视频教程
  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase
您的位置:首页 > 数据库 >Mysql > MySQL半同步--after_flush

MySQL半同步--after_flush

作者: 字体:[增加 减小] 来源:互联网 时间:2017-12-17

通过本文主要向大家介绍了mysql同步等相关知识,希望本文的分享对您有所帮助

简介

在主库semisync加载或初始化时,调用函数semi_sync_master_plugin_init,为transaction_delegate、binlog_storage_delegate、binlog_transmit_delegate增加observer,分别对应plugin的变量为trans_observer、storage_observer、transmit_observer。这三个observer定义了各自的函数接口。

代码分析

所有从server层向plugin的函数调用,都是通过函数指针来完成的,因此我们只需要搞清楚上述几个函数的调用逻辑:

 

static int semi_sync_master_plugin_init(void *p)
{

  if (repl_semisync.initObject())
    return 1;
  if (register_trans_observer(&trans_observer, p))
    return 1;
  if (register_binlog_storage_observer(&storage_observer, p))
    return 1;
  if (register_binlog_transmit_observer(&transmit_observer, p))
    return 1;
  return 0;
}
Binlog_storage_observer storage_observer = {
  sizeof(Binlog_storage_observer), // len

  repl_semi_report_binlog_update, // report_update,after_flush
};
/**
   Observe binlog logging storage
*/
typedef struct Binlog_storage_observer {
  uint32 len;

  /**
     This callback is called after binlog has been flushed

     This callback is called after cached events have been flushed to
     binary log file but not yet synced.

     @param param Observer common parameter
     @param log_file Binlog file name been updated
     @param log_pos Binlog position after update

     @retval 0 Sucess
     @retval 1 Failure
  */
  int (*after_flush)(Binlog_storage_param *param,
                     const char *log_file, my_off_t log_pos);
} Binlog_storage_observer;

阶段说明

 

该函数调用在第一个阶段,sync binlog之前,flush cache之后。对应的函数是repl_semi_report_binlog_update:

 

if (repl_semisync.getMasterEnabled()){
	error= repl_semisync.writeTranxInBinlog(log_file,log_pos);
}

在半同步开启的状态下,调用writeTranxInBinlog函数,更新flush最新的log_file和log_pos

 

 

mysql_mutex_lock(&LOCK_binlog_);
if (commit_file_name_inited_){
	int cmp = ActiveTranx::compare(log_file_name, log_file_pos,
                                   commit_file_name_, commit_file_pos_);
	if (cmp > 0){
      strncpy(commit_file_name_, log_file_name, FN_REFLEN-1);
      commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
      commit_file_pos_ = log_file_pos;
    }
}else{
	strncpy(commit_file_name_, log_file_name, FN_REFLEN-1);
	commit_file_name_[FN_REFLEN-1] = 0; /* make sure it ends properly */
	commit_file_pos_ = log_file_pos;
	commit_file_name_inited_ = true;
}
if (is_on()){
	if(active_tranxs_->insert_tranx_node(log_file_name, log_file_pos)){
		switch_off();
	}
}
mysql_mutex_unlock(&LOCK_binlog_);

说明

 

1、在LOCK_binlog_锁内执行该代码块
2、当没有可以看到的最大事务binlog时,将flush后的binlog名和位置保存到commit_file_name_和commit_file_pos_中,并将commit_file_name_inited_置成TRUE之后,再次进来时会flush后的binlog位置和文件名会和这个变量比较,保存最大的binlog名和位置。
3、is_on函数即半同步标志state_是TRUE时,即开启了半同步,会将flush的最大的binlog名和位置插入到活跃事务链表中。 active_tranxs_:用于管理所有正在等待从库相应的事务。事务在binlog中有个结束的位置,该结束位置以一个结构体TranxNode表示。当有多个事务在等待时,所有事务的TranxNode按照binlog中结束的位置的前后顺序排列,使用next_组织起来,形成一个链表保存在active_tranxs_中。

 

struct TranxNode {
  char             log_name_[FN_REFLEN];
  my_off_t         log_pos_;
  mysql_cond_t     cond;//该条件变量作为半同步判断
  int              n_waiters;
  struct TranxNode *next_;            /* the next node in the sorted list */
  struct TranxNode *hash_next_;    /* the next node during hash collision */
};

 

4、如果插入active_tranxs_链表失败,则需要调用switch_off函数将半同步关掉:

int ReplSemiSyncMaster::switch_off(){
	state_ = false;
	rpl_semi_sync_master_off_times++;
	wait_file_name_inited_   = false;
	reply_file_name_inited_  = false;
	active_tranxs_->signal_waiting_sessions_all();-->
	|--for (TranxNode* entry= trx_front_; entry; entry=entry->next_)
        |--  mysql_cond_broadcast(&entry->cond);
}

mysql_cond_broadcast(&entry->cond)广播该条件变量,让其他事务线程不在等待ACK了,直接进入异步流程走掉。
repl_semi_report_commit(after_commit)->commitTrx->mysql_cond_timedwait(&entry->cond, &LOCK_binlog_, &abstime);

 

5、总结:
这个桩主要用来处理每个事务的binlog位置。首先根据每个提交事务对应的结束位置,保存当前实例中已经flush的事务的最大binlog位置。然后通过一个HASH表,记录下当前实例中所有提交事务的结束位置,hash值是binlog文件名和pos组成,缓存这些信息的目的是发送binlog时判断要不要等待从库的ACK,至于发送事务的最后一个binlog时才要在发送的binlog中打标记,告诉从库这个event需要接受ACK。
 

分享到:QQ空间新浪微博腾讯微博微信百度贴吧QQ好友复制网址打印

您可能想查找下面的文章:

相关文章

  • 2018-12-05MSSQL 首字母替换成大写字母
  • 2018-12-05mysql中索引使用不当速度比没加索引还慢的测试
  • 2018-12-05MAC上Mysql忘记Root密码或权限错误的快速解决方案_MySQL
  • 2017-05-11MySQL Cluster如何创建磁盘表方法解读
  • 2018-12-05 一条SQL语句变得巨慢的原因及其解决方法
  • 2017-05-11Centos中安装多个mysql数据的配置实例
  • 2017-05-11Mysql中文乱码问题的最佳解决方法
  • 2018-12-05提高MySQL数据库的安全性(三)
  • 2018-12-05MySQL之-CentOS6.5_x64安装配置drbd8.4.2的示例代码
  • 2018-12-05SQL 研究 相似的数据类型

文章分类

  • MsSql
  • Mysql
  • oracle
  • MariaDB
  • DB2
  • SQLite
  • PostgreSQL
  • MongoDB
  • Redis
  • Access
  • 数据库其它
  • sybase
  • HBase

最近更新的内容

    • 将 Ghost 从 SQLite3 数据库迁移到 MySQL 数据库
    • MSSQL转MYSQL,gb2312转utf-8无乱码解决方法
    • 大幅优化MySQL查询性能的奇技淫巧
    • 解析SQL 表结构信息查询 含主外键、自增长
    • mysql导入数据大小设置方法
    • 通过mysqli扩展技术实现内存回收
    • Centos下Mysql安装图文教程_MySQL
    • MySQL 创建主键,外键和复合主键的语句
    • MySQL中group_concat函数深入理解
    • 忘记Mysql的root密码的处理办法

关于我们 - 联系我们 - 免责声明 - 网站地图

©2020-2025 All Rights Reserved. linkedu.com 版权所有