了解透明数据加密中的TDE SCAN过程

895 阅读9分钟

透明数据加密是一项SQL Server功能,用于保护存储在SQL Server数据库中的数据。在任何用户数据库上启用TDE的过程是一个简单明了的方法。一旦我们在任何用户数据库上启用TDE,SQL Server就会对进入缓冲池的每个数据页进行扫描,然后将加密的页面写回磁盘。扫描每个数据页的过程被称为TDE扫描。一旦TDE扫描将对数据库的所有数据页完成,任何数据库都是完全加密的。

如果你在任何用户数据库上启用或禁用了透明数据加密,无论你的SQL Server实例上运行的是什么工作负载,都必须执行TDE扫描。非常重要的一点是,如果我们有大的数据库,应该把这种操作的执行安排在非工作时间,因为扫描是一个非常昂贵的过程,它将给系统增加额外的CPU、内存和IO开销。这是一个很大的痛苦,在SQL Server 2019之前,我们对这个过程没有任何控制。

微软在SQL Server 2019中解决了这个问题,为透明数据加密扫描过程引入了SUSPENDRESUME选项。现在,DBA对这个扫描过程有了更多的控制,当扫描过程对数据库系统造成严重的性能影响时,他们可以暂停扫描过程,之后可以在非工作时间恢复扫描过程,完成TDE过程。

今天我将在这篇文章中通过暂停和恢复TDE扫描过程向你展示这个演示。

准备工作

我将使用DMV sys.dm_database_encryption_keys来跟踪TDE配置的进度。 这个DMV可以捕捉到非常有用的信息,比如数据库的加密状态、加密扫描状态、加密完成百分比等等。

让我们创建一个名为 "TestDB"的数据库,然后在这个数据库上启用TDE来跟踪它的TDE扫描进度。使用下面的T-SQL语句来创建这个数据库。

--Create DB TestDB
USE master;
GO
CREATE DATABASE TESTDB
ON
( NAME = TestDB_data,
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\TESTDB.mdf',
    SIZE = 10GB,
    FILEGROWTH = 5MB)
LOG ON
( NAME = TESTDB_log,
    FILENAME = 'C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\DATA\TESTDB_log.ldf',
    SIZE = 500MB,
    FILEGROWTH = 50MB ) ;
GO

在启用TDE期间分析TDE SCAN

我将使用DMV捕获其TDE扫描进度 sys.dm_database_encryption_keys捕获其TDE扫描进程,然后暂停扫描进程,接着恢复扫描进程,完成TDE扫描进程。

让我们通过运行下面的语句在新创建的数据库TESTDB上启用TDE。

--Create master key
USE master;
GO
CREATE MASTER KEY ENCRYPTION
BY PASSWORD='$ql$h@ck@12';
GO
 
--Create Certificate using above master key
CREATE CERTIFICATE TESTDB_TDECert
WITH 
SUBJECT='TESTDB_Encryption';
GO
 
--Create database encryption key
USE TESTDB
GO
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER CERTIFICATE TESTDB_TDECert;
GO
 
--Enable encryption
ALTER DATABASE TESTDB
SET ENCRYPTION ON;
GO

在新创建的数据库TESTDB上,透明数据加密已经被启用。通过从DMV获取细节来检查TDE的加密状态 sys.dm_database_encryption_keys.

