예약 된 백업 작업이 항상 작업이 성공했다고 말하더라도 모든 데이터베이스를 항상 백업하지는 않습니다.


9

SQL 2008에는 모든 데이터베이스를 백업하기 위해 저장된 proc을 실행하는 작업이 있습니다. 이것은 SQL Server 에이전트 작업을 통해 매일 실행됩니다.

매일 성공으로 종료되지만 며칠 동안 몇 개의 데이터베이스를 백업 한 후에 만 ​​성공으로 종료됩니다. 매번 다른 수의 데이터베이스가 될 수 있습니다. 대부분의 날은 모든 데이터베이스를 성공적으로 백업하지만 때로는 2 백업, 때로는 5 등을 백업합니다.

작업 기록, 이벤트 뷰어 또는 SQL Server 로그에 오류가 표시되지 않습니다.

폴더는 확장 가능한 스토리지 볼륨의 폴더에 대한 "접합"이지만 로컬 디스크에 백업이 수행됩니다.

OS는 Vmware ESXi 5 호스트에서 실행되는 가상 머신으로 Sql Server 2008 웹 에디션 64 비트를 실행하는 Windows 2003 64 비트입니다.

저장 프로 시저 :

ALTER PROCEDURE [dbo].[backup_all_databases] 
@path VARCHAR(255)='c:\backups\'

AS

DECLARE @name VARCHAR(50) -- database name  
DECLARE @fileName VARCHAR(256) -- filename for backup  
DECLARE @fileDate VARCHAR(20) -- used for file name 
DECLARE @dbIsReadOnly sql_variant -- is database read_only?
DECLARE @dbIsOffline sql_variant -- is database offline?

DECLARE db_cursor CURSOR FOR  
SELECT name 
FROM master.dbo.sysdatabases 
WHERE name NOT IN ('tempdb')
AND version > 0 AND version IS NOT NULL

OPEN db_cursor   
FETCH NEXT FROM db_cursor INTO @name   

WHILE @@FETCH_STATUS = 0   
BEGIN   
SET @fileName = @path + @name + '.bak'

SET @dbIsReadOnly = (SELECT DATABASEPROPERTY(@name, 'IsReadOnly')) -- 1 = Read Only
SET @dbIsOffline = (SELECT DATABASEPROPERTY(@name, 'IsOffline')) -- 1 = Offline

IF (@dbIsReadOnly = 0 OR @dbIsReadOnly IS NULL) AND @dbIsOffline =0
BEGIN
    BACKUP DATABASE @name TO DISK = @fileName  WITH INIT
    WAITFOR DELAY '00:00:20'
END

FETCH NEXT FROM db_cursor INTO @name 
END   

CLOSE db_cursor   
DEALLOCATE db_cursor

제발 어떤 제안?

답변:


9

오류를 처리하고 기록하기 위해 TRY / CATCH 블록을 추가합니다. DB는 단일 사용자이거나 복원 중이거나 기타 무엇이든 가능합니다.

그렇지 않으면 오류가 기록되지 않는 방식으로 오류가 중단 될 수 있습니다 (상태, 배치, 범위, 연결 등)

TRY / CATCH를 사용하면 컴파일 또는 연결 중단 오류를 제외한 모든 것이 기록됩니까? 그러나 나는 이것이 사실인지 의심한다.

또한 sysdatabases를 대체하고 더 많은 플래그를 읽는 sys.databases 를 사용 합니다.

-- declares etc

BEGIN TRY

    DECLARE db_cursor CURSOR FOR  
    SELECT name, state, user_access
    FROM sys.databases 
    WHERE name NOT IN ('tempdb')

    OPEN db_cursor   
    FETCH NEXT FROM db_cursor INTO @name, @state, @user_access

    WHILE @@FETCH_STATUS = 0   
    BEGIN   

        SET @fileName = @path + @name + '.bak'
        IF @state = 0 AND user_access = 0
        BEGIN
            BEGIN TRY
                BACKUP DATABASE @name TO DISK = @fileName  WITH INIT
            END TRY
            BEGIN CATCH
                -- log but do not rethrow so loop continues
            END CATCH
            WAITFOR DELAY '00:00:20'
        END
        ELSE
           --log user and/or state issues

        FETCH NEXT FROM db_cursor INTO @name 
    END   

    CLOSE db_cursor   
    DEALLOCATE db_cursor

