MySQL8 中文参考(九十八)

原文:docs.oracle.com/javase/tutorial/reallybigindex.html

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-server-transactions.html

25.6.16.55 ndbinfo server_transactions 表

server_transactions表是cluster_transactions表的子集,但仅包括当前 SQL 节点(MySQL 服务器)参与的事务,并包括相关的连接 ID。

server_transactions表包含以下列:

  • mysql_connection_id

    MySQL 服务器连接 ID

  • node_id

    事务协调器节点 ID

  • block_instance

    事务协调器块实例

  • transid

    事务 ID

  • state

    操作状态(请参阅可能的值)

  • count_operations

    事务中有状态的操作数

  • outstanding_operations

    仍由本地数据管理层(LQH 块)执行的操作

  • inactive_seconds

    等待 API 的时间

  • client_node_id

    客户端节点 ID

  • client_block_ref

    客户端块引用

注意事项

mysql_connection_idSHOW PROCESSLIST输出中显示的连接或会话 ID 相同。它从INFORMATION_SCHEMANDB_TRANSID_MYSQL_CONNECTION_MAP中获取。

block_instance指的是内核块的一个实例。与块名称一起,此数字可用于在threadblocks表中查找给定实例。

事务 ID(transid)是一个唯一的 64 位数字,可以使用 NDB API 的getTransactionId()方法获取。(目前,MySQL 服务器不公开正在进行的事务的 NDB API 事务 ID。)

state列可以具有以下任一值:CS_ABORTINGCS_COMMITTINGCS_COMMIT_SENTCS_COMPLETE_SENTCS_COMPLETINGCS_CONNECTEDCS_DISCONNECTEDCS_FAIL_ABORTEDCS_FAIL_ABORTINGCS_FAIL_COMMITTEDCS_FAIL_COMMITTINGCS_FAIL_COMPLETEDCS_FAIL_PREPAREDCS_PREPARE_TO_COMMITCS_RECEIVINGCS_REC_COMMITTINGCS_RESTARTCS_SEND_FIRE_TRIG_REQCS_STARTEDCS_START_COMMITTINGCS_START_SCANCS_WAIT_ABORT_CONFCS_WAIT_COMMIT_CONFCS_WAIT_COMPLETE_CONFCS_WAIT_FIRE_TRIG_REQ。(如果 MySQL 服务器使用ndbinfo_show_hidden启用运行,则可以通过从通常隐藏的ndb$dbtc_apiconnect_state表中选择来查看此状态列表。)

client_node_idclient_block_ref中,client指的是 NDB 集群 API 或 SQL 节点(即,NDB API 客户端或连接到集群的 MySQL 服务器)。

block_instance列提供了DBTC内核块实例编号。您可以使用此信息从threadblocks表中获取有关特定线程的信息。

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-table-distribution-status.html

25.6.16.56 ndbinfo 表table_distribution_status

table_distribution_status表提供了关于NDB表分布进度的信息。

table_distribution_status表包含以下列:

  • node_id

    节点 id

  • table_id

    表 ID

  • tab_copy_status

    将表分布数据复制到磁盘的状态;其中之一为IDLESR_PHASE1_READ_PAGESSR_PHASE2_READ_TABLESR_PHASE3_COPY_TABLEREMOVE_NODELCP_READ_TABLECOPY_TAB_REQCOPY_NODE_STATEADD_TABLE_COORDINATOR在 NDB 8.0.23 之前ADD_TABLE_MASTER)、ADD_TABLE_PARTICIPANT在 NDB 8.0.23 之前ADD_TABLE_SLAVE)、INVALIDATE_NODE_LCPALTER_TABLECOPY_TO_SAVEGET_TABINFO

  • tab_update_status

    表分布数据更新状态;其中之一为IDLELOCAL_CHECKPOINTLOCAL_CHECKPOINT_QUEUEDREMOVE_NODECOPY_TAB_REQADD_TABLE_MASTERADD_TABLE_SLAVEINVALIDATE_NODE_LCPCALLBACK

  • tab_lcp_status

    表 LCP 的状态;其中之一为ACTIVE(等待执行本地检查点)、WRITING_TO_FILE(检查点已执行但尚未写入磁盘)或COMPLETED(检查点已执行并持久化到磁盘)

  • tab_status

    表内部状态;其中之一为ACTIVE(表存在)、CREATING(表正在创建)或DROPPING(表正在删除)

  • tab_storage

    表可恢复性;其中之一为NORMAL(通过重做日志和检查点完全可恢复),NOLOGGING(从节点崩溃中恢复,空集群崩溃后恢复),或TEMPORARY(不可恢复)

  • tab_partitions

    表中的分区数

  • tab_fragments

    表中的片段数;通常与tab_partitions相同;对于完全复制的表,等于tab_partitions * [节点组数]

  • current_scan_count

    当前活动扫描数

  • scan_count_wait

    当前等待执行的扫描数,直到ALTER TABLE完成。

  • is_reorg_ongoing

    表当前是否正在重新组织(如果是则为 1)

原文:dev.mysql.com/doc/refman/8.0/zh/mysql-cluster-ndbinfo-table-fragments.html

25.6.16.57 ndbinfo 表 _fragments 表

table_fragments 表提供关于 NDB 表的分片、分区、分布和(内部)复制的信息。

table_fragments 表包含以下列:

  • node_id

    节点 ID(DIH 主节点)

  • table_id

    表 ID

  • partition_id

    分区 ID

  • fragment_id

    片段 ID(除非表完全复制,否则与分区 ID 相同)

  • partition_order

    片段在分区中的顺序

  • log_part_id

    片段的日志部分 ID

  • no_of_replicas

    片段副本数量

  • current_primary

    当前主节点 ID

  • preferred_primary

    首选主节点 ID

  • current_first_backup

    当前第一备份节点 ID

  • current_second_backup

    当前第二备份节点 ID

  • current_third_backup

    当前第三备份节点 ID

  • num_alive_replicas

    当前活片段副本数量

  • num_dead_replicas

    当前死片段副本数量

  • num_lcp_replicas

    剩余待检查点的片段副本数量

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-table-info.html

25.6.16.58 ndbinfo 表 table_info

table_info表提供了关于个别NDB表的日志记录、检查点、分布和存储选项的信息。

table_info表包含以下列:

  • table_id

    表 ID

  • logged_table

    表是否已记录(1)或未记录(0)

  • row_contains_gci

    表行是否包含 GCI(1 为真,0 为假)

  • row_contains_checksum

    表行是否包含校验和(1 为真,0 为假)

  • read_backup

    如果备份片段副本被读取,则为 1,否则为 0

  • fully_replicated

    如果表是完全复制的话,这个值为 1,否则为 0

  • storage_type

    表存储类型;其中之一为MEMORYDISK

  • hashmap_id

    哈希映射 ID

  • partition_balance

    表的分区平衡(片段计数类型);其中之一为FOR_RP_BY_NODEFOR_RA_BY_NODEFOR_RP_BY_LDMFOR_RA_BY_LDM

  • create_gci

    表创建时的 GCI

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-table-replicas.html

25.6.16.59 ndbinfo 表 _replicas 表

table_replicas表提供有关 NDB 表片段和片段副本的复制、分发和检查点的信息。

table_replicas表包含以下列:

  • node_id

    从中提取数据的节点的 ID(DIH主节点)

  • table_id

    表 ID

  • fragment_id

    片段 ID

  • initial_gci

    表的初始 GCI

  • replica_node_id

    存储片段副本的节点的 ID

  • is_lcp_ongoing

    如果此片段上正在进行 LCP,则为 1,否则为 0

  • num_crashed_replicas

    崩溃片段副本实例的数量

  • last_max_gci_started

    最近 LCP 中开始的最高 GCI

  • last_max_gci_completed

    最近 LCP 中完成的最高 GCI

  • last_lcp_id

    最近 LCP 的 ID

  • prev_lcp_id

    上一个 LCP 的 ID

  • prev_max_gci_started

    上一个 LCP 中开始的最高 GCI

  • prev_max_gci_completed

    上一个 LCP 中完成的最高 GCI

  • last_create_gci

    上一个崩溃片段副本实例的最后创建 GCI

  • last_replica_gci

    上一个崩溃片段副本实例的最后 GCI

  • is_replica_alive

    如果此片段副本存活,则为 1,否则为 0

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-tc-time-track-stats.html

25.6.16.60 The ndbinfo tc_time_track_stats Table

tc_time_track_stats 表提供从数据节点中的 DBTC 块(TC)实例中获取的时间跟踪信息,通过 API 节点访问 NDB。每个 TC 实例跟踪它代表 API 节点或其他数据节点执行的一组活动的延迟;这些活动包括事务、事务错误、键读取、键写入、唯一索引操作、任何类型的失败键操作、扫描、失败扫描、片段扫描和失败片段扫描。

为每种活动维护一组计数器,每个计数器覆盖小于或等于上限值的延迟范围。在每个活动结束时,确定其延迟并适当地递增计数器。tc_time_track_stats 将此信息呈现为行,每个实例对应一行:

  • 数据节点,使用其 ID

  • TC 块实例

  • 其他通信数据节点或 API 节点,使用其 ID

  • 上限值

每行包含每种活动类型的值。这是该活动发生的次数,其延迟在行指定的范围内(即,延迟不超过上限值)。

tc_time_track_stats 表包含以下列:

  • node_id

    请求节点 ID

  • block_number

    TC 块编号

  • block_instance

    TC 块实例编号

  • comm_node_id

    通信 API 或数据节点的节点 ID

  • upper_bound

    区间的上限值(以微秒为单位)

  • scans

    基于从打开到关闭的成功扫描持续时间,针对请求它们的 API 或数据节点进行跟踪。

  • scan_errors

    基于从打开到关闭的失败扫描持续时间,针对请求它们的 API 或数据节点进行跟踪。

  • scan_fragments

    基于从打开到关闭的成功片段扫描持续时间,针对执行它们的数据节点进行跟踪。

  • scan_fragment_errors

    基于从打开到关闭的失败片段扫描持续时间,针对执行它们的数据节点进行跟踪。

  • transactions

    基于从开始到发送提交ACK的成功事务持续时间,针对请求它们的 API 或数据节点进行跟踪。无状态事务不包括在内。

  • transaction_errors

    基于从开始到失败点的失败事务持续时间,针对请求它们的 API 或数据节点进行跟踪。

  • read_key_ops

    基于带锁的成功主键读取的持续时间。针对请求它们的 API 或数据节点以及执行它们的数据节点进行跟踪。

  • write_key_ops

    基于成功主键写入的持续时间,针对请求它们的 API 或数据节点以及执行它们的数据节点进行跟踪。

  • index_key_ops

    基于成功唯一索引键操作的持续时间,跟踪 API 或数据节点请求它们以及执行基表读取的数据节点。

  • key_op_errors

    基于所有不成功的键读取或写入操作的持续时间,跟踪 API 或数据节点请求它们以及执行它们的数据节点。

注意

block_instance列提供了DBTC内核块实例编号。您可以将其与块名称一起使用,从threadblocks表中获取有关特定线程的信息。

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-threadblocks.html

25.6.16.61 ndbinfo threadblocks

threadblocks 表关联数据节点、线程和 NDB 内核块的实例。

threadblocks 表包含以下列:

  • node_id

    节点 ID

  • thr_no

    线程 ID

  • block_name

    区块名称

  • block_instance

    块实例编号

备注

在这个表中,block_name 的值是从 ndbinfo.blocks 表中选择时在 block_name 列中找到的值之一。虽然在给定的 NDB Cluster 版本中可能值的列表是静态的,但在不同版本之间可能会有所不同。

block_instance 列提供了内核块实例编号。

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-threads.html

25.6.16.62 ndbinfo 线程表

threads表提供了关于在NDB内核中运行的线程的信息。

threads表包含以下列:

  • node_id

    线程所在节点的 ID

  • thr_no

    线程 ID(特定于此节点)

  • thread_name

    线程名称(线程类型)

  • thread_description

    线程(类型)描述

笔记

展示了一个包括线程描述的 2 节点示例集群的样本输出:

mysql> SELECT * FROM threads;
+---------+--------+-------------+------------------------------------------------------------------+
| node_id | thr_no | thread_name | thread_description                                               |
+---------+--------+-------------+------------------------------------------------------------------+
|       5 |      0 | main        | main thread, schema and distribution handling                    |
|       5 |      1 | rep         | rep thread, asynch replication and proxy block handling          |
|       5 |      2 | ldm         | ldm thread, handling a set of data partitions                    |
|       5 |      3 | recv        | receive thread, performing receive and polling for new receives  |
|       6 |      0 | main        | main thread, schema and distribution handling                    |
|       6 |      1 | rep         | rep thread, asynch replication and proxy block handling          |
|       6 |      2 | ldm         | ldm thread, handling a set of data partitions                    |
|       6 |      3 | recv        | receive thread, performing receive and polling for new receives  |
+---------+--------+-------------+------------------------------------------------------------------+
8 rows in set (0.01 sec)

NDB 8.0.23 引入了在将ThreadConfig参数mainrep设置为 0 的同时保持另一个参数为 1 的可能性,此时线程名称为main_rep,描述为主和副本线程,模式,分发,代理块和异步复制处理。从 NDB 8.0.23 开始,还可以将mainrep都设置为 0,此时生成线程的名称在此表中显示为main_rep_recv,描述为主,副本和接收线程,模式,分发,代理块和异步复制处理以及处理接收和轮询新接收

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-threadstat.html

25.6.16.63 ndbinfo threadstat

threadstat 表提供了运行在 NDB 内核中的线程统计的大致快照。

threadstat 表包含以下列:

  • node_id

    节点 ID

  • thr_no

    线程 ID

  • thr_nm

    线程名称

  • c_loop

    主循环中的循环次数

  • c_exec

    执行的信号数

  • c_wait

    等待额外输入的次数

  • c_l_sent_prioa

    发送到自身节点的优先级 A 信号数

  • c_l_sent_priob

    发送到自身节点的优先级 B 信号数

  • c_r_sent_prioa

    发送到远程节点的优先级 A 信号数

  • c_r_sent_priob

    发送到远程节点的优先级 B 信号数

  • os_tid

    OS 线程 ID

  • os_now

    OS 时间(毫秒)

  • os_ru_utime

    OS 用户 CPU 时间(微秒)

  • os_ru_stime

    OS 系统 CPU 时间(微秒)

  • os_ru_minflt

    OS 页面回收(软页错误)

  • os_ru_majflt

    OS 页面错误(硬页错误)

  • os_ru_nvcsw

    OS 自愿上下文切换

  • os_ru_nivcsw

    OS 非自愿上下文切换

