#### 23.4.3.13 数据节点内存管理

数据节点的所有内存分配都是在节点启动时执行的。这保证了数据节点可以在不使用交换内存的情况下以稳定的方式运行，从而[`新开发银行`](mysql-cluster.html)可用于延迟敏感（实时）的应用程序。在数据节点启动时分配以下类型的内存：

-   数据存储器

-   共享全局内存

-   重做日志缓冲区

-   作业缓冲区

-   发送缓冲区

-   磁盘数据记录的页面缓存

-   模式事务内存

-   事务内存

-   撤消日志缓冲区

-   查询内存

-   块对象

-   模式记忆

-   块数据结构

-   长信号记忆

-   共享内存通信缓冲区

    这[`新开发银行`](mysql-cluster.html)管理大部分数据节点内存的内存管理器，处理以下内存资源：

-   数据存储器（[`数据存储器`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-datamemory))

-   重做日志缓冲区 ([`重做缓冲区`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-redobuffer))

-   作业缓冲区

-   发送缓冲区 ([`发送缓冲区内存`](mysql-cluster-tcp-definition.html#ndbparam-tcp-sendbuffermemory),[`总发送缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-totalsendbuffermemory),[`额外发送缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-extrasendbuffermemory),[`ReservedSendBufferMemory`](https://dev.mysql.com/doc/refman/5.6/en/mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedsendbuffermemory))

-   磁盘数据记录页缓存（[`磁盘页面缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-diskpagebuffermemory),[`DiskPageBufferEntries`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-diskpagebufferentries))

-   事务内存 ([`事务内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-transactionmemory))

-   查询内存

-   磁盘访问记录

-   文件缓冲区

    这些资源中的每一个都设置有保留的内存区域和最大的内存区域。保留的内存区域只能被保留的资源使用，不能与其他资源共享；给定资源分配的内存永远不能超过该资源允许的最大内存。没有最大内存的资源可以扩展为使用内存管理器中的所有共享内存。

    这些资源的全局共享内存大小由[`共享全局内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-sharedglobalmemory)配置参数（默认值：128 MB）。

    数据内存总是保留的，永远不会从共享内存中获取任何内存。它是使用控制[`数据存储器`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-datamemory)配置参数，最大为 16384 GB。`数据存储器`是存储记录的地方，包括哈希索引（每行大约 15 个字节）、有序索引（每个索引每行 10-12 个字节）和行标题（每行 16-32 个字节）。

    重做日志缓冲区也只使用保留内存；这是由[`重做缓冲区`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-redobuffer)配置参数，它设置每个 LDM 线程的重做日志缓冲区的大小。这意味着实际使用的内存量是该参数的值乘以数据节点中的 LDM 线程数。

    作业缓冲区仅使用保留内存；该内存的大小由下式计算[`新开发银行`](mysql-cluster.html)，基于各种类型的线程数。

    发送缓冲区有一个保留部分，但也可以额外分配 25% 的共享全局内存。发送缓冲区保留大小分两步计算：

1.  使用的值[`总发送缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-totalsendbuffermemory)配置参数（无默认值）或数据节点的所有单独连接使用的单独发送缓冲区的总和。一个数据节点连接到所有其他数据节点、所有 API 节点和所有管理节点。这意味着，在具有 2 个数据节点、2 个管理节点和 10 个 API 节点的集群中，每个数据节点有 13 个节点连接。由于默认值为[`发送缓冲区内存`](mysql-cluster-tcp-definition.html#ndbparam-tcp-sendbuffermemory)数据节点连接为 2 MB，总计 26 MB。

2.  为了获得发送缓冲区的总保留大小，[`额外发送缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-extrasendbuffermemory)配置参数，如果有的话（默认值 0）。与上一步获得的值相加。

    换句话说，如果`总发送缓冲区内存`已设置，发送缓冲区大小为`TotalSendBufferMemory + ExtraSendBufferMemory`;否则，发送缓冲区的大小等于`（[*`节点连接数`*] * SendBufferMemory) + ExtraSendBufferMemory`.

    磁盘数据记录的页面缓存仅使用保留资源；该资源的大小由[`磁盘页面缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-diskpagebuffermemory)配置参数（默认 64 MB）。还为 32 KB 磁盘页条目分配了内存；这些的数量由[`DiskPageBufferEntries`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-diskpagebufferentries)配置参数（默认 10）。

    事务内存有一个保留部分，可以通过以下方式计算`新开发银行`，或使用显式设置[`事务内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-transactionmemory)配置参数，在 NDB 8.0 中引入（以前，这个值总是由[`新开发银行`](mysql-cluster.html));事务内存也可以使用无限量的共享全局内存。事务内存用于处理事务、扫描、锁定、扫描缓冲区和触发操作的所有操作资源。在下一次提交将它们写入数据内存之前，它还保存更新的表行。

    以前，操作记录使用专用资源，其大小由许多配置参数控制。在 NDB 8.0 中，这些都是从公共事务内存资源分配的，也可以使用来自全局共享内存的资源。此资源的大小可以使用单个[`事务内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-transactionmemory)配置参数。

    撤销日志缓冲区的保留内存可以使用[`初始日志文件组`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-initiallogfilegroup)配置参数。如果创建撤消日志缓冲区作为[`创建日志文件组`](create-logfile-group.html)SQL语句，内存取自事务内存。

    许多与磁盘数据资源的元数据相关的资源也没有保留部分，并且仅使用共享的全局内存。因此，共享全局共享内存在发送缓冲区、事务内存和磁盘数据元数据之间共享。

    如果[`事务内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-transactionmemory)未设置，根据以下参数计算：

-   [`MaxNoOfConcurrentOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentoperations)

-   [`MaxNoOfConcurrentTransactions`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrenttransactions)

-   [`MaxNoOfFiredTriggers`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooffiredtriggers)

-   [`MaxNoOfLocalOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooflocaloperations)

-   [`MaxNoOfConcurrentIndexOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentindexoperations)

-   [`MaxNoOfConcurrentScans`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentscans)

-   [`MaxNoOfLocalScans`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooflocalscans)

-   [`BatchSizePerLocalScan`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-batchsizeperlocalscan)

-   [`事务缓冲区内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-transactionbuffermemory)

    什么时候[`事务内存`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-transactionmemory)显式设置，刚刚列出的配置参数都没有用于计算内存大小。此外，参数[`MaxNoOfConcurrentIndexOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentindexoperations),[`MaxNoOfFiredTriggers`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooffiredtriggers),[`MaxNoOfLocalOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooflocaloperations)， 和[`MaxNoOfLocalScans`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooflocalscans)不兼容`事务内存`并且不能与其同时设置；如果`事务内存`被设置并且这四个参数中的任何一个也被设置在`配置文件`配置文件，管理服务器无法启动。这四个参数在 NDB 8.0 中已弃用；期望它们从 MySQL NDB Cluster 的未来版本中删除。

    事务内存资源包含大量内存池。每个内存池代表一个对象类型，包含一组对象；每个池包括在启动时分配给池的保留部分；这个保留的内存永远不会返回到共享的全局内存。保留记录是使用只有一个级别的数据结构来找到的，以便快速检索，这意味着每个池中的许多记录都应该保留。每个池中保留记录的数量对性能和保留内存分配有一些影响，但通常只有在某些非常高级的用例中才需要显式设置保留大小。

    可以通过设置以下配置参数来控制池保留部分的大小：

-   [`ReservedConcurrentIndexOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedconcurrentindexoperations)

-   [`ReservedFiredTriggers`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedfiredtriggers)

-   [`保留并发操作`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedconcurrentoperations)

-   [`ReservedLocalScans`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedlocalscans)

-   [`ReservedConcurrentTransactions`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedconcurrenttransactions)

-   [`ReservedConcurrentScans`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedconcurrentscans)

-   [`ReservedTransactionBufferMemory`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-reservedtransactionbuffermemory)

    如果没有设置刚刚列出的参数，则保留设置为事务内存的 25%。保留记录的数量是每个数据节点；这些记录在每个节点上处理它们的线程（LDM 和 TC 线程）中拆分。大多数情况下，设置就足够了`事务内存`单独，并允许池中的记录数由其值控制。

[`MaxNoOfConcurrentScans`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentscans)限制每个TC线程中可以活动的并发扫描数。这对于防止集群过载非常重要。

[`MaxNoOfConcurrentOperations`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentoperations)限制在更新事务时可在任何时间激活的操作数。（简单读取不受此参数影响。）这个数量需要加以限制，因为有必要为节点故障处理预先分配内存，并且当遇到节点故障时，必须有一个资源来处理一个TC线程中最大数量的活动操作。当务之急是`MaxNoOfConcurrentOperations`在所有节点上设置为相同的数字（在`[ndbd默认值]`部分`配置。伊尼`全局配置文件）。而它的值可以通过滚动重启来增加（参见[第23.6.5节，“执行NDB集群的滚动重启”](mysql-cluster-rolling-restart.html))，以这种方式降低它被认为是不安全的，因为在滚动重启期间可能发生节点故障。

