陆敬尚,Apache ShardingSphere Committer,SphereEx 基础设施研发工程师,酷爱开源,酷爱数据库技术,目前专一于 Apache ShardingSphere 事务模块的开发。
背景
随着业务的疾速倒退,数据的一直收缩,流量负载的减少,业务零碎遇到了强烈的挑战,对数据库系统可扩展性提出了强烈的诉求。Oracle、MySQL、SQL Server、PostgreSQL 传统单机数据库在线扩大上的问题日益凸显。为了解决扩大问题,呈现了可程度扩大的分布式数据库,于是分布式事务问题成为了必须面对的问题。
在这种背景下,ShardingSphere 提供了一套分布式数据库加强计算引擎,通过可插拔架构构建基于数据库之上的生态系统,提供了分布式事务的能力。
事务介绍
事务语义
事务语义定义了四个个性:原子性(Atomicity)、持久性(Durability)、一致性(Consistency)、隔离性(Isolatation)。
原子性(Atomicity)
在分布式场景下,一个事务的操作可能散布在多个物理节点上,保障在多个节点上的操作都胜利,或都不胜利。
持久性(Durability)
事务提交后,即便断电,事务的操作也是无效的。
一致性(Consistency)
留神:不是 CAP 实践中 C,CAP 中的 C 指的是多正本之间的数据统一问题,这里是不同档次的形象。
站在用户的角度,数据从一个状态,转移到另外一个状态,两个状态都满足肯定的束缚。比方:
银行账户数据,账户 A 有 500 元,账户 B 有 500 元,总额 1000,在一个事务中,执行完 A 和 B 的转账操作后,A 和 B 的账户总额还是 1000。
隔离性(Isolatation)
事务并发执行时,保障并发时数据的正确性。比方:两个事务同时批改一条数据,保障两个事务按肯定程序执行,使数据放弃在一个正确的状态。
面临的挑战
分布式事务绝对单机事务来说面临上面的挑战:
- 原子性,对于单机事务来说,应用 undo log 和 redo log 就能够保障全副提交或者全副回滚。而分布式事务波及多个物理节点,每个节点状况是不同的,有的节点日志写胜利,有的节点日志写不胜利。
- 网络的不稳固,对于单机来说,通信是稳固的,任何操作都能够失去回复,不管胜利与失败。而分布式场景下,网络是不稳固的,有可能一个操作是得不到回复的,怎么保障分布式事务的可用性(异样事务的清理、复原等)是一个问题。
- 并发管制,随着 MVCC 的呈现,操作的可线性化(linearizable)成为了刚需。在单机数据库中,能够很容易地产生全局枯燥递增的事务号,在分布式场景中则不然。
解决方案
原子提交
针对原子性和网络不稳固问题,目前支流的解决方案是 2PC,2PC 定义了两个角色 TM(Transaction Manager)、RM(Resource Manager)。
在分布式场景下,一个事务的操作可能散布在多个节点上,整个事务分两个阶段。
- 第一阶段,RM 锁定相干资源并执行具体操作,返回胜利与否给 TM。
- 第二阶段,TM 更具第一阶段 RM 返回的后果,如果全副胜利,执行最初的提交操作(事务状态的更改,锁状态删除等),如果有失败的,则回滚。
阐明:当然会有一些优化点,比方不波及多节点的事务转化为一阶段提交等。
留神:两阶段提交协定只解决了提交的问题,要么提交胜利,要么不胜利,不存在局部胜利的中间状态。和事务隔离级别没有必然关系。
并发管制
并发管制,就是保障并发执行的事务在某一种隔离级别上的执行策略。自从多版本控制(MVCC)呈现,支流数据库根本摈弃了以前的两阶段锁模型。
并发管制实质是对数据读和写的并发的管制。并发管制的策略决定了隔离级别,并发管制要解决两个问题。
- 决定并发的粒度,比方 MySQL 有行锁(粒度为一行),表锁(粒度为一个表)等
- 三种并发场景的行为:
a. 读读并发,不须要非凡解决,因为不波及数据的变更。
b. 写写并发,不能同时并发,否则会产生数据凌乱。
c. 读写并发,性能优化次要在这里做,有多种并发管制机制,根本都抉择了多版本并发管制 (MVCC)。
MVCC 并发管制模型
现有支流实现形式有两种:
- 基于事务 ID 和 ReadView
每次事务获取事务 ID,标识事务的开启程序,通过沉闷事务列表来获取快照,存储多个以事务 ID 为版本的数据,从而达到并发管制的成果。MySQL、Postgres-XL 都是采取的这种计划。
- 基于 timestamp
引入 timestamp,通过在数据中增加 timestamp 相干属性,通过比照数据的 commitTs(commit timestamp)和 Snapshot timestamp 来判断可见性,从而达到可线性化的并发管制成果。Spanner 采纳的这种计划。
下面两种计划都离不开全局事务号的生成,常见的全局事务号生成机制有 TrueTime(Spanner 采纳),HLC(CockroachDB 采纳有误差的 HLC),TSO(Timestamp Oracle),具体原理见参考文献。
ShardingSphere 事务设计
ShardingSphere 事务性能建设在存储 DB 的本地事务之上,提供 LOCAL、XA、BASE 三种模式事务,使用者只需应用原生事务形式(begin/commit/rollback),就能够应用三种模式,在一致性和性能做适合的衡量。
LOCAL
LOCAL 模式间接建设在存储 DB 的本地事务上的,会存在肯定的原子性问题,当然性能是最高的,如果能够容忍这个问题,这将是一个不错的抉择。
XA
XA 模式,XA 协定是基于 2PC 定义的一套交互协定,定义了 xa start/prepare/end/commit/rollback 等接口,罕用的实现有 Narayana、Atomics,ShardingSphere 集成了 Narayana、Atomics 的 XA 实现。
- app 连贯到 Proxy 上,Proxy 创立一个 session 的对象和这个 connection 绑定。
- app 执行 begin,Proxy 通过 Narayana TM 新建一个逻辑 transaction,和以后 session 绑定。
- app 执行具体 SQL,session 负责建设到存储 DB 的 connection,并把 connection 通过 Transaction.enlistResource() 接口把 connection 注册到 transaction,执行 XA START {XID} 开启事务,并执行路由改写后的 SQL。
- app 执行 commit 命令,transaction 中注册的连贯存储 DB 的 connection,别离执行 xa prepare,当所有 connection 返回 ok,更新 transaction 状态为 prepared,每个 connection 执行 xa commit,都返回 ok 更新 transaction 状态为 commited,提交胜利。如果 prepare 过程局部失败,用户能够通过 rollback 命令登程回滚,不解决则有后盾过程进行清理。
- app 执行 rollback 命令,transaction 中注册的连贯存储 DB 的 connection,别离执行 xa rollback,进行回滚。
BASE
Base(Basically Available, Soft State, Eventually Consistent)模式,BASE 事务是 CAP 实践中 C 和 A 衡量的后果,Seata 的 AT 模式是 Base 事务的一种实现,ShardingSphere 集成了 Seata 的 AT 实现。
- app 连贯到 Proxy 上,Proxy 创立一个 session 的对象和这个 connection 绑定。
- app 执行 begin,Proxy 通过 Seata TM 新建一个逻辑 transaction,和以后 session 绑定,并注册到 Seata Server。
- app 执行一条逻辑 SQL,session 负责建设到存储 DB 的 connection,每个 connection 是 Seata 的 ConnectionProxy 实例,对路由改写后的 actual sql 进行解析, 做一些拦挡,比方:如果是批改操作,执行 begin 获取本地锁,执行一条 SQL,执行 commit 开释本地锁,上报分支事务后果到 Seata Server。
- app 执行 commit 命令,Proxy 中的 Seata TM 告诉 Seata Server 后,间接返回 app,Seata Server 异步和 Proxy 交互,进行删除事务日志。
- app 执行 rollback 命令,Proxy 中的 Seata TM 告诉 Seata Server 后,间接返回 app,Seata Server 异步和 Proxy 交互,执行弥补操作,删除事务日志。
具体流程参考 Seata 官网。
应用示例
安装包筹备
以反对较好的 XA,集成 Narayana 的实现为例,进行介绍。因为 Narayana 的 License 问题,不能间接打包到安装包内,须要增加额定的依赖。
依据官网下载好安装包,解压到 ${ShardingSphere} 目录,往 ${ShardingSphere}/lib 目录下增加以下 jar 包。(下载地址:https://mvnrepository.com/)
<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”>jta<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
arjuna<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
common<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
jboss-connector-api_1<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.7</span>_spec<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-1.0</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.0</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar | ------------------------------------------------------------------------------------------------------------------------------------
jboss-logging<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-3.2</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.1</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar | ------------------------------------------------------------------------------------------------------------------------------------
jboss-transaction-api_1<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.2</span>_spec<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-1.0</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.0</span>.Alpha3.jar | ------------------------------------------------------------------------------------------------------------------------------------
jboss-transaction-spi<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-7.6</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.0</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
mysql-connector-java<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.1</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.47</span>.jar | ------------------------------------------------------------------------------------------------------------------------------------
narayana-jts-integration<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.12</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.4</span>.<span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">Final</span>.jar
shardingsphere-transaction-xa-narayana<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">-5.1</span><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">.1</span>-SNAPSHOT.jar
MySQL 实例筹备
- 筹备两个 MySQL 实例,127.0.0.1:3306,127.0.0.1:3307。
- 两个 MySQL 实例别离创立用户 root, 明码为 12345678。
- 两个 MySQL 实例别离创立 test 库。
ShardingSphere-Proxy 配置
批改 server.yaml 事务配置
<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”><span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">rules:</span>
- !AUTHORITY
<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">users:</span>
- root@%<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">:root</span>
- sharding@<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">:sharding</span>
<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">provider:</span>
<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">type:</span> ALL_PRIVILEGES_PERMITTED
- !TRANSACTION
<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">defaultType:</span> XA
<span class="hljs-symbol" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(42, 146, 146); word-wrap: inherit !important; word-break: inherit !important;">providerType:</span> Narayana
批改 conf/conf-sharding.yaml
<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”>dataSources:
ds_0:
url: jdbc:mysql://127.0.0.1:3306/<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">test</span>?serverTimezone=UTC&allowPublicKeyRetrieval=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">true</span>&useSSL=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">false</span>
username: root
password: 12345678
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
ds_1:
url: jdbc:mysql://127.0.0.1:3307/<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">test</span>?serverTimezone=UTC&allowPublicKeyRetrieval=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">true</span>&useSSL=<span class="hljs-literal" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">false</span>
username: root
password: 12345678
connectionTimeoutMilliseconds: 30000
idleTimeoutMilliseconds: 60000
maxLifetimeMilliseconds: 1800000
maxPoolSize: 50
minPoolSize: 1
rules:
- !SHARDING
tables:
account:
actualDataNodes: ds_<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${0..1}</span>.account<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${0..1}</span>
tableStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: account_inline
keyGenerateStrategy:
column: id
keyGeneratorName: snowflake
defaultDatabaseStrategy:
standard:
shardingColumn: id
shardingAlgorithmName: database_inline
defaultTableStrategy:
none:
shardingAlgorithms:
database_inline:
<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">type</span>: INLINE
props:
algorithm-expression: ds_<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${id % 2}</span><br> account_inline:<br> <span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">type</span>: INLINE<br> props:<br> algorithm-expression: account<span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${id % 2}</span>
keyGenerators:
snowflake:
<span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">type</span>: SNOWFLAKE
props:
worker-id: 123
启动 ShardingSphere-Proxy
参考如下命令启动 Proxy:
<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”><span class="hljs-built_in" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">cd</span> <span class="hljs-variable" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">${ShardingSphere}</span>
./bin/start.sh
应用 ShardingSphere-Proxy
应用 MySQL Client 连贯 ShardingSphere-Proxy 进行测试,参考如下命令。
<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”><span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">mysql</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-h127</span><span class="hljs-selector-class" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">.0</span><span class="hljs-selector-class" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">.0</span><span class="hljs-selector-class" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(190, 70, 120); word-wrap: inherit !important; word-break: inherit !important;">.1</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-P3307</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-uroot</span> <span class="hljs-selector-tag" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">-proot</span>
<div class=”output_wrapper” id=”output_wrapper_id” style=”font-size: 16px; color: rgb(62, 62, 62); line-height: 1.6; word-spacing: 0px; letter-spacing: 0px; font-family: ‘Helvetica Neue’, Helvetica, ‘Hiragino Sans GB’, ‘Microsoft YaHei’, Arial, sans-serif;”><pre style=”font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px;”>mysql> use sharding_db;
Database changed
mysql> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">create table <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">account</span>(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">id <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">int</span>, balance <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">float</span> ,transaction_id <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">int</span></span>)</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.12</span> sec</span>)
mysql> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">select</span> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">from</span> account</span>;
<span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">Empty <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">set</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.02</span> sec</span>)
mysql> begin</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.09</span> sec</span>)
mysql> insert <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">into</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">account</span>(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">id, balance, transaction_id</span>) <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">values</span>(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span></span>),(<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span>,<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span></span>)</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.53</span> sec</span>)
mysql> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">select</span> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">from</span> account</span>;
+------+---------+----------------+
| id | balance | transaction_id |
+------+---------+----------------+
| <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2.0</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> |
| <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1.0</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> |
+------+---------+----------------+
<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">in</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">set</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.03</span> sec</span>)
mysql> commit</span>;
Query OK, <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">affected</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.05</span> sec</span>)
mysql> <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">select</span> * <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">from</span> account</span>;
+------+---------+----------------+
| id | balance | transaction_id |
+------+---------+----------------+
| <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2.0</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> |
| <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1.0</span> | <span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">1</span> |
+------+---------+----------------+
<span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">2</span> <span class="hljs-function" style="font-size: inherit; color: inherit; line-height: inherit; margin: 0px; padding: 0px; word-wrap: inherit !important; word-break: inherit !important;">rows <span class="hljs-keyword" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(149, 90, 231); word-wrap: inherit !important; word-break: inherit !important;">in</span> <span class="hljs-title" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(87, 109, 219); word-wrap: inherit !important; word-break: inherit !important;">set</span> (<span class="hljs-params" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;"><span class="hljs-number" style="font-size: inherit; line-height: inherit; margin: 0px; padding: 0px; color: rgb(170, 87, 60); word-wrap: inherit !important; word-break: inherit !important;">0.02</span> sec</span>)
</span>
将来布局
当初 ShardingSphere 的分布式事务集成了第三方的 2PC 实现计划,提供了原子性的保障,隔离性依赖于存储 DB 的隔离保障,提供了可用的事务性能。将来基于全局 Timestamp 实现 MVCC,联合 2PC,对事务隔离语义提供更好的反对。欢送大家关注 ShardingSphere 的成长。
如果大家对 Apache ShardingSphere 有任何疑难或倡议,欢送在 GitHub issue 列表提出,或可返回中文社区交换探讨。
GitHub issue:https://github.com/apache/shardingsphere/issues
奉献指南:https://shardingsphere.apache.org/community/cn/contribute/
中文社区:https://community.sphere-ex.com/
参考文献
1.ACID wiki:https://en.wikipedia.org/wiki/ACID
2.ANSI isolation levels:https://renenyffenegger.ch/notes/development/databases/SQL/transaction/isolation-level
3.《Distributed Transactions Are Evil》:https://wiki.c2.com/?DistributedTransactionsAreEvil
4.《Distributed transactions and why you should care》:https://towardsdatascience.com/distributed-transactions-and-why-you-should-care-116b6da8d72
5.《Fault-Tolerant Stream Processing at Internet Scale》:http://static.googleusercontent.com/media/research.google.com/en/us/pubs/archive/41378.pdf
6.《Oracle Two Phase Commit 2PC Tips》:http://www.dba-oracle.com/t_two_phase_commit_2pc.htm
7.《2PC: Concurrency Control and Recovery in Database Systems》:https://courses.cs.washington.edu/courses/cse551/09au/papers/CSE550BHG-Ch7.pdf
8.《An Empirical Evaluation of In-Memory Multi-Version Concurrency Control》:https://15721.courses.cs.cmu.edu/spring2018/papers/05-mvcc1/wu-vldb2017.pdf
9.《Concurrency Control And Recovery In Database Systems》:https://courses.cs.washington.edu/courses/cse551/09au/papers/CSE550BHG-Ch7.pdf
10.《Optimistic Concurrency Control》:[https://15721.courses.cs.cmu….)]()
11.《Base: An Acid Alternative》:https://queue.acm.org/detail.cfm?id=1394128
12.《Jepsen: CockroachDB beta-20160829》:https://jepsen.io/analyses/cockroachdb-beta-20160829
13.《Spanner: Google’s Globally-Distributed Database》:https://static.googleusercontent.com/media/research.google.com/en//archive/spanner-osdi2012.pdf
欢送增加社区经理微信(ss_assistant_1)退出交换群,与泛滥 ShardingSphere 爱好者一起交换。