1.MySQL XA事务源码分析
2.MySQL · 源码分析 · Subquery代码分析
3.DockerMySQL 源码构建 Docker 镜像(基于 ARM 64 架构)
4.MySQL到底是码架不是开源软件mysql不开源吗
5.Mysql是什么开源协议
6.MySQL 核心模块揭秘 | 12 期 | 创建 savepoint
MySQL XA事务源码分析
事务类型外部 XA PREPARE 流程
省流版:
详细版:
外部 XA COMMIT 过程
省流版:
详细版:
外部 XA 2PC 阶段 Log 落盘顺序
------------------- XA PREPARE START -------------------------
------------------- XA PREPARE END -------------------------
.
.
.
.
.
.
------------------- XA COMMIT START -------------------------
------------------- XA COMMIT END -------------------------
本地事务 commit 流程
省流版
与外部 XA PREPARE 2PC 的不同
与外部 XA COMMIT 的不同
详细版:
------------------- PREPARE START -------------------------
------------------- PREPARE END -------------------------
------------------- COMMIT START -------------------------
------------------- COMMIT END -------------------------
外部 XA ROLLBACK 流程
省流版(Not Prepared Rollback 和 Prepared Rollback 的不同之处)
详细版
Not Prepared Rollback(在 end - prepare 之间 rollback)
Prepared Rollback(在 prepare 之后 rollback)
外部 XA RECOVERY 流程
省流版
详细版
本地事务 RECOVERY 流程
省流版
详细版
为什么只遍历最后一个binlog文件:
rotate 到新的 binlog 文件前,redo log 强制落盘,码架因此redo commit记录会落盘,码架保证老的码架binlog文件没有正在提交的事务
MySQL · 源码分析 · Subquery代码分析
子查询在MySQL中的处理方式,主要涉及到其在条件/投影中的码架应用。它们以Item_subselect这个表达式类的码架盛兴娱乐源码子类形式存在,描述结构丰富多样。码架所有子查询在MySQL中以Item_subselect为基类,码架包含相关或非相关的码架类型,且具有特定的码架标记来描述其性质。子查询的码架执行方式在Subquery_strategy枚举中被明确,共有五种最终执行方式。码架处理流程分为prepare、码架optimize和execute三个阶段。码架在prepare阶段,码架子查询通过抽象语法树进行初步构建,主要完成将子查询转换为衍生表或选择性执行的逻辑。optimize阶段根据代价估算决定子查询的执行策略,包括物化执行或EXISTS方式。execute阶段,依据优化阶段确定的策略执行子查询。总结而言,子查询的处理流程在MySQL中较为复杂,特别是在prepare阶段的转换逻辑,但整体处理思路清晰。通过这种方式,MySQL能够高效地处理子查询,实现数据查询和分析的复杂需求。
DockerMySQL 源码构建 Docker 镜像(基于 ARM 架构)
基于 ARM 架构,为避免MySQL版本变化带来的leetcode翻转源码额外成本,本文将指导你如何从头构建MySQL 5.7.的Docker镜像。首先,我们从官方镜像的Dockerfile入手,但官方仅提供MySQL 8.0以上版本的ARM镜像,因此需要采取特殊步骤。 步骤一,使用dfimage获取MySQL 5.7.的原始Dockerfile,注意其原文件中通过yum安装的逻辑不适用于ARM,因为官方yum源缺少该版本的ARM rpm。所以,你需要:在ARM环境中安装必要的依赖
下载源码并安装
修改源码配置以适应ARM架构
编译源码生成rpm文件,结果存放在/root/rpmbuild/RPMS/aarch目录
构建镜像的Dockerfile、docker-entrypoint.sh脚本(解决Kylin V兼容性问题,会在后续文章详细说明)以及my.cnf文件是构建过程中的关键组件。虽然原Dockerfile需要调整以消除EOF块的报错,但整个过程需要细心处理和定制化以适应ARM平台。MySQL到底是不是开源软件mysql不开源吗
MySQL到底是不是开源软件?
MySQL是一款广受欢迎的关系型数据库管理系统,被许多企业和个人用于各种应用场景中。MySQL的开发者们将其定义为开源软件,这意味着任何人都可以查看其源代码,以及修改、基于源代码构建新的软件。但是,这也引起了部分人的质疑:MySQL到底是不是真正的开源软件?
MySQL的开源历史
MySQL最初的版本由瑞典开发者米高·韦德格伦(Michael Widenius)于年编写,最初以GPL(GNU General Public License)协议发布,成为一款开源软件。随着版本逐渐升级,MySQL的架构也不断变化和进步,代码库越来越庞大。敏捷源码查看年,MySQL AB公司成立,开始专门维护和开发MySQL,并由此推出了商业化版本和相关技术支持服务,MySQL作为商业化软件逐渐走向市场。
随后在年,Sun Microsystems公司收购了MySQL AB公司。Sun Microsystems公司也是业界众所周知的开源支持者,这也更加加强了MySQL免费开源的立场,既能保持自由软件的开放精神,同时又能在技术/商业上的进展获得更广泛的支持与创新。
然而,Oracle在年收购了Sun Microsystems公司,从此成为MySQL的所有者,MySQL原则上仍是开源软件。但是,由于Oracle在商业上更加繁荣,也有人开始质疑MySQL在Oracle的管理下是否还能保持开源软件的特性。
MySQL的开源实践
虽然Oracle是MySQL的所有者,但是MySQL的开发和维护仍由MySQL开发团队负责。MySQL的开发团队始终认可和坚持MySQL的开源精神和GPL协议,没有改变MySQL的开放性质和开源协议。同时,MySQL的发布周期也非常规则,每年都会发布新版本,并且开放出源码。
此外,MySQL社区也非常活跃,用户可以在社区中提交BUG报告、应用源码转换提出新的需求、参与功能开发等活动。MySQL还使用了开源的开发工具和平台,例如GitHub、JIRA等等,这让MySQL具有了真正的开源精神。
当然,在商业模式方面,MySQL也推出了商业版,并提供高级技术支持服务。这样的模式可以让企业和个人享有所需的支持和服务,并帮助MySQL的开发团队获得更多的收入和人力支持,同时保持着MySQL的开源特性。
总结
MySQL的开源性质和GPL协议,以及多年来MySQL开发团队的坚持,确实让MySQL成为了一款优秀的开源软件。虽然曾经的Oracle收购引发了争议,甚至让许多人对MySQL的开源性产生了质疑,但是Oracle并没有改变MySQL的开放性质和源代码的开放性,MySQL依然是一款开源软件。因此,MySQL的未来将会继续在开放和自由软件的路上前进,为更多的企业和个人提供数据库技术支持,并为IT行业的良性发展作出贡献。
Mysql是什么开源协议
MySQL是一种开源的关系型数据库管理系统,它通过采用GNU通用公共许可证(GPL)和商业许可证的双许可证模式来运作。GPL许可证赋予用户广泛的权利,包括使用、修改和自由分发MySQL的源码安装向导源代码,确保了开源社区的利益。另一方面,商业许可证则让企业在无需遵守GPL条款的情况下使用MySQL,提供了一种灵活的商业模式,允许企业获取MySQL的商业版本,从而享受额外的功能和支持。
这种双许可证模式极大地提高了MySQL的灵活性和吸引力。对于开源项目的支持者而言,GPL确保了代码的开放性和透明性,促进了社区的发展和创新。而对于寻求商业解决方案的企业,商业许可证则提供了更多的选择,包括获得定制化支持和服务,满足特定的商业需求。
双许可证模式不仅促进了MySQL在开源领域的普及,也为商业用户提供了可靠的数据库管理解决方案。这种模式的成功应用,使得MySQL成为了全球最受欢迎的数据库之一,广泛应用于各种规模的企业和项目中。
MySQL 核心模块揭秘 | 期 | 创建 savepoint
回滚操作,除了回滚整个事务,还可以部分回滚。部分回滚,需要保存点(savepoint)的协助。本文我们先看看保存点里面都有什么。
作者:操盛春,爱可生技术专家,公众号『一树一溪』作者,专注于研究 MySQL 和 OceanBase 源码。 爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源
本文基于 MySQL 8.0. 源码,存储引擎为 InnoDB。
InnoDB 的事务对象有一个名为undo_no 的属性。事务每次改变(插入、更新、删除)某个表的一条记录,都会产生一条 undo 日志。这条 undo 日志中会存储它自己的序号。这个序号就来源于事务对象的 undo_no 属性。
也就是说,事务对象的 undo_no 属性中保存着事务改变(插入、更新、删除)某个表中下一条记录产生的 undo 日志的序号。
每个事务都维护着各自独立的 undo 日志序号,和其它事务无关。
每个事务的 undo 日志序号都从 0 开始。事务产生的第 1 条 undo 日志的序号为 0,第 2 条 undo 日志的序号为 1,依此类推。
InnoDB 的 savepoint 结构中会保存创建 savepoint 时事务对象的 undo_no 属性值。
我们通过 SQL 语句创建一个 savepoint 时,server 层、binlog、InnoDB 会各自创建用于保存 savepoint 信息的结构。
server 层的 savepoint 结构是一个SAVEPOINT 类型的对象,主要属性如下:
binlog 的 savepoint 结构很简单,是一个 8 字节的整数。这个整数的值,是创建 savepoint 时事务已经产生的 binlog 日志的字节数,也是接下来新产生的 binlog 日志写入 trx_cache 的 offset。
为了方便介绍,我们把这个整数值称为binlog offset。
InnoDB 的 savepoint 结构是一个trx_named_savept_t 类型的对象,主要属性如下:
创建 savepoint 时,server 层会分配一块 字节的内存,除了存放它自己的 SAVEPOINT 对象,还会存放 binlog offset 和 InnoDB 的 trx_named_savept_t 对象。
server 层的 SAVEPOINT 对象占用这块内存的前 字节,InnoDB 的 trx_named_savept_t 对象占用中间的 字节,binlog offset 占用最后的 8 字节。
客户端连接到 MySQL 之后,MySQL 会分配一个专门用于该连接的用户线程。
用户线程中有一个m_savepoints 链表,用户创建的多个 savepoint 通过 prev 属性形成链表,m_savepoints 就指向最新创建的 savepoint。
server 层创建 savepoint 之前,会按照创建时间从新到老,逐个查看链表中是否存在和本次创建的 savepoint 同名的 savepoint。
如果在用户线程的 m_savepoints 链表中找到了和本次创建的 savepoint 同名的 savepoint,需要先删除 m_savepoints 链表中的同名 savepoint。
找到的同名 savepoint,是 server 层的SAVEPOINT 对象,它后面的内存区域分别保存着 InnoDB 的 trx_named_savept_t 对象、binlog offset。
binlog 是个老实孩子,乖乖的把 binlog offset 写入了 server 层为它分配的内存里。删除同名 savepoint 时,不需要单独处理 binlog offset。
InnoDB 就不老实了,虽然 server 层也为 InnoDB 的 trx_named_savept_t 对象分配了内存,但是 InnoDB 并没有往里面写入内容。
事务执行过程中,用户每次创建一个 savepoint,InnoDB 都会创建一个对应的 trx_named_savept_t 对象,并加入 InnoDB 事务对象的 trx_savepoints 链表的末尾。
因为 InnoDB 自己维护了一个存放 savepoint 结构的链表,server 层删除同名 savepoint 时,InnoDB 需要找到这个链表中对应的 savepoint 结构并删除,流程如下:
InnoDB 从事务对象的 trx_savepoints 链表中删除 trx_named_savept_t 对象之后,server 层接着从用户线程的 m_savepoints 链表中删除 server 层的SAVEPOINT 对象,也就连带着清理了 binlog offset。
处理完查找、删除同名 savepoint 之后,server 层就正式开始创建 savepoint 了,这个过程分为 3 步。
第 1 步,binlog 会生成一个 Query_log_event。
以创建名为test_savept 的 savepoint 为例,这个 event 的内容如下:
binlog event 写入 trx_cache 之后,binlog offset 会写入 server 层为它分配的 8 字节的内存中。
第 2 步,InnoDB 创建 trx_named_savept_t 对象,并放入事务对象的 trx_savepoints 链表的末尾。
trx_named_savept_t 对象的 name 属性值是 InnoDB 的 savepoint 名字。这个名字是根据 server 层为 InnoDB 的 trx_named_savept_t 对象分配的内存的地址计算得到的。
trx_named_savept_t 对象的savept 属性,是一个 trx_savept_t 类型的对象。这个对象里保存着创建 savepoint 时,事务对象中 undo_no 属性的值,也就是下一条 undo 日志的序号。
第 3 步,把 server 层的 SAVEPOINT 对象加入用户线程的 m_savepoints 链表的尾部。
server 层会创建一个SAVEPOINT 对象,用于存放 savepoint 信息。
binlog 会把binlog offset 写入 server 层为它分配的一块 8 字节的内存里。
InnoDB 会维护自己的 savepoint 链表,里面保存着trx_named_savept_t 对象。
如果 m_savepoints 链表中存在和本次创建的 savepoint 同名的 savepoint, 创建新的 savepoint 之前,server 层会从链表中删除这个同名的 savepoint。
server 层创建的 SAVEPOINT 对象会放入m_savepoints 链表的末尾。
InnoDB 创建的 trx_named_savept_t 对象会放入事务对象的trx_savepoints 链表的末尾。
MySQL 优化器源码入门-内核实现 FULL JOIN 功能
本文以实现MySQL内核的FULL JOIN功能为目标,深入解析了MySQL源码的优化器工作流程。首先,作者通过环境和知识准备,明确将重点放在Server执行流程的探索上,从语法规则的修改开始,如在`sql_yacc.yy`中添加新支持,以及在`parse_tree_nodes.cc`中处理FULL JOIN的语法树解析和打印。接着,作者逐步解析了词法、语法分析后的Query_expression、Query_block和Query_term结构,并在关键函数中设置了断点以跟踪执行流程。
在探索了JOIN的优化工作流程后,作者选择在hypergraph_optimizer中实现FULL JOIN,该部分涉及RelationalExpression、JoinHypergraph的构建和AccessPath的生成。尽管过程复杂,但作者通过逐步调试和修改,成功在HashJoinIterator中添加了对FULL JOIN的支持,包括添加新数据成员和状态标记,以及在LEFT JOIN后执行ANTI JOIN流程。
在测试阶段,作者确认了FULL JOIN功能的正确性,通过在代码关键位置的断点观察,确认了FULL OUTER_JOIN的出现,并展示了改造后的迭代器结构。整个过程中,作者强调了在实现过程中面临的挑战和对MySQL历史的参考,最终决定以最少改动的方式完成任务,以保持代码的简洁和性能。
通过这个项目,作者不仅深入理解了MySQL源码,还实现了FULL JOIN功能,为读者提供了一个从零开始实现新功能的实例。
2024-12-22 20:45
2024-12-22 20:26
2024-12-22 20:23
2024-12-22 20:10
2024-12-22 20:03
2024-12-22 19:50