注意事项

os_time 使用系统 gettimeofday() 调用。

os_ru_utimeos_ru_stimeos_ru_minfltos_ru_majfltos_ru_nvcswos_ru_nivcsw 列的值是使用系统 getrusage() 调用或等效调用获取的。

由于该表包含在特定时间点采取的计数,为了获得最佳结果,需要定期查询该表并将结果存储在一个中间表或多个表中。 MySQL 服务器的事件调度程序可用于自动化此类监控。有关更多信息,请参见 Section 27.4, “Using the Event Scheduler”。

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-transporter-details.html

25.6.16.64 ndbinfo transporter_details 表

此表包含有关单个 NDB 传输器的信息,而不是由 transporters 表显示的聚合信息。transporter_details 表在 NDB 8.0.37 中添加。

transporter_details 表包含以下列:

  • node_id

    此数据节点在集群中的唯一节点 ID

  • block_instance

  • trp_id

    传输器 ID

  • remote_node_id

    远程数据节点的节点 ID

  • status

    连接的状态

  • remote_address

    远程主机的名称或 IP 地址

  • bytes_sent

    使用此连接发送的字节数

  • bytes_received

    使用此连接接收的字节数

  • connect_count

    在此传输器上建立连接的次数

  • overloaded

    如果此传输器当前过载,则为 1,否则为 0

  • overload_count

    此传输器自连接以来进入过载状态的次数

  • slowdown

    如果此传输器处于减速状态,则为 1,否则为 0

  • slowdown_count

    此传输器自连接以来进入减速状态的次数

  • encrypted

    如果此传输器使用 TLS 连接,则此列为 1,否则为 0

transporter_details 表显示集群中每个传输器的状态。有关此表中每列的更多信息,请参阅 transporters 表的注释。

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ndbinfo-transporters.html

25.6.16.65 ndbinfo transporters 表

此表包含有关 NDB 传输器的聚合信息。在 NDB 8.0.37 及更高版本中,您可以从transporter_details表中获取有关单个传输器的类似信息。

transporters 表包含以下列:

  • node_id

    此数据节点在集群中的唯一节点 ID

  • remote_node_id

    远程数据节点的节点 ID

  • status

    连接的状态

  • remote_address

    远程主机的名称或 IP 地址

  • bytes_sent

    使用此连接发送的字节数

  • bytes_received

    使用此连接接收的字节数

  • connect_count

    自此传输器建立连接以来的连接次数

  • overloaded

    如果此传输器当前超载,则为 1,否则为 0

  • overload_count

    此传输器自连接以来进入超载状态的次数

  • slowdown

    如果此传输器处于减速状态,则为 1,否则为 0

  • slowdown_count

    自连接以来此传输器进入减速状态的次数

注释

对于集群中每个运行的数据节点,transporters 表显示一行,显示该节点与集群中所有节点(包括自身)的每个连接的状态。此信息显示在表的status列中,该列可以具有以下任一值:CONNECTINGCONNECTEDDISCONNECTINGDISCONNECTED

