SQL Server 透明数据加密(TDE)的影响

在开启透明数据加密之前,严谨的管理者脑中会出现一些疑问:开启TDE会有哪些影响?会不会造成数据库性能严重下降?哪些影响可以避免、如何避免?本文将一一给出解答。

本文采取试验的方式来确认TDE的影响,因为试验步骤比较冗长,这里我们先将结果告知读者。值得注意的是,这里我们只做了简单的测试,其结论只可当做参考。因为您所在的环境包括物理环境(硬盘、CPU、内存)、生产环境(数据库结构、逻辑复杂度等)的不同,数据是否存在于内存(在内存中的数据是明文的,只要内存足够大,大量常用数据存在于内存中会极大减小TDE的影响),最终影响也会有较大差异,在生产环境上开启TDE时,可以参照后文中的试验案例测试,以确保开启TDE后不对您的业务产生严重影响。

TDE 影响增、删、改、查的性能

TDE使数据库的增、删、改、查下降5%左右。当然内存足够大时,数据读取到内存中后,减少了解密的CPU时间消耗,将会降低这一影响。具体到增、删、改、查每个部分的影响,可以根据后文中参考测试样例进行确定。

TDE影响数据库创建、重建

TDE数据库中索引创建CPU消耗时间、占用时间增加3个百分点左右。

TDE对存储的影响

对比非加密数据库和加密数据库,数据库加密与否,对存储几乎没有影响。

TDE对备份的影响

同样大小数据库备份,加密后耗时是加密前1倍左右。

 

加密数据库备份压缩效果要比非加密数据库差一倍,备份加密数据库开启压缩选项,会使得CPU耗时10倍增加,并且和为加压缩选项效果一样。

最佳实践:备份开启TDE数据库时,需要加COMPRESSION选项

TDE对系统数据库tempdb的影响

SQL Server 实例上的任意其他数据库启用TDE,tempdb系统数据库也会被加密,这将影响实例上其他不加密的数据库性能。

最佳实践:将tempdb文件放在I\O较好的硬盘上(如SSD盘)

TDE对事务日志传输、异实例附加、异实例还原的影响

事务日志传输、异实例附加、异实例还原后的数据库均为TDE数据库。

TDE 和 Transaction Logs

启用数据库TDE对正在进行事务日志没有影响,但下一个事务日志就会强制加密。这保证了在设置数据库进行加密之后,事务日志中不会留下任何明文。你可以通过系统视图 sys.dm_database_encryption_keys 的 encryption_state 列查看日志文件的加密状态。

TDE对复制分发的影响

加密数据库复制的数据仍然是明文的,如果您需要对复制的内容启用TDE,需要在分发、订阅数据库启用TDE。

TDE对FILESTREAM的影响

启用TDE的数据库,不会对FILESTREAM数据加密。

TDE 和 In-Memory OLTP

对于拥有In-Memory OLTP对象的数据库,仍然可以启用TDE。在SQL Server 2016(13.x)版本中,如果启用了TDE,In-Memory OLTP日志记录和数据页会被加密。

测试样例及结果

测试环境

在同一块盘符上创建两个数据库test、test_TDE:

