mysql ndb事务级别_mysql8 参考手册--NDB群集中与事务处理相关的限制

NDB Cluster在事务处理方面存在许多限制。其中包括:

事务隔离级别。 NDBCLUSTER存储引擎只支持READ COMMITTED事务隔离级别。(InnoDB,例如,支持 READ COMMITTED, READ UNCOMMITTED, REPEATABLE READ,和 SERIALIZABLE。)你应该记住,NDB器具 READ COMMITTED在每行的基础; 当读取请求到达存储该行的数据节点时,返回的是该行当时的最后提交版本。

未提交的数据永远不会返回,但是当修改多个行的事务与读取相同行的事务同时提交时,执行读取操作的事务可以观察其中的不同行的“ before ” 值,“ after ”值或两者。 ,这是因为可以在提交另一个事务之前或之后处理给定的行读取请求。

为确保给定的事务仅读取值之前或之后,可以使用施加行锁 SELECT ... LOCK IN SHARE MODE。在这种情况下,锁定将一直保持到拥有事务提交为止。使用行锁也会导致以下问题:

锁定等待超时错误的频率增加,并发减少

由于读取需要提交阶段,因此增加了事务处理开销

耗尽可用并发锁数的可能性受到以下限制: MaxNoOfConcurrentOperations

NDB用途READ COMMITTED对于所有除非改性剂,例如读取, LOCK IN SHARE MODE或FOR UPDATE使用。LOCK IN SHARE MODE导致使用共享的行锁; FOR UPDATE导致使用排他的行锁。唯一键读取会自动更新其锁,NDB以确保读取前后一致。BLOB读取还使用额外的锁定来保持一致性。

事务和BLOB或TEXT列。 NDBCLUSTER仅存储使用MySQL 可见表中的任何MySQL BLOB或 TEXT数据类型的列值的一部分 ;BLOB或 的其余部分 TEXT存储在MySQL无法访问的单独的内部表中。这引起了两个相关的问题,每当SELECT在包含这些类型的列的表上执行语句时,您都应该意识到 这些问题:

对于SELECTNDB群集表中的任何表:如果 SELECT包括a BLOB或 TEXT列,则 READ COMMITTED 事务隔离级别将转换为具有读取锁定的读取。这样做是为了保证一致性。

对于SELECT使用唯一键查找来检索使用任何BLOB或 TEXT数据类型并且在事务内执行的任何列的任何事物,在事务期间(即直到事务进行之前),共享的读取锁将保留在表上。被提交或中止。

使用索引或表扫描的查询不会发生此问题,即使对于 NDB具有 BLOB或 TEXT列的表也是如此。

例如,考虑t 以下CREATE TABLE语句定义的表:

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)

) ENGINE = NDB,

以下查询t由于使用唯一键查找而导致共享读取锁定:

SELECT * FROM t WHERE c = 1;

但是,此处显示的四个查询都不会导致共享读取锁定:

SELECT * FROM t WHERE b = 1;

SELECT * FROM t WHERE d = '1';

SELECT * FROM t;

SELECT b,c WHERE a = 1;

这是因为在这四个查询中,第一个使用索引扫描,第二个和第三个使用表扫描,而第四个在使用主键查找时,不检索any BLOB或 TEXTcolumn 的值 。

通过避免使用检索BLOB或 TEXT列的唯一键查找的查询,或者在无法避免此类查询的情况下,通过尽早提交事务,可以帮助最大程度地减少共享读取锁的问题。

唯一的键查找和事务隔离。 唯一索引是NDB 通过使用内部维护的隐藏索引表实现的。当NDB使用唯一索引访问用户创建的表时,首先将读取隐藏的索引表以找到主键,然后使用该主键读取用户创建的表。为了避免在此双读操作期间修改索引,在隐藏索引表中找到的行将被锁定。当用户创建的唯一索引引用的行NDB 如果更新表,隐藏索引表将受到执行更新的事务的排他锁。这意味着对同一张(用户创建的)NDB表的任何读取操作都必须等待更新完成。即使读取操作的事务级别为,也是如此 READ COMMITTED。

可以用来绕过潜在的阻塞读取的一种解决方法是,强制SQL节点在执行读取时忽略唯一索引。这可以通过将IGNORE INDEX索引提示用作SELECT读取表的语句的一部分来完成(请参见第8.9.4节“索引提示”)。由于MySQL服务器会为中创建的每个唯一索引创建一个阴影排序索引NDB,因此可以读取该排序索引,并避免了唯一索引访问锁定。结果读取与主键提交的读取保持一致,并在读取行时返回最后的提交值。

通过有序索引进行读取会使群集中的资源使用效率降低,并且可能会有更高的延迟。

通过查询范围而不是唯一值,还可以避免使用唯一索引进行访问。

回滚。 没有部分事务,也没有部分事务回滚。重复的密钥或类似错误会导致整个事务回滚。

此行为不同于其他事务存储引擎的行为,例如InnoDB 可能回滚单个语句的行为。

事务和内存使用情况。 如本章其他地方所述,NDB群集不能很好地处理大型事务。与尝试包含多个操作的单个大型事务相比,执行多个具有少量操作的小型事务要好。除其他考虑因素外,大型事务需要非常大量的内存。因此,如下列表中所述,许多MySQL语句的事务行为受到影响:

TRUNCATE TABLE在NDB表上使用时不是事务性的 。如果 TRUNCATE TABLE不能清空表,则必须重新运行它,直到成功。

DELETE FROM(即使没有 WHERE子句)也是 事务性的。对于包含很多行的表,您可能会发现通过使用多个DELETE FROM ... LIMIT ... 语句对删除操作进行“分块 ”可以提高性能。如果您的目标是清空表格,则不妨使用TRUNCATE TABLE。

LOAD DATA语句。 LOAD DATA在NDB表上使用时不是事务性的 。

重要

执行LOAD DATA语句时, NDB引擎以不规则的时间间隔执行提交,从而可以更好地利用通信网络。无法提前知道何时进行此类提交。

ALTER TABLE和事务。 当将NDB表格复制为的一部分时ALTER TABLE,副本的创建是非事务性的。(无论如何,删除副本后都会回滚此操作。)

事务和COUNT()函数。 使用NDB群集复制时,无法保证COUNT()从服务器上功能的事务一致性 。换句话说,在主服务器上执行更改单个事务中表中的行数的一系列语句(INSERT, DELETE或两者)时,在从服务器上执行查询可能会产生中间结果。这是由于可能执行脏读,而不是存储引擎中的错误 。(有关更多信息,请参见Bug#31321。) SELECT COUNT(*) FROM tableSELECT COUNT(...)NDB

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值