配置但当前未连接到集群的 API 和管理节点的连接显示为DISCONNECTED状态。在此表中不显示node_id为当前未连接的数据节点的行(这类似于ndbinfo.nodes表中省略了断开连接的节点。

remote_address 是显示在remote_node_id列中的节点的主机名或地址。从此节点发送的bytes_sent和此节点接收的bytes_received分别是使用此连接发送和接收的字节数。对于状态为CONNECTINGDISCONNECTED的节点,这些列始终显示0

假设您有一个由 2 个数据节点、2 个 SQL 节点和 1 个管理节点组成的 5 节点集群,如SHOW命令在ndb_mgm客户端的输出中所示:

ndb_mgm> SHOW
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=1    @10.100.10.1  (8.0.35-ndb-8.0.35, Nodegroup: 0, *)
id=2    @10.100.10.2  (8.0.35-ndb-8.0.35, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=10   @10.100.10.10  (8.0.35-ndb-8.0.35)

[mysqld(API)]   2 node(s)
id=20   @10.100.10.20  (8.0.35-ndb-8.0.35)
id=21   @10.100.10.21  (8.0.35-ndb-8.0.35)

transporters 表中有 10 行——第一个数据节点有 5 行,第二个数据节点也有 5 行——假设所有数据节点都在运行,如下所示:

mysql> SELECT node_id, remote_node_id, status
 ->   FROM ndbinfo.transporters;
+---------+----------------+---------------+
| node_id | remote_node_id | status        |
+---------+----------------+---------------+
|       1 |              1 | DISCONNECTED  |
|       1 |              2 | CONNECTED     |
|       1 |             10 | CONNECTED     |
|       1 |             20 | CONNECTED     |
|       1 |             21 | CONNECTED     |
|       2 |              1 | CONNECTED     |
|       2 |              2 | DISCONNECTED  |
|       2 |             10 | CONNECTED     |
|       2 |             20 | CONNECTED     |
|       2 |             21 | CONNECTED     |
+---------+----------------+---------------+
10 rows in set (0.04 sec)

如果您使用 ndb_mgm 客户端中的 2 STOP 命令关闭此集群中的一个数据节点,然后重复上一个查询(再次使用 mysql 客户端),则此表现在仅显示 5 行—每个连接从剩余管理节点到另一个节点,包括自身和当前离线的数据节点,显示每个剩余连接到当前离线的数据节点的状态为 CONNECTING,如下所示:

mysql> SELECT node_id, remote_node_id, status
 ->   FROM ndbinfo.transporters;
+---------+----------------+---------------+
| node_id | remote_node_id | status        |
+---------+----------------+---------------+
|       1 |              1 | DISCONNECTED  |
|       1 |              2 | CONNECTING    |
|       1 |             10 | CONNECTED     |
|       1 |             20 | CONNECTED     |
|       1 |             21 | CONNECTED     |
+---------+----------------+---------------+
5 rows in set (0.02 sec)

connect_countoverloadedoverload_countslowdownslowdown_count 计数器在连接时重置,并在远程节点断开连接后保留其值。bytes_sentbytes_received 计数器也在连接时重置,因此在断开连接后保留其值(直到下次连接重置它们)。

overloadedoverload_count 列所指的 过载 状态发生在此传输器的发送缓冲区包含超过 OVerloadLimit 字节(默认为 SendBufferMemory 的 80%,即 0.8 * 2097152 = 1677721 字节)时。当给定传输器处于过载状态时,任何尝试使用此传输器的新事务都会因错误 1218(NDB 内核中的发送缓冲区过载)而失败。这影响扫描和主键操作。

此表中 slowdownslowdown_count 列引用的 减速 状态发生在传输器的发送缓冲区包含超过过载限制的 60% 时(默认为 0.6 * 2097152 = 1258291 字节)。在此状态下,使用此传输器的任何新扫描都会将其批量大小减小以减少传输器的负载。

发送缓冲区减速或过载的常见原因包括以下内容:

  • 数据大小,特别是存储在 TEXT 列或 BLOB 列(或两种列类型)中的数据量

  • 在进行二进制日志记录的 SQL 节点上与数据节点(ndbd 或 ndbmtd)位于同一主机上

  • 每个事务或事务批次中的大量行

  • 配置问题,如不足的 SendBufferMemory

  • 硬件问题,如内存不足或网络连接质量差

参见 Section 25.4.3.14, “配置 NDB 集群发送缓冲区参数”。

25.6.17 NDB 集群的 INFORMATION_SCHEMA 表

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-information-schema-tables.html

两个INFORMATION_SCHEMA表提供了在管理 NDB 集群时特别有用的信息。FILES表提供了关于 NDB 集群磁盘数据文件的信息(参见第 25.6.11.1 节,“NDB 集群磁盘数据对象”)。ndb_transid_mysql_connection_map表提供了事务、事务协调器和 API 节点之间的映射。

可以从ndbinfo数据库中的表中获取有关 NDB 集群事务、操作、线程、块以及性能的其他统计数据。有关这些表的信息,请参见第 25.6.16 节,“ndbinfo: NDB 集群信息数据库”。

25.6.18 NDB Cluster and the Performance Schema

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-ps-tables.html

NDB 8.0 提供了关于线程和事务内存使用情况的 MySQL 性能模式信息;NDB 8.0.29 添加了ndbcluster插件线程,NDB 8.0.30 添加了事务批处理内存的仪表化。这些功能在接下来的章节中有更详细的描述。

ndbcluster 插件线程

从 NDB 8.0.29 开始,ndbcluster插件线程在性能模式threads表中可见,如下查询所示:

mysql> SELECT name, type, thread_id, thread_os_id
 -> FROM performance_schema.threads
 -> WHERE name LIKE '%ndbcluster%'\G
+----------------------------------+------------+-----------+--------------+
| name                             | type       | thread_id | thread_os_id |
+----------------------------------+------------+-----------+--------------+
| thread/ndbcluster/ndb_binlog     | BACKGROUND |        30 |        11980 |
| thread/ndbcluster/ndb_index_stat | BACKGROUND |        31 |        11981 |
| thread/ndbcluster/ndb_metadata   | BACKGROUND |        32 |        11982 |
+----------------------------------+------------+-----------+--------------+

threads表显示了这里列出的所有三个线程:

  • ndb_binlog:二进制日志线程

  • ndb_index_stat:索引统计线程

  • ndb_metadata:元数据线程

这些线程也在setup_threads表中按名称显示。

线程名称在threadssetup_threads表的name列中以*prefix*/*plugin_name*/*thread_name*的格式显示。 *prefix*是由performance_schema引擎确定的对象类型,对于插件线程是thread(参见 Thread Instrument Elements)。 *plugin_name*是ndbcluster。 *thread_name*是线程的独立名称(ndb_binlogndb_index_statndb_metadata)。

使用threadssetup_threads表中给定线程的线程 ID 或 OS 线程 ID,可以从性能模式中获取有关插件执行和资源使用的大量信息。此示例显示了如何通过连接threadsmemory_summary_by_thread_by_event_name表来获取ndbcluster插件创建的线程在mem_root区域分配的内存量:

mysql> SELECT
 ->   t.name,
 ->   m.sum_number_of_bytes_alloc,
 ->   IF(m.sum_number_of_bytes_alloc > 0, "true", "false") AS 'Has allocated memory'
 -> FROM performance_schema.memory_summary_by_thread_by_event_name m
 -> JOIN performance_schema.threads t
 -> ON m.thread_id = t.thread_id
 -> WHERE t.name LIKE '%ndbcluster%'
 ->   AND event_name LIKE '%THD::main_mem_root%';
+----------------------------------+---------------------------+----------------------+
| name                             | sum_number_of_bytes_alloc | Has allocated memory |
+----------------------------------+---------------------------+----------------------+
| thread/ndbcluster/ndb_binlog     |                     20576 | true                 |
| thread/ndbcluster/ndb_index_stat |                         0 | false                |
| thread/ndbcluster/ndb_metadata   |                      8240 | true                 |
+----------------------------------+---------------------------+----------------------+
事务内存使用情况

从 NDB 8.0.30 开始,您可以通过查询性能模式memory_summary_by_thread_by_event_name表来查看事务批处理使用的内存量,类似于下面显示的内容:

mysql> SELECT EVENT_NAME
 ->   FROM performance_schema.memory_summary_by_thread_by_event_name
 ->   WHERE THREAD_ID = PS_CURRENT_THREAD_ID()
 ->     AND EVENT_NAME LIKE 'memory/ndbcluster/%';
+-------------------------------------------+
| EVENT_NAME                                |
+-------------------------------------------+
| memory/ndbcluster/Thd_ndb::batch_mem_root |
+-------------------------------------------+
1 row in set (0.01 sec)

ndbcluster事务内存仪器也在性能模式setup_instruments表中可见,如下所示:

mysql> SELECT * from performance_schema.setup_instruments 
 ->   WHERE NAME LIKE '%ndb%'\G
*************************** 1\. row ***************************
         NAME: memory/ndbcluster/Thd_ndb::batch_mem_root
      ENABLED: YES
        TIMED: NULL
   PROPERTIES: 
   VOLATILITY: 0
DOCUMENTATION: Memory used for transaction batching 1 row in set (0.01 sec)

25.6.19 快速参考:NDB 集群 SQL 语句

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-sql-statements.html

本节讨论了几个 SQL 语句,这些语句在管理和监控连接到 NDB 集群的 MySQL 服务器时可能会有用,并在某些情况下提供有关集群本身的信息。

  • SHOW ENGINE NDB STATUSSHOW ENGINE NDBCLUSTER STATUS

    此语句的输出包含有关服务器与集群的连接、NDB 集群对象的创建和使用,以及 NDB 集群复制的二进制日志记录的信息。

    有关用法示例和更详细信息,请参见第 15.7.7.15 节,“SHOW ENGINE 语句”。

  • SHOW ENGINES

    此语句可用于确定 MySQL 服务器中是否启用了集群支持,以及如果是,则是否处于活动状态。

    有关更详细信息,请参见第 15.7.7.16 节,“SHOW ENGINES 语句”。

    注意

    此语句不支持LIKE子句。但是,您可以使用LIKE来过滤针对 Information Schema ENGINES表的查询,如下一项所述。

  • SELECT * FROM INFORMATION_SCHEMA.ENGINES [WHERE ENGINE LIKE 'NDB%']

    这相当于SHOW ENGINES,但使用INFORMATION_SCHEMA数据库的ENGINES表。与SHOW ENGINES语句不同,可以使用LIKE子句来过滤结果,并选择特定列以获取在脚本中可能有用的信息。例如,以下查询显示服务器是否构建有NDB支持,并且如果是,则是否已启用:

    mysql> SELECT ENGINE, SUPPORT FROM INFORMATION_SCHEMA.ENGINES
     ->   WHERE ENGINE LIKE 'NDB%';
    +------------+---------+
    | ENGINE     | SUPPORT |
    +------------+---------+
    | ndbcluster | YES     |
    | ndbinfo    | YES     |
    +------------+---------+
    

    如果未启用NDB支持,则上述查询将返回一个空集。有关更多信息,请参见第 28.3.13 节,“INFORMATION_SCHEMA ENGINES 表”。

  • SHOW VARIABLES LIKE 'NDB%'

    此语句提供了与NDB存储引擎相关的大多数服务器系统变量的列表及其值,如下所示:

    mysql> SHOW VARIABLES LIKE 'NDB%';
    +--------------------------------------+---------------------------------------+
    | Variable_name                        | Value                                 |
    +--------------------------------------+---------------------------------------+
    | ndb_allow_copying_alter_table        | ON                                    |
    | ndb_autoincrement_prefetch_sz        | 512                                   |
    | ndb_batch_size                       | 32768                                 |
    | ndb_blob_read_batch_bytes            | 65536                                 |
    | ndb_blob_write_batch_bytes           | 65536                                 |
    | ndb_clear_apply_status               | ON                                    |
    | ndb_cluster_connection_pool          | 1                                     |
    | ndb_cluster_connection_pool_nodeids  |                                       |
    | ndb_connectstring                    | 127.0.0.1                             |
    | ndb_data_node_neighbour              | 0                                     |
    | ndb_default_column_format            | FIXED                                 |
    | ndb_deferred_constraints             | 0                                     |
    | ndb_distribution                     | KEYHASH                               |
    | ndb_eventbuffer_free_percent         | 20                                    |
    | ndb_eventbuffer_max_alloc            | 0                                     |
    | ndb_extra_logging                    | 1                                     |
    | ndb_force_send                       | ON                                    |
    | ndb_fully_replicated                 | OFF                                   |
    | ndb_index_stat_enable                | ON                                    |
    | ndb_index_stat_option                | loop_enable=1000ms,loop_idle=1000ms,
    loop_busy=100ms,update_batch=1,read_batch=4,idle_batch=32,check_batch=8,
    check_delay=10m,delete_batch=8,clean_delay=1m,error_batch=4,error_delay=1m,
    evict_batch=8,evict_delay=1m,cache_limit=32M,cache_lowpct=90,zero_total=0      |
    | ndb_join_pushdown                    | ON                                    |
    | ndb_log_apply_status                 | OFF                                   |
    | ndb_log_bin                          | OFF                                   |
    | ndb_log_binlog_index                 | ON                                    |
    | ndb_log_empty_epochs                 | OFF                                   |
    | ndb_log_empty_update                 | OFF                                   |
    | ndb_log_exclusive_reads              | OFF                                   |
    | ndb_log_orig                         | OFF                                   |
    | ndb_log_transaction_id               | OFF                                   |
    | ndb_log_update_as_write              | ON                                    |
    | ndb_log_update_minimal               | OFF                                   |
    | ndb_log_updated_only                 | ON                                    |
    | ndb_metadata_check                   | ON                                    |
    | ndb_metadata_check_interval          | 60                                    |
    | ndb_metadata_sync                    | OFF                                   |
    | ndb_mgmd_host                        | 127.0.0.1                             |
    | ndb_nodeid                           | 0                                     |
    | ndb_optimization_delay               | 10                                    |
    | ndb_optimized_node_selection         | 3                                     |
    | ndb_read_backup                      | ON                                    |
    | ndb_recv_thread_activation_threshold | 8                                     |
    | ndb_recv_thread_cpu_mask             |                                       |
    | ndb_report_thresh_binlog_epoch_slip  | 10                                    |
    | ndb_report_thresh_binlog_mem_usage   | 10                                    |
    | ndb_row_checksum                     | 1                                     |
    | ndb_schema_dist_lock_wait_timeout    | 30                                    |
    | ndb_schema_dist_timeout              | 120                                   |
    | ndb_schema_dist_upgrade_allowed      | ON                                    |
    | ndb_show_foreign_key_mock_tables     | OFF                                   |
    | ndb_slave_conflict_role              | NONE                                  |
    | ndb_table_no_logging                 | OFF                                   |
    | ndb_table_temporary                  | OFF                                   |
    | ndb_use_copying_alter_table          | OFF                                   |
    | ndb_use_exact_count                  | OFF                                   |
    | ndb_use_transactions                 | ON                                    |
    | ndb_version                          | 524308                                |
    | ndb_version_string                   | ndb-8.0.35                            |
    | ndb_wait_connected                   | 30                                    |
    | ndb_wait_setup                       | 30                                    |
    | ndbinfo_database                     | ndbinfo                               |
    | ndbinfo_max_bytes                    | 0                                     |
    | ndbinfo_max_rows                     | 10                                    |
    | ndbinfo_offline                      | OFF                                   |
    | ndbinfo_show_hidden                  | OFF                                   |
    | ndbinfo_table_prefix                 | ndb$                                  |
    | ndbinfo_version                      | 524308                                |
    +--------------------------------------+---------------------------------------+
    

    查看更多信息,请参见第 7.1.8 节,“服务器系统变量”。

  • SELECT * FROM performance_schema.global_variables WHERE VARIABLE_NAME LIKE 'NDB%'

    这个语句相当于之前描述的SHOW VARIABLES语句,并提供几乎相同的输出,如下所示:

    mysql> SELECT * FROM performance_schema.global_variables
     ->   WHERE VARIABLE_NAME LIKE 'NDB%';
    +--------------------------------------+---------------------------------------+
    | VARIABLE_NAME                        | VARIABLE_VALUE                        |
    +--------------------------------------+---------------------------------------+
    | ndb_allow_copying_alter_table        | ON                                    |
    | ndb_autoincrement_prefetch_sz        | 512                                   |
    | ndb_batch_size                       | 32768                                 |
    | ndb_blob_read_batch_bytes            | 65536                                 |
    | ndb_blob_write_batch_bytes           | 65536                                 |
    | ndb_clear_apply_status               | ON                                    |
    | ndb_cluster_connection_pool          | 1                                     |
    | ndb_cluster_connection_pool_nodeids  |                                       |
    | ndb_connectstring                    | 127.0.0.1                             |
    | ndb_data_node_neighbour              | 0                                     |
    | ndb_default_column_format            | FIXED                                 |
    | ndb_deferred_constraints             | 0                                     |
    | ndb_distribution                     | KEYHASH                               |
    | ndb_eventbuffer_free_percent         | 20                                    |
    | ndb_eventbuffer_max_alloc            | 0                                     |
    | ndb_extra_logging                    | 1                                     |
    | ndb_force_send                       | ON                                    |
    | ndb_fully_replicated                 | OFF                                   |
    | ndb_index_stat_enable                | ON                                    |
    | ndb_index_stat_option                | loop_enable=1000ms,loop_idle=1000ms,
    loop_busy=100ms,update_batch=1,read_batch=4,idle_batch=32,check_batch=8,
    check_delay=10m,delete_batch=8,clean_delay=1m,error_batch=4,error_delay=1m,
    evict_batch=8,evict_delay=1m,cache_limit=32M,cache_lowpct=90,zero_total=0      |
    | ndb_join_pushdown                    | ON                                    |
    | ndb_log_apply_status                 | OFF                                   |
    | ndb_log_bin                          | OFF                                   |
    | ndb_log_binlog_index                 | ON                                    |
    | ndb_log_empty_epochs                 | OFF                                   |
    | ndb_log_empty_update                 | OFF                                   |
    | ndb_log_exclusive_reads              | OFF                                   |
    | ndb_log_orig                         | OFF                                   |
    | ndb_log_transaction_id               | OFF                                   |
    | ndb_log_update_as_write              | ON                                    |
    | ndb_log_update_minimal               | OFF                                   |
    | ndb_log_updated_only                 | ON                                    |
    | ndb_metadata_check                   | ON                                    |
    | ndb_metadata_check_interval          | 60                                    |
    | ndb_metadata_sync                    | OFF                                   |
    | ndb_mgmd_host                        | 127.0.0.1                             |
    | ndb_nodeid                           | 0                                     |
    | ndb_optimization_delay               | 10                                    |
    | ndb_optimized_node_selection         | 3                                     |
    | ndb_read_backup                      | ON                                    |
    | ndb_recv_thread_activation_threshold | 8                                     |
    | ndb_recv_thread_cpu_mask             |                                       |
    | ndb_report_thresh_binlog_epoch_slip  | 10                                    |
    | ndb_report_thresh_binlog_mem_usage   | 10                                    |
    | ndb_row_checksum                     | 1                                     |
    | ndb_schema_dist_lock_wait_timeout    | 30                                    |
    | ndb_schema_dist_timeout              | 120                                   |
    | ndb_schema_dist_upgrade_allowed      | ON                                    |
    | ndb_show_foreign_key_mock_tables     | OFF                                   |
    | ndb_slave_conflict_role              | NONE                                  |
    | ndb_table_no_logging                 | OFF                                   |
    | ndb_table_temporary                  | OFF                                   |
    | ndb_use_copying_alter_table          | OFF                                   |
    | ndb_use_exact_count                  | OFF                                   |
    | ndb_use_transactions                 | ON                                    |
    | ndb_version                          | 524308                                |
    | ndb_version_string                   | ndb-8.0.35                            |
    | ndb_wait_connected                   | 30                                    |
    | ndb_wait_setup                       | 30                                    |
    | ndbinfo_database                     | ndbinfo                               |
    | ndbinfo_max_bytes                    | 0                                     |
    | ndbinfo_max_rows                     | 10                                    |
    | ndbinfo_offline                      | OFF                                   |
    | ndbinfo_show_hidden                  | OFF                                   |
    | ndbinfo_table_prefix                 | ndb$                                  |
    | ndbinfo_version                      | 524308                                |
    +--------------------------------------+---------------------------------------+
    

    SHOW VARIABLES语句不同,可以选择单独的列。例如:

    mysql> SELECT VARIABLE_VALUE 
     ->   FROM performance_schema.global_variables
     ->   WHERE VARIABLE_NAME = 'ndb_force_send';
    +----------------+
    | VARIABLE_VALUE |
    +----------------+
    | ON             |
    +----------------+
    

    一个更有用的查询如下所示:

    mysql> SELECT VARIABLE_NAME AS Name, VARIABLE_VALUE AS Value
         >   FROM performance_schema.global_variables
         >   WHERE VARIABLE_NAME
         >     IN ('version', 'ndb_version',
         >       'ndb_version_string', 'ndbinfo_version');
    
    +--------------------+----------------+
    | Name               | Value          |
    +--------------------+----------------+
    | ndb_version        | 524317         |
    | ndb_version_string | ndb-8.0.29     |
    | ndbinfo_version    | 524317         |
    | version            | 8.0.29-cluster |
    +--------------------+----------------+
    4 rows in set (0.00 sec)
    

    更多信息,请参见第 29.12.15 节,“性能模式状态变量表”,以及第 7.1.8 节,“服务器系统变量”。

  • SHOW STATUS LIKE 'NDB%'

    这个语句一目了然地显示了 MySQL 服务器是否作为集群 SQL 节点运行,如果是的话,它提供了 MySQL 服务器的集群节点 ID、连接的集群管理服务器的主机名和端口,以及集群中的数据节点数量,如下所示:

    mysql> SHOW STATUS LIKE 'NDB%';
    +----------------------------------------------+-------------------------------+
    | Variable_name                                | Value                         |
    +----------------------------------------------+-------------------------------+
    | Ndb_metadata_detected_count                  | 0                             |
    | Ndb_cluster_node_id                          | 100                           |
    | Ndb_config_from_host                         | 127.0.0.1                     |
    | Ndb_config_from_port                         | 1186                          |
    | Ndb_number_of_data_nodes                     | 2                             |
    | Ndb_number_of_ready_data_nodes               | 2                             |
    | Ndb_connect_count                            | 0                             |
    | Ndb_execute_count                            | 0                             |
    | Ndb_scan_count                               | 0                             |
    | Ndb_pruned_scan_count                        | 0                             |
    | Ndb_schema_locks_count                       | 0                             |
    | Ndb_api_wait_exec_complete_count_session     | 0                             |
    | Ndb_api_wait_scan_result_count_session       | 0                             |
    | Ndb_api_wait_meta_request_count_session      | 1                             |
    | Ndb_api_wait_nanos_count_session             | 163446                        |
    | Ndb_api_bytes_sent_count_session             | 60                            |
    | Ndb_api_bytes_received_count_session         | 28                            |
    | Ndb_api_trans_start_count_session            | 0                             |
    | Ndb_api_trans_commit_count_session           | 0                             |
    | Ndb_api_trans_abort_count_session            | 0                             |
    | Ndb_api_trans_close_count_session            | 0                             |
    | Ndb_api_pk_op_count_session                  | 0                             |
    | Ndb_api_uk_op_count_session                  | 0                             |
    | Ndb_api_table_scan_count_session             | 0                             |
    | Ndb_api_range_scan_count_session             | 0                             |
    | Ndb_api_pruned_scan_count_session            | 0                             |
    | Ndb_api_scan_batch_count_session             | 0                             |
    | Ndb_api_read_row_count_session               | 0                             |
    | Ndb_api_trans_local_read_row_count_session   | 0                             |
    | Ndb_api_adaptive_send_forced_count_session   | 0                             |
    | Ndb_api_adaptive_send_unforced_count_session | 0                             |
    | Ndb_api_adaptive_send_deferred_count_session | 0                             |
    | Ndb_trans_hint_count_session                 | 0                             |
    | Ndb_sorted_scan_count                        | 0                             |
    | Ndb_pushed_queries_defined                   | 0                             |
    | Ndb_pushed_queries_dropped                   | 0                             |
    | Ndb_pushed_queries_executed                  | 0                             |
    | Ndb_pushed_reads                             | 0                             |
    | Ndb_last_commit_epoch_server                 | 37632503447571                |
    | Ndb_last_commit_epoch_session                | 0                             |
    | Ndb_system_name                              | MC_20191126162038             |
    | Ndb_api_event_data_count_injector            | 0                             |
    | Ndb_api_event_nondata_count_injector         | 0                             |
    | Ndb_api_event_bytes_count_injector           | 0                             |
    | Ndb_api_wait_exec_complete_count_slave       | 0                             |
    | Ndb_api_wait_scan_result_count_slave         | 0                             |
    | Ndb_api_wait_meta_request_count_slave        | 0                             |
    | Ndb_api_wait_nanos_count_slave               | 0                             |
    | Ndb_api_bytes_sent_count_slave               | 0                             |
    | Ndb_api_bytes_received_count_slave           | 0                             |
    | Ndb_api_trans_start_count_slave              | 0                             |
    | Ndb_api_trans_commit_count_slave             | 0                             |
    | Ndb_api_trans_abort_count_slave              | 0                             |
    | Ndb_api_trans_close_count_slave              | 0                             |
    | Ndb_api_pk_op_count_slave                    | 0                             |
    | Ndb_api_uk_op_count_slave                    | 0                             |
    | Ndb_api_table_scan_count_slave               | 0                             |
    | Ndb_api_range_scan_count_slave               | 0                             |
    | Ndb_api_pruned_scan_count_slave              | 0                             |
    | Ndb_api_scan_batch_count_slave               | 0                             |
    | Ndb_api_read_row_count_slave                 | 0                             |
    | Ndb_api_trans_local_read_row_count_slave     | 0                             |
    | Ndb_api_adaptive_send_forced_count_slave     | 0                             |
    | Ndb_api_adaptive_send_unforced_count_slave   | 0                             |
    | Ndb_api_adaptive_send_deferred_count_slave   | 0                             |
    | Ndb_slave_max_replicated_epoch               | 0                             |
    | Ndb_api_wait_exec_complete_count             | 4                             |
    | Ndb_api_wait_scan_result_count               | 7                             |
    | Ndb_api_wait_meta_request_count              | 172                           |
    | Ndb_api_wait_nanos_count                     | 1083548094028                 |
    | Ndb_api_bytes_sent_count                     | 4640                          |
    | Ndb_api_bytes_received_count                 | 109356                        |
    | Ndb_api_trans_start_count                    | 4                             |
    | Ndb_api_trans_commit_count                   | 1                             |
    | Ndb_api_trans_abort_count                    | 1                             |
    | Ndb_api_trans_close_count                    | 4                             |
    | Ndb_api_pk_op_count                          | 2                             |
    | Ndb_api_uk_op_count                          | 0                             |
    | Ndb_api_table_scan_count                     | 1                             |
    | Ndb_api_range_scan_count                     | 1                             |
    | Ndb_api_pruned_scan_count                    | 0                             |
    | Ndb_api_scan_batch_count                     | 1                             |
    | Ndb_api_read_row_count                       | 3                             |
    | Ndb_api_trans_local_read_row_count           | 2                             |
    | Ndb_api_adaptive_send_forced_count           | 1                             |
    | Ndb_api_adaptive_send_unforced_count         | 5                             |
    | Ndb_api_adaptive_send_deferred_count         | 0                             |
    | Ndb_api_event_data_count                     | 0                             |
    | Ndb_api_event_nondata_count                  | 0                             |
    | Ndb_api_event_bytes_count                    | 0                             |
    | Ndb_metadata_excluded_count                  | 0                             |
    | Ndb_metadata_synced_count                    | 0                             |
    | Ndb_conflict_fn_max                          | 0                             |
    | Ndb_conflict_fn_old                          | 0                             |
    | Ndb_conflict_fn_max_del_win                  | 0                             |
    | Ndb_conflict_fn_epoch                        | 0                             |
    | Ndb_conflict_fn_epoch_trans                  | 0                             |
    | Ndb_conflict_fn_epoch2                       | 0                             |
    | Ndb_conflict_fn_epoch2_trans                 | 0                             |
    | Ndb_conflict_trans_row_conflict_count        | 0                             |
    | Ndb_conflict_trans_row_reject_count          | 0                             |
    | Ndb_conflict_trans_reject_count              | 0                             |
    | Ndb_conflict_trans_detect_iter_count         | 0                             |
    | Ndb_conflict_trans_conflict_commit_count     | 0                             |
    | Ndb_conflict_epoch_delete_delete_count       | 0                             |
    | Ndb_conflict_reflected_op_prepare_count      | 0                             |
    | Ndb_conflict_reflected_op_discard_count      | 0                             |
    | Ndb_conflict_refresh_op_count                | 0                             |
    | Ndb_conflict_last_conflict_epoch             | 0                             |
    | Ndb_conflict_last_stable_epoch               | 0                             |
    | Ndb_index_stat_status                        | allow:1,enable:1,busy:0,
    loop:1000,list:(new:0,update:0,read:0,idle:0,check:0,delete:0,error:0,total:0),
    analyze:(queue:0,wait:0),stats:(nostats:0,wait:0),total:(analyze:(all:0,error:0),
    query:(all:0,nostats:0,error:0),event:(act:0,skip:0,miss:0),cache:(refresh:0,
    clean:0,pinned:0,drop:0,evict:0)),cache:(query:0,clean:0,drop:0,evict:0,
    usedpct:0.00,highpct:0.00)                                                     |
    | Ndb_index_stat_cache_query                   | 0                             |
    | Ndb_index_stat_cache_clean                   | 0                             |
    +----------------------------------------------+-------------------------------+
    

    如果 MySQL 服务器是使用NDB支持构建的,但当前未连接到集群,那么此语句的输出中的每一行都包含Value列的零或空字符串。

    参见第 15.7.7.37 节,“SHOW STATUS Statement”。

  • SELECT * FROM performance_schema.global_status WHERE VARIABLE_NAME LIKE 'NDB%'

    这个语句提供了类似于之前讨论的SHOW STATUS语句的输出。与SHOW STATUS不同的是,可以使用SELECT语句提取 SQL 中的数值,用于监控和自动化脚本。

    更多信息,请参见第 29.12.15 节,“性能模式状态变量表”。

  • SELECT * FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'NDB%'

    这个语句显示了与 NDB Cluster 相关的插件的信息,如版本、作者和许可证,如下所示:

    mysql> SELECT * FROM INFORMATION_SCHEMA.PLUGINS
         >     WHERE PLUGIN_NAME LIKE 'NDB%'\G
    *************************** 1\. row ***************************
               PLUGIN_NAME: ndbcluster
            PLUGIN_VERSION: 1.0
             PLUGIN_STATUS: ACTIVE
               PLUGIN_TYPE: STORAGE ENGINE
       PLUGIN_TYPE_VERSION: 80036.0
            PLUGIN_LIBRARY: NULL
    PLUGIN_LIBRARY_VERSION: NULL
             PLUGIN_AUTHOR: Oracle Corporation
        PLUGIN_DESCRIPTION: Clustered, fault-tolerant tables
            PLUGIN_LICENSE: GPL
               LOAD_OPTION: ON
    *************************** 2\. row ***************************
               PLUGIN_NAME: ndbinfo
            PLUGIN_VERSION: 0.1
             PLUGIN_STATUS: ACTIVE
               PLUGIN_TYPE: STORAGE ENGINE
       PLUGIN_TYPE_VERSION: 80036.0
            PLUGIN_LIBRARY: NULL
    PLUGIN_LIBRARY_VERSION: NULL
             PLUGIN_AUTHOR: Oracle Corporation
        PLUGIN_DESCRIPTION: MySQL Cluster system information storage engine
            PLUGIN_LICENSE: GPL
               LOAD_OPTION: ON
    *************************** 3\. row ***************************
               PLUGIN_NAME: ndb_transid_mysql_connection_map
            PLUGIN_VERSION: 0.1
             PLUGIN_STATUS: ACTIVE
               PLUGIN_TYPE: INFORMATION SCHEMA
       PLUGIN_TYPE_VERSION: 80036.0
            PLUGIN_LIBRARY: NULL
    PLUGIN_LIBRARY_VERSION: NULL
             PLUGIN_AUTHOR: Oracle Corporation
        PLUGIN_DESCRIPTION: Map between MySQL connection ID and NDB transaction ID
            PLUGIN_LICENSE: GPL
               LOAD_OPTION: ON
    

    你也可以使用SHOW PLUGINS语句来显示这些信息,但该语句的输出不容易过滤。另请参阅 MySQL 插件 API,其中描述了PLUGINS表中信息的获取位置和方式。

你还可以查询ndbinfo信息数据库中的表,获取关于许多 NDB 集群操作的实时数据。参见 Section 25.6.16, “ndbinfo: The NDB Cluster Information Database”。

25.6.20 NDB Cluster 安全性问题

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-security.html

25.6.20.1 NDB Cluster 安全性和网络问题

25.6.20.2 NDB Cluster 和 MySQL 权限

25.6.20.3 NDB Cluster 和 MySQL 安全程序

这一部分讨论了在设置和运行 NDB Cluster 时需要考虑的安全性问题。

本节涵盖的主题包括以下内容:

  • NDB Cluster 和网络安全问题

  • 与安全运行 NDB Cluster 相关的配置问题

  • NDB Cluster 和 MySQL 权限系统

  • 适用于 NDB Cluster 的 MySQL 标准安全程序

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-security-networking-issues.html

25.6.20.1 NDB Cluster 安全性和网络问题

在本节中,我们讨论与 NDB Cluster 相关的基本网络安全问题。非常重要的是要记住,NDB Cluster“开箱即用”并不安全;您或您的网络管理员必须采取适当措施,确保您的集群在网络上不会受到威胁。

集群通信协议本质上是不安全的,在集群节点之间的通信中不使用加密或类似的安全措施。由于网络速度和延迟直接影响集群的效率,因此不建议在节点之间的网络连接中使用 SSL 或其他加密,因为这些方案会导致通信变慢。

同样,对于控制 API 节点访问 NDB Cluster,也不使用任何身份验证。与加密一样,强加身份验证要求的开销会对集群性能产生不利影响。

另外,在访问集群时,以下两者之一的源 IP 地址没有检查:

  • SQL 或 API 节点使用config.ini文件中空的[mysqld][api]部分创建的“空闲插槽”

    这意味着,如果config.ini文件中有任何空的[mysqld][api]部分,那么任何知道管理服务器主机名(或 IP 地址)和端口的 API 节点(包括 SQL 节点)都可以连接到集群并访问其数据而不受限制。(有关此及相关问题的更多信息,请参阅第 25.6.20.2 节,“NDB Cluster 和 MySQL 权限”。)

    注意

    您可以通过为config.ini文件中所有[mysqld][api]部分指定HostName参数来对 SQL 和 API 节点访问集群进行一些控制。然而,这也意味着,如果您希望从以前未使用的主机连接 API 节点到集群,您需要在config.ini文件中添加一个包含其主机名的[api]部分。

    更多信息可在本章的其他地方找到关于HostName参数的信息。还请参阅第 25.4.1 节,“NDB Cluster 的快速测试设置”,以获取使用HostName与 API 节点的配置示例。

  • 任何ndb_mgm客户端

    这意味着任何被给予管理服务器主机名(或 IP 地址)和端口(如果不是标准端口)的集群管理客户端都可以连接到集群并执行任何管理客户端命令。这包括ALL STOPSHUTDOWN等命令。

出于这些原因,有必要在网络层面保护集群。对于集群来说,最安全的网络配置是将集群节点之间的连接与任何其他网络通信隔离开。可以通过以下任一方法实现这一点:

  1. 将集群节点保持在与任何公共网络物理隔离的网络上。这个选项是最可靠的;然而,实施成本最高。

    我们在这里展示了使用这种物理隔离网络的 NDB 集群设置的示例:

    图 25.7 带有硬件防火墙的 NDB 集群

    内容在周围的文本中描述。

    这种设置有两个网络,一个私有的(实线框)用于集群管理服务器和数据节点,一个公共的(虚线框)用于 SQL 节点所在。 (我们展示了管理和数据节点使用千兆交换机连接,因为这提供了最佳性能。)两个网络都受到硬件防火墙的保护,有时也称为基于网络的防火墙。

    这种网络设置是最安全的,因为没有数据包可以从网络外部到达集群的管理或数据节点,也没有集群的内部通信可以到达外部,除非通过 SQL 节点,只要 SQL 节点不允许任何数据包被转发。当然,这意味着所有 SQL 节点必须受到黑客攻击的保护。

    重要

    关于潜在的安全漏洞,SQL 节点与任何其他 MySQL 服务器没有区别。请参阅第 8.1.3 节,“使 MySQL 免受攻击者攻击”,了解您可以用来保护 MySQL 服务器的技术描述。

  2. 使用一个或多个软件防火墙(也称为主机防火墙)来控制从不需要访问集群的网络部分通过的数据包。在这种设置中,必须在集群中的每台主机上安装软件防火墙,否则可能会从本地网络外部访问。

    基于主机的选项是实施成本最低的,但纯粹依赖软件提供保护,因此最难保持安全。

    这种 NDB 集群的网络设置类型在这里说明:

    图 25.8 带有软件防火墙的 NDB 集群

    内容在周围的文本中描述。

    使用这种类型的网络设置意味着 NDB 集群主机有两个区域。每个集群主机必须能够与集群中的所有其他机器通信,但只有托管 SQL 节点(虚线框)的机器可以与外部进行任何联系,而那些位于包含数据节点和管理节点的区域(实线框)的机器必须与不属于集群的任何机器隔离。使用集群的应用程序和这些应用程序的用户被允许直接访问管理和数据节点主机。

    要实现这一点,您必须设置软件防火墙,根据每个集群主机计算机上运行的节点类型,限制流量到以下表中显示的类型或类型:

    表 25.68 主机防火墙集群配置中的节点类型

    节点类型允许的流量
    SQL 或 API 节点
    • 它源自管理或数据节点的 IP 地址(使用任何 TCP 或 UDP 端口)。

    • 它源自集群所在网络中,并位于应用程序正在使用的端口上。

    |

    数据节点或管理节点
    • 它源自管理或数据节点的 IP 地址(使用任何 TCP 或 UDP 端口)。

    • 它源自 SQL 或 API 节点的 IP 地址。

    |

    除了给定节点类型表中显示的流量之外的任何流量都应被拒绝。

    配置防火墙的具体细节因防火墙应用程序而异,超出了本手册的范围。iptables是一个非常常见和可靠的防火墙应用程序,通常与APF一起使用作为前端,以使配置更加简单。如果您选择实施此类 NDB 集群网络设置或在下一项中讨论的“混合”类型,您可以(也应该)查阅所使用软件防火墙的文档。

  3. 还可以采用前两种方法的组合,即同时使用网络和主机防火墙来保护集群。这在安全级别和成本方面介于前两种方案之间。这种类型的网络设置将集群置于硬件防火墙后面,但允许传入数据包穿过连接所有集群主机的路由器以到达 SQL 节点。

    一个可能的 NDB 集群网络部署示例,使用硬件和软件防火墙的组合如下所示:

    图 25.9 NDB 集群与硬件和软件防火墙的组合

    内容在周围文本中描述。

    在这种情况下,您可以设置硬件防火墙规则,拒绝除 SQL 节点和 API 节点之外的任何外部流量,然后仅允许它们在应用程序所需的端口上通信。

无论您使用何种网络配置,都要记住,从保持集群安全的角度来看,您的目标始终是一样的——防止任何不必要的流量到达集群,同时确保集群中节点之间的最有效通信。

因为 NDB 集群需要大量端口用于节点之间的通信,推荐的选项是使用隔离网络。这是防止不必要流量到达集群的最简单方式。

注意

如果您希望远程管理 NDB 集群(即从本地网络之外),推荐的方法是使用ssh或其他安全登录 shell 访问 SQL 节点主机。从这个主机上,您可以安全地运行管理客户端,从集群自己的本地网络中访问管理服务器。

即使在理论上可以这样做,也不建议使用ndb_mgm直接从集群所在的本地网络之外管理集群。由于管理客户端和管理服务器之间既没有认证也没有加密,这代表了一种极不安全的管理集群方式,几乎肯定会在早晚被破坏。

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-security-mysql-privileges.html

25.6.20.2 NDB Cluster 和 MySQL 特权

在本节中,我们讨论了 MySQL 特权系统在与 NDB Cluster 的关系中的工作原理,以及这对保持 NDB Cluster 安全性的影响。

标准的 MySQL 特权适用于 NDB Cluster 表。这包括在数据库、表和列级别授予的所有 MySQL 特权类型(SELECT特权、UPDATE特权、DELETE特权等),与任何其他 MySQL 服务器一样,用户和特权信息存储在mysql系统数据库中。用于在NDB表、包含这些表的数据库以及这些表中的列上授予和撤销特权的 SQL 语句在所有方面与用于涉及任何(其他)MySQL 存储引擎的数据库对象的GRANTREVOKE语句相同。对于CREATE USERDROP USER语句也是如此。

重要的是要记住,默认情况下,MySQL 授权表使用InnoDB存储引擎。因此,这些表通常不会在充当 NDB Cluster 中 SQL 节点的 MySQL 服务器之间复制或共享。换句话说,默认情况下,用户及其特权的更改不会在 SQL 节点之间自动传播。如果需要,您可以启用 NDB Cluster SQL 节点之间的 MySQL 用户和特权同步;有关详细信息,请参见第 25.6.13 节“特权同步和 NDB_STORED_USER”。

相反,因为 MySQL 中没有拒绝特权的方法(特权可以被撤销或者一开始就不授予,但不能被明确拒绝),因此没有办法在一个 SQL 节点上对NDB表进行特殊保护,使其免受在另一个 SQL 节点上具有特权的用户的影响;即使您没有使用用户特权的自动分发,这也是如此。这一点的明显例子是 MySQL 的root账户,它可以对任何数据库对象执行任何操作。结合config.ini文件中空的[mysqld][api]部分,这个账户可能特别危险。要理解原因,请考虑以下情景:

  • config.ini 文件至少包含一个空的 [mysqld][api] 部分。这意味着 NDB 集群管理服务器不会检查 MySQL 服务器(或其他 API 节点)访问 NDB 集群的主机。

  • 没有防火墙,或者防火墙无法阻止外部主机访问 NDB 集群。

  • NDB 集群管理服务器的主机名或 IP 地址已知或可以从网络外部确定。

如果这些条件成立,那么任何人在任何地方都可以启动一个带有 --ndbcluster --ndb-connectstring=*management_host* 的 MySQL 服务器,并访问这个 NDB 集群。使用 MySQL 的 root 账户,这个人可以执行以下操作:

  • 执行元数据语句,比如SHOW DATABASES语句(获取服务器上所有NDB数据库的列表)或SHOW TABLES FROM *some_ndb_database*语句(获取给定数据库中所有NDB表的列表)

  • 在任何发现的表上运行任何合法的 MySQL 语句,比如:

    • SELECT * FROM *some_table*TABLE *some_table* 从任意表中读取所有数据

    • DELETE FROM *some_table* 或 TRUNCATE TABLE 删除表中的所有数据

    • DESCRIBE *some_table*SHOW CREATE TABLE *some_table* 确定表结构

    • UPDATE *some_table* SET *column1* = *some_value* 用“垃圾”数据填充表列;这实际上可能造成比简单删除所有数据更大的损害

      更加隐匿的变种可能包括以下语句:

      UPDATE *some_table* SET *an_int_column* = *an_int_column* + 1
      

      或者

      UPDATE *some_table* SET *a_varchar_column* = REVERSE(*a_varchar_column*)
      

      这样的恶意语句仅受攻击者想象力的限制。

    唯一安全的表将是使用非 NDB 存储引擎创建的表,因此对于“流氓” SQL 节点不可见。

    一个能够以 root 身份登录的用户也可以访问 INFORMATION_SCHEMA 数据库及其表,从而获取关于存储在 INFORMATION_SCHEMA 中的数据库、表、存储过程、定时事件以及其他数据库对象的信息。

    对于不使用共享权限的情况,最好为不同的 NDB 集群 SQL 节点上的 root 账户使用不同的密码。

总的来说,如果直接从本地网络之外可以访问 NDB 集群,那么你无法拥有一个安全的 NDB 集群。

重要提示

永远不要将 MySQL root 账户密码留空。无论是在作为 NDB 集群 SQL 节点运行 MySQL 还是作为独立(非集群)MySQL 服务器运行时,都是正确的,应该在将 MySQL 服务器配置为 NDB 集群中的 SQL 节点之前作为 MySQL 安装过程的一部分来完成。

如果需要在 SQL 节点之间同步mysql系统表,可以使用标准的 MySQL 复制来实现,或者使用脚本在 MySQL 服务器之间复制表条目。用户及其权限可以使用NDB_STORED_USER特权进行共享和保持同步。

摘要。 关于 MySQL 特权系统与 NDB 集群相关的最重要的要点如下:

  1. 在一个 SQL 节点上建立的用户和权限不会自动存在或生效于集群中的其他 SQL 节点。反之,在集群中的一个 SQL 节点上删除用户或权限并不会从任何其他 SQL 节点中删除用户或权限。

  2. 你可以使用NDB_STORED_USER在 SQL 节点之间共享 MySQL 用户和权限。

  3. 一旦在 NDB 集群中的一个 SQL 节点上为一个 MySQL 用户授予了对NDB表的权限,该用户可以“看到”该表中的任何数据,无论数据来自哪个 SQL 节点,即使该用户没有共享。

译文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-security-mysql-security-procedures.html

25.6.20.3 NDB Cluster 和 MySQL 安全程序

在本节中,我们将讨论 MySQL 标准安全程序,因为它们适用于运行 NDB Cluster。

一般来说,运行 MySQL 安全的任何标准程序也适用于作为 NDB Cluster 的一部分运行 MySQL 服务器。首先,您应始终将 MySQL 服务器作为 mysql 操作系统用户运行;这与在标准(非集群)环境中运行 MySQL 没有区别。mysql 系统帐户应该是唯一且明确定义的。幸运的是,这是新 MySQL 安装的默认行为。您可以使用系统命令(例如下面显示的命令)验证 mysqld 进程是否以 mysql 操作系统用户身份运行:

$> ps aux | grep mysql
root     10467  0.0  0.1   3616  1380 pts/3    S    11:53   0:00 \
  /bin/sh ./mysqld_safe --ndbcluster --ndb-connectstring=localhost:1186
mysql    10512  0.2  2.5  58528 26636 pts/3    Sl   11:53   0:00 \
  /usr/local/mysql/libexec/mysqld --basedir=/usr/local/mysql \
  --datadir=/usr/local/mysql/var --user=mysql --ndbcluster \
  --ndb-connectstring=localhost:1186 --pid-file=/usr/local/mysql/var/mothra.pid \
  --log-error=/usr/local/mysql/var/mothra.err
jon      10579  0.0  0.0   2736   688 pts/0    S+   11:54   0:00 grep mysql

如果 mysqld 进程以除 mysql 之外的任何其他用户身份运行,您应立即关闭它,并以 mysql 用户重新启动它。如果此用户在系统上不存在,则应创建 mysql 用户帐户,并使此用户成为 mysql 用户组的一部分;在这种情况下,您还应确保此系统上的 MySQL 数据目录(使用 --datadir 选项设置为 mysqld)由 mysql 用户拥有,并且 SQL 节点的 my.cnf 文件在 [mysqld] 部分包含 user=mysql。或者,您可以在命令行上使用 --user=mysql 启动 MySQL 服务器进程,但最好使用 my.cnf 选项,因为您可能会忘记使用命令行选项,从而无意中以其他用户身份运行 mysqldmysqld_safe 启动脚本会强制 MySQL 以 mysql 用户身份运行。

重要提示

永远不要以系统根用户身份运行 mysqld。这样做意味着 MySQL 可能读取系统上的任何文件,因此——如果 MySQL 受到攻击——攻击者可能读取任何文件。

如前一节所述(请参阅 Section 25.6.20.2, “NDB Cluster and MySQL Privileges”),您应该在 MySQL 服务器运行后立即设置 root 密码。您还应删除默认安装的匿名用户帐户。您可以使用以下语句��行这些任务:

$> mysql -u root

mysql> UPDATE mysql.user
 ->     SET Password=PASSWORD('*secure_password*')
 ->     WHERE User='root';

mysql> DELETE FROM mysql.user
 ->     WHERE User='';

mysql> FLUSH PRIVILEGES;

在执行DELETE语句时要非常小心,不要忽略WHERE子句,否则会风险删除所有MySQL 用户。一旦修改了mysql.user表,请务必立即运行FLUSH PRIVILEGES语句,以便更改立即生效。没有FLUSH PRIVILEGES,更改将在下次服务器重新启动时才生效。

注意

许多 NDB 集群实用程序,如ndb_show_tablesndb_descndb_select_all也可以在没有身份验证的情况下工作,并且可以显示表名、模式和数据。默认情况下,这些程序在 Unix 风格系统上以权限wxr-xr-x(755)安装,这意味着任何可以访问mysql/bin目录的用户都可以执行它们。

有关这些实用程序的更多信息,请参见第 25.5 节,“NDB 集群程序”。

25.7 NDB 集群复制

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-replication.html

25.7.1 NDB 集群复制:缩写和符号

25.7.2 NDB 集群复制的一般要求

25.7.3 NDB 集群复制中已知问题

25.7.4 NDB 集群复制模式和表

25.7.5 准备 NDB 集群进行复制

25.7.6 启动 NDB 集群复制(单一复制通道)

25.7.7 使用两个复制通道进行 NDB 集群复制

25.7.8 使用 NDB 集群复制实现故障切换

25.7.9 使用 NDB 集群复制进行 NDB 集群备份

25.7.10 NDB 集群复制:双向和循环复制

25.7.11 使用多线程应用程序的 NDB 集群复制

25.7.12 NDB 集群复制冲突解决

NDB 集群支持异步复制,通常简称为“复制”。本节解释了如何设置和管理一个配置,其中一组计算机作为 NDB 集群操作,复制到第二台计算机或一组计算机。我们假定读者在标准 MySQL 复制方面有一定了解,如本手册的其他地方所述。 (参见 第十九章,复制).

注意

NDB 集群不支持使用 GTID 进行复制;半同步复制和组复制也不受 NDB 存储引擎支持。

正常(非集群)复制涉及源服务器和副本服务器,源被命名为源是因为要复制的操作和数据源自它,而副本是这些操作和数据的接收者。在 NDB Cluster 中,复制在概念上非常相似,但在实践中可能更加复杂,因为它可以扩展到涵盖许多不同的配置,包括在两个完整集群之间进行复制。虽然 NDB Cluster 本身依赖于NDB存储引擎进行集群功能,但不需要使用NDB作为副本的复制表的存储引擎(请参见从 NDB 到其他存储引擎的复制)。然而,为了最大的可用性,可以(并且最好)从一个 NDB Cluster 复制到另一个 NDB Cluster,我们将讨论这种情况,如下图所示:

图 25.10 NDB Cluster 到集群复制布局

![大部分内容在周围的文本中有描述。它展示了 MySQL 源是如何复制的。副本的不同之处在于它显示了一个 I/O(接收器)线程指向一个中继二进制日志,该中继二进制日志指向一个 SQL(应用程序)线程。此外,虽然二进制日志在源服务器上指向和从 NDBCLUSTER 引擎,但在副本上直接指向一个 SQL 节点(MySQL 服务器)。

在这种情况下,复制过程是一个连续记录源集群状态并保存到副本集群的过程。这个过程是通过一个特殊的线程完成的,称为 NDB 二进制日志注入器线程,它在每个 MySQL 服务器上运行并生成一个二进制日志(binlog)。该线程确保将产生二进制日志的集群中的所有更改(而不仅仅是通过 MySQL Server 实现的那些更改)以正确的序列化顺序插入到二进制日志中。我们将 MySQL 源和副本服务器称为复制服务器或复制节点,它们之间的数据流或通信线路称为复制通道。

有关使用 NDB Cluster 和 NDB Cluster Replication 执行时点恢复的信息,请参见 Section 25.7.9.2,“使用 NDB Cluster Replication 进行时点恢复”。

NDB API 复制状态变量。 NDB API 计数器可以提供增强的监控能力,用于监视副本集群。这些计数器实现为 NDB 统计 _slave 状态变量,如在 SHOW STATUS 的输出中所见,或者在连接到充当 NDB 集群复制中的副本的 MySQL 服务器的 mysql 客户端会话中对 Performance Schema session_statusglobal_status 表进行查询的结果中。通过比较执行影响复制的 NDB 表的语句之前和之后这些状态变量的值,您可以观察副本在 NDB API 级别上采取的相应操作,这在监视或故障排除 NDB 集群复制时可能很有用。第 25.6.15 节,“NDB API 统计计数器和变量”提供了额外信息。

从 NDB 复制到非 NDB 表。 可以将 NDB 表从作为复制源的 NDB 集群复制到使用其他 MySQL 存储引擎(如 InnoDBMyISAM)的表上,这些表位于一个副本 mysqld 上。这受到一些条件的限制;请参阅从 NDB 复制到其他存储引擎和从 NDB 复制到非事务性存储引擎以获取更多信息。

25.7.1 NDB 集群复制:缩写和符号

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-replication-abbreviations.html

在本节中,我们使用以下缩写或符号来指代源集群和副本集群,以及在集群或集群节点上运行的进程和命令:

表 25.69 本节中使用的缩写,指的是源集群和副本集群,以及在集群节点上运行的进程和命令

符号或缩写描述(指的是…)
S充当(主要)复制源的集群
R充当(主要)副本的集群
shell*S*>在源集群上发出的 shell 命令
mysql*S*>在作为 SQL 节点运行的单个 MySQL 服务器上发出的 MySQL 客户端命令
mysql*S**>在参与复制源集群的所有 SQL 节点上发出的 MySQL 客户端命令
shell*R*>在副本集群上发出的 shell 命令
mysql*R*>在副本集群上作为 SQL 节点运行的单个 MySQL 服务器上发出的 MySQL 客户端命令
mysql*R**>在参与副本集群的所有 SQL 节点上发出的 MySQL 客户端命令
C主要复制通道
C'次要复制通道
S'次要复制源
R'次要副本
符号或缩写描述(指的是…)

25.7.2 NDB Cluster Replication 的一般要求

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-replication-general.html

一个复制通道需要两个充当复制服务器的 MySQL 服务器(分别用于源和副本)。例如,这意味着在具有两个复制通道的复制设置中(为提供冗余的额外通道),应该总共有四个复制节点,每个集群两个。

正如本节和后续节中所述的 NDB Cluster 的复制取决于基于行的复制。这意味着复制源 MySQL 服务器必须使用--binlog-format=ROW--binlog-format=MIXED运行,如 Section 25.7.6, “Starting NDB Cluster Replication (Single Replication Channel)”")中所述。有关基于行的复制的一般信息,请参见 Section 19.2.1, “Replication Formats”。

重要提示

如果您尝试使用--binlog-format=STATEMENT与 NDB Cluster Replication,由于源集群上的ndb_binlog_index表和副本集群上的ndb_apply_status表的epoch列未更新,复制将无法正常工作(参见 Section 25.7.4, “NDB Cluster Replication Schema and Tables”)。相反,只有作为复制源的 MySQL 服务器上的更新会传播到副本,源集群中任何其他 SQL 节点的更新都不会被复制。

--binlog-format选项的默认值为MIXED

在任一集群中用于复制的每个 MySQL 服务器必须在所有参与任一集群的 MySQL 复制服务器中具有唯一标识(源和副本集群上不能共享相同 ID 的复制服务器)。这可以通过使用--server-id=*id*选项启动每个 SQL 节点来完成,其中*id*是唯一的整数。尽管这并非绝对必要,但我们在本讨论中假设所有 NDB Cluster 二进制文件都是相同版本。

在 MySQL 复制中通常是真实的,涉及的两个 MySQL 服务器(mysqld 进程)必须在复制协议版本和它们支持的 SQL 功能集方面彼此兼容(请参见 Section 19.5.2,“MySQL 版本之间的复制兼容性”)。由于 NDB 集群和 MySQL Server 8.0 发行版之间的二进制文件之间的差异,NDB 集群复制有额外的要求,即两个 mysqld 二进制文件必须来自 NDB 集群发行版。确保 mysqld 服务器兼容的最简单和最容易的方法是对所有源和副本 mysqld 二进制文件使用相同的 NDB 集群发行版。

我们假设副本服务器或集群专用于复制源集群,并且没有其他数据存储在其中。

所有被复制的 NDB 表必须使用 MySQL 服务器和客户端创建。使用 NDB API 创建的表和其他数据库对象(例如,使用 Dictionary::createTable())对 MySQL 服务器不可见,因此不会被复制。通过 NDB API 应用程序对使用 MySQL 服务器创建的现有表的更新可以被复制。

注意

可以使用基于语句的复制来复制 NDB 集群。但是,在这种情况下,以下限制适用:

  • 所有对作为源的集群上数据行的更新必须指向单个 MySQL 服务器。

  • 不可能使用多个同时的 MySQL 复制进程来复制集群。

  • 只有在 SQL 级别进行的更改才会被复制。

这些是基于语句的复制相对于基于行的复制的其他限制;有关两种复制格式之间差异的更具体信息,请参见 Section 19.2.1.1,“基于语句和基于行的复制的优缺点”。

25.7.3 NDB 集群复制中已知问题

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-replication-issues.html

本节讨论在使用 NDB 集群复制时可能遇到的已知问题或问题。

源和复制品之间的连接丢失。 连接丢失可能发生在源集群 SQL 节点和复制集群 SQL 节点之间,也可能发生在源 SQL 节点和源集群的数据节点之间。在后一种情况下,这不仅可能是由于物理连接丢失(例如,网络电缆断开),还可能是由于数据节点事件缓冲区溢出;如果 SQL 节点响应过慢,可能会被集群丢弃(通过调整MaxBufferedEpochsTimeBetweenEpochs配置参数,在一定程度上可以控制这种情况)。如果发生这种情况,完全有可能在源集群中插入新数据而不记录在源 SQL 节点的二进制日志中。因此,为了保证高可用性,非常重要的是维护备份复制通道,监视主要通道,并在必要时切换到次要复制通道,以保持复制集群与源的同步。NDB 集群不设计为自行执行此类监控;为此,需要外部应用程序。

当源 SQL 节点连接或重新连接到源集群时,源 SQL 节点会发出“gap”事件。(“gap”事件是一种“事故事件”的一种,表示发生了影响数据库内容但不容易表示为一组更改的事件。事故的例子包括服务器故障、数据库重新同步、某些软件更新和某些硬件更改。)当复制品在复制日志中遇到间隙时,它会停止并显示错误消息。此消息可在SHOW REPLICA STATUS的输出中找到(在 NDB 8.0.22 之前,请使用SHOW SLAVE STATUS),并指示 SQL 线程由于在复制流中注册的事件而停止,并且需要手动干预。有关在这种情况下应该采取的措施的更多信息,请参见第 25.7.8 节,“使用 NDB 集群复制实现故障转移”。

重要

因为 NDB 集群本身并不设计用于监视复制状态或提供故障转移,如果副本服务器或集群需要高可用性,则必须设置多个复制线路,监视主复制线路上的源mysqld,并准备在必要时切换到次要线路。这必须手动完成,或可能通过第三方应用程序完成。有关实施此类设置的信息,请参见第 25.7.7 节,“使用两个复制通道进行 NDB 集群复制”,以及第 25.7.8 节,“使用 NDB 集群复制实现故障转移”。

如果从独立的 MySQL 服务器复制到 NDB 集群,则通常一个通道就足够了。

循环复制。 NDB 集群复制支持循环复制,如下例所示。复制设置涉及三个 NDB 集群,编号为 1、2 和 3,其中集群 1 充当集群 2 的复制源,集群 2 充当集群 3 的源,集群 3 充当集群 1 的源,从而完成循环。每个 NDB 集群都有两个 SQL 节点,SQL 节点 A 和 B 属于集群 1,SQL 节点 C 和 D 属于集群 2,SQL 节点 E 和 F 属于集群 3。

使用这些集群进行循环复制时,需要满足以下条件:

  • 所有源和副本集群上的 SQL 节点都是相同的。

  • 所有充当源和副本的 SQL 节点都启用了系统变量log_replica_updates(NDB 8.0.26 及更高版本)或log_slave_updates(NDB 8.0.26 之前)。

这种循环复制设置类型如下图所示:

图 25.11 NDB 集群循环复制,所有源均为副本

周围文本描述了一些内容。图表显示了三个集群,每个集群有两个节点。连接不同集群中 SQL 节点的箭头说明所有源也是副本。

在这种情况下,集群 1 中的 SQL 节点 A 复制到集群 2 中的 SQL 节点 C;集群 2 中的 SQL 节点 C 复制到集群 3 中的 SQL 节点 E;SQL 节点 E 复制到 SQL 节点 A。换句话说,复制线路(图表中的曲线箭头表示)直接连接所有用作源和副本的 SQL 节点。

还应该可以设置循环复制,其中并非所有源 SQL 节点也是副本,如下所示:

图 25.12 NDB 集群循环复制,其中并非所有源均为副本

周围文本描述了一些内容。图表显示了三个集群,每个集群有两个节点。连接不同集群中的 SQL 节点的箭头说明并非所有源都是副本。

在这种情况下,每个集群中的不同 SQL 节点被用作源和副本。但是,您应该启用任何 SQL 节点的log_replica_updateslog_slave_updates系统变量。对于 NDB Cluster 的这种循环复制方案,其中复制线(在图中由曲线箭头表示)是不连续的,应该是可能的,但必须注意的是,这种方案尚未经过彻底测试,因此仍然被视为实验性。

注意

NDB 存储引擎使用幂等执行模式,可以抑制重复键和其他错误,否则会破坏 NDB Cluster 的循环复制。这相当于将系统变量replica_exec_modeslave_exec_mode的全局值设置为IDEMPOTENT,尽管在 NDB Cluster 复制中这并不是必需的,因为 NDB Cluster 会自动设置此变量并忽略任何显式设置的尝试。

NDB Cluster 复制和主键。 在节点故障的情况下,复制没有主键的NDB表可能仍会出现错误,因为在这种情况下可能会插入重复行。因此,强烈建议所有被复制的NDB表都有明确的主键。

NDB Cluster 复制和唯一键。 在较旧版本的 NDB Cluster 中,更新NDB表的唯一键列的操作在复制时可能会导致重复键错误。通过将唯一键检查推迟到所有表行更新执行之后,解决了在NDB表之间的复制中的此问题。

目前,只有NDB支持以这种方式推迟约束。因此,当从NDB复制到其他存储引擎(如InnoDBMyISAM)时,仍不支持唯一键的更新。

在没有延迟检查唯一键更新的情况下复制时遇到的问题可以使用 NDB 表,例如 t,在源上创建和填充(并传输到不支持延迟唯一键更新的副本)来说明:

CREATE TABLE t (
    p INT PRIMARY KEY,
    c INT,
    UNIQUE KEY u (c)
)   ENGINE NDB;

INSERT INTO t
    VALUES (1,1), (2,2), (3,3), (4,4), (5,5);

下面的 UPDATE 语句在源上成功,因为受影响的行是按照 ORDER BY 选项确定的顺序处理的,作用于整个表:

UPDATE t SET c = c - 1 ORDER BY p;

相同的语句在副本上失败,因为行更新的顺序是逐个分区执行的,而不是整个表。

注意

每个 NDB 表在创建时都会隐式按键进行分区。有关更多信息,请参见 26.2.5 节“KEY 分区”。

不支持 GTIDs。 使用全局事务 ID 进行复制与 NDB 存储引擎不兼容,也不受支持。启用 GTIDs 可能会导致 NDB Cluster 复制失败。

多线程副本。 以前,NDB Cluster 不支持多线程副本。此限制在 NDB 8.0.33 中已移除。

要在 NDB 8.0.33 及更高版本的副本上启用多线程,需要执行以下步骤:

  1. 在启动源 mysqld 时,将 --ndb-log-transaction-dependency 设置为 ON

  2. 同样在源 mysqld 上,将 binlog_transaction_dependency_tracking 设置为 WRITESET。这可以在 mysqld 进程运行时完成。

  3. 要确保副本使用多个工作线程,将 replica_parallel_workers 的值设置大于 1。默认值为 4,可以在运行时更改副本上的值。

在 NDB 8.0.26 之前,设置任何与多线程副本相关的系统变量,如 replica_parallel_workersslave_parallel_workers,以及 replica_checkpoint_groupslave_checkpoint_group(或等效的 mysqld 启动选项)完全被忽略,没有任何效果。

在 NDB 8.0.27 到 NDB 8.0.32 中,replica_parallel_workers必须设置为 0。在这些版本中,如果在启动时将其设置为其他任何值,NDB会将其更改为 0,并在mysqld服务器日志文件中写入一条消息。这个限制在 NDB 8.0.33 中也被解除。

使用–initial 重新启动。 使用--initial选项重新启动集群会导致 GCI 和时代号的序列从0重新开始。(这通常适用于 NDB 集群,不仅限于涉及集群的复制场景。)在这种情况下,涉及复制的 MySQL 服务器应该重新启动。之后,您应该使用RESET MASTERRESET REPLICA(在 NDB 8.0.22 之前,使用RESET SLAVE)语句清除无效的ndb_binlog_indexndb_apply_status表。

从 NDB 复制到其他存储引擎。 可以将源上的NDB表复制到副本上使用不同存储引擎的表,考虑到这里列出的限制:

  • 不支持多源和循环复制(源和副本上的表必须都使用NDB存储引擎才能正常工作)。

  • 在副本上使用不执行表的二进制日志记录的存储引擎需要特殊处理。

  • 在副本上使用非事务性存储引擎处理表格也需要特殊处理。

  • mysqld必须使用--ndb-log-update-as-write=0--ndb-log-update-as-write=OFF启动。

接下来的几段提供了关于刚才描述的每个问题的额外信息。

不支持将 NDB 复制到其他存储引擎的多源。 对于从NDB到不同存储引擎的复制,两个数据库之间的关系必须是一对一。这意味着 NDB 集群和其他存储引擎之间不支持双向或循环复制。

此外,在从 NDB 复制到不同存储引擎的副本时,不可能配置多个复制通道。 (NDB 集群数据库 可以 同时复制到多个 NDB 集群数据库。)如果源使用 NDB 表,则仍然可以让多个 MySQL 服务器维护所有更改的二进制日志,但是对于副本更改源(故障转移),新的源-副本关系必须在副本上明确定义。

将 NDB 表复制到不执行二进制日志记录的存储引擎。 如果尝试从 NDB 集群复制到使用不处理自己二进制日志的存储引擎的副本,则复制过程将因错误 Binary logging not possible … Statement cannot be written atomically since more than one engine involved and at least one engine is self-logging (Error 1595) 而中止。可以通过以下一种方式解决此问题:

  • 在副本上关闭二进制日志记录。 可以通过设置 sql_log_bin = 0 来实现。

  • 更改用于 mysql.ndb_apply_status 表的存储引擎。 使该表使用一个不处理自己二进制日志的引擎也可以消除冲突。可以通过在副本上发出类似 ALTER TABLE mysql.ndb_apply_status ENGINE=MyISAM 的语句来完成此操作。在副本上使用除 NDB 之外的存储引擎时,这样做是安全的,因为您不需要担心保持多个副本同步。

  • 在副本上过滤掉对 mysql.ndb_apply_status 表的更改。 可以通过使用 --replicate-ignore-table=mysql.ndb_apply_status 来启动副本来完成此操作。如果需要忽略其他表的复制更改,您可能希望使用适当的 --replicate-wild-ignore-table 选项。

重要提示

在从一个 NDB 集群复制到另一个 NDB 集群时,不应禁用 mysql.ndb_apply_status 的复制或二进制日志记录,也不应更改此表使用的存储引擎。有关详细信息,请参阅 NDB 集群之间复制和二进制日志过滤规则。

从 NDB 复制到非事务性存储引擎。 当从NDB复制到非事务性存储引擎(如MyISAM)时,当复制INSERT ... ON DUPLICATE KEY UPDATE语句时,可能会遇到不必要的重复键错误。您可以通过使用--ndb-log-update-as-write=0来抑制这些错误,该选项强制将更新记录为写入,而不是更新。

NDB 集群之间的复制和二进制日志过滤规则。 如果您使用任何--replicate-do-*--replicate-ignore-*--binlog-do-db--binlog-ignore-db选项来过滤正在复制的数据库或表,您必须注意不要阻止mysql.ndb_apply_status的复制或二进制日志记录,这对于 NDB 集群之间的复制正常运行是必需的。特别是,您必须牢记以下内容:

  1. 使用--replicate-do-db=*db_name*(以及没有其他--replicate-do-*--replicate-ignore-*选项)意味着只有数据库*db_name*中的表会被复制。在这种情况下,您还应该使用--replicate-do-db=mysql--binlog-do-db=mysql,或--replicate-do-table=mysql.ndb_apply_status来确保在副本上填充mysql.ndb_apply_status

    使用--binlog-do-db=*db_name*(以及没有其他--binlog-do-db选项)意味着只有数据库*db_name*中的表的更改会被写入二进制日志。在这种情况下,您还应该使用--replicate-do-db=mysql--binlog-do-db=mysql,或--replicate-do-table=mysql.ndb_apply_status来确保在副本上填充mysql.ndb_apply_status

  2. 使用--replicate-ignore-db=mysql意味着mysql数据库中的表不会被复制。在这种情况下,您还应该使用--replicate-do-table=mysql.ndb_apply_status来确保mysql.ndb_apply_status被复制。

    使用--binlog-ignore-db=mysql意味着不会将mysql数据库中的表更改写入二进制日志。在这种情况下,您还应该使用--replicate-do-table=mysql.ndb_apply_status来确保mysql.ndb_apply_status被复制。

您还应该记住,每个复制规则都需要以下内容:

  1. 自己的--replicate-do-*--replicate-ignore-*选项,并且不能在单个复制过滤选项中表示多个规则。有关这些规则的信息,请参见第 19.1.6 节,“复制和二进制日志选项和变量”。

  2. 自己的--binlog-do-db--binlog-ignore-db选项,并且不能在单个二进制日志过滤选项中表示多个规则。有关这些规则的信息,请参见第 7.4.4 节,“二进制日志”。

如果您将 NDB 集群复制到使用NDB之外的存储引擎的副本,则前面提到的考虑可能不适用,如本节其他地方所讨论的。

NDB 集群复制和 IPv6。 从 NDB 8.0.22 开始,所有类型的 NDB 集群节点都支持 IPv6;这包括管理节点、数据节点和 API 或 SQL 节点。

在 NDB 8.0.22 之前,NDB API 和 MGM API(因此数据节点和管理节点)不支持 IPv6,尽管 MySQL 服务器(包括在 NDB 集群中充当 SQL 节点的服务器)可以使用 IPv6 与其他 MySQL 服务器联系。在 8.0.22 之前的 NDB 集群版本中,您可以使用 IPv6 在 SQL 节点之间进行复制,连接源和副本的 SQL 节点如下图中的虚线箭头所示:

图 25.13 SQL 节点之间使用 IPv6 连接的复制

大部分内容在周围的文本中描述。代表 MySQL 到 MySQL 的 IPv6 连接的虚线连接在两个节点之间,分别来自源和副本集群。集群内的所有连接,如数据节点到数据节点或数据节点到管理节点,都使用实线连接表示仅为 IPv4 连接。

在 NDB 8.0.22 之前,所有源自 NDB 集群内部的连接——在前面的图表中用实箭头表示——必须使用 IPv4。换句话说,所有 NDB 集群数据节点、管理服务器和管理客户端必须能够使用 IPv4 相互访问。此外,SQL 节点必须使用 IPv4 与集群通信。在 NDB 8.0.22 及更高版本中,这些限制不再适用;此外,任何使用 NDB 和 MGM API 编写的应用程序都可以假定在仅使用 IPv6 的环境中编写和部署。

注意

在版本 8.0.22 至 8.0.33 中,NDB需要系统支持 IPv6 才能运行,无论集群是否实际使用任何 IPv6 地址。在 NDB Cluster 8.0.34 及更高版本中,这不再是问题,如果集群未使用 IPv6 寻址,则可以在 Linux 内核中禁用 IPv6。

属性提升和降级。 NDB 集群复制包括对属性提升和降级的支持。后者的实现区分了有损和无损类型转换,并且可以通过设置系统变量replica_type_conversions(NDB 8.0.26 及更高版本)或slave_type_conversions(NDB 8.0.26 之前)的全局值来控制在副本上的使用。

有关 NDB 集群中属性提升和降级的更多信息,请参阅基于行的复制:属性提升和降级。

NDB,与InnoDBMyISAM不同,不会将对虚拟列的更改写入二进制日志;然而,这对于 NDB 集群复制或NDB与其他存储引擎之间的复制没有不利影响。存储生成列的更改会被记录。

25.7.4 NDB 集群复制模式和表

原文:dev.mysql.com/doc/refman/8.0/en/mysql-cluster-replication-schema.html

NDB 集群中的复制利用了在充当被复制集群和副本中的 SQL 节点的每个 MySQL 服务器实例上的mysql数据库中的一些专用表。无论副本是单个服务器还是集群,这都是正确的。

ndb_binlog_indexndb_apply_status 表在 mysql 数据库中创建。用户不应明确复制这些表。通常不需要用户干预来创建或维护这两个表,因为两者都由NDB二进制日志(binlog)注入器线程维护。这使得源mysqld进程更新到由NDB存储引擎执行的更改。NDB binlog 注入器线程直接从NDB存储引擎接收事件。NDB注入器负责捕获集群中的所有数据事件,并确保所有更改、插入或删除数据的事件都记录在ndb_binlog_index表中。复制 I/O(接收器)线程将事件从源的二进制日志传输到复制的中继日志。

ndb_replication 表必须手动创建。用户可以更新此表以按数据库或表进行过滤。有关更多信息,请参见ndb_replication 表ndb_replication 也用于 NDB 复制冲突检测和解决冲突控制;请参见冲突解决控制

即使ndb_binlog_indexndb_apply_status是自动创建和维护的,建议在为复制准备 NDB 集群时,首先检查这些表的存在和完整性。可以通过直接在源上查询mysql.ndb_binlog_index表来查看二进制日志中记录的事件数据。这也可以通过在源或副本 SQL 节点上使用SHOW BINLOG EVENTS语句来完成。 (参见第 15.7.7.2 节,“SHOW BINLOG EVENTS Statement”.)

您还可以从SHOW ENGINE NDB STATUS的输出中获取有用信息。

注意

在对NDB表执行模式更改时,应用程序应等到发出该语句的 MySQL 客户端连接中返回ALTER TABLE语句后,再尝试使用表的更新定义。

ndb_apply_status 表

ndb_apply_status用于记录已从源复制到副本的操作。如果副本上不存在ndb_apply_status表,ndb_restore会重新创建它。

ndb_binlog_index不同,此表中的数据不针对(副本)集群中的任何一个 SQL 节点,因此ndb_apply_status可以使用NDBCLUSTER存储引擎,如下所示:

CREATE TABLE `ndb_apply_status` (
    `server_id`   INT(10) UNSIGNED NOT NULL,
    `epoch`       BIGINT(20) UNSIGNED NOT NULL,
    `log_name`    VARCHAR(255) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
    `start_pos`   BIGINT(20) UNSIGNED NOT NULL,
    `end_pos`     BIGINT(20) UNSIGNED NOT NULL,
    PRIMARY KEY (`server_id`) USING HASH
) ENGINE=NDBCLUSTER DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

ndb_apply_status表仅在副本上填充,这意味着在源上,此表永远不包含任何行;因此,在那里不需要为ndb_apply_status分配任何DataMemory

由于此表是从源头数据填充的,因此应允许其进行复制;任何无意中阻止副本更新ndb_apply_status或阻止源写入二进制日志的复制过滤或二进制日志过滤规则可能会阻止集群之间的复制正常运行。有关此类过滤规则可能引起的潜在问题的更多信息,请参阅在 NDB 集群之间进行复制时的复制和二进制日志过滤规则。

可以删除此表,但不建议这样做。删除它会使所有 SQL 节点进入只读模式;在 NDB 8.0.24 及更高版本中,NDB 检测到该表已被删除,并重新创建它,之后再次执行更新是可能的。删除并重新创建 ndb_apply_status 会在二进制日志中创建一个间隙事件;间隙事件会导致副本 SQL 节点停止应用来自源的更改,直到重新启动复制通道。在 NDB 8.0.24 之前,在这种情况下,需要重新启动所有 SQL 节点以使它们退出只读模式,然后手动重新创建 ndb_apply_status

该表的 epoch 列中的 0 表示来自于 NDB 以外的存储引擎的事务。

ndb_apply_status 用于记录从上游源复制并应用到副本集群的哪些时代事务。这些信息在 NDB 在线备份中被捕获,但(按设计)不会被 ndb_restore 恢复。在某些情况下,恢复这些信息以供新设置使用可能会有所帮助;从 NDB 8.0.29 开始,您可以通过使用 --with-apply-status 选项调用 ndb_restore 来实现这一点。有关该选项的更多信息,请参阅选项的描述。

ndb_binlog_index 表

NDB 集群复制使用 ndb_binlog_index 表来存储二进制日志的索引数据。由于该表对每个 MySQL 服务器都是本地的,并且不参与集群化,因此它使用 InnoDB 存储引擎。这意味着必须在参与源集群的每个 mysqld 上单独创建该表。(二进制日志本身包含来自集群中所有 MySQL 服务器的更新。)该表定义如下:

CREATE TABLE `ndb_binlog_index` (
    `Position` BIGINT(20) UNSIGNED NOT NULL,
    `File` VARCHAR(255) NOT NULL,
    `epoch` BIGINT(20) UNSIGNED NOT NULL,
    `inserts` INT(10) UNSIGNED NOT NULL,
    `updates` INT(10) UNSIGNED NOT NULL,
    `deletes` INT(10) UNSIGNED NOT NULL,
    `schemaops` INT(10) UNSIGNED NOT NULL,
    `orig_server_id` INT(10) UNSIGNED NOT NULL,
    `orig_epoch` BIGINT(20) UNSIGNED NOT NULL,
    `gci` INT(10) UNSIGNED NOT NULL,
    `next_position` bigint(20) unsigned NOT NULL,
    `next_file` varchar(255) NOT NULL,
    PRIMARY KEY (`epoch`,`orig_server_id`,`orig_epoch`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

注意

如果您正在从旧版本(NDB 7.5.2 之前)升级,请执行 MySQL 升级过程,并确保通过使用 --upgrade=FORCE 选项启动 MySQL 服务器来升级系统表。系统表升级会导致为该表执行 ALTER TABLE ... ENGINE=INNODB 语句。继续支持使用 MyISAM 存储引擎以实现向后兼容性。

ndb_binlog_index 转换为 InnoDB 后可能需要额外的磁盘空间。如果这成为问题,您可以通过使用 InnoDB 表空间来为这个表节省空间,将其 ROW_FORMAT 更改为 COMPRESSED,或两者兼而有之。有关更多信息,请参见 Section 15.1.21, “CREATE TABLESPACE Statement”,以及 Section 15.1.20, “CREATE TABLE Statement”,以及 Section 17.6.3, “Tablespaces”。

ndb_binlog_index 表的大小取决于每个二进制日志文件的时代数和二进制日志文件的数量。每个二进制日志文件的时代数通常取决于每个时代生成的二进制日志量和二进制日志文件的大小,较小的时代会导致每个文件有更多的时代。需要注意的是,即使 --ndb-log-empty-epochs 选项为 OFF,空时代也会向 ndb_binlog_index 表插入记录,这意味着每个文件的条目数量取决于文件的使用时间;这种关系可以用下面的公式表示:

[number of epochs per file] = [time spent per file] / TimeBetweenEpochs

繁忙的 NDB Cluster 定期写入二进制日志,并且可能比安静的集群更快地轮换二进制日志文件。这意味着一个带有 --ndb-log-empty-epochs=ON 的“安静” NDB Cluster 实际上可能比活动量大的集群每个文件有更多的 ndb_binlog_index 行。

当使用 --ndb-log-orig 选项启动 mysqld 时,orig_server_idorig_epoch 列分别存储事件起源服务器的 ID 和事件发生的时代,这在使用多个源的 NDB Cluster 复制设置中非常有用。用于在多源设置中找到最接近副本上最高应用时代的二进制日志位置的 SELECT 语句(参见 Section 25.7.10, “NDB Cluster Replication: Bidirectional and Circular Replication”)使用这两列,这两列没有索引。当尝试执行故障切换时,这可能导致性能问题,因为查询必须执行表扫描,特别是当源使用 --ndb-log-empty-epochs=ON 运行时。您可以通过为这些列添加索引来提高多源故障切换时间,如下所示:

ALTER TABLE mysql.ndb_binlog_index
    ADD INDEX orig_lookup USING BTREE (orig_server_id, orig_epoch);

在从单个源到单个副本的复制时,添加此索引不会带来任何好处,因为在这种情况下用于获取二进制日志位置的查询不使用 orig_server_idorig_epoch

有关使用 next_positionnext_file 列的更多信息,请参见第 25.7.8 节,“使用 NDB 集群复制实现故障切换”。

以下图显示了 NDB 集群复制源服务器、其二进制日志注入器线程和 mysql.ndb_binlog_index 表之间的关系。

图 25.14 复制源集群

大多数概念在周围的文本中有描述。这个复杂的图像有三个主要区域。左上角的区域分为三个部分:MySQL 服务器(mysqld)、NDBCLUSTER 表处理程序和互斥体。连接线程连接这些部分,接收器和注入器线程连接 NDBCLUSTER 表处理程序和互斥体。底部区域显示四个数据节点(ndbd)。它们都产生由箭头表示的事件,指向接收器线程,接收器线程也指向连接线程和注入器线程。一个节点发送和接收到互斥区域。表示注入器线程的箭头指向二进制日志以及在周围文本中描述的 ndb_binlog_index 表。

ndb_replication 表

ndb_replication 表用于控制二进制日志记录和冲突解决,并且是基于每个表的基础上操作的。该表中的每一行对应于被复制的表,确定如何记录对表的更改,并且如果指定了冲突解决函数,则确定如何解决该表的冲突。

ndb_apply_statusndb_replication 表不同,ndb_replication 表必须手动创建,使用此处显示的 SQL 语句:

CREATE TABLE mysql.ndb_replication  (
    db VARBINARY(63),
    table_name VARBINARY(63),
    server_id INT UNSIGNED,
    binlog_type INT UNSIGNED,
    conflict_fn VARBINARY(128),
    PRIMARY KEY USING HASH (db, table_name, server_id)
)   ENGINE=NDB
PARTITION BY KEY(db,table_name);

此表的列在此处列出,并附有描述:

  • db

    包含要复制表的数据库的名称���

    您可以在数据库名称中使用下划线 _ 和百分号 % 中的一个或两个通配符。(请参见使用通配符匹配,本节后面有更多信息。)

  • table_name

    要复制的表的名称。

    表名可以包含下划线 _ 和百分号 % 中的一个或两个通配符。请参见使用通配符匹配,本节后面有更多信息。

  • server_id

    MySQL 实例(SQL 节点)的唯一服务器 ID,表所在的位置。

    此列中的 0 充当通配符,相当于 %,匹配任何服务器 ID。(请参见使用通配符匹配,本节后面有更多信息。)

  • binlog_type

    要使用的二进制日志记录类型。有关值和描述,请参阅文本。

  • conflict_fn

    要应用的冲突解决函数之一是 NDB O L D ( ) " ) , N D B OLD()"),NDB OLD()")NDBMAX()“),NDB M A X D E L E T E W I N ( ) " ) , N D B MAX_DELETE_WIN()"),NDB MAXDELETEWIN()")NDBEPOCH()”),NDB E P O C H T R A N S ( ) " ) , N D B EPOCH_TRANS()"),NDB EPOCHTRANS()")NDBEPOCH2()“),NDB E P O C H 2 T R A N S ( ) " ) 中的一个; ‘ N U L L ‘ 表示此表不使用冲突解决。 N D B 8.0.30 及更高版本支持两个额外的冲突解决函数 N D B EPOCH2_TRANS()")中的一个;`NULL`表示此表不使用冲突解决。NDB 8.0.30 及更高版本支持两个额外的冲突解决函数 NDB EPOCH2TRANS()")中的一个;NULL表示此表不使用冲突解决。NDB8.0.30及更高版本支持两个额外的冲突解决函数NDBMAX_INS()”)和 NDB$MAX_DEL_WIN_INS()")。

    有关这些函数及其在 NDB 复制冲突解决中的用途的更多信息,请参见 Conflict Resolution Functions。

    一些冲突解决函数(NDB$OLD()NDB$EPOCH()NDB$EPOCH_TRANS())需要使用一个或多个用户创建的异常表。请参见 Conflict Resolution Exceptions Table。

