MySQL TDE是表空间级加密,必须逐表显式启用ENCRYPTION='Y',且需满足版本≥8.0.13、innodb_file_per_table=ON、component_keyring_file组件ACTIVE等前提,缺一即导致静默失败或报错。

不能直接“开启整个数据库”的TDE——MySQL TDE是表空间级的,必须逐表显式启用,且前提条件缺一不可,否则ALTER TABLE ... ENCRYPTION='Y'会静默失败或报错。
确认 MySQL 是否真支持 TDE(不只是版本够)
光看 SELECT VERSION() 返回 8.0.33 不够。社区版可能根本没编译加密模块。执行:
SELECT * FROM information_schema.INNODB_ENCRYPTION;
如果报错 Table 'information_schema.INNODB_ENCRYPTION' doesn't exist,说明不支持,换 Percona Server 或企业版;再查:
SHOW VARIABLES LIKE 'have_innodb_encryption';
值必须为 YES;最后确认插件状态:
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'component_keyring_file';
状态必须是 ACTIVE(注意:8.0+ 社区版用的是 component_keyring_file,不是旧式的 keyring_file.so 插件)。
配置 component_keyring_file 组件(8.0+ 社区版唯一可用方案)
MySQL 8.0+ 社区版不再用 early-plugin-load,改用组件(component)机制,配置稍复杂但更严格:
-
plugin_dir路径下必须存在component_keyring_file.so(执行SHOW VARIABLES LIKE 'plugin_dir'查路径,然后ls $plugin_dir/component_keyring_*确认) - 在
mysqld可执行文件所在目录(如/usr/sbin/)创建全局 manifest 文件mysqld.my,内容为:{ "components": "file://component_keyring_file" }权限必须是644且mysql用户只读 - 在同一
plugin_dir下创建配置文件component_keyring_file.cnf,内容为:{ "path": "/var/lib/mysql-keyring/keyring" }路径需真实存在、由mysql用户拥有、chmod 750,且不能在tmpfs或 NFS 上 - 重启
mysqld,再查插件状态确认ACTIVE
对刚建好的表启用加密的实际命令与陷阱
假设你刚建了 CREATE TABLE users (id INT) ENGINE=InnoDB;,现在要加密它:
- 必须先确保该表用的是独立表空间:
SHOW CREATE TABLE users;中不能有TABLESPACE = innodb_system,且innodb_file_per_table必须为ON - 执行:
ALTER TABLE users ENCRYPTION='Y';—— 单引号不能省,ON或1会报错ERROR 3182 - 这不是元数据标记,而是触发全表重建(
ALGORITHM=COPY),锁表、消耗 I/O、要求磁盘剩余空间 ≥ 1.5 倍表大小 - 验证是否生效:
SELECT NAME, ENCRYPTION_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME = 'your_db/users';,返回AES才算成功 - 注意:已存在的数据页不会立刻重写,仍以明文躺在磁盘上,直到被 purge 或 page split 覆盖
为什么刚建的表加密后性能可能突降?
加密本身不慢,但高频小记录写入时容易踩坑:
- InnoDB 加密单位是 16KB 页,不是单行。若每行只有几个字节(如
INT + CHAR(2)),一页塞几十行,每次 INSERT 都触发整页 AES-CBC 加密 - AES-CBC 需前一页密文作 IV,无法并行加解密,CPU 在
aes_256_cbc_encrypt上耗时可能占单条 UPDATE 的 30%+ - redo log 默认不加密,要启用需额外设
innodb_redo_log_encrypt=ON(8.0.17+),否则审计不闭环 -
component_keyring_file把主密钥存本地文件,合规场景(等保三级、金融密评)不认可,生产环境应对接 KMS(如component_keyring_aws)
最常被忽略的一点:TDE 不加密 binlog、临时表、客户端传输过程,也不自动加密新创建的表——每个表都得单独 ALTER,漏一个就等于没加密。


















