Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  The InnoDB Storage Engine  /  InnoDB Data-at-Rest Encryption

17.13 InnoDB 静态数据加密

InnoDB 支持静态数据加密 для 每个表文件 表空间、通用表空间mysql 系统表空间、重做日志和撤销日志。

您可以为模式和通用表空间设置加密默认值;这允许 DBA 控制在这些模式和表空间中创建的表是否加密。

InnoDB 静态数据加密功能和能力在本节的以下主题中描述。

关于静态数据加密

InnoDB 使用两层加密密钥架构,包括主加密密钥和表空间密钥。当表空间被加密时,表空间密钥被加密并存储在表空间头中。当应用程序或认证用户想要访问加密表空间数据时,InnoDB 使用主加密密钥来解密表空间密钥。解密后的表空间密钥从不改变,但主加密密钥可以根据需要更改。这项操作称为 主密钥轮换

静态数据加密功能依赖于密钥环组件或插件来管理主加密密钥。

所有 MySQL 版本都提供了 component_keyring_file 组件和 keyring_file 插件,每个都将密钥环数据存储在服务器主机的本地文件中。

MySQL Enterprise Edition 提供了附加的密钥环组件和插件:

  • component_keyring_encrypted_file: 将密钥环数据存储在服务器主机的本地、加密、密码保护的文件中。

  • keyring_encrypted_file: 将密钥环数据存储在服务器主机的本地、加密、密码保护的文件中。

  • keyring_okv:KMIP 1.1 插件,用于与 KMIP 兼容的后端密钥环存储产品。支持的 KMIP 兼容产品包括集中式密钥管理解决方案,如 Oracle Key Vault、Gemalto KeySecure、Thales Vormetric 密钥管理服务器和 Fornetix Key Orchestration。

  • keyring_aws:与 Amazon Web Services 密钥管理服务(AWS KMS)通信,以生成密钥,并使用本地文件进行密钥存储。

  • keyring_hashicorp:与 HashiCorp Vault 进行通信,以实现后端存储。

Warning

对于加密密钥管理,component_keyring_filecomponent_keyring_encrypted_file 组件,以及 keyring_filekeyring_encrypted_file 插件,不是为了符合监管合规性解决方案。安全标准如 PCI、FIPS 等要求使用密钥管理系统来保护、管理和保护加密密钥在密钥库或硬件安全模块(HSM)中。

一个安全且可靠的加密密钥管理解决方案对于安全和符合各种安全标准至关重要。当数据静态加密功能使用集中式密钥管理解决方案时,该功能被称为 MySQL 企业级透明数据加密(TDE)”

数据静态加密功能支持高级加密标准(AES)块加密算法。它使用 Electronic Codebook(ECB)块加密模式对表空间密钥进行加密,并使用 Cipher Block Chaining(CBC)块加密模式对数据进行加密。

关于数据静态加密功能的常见问题,请参阅 第 A.17 节,“MySQL 8.3 FAQ:InnoDB 数据静态加密”

加密先决条件

  • 必须在启动时安装和配置密钥环组件或插件。早期加载确保组件或插件在 InnoDB 存储引擎初始化之前可用。有关密钥环安装和配置说明,请参阅 第 8.4.4 节,“MySQL 密钥环”。说明显示如何确保所选组件或插件处于活动状态。

    一次只能启用一个密钥环组件或插件。启用多个密钥环组件或插件是不支持的,结果可能不如预期。

    Important

    一旦在 MySQL 实例中创建了加密表空间,就必须在启动时继续加载密钥环组件或插件。如果不这样做,将在服务器启动时和 InnoDB 恢复期间出现错误。

  • 在加密生产数据时,请确保采取措施防止主密钥丢失。如果主密钥丢失,存储在加密表空间文件中的数据将不可恢复。 如果使用 component_keyring_filecomponent_keyring_encrypted_file 组件,或者 keyring_filekeyring_encrypted_file 插件,请在创建第一个加密表空间后立即创建密钥环数据文件的备份,在主密钥轮换前和轮换后。对于每个组件,其配置文件将指示数据文件的位置。keyring_file_data 配置选项定义了 keyring_file 插件的密钥环数据文件位置。keyring_encrypted_file_data 配置选项定义了 keyring_encrypted_file 插件的密钥环数据文件位置。如果使用 keyring_okvkeyring_aws 插件,请确保您已经执行了必要的配置。有关说明,请参阅 第 8.4.4 节,“MySQL 密钥环”

