Sql server CTE查找无限循环中运行的顺序备份
我在下面编写了递归CTE查询,以按顺序查找日志备份,将下一个备份文件的LastLSN与FirstLSN匹配。但它一直在运行,似乎在某个地方成倍增加了行数。我需要帮助找出问题所在Sql server CTE查找无限循环中运行的顺序备份,sql-server,tsql,backup,Sql Server,Tsql,Backup,我在下面编写了递归CTE查询,以按顺序查找日志备份,将下一个备份文件的LastLSN与FirstLSN匹配。但它一直在运行,似乎在某个地方成倍增加了行数。我需要帮助找出问题所在 DECLARE @First_LSN varchar(100) DECLARE @Last_LSN varchar(100) DECLARE @Checkpoint_LSN varchar(100) DECLARE @DatabaseBackup_LSN varchar(100) DECLARE @BackupType
DECLARE @First_LSN varchar(100)
DECLARE @Last_LSN varchar(100)
DECLARE @Checkpoint_LSN varchar(100)
DECLARE @DatabaseBackup_LSN varchar(100)
DECLARE @BackupType VARCHAR(5);
DECLARE @DbName varchar(200);
SELECT @First_LSN = '3310284000022460000027', @Last_LSN = '3310301000015143400001', @Checkpoint_LSN = '3310284000022460000027', @DatabaseBackup_LSN = '3306268000010398600106'
,@BackupType = 'I'
,@DbName = 'Mosaic';
;WITH T1 AS
(
SELECT CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS SERVER
,bs.database_name
,bs.backup_start_date
,bs.backup_finish_date
,bs.expiration_date
,CASE bs.type
WHEN 'D'
THEN 'Database'
WHEN 'L'
THEN 'Log'
WHEN 'I'
THEN 'Differential'
ELSE NULL
END AS backup_type
,bs.backup_size
,bmf.logical_device_name
,bmf.physical_device_name
,bs.NAME AS backupset_name
,bs.description
,first_lsn
,last_lsn
,checkpoint_lsn
,database_backup_lsn
,is_copy_only
FROM msdb.dbo.backupmediafamily AS bmf
INNER JOIN msdb.dbo.backupset AS bs ON bmf.media_set_id = bs.media_set_id
WHERE database_name = @DbName
and is_copy_only = 0
and (
(@BackupType = 'L' AND bs.type = 'L' AND first_lsn = @Last_LSN) -- When both are log
OR
(@BackupType = 'I' AND bs.type = 'L' AND cast((cast(@Last_LSN as decimal(36,0))+1) as varchar(50)) BETWEEN first_lsn and last_lsn) -- When Last was Diff, and next is Log
OR
(@BackupType = 'D' AND bs.type = 'L' AND cast((cast(@Last_LSN as decimal(36,0))+1) as varchar(50)) BETWEEN first_lsn and last_lsn) -- When Last was Diff, and next is Log
)
--
UNION ALL
--
SELECT CONVERT(CHAR(100), SERVERPROPERTY('Servername')) AS SERVER
,bs.database_name
,bs.backup_start_date
,bs.backup_finish_date
,bs.expiration_date
,CASE bs.type
WHEN 'D'
THEN 'Database'
WHEN 'L'
THEN 'Log'
WHEN 'I'
THEN 'Differential'
ELSE NULL
END AS backup_type
,bs.backup_size
,bmf.logical_device_name
,bmf.physical_device_name
,bs.NAME AS backupset_name
,bs.description
,bs.first_lsn
,bs.last_lsn
,bs.checkpoint_lsn
,bs.database_backup_lsn
,bs.is_copy_only
FROM T1
INNER JOIN msdb.dbo.backupset AS bs ON T1.last_lsn = bs.first_lsn
INNER JOIN msdb.dbo.backupmediafamily AS bmf ON bmf.media_set_id = bs.media_set_id
WHERE bs.database_name = @DbName
and bs.is_copy_only = 0
and bs.type = 'L'
)
SELECT *
FROM T1
option ( MaxRecursion 500 )
以上是结果的屏幕截图。顶部的第二个快照显示备份信息如何开始在resultset中重复。在红色箭头指向的行中,第一个\u lsn和最后一个\u lsn是相等的,因此递归cte会不断重复添加该行(及其后续行)。这就是无限循环的由来。很奇怪,为什么不拉取所有备份,按比赛日期排序,然后使用LAG或其他窗口功能查看是否缺少备份?提示:常见的调试技术是在CTE中添加一个计数器,例如,锚定中的
1作为行
,递归查询中的Rows+1
,然后通过向where
子句中添加Rows<10和
来限制结果。如果您想看到更多(或更少)行,请查看递归的前进方向并调整限制。@scsimon,您建议的方法是我常用的方法。但昨天,我们的2节点SQL集群崩溃了,我们遇到了一个非常奇怪的情况,SQL服务被卡住了,部分运行在被动节点上。这导致日志备份作业同时在两台服务器上运行:)下面是示例屏幕截图,我们可以在其中同时看到日志备份(默认情况下应序列化)。谢谢,@Wolfgang Kais。我的眼睛看不到:)