USE master
GO
CREATE DATABASE [test] ON  PRIMARY
( NAME = N'test', FILENAME = N'D:\database\test.mdf' , SIZE = 4096KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON
( NAME = N'test_log', FILENAME = N'D:\database\test.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
CREATE DATABASE [test_TDE] ON  PRIMARY
( NAME = N'test_TDE', FILENAME = N'D:\database\test_TDE.mdf' , SIZE = 4096KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
 LOG ON
( NAME = N'test_TDE_log', FILENAME = N'D:\database\test_TDE.ldf' , SIZE = 2048KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO

分别在两个数据库中各创建一个结构相同的表:

USE test
SELECT TOP 0 PERCENT * INTO test FROM sys.all_objects
USE test_TDE
SELECT TOP 0 PERCENT * INTO test FROM sys.all_objects

启用test_TDECert数据库TDE加密,注意,这个要在对非加密数据库各样例执行完毕,再启用,以防止启用后对tempdb数据库的影响造成测试结果的不准确(实例上任何数据库启动了TDE,tempdb随之启动TDE)

USE master
GO
--创建数据库主密钥DMK
CREATE MASTER KEY ENCRYPTION BY PASSWORD='$Mf1=oVS_Y3:Ydt'
GO
--创建服务器证书
CREATE CERTIFICATE test_TDECert
WITH SUBJECT='DEK Certificate of test_TDECert database'
--备份服务器证书
BACKUP CERTIFICATE test_TDECert
TO FILE ='D:\test_TDECert.cer'
WITH PRIVATE KEY(FILE='D:\test_TDECert_Key.pvk',
ENCRYPTION BY PASSWORD='$Mf1=oVS_Y3:Ydt')
USE test_TDE
GO
--创建服务器证书加密的数据库密钥
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM=AES_128
ENCRYPTION BY SERVER CERTIFICATE test_TDECert
--启用TDE
ALTER DATABASE test_TDE SET ENCRYPTION ON

INSERT测试

测试样例:

DECLARE @bdatetime AS DATETIME=GETDATE()
DECLARE @i INT=1
SET NOCOUNT ON
WHILE @i<10000
BEGIN
      INSERT INTO test
      SELECT TOP(@i) * FROM sys.all_objects
      ORDER BY NEWID()
      SET @i=@i+1
END
SELECT @bdatetime,GETDATE()

test库结果:

test_TDE测试结果:

对比加密数据库和非加密数据库INSERT操作,平均时间上慢8个点 (802086-737700)*1.0/737700=0.08727938,当然这里并没有考虑索引维护等时间。

下面进行INSERT单次试验,检查CPU、IO消耗情况:

USE test
GO
SET STATISTICS IO ON
SET   STATISTICS TIME ON
INSERT INTO test
SELECT TOP(1000) * FROM sys.all_objects
ORDER BY NEWID()
SET STATISTICS IO OFF
SET   STATISTICS TIME OFF

加密数据库和非加密数据库逻辑读次数一致,总时间消耗差异9.5%,CPU消耗的时间是未加密的近1倍;可以看出加密数据库对CPU的计算能力要高,而提高CPU的计算能力,可以有效降低数据库加密后的对INSERT的影响。因为加密数据库的数据写入硬盘之前是要进行加密处理的。

SELECT 测试

测试样例

USE test
DECLARE @bdatetime AS DATETIME=GETDATE()
DECLARE @i INT=1
SET NOCOUNT ON
WHILE @i<100
BEGIN
      
      SELECT TOP(@i) * FROM test
      SET @i=@i+1
END
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())

test库测试结果:

test_TDE库测试结果:

因为100次查询的结果都不相同,对于加密数据库来说,每次都需要将数据读取到内存中解密,可以看出同样的查询,加密数据库消耗的时间几乎是不加密数据库的1倍。当然这个测试对于重复读取相同的数据时,平均影响较小。

下面进行单次查询,检验SELECT的CPU、IO消耗

USE test
GO
SET STATISTICS IO ON
SET   STATISTICS TIME ON
SELECT TOP(1000) * FROM test
SET STATISTICS IO OFF
SET   STATISTICS TIME OFF

两次查询逻辑读一样,TDE的查询占用时间反而低于非加密数据库的时间。单次测试可能存在较大误差。

UPDATE测试

测试样例:

USE test
DECLARE @bdatetime AS DATETIME=GETDATE()
DECLARE @i INT=1
SET NOCOUNT ON
WHILE @i<100
BEGIN
      
      UPDATE TOP(@i) test SET principal_id=1
      WHERE principal_id is null
      SET @i=@i+1
END
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())
GO

test库测试结果:

test_TDE 测试结果:

发现加密数据库和非加密数据库的更新操作时间差异较小,只有不到5个百分点。

如下单次执行UPDATE,检查CPU、IO的影响

USE test
GO
SET STATISTICS IO ON
SET   STATISTICS TIME ON
UPDATE TOP(100) test SET principal_id=1
      WHERE principal_id is null
SET STATISTICS IO OFF
SET   STATISTICS TIME OFF

发现TDE的UPDATE逻辑读、时间消耗均低于非加密数据库。

DELETE操作

测试样例:

USE test
DECLARE @bdatetime AS DATETIME=GETDATE()
DECLARE @i INT=1
SET NOCOUNT ON
WHILE @i<100
BEGIN
      
      DELETE TOP(@i) test
      WHERE principal_id is null
      SET @i=@i+1
END
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())
GO

test库测试结果:

test_TDE库测试结果:

删除的平均时间差异只有2.6个百分点。

如下单次DELETE对CPU、IO的影响

USE test
GO
SET STATISTICS IO ON
SET   STATISTICS TIME ON
DELETE TOP(100) test
WHERE principal_id=1
SET STATISTICS IO OFF
SET   STATISTICS TIME OFF

从单次删除来看,加密数据库的逻辑读远大于非加密数据库,达到了将近5倍,而CPU消耗更达到了近8倍,占用时间也在1倍以上。

创建索引

测试样例:

USE test
DECLARE @bdatetime AS DATETIME=GETDATE()
SET STATISTICS IO ON
SET   STATISTICS TIME ON
CREATE INDEX ix_test_principal_id ON test(principal_id)
SET STATISTICS IO OFF
SET   STATISTICS TIME OFF
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())
GO

test库测试结果:

test_TDE库测试结果:

索引创建时间、CPU消耗,加密数据库比非加密数据库多用了3个百分点左右。

对存储的影响

test数据库表test使用的存储空间:

ALTER TABLE [dbo].[test] REBUILD PARTITION = ALL
WITH
(DATA_COMPRESSION = ROW
)

行压缩后test数据中表test存储使用空间:

页压缩后test数据中表test存储使用空间:

数据库test_TDE表test的空间使用:

行压缩后test_TDE数据中表test存储使用空间:

页压缩后test_TDE数据中表test存储使用空间:

对比非加密数据库和加密数据库,数据库加密与否,对存储几乎没有影响。

TDE对备份影响测试

非加密数据库的非压缩备份

DECLARE @bdatetime DATETIME=GETDATE()
SET STATISTICS IO ON
SET STATISTICS TIME ON
BACKUP DATABASE test TO DISK='D:\test_f.bak'
WITH init,STATS=10
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())

SQL Server 分析和编译时间:

   CPU 时间= 0 毫秒,占用时间= 1 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

SQL Server 分析和编译时间:

   CPU 时间= 0 毫秒,占用时间= 1 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

已处理百分之10。

已处理百分之20。

已处理百分之30。

已处理百分之40。

已处理百分之50。

已处理百分之60。

已处理百分之70。

已处理百分之80。

已处理百分之90。

已为数据库'test',文件'test' (位于文件1 上)处理了193248 页。

已处理百分之100。

已为数据库'test',文件'test_log' (位于文件1 上)处理了1 页。

BACKUP DATABASE 成功处理了193249 页,花费23.636 秒(63.875 MB/秒)。

 SQL Server 执行时间:

   CPU 时间= 296 毫秒,占用时间= 23939 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 

非加密数据库的压缩备份

USE master
GO
SET NOCOUNT ON
DECLARE @bdatetime DATETIME=GETDATE()
SET STATISTICS IO ON
SET STATISTICS TIME ON
BACKUP DATABASE test TO DISK='D:\test_f_Com.bak'
WITH init,STATS=10,COMPRESSION
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())

已处理百分之10。

已处理百分之20。

已处理百分之30。

已处理百分之40。

已处理百分之50。

已处理百分之60。

已处理百分之70。

已处理百分之80。

已处理百分之90。

已为数据库'test',文件'test' (位于文件1 上)处理了193248 页。

已处理百分之100。

已为数据库'test',文件'test_log' (位于文件1 上)处理了1 页。

BACKUP DATABASE 成功处理了193249 页,花费24.328 秒(62.058 MB/秒)。

 SQL Server 执行时间:

   CPU 时间= 281 毫秒,占用时间= 24702 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 

TDE数据库的非压缩备份

DECLARE @bdatetime DATETIME=GETDATE()
SET STATISTICS IO ON
SET STATISTICS TIME ON
BACKUP DATABASE test_TDE TO DISK='D:\test_TDE_f_Com.bak'
WITH init,STATS=10
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())

已处理百分之10。

已处理百分之20。

已处理百分之30。

已处理百分之40。

已处理百分之50。

已处理百分之60。

已处理百分之70。

已处理百分之80。

已处理百分之90。

已为数据库'test_TDE',文件'test_TDE' (位于文件1 上)处理了193248 页。

已处理百分之100。

已为数据库'test_TDE',文件'test_TDE_log' (位于文件1 上)处理了1 页。

BACKUP DATABASE 成功处理了193249 页,花费38.212 秒(39.510 MB/秒)。

 SQL Server 执行时间:

   CPU 时间= 435 毫秒,占用时间= 38566 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 

TDE数据库的压缩备份

DECLARE @bdatetime DATETIME=GETDATE()
SET STATISTICS IO ON
SET STATISTICS TIME ON
BACKUP DATABASE test_TDE TO DISK='D:\test_TDE_f.bak'
WITH init,STATS=10,COMPRESSION
SET STATISTICS IO OFF
SET STATISTICS TIME OFF
SELECT @bdatetime,GETDATE(),DATEDIFF(millisecond,@bdatetime,GETDATE())

已处理百分之10。

已处理百分之20。

已处理百分之30。

已处理百分之40。

已处理百分之50。

已处理百分之60。

已处理百分之70。

已处理百分之80。

已处理百分之90。

已为数据库'test_TDE',文件'test_TDE' (位于文件1 上)处理了193248 页。

已处理百分之100。

已为数据库'test_TDE',文件'test_TDE_log' (位于文件1 上)处理了7 页。

BACKUP DATABASE 成功处理了193255 页,花费38.111 秒(39.615 MB/秒)。

 SQL Server 执行时间:

   CPU 时间= 3433 毫秒,占用时间= 50686 毫秒。

 SQL Server 执行时间:

   CPU 时间= 0 毫秒,占用时间= 0 毫秒。

 

加密数据库备份压缩效果要比非加密数据库差一倍,备份加密数据库开启压缩选项,会使得CPU耗时10倍增加,并且和为加压缩选项效果一样。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值