要启用与 NDB 复制的冲突解决,需要在 SQL 节点或应解决冲突的节点上创建并填充此表,其中包含有关控制信息。根据要使用的冲突解决类型和方法,这可能是源、副本或两个服务器。在简单的源-副本设置中,数据也可以在副本上本地更改,这通常是副本。在更复杂的复制方案中,例如双向复制,这通常是所有涉及的源。有关更多信息,请参见 Section 25.7.12,“NDB Cluster Replication Conflict Resolution”。

ndb_replication表允许在冲突解决范围之外对二进制日志进行表级控制,在这种情况下,conflict_fn指定为NULL,而其余列值用于控制给定表或与通配符表达式匹配的一组表的二进制日志。通过为binlog_type列设置适当的值,您可以使给定表或表使用所需的二进制日志格式进行记录,或完全禁用二进制日志记录。此列的可能值及其描述如下表所示:

表 25.70 binlog_type 值及其描述

描述
0使用服务器默认值
1不在二进制日志中记录此表(与sql_log_bin = 0效果相同,但仅适用于一个或多个指定表)
2仅记录更新的属性;将其记录为WRITE_ROW事件
3记录完整行,即使未更新(MySQL 服务器默认行为)
6使用更新的属性,即使值未更改
7记录完整行,即使没有值更改;将更新记录为UPDATE_ROW事件
8将更新记录为UPDATE_ROW;仅记录主键列的前图像,以及更新后图像中的列(与--ndb-log-update-minimal效果相同,但仅适用于一个或多个指定表)
9将更新记录为UPDATE_ROW;仅记录主键列的前图像,以及除主键列之外的所有列的后图像

