暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

[译文] MySQL 8.0:您需要了解的有关 SDI 的所有信息

原创 Frederic Descamps 2021-08-13
2237

我们最近看到MySQL 8.0 中的 MyISAM 表已经在某种程度上替换了.frm文件(参见这篇文章)。

但是,那些文件是什么?它们可以用于除 MyISAM 表之外的其他用途吗?… 让我们尝试回答这些问题并更熟悉.sdi文件。

SDI 代表什么?

SDI首字母缩写词代表序列化字典信息

图片.png

您可能已经知道,MySQL 8.0 取代了将表元数据及其结构存储到新事务数据字典(在 InnoDB 中)的旧方法。

此外,该信息也是任何 InnoDB 表空间的一部分,它被附加到表空间,因此元数据和数据捆绑在一起。

对于不支持此功能的存储引擎,会创建一个外部文件,即实际的SDI。例如,MyISAM 表就是这种情况。

他们看起来怎么样 ?
所以我们知道,对于没有能力存储表元数据的存储引擎,会创建一个 SDI 文件。它是什么样子的 ?

事实上,SDI 文件是一个紧凑的 JSON 文件。它的名称由表的名称和表的 id 组成。

如果我们采用上一篇文章中的示例表,在文件系统上,SDI 文件如下所示:

[root@imac my_isam_db]# ls -l *.sdi
-rw-r----- 1 mysql mysql 3600 8 月 2 日 12:49 t1_5017.sdi

5017 是表的隐藏 ID。

实际上,它是字典对象的 OID 的字符串表示形式。OID 确保唯一性,这是必需的,因为多个表可能映射到相同的名称。

现在让我们看看 JSON 是什么样子的:

{
  "mysqld_version_id": 80026,
  "dd_version": 80023,
  "sdi_version": 80019,
  "dd_object_type": "Table",
  "dd_object": {
    "name": "t1",
    "mysql_version_id": 80026,
    "created": 20210802104936,
    "last_altered": 20210802104936,
    "hidden": 1,
    "options": "avg_row_length=0;key_block_size=0;keys_disabled=0;pack_record=1;stats_auto_recalc=0;stats_sample_pages=0;",
    "columns": [
      {
        "name": "id",
        "type": 4,
        "is_nullable": false,
        "is_zerofill": false,
        "is_unsigned": true,
        "is_auto_increment": true,
        "is_virtual": false,
        "hidden": 1,
        "ordinal_position": 1,
        "char_length": 10,
        "numeric_precision": 10,
        "numeric_scale": 0,
        "numeric_scale_null": false,
        "datetime_precision": 0,
        "datetime_precision_null": 1,
        "has_no_default": false,
        "default_value_null": false,
        "srs_id_null": true,
        "srs_id": 0,
        "default_value": "AAAAAA==",
        "default_value_utf8_null": true,
        "default_value_utf8": "",
        "default_option": "",
        "update_option": "",
        "comment": "",
        "generation_expression": "",
        "generation_expression_utf8": "",
        "options": "interval_count=0;",
        "se_private_data": "",
        "engine_attribute": "",
        "secondary_engine_attribute": "",
        "column_key": 2,
        "column_type_utf8": "int unsigned",
        "elements": [],
        "collation_id": 8,
        "is_explicit_collation": false
      },
      {
        "name": "name",
        "type": 16,
        "is_nullable": true,
        "is_zerofill": false,
        "is_unsigned": false,
        "is_auto_increment": false,
        "is_virtual": false,
        "hidden": 1,
        "ordinal_position": 2,
        "char_length": 20,
        "numeric_precision": 0,
        "numeric_scale": 0,
        "numeric_scale_null": true,
        "datetime_precision": 0,
        "datetime_precision_null": 1,
        "has_no_default": false,
        "default_value_null": true,
        "srs_id_null": true,
        "srs_id": 0,
        "default_value": "",
        "default_value_utf8_null": true,
        "default_value_utf8": "",
        "default_option": "",
        "update_option": "",
        "comment": "",
        "generation_expression": "",
        "generation_expression_utf8": "",
        "options": "interval_count=0;",
        "se_private_data": "",
        "engine_attribute": "",
        "secondary_engine_attribute": "",
        "column_key": 1,
        "column_type_utf8": "varchar(20)",
        "elements": [],
        "collation_id": 8,
        "is_explicit_collation": false
      },
      {
        "name": "inserted",
        "type": 18,
        "is_nullable": false,
        "is_zerofill": false,
        "is_unsigned": false,
        "is_auto_increment": false,
        "is_virtual": false,
        "hidden": 1,
        "ordinal_position": 3,
        "char_length": 19,
        "numeric_precision": 0,
        "numeric_scale": 0,
        "numeric_scale_null": true,
        "datetime_precision": 0,
        "datetime_precision_null": 0,
        "has_no_default": false,
        "default_value_null": false,
        "srs_id_null": true,
        "srs_id": 0,
        "default_value": "AAAAAA==",
        "default_value_utf8_null": false,
        "default_value_utf8": "CURRENT_TIMESTAMP",
        "default_option": "CURRENT_TIMESTAMP",
        "update_option": "",
        "comment": "",
        "generation_expression": "",
        "generation_expression_utf8": "",
        "options": "interval_count=0;",
        "se_private_data": "",
        "engine_attribute": "",
        "secondary_engine_attribute": "",
        "column_key": 1,
        "column_type_utf8": "timestamp",
        "elements": [],
        "collation_id": 8,
        "is_explicit_collation": false
      }
    ],
    "schema_ref": "my_isam_db",
    "se_private_id": 18446744073709552000,
    "engine": "MyISAM",
    "last_checked_for_upgrade_version_id": 0,
    "comment": "",
    "se_private_data": "",
    "engine_attribute": "",
    "secondary_engine_attribute": "",
    "row_format": 2,
    "partition_type": 0,
    "partition_expression": "",
    "partition_expression_utf8": "",
    "default_partitioning": 0,
    "subpartition_type": 0,
    "subpartition_expression": "",
    "subpartition_expression_utf8": "",
    "default_subpartitioning": 0,
    "indexes": [
      {
        "name": "PRIMARY",
        "hidden": false,
        "is_generated": false,
        "ordinal_position": 1,
        "comment": "",
        "options": "flags=0;",
        "se_private_data": "",
        "type": 1,
        "algorithm": 2,
        "is_algorithm_explicit": false,
        "is_visible": true,
        "engine": "MyISAM",
        "engine_attribute": "",
        "secondary_engine_attribute": "",
        "elements": [
          {
            "ordinal_position": 1,
            "length": 4,
            "order": 2,
            "hidden": false,
            "column_opx": 0
          }
        ]
      }
    ],
    "foreign_keys": [],
    "check_constraints": [],
    "partitions": [],
    "collation_id": 8
  }
}

