Trafodion事务管理怎么理解

95次阅读
没有评论

共计 4883 个字符,预计需要花费 13 分钟才能阅读完成。

这篇文章主要介绍“Trafodion 事务管理怎么理解”,在日常操作中,相信很多人在 Trafodion 事务管理怎么理解问题上存在疑惑,丸趣 TV 小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Trafodion 事务管理怎么理解”的疑惑有所帮助!接下来,请跟着丸趣 TV 小编一起来学习吧!

Trafodion 这个词的本意是“事务”,可见项目组对事务处理的重视程度。

事务主要用来防止和处理数据出现不一致的错误。首先理解什么是数据一致性,给出具体的定义实在太为难笔者。还是举个例子吧。笔者年轻时大家都知道“香港四大天王”,他们是刘德华,张学友,黎明和郭富城。我定义这四个名字是“一致的”,而“刘学友”或者“张德华”就不是一致性的数据。或者在介绍的时候不全:比如“香港四大天王是:刘德华,”,其他天王要不高兴了。另外,刘德华唱过《忘情水》,如果数据库查询得到刘德华唱了《吻别》,也是不一致的数据。

造成数据不一致主要有两种因素,分别用两种事务技术解决。在 Trafodion 中,一个技术是日志;另一个技术是多版本并发控制 MVCC。

日志

第一种造成数据不一致的因素是不可预知的故障。故障会导致正在处理数据的过程异常中断,比如数据正在往磁盘中写入的时候系统断电,那么结果就是未知的,有可能写入了不完整的数据。比如应该写入”张学友”覆盖原本的”刘德华”,却只写了”张”,剩下两个字节没来得及写入,所以还是老数据,于是磁盘数据变成“张德华”,造成数据了不一致,从来没有这个天王;或者说正在顺序写入四个人的名字,断电了,只写了刘德华,其他人都没写,也是不一致,要么 4 位全写,要么全都不写,写一个漏掉其他算是什么意思,看不起其他天王么?

处理这类错误的方法是 WAL 日志,write ahead log。即每次写入数据之前,先将变化写入日志,再写数据。这样,如果有错误发生,通过查询日志,就可以进行恢复。比如前面的例子,在将“张学友”写入数据文件之前,先写入日志。这样即便发生了故障,也不会有问题,如果故障发生在写日志的过程中,那么数据文件中依然是“刘德华”。如果故障发生在写数据文件的过程中,那么虽然数据文件中是“张德华”,但是 WAL 日志中却是正确的数据“张学友”,我们将日志 replay 一下,用“张学友”覆盖“张德华”即可。
如果遇到写中断错误,则可以利用日志将做过的操作全部撤销,比如写入了刘德华,然后出错了,查询日志,发现已经写了刘德华,那么 rollback 就是把“刘德华”删除掉。
通过日志,保证了在任何错误情况下,事务的一致性,即 ACID 中的 A 和 D。

传统的日志技术包括 Redo,undo, redo/undo 等。和所有其他数据库一样,Trafodion 采用 redo/undo 日志。

Trafodion 采用 HBase 的 WAL 做 Redo 日志,当 region 恢复时,HBase 负责回放 WAL 进行恢复。

在 R1.0 版本中,Trafodion 将写入数据缓存在内存中,提交的时候才将内存中的数据写入磁盘,因此不需要 undo 日志。如果事务需要回滚,只需要将内存中的数据丢弃即可。

目前计划在 R1.2 版本中,Trafodion 将使用一种被称为 SSCC 的最新技术,SSCC 利用 HBase 的多版本支持存储数据的变化历史,以便提供 repeated read 隔离级别,这些数据历史同时作为 undo 日志。

MVCC 的并发控制方法

还有一种错误,靠日志也不管用,就是多个事务并发写同一个数据,这类错误和我们在多线程程序中修改共享变量时发生的 race condition 是同一类问题。比如我们有两个线程写数据库,都要更新歌曲排行榜的第一名。线程 A 写入一行数据:[singer= 刘德华, song= 忘情水];线程 B 写入另一行数据[singer= 张学友,song= 吻别]。A 和 B 一起写,一种可能的写法为 A 写了歌手后被 B 打断,B 写了歌手和歌曲,A 恢复执行,写入歌曲。最后变成了[singer= 张学友, song= 忘情水]。可是张学友没有唱过《忘情水》。

