在開啓透明數據加密之前,嚴謹的管理者腦中會出現一些疑問:開啓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倍增加,並且和爲加壓縮選項效果一樣。