如您所见,此 SDI 文件包含大量信息。仅供参考,这是表的创建语句:

CREATE TABLE `t1` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `inserted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1

SDI 文件是否仅与 MyISAM 一起使用?

该 SDI 文件可用于使用特定语句IMPORT TABLE FROM在 MySQL 8.0 服务器周围复制 MySIAM 表。

SDI 文件还用于无法嵌入元数据信息的任何其他存储引擎。目前只有 InnoDB 和 NDB 不需要任何 SDI 文件。

如果您创建一个 CVS 表,它也会有一个 SDI:

CREATE TABLE `t2` (
  `id` int unsigned NOT NULL,
  `name` varchar(20) NOT NULL DEFAULT '',
  `inserted` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=CSV DEFAULT CHARSET=latin1

[root@imac my_isam_db]# ls -l t2*
-rw-r----- 1 mysql mysql 3268 Aug 11 13:27 t2_5037.sdi
-rw-r----- 1 mysql mysql   35 Aug 11 13:27 t2.CSM
-rw-r----- 1 mysql mysql    0 Aug 11 13:27 t2.CSV

当然,我们也可以从 SDI 文件中检查该信息:

[root@imac my_isam_db]# cat t2_5037.sdi | jq ."dd_object"."engine"
"CSV"

SDI 文件提供元数据冗余。即使对于 InnoDB 表,如果数据字典变得不可用,它也很有用,可以直接从 InnoDB 表空间文件中提取对象元数据。

SDI 信息和 InnoDB

对于 InnoDB 表,可以使用名为ibd2sdi的工具从表空间中提取 SDI 信息。

ibd2sdi 可以在file-per-table 表空间文件(.ibd 文件)、通用表空间文件(.ibd 文件)、系统表空间文件(ibdata* 文件)和数据字典表空间(mysql.ibd)上运行。不支持与临时表空间或撤消表空间一起使用。

让我们用 InnoDB 试试。我刚刚创建了另一个表((t3),就像之前的表一样,但使用 InnoDB 作为存储引擎,并且确实在架构目录中我们可以看到这个单个.ibd文件:

[root@imac my_isam_db]# ls
t1_5017.sdi t1.MYD t1.MYI t2_5037.sdi t2.CSM t2.CSV   t3.ibd

现在我们可以从中生成一个 SDI 文件:

# ibd2sdi t3.ibd -d t3.sdi

我们可以解析新创建的 SDI 文件,但 MySQL 不需要它,它只是元数据的额外副本。

我可以手动修改现有的 SDI 文件吗?

当然,这是不推荐的。但是,如果在表已经在 MySQL 中之后删除或修改.sdi文件,服务器将不需要它,因为该结构已经是数据字典的一部分。

每次使用需要 SDI 文件的引擎修改表时,具有不同 OID 编号的新文件将替换最终的前一个文件。

文章来源:https://blogs.oracle.com/mysql/mysql-80%3a-all-you-need-to-know-about-sdi

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论