21.1.7.3 NDB 群集中与事务处理相关的限制

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

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

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

NDB使用READ COMMITTED进行所有读取,除非使用了LOCK IN SHARE MODEFOR UPDATE之类的修饰符。 LOCK IN SHARE MODE导致使用共享行锁; FOR UPDATE导致使用排他行锁。唯一键读取的锁由NDB自动升级,以确保读取前后一致。 BLOB读取还采用了额外的锁定以保持一致性。

有关 NDB Cluster 的事务隔离级别的实现如何影响NDB数据库的备份和还原的信息,请参见第 21.5.8.4 节“ NDB 群集备份故障排除”

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

例如,考虑以下CREATE TABLE语句定义的 tablet

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;

这是因为在这四个查询中,第一个使用索引扫描,第二个和第三个使用 table 扫描,而第四个在使用主键查找时不检索任何BLOBTEXT列的值。

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

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

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

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

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

Important

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

首页