MySQL NDB Cluster 7.3.6 是 NDB Cluster 的新版本,基于 MySQL Server 5.6,包括
NDB
存储引擎 7.3 版的功能,并修复了以前 NDB Cluster 版本中最近发现的一些错误。
获取 MySQL NDB Cluster 7.3。 可以从https://mysql.net.cn/downloads/cluster/获得 MySQL NDB Cluster 7.3 源代码和二进制文件。
有关 MySQL NDB Cluster 7.3 中所做更改的概述,请参阅 NDB Cluster 7.3 中的新增功能。
此版本还合并了以前 NDB Cluster 版本中所做的所有错误修复和更改,以及通过 MySQL 5.6.19 在主线 MySQL 5.6 中添加的所有错误修复和功能更改(请参阅MySQL 5.6.19 中的更改(2014-05- 30,一般可用性))。
-
NDB Cluster API: 添加为调试为给定
Ndb
对象指定人类可读名称并稍后检索它的能力的辅助工具。这些操作分别作为setNdbObjectName()
和getNdbObjectName()
方法实现。为了
NDB
更容易地跟踪用户应用程序之间的事件处理,您可以在打印输出中使用引用(fromgetReference()
后跟名称(如果提供);引用将应用程序Ndb
对象、事件缓冲区和NDB
存储引擎的SUMA
块联系在一起。(漏洞 #18419907)
NDB 磁盘数据: 将 undo 缓冲区大小设置为
InitialLogFileGroup
大于SharedGlobalMemory
阻止数据节点启动设置的值;数据节点因错误 1504 Out of logbuffer memory 而失败。虽然失败本身是预期的行为,但错误消息没有提供足够的信息来诊断问题的实际来源;现在在这种情况下,会提供更具体的错误消息 Out of logbuffer memory(指定更小的 undo_buffer_size 或增加 SharedGlobalMemory)。(缺陷 #11762867,缺陷 #55515)-
NDB 复制: 使用时
NDB$EPOCH_TRANS
,DELETE
操作之间的冲突像更新之间的冲突一样处理,主要拒绝事务和从属,并重新对齐辅助。这意味着它们对任何受影响的一行或多行的后续操作的行为取决于它们是处于同一时期还是不同时期:在同一时期内,它们被视为冲突事件;在不同的时代,它们不被认为是冲突的。此修复程序带来了删除之间的冲突处理 与用于冲突检测和解决
NDB$EPOCH_TRANS
时执行的冲突,并扩展了包含 “删除-删除”冲突的测试,并 封装了预期结果,修改了事务性冲突处理,以便冲突仅在操作 之间存在冲突不足以导致事务被视为冲突。(漏洞#18459944)NDB$EPOCH
NDB$EPOCH
NDB$EPOCH_TRANS
DELETE
-
NDB 复制:作为二进制日志轮换的一部分执行 的隐式
FLUSH LOGS
操作可能会因 . 的值足够小而死锁和超时max_binlog_size
。(错误#18274220、错误#19895502、错误#20009154)参考资料:另请参阅:Bug #18845822、Bug #19793475、Bug #16884594。
NDB Cluster API: 当两个表具有同名的不同外键时, ndb_restore认为这是名称冲突并且无法恢复模式。由于此修复,
/
现在明确禁止在外键名称中使用斜杠字符 ( ),并且命名格式parent_id
/child_id
/fk_name
现在由 NDB API 强制执行。(漏洞 #18824753)-
NDB Cluster API: 当
NDB
数据节点通过空纪元指示缓冲区溢出时,事件缓冲区会将不一致的数据事件放入事件队列中。当它被消费时,它没有按预期从事件队列中移除,导致后续nextEvent()
调用返回 0。这导致事件消费停止,因为不一致永远被标记,而事件数据在队列中累积。属于空的不一致纪元的事件数据可以在开头或中间某处找到。
pollEvents()
第一种情况返回 0。此修复处理第二种情况:调用nextEvent()
call 在返回之前将不一致的事件从队列中取出。为了从此修复中受益,nextEvent()
即使pollEvents()
返回 0,用户应用程序也必须调用。(缺陷 #18716991) NDB Cluster API: 该
pollEvents()
方法返回 1,即使在等待时间等于 0 的情况下调用,并且队列中没有等待的事件。现在,在这种情况下,它会按预期返回 0。(漏洞 #18703871)-
MySQL NDB ClusterJ: 当从固定宽度的
char
列utf8
相同类型和长度但使用的另一列latin1
。数据在插入期间被填充后返回带有额外的空格。该值现在在返回之前被修剪。此修复程序还纠正了插入 2 个或更多字节的有效字符期间数据长度太长的错误。
utf8
这是由于在编码之前而不是之后对数据进行了填充。(错误#71435,错误#18283369) -
处理包含无效节点 ID 的 NODE_FAILREP 信号可能会导致数据节点失败。(缺陷 #18993037,缺陷 #73015)
参考:这个问题是 Bug #16007980 的回归。
从源代码构建时,一些文件被写入源目录而不是构建目录。这些包括
manifest.mf
用于创建 ClusterJ jar 的pom.xml
文件 和mvn_install_ndbjtie.sh
. 此外,ndbinfo.sql
被写入构建目录,但在CMakeLists.txt
. (错误#18889568,错误#72843)当二进制日志注入器线程向二进制日志提交一个纪元并且这导致日志文件达到最大大小时,它可能需要轮换二进制日志。直到所有客户端线程的所有已提交事务都刷新到二进制日志,或者最多 30 秒后,才会执行轮换。在所有事务都在 30 秒等待之前提交的情况下,来自多个客户端线程的已提交事务可能属于比注入器线程提交的最新纪元更新的纪元,从而导致线程与自身发生死锁,并且在打破僵局之前造成不必要的 30 秒延迟。(漏洞 #18845822)
如果父索引是父表的主键,主键不在表的初始属性上,并且子表不为空,则添加外键失败并出现 NDB 错误 208。(漏洞#18825966)
-
当一个
NDB
表同时作为父表和子表的2个不同的同名外键时,删除子表上的外键可能会导致父表上的外键被删除,导致这种情况不可能删除剩余的外键。CREATE TABLE
可以使用以下语句 对这种情况进行建模:CREATE TABLE parent ( id INT NOT NULL, PRIMARY KEY (id) ) ENGINE=NDB; CREATE TABLE child ( id INT NOT NULL, parent_id INT, PRIMARY KEY (id), INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES parent(id) ) ENGINE=NDB; CREATE TABLE grandchild ( id INT, parent_id INT, INDEX par_ind (parent_id), FOREIGN KEY (parent_id) REFERENCES child(id) ) ENGINE=NDB;
使用刚才显示的创建表,问题发生在执行语句时
ALTER TABLE child DROP FOREIGN KEY parent_id
,因为在某些情况下可能会从表NDB
中删除外键。grandchild
发生这种情况时,任何后续尝试child
从grandchild
表中删除外键的尝试都会失败。(漏洞#18662582) -
当正在重启的节点与一个或多个订阅 API 节点之间存在连接问题时, 数据节点重启可能会无限期地卡在启动阶段 101(请参阅 NDB Cluster 启动阶段摘要)。
为了帮助防止这种情况的发生,
RestartSubscriberConnectTimeout
引入了一个新的数据节点配置参数,该参数可用于控制数据节点重启在放弃并尝试再次重启之前可以在启动阶段 101 中停止多长时间。默认值为 12000 毫秒。(漏洞#18599198) -
ALTER TABLE ... REORGANIZE PARTITION
将集群中的数据节点数量从 4 个增加到 16 个后 执行 导致数据节点崩溃。此问题显示为由先前的修复引起的回归,该修复使用已在使用的转储代码 (7019) 添加了新的转储处理程序,这导致命令执行两个具有不同语义的不同处理程序。新处理程序被分配了一个新DUMP
代码 (7024)。(漏洞#18550318)参考:这个问题是 Bug #14220269 的回归。
在一长串插入之后,当使用相对较小的重做日志和 的值不够大时
MaxNoOfConcurrentTransactions
,仍然存在因缺少重做日志而阻塞的事务,因此没有在正确的状态下中止(等待准备日志被发送到磁盘或LOG_QUEUED
状态)。这导致重做日志保持阻塞状态,直到通过完成本地检查点解除阻塞。这可能会导致死锁,当阻塞的中止变成阻塞的全局检查点,并且阻塞的 GCP 阻塞 LCP。为了防止出现这种情况,我们现在在到达LOG_QUEUED
中止状态处理程序中的状态时立即中止。(漏洞 #18533982)-
ndbmtd支持多个并行接收器线程,每个接收器线程为远程节点连接(传输器)的一个子集执行信号接收,并将 remote_nodes 映射到节点启动时决定的接收器线程。连接控制由多实例
TRPMAN
块管理,多实例块被组织为代理和工作者,每个接收线程都有一个TRPMAN
本地运行的工作者。该
QMGR
块发送信号以TRPMAN
启用和禁用与远程节点的通信。这些信号被发送到TRPMAN
代理,代理将它们转发给工人。工作人员根据他们管理的一组远程节点自行决定是否对信号采取行动。当前问题的出现是因为
TRPMAN
worker 用来确定他们负责哪些连接的机制是以这样一种方式实现的,即每个 worker 都认为它负责所有连接。这导致 、 和 的操作 被TRPMAN
多次处理。OPEN_COMORD
ENABLE_COMREQ
CLOSE_COMREQ
该修复使实例(接收方
TRPMAN
线程)保持执行OPEN_COMORD
和 请求。此外,从该实例路由特定远程连接时,现在会选择正确的实例。(漏洞 #18518037)ENABLE_COMREQ
CLOSE_COMREQ
TRPMAN
-
在数据节点故障处理期间,执行接管的事务协调器收集任何失败的 TC 实例事务的所有已知状态信息,确定每个事务是已提交还是已中止,并通知所有涉及的 API 节点,以便它们可以将此准确地报告给它们的客户端。TC 实例通过在每个受影响的交易顶部适当地向 API 节点 发送
TCKEY_FAILREF
或 发送信号来提供此信息。TCKEY_FAILCONF
如果这个 TC 实例没有直接连接到 API 节点,它会尝试通过与故障 TC 在同一节点组中的另一个数据节点路由它来传递信号,并向
GSN_TCKEY_FAILREFCONF_R
TC 块实例 0 发送信号在该数据节点中。在多个事务协调器的情况下出现了一个问题,当这个 TC 实例没有用于此类信号的信号处理程序时,这导致它失败。此问题已通过向 TC 代理块添加一个处理程序得到纠正,在这种情况下,该处理程序会将信号转发到本地 TC 工作实例之一,而该实例又会尝试将信号转发到 API 节点。(漏洞 #18455971)
当在不同的 CPU 上运行一个非常慢的主线程和一个或多个事务协调器线程时,发送
DIH_SCAN_GET_NODESREQ
信号时可能会遇到超时,这可能导致数据节点崩溃。现在在这种情况下可以避免超时。(漏洞 #18449222)在中等流量下,在将ndbmtd与多个 TC 线程一起 使用时,多个节点的故障 没有得到妥善处理,这在某些情况下可能导致集群意外关闭。(错误号 18069334)
-
使用全局 LCP 状态 ( ) 跟踪本地检查点 (LCP
c_lcpState
),并且每个NDB
表都有一个状态指示符,指示该表的 LCP 状态 (tabLcpStatus
)。如果全局 LCP 状态为LCP_STATUS_IDLE
,则所有表的 LCP 状态都应为TLS_COMPLETED
。当 LCP 启动时,全局 LCP 状态为
LCP_INIT_TABLES
并且线程开始将所有NDB
表设置为TLS_ACTIVE
。如果任何表还没有为 LCP 准备好,则 LCP 初始化过程会继续CONTINUEB
发出信号,直到所有表都变得可用并被标记为止TLS_ACTIVE
。初始化完成后,全局 LCP 状态设置为LCP_STATUS_ACTIVE
。满足以下条件时会发生此错误:
LCP 处于该
LCP_INIT_TABLES
状态,一些但不是所有表已设置为TLS_ACTIVE
.在全局 LCP 状态更改为之前主节点发生故障
LCP_STATUS_ACTIVE
;也就是说,在 LCP 完成所有表的处理之前。节点故障导致的信号在 LCP 初始化过程
NODE_FAILREP
的最终CONTINUEB
信号之前得到处理,因此在 LCP 保持LCP_INIT_TABLES
状态的同时处理节点故障。
在主节点出现故障并选择新主节点后,新主节点使用
MASTER_LCPREQ
信号查询剩余节点以确定 LCP 的状态。此时,由于 LCP 状态为LCP_INIT_TABLES
,LCP 状态被重置为LCP_STATUS_IDLE
。但是,表的 LCP 状态未被修改,因此仍然存在带有TLS_ACTIVE
. 之后,故障节点从 LCP 中移除。如果给定表的 LCP 状态为TLS_ACTIVE
,则检查全局 LCP 状态是否为LCP_STATUS_IDLE
;此检查失败并导致数据节点失败。现在
MASTER_LCPREQ
处理程序确保将tabLcpStatus
所有表的 更新到TLS_COMPLETED
全局 LCP 状态更改为 时LCP_STATUS_IDLE
。(漏洞 #18044717) -
执行复制
ALTER TABLE
操作时,mysqld创建要更改的表的新副本。该中间表的名称带有前缀#sql-
,具有更新的架构但不包含任何数据。然后mysqld将原表的数据复制到这张中间表,删除原表,最后用原表的名字重命名中间表。mysqld将这样的表视为临时表,并且不将其包含在 ; 的输出中
SHOW TABLES
。 mysqldump也忽略中间表。但是,NDB
这样的中间表与任何其他表之间没有区别。mysqld(和 MySQL 客户端程序)和 查看中间表的方式的这种差异NDB
可能会在执行备份和恢复时出现问题,如果中间表存在于 中是使用复制NDB
失败遗留下来的ALTER TABLE
如果使用mysqldump 和mysql执行模式备份客户,此表不包括在内。但是,在使用ndb_mgm客户端BACKUP
命令完成数据备份的情况下,中间表被包含在内,并且也被 ndb_restore包含,然后由于尝试将数据加载到未在备份中定义的表中而失败模式。为了防止发生此类故障, ndb_restore现在默认忽略在
ALTER TABLE
操作期间创建的中间表(即名称以前缀开头的表#sql-
)。添加了一个新选项--exclude-intermediate-sql-tables
,可以覆盖新行为。该选项的默认值为TRUE
; 要使 ndb_restore恢复到旧行为并尝试恢复中间表,请将此选项设置为FALSE
。(漏洞 #17882305) 改进了插入失败的记录。这旨在帮助诊断写入
mysql.ndb_binlog_index
表时偶尔出现的问题。(漏洞 #17461625)表中的
DEFINER
列INFORMATION_SCHEMA.VIEWS
包含ndbinfo
信息数据库中包含的视图的错误值。这可以在查询的结果中看到,例如SELECT TABLE_NAME, DEFINER FROM INFORMATION_SCHEMA.VIEWS WHERE TABLE_SCHEMA='ndbinfo'
. (漏洞 #17018500)使用
CHAR
使用UTF8
字符集的列作为表的主键列会导致在重新启动数据节点时节点出现故障。尝试使用这样的主键恢复表也会导致ndb_restore失败。(错误#16895311,错误#68893)-
ndb_select_all实用程序 的
--order
(-o
) 选项 仅在指定为最后一个选项时起作用,并且不适用于等号。作为此修复的一部分,程序的
--help
输出也与--order
选项的正确行为保持一致。(漏洞 #64426,漏洞 #16374870)