如何检测数据库(DDL和DML)的任何更改
-
16-10-2019 - |
题
我客户端的SQL Server上有很多数据库。这些数据库正在开发中,因此开发人员可以设计,重构,进行数据修改等。有些数据库很少发生变化。我的客户必须确保所有这些都安全(备份),并花一些时间来管理环境。 (公司在公司中没有DB管理员职位。)经过长时间的讨论,由于易于恢复,客户已决定使用每日完整的备份策略。
因此,这是情况的摘要:
- 数据库的数量每天可能有所不同。
- 已更改的数据库(意味着已更改数据和/或结构)应备份。
- 未更改的数据库不得备份。
- 解决方案不影响数据库结构(这不是限制要求)
- 该“备份引擎”应自动工作。
主要问题:如何检测数据库已更改。 问题的第一部分(DDL更改)可以通过使用 DDL触发器. 。但是数据更改(DML更改)是一个问题。不可能将DML触发器应用于所有数据库的所有表来跟踪更改(性能,扩展对象的管理...)。备份引擎必须跟踪所有更改,以将每个数据库标记为准备备份。
更改数据捕获 是一个解决方案,但似乎太重(也需要SQL Server Enterprise Edition)。
另一种方法是跟踪数据库文件更改(大小或最后更改时间),但它无法正常工作:当数据库超过所有保留的自由空间和 sp_spaceused 不是解决方案。
跟踪是一种解决方案,但它导致 性能问题 并需要额外的管理。
是否有任何解决方案来计算实际数据库使用大小,而不会影响其他数据库管理对象(例如统计信息..)?当然,对表格数据的更改不会改变表的大小不会触发(我认为),但总比没有好。真的,我正在寻找SQL Server 2008的直接或间接解决方案。
感谢您的任何评论,解决方案和想法。
添加:
这是解决方案(感谢 玛丽安):
Select
NextLSN = MAX(fn.[Current LSN])
,Databasename = DB_NAME()
from fn_dblog(NULL, NULL) fn
LEFT JOIN sys.allocation_units au
ON fn.AllocUnitId = au.allocation_unit_id
LEFT JOIN sys.partitions p
ON p.partition_id = au.container_id
LEFT JOIN sys.objects so
ON so.object_id = p.object_id
WHERE
(
(Operation IN
('LOP_INSERT_ROWS','LOP_MODIFY_ROW',
'LOP_DELETE_ROWS','LOP_BEGIN_XACT','LOP_COMMIT_XACT')
AND so.is_ms_shipped = 0)
OR
([Lock Information] like '%ACQUIRE_LOCK_SCH_M OBJECT%')
)
解决方案
一个想法是每天制作快照,并使用文件监视器监视磁盘上的快照大小。该快照仅在添加数据时会增加其大小,因此,如果您会找到一种工具来监视实际尺寸(报告的尺寸),那将是一个有效的想法。
现在..我没有使用它,所以不能给您技术见解:-)。
另一个想法是验证我在论坛上看到的某些功能(db_fnlog ..或某些东西),验证每个DB的交易日志(如果您在它们上使用完整恢复模式),这些功能从日志读取操作,看看您是否有任何删除/插入/更新。
这些绝非易事。但是我希望您会发现它们有用。
PS:使用日志读取函数找到文章(这是fndblog,顺便说一句:-):: 阅读Jens K. Suessmeyer的交易日志.
其他提示
- 对于DDL更改,您可能会阅读默认跟踪.
- 对于DML修改,由于您发现CDC有点重,因此您可以运行自己的轻量级服务器端跟踪,该跟踪仅跟踪相关事件
对于DDL更改您的DDL触发器,但是DML更改可以尝试使用3个不同的选项
1)更改跟踪2)CDC(更改数据捕获)3)审核功能
用于更改跟踪..您可以看到以下链接 http://www.mssqltips.com/sqlservertip/1819/ususe-change-tracking-in-sql-server-2008/
此更改跟踪只会使用呼啸声,表是否已更改...但是很难找到已更改的数据。
对于sqlserver中的aduit ..您可以检查以下链接 http://blogs.msdn.com/b/manisblog/archive/2008/07/21/sql-server-2008-auditing.aspx
对于DML更改,您可以使用任何关注者本机SQL Server审核功能:
- SQL Server更改跟踪
- SQL Server更改数据捕获
- SQL服务器审核
每个人都有其优点和缺点,但是审计是微软最新提出的,因此,最好构建包含它的当前和将来的解决方案是一个好主意。
请注意,只有审核功能才能提供有关谁 /何时 /如何的信息
您可以使用跟踪文件检测任何DDL更改。以下是脚本以获取更改。
SELECT
te.name AS eventtype
,t.loginname
,t.spid
,t.starttime
,t.objectname
,t.databasename
,t.hostname
,t.ntusername
,t.ntdomainname
,t.clientprocessid
,t.applicationname
FROM sys.fn_trace_gettable
(
CONVERT
(VARCHAR(150)
,(
SELECT TOP 1
value
FROM sys.fn_trace_getinfo(NULL)
WHERE property = 2
)),DEFAULT
) T
INNER JOIN sys.trace_events as te
ON t.eventclass = te.trace_event_id
WHERE eventclass=164
您可以使用此脚本检测表和存储过程的任何修改:
SELECT
SO.Name
,SS.name
,SO.type_desc
,SO.create_date
,SO.modify_date
FROM sys.objects AS SO
INNER JOIN sys.schemas AS SS
ON SS.schema_id = SO.schema_id
WHERE DATEDIFF(D,modify_date, GETDATE()) < 50
AND TYPE IN ('P','U')