注意

binlog_type值 4 和 5 未被使用,因此未包含在刚刚显示的表中,也未包含在下一个表中。

几个binlog_type值等同于各种组合的mysqld日志选项--ndb-log-updated-only--ndb-log-update-as-write,和--ndb-log-update-minimal,如下表所示:

表 25.71 binlog_type 值与 NDB 日志选项等效组合

--ndb-log-updated-only--ndb-log-update-as-write--ndb-log-update-minimal
0
1
2
3
6
7
8
9

通过向 ndb_replication 表中插入行,可以为不同的表设置不同的二进制日志记录格式,使用适当的 dbtable_namebinlog_type 列值。在设置二进制日志记录格式时,应使用前面表中显示的内部整数值。以下两个语句将二进制日志记录设置为对表 test.a 进行完整行记录(值为 3),以及对表 test.b 仅记录更新(值为 2):

# Table test.a: Log full rows
INSERT INTO mysql.ndb_replication VALUES("test", "a", 0, 3, NULL);

# Table test.b: log updates only
INSERT INTO mysql.ndb_replication VALUES("test", "b", 0, 2, NULL);

要禁用一个或多个表的日志记录,请使用 binlog_type 为 1,如下所示:

# Disable binary logging for table test.t1
INSERT INTO mysql.ndb_replication VALUES("test", "t1", 0, 1, NULL);