--Check TDE status
SELECT DB_Name(database_id) As [DB Name, encryption_state, encryption_state_desc, percent_complete, encryption_scan_state_desc
FROM sys.dm_database_encryption_keys
Go
--Check TDE for Tempdb and user datababase
SELECT name, is_encrypted
FROM sys.databases
Go

看一下这个输出。这里,encryption_state显示为 "ENCRYPTION IN PROGRESS",encryption_scan_state_desc显示为RUNNINGpercent_complete也显示为只有6%。这意味着TDE扫描正在进行中,现在我将暂停这个扫描,并通过运行上面的T-SQL语句再次向你显示这个状态。

Check TDE SCAN during enabling TDE

让我们通过执行下面的ALTER DATABASE语句来暂停TDE扫描。如果你的系统是正常的,没有面临任何性能问题,请不要暂停。暂停该扫描将暂停透明数据加密过程,这需要稍后通过恢复其扫描过程来完成。

-- Suspend TDE Scan to pause TDE enablement
ALTER DATABASE TESTDB SET ENCRYPTION SUSPEND
Go

下面是上述执行的输出。

Suspend TDE SCAN

让我们通过运行图1中显示的相同的T-SQL语句再次检查TDE扫描状态。在下面的输出中,你还会注意到,TDE启用的状态在sys.databases系统对象中变成了启用,而它在数据库内部并没有完全启用,而是被暂停在6%。一旦数据库的加密扫描过程完全完成,它就被完全加密了。

我们可以看到,对于数据库TESTDB来说,ENCRYPTION IN PROGRESS状态仍然存在, percent_complete被设置为0,因为它已经暂停了,它的扫描状态显示为SUSPENDED,因为我们已经通过运行上述ALTER DATABASE语句暂停了TDE扫描过程。

Check TDE SCAN state after suspending it

现在,让我们通过运行下面的ALTER STATEMENT来启用TDE扫描过程。如果你因为性能问题暂停了TDE扫描进程,请确保在非工作时间或得到企业的适当批准后进行。

-- Resume TDE Scan
ALTER DATABASE TESTDB SET ENCRYPTION RESUME
Go

上面的T-SQL语句已经被执行以恢复TDE扫描过程。请看一下这个输出。

Resume TDE scan process

现在,再次检查TDE扫描的状态。扫描过程已经开始了,因为它被暂停了,它的扫描状态又变成了RUNNING,现在根据下面的图片,完成百分比也显示为44%。

check TDE scan state after resuming it

让这个扫描过程运行并完成用户数据库TESTDB的TDE启用过程。一旦扫描完成,扫描的状态将改为COMPLETE,TDE的状态将从ENCRYPTION in PROGRESS改为ENCRYPTED

Check encryption state after TDE SCAN

我们从在用户数据库TESTDB上启用TDE到暂停其扫描过程,最后恢复扫描以完成TDE加密的整个过程将被记录在SQL Server错误日志中。请看下面的截图,你可以分析一下那里记录的事件序列。

在TDE扫描过程中,错误日志也捕捉到了系统中的IO压力。这就是为什么我们总是建议在生产中启用它之前做仔细的计划,因为透明数据加密的扫描过程是一个资源密集型的操作,在读取缓冲区中的每一页,然后将其保存到磁盘的过程中执行大量的IO操作。这些操作增加了CPU、内存和IO的巨大负荷。

SQL Server error log for TDE SCAN

我已经向你展示了如果你在用户数据库的TDE启用过程中面临严重的性能问题,如何暂停和恢复TDE扫描过程。现在,让我们在下一节中分析在同一用户数据库TESTDB上禁用TDE时的相同行为。

分析在禁用TDE期间的TDE扫描

在加密和解密的过程中,SQL Server会执行TDE扫描。我将在本节中向你展示并证明在解密TESTDB数据库时的情况。在上一节中,TDE已经在用户数据库TESTDB上启用了。让我们关闭这个数据库的透明数据加密,并分析扫描过程。我不会删除任何密钥或证书作为这个禁用的一部分,因为我们不想从数据库中删除透明数据加密,但我们只是暂时禁用TDE来分析其扫描过程。不要为了测试目的在你的生产中执行这个操作。如果你想从SQL Server实例中完全删除TDE,那么我建议阅读这里所附的另一篇文章,从SQL Server用户数据库中删除透明数据加密(TDE)。

运行下面的ALTER语句,从数据库TESTDB中关闭TDE。

--Disable TDE
ALTER DATABASE TESTDB
SET ENCRYPTION OFF;
GO

下面是其执行的输出。

Turn off TDE from user database

一旦上述T-SQL语句被执行,TDE扫描将开始对数据库TESTDB进行解密。让我们通过查看DMV来确认它 sys.dm_database_encryption_keys。 下面是输出结果,它显示了与我们预期一致的结果。TDE扫描已经开始对数据库TESTDB进行扫描。其他细节,如加密状态显示为 "DECRYPTION IN PROGRESS",完成百分比也在下面的图片中显示其数字。

Check decryption state during TDE scan after disabling TDE

现在,我们将通过运行下面的T-SQL语句在解密过程中暂停TDE扫描过程,看看它的影响。

-- Suspend TDE Scan to pause TDE
ALTER DATABASE TESTDB SET ENCRYPTION SUSPEND
Go

Suspend TDE SCAN during decryption

让我们检查一下DMV sys.dm_database_encryption_keys来看看扫描的状态和它的加密状态。

输出显示与我们在为数据库TESTDB启用透明数据加密时捕获的一样。下面的图片显示,TDE扫描被暂停,其状态显示为DECRYPTION IN PROGRESS。同样,sys.databases对象显示TESTDB没有被加密,而它的解密过程已经用ALTER语句暂停了。始终查看上述DMV以获得透明数据加密的最新状态,而不是系统对象sys.databases。

Check TDE SCAN state after suspending it

现在,让我们恢复TDE扫描,通过运行下面的T-SQL语句完成解密过程。

-- Resume TDE Scan
ALTER DATABASE TESTDB SET ENCRYPTION RESUME
Go

一旦上述语句被执行,在DMV中检查其状态 sys.dm_database_encryption_keys。这是输出结果,我们可以看到加密扫描的状态已经从SUSPEND变为RUNNING了。完成百分比也显示了它的数字。

Check scan state after resuming it

一旦这个TDE扫描完成,用户数据库TESTDB将被解密,TDE将从这个数据库完全关闭。

下面是TDE扫描完成后的截图,数据库的加密状态显示为UNENCRYPTED,加密扫描显示为COMPLETE

Check encryption state after scan completion

在解密过程中,SQL Server日志捕捉到了另一个糟糕的IO性能日志,如下图所示,在SQL Server错误日志中。此外,它还在其错误日志文件中记录了所有透明数据加密操作。

SQL Server error log during decryption process

总结

我在这篇文章中讨论了透明数据加密的内部过程TDE SCAN。无论你在任何用户数据库上启用TDE还是禁用TDE,TDE扫描都是完成用户数据库加密或解密的一个内部必经的过程。虽然这个内部过程在早期版本的SQL Server中已经存在,但SQL Server 2019给了我们对这个过程更多的控制权,可以根据我们的需要暂停它和恢复它。

我已经在上述章节中详细解释了启用或禁用TDE的过程。在进行这些活动时,你应该总是仔细计划。不要在工作时间内进行这些活动。在你的生产系统上做任何事情之前,要得到适当的批准。