定义模式和通用表空间的加密默认值

默认表加密 系统变量定义了模式和通用表空间的默认加密设置。CREATE TABLESPACECREATE SCHEMA 操作将应用 默认表加密 设置,当没有明确指定 ENCRYPTION 子句时。

ALTER SCHEMAALTER TABLESPACE 操作不应用 默认表加密 设置。必须明确指定 ENCRYPTION 子句以更改现有模式或通用表空间的加密。

可以使用 默认表加密 变量为个体客户端连接或全局设置使用 SET 语法。例如,以下语句启用了全局模式和表空间加密:

mysql> SET GLOBAL default_table_encryption=ON;

模式的默认加密设置也可以使用 DEFAULT ENCRYPTION 子句在创建或更改模式时定义,如下所示:

mysql> CREATE SCHEMA test DEFAULT ENCRYPTION = 'Y';

如果在创建模式时没有指定 DEFAULT ENCRYPTION 子句,则应用 默认表加密 设置。必须指定 DEFAULT ENCRYPTION 子句以更改现有模式的默认加密。

默认情况下,表继承了它所在的模式或通用表空间的加密设置。例如,在启用加密的模式中创建的表默认情况下是加密的。这使得 DBA 能够通过定义和实施模式和通用表空间加密默认值来控制表加密的使用。

加密默认值通过启用 table_encryption_privilege_check 系统变量来实施。当 table_encryption_privilege_check 启用时,在创建或更改模式或通用表空间时,如果加密设置与 默认表加密 设置不同,或者在创建或更改表时,如果加密设置与默认模式加密不同,将进行权限检查。当 table_encryption_privilege_check 禁用(默认情况),权限检查不发生,并且之前提到的操作将继续进行,但带有警告。

需要 TABLE_ENCRYPTION_ADMIN 权限来 override 默认加密设置,当 table_encryption_privilege_check 启用时。DBA 可以授予该权限,以便用户可以在创建或更改模式或通用表空间时偏离 默认表加密 设置,或者在创建或更改表时偏离默认模式加密。但是,该权限不允许偏离通用表空间的加密设置时创建或更改表。

文件每个表表空间加密

文件每个表表空间继承了所在模式的默认加密设置,除非在 CREATE TABLE 语句中明确指定了 ENCRYPTION 子句。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';

要更改现有文件每个表表空间的加密,必须指定 ENCRYPTION 子句。

mysql> ALTER TABLE t1 ENCRYPTION = 'Y';

表加密权限检查启用时,指定一个与默认模式加密不同的ENCRYPTION子句需要TABLE_ENCRYPTION_ADMIN权限。请参阅为模式和通用表空间定义加密默认值

通用表空间加密

变量default_table_encryption确定了新创建的通用表空间的加密,除非在CREATE TABLESPACE语句中明确指定了ENCRYPTION子句。

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' ENCRYPTION = 'Y' Engine=InnoDB;

要更改现有通用表空间的加密,必须指定ENCRYPTION子句。

mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';

如果table_encryption_privilege_check启用,指定一个与默认模式加密不同的ENCRYPTION子句需要TABLE_ENCRYPTION_ADMIN权限。请参阅为模式和通用表空间定义加密默认值

双写文件加密

在 MySQL 8.3 中,InnoDB 自动加密属于加密表空间的双写文件页。无需采取任何操作。双写文件页使用关联表空间的加密密钥进行加密。未加密表空间的双写文件页保持未加密状态。

在恢复期间,加密的双写文件页将被解密并检查是否损坏。

mysql 系统表空间加密

mysql 系统表空间包含 mysql 系统数据库和 MySQL 数据字典表。默认情况下,它未加密。要启用 mysql 系统表空间的加密,请在ALTER TABLESPACE语句中指定表空间名称和ENCRYPTION选项。

mysql> ALTER TABLESPACE mysql ENCRYPTION = 'Y';

要禁用 mysql 系统表空间的加密,请在ALTER TABLESPACE语句中设置ENCRYPTION = 'N'

mysql> ALTER TABLESPACE mysql ENCRYPTION = 'N';

启用或禁用 mysql 系统表空间的加密需要CREATE TABLESPACE权限在所有实例表上 (CREATE TABLESPACE on *.*)

重做日志加密

