연구개발/SQL2005

로그전달 구축강좌 5/6 - 복원 수행 프로시저, 테이블 생성

알 수 없는 사용자 2009. 6. 18. 19:52

[Section 5] 대상 서버에서 로그 복원을 수행할 테이블 및 프로시저 생성, 공유 폴더 설정

원본 서버에서 발생되는 트랜잭션 로그 파일을 저장할 공유 폴더를 설정하고, 로그 복원을 수행할 저장 프로시저를 생성합니다.

 

 

10. [대상 서버] 로그 백업 파일을 가져오기 위한 작업과 관련된 테이블과 저장 프로시저를 생성합니다. 쿼리 분석기에서 대상서버로 연결한 후, 다음 스크립트를 수행하여 테이블과 저장 프로시저를 생성합니다.

USE MSDB

GO

 

--로그 백업 수행 정보를 보관하는 테이블

if EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[TB_LOGRESTORELIST]') AND OBJECTPROPERTY(id, N'IsUserTable') = 1)

drop table [dbo].[TB_LOGRESTORELIST]

GO

 

CREATE TABLE [dbo].[TB_LOGRESTORELIST] (

             [No] [int] NOT NULL ,

             [List] [varchar] (128) COLLATE Korean_Wansung_CI_AS NOT NULL ,

             [RestoreYN] [char] (1) NOT NULL Default('N'),

             [CopyYN] [char] (1) NOT NULL Default('N'),

             [FileSize] [bigint] NOT NULL Default(0),

             [Start_Time] [datetime] NULL,

             [End_Time] [datetime] NULL,

             [Duration] AS ISNULL(DATEDIFF(SS, Start_Time, End_Time), 0)

) ON [PRIMARY]

GO

 

CREATE CLUSTERED INDEX CIX_TB_LOGRESTORELIST ON TB_LOGRESTORELIST(No)

GO

 

 

11. [대상 서버] 원본 서버의 트랜잭션 로그 파일을 가져와서 저장할 폴더를 생성하고, 이 폴더를 공유합니다. 공유 권한은 읽기 및 쓰기로 지정 되어야 합니다. 본 예제에서는 D:\LogBackup_Target 이라는 폴더를 이용하겠습니다.

 

 

 

12. [대상 서버] 원본 서버에 있는 로그 리스토어 정보 테이블을 읽어오기 위해 대상 서버와 원본 서버 간의 연결을 설정해 줘야 합니다. 다음과 같은 방식으로 대상 서버에서 연결을 설정합니다.

--대상 서버(ADC2)에서 원본 서버(ADC1)으로 Linked Server를 설정합니다

 

sp_addlinkedserver 'ADC1'

GO

 

sp_addlinkedsrvlogin 'ADC1', 'false', NULL, '<로그인 아이디>', '<로그인 패스워드>'

GO

 

 

13. [대상 서버] 이제 로그 백업 파일을 복사해 오는 작업을 수행할 저장 프로시저와, 로그 백업을 수행하기 전에 해당 DB의 사용자를 모두 Kill 시키는 프로시저, 로그 백업 정보를 이용하여 복원을 수행하는 프로시저를 생성하겠습니다. 쿼리 분석기를 이용하여 다음 스크립트를 실행하여 프로시저 들을 생성합니다.

 

USE MSDB

GO

 

--대상 서버(ADC2)에서 로그 리스토어를 수행하기 전에 해당DB(TestDB)를 사용하는 프로세스를 KILL하는 프로시저

if EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[USP_KillSPIDUsing_TestDB]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[USP_KillSPIDUsing_TestDB]

GO

 

 

CREATE PROC USP_KillSPIDUsing_TestDB

AS     

BEGIN      

             SET NOCOUNT ON      

             DECLARE  @spid  smallint, @str  varchar(50)     

 

             SELECT spid INTO  #SPID_USING_USERDB      

             FROM master..sysprocesses      

             WHERE dbid=db_id('TestDB') AND cmd NOT LIKE 'RESTORE LOG%' -- Log Restore Process는제외    

             AND program_name NOT LIKE 'SQLAgent%' AND program_name NOT LIKE 'DTS%'   

               -- SQLAgent 관련Process는제외    

             UNION

             SELECT spid FROM master..sysprocesses a  

             WHERE EXISTS (SELECT 1 FROM master..syslocks

                          WHERE spid = a.spid AND dbid = db_id('TestDB')) AND

                          cmd NOT LIKE 'RESTORE LOG%' AND -- Log Restore Process는제외    

                          program_name NOT LIKE 'SQLAgent%' AND program_name NOT LIKE 'DTS%' 

 

             DECLARE spid_cursor CURSOR      

             FOR SELECT spid FROM #SPID_USING_USERDB FOR READ ONLY     

            

             OPEN spid_cursor     

             FETCH NEXT FROM spid_cursor INTO @spid     

                           WHILE @@FETCH_STATUS = 0     

                                        BEGIN     

                                                     SET @str = 'kill ' + CONVERT (char(5), @spid)      

                                                     EXECUTE (@str)     

                                                     FETCH NEXT FROM spid_cursor INTO @spid     

                                        END     

               

             CLOSE spid_cursor     

             DEALLOCATE spid_cursor     

             END   

GO

 

 

USE MSDB

GO

 

--원본서버(ADC1)에서 대상서버(ADC2)로 로그 파일을 복사하는 스크립트

if EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[USP_LOGCOPY]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[USP_LOGCOPY]

GO

 

CREATE PROCEDURE USP_LOGCOPY AS

