开发者社区> zhaiwx_yinfeng> 正文

MySQL8.0: Serialized Dictionary Information(SDI) 浅析

简介:
+关注继续查看

SDI是Serialized Dictionary Information的缩写,是MySQL8.0重新设计数据词典后引入的新产物。我们知道MySQL8.0开始已经统一使用InnoDB存储引擎来存储表的元数据信息,但对于非InnoDB引擎,MySQL提供了另外一中可读的文件格式来描述表的元数据信息,在磁盘上以 $tbname.sdi的命名存储在数据库目录下。

你可以基于sdi文件来对非事务引擎表进行导出,导入操作,具体参阅官方文档

而对于InnoDB表没有创建sdi文件,而是将sdi信息冗余存储到表空间中(临时表空间和undo表空间除外)。

既然已经有了新的数据词典系统,为什么还需要冗余的sdi信息呢,这主要从几个方面考虑:

  • 当数据词典损坏时,实例可能拒绝启动,在这种情况下我们可以通过冗余的sdi信息,将数据拷贝到另外一个实例上,并进行数据重建
  • 可以离线的查看表的定义
  • 可以基于此实现简单的数据转储
  • MySQL Cluster/Ndb也可能依赖SDI信息进行元数据同步

官方提供了一个工具叫做ibd2sdi,在安装目录下可以找到,可以离线的将ibd文件中的冗余存储的sdi信息提取出来,并以json的格式输出到终端。

ibd2sdi工具的使用文档

相关worklog: WL#7069

下面简单的试玩下:

root@test 02:59:12>create table t1 (a int primary key, b char(10));
Query OK, 0 rows affected (0.02 sec)

通过ibd2sdi查看ibd文件

$bin/ibd2sdi data/test/t1.ibd
// 默认情况下打印所有信息
// 包含所有的列,索引的各个属性

也可以查询部分信息:

$bin/ibd2sdi --skip-data data/test/t1.ibd
["ibd2sdi"
,
{
        "type": 1,
        "id": 701
}
,
{
        "type": 2,
        "id": 235
}
]


$bin/ibd2sdi --id 235 data/test/t1.ibd
["ibd2sdi"
,
{
        "type": 2,
        "id": 235,
        "object":
                {
    "mysqld_version_id": 80011,
    "dd_version": 80011,
    "sdi_version": 1,
    "dd_object_type": "Tablespace",
    "dd_object": {
        "name": "test/t1",
        "comment": "",
        "options": "",
        "se_private_data": "flags=16417;id=212;server_version=80011;space_version=1;",
        "engine": "InnoDB",
        "files": [
            {
                "ordinal_position": 1,
                "filename": "./test/t1.ibd",
                "se_private_data": "id=212;"
            }
        ]
    }
}
}
]

当然还有很多其他的选项(ib2sdi --help),感兴趣的可以自行把玩。

首先ibd文件的第一个page中标记了是否存在sdi信息:FSP_FLAGS_POS_SDI,如果是从老版本(例如5.7)
物理恢复过来的数据,该标记位是未设置的。

在建表时,sdi相关堆栈如下:

ha_innobase::create
|--> innobase_basic_ddl::create_impl
    |--> create_table_info_t::create_table
        |--> create_table_info_t::create_table_def
            |--> row_create_table_for_mysql
                |--> dict_build_table_def
                    |--> dict_build_tablespace_for_table
                        |--> btr_sdi_create_index