重做日志数据加密使用innodb_redo_log_encrypt配置选项启用。重做日志加密默认情况下禁用。

与表空间数据一样,重做日志数据加密发生在重做日志数据写入磁盘时,解密发生在重做日志数据从磁盘读取时。一旦重做日志数据读取到内存中,它将处于未加密状态。重做日志数据使用表空间加密密钥进行加密和解密。

innodb_redo_log_encrypt启用时,磁盘上的未加密重做日志页保持未加密,新的重做日志页以加密形式写入磁盘。同样,当innodb_redo_log_encrypt禁用时,磁盘上的加密重做日志页保持加密,新的重做日志页以未加密形式写入磁盘。

重做日志加密元数据,包括表空间加密密钥,存储在最新检查点LSN的重做日志文件头中。如果包含加密元数据的重做日志文件被删除,重做日志加密将被禁用。

一旦重做日志加密启用,正常重新启动without keyring组件或插件或加密密钥是不可能的,因为InnoDB必须在启动时扫描重做页,而这在重做日志页加密时是不可能的。没有keyring组件或插件或加密密钥,只能强制启动without redo日志(SRV_FORCE_NO_LOG_REDO)。见第17.20.3节,“强制InnoDB恢复”

撤销日志加密

撤销日志数据加密使用innodb_undo_log_encrypt配置选项启用。撤销日志加密适用于驻留在撤销表空间中的撤销日志。见第17.6.3.4节,“撤销表空间”。撤销日志数据加密默认情况下禁用。

与表空间数据一样,撤销日志数据加密发生在撤销日志数据写入磁盘时,解密发生在撤销日志数据从磁盘读取时。一旦撤销日志数据读取到内存中,它将以未加密形式存在。撤销日志数据使用表空间加密密钥加密和解密。

innodb_undo_log_encrypt启用时,磁盘上的未加密撤销日志页保持未加密,新的撤销日志页以加密形式写入磁盘。同样,当innodb_undo_log_encrypt禁用时,磁盘上的加密撤销日志页保持加密,新的撤销日志页以未加密形式写入磁盘。

撤销日志加密元数据,包括表空间加密密钥,存储在撤销日志文件头中。

Note

当撤销日志加密禁用时,服务器继续需要用于加密撤销日志数据的keyring组件或插件,直到包含加密撤销日志数据的撤销表空间被截断。(只有在撤销表空间被截断时,撤销表空间的加密头才会被删除。)有关截断撤销表空间的信息,请见截断撤销表空间

主密钥轮换

主加密密钥应该定期轮换,并在您怀疑密钥已被泄露时轮换。

主密钥轮换是一个原子级别的实例级操作。每次主加密密钥轮换时,所有表空间密钥在MySQL实例中都会被重新加密并保存回各自的表空间头中。作为原子操作,重新加密必须在一次轮换操作中成功。如果主密钥轮换在服务器失败时被中断,InnoDB将在服务器重新启动时继续操作。有关更多信息,请见加密和恢复

轮换主加密密钥只更改主加密密钥并重新加密表空间密钥,不会解密或重新加密关联的表空间数据。

轮换主加密密钥需要ENCRYPTION_KEY_ADMIN特权(或已弃用的SUPER特权)。

要轮换主加密密钥,请运行:

mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;

实例更改 ROTATE INNODB 主密钥 支持并发 DML。然而,它不能与表空间加密操作并发运行,并锁定以防止可能来自并发执行的冲突。如果 实例更改 ROTATE INNODB 主密钥 操作正在运行,必须在表空间加密操作之前完成,反之亦然。

加密和恢复

如果在加密操作期间发生服务器故障,操作将在服务器重新启动时继续执行。对于通用表空间,加密操作将在背景线程中从最后处理的页面继续。

如果在主密钥轮换期间发生服务器故障,InnoDB 将在服务器重新启动时继续操作。

密钥环组件或插件必须在存储引擎初始化之前加载,以便从表空间头部检索解密表空间数据页面所需的信息,然后 InnoDB 初始化和恢复活动访问表空间数据。(见 加密先决条件。)

InnoDB 初始化和恢复开始时,主密钥轮换操作将继续。由于服务器故障,一些表空间密钥可能已经使用新主加密密钥加密。InnoDB 从每个表空间头部读取加密数据,如果数据表明表空间密钥使用旧主加密密钥加密,InnoDB 将从密钥环中检索旧密钥,并使用它来解密表空间密钥。InnoDB 然后使用新主加密密钥重新加密表空间密钥,并将重新加密的表空间密钥保存回表空间头部。