SET NOCOUNT ON                   

 DECLARE @list varchar(128), @copystr varchar(256), @no int, @maxno int     

     

 --TB_LOGRESTORELIST 에서의최종No를구한다.      

 SELECT @maxno = isnull(MAX(No), 0) FROM TB_LOGRESTORELIST WITH (NOLOCK)     

     

 --ADC1 서버로부터 새로 추가된 리스트 정보를 입력 받아서 TB_LOGRESTORELIST에 저장    

 INSERT msdb.dbo.TB_LOGRESTORELIST(No, List)     

 SELECT No, List FROM ADC1.msdb.dbo.TB_LOGBACKUPLIST     

 WHERE No>@maxno     

     

     

 DECLARE  cur cursor  for                 

 SELECT NO, LIST FROM TB_LOGRESTORELIST WITH (NOLOCK) WHERE CopyYN = 'N'     

 ORDER BY  NO     

 -- logbackuplist에서 CopyYN = 'N' 인것을가져온다.     

                  

 OPEN cur                 

 FETCH  NEXT FROM cur  INTO  @no, @list          

                  

 WHILE  @@fetch_status =  0      

 BEGIN 

 

 -- 파일을 복사하기 전 CopyYN = 'C'로 설정  

     UPDATE TB_LOGRESTORELIST SET CopyYN = 'C' WHERE NO = @no     

 

  SET @copystr = 'COPY \\ADC1\LogBackup\' + @list +' \\ADC2\LogBackup_Target\'           

     EXEC master..xp_cmdshell @copystr, NO_OUTPUT      

 

   IF @@ERROR = 0

     BEGIN

          UPDATE TB_LOGRESTORELIST SET CopyYN = 'Y' WHERE NO = @no     

 

 

          --Copy 해온파일의Size를계산시작

          DECLARE @tmpStr varchar(500), @tmpResultStr varchar(500)

 

          CREATE TABLE #TEMPSIZE(RESULTSTR VARCHAR(1000))

 

          SET @tmpStr = 'dir \\ADC2\LogBackup_Target\' + @List + ' |find "' + @List + '"'

 

          INSERT #TEMPSIZE

          EXEC master..xp_cmdshell @tmpStr

 

          DELETE FROM #TEMPSIZE WHERE RESULTSTR IS NULL

 

          IF EXISTS (SELECT 1 FROM #TEMPSIZE)

            BEGIN

              SET @tmpResultStr = (SELECT TOP 1 RESULTSTR FROM #TEMPSIZE)

 

               SET @tmpResultStr = REPLACE(REPLACE(REPLACE(SUBSTRING(@tmpResultStr, 19, LEN(@tmpResultStr)), @List, ''), ' ',''),',','')

 

              IF ISNUMERIC(@tmpResultStr) = 1

                 BEGIN

                           UPDATE TB_LOGRESTORELIST SET FileSize = CAST(@tmpResultStr AS INT) WHERE NO = @no

                 END

            END

 

          DROP TABLE #TEMPSIZE

          --Copy 해온 파일의 Size 계산 종료

 

        END

     

  FETCH  NEXT FROM cur  INTO  @no, @list          

 END     

 

 CLOSE  cur                 

 DEALLOCATE  cur       

GO

 

 

 

USE MSDB

GO

 

--대상 서버(ADC2)에서 로그 리스토어를 수행하는 프로시저

if EXISTS (SELECT * FROM dbo.sysobjects WHERE id = object_id(N'[dbo].[USP_LOGRESTORE]') AND OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[USP_LOGRESTORE]

GO

 

 

CREATE PROCEDURE USP_LOGRESTORE AS           

           

DECLARE @list varchar(128), @restorestr varchar(256), @no int, @err int ,

               @delstr varchar(256)  , @error int     

               

 EXEC DBO.USP_KILLSPIDUSING_TestDB 

   

 DECLARE  cur cursor  for               

 SELECT NO, LIST FROM TB_LOGRESTORELIST WITH (NOLOCK) WHERE RestoreYN <>'Y' AND CopyYN = 'Y'    

 ORDER BY  NO   

 -- logbackuplist에서 RestoreYN'Y'가 아니며, CopyYN = 'Y' 인 것을 가져온다.   

                

 OPEN cur               

 FETCH  NEXT FROM cur  INTO  @no, @list        

                

 WHILE  @@fetch_status =  0    

 BEGIN                  

  UPDATE TB_LOGRESTORELIST SET restoreYN = 'C', start_time=getdate() WHERE no=@no -- 시작 시간을 업데이트  

  SET @restorestr = 'restore log TestDB FROM disk=''\\ADC2\LogBackup_Target\' + @list +''''               

    + ' with standby=''D:\DBData\TestDB_Standby.tdf''' -- Standby옵션으로 TestDB서버에있는 로그를 restore한다.               

                

  EXEC (@restorestr)   

  SET @error  = @@error     

      

  if @error = 0               

   BEGIN         

    UPDATE TB_LOGRESTORELIST   

    SET restoreYN = 'Y', end_time = getdate()  -- 에러가 없으면 restoreY 필드를 'Y'로 채운다.               

    WHERE  no = @no      

            

    --리스토어가 정상적으로 수행 되었으면 해당파일을 삭제.     

    SET @delstr ='master..xp_cmdshell ''del \\ADC2\LogBackup_Target\' + @list + ''''       

    EXEC (@delstr)        

   END   

   

  FETCH  NEXT FROM cur  INTO  @no, @list        

 END   

 CLOSE  cur               

 DEALLOCATE  cur     

GO

 

 

 

 

-------------------------------------------------------------

SQLLeader.com / ADConsulting / 한대성 (olaper@지메일.)

-------------------------------------------------------------