关键字:mysql源码解读之事务提交过程--第一篇
mysql是一种关系型数据库,关系型数据库一个重要的特性就是支持事务,这是区别于no-sql产品的一个核心特性。当然了,no-sql产品支持键值查询,不能支持sql语句,这也是一个区别。今天主要讨论下事务的提交流程,由于mysql插件式存储架构,导致开启binlog后,事务提交实质是二阶段提交,通过两阶段提交,来保证存储引擎和二进制日志的一致。本文仅讨论binlog未打卡状态下的提交流程,后续会讨论打开binlog选项后的提交逻辑。源码调试环境如下:
测试环境:
OS:windows
DB:mysql 5.6.12
engine:innodb
测试前置条件:
set autocommit=0;
create table tt(col1 int, col2 varchar(100));
测试语句:
insert into tt values(1, 'abcdef');
commit;
无论对于dml语句【insert,update,delete等】还是dcl语句【commit,rollback】,mysql提供了公共接口mysql_execute_command,我们先分析mysql_execute_command接口的基本流程:
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_t mysql_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 */
}
分享到:
相关推荐
* 2022 年 1 月,PolarDB-X 正式发布 2.0.0 版本,继 2021 年 10 月 20 号云栖大会正式开源后的第一次版本更新,更新内容包括新增集群扩缩容、以及 binlog 生态兼容等特性,兼容 maxwell 和 debezium 增量日志订阅,...
4. **源码解读** 源码数据库通常包含Java源代码、配置文件、数据库脚本等。源码分析可以帮助我们理解业务逻辑、数据流向以及框架配置。例如,Controller类处理HTTP请求,Service类封装业务逻辑,DAO层与数据库交互...
第9章通过源码解读,让读者对MySQL的启动、配置加载、连接处理和SQL执行流程有更深入的理解。 **下篇 - 手册篇** 手册篇提供了一个实用的参考资源,包括MySQL内置函数的详细列表,方便开发人员查询和使用。同时,...
本篇文章将详细解读一个基于SSM(Spring、SpringMVC、MyBatis)和MySQL数据库的娱乐影视公司管理系统源码数据库,这是一份适用于毕业设计的优秀案例,对于学习Java Web开发的学生以及初入行业的开发者具有很高的参考...
四、源码解读 源码中常见的关键组件包括: 1. 用户认证模块:实现用户登录、注册、权限验证等功能。 2. 数据操作模块:处理数据库CRUD(创建、读取、更新、删除)操作。 3. 业务逻辑模块:封装具体业务规则,如绩效...
"精选_基于JSP和MySql的在线电子书商城_源码打包"这个标题揭示了我们讨论的核心内容是一个完整的项目源码,它是一个在线电子书商城的实现,采用Java的Web开发技术JSP(JavaServer Pages)和关系型数据库MySQL。...
2. **数据库设计**:使用MySQL或其他数据库管理系统存储商品信息、订单、用户数据等,涉及SQL查询、事务处理、索引优化等知识。 3. **前端技术**:包括HTML、CSS和JavaScript,用于构建用户友好的交互界面,可能...
- 这是连接数据库的第一步,也是必不可少的一步。 **3.2 建立数据库的连接** - 通过 `DriverManager.getConnection()` 方法建立连接。 - 参数包括连接 URL、用户名和密码。 **3.3 规范 QuickStart 中的例子** - 在...
在SQL性能调整领域,优化数据库查询是至关重要的。...以上就是对"sql性能的调整-总结"的详细解读,涵盖了从索引优化到源码调整的多个层面,通过这些方法可以显著提高SQL查询效率,进而提升整个数据库系统的性能。
首先,"PHP和MySQL WEB开发(4th)源码"表明这是一本关于PHP与MySQL结合进行Web开发的书籍的第四版源代码。这通常涵盖了从基础到进阶的PHP编程技巧,以及如何与MySQL数据库进行交互,包括SQL查询、事务处理、存储过程...
以下将对该课程可能涵盖的一些核心知识点进行详细解读,并结合Web开发领域的常见技术栈来进行拓展说明。 ### 一、Web基础知识 #### 1. HTML5 - **定义与作用**:HTML(Hyper Text Markup Language)是构成网页的...
"微信小程序大学生闲置物品交易平台设计+ssm后端源码案例设计" 这个标题表明,这是一个关于微信小程序开发的项目,主要针对大学生群体,目的是搭建一个平台,让学生们可以交易自己不再需要的物品。这里的“SSM”指的...
在【压缩包子文件的文件名称列表】中,我们看到的"132692195470427599"可能是一个文件或目录名,但在这个上下文中,无法直接解读其具体含义。通常,一个完整的源码包会包含如HTML、CSS、JavaScript文件(用于前端...
1. **Java编程语言**:Java是一种跨平台的面向对象的编程语言,尤其适合于开发大型分布式应用,如网上商城。它提供了丰富的类库和强大的性能,确保系统的稳定性和可扩展性。 2. **MVC架构**:在电商系统中,Model-...
2. **数据库相关** - 这个标签强调了 Ehlib 的核心功能,即提供数据库访问接口,支持多种数据库引擎,如 SQL Server、Oracle、MySQL 等,提供了丰富的数据库操作方法和事务处理能力。 3. **源码** - 提供源代码意味...
1. **网上银行系统**:这是一个模拟真实银行服务的应用程序,包括用户注册、登录、存款、取款、转账等功能。设计这个系统时,你需要理解银行交易的流程,熟悉数据库操作,以及如何处理并发和安全性问题。这涉及到...
第3~9行定义了一个数据源,其实现类是apache的BasicDataSource,第11~25行定义了Hibernate的会话工厂,会话工厂类用Spring提供的LocalSessionFactoryBean维护,它注入了数据源和资源映射文件,此外还通过一些键值...
这篇博文(虽然链接已不可用)可能提供了关于该项目的详细解读,帮助读者理解如何从零开始搭建一个类似的在线购物平台。 在电商网站开发中,以下几个关键知识点是不可或缺的: 1. **前端框架**:吉淘网站可能采用...