日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

發布時間:2023/12/3 数据库 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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中會存儲多條數據
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的MySQL8.0: Serialized Dictionary Information(SDI) 浅析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。