# Disable binary logging for any table in 'test' whose name begins with 't'
INSERT INTO mysql.ndb_replication VALUES("test", "t%", 0, 1, NULL);

为给定表禁用日志记录相当于设置sql_log_bin = 0,只是它适用于一个或多个表。如果 SQL 节点不为给定表执行二进制日志记录,则不会发送这些表的行更改事件。这意味着它不是接收所有更改并丢弃一些,而是不订阅这些更改。

禁用日志记录可能有多种原因,包括以下列出的原因:

  • 不将更改发送到网络通常可以节省带宽、缓冲和 CPU 资源。

  • 不记录对具有非常频繁更新但价值不大的表的更改非常适合瞬态数据(例如会话数据),在集群完全失败的情况下可能相对不重要。

  • 使用会话变量(或 sql_log_bin)和应用程序代码,还可以记录(或不记录)某些 SQL 语句或类型的 SQL 语句;例如,在某些情况下,可能不希望记录一个或多个表上的 DDL 语句。

  • 将复制流拆分为两个(或更多)二进制日志文件可以出于性能、需要将不同数据库复制到不同位置、使用不同的二进制日志记录类型等原因进行操作。

使用通配符进行匹配。 为了不必为复制设置中每个数据库、表和 SQL 节点的每个组合插入一行到 ndb_replication 表中,NDB 支持在此表的 dbtable_nameserver_id 列上进行通配符匹配。在 dbtable_name 中使用的数据库和表名可以包含以下通配符中的一个或两个:

  • _(下划线字符):匹配零个或多个字符

  • %(百分号):匹配一个字符