处理第二类错误的方法被称为并发控制。通常有两种解决方案,第一种是传统的数据库通常使用的方法,即锁管理器;第二种是 MVCC(多版本并发控制)。Trafodion 采用 MVCC 的方法,没有使用锁管理器。因此在 Trafodion 中没有因为锁而引起的读写阻塞和死锁问题。
MVCC 的基本思想和人们使用 SVN 版本控制系统是一样的,每个程序员都是一个事务,而修改的代码就是数据库中的表。如果用 sourcesafe,那么就类似锁管理,张三修改写文件 A 的时候别人谁都不能读写,等张三修改完 check in 才行。用 SVN 后,如果张三正在写文件 A,他写的是本地的一个版本,另外的人想读,可以随时读;别的程序员也可以修改文件 A。但是两个人不能都 commit。先 commit 的人成功,后 commit 的人需要做 merge,如果两个人修改了不同的行(类似两个事务修改不同数据行),则一般都可以 commit,SVN 可以自动 merge。否则就有冲突,需要第二个 commit 的人手动 merge,或者干脆放弃(Abort)。Trafodion 的 MVCC 方法和这个过程完全一样。

HBase 本身提供多版本服务,因此非常适合采用 MVCC 技术。每个写操作都会产生一个新的数据版本,而不会覆盖老版本数据。读操作根据事务开始时间,读取正确的数据版本,即数据的一个历史快照。这避免了幻读,提供了 repeated read 隔离级别的保证。笔者孤陋寡闻,窃以为 MVCC 是 Oracle 最先采用的,Oracle 工程师经常对此非常自豪,因为读不会被写阻塞,提供了很高的并行度。后来 innodb 山寨了 Oracle 的所有实现细节,使得 MySQL 也拥有了类似的能力;PostgreSql 则采用了和 Oracle/innoDb 不同的 MVCC 实现方法,Trafodion 的实现更加类似于 Postgresql,即保存多版本数据用来提供快照读取,而非用作 undo 日志,然后定期进行垃圾收集,删除过期的快照。而 Oracle 则利用了 undo 日志来作为历史快照;前者读取历史版本的速度很快,因为数据和快照都在一起,但需要处理每条历史数据,检查它们的可见性,比较低效;Oracle 则需要到 undo segment 中读取历史数据,应用 undo 日志对数据进行回滚,貌似会比较慢;但是不需要考虑 GC 的问题,而且节约了空间,因为 undo 空间一举两得。所以笔者认为 Oracle/InnoDB 的模式好些,但也主要还是取决于具体的应用场景,假如并发很高,读取历史版本的比例比读取最近数据的频率还要高,则 PostgreSQL/Trafodion 的模式应该更好,因为它们读取快照的效率更好。
不过作者水平经验都很有限,在这里议论其他产品有点儿心中坎坷,各位如果不以为然还请不吝赐教。

在 Commit 的时候,进行 write-write 冲突检测。如果发现两个并发事务同时写一行数据,就依据”first committer win”的原则处理,第一个提交的事务成功,而其他的事务则失败回滚。如前所述的线程 A 和 B,A 写入歌手信息刘德华之后,被打断,B 写入张学友唱《吻别》,这条数据不会覆盖原始数据,而是新生成一条记录,(有些人喜欢称为 COW),这条记录用线程 B 的事务 ID 标记它。这时线程 A 被调度回来,继续写入,同样 A 写的刘德华唱《忘情水》也不会覆盖原始数据,而是新生成一条新的记录,用 A 的事务 ID 标记。在 commit 的时候,Trafodion 发现,这同一行数据有两条新纪录,根据 first commit win 的原则,A 获胜。所以如果线程 A 提交,会成功;而线程 B 提交的时候会报错,回滚。最终数据库的记录为刘德华唱的《忘情水》。是一致的。

