在处理事务方面,NDB集群存在许多限制。其中包括:
事务隔离级别。的
NDBCLUSTER
存储引擎只支持读过承诺
事务隔离级别。(InnoDB
例如,支持读过承诺
,读未提交
,可重复读取
,可序列化的
)。你应该记住这一点NDB
实现了读过承诺
按每行计算;当读请求到达存储该行的数据节点时,返回的是该行当时的最后提交版本。未提交的数据永远不会返回,但是当修改多个行的事务与读取相同行的事务同时提交时,执行读取的事务可以观察到”之前”值,”后”值,或者两者都是,这是因为给定的行读请求可以在另一个事务提交之前或之后处理。
为确保给定事务仅在值之前或之后读取,可以使用
选择……共享模式锁定
.在这种情况下,锁将一直持有,直到提交所属事务为止。使用行锁还会导致以下问题:增加了锁等待超时错误的频率,并减少了并发性
由于读取需要提交阶段,增加了事务处理开销
耗尽可用并发锁数量的可能性
MaxNoOfConcurrentOperations
NDB
使用读过承诺
对于所有的读,除非有修饰语如共享模式锁定
或更新
使用。共享模式锁定
导致使用共享行锁;更新
导致使用排他行锁。唯一的密钥读取会自动升级其锁NDB
确保自一致的读取;团
读还使用额外的锁以保持一致性。看到“NDB集群备份故障处理”21.5.8.4节的事务隔离级别的实现如何影响备份和恢复的信息
NDB
数据库。事务和BLOB或TEXT列。
NDBCLUSTER
只存储使用任何MySQL的列值的一部分团
或文本
表中对MySQL可见的数据类型;其余的团
或文本
存储在一个单独的内部表中,MySQL无法访问。这会产生两个相关的问题,您在执行时应该注意这两个问题选择
包含这些类型列的表上的语句:对于任何
选择
其中使用唯一键查找来检索使用团
或文本
数据类型和在事务中执行的数据类型,则共享读锁将在事务的整个过程中保存在表上,也就是说,直到事务提交或中止为止。使用索引或表扫描的查询不会出现此问题,甚至对
NDB
表有团
或文本
列。例如,考虑这个表
t
由以下定义创建表
声明:CREATE TABLE t (a INT NOT NULL AUTO_INCREMENT PRIMARY KEY, b INT NOT NULL, c INT NOT NULL, d TEXT, INDEX i(b), UNIQUE KEY u(c))
以下查询是关于
t
导致共享读锁,因为它使用唯一的键查找:SELECT * FROM t WHERE c = 1;
然而,这里显示的四个查询都不会导致共享读锁:
SELECT * FROM t WHERE b = 1;SELECT * FROM WHERE d = '1';SELECT * FROM t;SELECT b,c WHERE a = 1;
这是因为,在这四个查询中,第一个使用索引扫描,第二个和第三个使用表扫描,而第四个虽然使用主键查找,但不检索任何值
团
或文本
列。通过避免使用检索惟一键查找的查询,您可以帮助最小化共享读锁的问题
团
或文本
列,或者(在无法避免此类查询的情况下)在之后尽快提交事务。
惟一键查找和事务隔离。中实现惟一索引
NDB
使用内部维护的隐藏索引表。当用户创建NDB
表是使用唯一索引访问的,首先读取隐藏索引表以找到主键,然后使用主键读取用户创建的表。为了避免在此双读操作期间修改索引,在隐藏索引表中找到的行被锁定。中由惟一索引引用的行NDB
表被更新时,隐藏索引表受到执行更新的事务的排他锁。这意味着在相同的(用户创建的)NDB
表必须等待更新完成。即使当读操作的事务级别为读过承诺
.可以用来绕过潜在阻塞读取的一种解决方法是强制SQL节点在执行读取时忽略惟一索引。可以通过使用
忽略指数
索引提示的一部分选择
语句读取表(参见第8.9.4节“索引提示”).因为MySQL服务器为中创建的每个惟一索引创建一个阴影排序索引NDB
,这让有序索引被读取,并避免唯一索引访问锁定。结果读取与通过主键提交的读取一致,返回该行读取时最后提交的值。通过有序索引读取会降低集群中资源的使用效率,并且可能会有更高的延迟。
通过查询范围而不是查询惟一值,也可以避免使用惟一索引进行访问。
回滚。没有部分事务,也没有事务的部分回滚。重复的键或类似的错误将导致整个事务回滚。
这种行为不同于其他事务存储引擎,例如
InnoDB
这可能会回滚个别语句。事务和内存使用。正如本章其他地方提到的,新开发银行集群不能很好地处理大型交易;最好是执行多个包含少量操作的小事务,而不是尝试一个包含大量操作的大事务。在其他考虑因素中,大型事务需要大量的内存。因此,许多MySQL语句的事务行为受到如下所示的影响:
事务和COUNT()函数。当使用NDB集群复制时,无法保证事务一致性
COUNT ()
在副本上执行函数。换句话说,当在源上执行一系列语句时(插入
,删除
,或两者都使用),它在正在执行的单个事务中更改表中的行数选择count (*) from
对副本的查询可能会产生中间结果。这是因为表格
选择计数(…)
可能执行脏读,而不是一个bug在NDB
存储引擎。(更多信息请参见Bug #31321。)