小编Eri*_*obb的帖子

备份压缩导致 SQL 2017 TDE 数据库损坏

在 SQL Server 2017 (CU3) 上,每当我在我的一个 TDE 数据库上启用备份压缩时,备份过程总是会损坏数据库中的特定页面。如果我在不压缩的情况下运行备份,它不会被损坏。以下是我为验证和重现此问题而采取的步骤:

  1. 在数据库“TDE_DB1”上运行 DBCC CheckDB;一切都很好,没有错误;
  2. 成功备份数据库,无需压缩;RESTORE VERIFYONLY 表示一切正常;
  3. 成功将数据库恢复为“TDE_DB2”;一切都很好,DBCC CheckDB 没有显示错误;
  4. 成功备份“TDE_DB1”数据库WITH压缩;RESTORE VERIFYONLY 错误,提示“检测到备份集损坏”;
  5. 尝试将数据库恢复为“TDE_DB2”;错误,说“RESTORE 在数据库中的页面 (1:92454) 上检测到错误”
  6. 重复步骤1-3;一切都很好;
  7. 删除“TDE_DB1”和“TDE_DB2”;从备份中恢复“TDE_DB1”;一切都很好;
  8. 重复步骤1-5;得到相同的结果;

总结一下:数据库和常规备份看起来不错,在数据库上运行 CHECKDB 并在备份上运行 VERIFYONLY 不会报告任何错误。使用压缩备份数据库似乎会导致损坏。

下面是有错误的代码示例。(注意:在 TDE 数据库中使用压缩需要 MAXTRANSFERSIZE

-- Good, completes with no corruption;
BACKUP DATABASE [TDE_DB1] TO DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;
RESTORE VERIFYONLY FROM DISK = N'E:\MSSQL\Backup\TDE_DB1a.bak' WITH CHECKSUM;

RESTORE DATABASE [TDE_DB2]
FROM DISK = 'E:\MSSQL\Backup\TDE_DB1a.bak'
WITH MOVE 'DataFileName' to 'E:\MSSQL\Data\TDE_DB2.mdf'
,MOVE 'LogFileName' to 'F:\MSSQL\Log\TDE_DB2_log.ldf';


-- Bad, I …
Run Code Online (Sandbox Code Playgroud)

sql-server corruption transparent-data-encryption sql-server-2017

13
推荐指数
1
解决办法
823
查看次数

使用扩展事件跟踪表的更新

我有一张不断更新的表,没有人能弄清楚更新的来源。我怀疑它们来自实体框架,但我想通过扩展事件捕获更新和相关信息来证明这个理论。

我正在使用 SQL 2014 Enterprise,并尝试使用 exec_prepared_sql 和 sql_statement_starting 事件捕获该信息。这是我到目前为止所拥有的:

CREATE EVENT SESSION [Query Trace] ON SERVER 
ADD EVENT sqlserver.exec_prepared_sql(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
    WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123))),
ADD EVENT sqlserver.sql_statement_starting(
    ACTION(sqlserver.client_app_name,sqlserver.client_hostname,sqlserver.database_id,sqlserver.database_name,sqlserver.plan_handle,sqlserver.session_id,sqlserver.sql_text,sqlserver.username)
    WHERE ([sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%UPDATE %') AND [sqlserver].[like_i_sql_unicode_string]([sqlserver].[sql_text],N'%TableA%') AND [sqlserver].[database_id]=(123)))
ADD TARGET package0.event_file(SET filename=N'E:\ExtendedEvent\Query-Trace.xel')
WITH (MAX_MEMORY=4096 KB,EVENT_RETENTION_MODE=ALLOW_SINGLE_EVENT_LOSS,MAX_DISPATCH_LATENCY=30 SECONDS,MAX_EVENT_SIZE=0 KB,MEMORY_PARTITION_MODE=NONE,TRACK_CAUSALITY=ON,STARTUP_STATE=OFF)
GO
Run Code Online (Sandbox Code Playgroud)

这似乎工作得很好,我已经对其进行了测试,并且能够捕获常规 UPDATE 语句和使用 sp_executesql 调用的语句。但是,我仍然缺少一些东西。表中的数据仍在修改,并且此扩展事件未捕获执行此操作的 UPDATE。

所以,我的问题是:

1) 为了捕获可能来自实体框架的更新,我还需要在扩展事件中观察其他什么吗?

2)为此我应该使用其他什么来代替扩展事件吗?

谢谢!

sql-server extended-events sql-server-2014

7
推荐指数
1
解决办法
8157
查看次数