END TRY
BEGIN CATCH
  -- some useful stuff here
END CATCH

sys.databases 사용에 대한 조언 +1
Peter Schofield

2

"backup"명령 후 오류를 확인하고 감지 된 오류가 있는지 이메일을 보내십시오.

이것은 당신에게 무슨 일이 일어나고 있는지 볼 수있는 출발점을 제공하고, 당신이 직업 문제를 정리할 때까지 어떤 문제에 대해서도 경고 할 것을 보장합니다.


2

커서로 주문하십시오. SQL에서 데이터가 반환되는 순서를 선택할 수있게하면 sys.databases에 커서에 "문제"가있는 것을 보았습니다. 이름으로 주문하면 충분합니다.


2

테이프 백업 또는 다른 프로세스가 백업 파일을 복사하거나 액세스하는 것과 동시에 백업이 실행됩니까? 그렇다면 파일이 사용 중이기 때문에 파일을 덮어 쓰지 않는 것이 좋습니다. 여러 개의 백업 사본을위한 공간이있는 경우 출력 파일에 날짜 스탬프를 추가하도록 proc을 변경할 수 있지만 정리 루틴이 필요합니다.


내가 아는 것은 아닙니다. 백업은 로컬에서 수행 한 후 몇 시간 후에 rsync로 오프 사이트에서 수행됩니다.
Andy Davies

0

SQL Server 2005가 도입되면서 sysdatabases 및 sys.databases를 통한 커서 루프가 변경되어 신뢰할 수 없었습니다. 이러한 동작 변경은 sp_foreachdb에서도 볼 수 있습니다.

커서 유형을 변경하면 도움이되는 것으로 나타 났지만 (빠른 진행이라고 생각합니다.) 궁극적으로 Ola Hallengren의 백업 및 유지 관리 솔루션과 같은 솔루션으로 전환했습니다. 백업과 같은 중요한 것들과 마찬가지로, 모든 잠재적 인 솔루션으로도 백업되었는지 확인하기 위해 모든 데이터베이스를 교차 점검해야합니다.

커서 유형 : http://msdn.microsoft.com/en-us/library/ms378405(v=SQL.90).aspx

Ola의 유지 관리 솔루션 : http://ola.hallengren.com/


0

특히 큰 DB를 백업하는 동안 동일한 문제가 발생했습니다.

@@fetch_status는 GLOBAL 변수이므로 사용자가 아닌 다른 커서로 변경 될 수 있습니다 (0으로 설정). 다음을 수행하여 (의사 코드로) 해결했습니다.

create a temp table with dbNames
select top 1 in a variable (use order by)
while variable is null
do your thing

set variable = null
delete top 1(use order by)
select top 1 in a variable (use order by)
loop

-1

나는이 문제를 알아 내려고 노력했으며 사용자가 커서 선언을 둔감하게하면 작동하기 시작하는 솔루션을 여러 번 게시 한 것처럼 보입니다. 그래서 나는 그것을 테스트했으며 커서 선언이 정적이며 작동하기 시작하는지 확인합니다.

실패한 사실은-서버 레벨 커서 임계 값 설정을 확인하십시오--1로 구성된 경우 커서 키 세트를 읽으려고 시도하는 동안 모든 커서가 동 기적으로 채워지는 것을 의미합니다. 동시에 읽으십시오. 이 값을 0으로 변경하면 SQL 서버가 간단한 단어로 비동기 채우기를 수행하도록 지시하면 키 세트가 여전히 채워지는 동안 커서가 레코드를 가져올 수 있으며 서버 수준 에서이 변경을 수행 한 후에는 사용중인 데이터베이스를 놓치지 않을 것입니다 커서.

솔루션 : 커서 정적 선언 또는 서버 레벨 설정 "커서 임계 값"을 -1에서 0으로 변경하십시오.

감사합니다, Gaurav Mishra | 선임 DBA

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.