一、前置准备
1. 硬件软件要求
需要已安装的MySQL 8.0.16+ 企业版/社区版(社区版需使用plugin_keyring_file插件)的Windows/Linux/Mac设备,预留至少100MB磁盘空间用于存放加密插件密钥文件,服务器CPU需支持AES-NI指令集(可通过`lscpu | grep aes`或Windows任务管理器-性能-CPU查看)。
2. 创建加密密钥专用目录
- Linux/Mac:执行以下命令创建并设置权限(权限必须严格700,否则插件无法读取密钥):
```bash
sudo mkdir -p /var/lib/mysql-keyring
sudo chown mysql:mysql /var/lib/mysql-keyring
sudo chmod 700 /var/lib/mysql-keyring
```
- Windows:在MySQL数据目录(默认C:\ProgramData\MySQL\MySQL Server 8.0\Data)同级新建`mysql-keyring`文件夹,右键属性-安全,删除所有继承权限,只保留MySQL服务运行用户(默认NT AUTHORITY\NetworkService)的完全控制权限。
二、配置MySQL加载加密插件
1. 编辑配置文件
找到并打开MySQL配置文件(Linux/Mac默认/etc/my.cnf,Windows默认C:\ProgramData\MySQL\MySQL Server 8.0\my.ini),在[mysqld]节点末尾添加完整配置项(无需注释):
- 所有平台通用核心配置:
```ini
启用plugin_keyring_file插件
early-plugin-load=keyring_file.so
Linux/Mac密钥文件路径
keyring_file_data=/var/lib/mysql-keyring/keyring
Windows密钥文件路径(将Data同级目录替换为实际路径)
keyring_file_data=C:\ProgramData\MySQL\MySQL Server 8.0\mysql-keyring\keyring
强制所有新建表使用加密(可选,若不加需手动指定ENCRYPTION='Y')
default_table_encryption=ON
禁止未加密表的创建(可选,强制合规性)
table_encryption_privilege_check=ON
```
注意:Windows下early-plugin-load的.so要换成.dll吗?MySQL 8.0社区版Windows下插件后缀仍为.so,无需修改。
2. 重启MySQL服务
- Linux(systemd管理):
```bash
sudo systemctl restart mysqld
```
- Mac(Homebrew安装):
```bash
brew services restart mysql
```
- Windows(管理员CMD):
```cmd
net stop MySQL80
net start MySQL80
```
3. 验证插件加载与密钥生成
登录MySQL(使用root或有PROCESS权限的用户):
```bash
mysql -u root -p
```
执行以下两个验证命令,结果必须符合预期:
- 验证插件状态(ACTIVE必须为YES):
```sql
SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%';
```
- 验证密钥文件是否存在(可以直接在之前创建的目录中查看是否生成keyring文件,也可以用SQL查询内部密钥状态):
```sql
SELECT FROM performance_schema.keyring_keys;
```
三、加密已有数据与新建表
1. 加密已有普通表
注意:加密大表需预留双倍表大小的磁盘空间,加密过程会锁表(MySQL 8.0.12+支持Online DDL,但建议业务低峰期操作)。
执行以下SQL,将`test_db`和`test_table`替换为实际库名和表名:
```sql
USE test_db;
-- 查看当前表是否加密(CREATE_OPTIONS为空表示未加密)
SHOW CREATE TABLE test_table;
-- 执行加密(指定AES-256-CBC算法,这是TDE默认算法,无需额外指定)
ALTER TABLE test_table ENCRYPTION='Y';
-- 再次验证
SHOW CREATE TABLE test_table;
```
2. 新建加密表

如果在配置文件中开启了`default_table_encryption=ON`,直接建表即可自动加密;如果未开启,需手动添加`ENCRYPTION='Y'`参数:
```sql
USE test_db;
CREATE TABLE encrypted_table (
id INT PRIMARY KEY AUTO_INCREMENT,
data VARCHAR(255) NOT NULL
) ENCRYPTION='Y';
```
四、验证数据加密效果
1. 模拟明文窃取场景验证
直接打开MySQL数据目录下的ibd文件(表空间文件),分别查看加密前和加密后的内容:
- 未加密:使用记事本/less命令可直接看到存储的明文数据(比如之前建表插入的"data content");
- 加密后
2. 业务操作验证
加密后的表对业务完全透明,执行增删改查无需修改任何代码:
```sql
USE test_db;
-- 插入数据
INSERT INTO encrypted_table (data) VALUES ('透明加密测试数据123');
-- 查询数据
SELECT FROM encrypted_table;
-- 更新数据
UPDATE encrypted_table SET data = '更新后的加密测试数据' WHERE id = 1;
-- 删除数据
DELETE FROM encrypted_table WHERE id = 1;
```
所有操作应与未加密表完全一致,性能损耗在5%以内(官方测试数据,受硬件AES-NI影响)。
五、密钥备份与恢复
1. 密钥备份
这是最关键的步骤,密钥丢失后加密表将永久无法恢复!
- Linux/Mac:将/var/lib/mysql-keyring目录下的所有文件复制到离线存储介质(U盘、硬盘、云端加密存储),并设置与源文件相同的700权限;
- Windows:将mysql-keyring目录下的所有文件复制到离线存储介质,保留NT AUTHORITY\NetworkService的完全控制权限(或恢复时临时赋予运行用户权限)。
2. 密钥恢复
假设服务器故障或密钥误删,按以下步骤恢复:
- 停止MySQL服务;
- 将备份的密钥文件复制回原密钥目录,并设置正确的权限;
- 重启MySQL服务;
- 登录MySQL验证表是否可正常访问。
六、常见问题排查
1. 插件无法加载(PLUGIN_STATUS为DISABLED)
检查以下三点:
- early-plugin-load是否放在[mysqld]节点的最前面?必须先加载插件再启动其他功能;
- 密钥目录权限是否为700?Linux/Mac下必须严格700;
- MySQL版本是否符合要求?plugin_keyring_file仅支持8.0.16+社区版。
2. ALTER TABLE加密时报错“Table storage engine for 'test_table' doesn't support encryption”
仅InnoDB存储引擎支持TDE,执行以下SQL将表转换为InnoDB后再加密:
```sql
ALTER TABLE test_table ENGINE=InnoDB;
```