btr_sdi_create_index:

  • 从代码来看,sdi index也是按照一个普通btree的标准函数(btr_create)来创建的,但其对应的page类型为FIL_PAGE_SDI
  • 内存中有一个和tablespace_id对应的dict_table_t对象,称作sdi table(dict_sdi_get_table), 表上包含4个列:

    • type
    • id
    • compressed_len
    • uncompressed_len
    • data(blob
  • sdi table的table_id从tablespace id中生成(dict_sdi_get_table_id)
  • sdi table上包含一个索引,索引列为(type, id), ref: dict_sdi_create_idx_in_mem
  • sdi pindex的root page no及sdi版本号被写到表空间的第一个page中(fsp_sdi_write_root_to_page)
  • 另外在之前版本中ibd文件的初始化大小为4个page,而到了8.0版本变成了7个page(FIL_IBD_FILE_INITIAL_SIZE),包括:
0: file space header
1: insert buffer bitmap
2: inode page
3: sdi index page
4: index page
5: freshly allocated page
6: freshly allocated page

在创建完table对象后,需要更新全局数据词典(create_table_info_t::create_table_update_global_dd)

写入tablespace信息到sdi中

innobase_basic_ddl::create_impl
|--> create_table_info_t::create_table_update_global_dd
    |--> dd_create_implicit_tablespace
        |--> create_dd_tablespace
            |--> dd::cache::Dictionary_client::store
                |--> dd::cache::Storage_adapter::store
                    |--> dd::sdi::store
                        |--> dd::sdi_tablespace::store_tsp_sdi
                            |--> dict_sdi_set

id=220

写入table信息到sdi中,包含了完整表的定义,每个列的属性信息等

ha_create_table
|-->dd::cache::Dictionary_client::update<dd::Table> 
    |-->dd::cache::Storage_adapter::store<dd::Table>
        |-->dd::sdi::store
            |-->dd::(anonymous namespace)::with_schema<long long unsigned int, dd::sdi::store
                |--> operator() 
                    |--> dd::sdi_tablespace::store_tbl_sdi
                        |--> apply_to_tablespaces //sdi_tablespace.cc:140
                            |--> ...
                                |--> dict_sdi_set
  • Server层提供的sdi接口:
[$/MySQL_8.0/sql/dd/impl]
$ls * | grep sdi
sdi_api.cc
sdi.cc
sdi_file.cc
sdi.h
sdi_impl.h
sdi_tablespace.cc
sdi_tablespace.h
sdi_utils.h
  • 构建sdi序列化词典信息的入口函数: dd::serialize, 这里会产生一个字符串,存储sdi信息
  • 调用innodb接口函数dict_sdi_set,将数据插入到其sdi index中,接口使用innodb api/api0api.cc(之前只由memcached使用)
  • 实际存储的数据是经过压缩的,压缩算法为zlib(Sdi_Compressor)
  • 向ibd中写入记录(ib_sdi_set),如果存在duplicate key,则更新记录
  • 之前介绍过sdi index中存在lob字段,其外部存储页的类型为FIL_PAGE_SDI_BLOB或者FIL_PAGE_SDI_ZBLOB
  • 当使用general tablespace时,sdi index中会存储多条数据

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
10019 0
使用SSH远程登录阿里云ECS服务器
远程连接服务器以及配置环境
13983 0
阿里云服务器怎么设置密码?怎么停机?怎么重启服务器?
如果在创建实例时没有设置密码,或者密码丢失,您可以在控制台上重新设置实例的登录密码。本文仅描述如何在 ECS 管理控制台上修改实例登录密码。
20697 0
腾讯云服务器 设置ngxin + fastdfs +tomcat 开机自启动
在tomcat中新建一个可以启动的 .sh 脚本文件 /usr/local/tomcat7/bin/ export JAVA_HOME=/usr/local/java/jdk7 export PATH=$JAVA_HOME/bin/:$PATH export CLASSPATH=.
14118 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
18999 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,云吞铺子总结大概有三种登录方式: 登录到ECS云服务器控制台 在ECS云服务器控制台用户可以更改密码、更换系统盘、创建快照、配置安全组等操作如何登录ECS云服务器控制台? 1、先登录到阿里云ECS服务器控制台 2、点击顶部的“控制台” 3、通过左侧栏,切换到“云服务器ECS”即可,如下图所示 通过ECS控制台的远程连接来登录到云服务器 阿里云ECS云服务器自带远程连接功能,使用该功能可以登录到云服务器,简单且方便,如下图:点击“远程连接”,第一次连接会自动生成6位数字密码,输入密码即可登录到云服务器上。
33623 0
使用NAT网关轻松为单台云服务器设置多个公网IP
在应用中,有时会遇到用户询问如何使单台云服务器具备多个公网IP的问题。 具体如何操作呢,有了NAT网关这个也不是难题。
35350 0
阿里云服务器安全组设置内网互通的方法
虽然0.0.0.0/0使用非常方便,但是发现很多同学使用它来做内网互通,这是有安全风险的,实例有可能会在经典网络被内网IP访问到。下面介绍一下四种安全的内网互联设置方法。 购买前请先:领取阿里云幸运券,有很多优惠,可到下文中领取。
19220 0
+关注
zhaiwx_yinfeng
MySQL内核开发者, 《高性能MySQL 第三版》译者之一,活跃于MySQL社区,BugList,etc...
224
文章
5
问答
来源圈子
更多
阿里云数据库:帮用户承担一切数据库风险,给您何止是安心!支持关系型数据库:MySQL、SQL Server、PostgreSQL、PPAS(完美兼容Oracle)、自研PB级数据存储的分布式数据库Petadata、自研金融级云数据库OceanBase支持NoSQL数据库:MongoDB、Redis、Memcache更有褚霸、丁奇、德哥、彭立勋、玄惭、叶翔等顶尖数据库专家服务。
+ 订阅
相关文档: 云数据库 OceanBase 版 可信账本数据库 云原生关系型数据库 PolarDB PostgreSQL引擎
文章排行榜
最热
最新
相关电子书
更多
JS零基础入门教程(上册)
立即下载
性能优化方法论
立即下载
手把手学习日志服务SLS,云启实验室实战指南
立即下载