MySQL8 中文参考(八十七)(3)https://developer.aliyun.com/article/1565938
- 在上述公式中,*
key_size
是有序索引键的大小(以字节为单位),key_attributes
是有序索引键中的属性数,rows
*是基本表中的行数。
假设表t1
有 100 万行,并且有一个命名为ix1
的有序索引,其中包含两个四字节整数。另外假设IndexStatSaveSize
和IndexStatSaveScale
设置为它们的默认值(32K 和 100)。使用前面的两个公式,我们可以计算如下:
sample_size = 8 + ((1 + 2) * 4) = 20 bytes
sample_rows = 32K
* ((0.01 * 100 * log2(1000000*20)) + 1)
/ 20
= 32768 * ( (1 * ~16.811) +1) / 20
= 32768 * ~17.811 / 20
= ~29182 rows
- 预期的索引内存使用量为 2 * 18 * 29182 = ~1050550 字节。
在 NDB 8.0 中,此参数的最小和默认值为 0(零)。
StringMemory
- 此参数确定为诸如表名之类的字符串分配了多少内存,并在
config.ini
文件的[ndbd]
或[ndbd default]
部分中指定。介于0
和100
之间的值被解释为最大默认值的百分比,该值是基于多个因素计算的,包括表的数量、最大表名大小、.FRM
文件的最大大小、MaxNoOfTriggers
、最大列名大小和最大默认列值。
大于100
的值被解释为字节数。
默认值为 25,即默认最大值的 25%。
在大多数情况下,默认值应该足够,但当您有很多NDB
表(1000 个或更多)时,可能会出现错误 773“字符串内存不足,请修改 StringMemory 配置参数:永久错误:模式错误”,在这种情况下,您应该增加此值。25
(25%)不算过多,并且应该可以防止此错误在除了最极端情况之外的所有情况下再次发生。
以下示例说明了如何为表使用内存。考虑以下表定义:
CREATE TABLE example (
a INT NOT NULL,
b INT NOT NULL,
c INT NOT NULL,
PRIMARY KEY(a),
UNIQUE(b)
) ENGINE=NDBCLUSTER;
对于每条记录,有 12 字节的数据加上 12 字节的开销。没有可空列可以节省 4 字节的开销。此外,我们在列a
和b
上有两个有序索引,每条记录大约消耗 10 字节。基表上有一个主键哈希索引,每条记录大约使用 29 字节。唯一约束由一个单独的表实现,其中b
作为主键,a
作为列。这个其他表在example
表中每条记录额外消耗 29 字节的索引内存,以及 8 字节的记录数据加上 12 字节的开销。
因此,对于一百万条记录,我们需要 58MB 的索引内存来处理主键和唯一约束的哈希索引。我们还需要 64MB 来存储基表和唯一索引表的记录,以及两个有序索引表。
您可以看到哈希索引占用了相当多的内存空间;然而,它们提供了非常快速的数据访问。它们还用于 NDB 集群中处理唯一性约束。
目前,唯一的分区算法是哈希分区,有序索引是每个节点本地的。因此,在一般情况下,有序索引不能用于处理唯一性约束。
对于IndexMemory
和DataMemory
的一个重要点是,总数据库大小是每个节点组的所有数据内存和所有索引内存的总和。每个节点组用于存储复制的信息,因此如果有四个节点,每个节点有两个片段副本,则有两个节点组。因此,每个数据节点可用的总数据内存为 2 × DataMemory
。
强烈建议为所有节点设置相同的DataMemory
和IndexMemory
值。数据在集群中的所有节点上均匀分布,因此任何节点的最大可用空间不能大于集群中最小节点的空间。
DataMemory
可以更改,但减少它可能存在风险;这样做很容易导致一个节点甚至整个 NDB 集群由于内存空间不足而无法重新启动。增加这些值应该是可以接受的,但建议像软件升级一样进行这样的升级,首先更新配置文件,然后重新启动管理服务器,然后依次重新启动每个数据节点。
MinFreePct. 数据节点资源(包括 DataMemory
)的一部分(默认为 5%)被保留,以确保数据节点在执行重启时不会耗尽内存。可以使用 MinFreePct
数据节点配置参数(默认为 5)进行调整。
更新不会增加索引内存使用量。插入操作会立即生效;然而,直到事务提交之前,行并不会被实际删除。
事务参数。 我们将讨论的接下来的几个 [ndbd]
参数非常重要,因为它们影响系统能够处理的并行事务数量和事务大小。MaxNoOfConcurrentTransactions
设置了节点中可能的并行事务数量。MaxNoOfConcurrentOperations
设置了可以处于更新阶段或同时被锁定的记录数量。
这两个参数(特别是 MaxNoOfConcurrentOperations
)很可能是用户设置特定值而不使用默认值的目标。默认值适用于使用小事务的系统,以确保这些事务不会使用过多内存。
MaxDMLOperationsPerTransaction
设置了在给定事务中可以执行的最大 DML 操作数量。
MaxNoOfConcurrentTransactions
- 每个集群数据节点都需要为集群中的每个活动事务记录一个事务记录。协调事务的任务分布在所有数据节点之间。集群中的事务记录总数是任何给定节点中的事务数乘以集群中节点数的结果。
事务记录分配给各个 MySQL 服务器。连接到 MySQL 服务器至少需要一个事务记录,以及每个连接访问的表的额外事务对象。这意味着集群中事务总数的合理最小值可以表示为
TotalNoOfConcurrentTransactions =
(maximum number of tables accessed in any single transaction + 1)
* number of SQL nodes
- 假设集群中有 10 个 SQL 节点。涉及 10 个表的单个连接需要 11 个事务记录;如果一个事务中有 10 个这样的连接,那么这个事务需要 10 * 11 = 110 个事务记录,每个 MySQL 服务器都是如此,或者总共需要 110 * 10 = 1100 个事务记录。每个数据节点可以处理 TotalNoOfConcurrentTransactions / 数据节点数 的事务。对于具有 4 个数据节点的 NDB 集群,这意味着在每个数据节点上将
MaxNoOfConcurrentTransactions
设置为 1100 / 4 = 275。此外,您应该通过确保单个节点组可以容纳所有并发事务来提供故障恢复;换句话说,每个数据节点的 MaxNoOfConcurrentTransactions 足以覆盖等于 TotalNoOfConcurrentTransactions / 节点组数 的事务数量。如果此集群只有一个节点组,则 MaxNoOfConcurrentTransactions
应设置为 1100(与整个集群的并发事务总数相同)。
此外,每个事务至少涉及一个操作;因此,为 MaxNoOfConcurrentTransactions
设置的值应始终不超过 MaxNoOfConcurrentOperations
的值。
所有集群数据节点必须设置此参数的相同值。这是因为当数据节点失败时,最老的存活节点会重新创建失败节点中正在进行的所有事务的事务状态。
可以使用滚动重启来更改此值,但在此过程中发生的事务数量不能超过旧值和新值中较低的那个。
默认值为 4096。
MaxNoOfConcurrentOperations
- 根据事务的大小和数量调整此参数的值是一个好主意。执行仅涉及少量操作和记录的事务时,通常情况下此参数的默认值就足够了。执行涉及许多记录的大型事务通常需要增加其值。
为更新集群数据的每个事务在事务协调器和实际执行更新的节点上保留记录。这些记录包含查找回滚的 UNDO 记录、锁队列和其他目的所需的状态信息。
此参数应至少设置为事务中同时更新的记录数除以集群数据节点数。例如,在一个有四个数据节点并且预计使用事务处理一百万并发更新的集群中,应将此值设置为 1000000 / 4 = 250000。为了提供对故障的弹性,建议将此参数设置为足够高的值,以允许单个数据节点处理其节点组的负载。换句话说,应将该值设置为总并发操作数 / 节点组数
。(在只有一个节点组的情况下,这与整个集群的总并发操作数相同。)
由于每个事务总是涉及至少一个操作,MaxNoOfConcurrentOperations
的值应始终大于或等于MaxNoOfConcurrentTransactions
的值。
设置锁的读取查询也会导致创建操作记录。在各个节点内部分配了一些额外空间,以适应分布在节点上不完美的情况。
当查询使用唯一哈希索引时,实际上每个事务中的记录会使用两个操作记录。第一条记录代表索引表中的读取,第二条处理基本表中的操作。
默认值为 32768。
该参数实际上处理两个可以分别配置的值。其中第一个指定要放置在事务协调器中的操作记录数量。第二部分指定要放置在数据库本地的操作记录数量。
在八节点集群上执行的非常大的事务需要与事务中涉及的读取、更新和删除相同数量的操作记录。但是,这些操作记录分布在所有八个节点上。因此,如果需要为一个非常大的事务配置系统,最好将两部分分开配置。MaxNoOfConcurrentOperations
始终用于计算节点事务协调器部分中的操作记录数量。
对于操作记录的内存需求也是很重要的。每个记录大约消耗 1KB。
MaxNoOfLocalOperations
- 默认情况下,此参数计算为 1.1 ×
MaxNoOfConcurrentOperations
。这适用于具有许多同时事务的系统,其中没有一个事务非常大。如果需要一次处理一个非常大的事务,并且有许多节点,则明确指定此参数以覆盖默认值是一个好主意。
此参数在 NDB 8.0 中已弃用,并可能在未来的 NDB 集群版本中被移除。此外,此参数与TransactionMemory
参数不兼容;如果您尝试在集群配置文件(config.ini
)中为这两个参数设置值,管理服务器将拒绝启动。
MaxDMLOperationsPerTransaction
- 此参数限制了事务的大小。如果事务需要的 DML 操作超过此数量,事务将被中止。
此参数的值不能超过MaxNoOfConcurrentOperations
设置的值。
事务临时存储。 下一组[ndbd]
参数用于确定在执行作为集群事务一部分的语句时的临时存储。当语句完成并且集群正在等待提交或回滚时,所有记录都会被释放。
对于大多数情况,默认值对这些参数是足够的。然而,需要支持涉及大量行或操作的事务的用户可能需要增加这些值以在系统中实现更好的并行性,而需要相对较小事务的应用程序的用户可以减少这些值以节省内存。
MaxNoOfConcurrentIndexOperations
- 对于使用唯一哈希索引的查询,在查询执行阶段会使用另一个临时操作记录集。此参数设置了该记录池的大小。因此,此记录仅在执行查询的一部分时分配。一旦执行完这部分,记录就会被释放。处理中止和提交所需的状态由正常操作记录处理,其中池大小由参数
MaxNoOfConcurrentOperations
设置。
此参数的默认值为 8192。只有在极端高并行性的罕见情况下,使用唯一哈希索引可能需要增加此值。如果数据库管理员确定集群不需要高并行性,则可以使用较小的值,从而节省内存。
此参数在 NDB 8.0 中已被弃用,并将在未来的 NDB Cluster 发布中被移除。此外,此参数与TransactionMemory
参数不兼容;如果您尝试在集群配置文件(config.ini
)中为两个参数设置值,则管理服务器将拒绝启动。
MaxNoOfFiredTriggers
MaxNoOfFiredTriggers
的默认值为 4000,在大多数情况下足够使用。在某些情况下,如果数据库管理员确定集群中不需要高并行性,则甚至可以减少此值。
当执行影响唯一哈希索引的操作时,将创建一条记录。在具有唯一哈希索引的表中插入或删除记录,或更新作为唯一哈希索引一部分的列,会在索引表中触发插入或删除。生成的记录用于表示等待原始操作完成的索引表操作。此操作生命周期短暂,但在包含一组唯一哈希索引的基表上有许多并行写操作的情况下,仍可能需要大量记录。
此参数在 NDB 8.0 中已被弃用,并将在未来的 NDB Cluster 发布中被移除。此外,此参数与TransactionMemory
参数不兼容;如果您尝试在集群配置文件(config.ini
)中为两个参数设置值,则管理服务器将拒绝启动。
TransactionBufferMemory
- 此参数影响的内存用于跟踪更新索引表和读取唯一索引时触发的操作。此内存用于存储这些操作的键和列信息。很少情况下需要修改此参数的默认值。
TransactionBufferMemory
的默认值为 1MB。
正常的读写操作使用类似的缓冲区,其使用时间更短暂。编译时参数ZATTRBUF_FILESIZE
(位于ndb/src/kernel/blocks/Dbtc/Dbtc.hpp
中)设置为 4000 × 128 字节(500KB)。用于键信息的类似缓冲区,ZDATABUF_FILESIZE
(也在Dbtc.hpp
中)包含 4000 × 16 = 62.5KB 的缓冲区空间。Dbtc
是处理事务协调的模块。
事务资源分配参数。 以下列表中的参数用于在事务协调器(DBTC
)中分配事务资源。将其中任何一个设置为默认值(0)将为相应资源的预估总数据节点使用量的 25%分配事务内存。这些参数的实际最大可能值通常受到数据节点可用内存量的限制;设置它们不会影响分配给数据节点的总内存量。此外,您应该记住,它们控制数据节点的保留内部记录数量,独立于MaxDMLOperationsPerTransaction
、MaxNoOfConcurrentIndexOperations
、MaxNoOfConcurrentOperations
、MaxNoOfConcurrentScans
、MaxNoOfConcurrentTransactions
、MaxNoOfFiredTriggers
、MaxNoOfLocalScans
或TransactionBufferMemory
的任何设置(参见事务参数和事务临时存储)。
ReservedConcurrentIndexOperations
- 在一个数据节点上具有专用资源的同时索引操作数。
ReservedConcurrentOperations
- 在一个数据节点上具有专用资源的事务协调器上的同时操作数。
ReservedConcurrentScans
- 单个数据节点上具有专用资源的同时扫描数。
ReservedConcurrentTransactions
- 单个数据节点上具有专用资源的同时事务数。
ReservedFiredTriggers
- 单个 ndbd(DB)节点上具有专用资源的触发器数。
ReservedLocalScans
- 单个数据节点上具有专用资源的同时片段扫描数。
ReservedTransactionBufferMemory
- 为每个数据节点分配的键和属性数据的动态缓冲空间(以字节为单位)。
TransactionMemory
- 重要许多配置参数与
TransactionMemory
不兼容;不可能同时设置这些参数中的任何一个与TransactionMemory
,如果尝试这样做,管理服务器将无法启动(参见与 TransactionMemory 不兼容的参数)。此参数确定每个数据节点上为事务分配的内存(以字节为单位)。事务内存的设置如下处理:
- 如果设置了
TransactionMemory
,则此值用于确定事务内存。
- 否则,事务内存的计算与 NDB 8.0 之前的计算方式相同。
- 与 TransactionMemory 不兼容的参数。 以下参数不能与
TransactionMemory
同时使用,并在 NDB 8.0 中已弃用:
MaxNoOfConcurrentIndexOperations
MaxNoOfFiredTriggers
MaxNoOfLocalOperations
MaxNoOfLocalScans
- 当在集群配置文件(
config.ini
)中设置了TransactionMemory
时,显式设置上述任何参数会阻止管理节点启动。
有关 NDB 集群数据节点中资源分配的更多信息,请参见第 25.4.3.13 节,“数据节点内存管理”。
扫描和缓冲。 在Dblqh
模块(位于ndb/src/kernel/blocks/Dblqh/Dblqh.hpp
)中有额外的[ndbd]
参数影响读取和更新。这些包括ZATTRINBUF_FILESIZE
,默认设置为 10000 × 128 字节(1250KB),以及ZDATABUF_FILE_SIZE
,默认设置为 10000*16 字节(大约 156KB)的缓冲空间。迄今为止,用户没有任何报告,我们自己的广泛测试也没有任何结果表明这些编译时限制中的任何一个应该增加。
- 此参数用于计算用于处理并发扫描操作的锁记录数。
BatchSizePerLocalScan
与 SQL 节点中定义的BatchSize
有很强的关联。
在 NDB 8.0 中已弃用。
LongMessageBuffer
- 这是用于在单个节点内和节点之间传递消息的内部缓冲区。默认值为 64MB。
此参数很少需要从默认值更改。
MaxFKBuildBatchSize
- 用于构建外键的最大扫描批量大小。增加此参数设置的值可能加快构建外键的速度,但会对正在进行的流量产生更大的影响。
MaxNoOfConcurrentScans
- 此参数用于控制集群中可以执行的并行扫描数量。每个事务协调器可以处理为此参数定义的并行扫描数量。每个扫描查询通过并行扫描所有分区来执行。每个分区扫描在包含分区的节点上使用扫描记录,记录数量为此参数值乘以节点数量。集群应能够同时从集群中的所有节点并行支持
MaxNoOfConcurrentScans
扫描。
实际上有两种情况下执行扫描。第一种情况发生在没有哈希或有序索引来处理查询时,此时通过执行全表扫描来执行查询。第二种情况是在没有哈希索引支持查询但存在有序索引时遇到的情况。使用有序索引意味着执行并行范围扫描。顺序仅在本地分区上保持,因此需要在所有分区上执行索引扫描。
MaxNoOfConcurrentScans
的默认值为 256。最大值为 500。
MaxNoOfLocalScans
- 指定如果许多扫描未完全并行化,则本地扫描记录的数量。当未提供本地扫描记录数量时,计算如下所示:
4 * MaxNoOfConcurrentScans * [# data nodes] + 2
- 此参数在 NDB 8.0 中已弃用,并可能在将来的 NDB Cluster 版本中删除。此外,此参数与
TransactionMemory
参数不兼容;如果您尝试在集群配置文件(config.ini
)中为两个参数设置值,则管理服务器将拒绝启动。
MaxParallelCopyInstances
- 此参数设置了节点重启或系统重启的复制阶段中使用的并行化,当当前正在启动的节点与已经具有当前数据的节点同步时,通过从最新数据的节点复制任何更改的记录来实现。因为在这种情况下完全并行可能导致过载情况,
MaxParallelCopyInstances
提供了一种减少的方法。此参数的默认值为 0。这个值意味着有效的并行性等于刚刚启动的节点中的 LDM 实例数以及更新它的节点中的 LDM 实例数。
MaxParallelScansPerFragment
- 可以配置允许在开始排队进行串行处理之前允许的最大并行扫描数(
TUP
扫描和TUX
扫描)。您可以增加此值以利用在并行执行大量扫描时未使用的 CPU,并提高它们的性能。
MaxReorgBuildBatchSize
- 用于重新组织表分区的最大扫描批量大小。增加此参数的设置值可能加快重新组织的速度,但会对正在进行的流量产生更大的影响。
MaxUIBuildBatchSize
- 用于构建唯一键的最大扫描批量大小。增加此参数的设置值可能加快此类构建的速度,但会对正在进行的流量产生更大的影响。
内存分配
MaxAllocate
此参数在旧版本的 NDB 集群中使用,但在 NDB 8.0 中没有效果。自 NDB 8.0.27 起已弃用,并可能在将来的版本中删除。
多个传输器
从 8.0.20 版本开始,NDB
为数据节点之间的通信分配了多个传输器。所分配的传输器数量可以通过在该版本中引入的NodeGroupTransporters
参数设置适当的值来影响。
NodeGroupTransporters
此参数确定在同一节点组中的节点之间使用的传输器数量。默认值(0)意味着使用的传输器数量与节点中的 LDM 数相同。这对于大多数用例应该足够了,因此很少需要从默认值更改此值。
将NodeGroupTransporters
设置为大于 LDM 线程数或 TC 线程数中较高者的数字会导致NDB
使用这两个数字中较大的线程数。这意味着大于此值的值实际上会被忽略。
哈希映射大小
DefaultHashMapSize
此参数的原始预期用途是促进升级,特别是从非常旧的版本升级和降级到具有不同默认哈希映射大小的版本。当从 NDB Cluster 7.3(或更高版本)升级到更高版本时,这不是问题。
在任何表使用DefaultHashMapSize
等于 3840 创建或修改后在线减少此参数目前不受支持。
日志和检查点。 以下的[ndbd]
参数控制日志和检查点的行为。
- 设置此参数使您能够直接控制重做日志文件的大小。在 NDB Cluster 在高负载下运行且在尝试打开新的片段日志文件之前无法快速关闭片段日志文件的情况下,增加片段日志文件的大小可以给集群更多时间在尝试打开每个新的片段日志文件之前。此参数的默认值为 16M。
有关片段日志文件的更多信息,请参阅NoOfFragmentLogFiles
的描述。
InitialNoOfOpenFiles
- 此参数设置要为打开文件分配的内部线程的初始数量。
默认值为 27。
InitFragmentLogFiles
- 默认情况下,在数据节点进行初始启动时,片段日志文件会稀疏创建,也就是说,根据所使用的操作系统和文件系统,不一定所有字节都会写入磁盘。但是,可以通过这个参数来覆盖此行为,并强制写入所有字节,无论使用的平台和文件系统类型如何。
InitFragmentLogFiles
接受两个值:
SPARSE
。片段日志文件会稀疏创建。这是默认值。
FULL
。强制将片段日志文件的所有字节写入磁盘。
- 根据您的操作系统和文件系统,设置
InitFragmentLogFiles=FULL
可能有助于消除写入重做日志时的 I/O 错误。
EnablePartialLcp
- 当为
true
时,启用部分本地检查点:这意味着每个 LCP 仅记录部分完整数据库,以及自上次 LCP 以来更改的任何记录;如果没有更改行,则 LCP 仅更新 LCP 控制文件,而不更新任何数据文件。
如果EnablePartialLcp
被禁用(false
),每个 LCP 只使用一个文件并写入完整的检查点;这需要最少的 LCP 磁盘空间,但会增加每个 LCP 的写入负载。默认值为启用(true
)。部分 LCPS 使用的空间比例可以通过RecoveryWork
配置参数的设置进行修改。
有关用于完整和部分 LCP 的文件和目录的更多信息,请参阅 NDB 集群数据节点文件系统目录。
将此参数设置为false
还会禁用自适应 LCP 控制机制使用的磁盘写入速度的计算。
LcpScanProgressTimeout
- 本地检查点片段扫描看门狗定期检查每个本地检查点中执行的片段扫描是否没有进展,并在经过一定时间后没有进展时关闭节点。可以使用
LcpScanProgressTimeout
数据节点配置参数设置此间隔,该参数设置了本地检查点在 LCP 片段扫描看门狗关闭节点之前可以停滞的最长时间。
默认值为 60 秒(与先前版本兼容)。将此参数设置为 0 会完全禁用 LCP 片段扫描看门狗。
MaxNoOfOpenFiles
MySQL8 中文参考(八十七)(5)https://developer.aliyun.com/article/1565940