MySQL Cluster重启过程 (2) READ_CONFIG_REQ

READ_CONFIG_REQ对所有软件模块或多或少都相同。 它分配软件模块所需的内存并初始化内存(创建各种空闲列表等)。 它还读取模块感兴趣的各种配置参数(这些参数通常会影响我们分配的内存大小)。

原文

它从CMVMI开始,分配大部分全局内存池,接下来我们有NDBFS为磁盘数据创建必要的文件目录,它还创建一次可以由一个文件使用的绑定IO线程(初始线程数可配置) 通过InitalNoOpenFiles),然后它创建了一些磁盘数据文件(用于处理磁盘数据的所有文件)使用的空闲线程(它们可通过IOThreadPool配置的数量),每个这样的线程可用于打开/读取/写入/关闭 磁盘数据文件。 最后,NDBFS还会创建从文件系统线程返回到其他线程的通信通道。

所有其他模块遵循相同的标准,它们根据硬编码定义或通过配置变量计算多个大小,它们为这些变量分配内存,最后它们初始化那些分配的内存结构。

STTOR Phase 0

执行的第一个STTOR阶段是STTOR阶段0.在此阶段执行任何操作的唯一模块是NDBCNTR,如果启动是初始启动,则清除文件系统,CMVMI创建文件系统目录。

STTOR Phase 1

下一阶段执行的是STTOR阶段1,在此阶段,大多数模块初始化一些更多数据,必要时设置对相邻模块的引用。 此外,DBDIH创建了一些特殊的互斥锁,确保一次只能在代码的某些部分中涉及一个进程。

NDBCNTR在阶段2开始初始化与运行NDB_STTOR相关的一些数据。如果配置为这样,CMVMI将锁定内存,此后它会安装正常的监视程序超时,因为现在执行所有大内存分配。 CMVMI还启动定期内存报告。

QMGR是此阶段中最活跃的模块。 它初始化一些数据,它从DBDIH获得重启类型(初始启动或正常启动),它打开与集群中所有节点的通信,它开始检查包含节点处理的节点故障。 最后,它运行协议以将新节点包括在心跳协议中。 这可能需要一段时间,因为节点包含过程一次只能引入一个节点,并且协议包含一些延迟。
然后,BACKUP模块启动磁盘速度检查循环,该循环将在节点启动并运行时运行。

STTOR Phase 2

下一步是执行STTOR阶段2.在STTOR阶段2中执行任何操作的唯一模块是NDBCNTR,它要求DIH执行重启类型,它从配置中读取节点,它初始化控制多长时间的部分超时变量 在我们执行部分启动之前等待。

NDBCNTR将信号CNTR_START_REQ发送到当前主节点中的NDBCNTR,该信号使主节点能够在必要时由于其他起始节点或某些其他条件而延迟该节点的启动。 对于集群启动/重启,它还使主节点有机会确保在启动节点之前等待足够的节点启动。

主设备一次只接受一个接收CNTR_START_CONF的节点,下一个节点只能在前一个起始节点完成复制元数据并释放元数据锁并锁定DIH信息后接收CNTR_START_CONF,这在STTOR阶段5中发生。

因此,在滚动重启中,第一个节点将获得CNTR_START_CONF,然后在DICT锁定上被阻塞,等待LCP完成,这是很常见的。 并行启动的其他节点将在CNTR_START_CONF上等待,因为一次只有一个节点可以通过它。

收到CNTR_START_CONF后,NDBCNTR继续运行NDB_STTOR阶段1.此处DBLQH初始化节点记录,它启动报告服务。 它还初始化有关REDO日志的数据,这还包括在所有类型的初始启动时初始化磁盘上的REDO日志(可能非常耗时)。

DBDICT初始化模式文件(包含已在集群中创建的表和其他元数据对象)。 DBTUP初始化一个默认值片段,DBTC和DBDIH初始化一些数据变量。 完成NDBCNTR中的NDB_STTOR阶段后,STTOR阶段2中没有更多工作。

STTOR Phase 3

下一步是运行STTOR阶段3.大多数需要集群中节点列表的模块在此阶段读取此信息。 DBDIH在此阶段读取节点,DBDICT设置重启类型。 下一个NDBCNTR接收此阶段并启动NDB_STTOR阶段2.在此阶段,DBLQH设置从其操作记录到DBACC和DBTUP中的操作记录的连接。 这是针对所有DBLQH模块实例并行完成的。

DBDIH现在通过锁定元数据来准备节点重启过程。 这意味着我们将等待任何正在进行的元数据操作完成,并且当它完成时,我们将锁定元数据,这样在我们完成复制元数据信息的阶段之前,不能进行元数据更改。

