提交mysql代码_mysql源码解读之事务提交过程(一)

mysql_execute_command

{

switch (command)

{

case SQLCOM_INSERT:

mysql_insert();

break;

case SQLCOM_UPDATE:

mysql_update();

break;

case SQLCOM_DELETE:

mysql_delete();

break;

......

}

if thd->is_error() //语句执行错误

trans_rollback_stmt(thd);

else

trans_commit_stmt(thd);

}

可以看到执行任何语句最后,都会执行trans_rollback_stmt,或trans_commit_stmt,这两个调用分别是语句级提交和语句级回滚。语句级提交,对于非自动模式提交情况下,主要作两件事情,一是释放autoinc锁,这个锁主要用来处理多个事务互斥地获取自增列值,因此,无论最后该语句提交或是回滚,该资源都是需要而且可以立马放掉的。二是标识语句在事务中位置,方便语句级回滚。执行commit后,可以进入commit流程,现在来看看具体事务提交的流程是怎样的。

mysql_execute_command

trans_commit

ha_commit_trans(thd, FALSE);

{

TC_LOG_DUMMY:ha_commit_low

ha_commit_low()

innobase_commit

{

//获取innodb层对应的事务结构

trx = check_trx_exists(thd);

if(单个语句,且非自动提交)

{

//释放自增列占用的autoinc锁资源

lock_unlock_table_autoinc(trx);

//标识sql语句在事务中的位置,方便语句级回滚

trx_mark_sql_stat_end(trx);

}

else 事务提交

{

innobase_commit_low()

{

trx_commit_for_mysql();

trx_commit(trx);

}

//确定事务对应的redo日志是否落盘【根据flush_log_at_trx_commit参数,确定redo日志落盘方式】

trx_commit_complete_for_mysql(trx);

trx_flush_log_if_needed_low(trx->commit_lsn);

log_write_up_to(lsn);

}

}

}

trx_commit

trx_commit_low

{

trx_write_serialisation_history

{

trx_undo_update_cleanup //供purge线程处理,清理回滚页

}

trx_commit_in_memory

{

lock_trx_release_locks //释放锁资源

trx_flush_log_if_needed(lsn) //刷日志

trx_roll_savepoints_free //释放savepoints

}

}

mysql通过WAL方式,来保证数据库事务的一致性和持久性,即ACID特性中的C(consistent)和D(durability)。WAL(Write-Ahead Logging)是一种实现事务日志的标准方法,具体而言就是修改记录前,一定要先写日志;事务提交过程中,一定要保证日志先落盘,才能算事务提交完成。通过WAL方式,在保证事务特性的情况下,可以提交数据库的性能。从上述流程可以看出,提交过程中,主要做了4件事情,首先是清理undo段信息,对于innodb存储引擎的更新操作来说,undo段需要purge,这里的purge主要职能是,真正删除物理记录。在执行delete或update操作时,实际旧记录没有真正删除,只是在记录上打了一个标记,而是在事务提交后,purge线程真正删除,释放物理页空间。因此,提交过程中会将undo信息加入purge列表,供purge线程处理。然后是释放锁资源,mysql通过锁互斥机制保证不同事务不同时操作一条记录,事务执行后才会真正释放所有锁资源,并唤醒等待其锁资源的其他事务;再就是刷redo日志,前面我提到了,mysql实现事务一致性和持久性的机制。通过redo日志落盘操作,保证了即使修改的数据页没有即使更新到磁盘,只要日志是完成了,就能保证数据库的完整性和一致性;最后就是清理保存点列表,每个语句实际都会有一个savepoint(保存点),保存点作用是为了可以回滚到事务的任何一个语句执行前的状态,由于事务都已经提交了,所以保存点列表可以被清理了。

关于里面提到的mysql的锁机制,purge原理,redo日志,undo段等内容,其实都是数据库的核心,里面内容也很多,后面学习研究后再给大家分享。后面附录是有关事务的关键数据结构及其成员。

struct trx_t{

trx_rseg_t*rseg;/*!< rollback segment assigned to the

transaction, or NULL if not assigned

trx_undo_t*insert_undo;/*!< pointer to the insert undo log, or

NULL if no inserts performed yet */

trx_undo_t*update_undo;/*!< pointer to the update undo log, or

NULL if no update performed yet */

const char*mysql_log_file_name;

/*!< if MySQL binlog is used, this field

contains a pointer to the latest file

name; this is NULL if binlog is not

used */

ib_int64_tmysql_log_offset;

/*!< if MySQL binlog is used, this

field contains the end offset of the

binlog entry */

}

/* The rollback segment memory object */

struct trx_rseg_t{

/* Fields for update undo logs */

UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_list;

/* List of update undo logs */

UT_LIST_BASE_NODE_T(trx_undo_t) update_undo_cached;

/* List of update undo log segments

cached for fast reuse */

/*--------------------------------------------------------*/

/* Fields for insert undo logs */

UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_list;

/* List of insert undo logs */

UT_LIST_BASE_NODE_T(trx_undo_t) insert_undo_cached;

/* List of insert undo log segments

cached for fast reuse */

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值