一文读懂 OceanBase 数据库的启动恢复代码解析

作者简介:镜水,一个致力于无限进步的数据库学徒。
作者简介:海芊,一个致力于当网红的 OceanBase 文档工程师。个人频道:Amber loves OB

本文主要介绍 OceanBase 数据库启动时是如何将已持久化的日志和数据恢复到内存,重新形成各类信息(如租户信息、分区信息等)的内存映像,从而回到宕机前的状态。

在介绍具体的恢复流程之前,我们首先来了解一些与之相关的存储结构。

存储数据结构

MacroBlock

OceanBase 数据库将数据分为增量数据和基线数据,基线数据是几乎占满整个磁盘的一个超大文件,OceanBase 数据库以固定大小的宏块(MacroBlock,默认大小为 2 MB)为单位对磁盘上的基线数据进行管理,从而优化每日合并过程并高效利用磁盘空间,这类似于操作系统中内存的页式管理。宏块按照其在磁盘中的位置进行逻辑编号,起始编号为 0。

MacroBlockType 枚举类型标识了宏块有哪些种类:

enum MacroBlockType {
    Free = 0,							// 空闲宏块
    SSTableData = 1,					// 数据宏块,实际存放用户数据
    PartitionMeta = 2,					// 分区元数据宏块,通常以宏块链表的方式进行存储
    // SchemaData = 3,
    // Compressor = 4,
    MacroMeta = 5,						// 宏块元数据宏块,通常以宏块链表的方式进行存储
    Reserved = 6,
    MacroBlockSecondIndex = 7,  		// deprecated
    SortTempData = 8,
    LobData = 9,
    LobIndex = 10,
    TableMgrMeta = 11,					// 新版本已废弃
    TenantConfigMeta = 12,				// 租户配置元数据宏块,通常以宏块链表的方式进行存储
    BloomFilterData = 13,
    MaxMacroType,
  };

除此之外,类似于文件系统,宏块还有一种称为 Super Block 的特殊种类。Super Block 存放了整个基线数据的关键信息,比如元数据入口点和日志回放点,固定为第 0 块宏块,通常还有若干个备份块。

除了 Super Block 以外每个宏块都有一个 ObMacroBlockCommonHeader

struct ObMacroBlockCommonHeader {
  int32_t header_size_;  // struct size
  int32_t version_;      // header version
  int32_t magic_;        // magic number
  						 // each bits of the lower 8 bits represents:
  						 // is_free, sstable meta, tablet meta, compressor name, macro block meta, 0, 0, 0
  int32_t attr_;         // MacroBlockType
  union {
    uint64_t data_version_;  // sstable macro block: major version(48 bits) + minor version(16 bits)
    /**
     * For meta block, it is organized as a link block. The next block has a index point to
     * its previous block. The entry block index is store in upper layer meta (super block)
     * 0 or -1 means no previous block
     */
    int64_t previous_block_index_;
  };
  union {
    int64_t reserved_;
    struct {
      int32_t payload_size_;      // not include the size of common header
      int32_t payload_checksum_;  // crc64 of payload
    };
  };
};

NOTE:previous_block_index_ 为前向指针,通常为链式结构的元数据宏块,它表明从新到旧的一个前向关系。例如,下表所示宏块链表的写入顺序为 12345,但由于前向链接,读取时的入口点为 5,从而导致读取顺序为 54321,因此实际使用数据时,通常需要一次正向(54321)读取获取 block id 的数组后,再进行一次反向(12345)读取,从而得到正确的数据写入顺序。
在这里插入图片描述
在了解了数据块的基本单元 Macro Block 后,我们接着来介绍 Super Block 以及 Meta Block

由于历史原因,目前对于super block以及meta block的组织方式有新旧两个版本之分,下面我们将这两个版本分开介绍。

旧版本:

旧版本的 Super Block 和所有的 Meta Block 都在同一个大文件(如果对 observer 的执行目录有所了解的话,这个大文件可以理解为 sstable 目录下的 block_file)上。

Super Block

Super Block 可以简单理解为所有持久化数据的普遍元数据,其中包含了各种 Meta Block 的入口块(即宏块链表第一块)以及 SLog 的回放入口点(SLog 文件中的日志经过 checkpoint 后成为 Meta Block,这里的回放入口点即 SLog 中尚未经过 checkpoint 形成 meta 的日志偏移位置,如果将 Meta Block看作 meta 的基线数据,那么SLog 需要回放的日志可以理解为 meta 的增量数据),一般是前两个 macro block

struct ObSuperBlockHeader {
  static const int64_t OB_MAX_SUPER_BLOCK_SIZE = 64 * 1024;
  int32_t super_block_size_;  // not used any more
  int32_t version_;
  int32_t magic_;  // magic number
  int32_t attr_;   // reserved, set 0
};
struct ObSuperBlockV2 {
  struct MetaEntry {
    static const int64_t META_ENTRY_VERSION = 1;
    int64_t block_index_;  // first entry meta macro block id
    int64_t log_seq_;      // replay log seq
    int64_t file_id_;      // ofs file id
    int64_t file_size_;    // ofs file size
  };
  struct SuperBlockContent {
    static const int64_t SUPER_BLOCK_CONTENT_VERSION = 2;

    int64_t create_timestamp_;  // create timestamp
    int64_t modify_timestamp_;  // last modified timestamp
    int64_t macro_block_size_;
    int64_t total_macro_block_count_;
    int64_t free_macro_block_count_;
    int64_t total_file_size_;

    // entry of macro block meta blocks,
    common::ObLogCursor replay_start_point_;		// SLog 回放入口点
    MetaEntry macro_block_meta_;				    // macro block 元数据回放入口点
    MetaEntry partition_meta_;						// partition 元数据回放入口点
    MetaEntry table_mgr_meta_;						// table mgr 元数据回放入口点
    MetaEntry tenant_config_meta_;					// tenant config 元数据回放入口点
  };
  ObSuperBlockHeader he
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值