InnoDB
支持对 每个表一个文件 表空间、通用 表空间、mysql
系统表空间、重做日志和撤销日志进行静态数据加密。
您可以为模式和通用表空间设置加密默认值;这允许 DBA 控制在这些模式和表空间中创建的表是否加密。
InnoDB
静态数据加密功能和功能在本节的以下主题中进行了描述。
InnoDB
使用两层加密密钥体系结构,包括主加密密钥和表空间密钥。当表空间被加密时,表空间密钥会被加密并存储在表空间头中。当应用程序或经过身份验证的用户想要访问加密表空间数据时,InnoDB
使用主加密密钥解密表空间密钥。表空间密钥的解密版本永远不会更改,但主加密密钥可以根据需要更改。此操作称为 主密钥轮换.
静态数据加密功能依赖于用于主加密密钥管理的密钥环组件或插件。
所有 MySQL 版本都提供 component_keyring_file
组件,该组件将密钥环数据存储在服务器主机本地文件。
MySQL 企业版提供额外的密钥环组件和插件
component_keyring_encrypted_file
:将密钥环数据存储在服务器主机本地加密的、受密码保护的文件中。keyring_okv
:用于与 KMIP 兼容的后端密钥环存储产品一起使用的 KMIP 1.1 插件。支持的 KMIP 兼容产品包括集中式密钥管理解决方案,例如 Oracle Key Vault、Gemalto KeySecure、Thales Vormetric 密钥管理服务器和 Fornetix Key Orchestration。keyring_aws
:与 Amazon Web Services 密钥管理服务 (AWS KMS) 通信作为密钥生成的后端,并使用本地文件进行密钥存储。keyring_hashicorp
:与 HashiCorp Vault 通信以进行后端存储。
对于加密密钥管理,component_keyring_file
和 component_keyring_encrypted_file
组件并非旨在用作监管合规解决方案。PCI、FIPS 等安全标准要求使用密钥管理系统来保护、管理和保护加密密钥,这些密钥存储在密钥库或硬件安全模块 (HSM) 中。
安全可靠的加密密钥管理解决方案对于安全性和符合各种安全标准至关重要。当静态数据加密功能使用集中式密钥管理解决方案时,该功能称为 “MySQL 企业版透明数据加密 (TDE)”.
静态数据加密功能支持高级加密标准 (AES) 块加密算法。它使用电子密码本 (ECB) 块加密模式进行表空间密钥加密,使用密码分组链接 (CBC) 块加密模式进行数据加密。
有关静态数据加密功能的常见问题解答,请参阅 第 A.17 节,“MySQL 9.0 常见问题解答:InnoDB 静态数据加密”.
必须在启动时安装和配置密钥环组件或插件。提前加载确保在初始化
InnoDB
存储引擎之前可以使用该组件或插件。有关密钥环安装和配置说明,请参阅 第 8.4.4 节,“MySQL 密钥环”。说明显示如何确保所选组件或插件处于活动状态。一次只能启用一个密钥环组件或插件。启用多个密钥环组件或插件不受支持,结果可能与预期不符。
重要在 MySQL 实例中创建加密表空间后,必须在启动时继续加载创建加密表空间时加载的密钥环组件或插件。否则,在启动服务器和执行
InnoDB
恢复时会导致错误。在加密生产数据时,请确保采取措施防止丢失主加密密钥。 如果丢失了主加密密钥,则存储在加密表空间文件中的数据将无法恢复。 如果使用
component_keyring_file
或component_keyring_encrypted_file
组件,请在创建第一个加密表空间后、在主密钥轮换之前以及在主密钥轮换之后立即备份密钥环数据文件。对于每个组件,其配置文件都指示数据文件位置。如果使用keyring_okv
或keyring_aws
插件,请确保已执行必要的配置。有关说明,请参见 第 8.4.4 节,“MySQL 密钥环”。
default_table_encryption
系统变量定义模式和通用表空间的默认加密设置。 CREATE TABLESPACE
和 CREATE SCHEMA
操作在未明确指定 ENCRYPTION
子句时应用 default_table_encryption
设置。
ALTER SCHEMA
和 ALTER TABLESPACE
操作不应用 default_table_encryption
设置。必须明确指定 ENCRYPTION
子句才能更改现有模式或通用表空间的加密。
default_table_encryption
变量可以为单个客户端连接或使用 SET
语法在全局范围内设置。例如,以下语句在全局范围内启用默认模式和表空间加密
mysql> SET GLOBAL default_table_encryption=ON;
模式的默认加密设置也可以使用 DEFAULT ENCRYPTION
子句在创建或更改模式时定义,例如以下示例
mysql> CREATE SCHEMA test DEFAULT ENCRYPTION = 'Y';
如果在创建模式时未指定 DEFAULT ENCRYPTION
子句,则应用 default_table_encryption
设置。必须指定 DEFAULT ENCRYPTION
子句才能更改现有模式的默认加密。否则,模式将保留其当前加密设置。
默认情况下,表会继承其创建所在模式或通用表空间的加密设置。例如,在启用加密的模式中创建的表默认情况下是加密的。此行为使 DBA 能够通过定义和强制执行模式和通用表空间加密默认值来控制表加密的使用情况。
通过启用 table_encryption_privilege_check
系统变量来强制执行加密默认值。当启用 table_encryption_privilege_check
时,在使用与 default_table_encryption
设置不同的加密设置创建或更改模式或通用表空间时,或在使用与默认模式加密不同的加密设置创建或更改表时,会进行权限检查。当禁用 table_encryption_privilege_check
(默认值)时,不会进行权限检查,并且允许上述操作继续进行,并发出警告。
TABLE_ENCRYPTION_ADMIN
权限是必需的,以便在启用 table_encryption_privilege_check
时覆盖默认加密设置。DBA 可以授予此权限以使用户能够在创建或更改模式或通用表空间时偏离 default_table_encryption
设置,或者在创建或更改表时偏离默认模式加密。此权限不允许偏离在创建或更改表时通用表空间的加密。表必须与其所在的通用表空间具有相同的加密设置。
每个表的文件表空间会继承创建该表所在的模式的默认加密,除非在 CREATE TABLE
语句中明确指定了 ENCRYPTION
子句。
mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';
要更改现有每个表的文件表空间的加密,必须指定 ENCRYPTION
子句。
mysql> ALTER TABLE t1 ENCRYPTION = 'Y';
如果启用 table_encryption_privilege_check
,则需要 TABLE_ENCRYPTION_ADMIN
权限才能指定与默认模式加密不同的设置的 ENCRYPTION
子句。请参见 定义模式和通用表空间的加密默认值。
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
,则需要 TABLE_ENCRYPTION_ADMIN
权限才能指定与 default_table_encryption
设置不同的设置的 ENCRYPTION
子句。请参见 定义模式和通用表空间的加密默认值。
在 MySQL 9.0 中,InnoDB
会自动加密属于加密表空间的双写文件页面。无需执行任何操作。双写文件页面使用关联的表空间的加密密钥进行加密。写入表空间数据文件的相同加密页面也会写入双写文件。属于未加密表空间的双写文件页面将保持未加密状态。
在恢复期间,加密的双写文件页面会解密并检查是否有损坏。
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 的重做日志文件标头中。如果删除具有加密元数据的重做日志文件,则重做日志加密将被禁用。
启用重做日志加密后,如果缺少密钥环组件或插件,或者缺少加密密钥,则无法正常重启,因为 InnoDB
必须能够在启动期间扫描重做页面,而如果重做日志页面已加密,则无法执行此操作。如果缺少密钥环组件或插件,或者缺少加密密钥,则只能强制执行不包含重做日志的启动(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
后,磁盘上存在的加密撤消日志页面将保持加密状态,新的撤消日志页面将以未加密形式写入磁盘。
撤消日志加密元数据(包括表空间加密密钥)存储在撤消日志文件标头中。
禁用撤消日志加密后,服务器将继续需要用于加密撤消日志数据的密钥环组件或插件,直到包含加密撤消日志数据的撤消表空间被截断。(只有在撤消表空间被截断后,才会从撤消表空间中删除加密标头。)有关截断撤消表空间的信息,请参见 截断撤消表空间。
应定期轮换主加密密钥,并且在怀疑密钥已被泄露时也应轮换密钥。
主密钥轮换是原子级的,实例级别的操作。每次主加密密钥轮换时,MySQL 实例中的所有表空间密钥都会重新加密并保存回各自的表空间头。作为原子操作,一旦开始轮换操作,所有表空间密钥的重新加密必须成功。如果主密钥轮换因服务器故障而中断,InnoDB
会在服务器重启时将操作向前推进。有关更多信息,请参见 加密和恢复。
轮换主加密密钥只会更改主加密密钥并重新加密表空间密钥。它不会解密或重新加密关联的表空间数据。
轮换主加密密钥需要 ENCRYPTION_KEY_ADMIN
权限(或已弃用的 SUPER
权限)。
要轮换主加密密钥,请运行
mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;
ALTER INSTANCE ROTATE INNODB MASTER KEY
支持并发 DML。但是,它不能与表空间加密操作同时运行,并且会采取锁定措施以防止并发执行可能产生的冲突。如果 ALTER INSTANCE ROTATE INNODB MASTER KEY
操作正在运行,则必须在表空间加密操作可以继续之前完成,反之亦然。
如果在加密操作期间发生服务器故障,则在服务器重启时将操作向前推进。对于常规表空间,加密操作将从最后一个处理的页面开始,在后台线程中继续进行。
如果在主密钥轮换期间发生服务器故障,InnoDB
将在服务器重启时继续该操作。
必须在存储引擎初始化之前加载密钥环组件或插件,以便在InnoDB
初始化和恢复活动访问表空间数据之前,可以从表空间头检索解密表空间数据页面的必要信息。(参见 加密先决条件。)
当 InnoDB
初始化和恢复开始时,主密钥轮换操作将恢复。由于服务器故障,一些表空间密钥可能已经使用新的主加密密钥加密。InnoDB
从每个表空间头读取加密数据,如果数据表明表空间密钥是使用旧的主加密密钥加密的,InnoDB
将从密钥环中检索旧密钥并使用它解密表空间密钥。然后,InnoDB
使用新的主加密密钥重新加密表空间密钥,并将重新加密的表空间密钥保存回表空间头。
仅支持每表文件表空间的表空间导出。
当导出加密表空间时,InnoDB
会生成一个 传输密钥,用于加密表空间密钥。加密的表空间密钥和传输密钥存储在
文件中。此文件连同加密的表空间文件一起,是执行导入操作所必需的。在导入时,tablespace_name
.cfpInnoDB
使用传输密钥来解密
文件中的表空间密钥。有关相关信息,请参见 第 17.6.1.3 节,“导入 InnoDB 表”。tablespace_name
.cfp
ALTER INSTANCE ROTATE INNODB MASTER KEY
语句仅在源和副本运行支持表空间加密的 MySQL 版本的复制环境中受支持。成功的
ALTER INSTANCE ROTATE INNODB MASTER KEY
语句将写入二进制日志,以便在副本上进行复制。如果
ALTER INSTANCE ROTATE INNODB MASTER KEY
语句失败,则不会记录到二进制日志,也不会在副本上进行复制。如果密钥环组件或插件安装在源上,但未安装在副本上,则
ALTER INSTANCE ROTATE INNODB MASTER KEY
操作的复制将失败。
信息架构 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 TABLE
或 ALTER TABLE
语句中指定 ENCRYPTION
选项时,它将记录在 INFORMATION_SCHEMA.TABLES
的 CREATE_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_ESTIMATED
和 WORK_COMPLETED
信息。
以下示例演示如何启用 stage/innodb/alter tablespace (encryption)
阶段事件仪器和相关消费者表,以监控常规表空间或 mysql
系统表空间加密进度。有关性能架构阶段事件仪器和相关消费者的信息,请参见 第 29.12.5 节,“性能架构阶段事件表”。
启用
stage/innodb/alter tablespace (encryption)
仪器mysql> USE performance_schema; mysql> UPDATE setup_instruments SET ENABLED = 'YES' WHERE NAME LIKE 'stage/innodb/alter tablespace (encryption)';
启用阶段事件消费者表,包括
events_stages_current
、events_stages_history
和events_stages_history_long
。mysql> UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%';
运行表空间加密操作。在此示例中,名为
ts1
的常规表空间已加密。mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';
通过查询性能架构
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
算法重建。更改常规表空间或mysql
系统表空间的ENCRYPTION
属性时,将使用INPLACE
算法。INPLACE
算法允许对驻留在常规表空间中的表进行并发 DML。并发 DDL 将被阻止。当加密常规表空间或
mysql
系统表空间时,驻留在表空间中的所有表都将被加密。同样,在加密表空间中创建的表也将被加密。如果服务器在正常操作期间退出或停止,建议使用之前配置的相同加密设置重启服务器。
当第一个新表空间或现有表空间被加密时,将生成第一个主加密密钥。
主密钥轮换会重新加密表空间密钥,但不会更改表空间密钥本身。要更改表空间密钥,必须禁用并重新启用加密。对于每表文件表空间,重新加密表空间是
ALGORITHM=COPY
操作,它会重建表。对于常规表空间和mysql
系统表空间,它是ALGORITHM=INPLACE
操作,它不需要重建驻留在表空间中的表。如果使用
COMPRESSION
和ENCRYPTION
选项创建表,则将在对表空间数据加密之前执行压缩。卸载
component_keyring_file
或component_keyring_encrypted_file
组件不会删除现有的密钥环数据文件。建议不要将密钥环数据文件放在与表空间数据文件相同的目录下。
加密支持在添加
FULLTEXT
索引时隐式创建的InnoDB
FULLTEXT
索引表。有关相关信息,请参见 InnoDB 全文索引表。
高级加密标准 (AES) 是唯一支持的加密算法。
InnoDB
表空间加密对表空间密钥加密使用电子密码本 (ECB) 块加密模式,对数据加密使用密码分组链接 (CBC) 块加密模式。CBC 块加密模式不使用填充。相反,InnoDB
确保要加密的文本是块大小的倍数。加密仅支持 每表文件 表空间、常规 表空间和
mysql
系统表空间。不支持其他表空间类型,包括InnoDB
系统表空间。您无法将表从加密表空间移动或复制到未加密的表空间。但是,允许将表从未加密的表空间移动到加密的表空间。例如,您可以将表从未加密的 每表文件 或 常规 表空间移动或复制到加密的常规表空间。
默认情况下,表空间加密仅应用于表空间中的数据。可以通过启用
innodb_redo_log_encrypt
和innodb_undo_log_encrypt
来加密重做日志和撤销日志数据。有关重做日志加密和撤销日志加密的更多信息,请参见 重做日志加密 和 撤销日志加密。有关二进制日志文件和中继日志文件加密的信息,请参见 第 19.3.2 节,“加密二进制日志文件和中继日志文件”。不允许更改位于加密表空间中或之前位于加密表空间中的表的存储引擎。