可以通过以下方式限制NDB集群中单个事务的大小：`MaxDmloperationsPertTransaction`参数如果未设置，则一个事务的大小受以下限制：`MaxNoOfConcurrentOperations`因为这个参数限制了每个TC线程的并发操作总数。

架构内存大小由以下一组配置参数控制：

-   [`MaxNoOfSubscriptions`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofsubscriptions)

-   [`MaxNoOfSubscribers`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofsubscribers)

-   [`MaxNoofConcurrent子操作`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofconcurrentsuboperations)

-   [`MaxNootFattributes`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofattributes)

-   [`MaxNoOfTables`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooftables)

-   [`MaxNoOfOrderedIndexes`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooforderedindexes)

-   [`MaxNoofuniquehashindex`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnoofuniquehashindexes)

-   [`MaxNoOfTriggers`](mysql-cluster-ndbd-definition.html#ndbparam-ndbd-maxnooftriggers)

    节点的数量和LDM线程的数量对模式内存的大小也有重大影响，因为每个表和每个分区（及其片段副本）中的分区数量必须在模式内存中表示。

    此外，在启动期间还会分配一些其他记录。这些相对较小。每个线程中的每个块都包含使用内存的块对象。与其他数据节点内存结构相比，该内存大小通常也非常小。
