MySQL Cluster重启过程(3) START OF DATABASE RECOVERY

  • LCP:本地检查点,在NDB中,这意味着主内存中的所有数据都写入磁盘,我们还将更改的磁盘页写入磁盘,以确保磁盘上某个点之前的所有更改都可用。 执行REDO日志:这意味着我们一次读取REDO日志一条REDO日志记录,并在需要时执行REDO日志记录中的操作。
  • Apply the REDO log:执行REDO日志的同义词。

  • Prepare REDO log record: 这是一个REDO日志记录,包含有关数据库更改的信息(插入/删除/更新/写入)。

  • COMMIT REDO log:这是一个REDO日志记录,指定要实际执行Prepare REDO日志记录。 COMMIT REDO日志记录包含Prepare REDO日志记录的后向引用。

  • ABORT REDO log record:与COMMIT REDO日志记录类似,但此处事务已中止,因此无需应用REDO日志记录。

  • Database:在此上下文中表示当节点重新启动时驻留在集群或节点中的所有数据。

  • Off-line Database:意味着我们节点中的数据库不在线,因此不能用于读取。 这是恢复LCP后但在应用REDO日志之前的数据库状态。

  • Off-line Consistent database:这是一个数据库状态,它与最新的更改不是最新的,但它表示先前存在的数据库中的旧状态。 恢复LCP并执行REDO日志后,即可实现此状态。

  • On-line Database:这是一个最新的数据库状态,任何可用于读取数据的节点都有其数据库在线(实际上片段是逐个联机的)。
  • On-line Recoverable Database:这是一个也可以恢复的在线数据库。 在节点重启中,我们首先到达状态在线数据库,但是我们需要运行LCP,然后数据库也可以恢复到其当前状态。 可恢复的数据库也是持久的,这意味着当我们达到此状态时,我们将ACID中的D添加到数据库中。
  • Node:有API节点,数据节点和管理服务器节点。 数据节点是ndbd / ndbmtd进程,它运行所有数据库逻辑并包含数据库数据。 管理服务器节点是运行包含群集配置的ndb_mgmd并且还执行许多管理服务的进程。 API节点是应用程序进程的一部分,在mysqld中。 每个应用程序进程可以有多个API节点。 每个API节点通过套接字(或其他通信介质)连接到每个数据节点和管理服务器节点。 当一个人引用本文中的节点时,我们主要暗示的是我们在谈论一个数据节点。
  • Node Group:一组数据节点,它们都包含相同的数据。 节点组中的节点数等于我们在集群中使用的副本数。
  • Fragment:表的一部分,完全存储在一个节点组中。
  • Partition:Synonym of fragment.
  • Fragment replica:这是一个节点中的一个片段。 一个片段最多可以有4个副本(因此节点组中最多可以有4个节点)。
  • Distribution information: 这是有关表的分区(片段的同义词)以及它们驻留在哪些节点上的信息,以及有关在每个片段副本上执行的LCP的信息。
  • Metadata:这是有关表,索引,触发器,外键,哈希映射,文件,日志文件组,表空间的信息。 字典信息:元数据的同义词。
  • LDM:代表本地数据管理器,这些是执行处理一个数据节点内处理的数据的代码的块。 它包含处理元组存储的块,哈希索引,T树索引,页面缓冲区管理器,表空间管理器,写入LCP的块和恢复LCP的块,磁盘数据的日志管理器。

作为START_COPYREQ的一部分,真正的数据库恢复过程是什么。 这里执行大多数重要的数据库恢复算法以使数据库再次联机。 仍需要早期阶段来恢复元数据和设置通信,设置内存并将起始节点作为数据节点集群中的完整公民。

START_COPYREQ遍历所有分发信息,并将START_FRAGREQ发送到拥有的DBLQH模块实例,以便在节点上恢复每个片段副本。 DBLQH将立即启动以恢复这些片段副本,它将对片段副本进行排队并一次恢复一个。 这发生在两个阶段,首先需要恢复本地检查点的所有片段副本开始这样做。

在发送了所有要恢复的片段副本之后,我们已经从存储在磁盘上的本地检查点恢复了所有片段(或者有时通过从活动节点获取整个片段),然后是运行磁盘数据UNDO日志的时候了。 最后,在运行此UNDO日志之后,我们已准备好通过应用REDO日志将片段副本恢复到最新的磁盘持久状态。