导出加密表空间

仅支持文件每表表空间的表空间导出。

当加密表空间被导出时,InnoDB 生成一个 传输密钥,用于加密表空间密钥。加密表空间密钥和传输密钥被存储在 tablespace_name.cfp 文件中。该文件与加密表空间文件一起是执行导入操作所需的。在导入时,InnoDB 使用传输密钥来解密表空间密钥在 tablespace_name.cfp 文件中。有关信息,请参阅 第 17.6.1.3 节,“导入 InnoDB 表”

加密和复制

标识加密的表空间和模式

信息模式 INNODB_TABLESPACES 表包括一个 ENCRYPTION 列,可以用来标识加密的表空间。

mysql> SELECT SPACE, NAME, SPACE_TYPE, ENCRYPTION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
       WHERE ENCRYPTION='Y'\G
*************************** 1. row ***************************
     SPACE: 4294967294
      NAME: mysql
SPACE_TYPE: General
ENCRYPTION: Y
*************************** 2. row ***************************
     SPACE: 2
      NAME: test/t1
SPACE_TYPE: Single
ENCRYPTION: Y
*************************** 3. row ***************************
     SPACE: 3
      NAME: ts1
SPACE_TYPE: General
ENCRYPTION: Y

当在 CREATE TABLEALTER TABLE 语句中指定 ENCRYPTION 选项时,它将被记录在 INFORMATION_SCHEMA.TABLESCREATE_OPTIONS 列中。该列可以被查询以标识驻留在加密文件每表表空间中的表。

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES
       WHERE CREATE_OPTIONS LIKE '%ENCRYPTION%';
+--------------+------------+----------------+
| TABLE_SCHEMA | TABLE_NAME | CREATE_OPTIONS |
+--------------+------------+----------------+
| test         | t1         | ENCRYPTION="Y" |
+--------------+------------+----------------+

查询信息模式 INNODB_TABLESPACES 表以检索与特定模式和表关联的表空间信息。

mysql> SELECT SPACE, NAME, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME='test/t1';
+-------+---------+------------+
| SPACE | NAME    | SPACE_TYPE |
+-------+---------+------------+
|     3 | test/t1 | Single     |
+-------+---------+------------+

您可以通过查询信息模式 SCHEMATA 表来标识启用加密的模式。

mysql> SELECT SCHEMA_NAME, DEFAULT_ENCRYPTION FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE DEFAULT_ENCRYPTION='YES';
+-------------+--------------------+
| SCHEMA_NAME | DEFAULT_ENCRYPTION |
+-------------+--------------------+
| test        | YES                |
+-------------+--------------------+

SHOW CREATE SCHEMA 也显示 DEFAULT ENCRYPTION 子句。

监控加密进度

您可以使用 性能模式 监控一般表空间和 mysql 系统表空间加密进度。

阶段事件仪表 stage/innodb/alter tablespace (encryption) 报告 WORK_ESTIMATEDWORK_COMPLETED 信息,以监控一般表空间加密操作。

以下示例演示如何启用 stage/innodb/alter tablespace (encryption) 阶段事件仪表和相关消费者表,以监控一般表空间或 mysql 系统表空间加密进度。有关性能模式阶段事件仪表和相关消费者的信息,请参阅 第 29.12.5 节,“性能模式阶段事件表”

  1. 启用 stage/innodb/alter tablespace (encryption) 仪表:

    mysql> USE performance_schema;
    mysql> UPDATE setup_instruments SET ENABLED = 'YES'
           WHERE NAME LIKE 'stage/innodb/alter tablespace (encryption)';
  2. 启用阶段事件消费者表,包括 events_stages_currentevents_stages_historyevents_stages_history_long

    mysql> UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%';
  3. 运行表空间加密操作。在本示例中,一个名为 ts1 的一般表空间被加密。

    mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';
  4. 通过查询性能模式 events_stages_current 表来检查加密操作的进度。WORK_ESTIMATED 报告表空间中的总页数。WORK_COMPLETED 报告已处理的页数。

    mysql> SELECT EVENT_NAME, WORK_ESTIMATED, WORK_COMPLETED FROM events_stages_current;
    +--------------------------------------------+----------------+----------------+
    | EVENT_NAME                                 | WORK_COMPLETED | WORK_ESTIMATED |
    +--------------------------------------------+----------------+----------------+
    | stage/innodb/alter tablespace (encryption) |           1056 |           1407 |
    +--------------------------------------------+----------------+----------------+

    如果加密操作已完成,则 events_stages_current 表将返回一个空集。在这种情况下,您可以检查 events_stages_history 表以查看已完成操作的事件数据。例如:

    mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM events_stages_history;
    +--------------------------------------------+----------------+----------------+
    | EVENT_NAME                                 | WORK_COMPLETED | WORK_ESTIMATED |
    +--------------------------------------------+----------------+----------------+
    | stage/innodb/alter tablespace (encryption) |           1407 |           1407 |
    +--------------------------------------------+----------------+----------------+

