自己怎么创建免费网站,京东商城官网登录,wordpress万网,企业网站平台建设咨询合同需要对接的接口以及每个接口的实现
recovery 阶段
此阶段由 xa.cc 文件中的 xarecover_handlerton() 函数完成#xff0c;它通过三个接口实现与存储引擎的沟通#xff1a;recover()#xff0c;commit_by_xid() #xff0c;rollback_by_xid()。其流程如下#xff1a;
此…需要对接的接口以及每个接口的实现
recovery 阶段
此阶段由 xa.cc 文件中的 xarecover_handlerton() 函数完成它通过三个接口实现与存储引擎的沟通recover()commit_by_xid() rollback_by_xid()。其流程如下
此函数首先已经收集到了最后一个 binlog 文件中成功提交了的事物 xid将其放入一个 SET 中具体是不是从最后一个 binlog 文件收集的怎么收集的下层存储引擎不需要知道。调用recover()收集存储引擎中处于 prepared 阶段的事务对于其中的每一个事物的 xid 判断其是否存在于上述 SET 。如果 xid 存在于 SET 中则调用commit_by_xid()。否则则调用rollback_by_xid()。 **recover()** /** This function is used to recover X/Open XA distributed transactions.return number of prepared transactions stored in xid_list */
static int innobase_xa_recover(handlerton *hton, /*! in: InnoDB handlerton */XA_recover_txn *txn_list, /*! in/out: prepared transactions */uint len, /*! in: number of slots in xid_list */MEM_ROOT *mem_root); /*! in: memory for table names */// init
innobase_hton-recover innobase_xa_recover;返回值表示收集到的事务的数量
*txn_list 用于返回事务链。对于每一个处于prepare 状态的事务InnoDB 做如下工作
将其事务 xid 写入 txn_list将事务对应的 table 信息 push 入 txn_list
// xid
txn_list-id *trx-xid;
txn_list-mod_tables new (mem_root) Listst_handler_tablename();// tables
for (auto dd_table : trx-mod_tables) {st_handler_tablename *table new (mem_root) st_handler_tablename();if (!table || get_table_name_info(table, dd_table, mem_root) ||txn_list-mod_tables-push_back(table, mem_root))}len表示 txn_list 最长的长度InnoDB 中如果 prepared 阶段的事务数量达到了 len 个直接返回。
if (count len)break;**commit_by_xid()** /** This function is used to commit one X/Open XA distributed transaction which is in the prepared statereturn 0 or error number */
static xa_status_code innobase_commit_by_xid(handlerton *hton, /*! in: InnoDB handlerton */XID *xid); /*! in: X/Open XA transaction identification */innobase_hton-commit_by_xid innobase_commit_by_xid;这个接口由于底层实现原因可以不用参考 InnoDB 具体的操作只需要在引擎中完成以下操作即可
对该 xid 对应的事务完成恢复。补充该事务的 commit_record。 **commit_by_xid()** /** This function is used to rollback one X/Open XA distributed transactionwhich is in the prepared statereturn 0 or error number */
static xa_status_code innobase_rollback_by_xid(handlerton *hton, /*! in: InnoDB handlerton */XID *xid); /*! in: X/Open XA transaction identification */innobase_hton-rollback_by_xid innobase_rollback_by_xid;
直接抛弃 xid 对应的事务不做恢复。
甚至可以不用实现该接口在恢复完成后抛弃没有恢复的事务就行。
XID 的设计有点坑
用于恢复的 xid 本身只是一个 uint64 类型但 mysql 设计的 xid_t 类型占用了 152 byte 。真正的 xid 被存进了 data 字符数组中。
按道理日志只需要记录 uint64 大小的 xid 就行但是 xit_t 并没有提供设置其 xid 的办法只有 set_data() 设置其 data 数据。
目前在 prepare_record 中将整个 xid_t 的内容都存入了152b恢复时会恢复一个完整的 xid_t。
#define XIDDATASIZE 128
typedef struct xid_t {private:/**-1 means that the XID is null*/long formatID;/**value from 1 through 64*/long gtrid_length;/**value from 1 through 64*/long bqual_length;/**distributed trx identifier. not \0-terminated.*/char data[XIDDATASIZE];
...
} XID;prepare 阶段
此阶段只有一个 stage对应 prepare 接口 **prepare()** /** This function is used to prepare an X/Open XA distributed transaction.return 0 or error number */
static int innobase_xa_prepare(handlerton *hton, /*! in: InnoDB handlerton */THD *thd, /*! in: handle to the MySQL thread ofthe user whose XA transaction shouldbe prepared */bool all); /*! in: true - prepare transactionfalse - the current SQL statementended */// init
innobase_hton-prepare innobase_xa_prepare;
此接口需要实现两个功能
判断事务是否需要回滚如果需要则返回错误码。如果事务可以正常提交则生成该事务的日志生成 prepare_record其中存储 xid并等待落盘完成。
commit
分为了三个阶段三个阶段之间可以并发进行但每个阶段内顺序运行第一个进入某个阶段的事务为 leader后续进入的事务为 follower。leader 所在的线程领导 follower 顺序完成此阶段的任务。
其中第一个阶段刷 redo-log进入这个阶段的所有事务只刷盘一次。除了刷盘 redo-logbin-log 需要在这个阶段顺序产生这样一来保证了 redo-log 和 bin-log 日志中事务的顺序是相同的。第二个阶段刷 bin-log第三个阶段执行 commit顺序调用存储引擎的 commit 接口 **flush_logs()** 第一个阶段 /** Flush InnoDB redo logs to the file system.
param[in] hton InnoDB handlerton
param[in] binlog_group_flush true if we got invoked by binlog
group commit during flush stage, false in other cases.
return false */
static bool innobase_flush_logs(handlerton *hton, bool binlog_group_flush);innobase_hton-flush_logs innobase_flush_logs;这个接口的作用是等待 redo_log 进行刷盘是进行组提交的接口。但是测试发现每一个事务prepare 之后都会调用此接口且 InnoDB 都会执行刷盘或者等待刷盘操作。 **commit()** 第三个阶段 int ha_commit_low(THD *thd, bool all, bool run_after_commit true);innobase_hton-commit innobase_commit;此接口需要实现两个功能
这个接口不需要做回滚操作如果事务没有执行成功需要执行回滚只需要返回一个错误码。mysql 随后会调用 rollback接口回滚。执行存储引擎的提交操作并在提交结束后生成一条 commit_record 日志记录这里不需要等待此日志记录落盘因为此日志记录是否落盘不影响已经提交了的事务对应的 tuple 的可见性。且日志的完整性已由 prepare_record 保证。