CTE для поиска последовательных резервных копий в бесконечном цикле - PullRequest
0 голосов
/ 08 сентября 2018

Я написал ниже Рекурсивный запрос 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 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 )

Выше приведен скриншот с результатом. Второй снимок сверху показывает, как информация о резервном копировании начинает повторяться в наборе результатов.

1 Ответ

0 голосов
/ 09 сентября 2018

В строке, на которую указывает ваша красная стрелка, first_lsn и last_lsn равны, поэтому рекурсивный cte продолжает добавлять эту строку (и ее преемники) снова и снова. Вот откуда исходит бесконечный цикл.

...