Trafodion 目前的版本为 R1.0,在今后的版本中 (计划在 R1.2 版本中) 使能一种新的并发控制算法 SSCC。SSCC 是中科院的研究成果,Trafodion 团队和中科院紧密合作,即将推出这一全新的并发控制机制,SSCC 提供比 SnapShot Isolation 更高级的隔离级别,同时对无状态写操作有很高效的支持。
SSCC 认为 SQL 的写操作有两种:stateful 的写比如 a =a+1,是有状态的;stateless 的写,比如 delete,或者覆盖旧数据,这类写操作和历史状态无关。
无状态写在 web 应用中非常普遍,比如 Google 的 index generating。采用这一机制,Trafodion 可以高效地为相关的 web 应用提供强大的支持。

笔者也会尝试在后续的博客中介绍 SSCC 这一创新的并发控制算法。

并发控制保证了 ACID 中的 I。
最后还有 ACID 的 C 没有提到,是 一致 的意思,然而这个 C 却不是靠事务处理器来保证的。ACID 的 Consistency 靠数据库的约束保证。因此笔者不喜欢用 ACID 来描述事务。但是这个是经典,也不得不提。

两阶段提交

对于单机的数据库,比如 MySQL,Oracle (not RAC),SQL Server,PostgreSql (not xl 版)等,以上两个技术就完全可以实现 ACID 事务了。但是 Trafodion 是一个分布式数据库,操作分布在集群的不同节点执行,比如两条写操作可能由两个不同的 ESP 在不同节点运行,所以 Trafodion 还需要处理分布式事务。

Trafodion 的事务处理器将并发控制的职责分成两部分,TM(Transaction Manager)负责整个事务的分布式并发控制,保证事务本身的一致性;RM(Resource Manager)负责数据访问的并发控制,保证数据的一致性。

具体来说,RM 采用前面所说的 MVCC 技术,提供 Snapshot Isolation 级别的数据一致性。

在 Trafodion 中,每个 HBase 的 Region 都是一个 RM。一个事务很可能会在多个 Region 上操作,比如事务需要更新两行数据,而它们分别属于两个不同的 Region。在这种情况下,一个事务会有多个 RM 参与。而 HBase 的 Region 很可能运行在不同的物理节点上,因此这是一种分布式事务。分布式事务由 TM 保证整个事务的一致性。

TM 使用两阶段提交协议来保证分布式事务的一致性。两阶段提交是一个非常简单直观的协议,类似公司的秘书安排几个人都必须参加的会议。第一阶段:秘书发信给所有参与者:“周一下午 3 点开会,OK?”,如果所有有人都回复“OK”,则最终决定开会进入第二阶段;如果有人回答 no,或者有人不回答,则不开会进入第二阶段;第二阶段根据第一阶段的结果进行不同处理,如果是开会,秘书给每个人发信: 确定周一下午 3 点开会;如果不开会,秘书给每个人发信:‘不开会’。

每个事务都由一个 TM 发起,事务开始的时候,TM 会给事务创建一个 ID。此后,事务中的每一个 DML 操作都带有该 ID,用来在 RM 内部确定该读取的数据版本。

在提交的时候,TM 先进行第一阶段的 prepare commit,向每个 RM 发送 prepare 消息。RM 在收到 prepare 消息时,进行 write-write 冲突检测,如果有冲突则返回冲突,否则返回提交成功。TM 得到所有 RM 的回复后进行判断,如果所有的 RM 都提交成功,则该事务成功,否则事务失败;进入第二阶段,如果事务成功,TM 向所有 RM 发送 commit 消息,每一个 RM 收到 commit 消息后将事务的所有操作都写入物理磁盘,完成事务处理;如果有任何一个 RM 返回冲突,或者任何一个 RM 超时没有反应,TM 认为事务失败,在第二阶段向所有的 RM 发送 abort 消息;每个 RM 在收到 abort 消息后进行事务回滚操作。

DDL 事务

从 R1.1 版本开始,Trafodion 还支持 DDL 的事务处理,比如创建 2 个表,第一个成功,第二个失败,回滚后,两个表都不存在。

到此,关于“Trafodion 事务管理怎么理解”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注丸趣 TV 网站,丸趣 TV 小编会继续努力为大家带来更多实用的文章!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计4883字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)