症状
假设你定期打开和关闭数据库加密,还会在 SQL Server 2012 中定期更改数据库上的加密密钥。 在这种情况下,当您启用加密时,数据库可能不会加密。 如果更改加密密钥,可能会发生断言。
原因
出现此问题的原因是,如果数据库加密密钥(DEK)未处于加密状态并且密钥已更改,则下一次更新密钥将复制 DEK 的密钥部分,但不会正确复制设置的加密状态。 在 SQL Server 2012 中,在解密扫描之后,将保留文件控制块(FCB)标头中的 DEK,并且仅当密钥被删除时,才会删除 DEK。 当加密关闭时,有一个密钥更改,然后你尝试启用加密,"动态管理" 视图(DMV)显示已完成加密。 但是,不会执行加密扫描,也不会对页面进行加密。
解决方案
累积更新信息
SQL Server 2012
此问题的修补程序首次在累积更新1中发布。有关如何为 SQL Server 2012 获取此累积更新包的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2679368 SQL Server 2012 的累积更新包1注意 由于这些版本是累积的,因此每个新的修复版本都包含以前的 SQL Server 2012 修复版本附带的所有修补程序和所有安全修补程序。 我们建议你考虑应用包含此修补程序的最新修复版本。 有关更多信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:
2692828 在 SQL Server 2012 发布后发布的 SQL Server 2012 版本
状态
Microsoft 已确认这是在“适用范围”部分中列出的 Microsoft 产品存在的问题。
解决方法
若要解决此问题,请在每次关闭数据库加密时删除加密密钥。
更多信息
呼叫堆栈信息
FCB::InitializeReencryptionScan ntdbms\storeng\dfs\manager\fcb.cpp 8407FCB::ReencryptFile ntdbms\storeng\dfs\manager\fcb.cpp 8934AsynchronousDiskAction::DoReencryptFile ntdbms\storeng\dfs\manager\asyncdp.cpp 810AsynchronousDiskAction::ExecuteDeferredAction ntdbms\storeng\dfs\manager\asyncdp.cpp 1203AsynchronousDiskPool::ProcessActions ntdbms\storeng\dfs\manager\asyncdp.cpp 2252AsynchronousDiskWorker::ThreadRoutine ntdbms\storeng\dfs\manager\asyncdp.cpp 3120SubprocEntrypoint ntdbms\storeng\dfs\process\subproc.cpp 444SOS_Task::Param::Execute e:\sql11_main_t\sql\common\dk\sos\include\sos.inl 8564SOS_Scheduler::RunTask e:\sql11_main_t\sql\common\dk\sos\src\scheduler.cpp 976SOS_Scheduler::ProcessTasks e:\sql11_main_t\sql\common\dk\sos\src\scheduler.cpp 852SchedulerManager::WorkerEntryPoint e:\sql11_main_t\sql\common\dk\sos\src\node.cpp 1809SystemThread::RunWorker e:\sql11_main_t\sql\common\dk\sos\include\worker.inl 823SystemThreadDispatcher::ProcessWorker e:\sql11_main_t\sql\common\dk\sos\src\node.cpp 449Assert in FCB::InitializeReencryptionScan in file fcb.cpp @ 8407Expression: a_dbDEK->GetDbeState () == CSECDEK::x_dbe_DecryptionInProgress || a_dbDEK->GetDbeState () == CSECDEK::x_dbe_EncryptionInProgress