SQL Server无timestamp列表查询近一小时插入数据的替代方案
以下方案均不需要修改业务表结构、不需要新增列、不需要创建触发器,符合权限限制要求:
变更数据捕获(CDC)
这是比已知变更跟踪(CT)更适配该场景的原生功能,和CT仅跟踪行变更版本不同,CDC会自动捕获所有INSERT/UPDATE/DELETE操作的执行时间、具体变更内容,跟踪数据存在系统自动生成的系统表中,完全不侵入业务表。
RDS SQL Server 标准版及以上版本均支持该功能,开启单表CDC仅需执行系统存储过程,不会改动业务表结构。开启后可通过关联LSN时间映射表直接过滤近1小时的插入记录,示例查询:-- __$operation = 2 对应插入操作 SELECT cdc_table.* FROM cdc.dbo_<你的业务表名>_CT cdc_table JOIN cdc.lsn_time_mapping lsn_map ON cdc_table.__$start_lsn = lsn_map.start_lsn WHERE cdc_table.__$operation = 2 AND lsn_map.tran_end_time >= DATEADD(HOUR, -1, GETUTCDATE())注意CDC会占用少量额外存储存变更日志,适合长期稳定做精确查询的场景。
事务日志直接解析
SQL Server所有数据插入操作都会完整记录在事务日志中,和是否有时间戳列无关。你可以通过原生的日志查询函数sys.fn_dblog直接读取在线事务日志,按事务提交时间过滤近1小时的目标表插入记录,不需要提前开启任何功能,只要有服务器状态查看权限即可使用,示例:SELECT * FROM sys.fn_dblog(NULL, NULL) WHERE Operation = 'LOP_INSERT_ROWS' AND AllocUnitName LIKE 'dbo.<你的业务表名>%' AND [Begin Time] >= DATEADD(HOUR, -1, GETDATE())该方案适合临时一次性排查场景:在线日志会被循环覆盖,如果近1小时日志已经被备份截断,需要改用
sys.fn_dump_dblog读取对应的日志备份文件;另外日志中存储的是原始行格式,需要手动对应业务字段做解析,不适合高频业务查询。扩展事件(Extended Events)捕获
你可以在实例级别创建轻量级扩展事件会话,专门捕获目标表的INSERT完成事件,记录事件发生时间和插入的行数据。整个配置在服务端完成,完全不触碰业务表,性能损耗远低于触发器。
注意该方案只能捕获会话创建之后产生的插入记录,无法回溯历史数据,适合需要长期持续监控新增记录、对性能损耗敏感的场景。数据页LSN近似匹配
SQL Server每个数据页的页头都会记录最后一次修改该页的LSN(日志序列号),而LSN和事务提交时间是一一映射的。你可以先计算出1小时前时间点对应的LSN基线,再扫描目标表筛选出所在页LSN大于基线的记录,即可得到近1小时左右插入/修改的近似结果。
该方案不需要开启任何额外功能,仅有表查询权限即可使用,但结果存在少量误差:如果数据页在近1小时被修改过,页上存储的更早插入的记录也会被一并返回,适合对精度要求不高、需要快速捞取近似数据的场景。
选型建议:长期做精确查询优先选CDC;临时排查优先用事务日志解析;长期低损耗监控选扩展事件;快速捞近似数据用LSN匹配即可。
内容的提问来源于stack exchange,提问作者Himanshu Pingulkar

