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倍增加,並且和爲加壓縮選項效果一樣。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章