加密使用注意事项

  • 当更改现有文件每表表空间时,请适当地计划,使用 ENCRYPTION 选项。驻留在文件每表表空间中的表使用 COPY 算法重建。使用 INPLACE 算法更改通用表空间或 mysql 系统表空间的 ENCRYPTION 属性。 INPLACE 算法允许在通用表空间中的表上执行并发 DML 操作。并发 DDL 操作被阻止。

  • 当通用表空间或 mysql 系统表空间被加密时,驻留在表空间中的所有表都将被加密。同样,在加密表空间中创建的表也将被加密。

  • 如果服务器在正常操作期间退出或停止,建议使用之前配置的相同加密设置重新启动服务器。

  • 第一个主加密密钥是在第一次加密表空间时生成的。

  • 主密钥轮换重新加密表空间密钥,但不更改表空间密钥本身。要更改表空间密钥,必须禁用并重新启用加密。对于文件每表表空间,重新加密表空间是一个 ALGORITHM=COPY 操作,重建表。对于通用表空间和 mysql 系统表空间,它是一个 ALGORITHM=INPLACE 操作,不需要重建表空间中的表。

  • 如果表是使用 COMPRESSIONENCRYPTION 选项创建的,那么压缩是在表空间数据加密之前执行的。

  • 如果密钥环数据文件(由 keyring_file_datakeyring_encrypted_file_data 指定的文件)为空或丢失,第一次执行 ALTER INSTANCE ROTATE INNODB MASTER KEY 将创建一个主加密密钥。

  • 卸载 component_keyring_filecomponent_keyring_encrypted_file 组件不会删除现有的密钥环数据文件。卸载 keyring_filekeyring_encrypted_file 插件也不会删除现有的密钥环数据文件。

  • 建议不要将密钥环数据文件放在与表空间数据文件相同的目录下。

  • 在运行时或重新启动服务器时修改 keyring_file_datakeyring_encrypted_file_data 设置可能会使之前加密的表空间变得不可访问,从而导致数据丢失。

  • 加密支持 InnoDB FULLTEXT 索引表,该表隐式创建于添加 FULLTEXT 索引时。有关信息,请参阅 InnoDB Full-Text Index Tables

加密限制

  • 高级加密标准(AES)是唯一支持的加密算法。InnoDB 表空间加密使用 Electronic Codebook(ECB)块加密模式对表空间密钥进行加密,并使用 Cipher Block Chaining(CBC)块加密模式对数据进行加密。CBC 块加密模式不使用填充。相反,InnoDB 确保要加密的文本是块大小的倍数。

  • 加密仅支持 文件每表 表空间、通用表空间mysql 系统表空间。加密不支持其他表空间类型,包括 InnoDB 系统表空间

  • 您不能将表从加密的 文件每表 表空间、通用表空间mysql 系统表空间移到不支持加密的表空间类型。

  • 您不能将表从加密表空间移到非加密表空间中。然而,将表从非加密表空间移到加密表空间中是允许的。例如,您可以将表从非加密的每个文件表通用表空间移到加密的通用表空间中。

  • 默认情况下,表空间加密仅适用于表空间中的数据。redo日志和undo日志数据可以通过启用innodb_redo_log_encryptinnodb_undo_log_encrypt来加密。请参阅redo日志加密undo日志加密。有关二进制日志文件和中继日志文件加密的信息,请参阅第19.3.2节,“加密二进制日志文件和中继日志文件”

  • 不允许更改驻留在或曾经驻留在加密表空间中的表的存储引擎。