(这些是 MySQL LIKE 操作符支持的相同通配符。)

server_id 列支持 0 作为 _ 的通配符等效(匹配任何内容)。这在前面显示的示例中使用。

ndb_replication表中的给定行可以使用通配符来匹配任何数据库名称、表名称和服务器 ID 的任意组合。在表中存在多个潜在匹配项的情况下,根据此处显示的表,选择最佳匹配项,其中W表示通配符匹配,E表示精确匹配,Quality列中的值越大,匹配越好:

表 25.72 不同列的通配符和精确匹配组合的权重

dbtable_nameserver_id质量
WWW1
WWE2
WEW3
WEE4
EWW5
EWE6
EEW7
EEE8

因此,数据库名称、表名称和服务器 ID 的精确匹配被认为是最佳(最强),而三个列的通配符匹配被认为是最弱(最差)。在选择应用哪个规则时,只考虑匹配的强度;表中行的顺序对此决定没有影响。

记录完整或部分行。 有两种基本记录行的方法,由--ndb-log-updated-only选项设置为mysqld决定:

  • 记录完整行(选项设置为ON)

  • 仅记录已更新的列数据,即已设置值的列数据,无论该值是否实际更改。这是默认行为(选项设置为OFF)。

通常仅记录已更新的列就足够且更有效;但是,如果需要记录完整行,可以通过将--ndb-log-updated-only设置为0OFF来实现。