锁定的原因是所有元数据和分发信息都是完全复制的。 因此,在将数据从主节点复制到起始节点时,我们需要锁定此信息。 虽然我们保留了此锁,但我们无法通过元数据事务更改元数据。 在稍后复制元数据之前,我们还需要确保没有运行本地检查点,因为这也会更新分发信息。

锁定后,我们需要请求从主节点启动节点的权限。 启动节点的许可请求由发送START_PERMREQ到主节点的起始节点处理。 如果另一个节点已在处理节点重启,则可能会收到否定答复,如果需要初始启动,则可能会失败。 如果另一个节点已经启动,我们将等待3秒钟再试一次。 这在DBDIH中作为NDB_STTOR阶段2的一部分执行。

在完成NDB_STTOR阶段2之后,STTOR阶段3继续由CMVMI模块激活对扫描和密钥操作使用的发送打包数据的检查。

接下来,BACKUP模块读取配置的节点。 接下来,SUMA模块设置对页面池的引用,以便它可以重用此全局内存池中的页面,然后DBTUX设置重新启动类型。 最后,PGMAN启动一个stats循环和一个清理循环,只要节点启动并运行,它就会运行。

如果我们的节点仍然涉及主节点中正在进行的某些进程,我们可能会崩溃节点。 这是相当正常的,只会触发一次崩溃,然后是天使进程正常的新启动。 权限请求由主服务器向所有节点发送信息来处理。

对于初始启动,权限请求可能非常耗时,因为我们必须使所有节点上元数据中所有表的所有本地检查点无效。 目前没有此失效过程的并行化,因此它将一次使一个表无效。

STTOR Phase 4

完成STTOR阶段3后,我们进入STTOR阶段4.此阶段由DBLQH在BACKUP模块中获取备份记录开始,该备份记录将用于本地检查点处理。

下一个NDBCNTR启动NDB_STTOR阶段3.这也在DBLQH中开始,我们在其中读取已配置的节点。 然后我们开始阅读REDO日志以进行设置(我们将在后台设置它,它将通过稍后描述的集群重启/节点重启的另一部分进行同步),对于所有类型的初始启动,我们将等到 REDO日志的初始化已经完成,直到报告此阶段完成为止。

下一个DBDICT将读取已配置的节点,然后DBTC将读取已配置的节点并启动事务计数器报告。 接下来在NDB_STTOR阶段3中,DBDIH初始化重启数据以进行初始启动。

在完成STTOR第4阶段的工作之前,NDBCNTR将设置一个等待点,使所有起始节点在继续之前达到此点。 这仅适用于群集启动/重新启动,因此不适用于节点重新启动。

主节点控制此等待点,并在集群重启的所有节点都达到此点时将信号NDB_STARTREQ发送到DBDIH。 稍后将详细介绍此信号。 STTOR阶段4中发生的最后一件事是DBSPJ读取配置的节点。

STTOR Phase 5

我们现在进入STTOR阶段5.这里做的第一件事是运行NDB_STTOR阶段4.只有DBDIH在这里做了一些工作,它只在节点重启时做了一些事情。 在这种情况下,它要求当前主节点通过向其发送START_MEREQ信号来启动它。

START_MEREQ的工作原理是从主DBDIH节点复制分发信息,然后从主DBDICT复制元数据信息。 它一次复制一个分发信息表,这使得该过程有点慢,因为它包括将表写入起始节点中的磁盘。

跟踪此事件的唯一方法是在起始节点中的DBDIH中将每个表的表分布信息写入。 我们可以跟踪在起始节点DBDICT中接收的DICTSTARTREQ的接收。

当复制DBDIH和DBDICT信息时,我们需要阻止全局检查点,以便从现在开始将新节点包含在元数据和分发信息的所有更改中。 这是通过将INCL_NODEREQ发送到所有节点来执行的。 在此之后,我们可以释放由DBDIH在STTOR阶段2中设置的元数据锁。

完成NDB_STTOR阶段4后,NDBCNTR以下列方式再次同步启动:

如果初始集群启动和主节点然后创建系统表如果集群启动/重新启动,则等待所有节点到达此点。 等待集群启动/重启中的节点后,在主节点中运行NDB_STTOR阶段5(仅发送到DBDIH)。 如果节点重新启动,则运行NDB_STTOR阶段5(仅发送到DBDIH)。

DBDIH中的NDB_STTOR阶段5正在等待本地检查点的完成(如果它是主设备)并且我们正在运行集群启动/重启。 对于节点重启,我们将信号START_COPYREQ发送到起始节点,要求将数据复制到我们的节点。