spDeleteUpdate 저장 프로시저가 느리게 실행됩니다.
저장 프로시저가 spDeleteUpdate
실행되면 단일 업데이트를 삭제하는 데 수십 초가 걸릴 수 있습니다. WSUS(Windows Server Update Services) 유지 관리 중에 수백 또는 수천 개의 업데이트를 삭제하는 데 사용하는 spDeleteUpdate
경우 완료하는 데 며칠이 걸릴 수 있습니다.
원인
기본 키가 만들어 spDeleteUpdate
지는 임시 테이블에 설정되지 않았기 때문에 성능이 저하됩니다.
해결
이 문제를 해결하려면 영향을 받는 모든 WSUS 서버에서 WSUS 데이터베이스(SUSDB)에 대해 다음 SQL 스크립트를 실행합니다. 이 스크립트는 임시 테이블에서 기본 키를 @revisionList
설정합니다.
USE [SUSDB]
GO
/****** Object: StoredProcedure [dbo].[spDeleteUpdate] Script Date: 11/2/2020 8:55:02 AM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
ALTER PROCEDURE [dbo].[spDeleteUpdate]
@localUpdateID int
AS
SET NOCOUNT ON
BEGIN TRANSACTION
SAVE TRANSACTION DeleteUpdate
DECLARE @retcode INT
DECLARE @revisionID INT
DECLARE @revisionList TABLE(RevisionID INT PRIMARY KEY)
INSERT INTO @revisionList (RevisionID)
SELECT r.RevisionID FROM dbo.tbRevision r
WHERE r.LocalUpdateID = @localUpdateID
IF EXISTS (SELECT b.RevisionID FROM dbo.tbBundleDependency b WHERE b.BundledRevisionID IN (SELECT RevisionID FROM @revisionList))
OR EXISTS (SELECT p.RevisionID FROM dbo.tbPrerequisiteDependency p WHERE p.PrerequisiteRevisionID IN (SELECT RevisionID FROM @revisionList))
BEGIN
RAISERROR('spDeleteUpdate got error: cannot delete update as it is still referenced by other update(s)', 16, -1)
ROLLBACK TRANSACTION DeleteUpdate
COMMIT TRANSACTION
RETURN(1)
END
INSERT INTO @revisionList (RevisionID)
SELECT DISTINCT b.BundledRevisionID FROM dbo.tbBundleDependency b
INNER JOIN dbo.tbRevision r ON r.RevisionID = b.RevisionID
INNER JOIN dbo.tbProperty p ON p.RevisionID = b.BundledRevisionID
WHERE r.LocalUpdateID = @localUpdateID
AND p.ExplicitlyDeployable = 0
IF EXISTS (SELECT IsLocallyPublished FROM dbo.tbUpdate WHERE LocalUpdateID = @localUpdateID AND IsLocallyPublished = 1)
BEGIN
INSERT INTO @revisionList (RevisionID)
SELECT DISTINCT pd.PrerequisiteRevisionID FROM dbo.tbPrerequisiteDependency pd
INNER JOIN dbo.tbUpdate u ON pd.PrerequisiteLocalUpdateID = u.LocalUpdateID
INNER JOIN dbo.tbProperty p ON pd.PrerequisiteRevisionID = p.RevisionID
WHERE u.IsLocallyPublished = 1 AND p.UpdateType = 'Category'
END
DECLARE #cur CURSOR LOCAL FAST_FORWARD FOR
SELECT t.RevisionID FROM @revisionList t ORDER BY t.RevisionID DESC
OPEN #cur
FETCH #cur INTO @revisionID
WHILE (@@ERROR=0 AND @@FETCH_STATUS=0)
BEGIN
IF EXISTS (SELECT b.RevisionID FROM dbo.tbBundleDependency b WHERE b.BundledRevisionID = @revisionID
AND b.RevisionID NOT IN (SELECT RevisionID FROM @revisionList))
OR EXISTS (SELECT p.RevisionID FROM dbo.tbPrerequisiteDependency p WHERE p.PrerequisiteRevisionID = @revisionID
AND p.RevisionID NOT IN (SELECT RevisionID FROM @revisionList))
BEGIN
DELETE FROM @revisionList WHERE RevisionID = @revisionID
IF (@@ERROR <> 0)
BEGIN
RAISERROR('Deleting disqualified revision from temp table failed', 16, -1)
GOTO Error
END
END
FETCH NEXT FROM #cur INTO @revisionID
END
IF (@@ERROR <> 0)
BEGIN
RAISERROR('Fetching a cursor to value a revision', 16, -1)
GOTO Error
END
CLOSE #cur
DEALLOCATE #cur
DECLARE #cur CURSOR LOCAL FAST_FORWARD FOR
SELECT t.RevisionID FROM @revisionList t ORDER BY t.RevisionID DESC
OPEN #cur
FETCH #cur INTO @revisionID
WHILE (@@ERROR=0 AND @@FETCH_STATUS=0)
BEGIN
EXEC @retcode = dbo.spDeleteRevision @revisionID
IF @@ERROR <> 0 OR @retcode <> 0
BEGIN
RAISERROR('spDeleteUpdate got error from spDeleteRevision', 16, -1)
GOTO Error
END
FETCH NEXT FROM #cur INTO @revisionID
END
IF (@@ERROR <> 0)
BEGIN
RAISERROR('Fetching a cursor to delete a revision', 16, -1)
GOTO Error
END
CLOSE #cur
DEALLOCATE #cur
COMMIT TRANSACTION
RETURN(0)
Error:
CLOSE #cur
DEALLOCATE #cur
IF (@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION DeleteUpdate
COMMIT TRANSACTION
END
RETURN(1)
GO