将更改的数据记录为更新。 MySQL 服务器的--ndb-log-update-as-write选项的设置确定是否执行记录时是否包含“之前”图像。

因为更新和删除操作的冲突解决是在 MySQL 服务器的更新处理程序中完成的,所以有必要控制复制源执行的日志记录,使更新为更新而不是写入;也就是说,使更新被视为现有行的更改,而不是写入新行,即使这些行替换了现有行。

此选项默认为打开;换句话说,更新被视为写入。也就是说,默认情况下,更新被写入二进制日志中的write_row事件,而不是update_row事件。

要禁用该选项,请使用--ndb-log-update-as-write=0--ndb-log-update-as-write=OFF启动源mysqld。当从 NDB 表复制到使用不同存储引擎的表时,您必须执行此操作;请参阅从 NDB 复制到其他存储引擎和从 NDB 复制到非事务性存储引擎以获取更多信息。

重要提示

(NDB 8.0.30 及更高版本😃 对于使用NDB$MAX_INS()NDB$MAX_DEL_WIN_INS()进行插入冲突解决的情况,一个 SQL 节点(即一个mysqld进程)可以记录源集群上的行更新为WRITE_ROW事件,并启用--ndb-log-update-as-write选项以确保幂等性和最佳大小。这对这些算法有效,因为它们都将WRITE_ROW事件映射到插入或更新,具体取决于行是否已经存在,并且所需的元数据(时间戳列的“后”图像)存在于WRITE_ROW事件中。
这些更改。

禁用日志记录可能有多种原因,包括以下列出的原因:

  • 不将更改发送到网络通常可以节省带宽、缓冲和 CPU 资源。

  • 不记录对具有非常频繁更新但价值不大的表的更改非常适合瞬态数据(例如会话数据),在集群完全失败的情况下可能相对不重要。

  • 使用会话变量(或 sql_log_bin)和应用程序代码,还可以记录(或不记录)某些 SQL 语句或类型的 SQL 语句;例如,在某些情况下,可能不希望记录一个或多个表上的 DDL 语句。

  • 将复制流拆分为两个(或更多)二进制日志文件可以出于性能、需要将不同数据库复制到不同位置、使用不同的二进制日志记录类型等原因进行操作。

使用通配符进行匹配。 为了不必为复制设置中每个数据库、表和 SQL 节点的每个组合插入一行到 ndb_replication 表中,NDB 支持在此表的 dbtable_nameserver_id 列上进行通配符匹配。在 dbtable_name 中使用的数据库和表名可以包含以下通配符中的一个或两个:

  • _(下划线字符):匹配零个或多个字符

  • %(百分号):匹配一个字符

(这些是 MySQL LIKE 操作符支持的相同通配符。)

server_id 列支持 0 作为 _ 的通配符等效(匹配任何内容)。这在前面显示的示例中使用。

ndb_replication表中的给定行可以使用通配符来匹配任何数据库名称、表名称和服务器 ID 的任意组合。在表中存在多个潜在匹配项的情况下,根据此处显示的表,选择最佳匹配项,其中W表示通配符匹配,E表示精确匹配,Quality列中的值越大,匹配越好:

表 25.72 不同列的通配符和精确匹配组合的权重

dbtable_nameserver_id质量
WWW1
WWE2
WEW3
WEE4
EWW5
EWE6
EEW7
EEE8

因此,数据库名称、表名称和服务器 ID 的精确匹配被认为是最佳(最强),而三个列的通配符匹配被认为是最弱(最差)。在选择应用哪个规则时,只考虑匹配的强度;表中行的顺序对此决定没有影响。

记录完整或部分行。 有两种基本记录行的方法,由--ndb-log-updated-only选项设置为mysqld决定:

  • 记录完整行(选项设置为ON)

  • 仅记录已更新的列数据,即已设置值的列数据,无论该值是否实际更改。这是默认行为(选项设置为OFF)。

通常仅记录已更新的列就足够且更有效;但是,如果需要记录完整行,可以通过将--ndb-log-updated-only设置为0OFF来实现。

将更改的数据记录为更新。 MySQL 服务器的--ndb-log-update-as-write选项的设置确定是否执行记录时是否包含“之前”图像。

因为更新和删除操作的冲突解决是在 MySQL 服务器的更新处理程序中完成的,所以有必要控制复制源执行的日志记录,使更新为更新而不是写入;也就是说,使更新被视为现有行的更改,而不是写入新行,即使这些行替换了现有行。

此选项默认为打开;换句话说,更新被视为写入。也就是说,默认情况下,更新被写入二进制日志中的write_row事件,而不是update_row事件。

要禁用该选项,请使用--ndb-log-update-as-write=0--ndb-log-update-as-write=OFF启动源mysqld。当从 NDB 表复制到使用不同存储引擎的表时,您必须执行此操作;请参阅从 NDB 复制到其他存储引擎和从 NDB 复制到非事务性存储引擎以获取更多信息。

重要提示

(NDB 8.0.30 及更高版本😃 对于使用NDB$MAX_INS()NDB$MAX_DEL_WIN_INS()进行插入冲突解决的情况,一个 SQL 节点(即一个mysqld进程)可以记录源集群上的行更新为WRITE_ROW事件,并启用--ndb-log-update-as-write选项以确保幂等性和最佳大小。这对这些算法有效,因为它们都将WRITE_ROW事件映射到插入或更新,具体取决于行是否已经存在,并且所需的元数据(时间戳列的“后”图像)存在于WRITE_ROW事件中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值