让权威网站Percona来回答这个很多人都在关心的问题。
原文网址:ChatGPT 不会取代 MySQL DBA - 关于静态加密的问题示例 - Percona 数据库性能博客
作者:Edwin Wang
译者,姚远
ChatGPT是目前科技界最热门的话题,有人甚至说ChatGPT已经通过了谷歌的3级编程面试。我想知道,这是否意味着ChatGPT也准备好取代MySQL DBA?答案是否定的,让我来告诉你为什么。
最近,我们的一位客户正在考虑使用基于文件的密钥环插件加密他们的静态数据。为了使这个过程更安全,他们考虑在MySQL启动后删除本地keyring_file。因此,即使有人获得主机访问权限,数据文件仍然受到保护,因为他们无法访问主密钥,而主密钥用于加密保存静态数据的表的密钥。
让 ChatGPT 尝试 MySQL 管理
让我们看看ChatGPT会如何回答下面的问题。
我问了ChatGPT一个问题:“我们能不能先备份用于静态加密插件的密钥环文件,然后在MySQL启动后删除这个文件?”
来自ChatGPT的回答是:“不,不建议在MySQL运行时删除用于静态加密插件的密钥环文件,因为这可能导致数据损坏或意外结果。密钥环文件是静态加密插件的重要组成部分,用于安全地存储包括密码在内的加密信息。为了安全地对密钥环文件进行更改,建议先停止MySQL服务,再备份密钥环文件,然后再进行必要的修改或删除,完成变更后,最后再次重新启动MySQL服务。没有停止MySQL服务就更改密钥环文件可能会导致数据丢失或损坏,并且可能无法恢复数据。”
乍一看,答案看起来非常正确,如果您没有足够的基于文件密钥环插件的经验,答案似乎非常合理。事实上,这个答案只是部分正确,而且犯了两个错误。
ChatGPT犯的第一个错误是说不能在MySQL正在运行时删除用于静态加密插件的密钥环文件,实际上是可以的。在MySQL运行时删除了密钥环文件后,该插件仍将正常工作,继续加密新表,并解密已经加密表中的数据,而不会损坏或意外行为。
这是因为启动时的密钥环插件已经将keyring_file的全部内容(即密钥ID,密钥用户,密钥类型以及密钥本身)加载到缓存中,除非MySQL重新启动,或者您想轮换(rotate)主密钥(您不会,因为您知道您已经删除了keyring_file),它将不再需要密钥环文件。我们可以通过以下示例进行验证:
当MySQL启动时,它创建了一个空文件/var/lib/mysql/keyring_file。但是,当我们使用 ENCRYPTION=‘Y’ 创建一个表时,我们可以看到文件 /var/lib/mysql/keyring_file 不再为空。这是因为Keyring_file插件创建了一个主密钥,将所有信息放入内存中,并将密钥数据的备份副本保存到文件 /var/lib/mysql/keyring_file 中。
ec2-user@ip-172-31-32-242 ~]$ cat /etc/my.cnf
#encryption at rest
early-plugin-load=keyring_file.so
keyring_file_data=/var/lib/mysql/keyring_file
mysql> create database test;
mysql> show create schema testG
*************************** 1. row ***************************
Database: test
Create Database: CREATE DATABASE `test` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */
[ec2-user@ip-172-31-32-242 ~]$ sudo ls -lhr /var/lib/mysql/
-rw-r----- 1 mysql mysql 0 Feb 9 00:04 keyring_file
mysql> use test;
Database changed
mysql> CREATE TABLE t1 (c1 INT, PRIMARY KEY pk(c1)) ENCRYPTION='Y';
mysql> insert into t1(c1) values(1);
mysql> select * from t1;
+----+
| c1 |
+----+
| 1 |
+----+
mysql> show create table t1G
*************************** 1. row ***************************
Table: t1
Create Table: CREATE TABLE `t1` (
`c1` int NOT NULL,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ENCRYPTION='Y'
[ec2-user@ip-172-31-32-242 ~]$ sudo ls -lhr /var/lib/mysql/keyring_file
-rw-r----- 1 mysql mysql 187 Feb 9 00:07 /var/lib/mysql/keyring_file
mysql> show variables like '%UUID%';
+---------------+--------------------------------------+
| Variable_name | Value |
+---------------+--------------------------------------+
| server_uuid | ccdb4a6c-9c3b-11ed-805e-0a357402d413 |
+---------------+--------------------------------------+
[ec2-user@ip-172-31-32-242 ~]$ sudo vi /var/lib/mysql/keyring_file
00000000: 4b65 7972 696e 6720 6669 6c65 2076 6572 Keyring file ver
00000010: 7369 6f6e 3a32 2e30 8000 0000 0000 0000 sion:2.0........
00000020: 3000 0000 0000 0000 0300 0000 0000 0000 0...............
00000030: 0000 0000 0000 0000 2000 0000 0000 0000 ........ .......
00000040: 494e 4e4f 4442 4b65 792d 6363 6462 3461 INNODBKey-ccdb4a
00000050: 3663 2d39 6333 622d 3131 6564 2d38 3035 6c-9c3b-11ed-805
00000060: 652d 3061 3335 3734 3032 6434 3133 2d31 e-0a357402d413-1
00000070: 4145 537d 7c7f a42e 8e5a 85ff 2301 cd95 AES}|....Z..#...
00000080: d4b0 9e67 dd5c 3bfe 1cc7 77e2 8d22 57e6 ...g.;...w.."W.
00000090: bb60 c500 0000 0000 454f 4691 068e 5190 .`......EOF...Q.
000000a0: d204 4689 8620 3022 80fb 90af 4b9d 1302 ..F.. 0"....K...
000000b0: 5a7c 84bb 516f 07a8 d1b6 9a0a Z|..Qo......
我们备份并删除了keyring_file文件,但没有重新启动MySQL,MySQL 仍然运行正常,我们可以从加密表中查询数据,也可以创建一个ENCRYPTION=‘Y’ 的新表,一切都和删除keyring_file文件之前相同。
[ec2-user@ip-172-31-32-242 ~]$ sudo mv /var/lib/mysql/keyring_file /var/lib/mysql/keyring_file_1
[ec2-user@ip-172-31-32-242 ~]$ sudo ls -lhr /var/lib/mysql/keyring_file
ls: cannot access /var/lib/mysql/keyring_file: No such file or directory
[ec2-user@ip-172-31-32-242 ~]$ sudo ls -lhr /var/lib/mysql/keyring_file_1
-rw-r----- 1 mysql mysql 187 Feb 9 00:07 /var/lib/mysql/keyring_file_1
mysql> select * from t1;
+----+
| c1 |
+----+
| 1 |
+----+
mysql> CREATE TABLE t2 (c1 INT, PRIMARY KEY pk(c1)) ENCRYPTION='Y';
mysql> show create table t2G
*************************** 1. row ***************************Table: t2
Create Table: CREATE TABLE `t2` (`c1` int NOT NULL,PRIMARY KEY (`c1`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ENCRYPTION='Y'
mysql> insert into t2(c1) values(2);
mysql> select * from t2;
+----+
| c1 |
+----+
| 2 |
+----+
我们重新启动了MySQL,发现MySQL启动时出现错误,提示“[InnoDB] Encryption can’t find master key, please check the keyring is loaded.”。但它在重新启动后创建了另一个空文件 /var/lib/mysql/keyring_file。现在,我们无法对加密表执行任何操作,如果我们不重新启动MySQL,即使我们使用备份文件 /var/lib/mysql/keyring_file_1 来覆盖文件 /var/lib/mysql/keyring_file 也不行。
[ec2-user@ip-172-31-32-242 ~]$ sudo systemctl stop mysql
[ec2-user@ip-172-31-32-242 ~]$ sudo systemctl start mysql
[ec2-user@ip-172-31-32-242 ~]$ mysql -u root -p
mysql> select * from t1;
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
mysql> select * from t2;
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
mysql> show create table t1G
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
mysql> show create table t2G
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
mysql>
[ec2-user@ip-172-31-32-242 ~]$ sudo cat /var/log/mysqld.log
...
2023-02-09T00:14:56.719139Z 1 [ERROR] [MY-012657] [InnoDB] Encryption can't find master key, please check the keyring is loaded.
2023-02-09T00:14:56.719170Z 1 [ERROR] [MY-012226] [InnoDB] Encryption information in datafile: ./test/t1.ibd can't be decrypted, please confirm that keyring is loaded.
2023-02-09T00:14:56.720098Z 1 [ERROR] [MY-012657] [InnoDB] Encryption can't find master key, please check the keyring is loaded.
2023-02-09T00:14:56.720117Z 1 [ERROR] [MY-012226] [InnoDB] Encryption information in datafile: ./test/t2.ibd can't be decrypted, please confirm that keyring is loaded.
[ec2-user@ip-172-31-32-242 ~]$ sudo ls -lhr /var/lib/mysql/keyring_file
-rw-r----- 1 mysql mysql 0 Feb 9 00:14 /var/lib/mysql/keyring_file
[ec2-user@ip-172-31-32-242 ~]$ sudo mv /var/lib/mysql/keyring_file_1 /var/lib/mysql/keyring_file
[ec2-user@ip-172-31-32-242 ~]$ sudo ls -lhr /var/lib/mysql/keyring_file
-rw-r----- 1 mysql mysql 187 Feb 9 00:07 /var/lib/mysql/keyring_file
mysql> select * from t1;
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
mysql> select * from t2;
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring is loaded and initialized successfully.
我们用备份文件/var/lib/mysql/keyring_file_1覆盖文件/var/lib/mysql/keyring_file,然后再次重启MySQL。现在一切都恢复正常了。
[ec2-user@ip-172-31-32-242 ~]$ sudo systemctl stop mysql
[ec2-user@ip-172-31-32-242 ~]$ sudo systemctl start mysql
[ec2-user@ip-172-31-32-242 ~]$ mysql -u root -p
mysql> select * from t1;
+----+
| c1 |
+----+
| 1 |
+----+
mysql> select * from t2;
+----+
| c1 |
+----+
| 2 |
+----+
另外,我们不应该对密钥环文件进行任何更改,而是应该通过加密插件来轮换(rotate)密钥,并且我们应该在轮换密钥之前备份密钥。但是,ChatGPT 提供的答案暗示我们可以对密钥环文件进行一些更改,这是非常错误的,这是ChatGPT 犯的第二个错误。
结论
ChatGPT 只能为您的问题提供部分正确,甚至是完全错误的答案,因此仍然需要具备专业知识的DBA来仔细检查其答案的正确性。而搜索引擎提供与您问题的答案相关的链接,DBA依靠自己专业知识来分析这些信息。因此,我们认为,无论是使用ChatGPT和/或搜索引擎,您都必须为MySQL数据库配备DBA。
当我完成这篇博客时,我再次询问了ChatGPT同样的问题,它的回答和之前有些不同(具体答案省略)。第二天,我又得到了另一个不同的答案。
因此,ChatGPT 可能会在不同的时间对同一个问题给出不同的答案。它使ChatGPT更加不可靠,特别是如果你想让它成为你的DBA时。事实上,人们向 ChatGPT 提出问题并在答案旁边投票👍或👎是在帮助 AI 学习。换句话说,我们正在使用一个alpha版本的ChatGPT,并正在帮助它进步。