MySQL 5.7 并行复制源码分析

目录

1. 基础数据结构

2. 处理逻辑

2.1 Prepare阶段存储本事务的last_commit

2.2 Commit第三阶段更新全局的m_max_committed_transaction

2.3 Flush阶段获取事务的sequence_number


1. 基础数据结构

添加全局的事务计数器产生事务timestamp和记录当前最大事务timestamp的clock。

每个BinLog文件对应一对,代码关系为:

class MYSQL_BIN_LOG: public TC_LOG

=>Transaction_dependency_tracker => Commit_order_trx_dependency_tracker

class MYSQL_BIN_LOG: public TC_LOG
{
  ...
  public:
  /* Committed transactions timestamp */
  Logical_clock max_committed_transaction;
  /* "Prepared" transactions timestamp */
  Logical_clock transaction_counter;
  ...
}
class  Logical_clock
{
private:
  int64 state;
  /*
    Offset is subtracted from the actual "absolute time" value at
    logging a replication event. That is the event holds logical
    timestamps in the "relative" format. They are meaningful only in
    the context of the current binlog.
    The member is updated (incremented) per binary log rotation.
  */
  int64 offset;
public:
  Logical_clock();
  int64 step();
  int64 set_if_greater(int64 new_val);
  int64 get_timestamp();
  int64 get_offset() { return offset; }
  /*
    Updates the offset.
    This operation is invoked when binlog rotates and at that time
    there can't any concurrent step() callers so no need to guard
    the assignement.
  */
  void update_offset(int64 new_offset)
  {
    DBUG_ASSERT(offset <= new_offset);

    offset= new_offset;
  }
};

state是一个自增的值,offset在每次二进制日志发生rotate时更新,记录发生rotate时的state值。其实state和offset记录的是全局的计数值,而存在二进制日志中的仅是当前文件的相对值。

 

对每个事务定义其lock interval,并记录到binlog中,在每个transaction中添加下面两个member。

class Transaction_ctx
{
  ...
  /*
    Store for the transaction's commit parent sequence_number.
    The value specifies this transaction dependency with a "parent"
    transaction.
    The member is assigned, when the transaction is about to commit
    in binlog to a value of the last committed transaction's sequence_number.
    This and last_committed as numbers are kept ever incremented
    regardless of binary logs being rotated or when transaction
    is logged in multiple pieces.
    However the logger to the binary log may convert them
    according to its specification.
  */
  int64 last_committed;
  /*
    The transaction's private logical timestamp assigned at the
    transaction prepare phase. The timestamp enumerates transactions
    in the binary log. The value is gained through incrementing (stepping) a
    global clock.
    Eventually the value is considered to increase max_committed_transaction
    system clock when the transaction has committed.
  */
  int64 sequence_number;
  ...
}

 

2. 处理逻辑

2.1 Prepare阶段存储本事务的last_commit

从BinLog对象中取出m_max_committed_transaction,存储到(Transaction_ctx)Trx_ctx的last_committed中。

static int binlog_prepare(handlerton *hton, THD *thd, bool all)
{
  DBUG_ENTER("binlog_prepare");
  if (!all)
  {
    thd->get_transaction()->store_commit_parent(mysql_bin_log.
      m_dependency_tracker.get_max_committed_timestamp());

  }

  DBUG_RETURN(all && is_loggable_xa_prepare(thd) ?
              mysql_bin_log.commit(thd, true) : 0);
}

 

2.2 Commit第三阶段更新全局的m_max_committed_transaction

    if (head->get_transaction()->sequence_number != SEQ_UNINIT)
    {
      mysql_mutex_lock(&LOCK_slave_trans_dep_tracker);
      m_dependency_tracker.update_max_committed(head);
      mysql_mutex_unlock(&LOCK_slave_trans_dep_tracker);
    }

------
void
Transaction_dependency_tracker::update_max_committed(THD *thd)
{
  Transaction_ctx *trn_ctx= thd->get_transaction();
  m_commit_order.update_max_committed(trn_ctx->sequence_number);
  /*
    sequence_number timestamp isn't needed anymore, so it's cleared off.
  */
  trn_ctx->sequence_number= SEQ_UNINIT;

  DBUG_ASSERT(trn_ctx->last_committed == SEQ_UNINIT ||
              thd->commit_error == THD::CE_FLUSH_ERROR);
}

 

2.3 Flush阶段获取事务的sequence_number

binlog_cache_data::flush(THD *thd, my_off_t *bytes_written, bool *wrote_xid)
{
    Transaction_ctx *trn_ctx= thd->get_transaction();
    trn_ctx->sequence_number= mysql_bin_log.m_dependency_tracker.step();

    mysql_bin_log.write_gtid(thd, this, &writer)
}

------

return m_transaction_counter.step();
return ++state;

 

https://www.jianshu.com/p/8c416f3f471b

https://www.cnblogs.com/xiaotengyi/p/5532191.html

https://blog.csdn.net/andong154564667/article/details/82117727

http://mysql.taobao.org/monthly/2017/12/03/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 5.7的主从复制配置步骤如下: 1. 在主库上重启MySQL服务并进入MySQL控制台。创建一个用于从库复制的用户,并为其授权。 ``` CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%'; ``` 2. 在主库上查看主库参数,记住File和Position对应的参数值,从库需要配置这些参数。 ``` show master status; ``` 3. 在从库上重启MySQL服务并进入MySQL控制台。配置主库参数,将master_log_file设置为主库的File值,将master_log_pos设置为主库的Position值。 ``` change master to master_host='192.168.1.15', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000003', master_log_pos=2336, master_connect_retry=30; ``` 4. 在从库上启动主从复制。 ``` start slave; ``` 5. 查看主从复制状态,确保Slave_IO_Running和Slave_SQL_Running都为Yes。 ``` show slave status \G; ``` 6. 若要修改MySQL配置文件,进入配置文件中的部分,插入或修改以下关键配置: ``` [mysqld] log-bin=mysql-bin server-id=1 ``` 请确保在配置主从复制之前,主库和从库之间可以正常通信,且主库的binlog模式已经开启。当主从复制配置成功后,从库会自动从主库同步数据。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* [MySQL 5.7 主从复制](https://blog.csdn.net/MrYang_Wei/article/details/129587645)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] - *3* [MySQL5.7主从复制](https://blog.csdn.net/qq_43681755/article/details/108365639)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT0_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值