我一直在各种服务器上交换 TDE 证书,以便更轻松地进行恢复 - 有些证书的名称错误、指纹错误,甚至两者都有。这涉及将数据库转移到临时证书、删除旧证书、创建目标证书(来自证书和密钥文件)以及将数据库转移到该证书。除了一台服务器上的数据库外,一切都很顺利。
执行时DBCC CHECKDB(SomeDatabase) WITH NO_INFOMSGS, ALL_ERRORMSGS, DATA_PURITY
,我收到此信息:
Msg 33111, Level 16, State 3, Line 106
Cannot find server certificate with thumbprint '<old removed thumbprint>'.
Msg 1823, Level 16, State 2, Line 106
A database snapshot cannot be created because it failed to start.
Msg 1823, Level 16, State 8, Line 106
A database snapshot cannot be created because it failed to start.
Msg 7928, Level 16, State 1, Line 106
The database snapshot for online checks could not be created. Either the reason is given in a previous error or one of the underlying volumes does not support sparse files or alternate streams. Attempting to get exclusive access to run checks offline.
如果使用信息消息重新运行,它会随后执行预期的 CHECKDB 行为,因此它似乎获得了离线所需的访问权限。
备份具有类似的输出。我通常使用 SSMS UI 进行临时备份,其脚本输出以下命令:
BACKUP DATABASE [SomeDatabase] TO DISK = N'some\path\SomeDatabase.bak' WITH DIFFERENTIAL , NOFORMAT, NOINIT, NAME = N'SomeDatabase-Full Database Backup', SKIP, NOREWIND, NOUNLOAD, STATS = 10
。结果如下:
Msg 33111, Level 16, State 3, Line 108
Cannot find server certificate with thumbprint '<old removed thumbprint>'.
Msg 3013, Level 16, State 1, Line 108
BACKUP DATABASE is terminating abnormally.
完整备份和仅复制备份也会发生同样的事情。
观察加密状态:
SELECT a.dbid, a.name AS DatabaseName
,b.encryption_state
,CASE b.encryption_state
WHEN 0 THEN 'No database encryption key present, no encryption'
WHEN 1 THEN 'Unencrypted - Encryption enabled, but not turned on'
WHEN 2 THEN 'Encryption in progress'
WHEN 3 THEN 'Encrypted'
WHEN 4 THEN 'Key change in progress'
WHEN 5 THEN 'Decryption in progress'
WHEN 6 THEN 'Protection change in progress (The certificate or asymmetric key that is encrypting the database encryption key is being changed.)'
END AS encryption_state_desc
,percent_complete
,encryptor_type
,key_algorithm
,key_length
,encryptor_thumbprint
,create_date
,regenerate_date
,modify_date
,set_date
,opened_date
FROM master.dbo.sysdatabases a
LEFT JOIN sys.dm_database_encryption_keys b
ON a.dbid = b.database_id
ORDER BY b.encryption_state desc,
DatabaseName;
发生故障的数据库处于状态 1(已创建数据库加密密钥但未启用加密),并将新的 TdeCert 指纹显示为列encryptor_thumbprint
。有几个数据库处于状态 3(已加密),这些数据库无需旧证书即可顺利备份。如果我只需将证书放回服务器上,CHECKDB/backups 就会顺利执行 - 不需要针对数据库的其他命令。
问题
- 为什么它仍然尝试使用旧证书?我认为,由于数据库加密密钥已由新证书加密,因此不再需要旧证书。
- 为什么只需将旧证书放回服务器就能让一切恢复正常?我原本以为必须再次更改数据库中的某些内容。
- 如果有人正在使用旧证书,为什么当我删除它时没有出现错误?
- 我仅在一台服务器上遇到此行为,这有什么可能的原因吗?
一般信息
- 版本:Microsoft SQL Server 2019 (RTM-CU27) (KB5037331) - 15.0.4375.4 (X64)... 标准版
- TDE 使用对称密钥设置,没有外部密钥库。
- 一切都在本地,没有 Azure/云因素。
- 这是一个非生产服务器;所有数据库都使用简单恢复模型(无事务日志)。
- 这些错误发生在自动化作业以及直接在 SSMS 中执行的语句中。我本人和用于作业的帐户在服务器上都有 sysadmin 权限。
- 这只发生在一台服务器上。我交换过证书的其他所有服务器(包括相同版本的服务器)都没有出现过此问题,而且我无法在其他服务器上复制此问题。
- 旧证书与我希望使用的证书同名。我认为这没什么关系 - 对其他服务器来说也不重要 - 但考虑到有些东西似乎“卡住了”,这可能很重要。
测试
- 失败:CHECKDB输出错误消息并进入离线工作
- 成功:没有错误消息,命令执行成功
完全启用加密(ALTER DATABASE SomeDatabase SET ENCRYPTION ON)-失败
只需恢复旧证书,不要更改任何数据库 -成功
- 但一旦旧证书再次被删除,它就会再次失败
将数据库加密密钥更改为其他密钥,然后运行 CHECKDB
- 新临时证书 -失败
- 恢复所需证书并将 DEK 更改为该证书 -成功
- 在恢复的证书仍然存在的情况下转移回临时证书 -成功
- 删除旧的/恢复的证书 -失败
重新生成数据库加密密钥 -失败
删除新的标准 TdeCert 证书并重新运行转移脚本 - 仍然失败
删除数据库加密密钥,然后运行 CHECKDB -成功
- 使用任意证书创建新的数据库加密密钥 -成功
未解决我的问题的相关文章
- 这个问题演示了一些非常相似的事情,但似乎并不相关,因为我使用的是不同的版本,在描述的修复之后发布了几个版本。
- 这篇 Microsoft 文章描述了在指定 COMPRESSION 和 MAXTRANSFERSIZE 选项时发生“无法找到服务器证书”的错误。我使用的备份命令未指定这些选项,并且所述问题已在旧版本中得到解决。
- 有很多关于在尝试恢复时遇到“无法找到服务器证书”的问题和文章,但由于我没有进行恢复,因此这些问题和文章似乎都不相关。
轮换 DEK 保护证书的工作方式和 TDE 的工作方式要求旧证书在更改后的一段时间内可用,除非您已正确规划日志截断和备份。让我解释一下。
保护 DEK 的证书被标记在数据库配置中,因此它知道哪个证书当前正在保护它,因此可以尝试在实例主控(或者在包含 AG 的情况下,也是复制的主控)中找到它。当使用新证书保护 DEK 时,旧证书指纹将移动到历史证书保护点,新证书指纹将覆盖数据库配置中的当前保护器点,只有 2 个保护器的历史记录(如果您尝试过快地轮换密钥,在某些情况下会出现错误)。
当 DEK 的保护发生变化时,当前 VLF(其头部带有类似信息的标记)需要结束,因此 VLF 会在此时以旧保护器结束。下一个 VLF 将被使用,并带有新保护器的标记。
您在运行 CheckDB 和备份时收到错误的原因是由于这些进程需要返回受旧证书保护的 VLF。要解决此问题,您需要放回旧证书并运行日志备份/截断日志,直到仅使用新保护器。然后,您可以从实例中删除旧保护器 - 但请注意,当您通过使用列并
vlf_encryptor_thumbprint
加入sys.dm_db_log_info
它或在 master 中查找指纹来验证不需要旧保护器时,您仍然需要它来恢复备份等sys.certificates
。