DBDIH将所有片段副本的所有必需信息发送到DBLQH,然后它将START_RECREQ发送到DBLQH以指示现在已发送所有片段副本信息。

START_RECREQ通过DBLQH代理模块发送,并且该部分被并行化,以便所有LDM实例并行执行以下部分。

如果我们正在进行初始节点重启,我们不需要恢复任何本地检查点,因为初始节点重启意味着我们在没有文件系统的情况下启动。 所以这意味着我们必须从节点组中的其他节点恢复所有数据。 在这种情况下,当我们收到START_FRAGREQ时,我们立即开始在DBLQH中应用片段副本的复制。 在这种情况下,我们不需要运行任何撤消或重做日志,因为没有本地检查点来恢复片段。

完成此操作后,DBDIH报告已通过将START_RECREQ发送到DBLQH发送了所有要启动的片段副本,我们将向TSMAN发送START_RECREQ,之后我们将完成数据的恢复。

我们将指定要作为REDO日志执行的一部分进行恢复的所有片段副本。 这是通过信号EXEC_FRAGREQ完成的。 当所有这些信号都被发送后,我们发送EXEC_SRREQ表示我们已经准备好在DBLQH中执行下一个REDO日志执行阶段。

当发送所有这些信号时,我们已经完成了所谓的DBLQH的第2阶段,DBLQH中的阶段1是在NDB_STTOR阶段3中开始准备REDO日志以进行读取。 因此,当这两个阶段都完成时,我们就可以开始在DBLQH中开始所谓的阶段3。

这些DBLQH阶段与启动阶段无关,这些阶段是DBLQH模块中启动的内部阶段。

DBLQH中的第3阶段是读取REDO日志并将其应用于从本地检查点恢复的片段副本。 这是创建在特定全局检查点上同步的数据库状态所必需的。 因此,我们首先为所有片段安装本地检查点,接下来我们应用REDO日志将片段副本与某个全局检查点同步。

在执行REDO日志之前,我们需要通过检查我们将恢复到所需全局检查点的所有片段副本的限制来计算要在REDO日志中应用的起始GCI和最后一个GCI。

DBDIH已存储有关片段副本的每个本地检查点的信息,这些信息是从REDO日志运行所需的全局检查点范围,以使其进入某个全局检查点的状态。 此信息已在START_FRAGREQ信号中发送。 DBLQH会将每个片段副本的所有这些限制合并到全局范围的全局检查点,以便为此LDM实例运行。 因此每个片段副本都有自己的GCP id范围来执行,这意味着所有这些起始范围的最小值和所有结束范围的最大值是我们需要在REDO日志中执行以引入集群的全局GCP ID范围 再次在线。

下一步是使用start和stop全局检查点id计算每个日志部分的REDO日志中的开始和停止兆字节。 计算这个所需的所有信息已经在内存中,所以这是一个纯粹的计算。

当我们执行REDO日志时,实际上我们只在正确的全局检查点范围内应用COMMIT记录。 COMMIT记录和实际更改记录位于REDO日志中的不同位置,因此对于每兆字节的REDO日志,我们记录REDO日志中我们必须返回多长时间才能找到更改记录。

在运行REDO日志时,我们维护一个相当大的REDO日志缓存,以避免在事务运行很长时间的情况下我们必须执行磁盘读取。

这意味着长时间运行和大型事务可能会对重新启动时间产生负面影响。

在所有日志部分完成此计算后,我们现在准备开始执行REDO日志。 在执行REDO日志完成后,我们还会在REDO日志中写入一些内容,以表明我们之前使用的任何信息都不会在以后使用。

我们现在需要等待所有其他日志部分也完成其REDO日志部分的执行。 REDO日志执行的设计使我们可以在多个阶段执行REDO日志,这适用于我们可以从多个活动节点重建节点的情况。 目前绝不应使用此代码。

因此,下一步是检查REDO日志部件的新头部和尾部。 这是通过使用启动和停止全局检查点来计算此数字的相同代码完成的。 代码的这一阶段还通过确保正确的REDO日志文件打开来准备REDO日志部分以编写新的REDO日志记录。 它还涉及一些相当棘手的代码,以确保正确处理已脏的页面。