MySQL表加密是鸡肋吗?

MySql社区版从5.7.11开始支持基于表的数据加密方案,模块名为keyring_file,支持加密整张表。这种是加密方式其实是基于文件加密的,一旦mysqld读取key启动后,将会解密整张表的数据,在mysql服务内,读取的数据都是解密后的,也就是说对客户端而言是无感知的。而这个key是本地存放的,mysql服务拥有读写这个key的权限。

针对已有的项目面对客户的安全审查需求,要对mysql进行表加密吗?

表加密影响性能吗?

对主从复制有没有影响?加密后对业务系统有影响吗?

对备份恢复有没有性能影像?

大数据量情况下,加密解密耗时吗?

加密后会增加存储空间占用吗?

数据库的有些特性通常都是双刃剑,有利也有弊,当然要测试过才知道。

以客户现场业务数据库数据量为基准,做如下测试:

1:增删改查加密前和加密后的性能对比

2:主从复制加密后系统主流程功能验证

3:加密前和加密后备份恢复时间对比

4:加密,解密耗时测试

5:加密前加密后占用存储空间对比

 

整个测试流程如下:

1.把现场数据拷回来,再进行还原到两台相同配置的服务器(8核16G内存),一台服务器所有表未加密,一台服务器所有表都加密;

2. 把现场业务系统的主要工作流的sql拿来,使用jmeter做并发性能测试对比;

3.设置主从,测试加密情况下,主从同步是否正常,同步是否及时;

考虑理论上应该没什么大问题,这里只简单的通过导入一个大批量插入数据的sql,来测试是否及时同步到从库。

4.在对第二台服务器中的所有业务数据表进行加密时,顺便记录加密耗时,以及加密后的空间占用计算空间增长,以及解密耗时;

5.分别测试加密和没有加密情况下的备份恢复时间。

经过两天的测试,基本结论如下:

1:表加密后业务系统的增删改查操作没有出现明显的性能降低

2:备份恢复的性能也没有明显的影响;

3:不影响主从复制,主从同步的及时性方面基本不受影响,没有出现明显的延迟;

4:空间增长方面,加密后反倒占用空间变小了;但是加密解密需较多的存储空间

由于数据库中设置了innodb_file_per_table=1,每个表独占一个表空间,分别单独加密。很明显的看到加密后的文件反倒比加密前变小了,估计是加密过程中去掉了文件中的碎片?

但是加密过程中需要有和原表文件大小差不多的空闲空间,否则加密会失败,解密也是一样。

因为mysql表加密采用AES加密算法,实际上源文件不变,Mysql会新生成一个临时文件,把原表文件的数据,不断读取写入到新文件,直到加密完成,再删除原文件,把加密后的文件替换到原文件。解密也是一样。

如果是单用户串行操作完成整个数据库的加密,可以简单的估算,加密解密额外需要的表空间大小为:需要加密的数据库中单个表文件占用空间最大的表,所占用的空间。

例如一个300G的数据库中,最大的表占用70G,如果是串行加密所有的表,整个加密所需要的额外的磁盘空间为70G。解密也是同样如此。

如果是多个会话并行执行加密操作,需要的空间就是各自需要加密的表中最大的表空间占用大小之和。

5:加密,解密非常耗时,在生产环境不可接受

如果上面说的空间占用情况还可以接受,可耗时问题就让人觉得mysql的加密非常鸡肋了。

测试下来,一个亿不到的业务量的情况下 整个系统的所有表加密完成时间需要整整一个晚上才行。

测试数据如下:测试环境,8G内存,4核CPU

 

表(行数) 加密耗时 解密耗时
业务表1,字段不多(369928)

24秒

3分56秒

业务表2,含有较多大文本字段(460436) 4分35秒 25分34秒
业务表3(135185)

8秒

11秒

业务表4,结构同表3,行数变多(21874128)

15分56秒

13分48秒

业务表4(39948892)

15分56秒

13分48秒

业务表5(95117965)

1小时3分16秒

31分49秒

业务表6(2880473))

8分5秒

4分12秒

业务表7(95123072)

2小时48分46秒

1小时40分

业务表8(490925)

59秒

1分57秒

业务表9(411934)

34秒

1分4秒

业务表10(95117965)

6小时30分

超过6小时未完成

同样是9千多万的数据量,业务表10比表5字段少很多,只是多了一个varchar(500)类型的字段,存储文件的磁盘完整路径的。然而加密耗时却多了几倍。

6:在不停止业务系统的情况下,加密加密不会阻塞数据查询操作,但是会阻塞增删改操作。

根据执行时间直到加密解密操作完成才执行额外发起的增删改操作,成功或者超时,而对业务系统来说,多半都是会超时失败。

总结:

mysql的 加密解密虽然不需要停机操作,但是会阻塞对数据库的增删改操作。要想快速完成加密解密操作,最好是先停止业务系统读写数据库,再执行。

然而,加密解密的耗时决定了停机肯定会超出用户的能接受的停机时间!

再来看安全性方面,虽然数据库文件是加密的,但是只要能有mysql服务的账户,访问数据都是自动解密的,加密的意义又在哪里呢?而对于加密key来说,熟悉mysql加密原理的,完全可以把key一定带走。可以预见,社区版的加密的安全性方面只不过是掩耳盗铃罢了!

不知道大家的项目中是否也有数据库加密的需求呢?是否有别的更好的方式,在不购买企业版的情况下?

你可能感兴趣的:(数据库,mysql)