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

转自: https://yq.aliyun.com/articles/600183

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中会存储多条数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/330537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

非常有用的并发控制-倒计时器CountDownLatc

转载自 非常有用的并发控制&#xff0d;倒计时器CountDownLatch CountDownLatch见名思义&#xff0c;即倒计时器&#xff0c;是多线程并发控制中非常有用的工具类&#xff0c;它可以控制线程等待&#xff0c;直到倒计时器归0再继续执行。 给你出个题&#xff0c;控制5个线程执…

移除指定的session

在上次我写的文章中&#xff0c;我描述了如何把数据添加到session里面&#xff0c;再让临时表格读取session的数据显示到页面。 我们都知道&#xff0c;有添加就有移除对吧&#xff0c;哪么我们又该如何把临时表格里面的数据移除呢&#xff1f;嘿嘿&#xff0c;这个其实也挺简…

javap命令参数

C:\Users\pacoson>javap -help 用法: javap <options> <classes> 其中, 可能的选项包括:-help --help -? 输出此用法消息-version 版本信息-v -verbose 输出附加信息-l 输出行号和本地变量表-pub…

非常有用的并发控制-循环栅栏CyclicBarrier

转载自 非常有用的并发控制&#xff0d;循环栅栏CyclicBarrier昨天我讲了倒计时器CountDownLatch的应用&#xff0c;它是阻塞线程直到计时器归0的一种等待方式。今天讲的这个循环栅栏CyclicBarrier与倒计时器非常类似&#xff0c;但它比倒时器更加强大且稍微复杂&#xff0c;它…

一个会定时执行的方法

开发工具与关键技术&#xff1a;Visual Studio、MVC作者&#xff1a;幻奏撰写时间&#xff1a;2019.6.27我们在做项目的时候不是有一些要我们定时完成的任务吗&#xff1f;很多人应该都会用定时器来完成这个任务。我今天要讲的就是如何使用定时器的插件来完成我们今天的任务。 …

VC6.0下载及安装

转自&#xff1a; https://blog.csdn.net/weixin_37536336/article/details/81187963 希望对下载&#xff0c;并学习C语言的朋友&#xff0c;有帮助。 1.绿色版&#xff1a; 网址&#xff1a;https://pan.baidu.com/s/1jN70y8x6-_1XGJHESlMspA 密码&#xff1a;sla5 2.企业…

如何实现下拉框的绑定

开发工具与关键技术&#xff1a;Visual Studio、MVC 作者&#xff1a;幻奏 撰写时间&#xff1a;2019.7.5下拉框你们都见过吧&#xff0c;下拉框的作用是方便用户更快的输入&#xff0c;同时也限制了用户&#xff0c;再也不怕用户乱写啦。 下拉框我们该如何绑定呢&#xff0c;这…

volatile关键字解析~高级java必问

转载自 volatile关键字解析~高级java必问昨天我介绍了原子性、可见性、有序性的概念&#xff0c;那么今天就来见识下这些概念的主角-volatile关键字。volatile基本介绍volatile可以看成是synchronized的一种轻量级的实现&#xff0c;但volatile并不能完全代替synchronized&…

B树、B+树、B*树谈到R 树

转自&#xff1a; https://blog.csdn.net/v_JULY_v/article/details/6530142 从B 树、B 树、B* 树谈到R 树 作者&#xff1a;July、weedge、Frankie。编程艺术室出品。 说明&#xff1a;本文从B树开始谈起&#xff0c;然后论述B树、B*树&#xff0c;最后谈到R 树。其中B树、B树…

一个会定时完成的任务(二)

开发工具与关键技术&#xff1a;Visual Studio、MVC 作者&#xff1a;幻奏 撰写时间&#xff1a;2019.7.5上次我大概说了一下定时任务是如何实现的&#xff0c;由于我只是大概的说了那个插件是如何使用的&#xff0c;它的其他方法我还没和你们细说&#xff0c;所以&#xff0c;…

String.format()方法的使用

转载自 java字符串格式化&#xff1a;String.format()方法的使用常规类型的格式化 String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的读者应该记得C语言的sprintf()方法&#xff0c;两者有类似之处。format()方法有两种重载形式。 l form…

转-《高性能mysql》并不是一本好书——SQL笔记

转自&#xff1a; https://book.douban.com/review/8122660/ 版权归作者所有&#xff0c;任何形式转载请联系作者。 作者&#xff1a;姚泽源&#xff08;来自豆瓣&#xff09; 来源&#xff1a;https://book.douban.com/review/8122660/ 在知乎上发过一次&#xff0c;这里也发一…

实现模糊查询并忽略大小写

开发工具与关键技术&#xff1a;Visual Studio、MVC 作者&#xff1a;幻奏 撰写时间&#xff1a;2019.7.13我们在实现查询功能的时候&#xff0c;常常会用到模糊查询。这个呀&#xff0c;可是很重要的&#xff0c;当用户输入条件查询时&#xff0c;我们就要显示对应的数据&…

字符串拼接方式

转载自 java提高篇之字符串对于字符串而言我们经常是要对其进行拼装处理的&#xff0c;在java中提高了三种拼装的方法&#xff1a;、concat()以及append()方法。这三者之间存在什么区别呢&#xff1f;先看如下示例&#xff1a; public class StringTest {/*** desc 使用、conca…

用js比较时间大小

开发工具与关键技术&#xff1a;Visual Studio、js 作者&#xff1a;幻奏 撰写时间&#xff1a;2019.7.17对比时间的大小在很多项目里面都有用到&#xff0c;刚开始我还不会怎样比较时间的大小&#xff0c;后来上了老师的课之后&#xff0c;我才知道怎样比较时间的大小。 比较时…

独家:这也许是最具珍藏价值的Oracle DBA生存宝典!

转自&#xff1a; https://dbaplus.cn/news-10-1475-1.html 曾几何时&#xff0c;DBA一度被视为越老越吃香的职业&#xff0c;而从事数据库霸主Oracle的DBA更是风靡多时的技术人择业之选。 但随着Oracle自身技术的不断提升和完善&#xff0c;人手的操作不断被削弱&#xff0c;O…

StringTokenizer的使用

转载自 Java学习笔记--StringTokenizer的使用拓展&#xff1a;Pattern.split替代String.split http://www.cnblogs.com/gnivor/p/4386978.html StringTokenizer是一个用来分隔String的应用类 &#xff11;. 构造函数。1. StringTokenizer(String str) &#xff1a;构造一个用来…

Post请求如何取消异步

开发工具与关键技术&#xff1a;Visual Studio、post 作者&#xff1a;幻奏 撰写时间&#xff1a;2019.7.22其实关于异步这个问题我还不太懂&#xff0c;因为我还是一只萌新嘛&#xff0c;所以我在做项目时就出现了一个关于异步的问题。 我做的项目是一个客房管理系统&#xff…

Oracle必读好书推荐

转自&#xff1a;https://blog.csdn.net/notbaron/article/details/52305255 Oracle必读好书推荐 -------------------------------------------------------------------------- tkyte的书 1、Expert Oracle Database Architecture: 9i and 10g Programming Techniques and…

如何在linq使用左连接

开发工具与关键技术&#xff1a;Visual Studio、linq 作者&#xff1a;幻奏 撰写时间&#xff1a;2019.7.26我先说一下我的项目吧&#xff0c;上次就已经提过了&#xff0c;我做的是酒店的客房管理系统&#xff0c;首先要实现的是房态图&#xff0c;这个是根据房间的数量来新增…