출처 : 블로그
원문 : 그는 무슨생각을 하는가?
SQL Server의 로그 쉬핑(log shipping) 방법
스탠바이 서버(standby server)의 필요성
세상이 완벽하다면 SQL Server를 위한 스탠바이 서버는 필요치 않을 것이다. 하드웨어가 고장 나지도 않을 것이고 NT Server 4.0이나 Windows 2000이 공포의 파란 화면을 띄우지도 않을 것이다. SQL Server는 절대로 멈추지 않으며 애플리케이션도 실행되는데 전혀 방해 받지 않을 것이다.
부분적으로 완벽한 세계에서라면 손상되거나 다운된 SQL Server를 자동적으로 패일오버(failover) 시키는 고가의 클러스터된 SQL Server를 사용함으로써 고민거리를 줄이고 사용자들도 항상 만족시킬 수 있다.
그러나 SQL Server의 패일오버를 구현하기 위한 가장 현실적인 방법은 수동으로 패일오버를 해 주어야 하는 스탠바이 서버를 도입하는 것이다. 물론 스탠바이 서버도 부담이 만만치는 않지만 여기서는 독자들이 스탠바이 서버를 구입할 여력이 있다고 가정하도록 하겠다.
스탠바이 서버의 개념은 새로운 것은 아니다. 이것은 오래 전부터 알려져 있었으며 이미 많은 DBA들이 사용하고 있다. 전통적으로는 스탠바이 서버를 패일오버에 사용한다고 함은 수동으로 운영 환경의 데이터베이스와 트랜잭션 로그를 백업해서 정기적으로 스탠바이 서버에 복사하는 방식으로 진행된다. 이렇게 처리하면 운영중인 서버가 다운되었을 때 사용자들은 대신 스탠바이 서버에 접속함으로써 서비스 단절 시간과 데이터 손실을 최소화 하게 된다.
본 글은 수동으로 처리하던 스탠바이 서버를 이용한 패일오버 과정을 한 단계 개선한 로그 쉬핑(log shipping)에 관한 것이다. 전통적인 방식과 비교해서 로그 쉬핑의 장점은 모든 과정이 자동으로 처리되고 데이터 손실 가능성을 보다 줄여주는 데에 있다.
로그 쉬핑이란 무엇인가?
로그 쉬핑의 본래의 의미는 운영중인 SQL Server의 데이터베이스와 트랜잭션 로그 파일을 백업 받아서 스탠바이 서버로 리스토어(restore) 하는 과정을 자동화 하는 것을 뜻한다. 그러나 이것이 전부라고는 할 수 없다. 로그 쉬핑의 핵심 기능은 하루 종일(지정한 간격으로) 트랜잭션 로그를 백업해서 스탠바이 서버로 자동으로 리스토어 시켜 주는 것이다. 이렇게 하면 두개의 SQL Server는 서로 동기 상태(synchronized)를 유지하게 되며 만약 운용중인 서버가 다운되면 단지 사용자들이 새로운 서버를 사용하도록 하면 된다. 실제로 그렇게 쉬운 일은 아니지만 로그 쉬핑을 설정하는 데 충분한 노력을 기울인다면 어렵지 않게 처리할 수 있다.
로그 쉬핑의 이점
앞에서 로그 쉬핑의 이점에 대해서 몇 가지 언급했지만 좀더 자세하게 살펴보도록 하자.
- 로그 쉬핑은 고가의 하드웨어나 소프트웨어를 필요로 하지 않는다. 스탠바이 서버와 운영중인 서버가 성능이 비슷하면 좋겠지만 꼭 그럴 필요까지는 없다. 게다가 스탠바이 서버에 투입된 자금을 낭비 하지 않기 위해서 다른 용도로 활용할 수도 있다. 이 때는 패일오버를 하게 되면 스탠바이 서버가 하나가 아닌 두 종류의 부하를 처리해야 한다는 점만 기억하면 된다. 필자는 스탠바이 서버를 개발용으로도 사용함으로써 개발자들을 운영 환경으로부터 분리해 놓고 있다. 하지만 스탠바이 서버에 너무 많은 부하를 부과하지는 말기 바란다.
- 로그 쉬핑을 정확하게 구현하였다면 매우 안정적으로 동작한다.
- 수동으로 패일오버를 처리하는 과정은 보통 15분 이내의 짧은 시간이면 가능하다.
- 로그 쉬핑을 설계한 방법에 따라서 다르겠지만 패일오버를 할 경우 데이터의 손실은 전혀 없거나 아니면 매우 적은 분량만 발생한다. 유실된 데이터의 양은 운영 환경의 서버가 다운된 이유에 따라서도 달라지게 된다.
- 로그 쉬핑을 구현하는 것은 기술적으로 어렵지 않다. 수 개월 정도 SQL Server 7 을 다루어본 경험이 있는 DBA라면 대부분 성공적으로 구현할 수 있다.
로그 쉬핑의 문제점
로그 쉬핑은 일종의 타협안임을 인정해야 한다. 이것은 이상적인 해결방법은 아니지만 현실적인 예산의 한계를 감안하면 실용적인 솔루션이라고 할 수 있다.
- 로그 쉬핑을 이용한 패일오버는 자동적으로 처리되지는 않는다. DBA가 직접 서버를 패일오버 시켜야 하며 이는 패일오버를 위해서는 DBA가 자리를 지키고 있어야 함을 뜻한다.
- 사용자들은 어느 정도의 서비스 중단은 감수해야 한다. 서비스 단절이 얼마나 지속될 것인가는 로그 쉬핑을 얼마나 잘 구현해 놓았는지, 운영중인 서버가 왜 다운되었는지와 네트워크, 스탠바이 서버, 패일오버 시켜야 할 애플리케이션 등에 의해서 결정된다.
- 항상 그런 것은 아니지만 데이터의 일부는 유실될 수 있다. 얼마나 많은 데이터 손실이 발생할 것인가는 로그 쉬핑을 얼마나 자주 하도록 설정하였는지와 다운된 운영 환경의 트랜잭션 로그가 복구 가능한지의 여부에 달려 있다.
- 스탬바이 서버로 패일오버 중인 데이터베이스는 어떠한 용도로든 사용될 수 없지만 패일오버에 사용중이 아닌 스탠바이 서버의 데이터베이스는 정상적으로 이용 가능하다.
- 실제로 패일오버가 이루어질 시점이 되면 애플리케이션이 정상적으로 작동하도록 하기 위해서 다음의 두 가지 작업 중 하나를 해야만 한다. 즉, 스탬바이 서버의 이름(IP 어드레스 포함)을 다운된 운영환경의 서버와 동일하게 변경하거나 사용자의 애플리케이션이 새로운 스탠바이 서버를 사용하도록 재지정 해야 한다. 때로는 이들 두 가지 방법 모두가 적절하지 않은 경우도 있다.
로그 쉬핑 개론
로그 쉬핑을 구현하는 방법에 대해서 자세히 분석하기에 앞서 전체적인 관점에서 먼저 살펴보기로 하자. 로그 쉬핑을 구현하기 위해서 해야할 일은 다음과 같다.
- 로그 쉬핑을 위한 하드웨어와 소프트웨어가 제대로 준비되어 있는지 확인한다.
- 운영 환경의 서버와 스탠바이 서버에 있는 SQL Server의 로그인 ID를 일치시킨다.
- 두 개의 백업 디바이스를 만든다. 하나는 데이터베이스 백업을 위한 것이고 다른 하나는 트랜잭션 로그의 백업을 위한 것이다.
- 운영 환경의 서버에서 스탠바이 서버로 Linked Server를 만든다.
- 스탠바이 서버에서 두 개의 스토어드 프로시저를 만든다. 하나는 데이터베이스를 리스토어 하는데 사용되는 것이고 다른 하나는 트랜잭션 로그를 리스토어 할 때 사용된다.
- 운영 환경의 서버에서 데이터베이스와 트랜잭션 로그의 백업을 수행하는데 사용되는 두개의 SQL Server 잡(Job)을 생성한다. 각 잡은 백업을 수행하고, 운영 환경의 서버에서 스탠바이 서버로 파일을 복사하고, 데이터베이스와 트랜잭션 로그 파일을 리스토어 하는 스토어드 프로시저를 실행하는 등의 여러 단계의 스크립트로 이루어져 있다.
- 로그 쉬핑 과정을 실행하여 테스트해 본다.
- 패일오버 과정을 계획하고 테스트한다.
- 로그 쉬핑 과정을 관찰한다.
물론 세부적인 사항에 대해서는 언급하지 않았지만 이제 최소한 어떻게 작업이 진행되는 지는 감을 잡았을 것이다.
설명을 보다 이해하기 편하게 하기 위하여 모든 예는 하나의 데이터베이스만을 패일오버 시키는 것으로 가정한다. 실제 상황에서는 하나 이상의 데이터베이스를 패일오버 시키는 경우가 많겠지만 일단 하나의 데이터베이스에 대하여 로그 쉬핑을 구현해 보면 다른 것들도 어떻게 구현해야 할 지 쉽게 알게 될 것이다. 필자는 기존의 스크립트와 잡에 새로운 데이터베이스에 관한 내용을 추가해서 사용하고 있다. 그러나 패일오버 시키고자 하는 각 데이터베이스에 대해서 스크립트와 잡을 별도로 만들어도 상관 없다.
다음에 소개될 로그 쉬핑을 구현하는 상세한 과정을 읽다 보면 이와는 다른 방법을 생각해 낼 수도 있을 것이다. 로그 쉬핑을 구현하는 방법은 다양하게 존재할 수 있으므로 어떤 것은 필자의 것보다 뛰어날 수도 있을 것이다. 그러므로 여기서 제시하는 방법을 마음껏 개선해 보기 바란다.
하드웨어 및 소프트웨어 요구사항
로그 쉬핑을 위한 하드웨어와 소프트웨어의 요구 조건은 별로 까다롭지 않다. 운영환경의 서버와 스탠바이 서버의 하드웨어 사양은 예산이 허용하는 한 가능한 비슷해야 한다. 운영 환경의 서버가 단지 수십 명 정도의 동시 사용자를 처리하는 정도라면 스탠바이 서버를 운영환경의 서버와 같도록 만들기 위해서 투자를 많이 할 필요가 없다.
반면, 운영 환경의 서버가 500명의 동시 사용자를 처리하고 수 기가 바이트의 데이터베이스를 보유하고 있다면 스탠바이 서버가 운영환경의 서버와 비슷해 질 수 있도록 충분한 자금을 투입해야 할 것이다.
소프트웨어 측면에서는 필자는 두 시스템의 NT Server와 SQL Server가 동일한 서비스 팩(service pack)을 사용하고 있는가 정도만 확인한다. 그리고 두 시스템의 SQL Server 7은 유사하게 설정되어 있어야 한다. 예를 들면, 코드페이지/문자 셋(character set), 정렬 순서, 유니코드 콜레이션(collation), 로케일(locale) 등이 양 서버간에 동일해야 한다.
운영 환경의 서버에서 스탠바이 서버로 패일오버 하는 도중 발생할 수 있는 데이터 손실을 줄이기 위해서는 운영 환경의 서버에서 트랜잭션 로그를 데이터베이스 파일과는 물리적으로 다른 디스크에 위치시켜야 한다. 이렇게 하면 서버의 성능이 향상되는 점도 있지만 가장 큰 이유는 데이터 손실을 줄이자는 데에 있다.
SQL Server 로그인 ID의 동기화
이제부터는 실제로 로그 쉬핑을 설정하는 방법에 대해서 세부적으로 들어가 보기로 하자. 이해하기 어려운 내용이 많으므로 받아들일 준비를 하기 바란다.
로그 쉬핑을 시작하기 전에 준비해야 할 첫번째 단계는 SQL Server 로그인 ID가 운영 환경과 스탠바이 서버간에 동기화 되었는지를 확인하는 것이다. SQL Server는 서버마다 별도로 보안 설정을 관리하는데 하나의 서버에서 데이터베이스를 백업해서 다른 서버로 리스토어 하는 작업을 해야 하기 때문에 이점은 매우 중요하다. 운영 환경 데이터베이스의 USER ID(각 데이터베이스에서)가 스탠바이 서버에서도 작동하려면(데이터베이스가 리스토어 되는 곳) 해당 서버에 일치하는 SQL Server 로그인 ID가 존재해야 하며 그렇지 않으면 사용자들은 스탠바이 서버의 데이터베이스에 접속할 수 없다.
이를 위한 방법에는 여러 가지가 있다.
- 두 서버간에 SQL Server 로그인 ID를 수동으로 동기화 시킨다. 효과적이기는 하지만 다소 지루한 작업이다.
- 운영 환경의 서버에서 로그인 ID를 스크립트로 저장했다가 스탠바이 서버에서 이 스크립트를 실행하여 로그인 ID를 생성한다. 사용자들이 계속적으로 추가되거나 삭제되므로 주기적으로 이 작업을 해주어야 한다. NT 인증(NT Authentication)을 사용하는 SQL Server 로그인 ID는 스크립팅이 잘 되지만 SQL Server 인증을 사용하는 로그인 ID는 그렇지 못하다. SQL Server 인증을 사용하는 로그인 ID를 설정하기 위해서는 사용자의 패스워드를 알고 있거나 아니면 사용자들이 직접 패스워드를 설정하게 하는 방법을 알아내야 하기 때문이다. NT 인증을 사용하는 로그인 ID는 패스워드를 사용하지 않기 때문에 이런 문제가 없다.
- 운영 환경의 서버에서 마스터 데이터베이스를 백업하여 스탠바이 서버로 리스토어 시킨다. 사용자들이 계속 추가 및 삭제되므로 이 작업도 정기적으로 해 주어야 한다. 또는 SQL Server 로그인 ID의 동기화를 유지하기 위해서 마스터 데이터베이스에 대한 로그 쉬핑도 고려해 볼 만 하다.
어떠한 방법을 선택하느냐는 스탠바이 서버가 사용되는 방식에 따라 다를 것이다. 스탠바이 서버가 패일오버 전용으로 사용된다면 마스터 데이터베이스를 로그 쉬핑하도록 설정하는 것이 좋은 솔루션이 된다.
그러나 스탠바이 서버를 개발용 데이터베이스 등의 다른 데이터베이스와 함께 사용한다면 마스터 데이터베이스를 로그 쉬핑 하는 방법은 사용할 수가 없다. 그 대신, 스크립트 방식을 선택하거나 수동으로 동기화를 유지해야 할 것이다. 앞에서도 얘기했듯이, 이렇게 처리하는 경우에는 패스워드 문제가 있는 SQL Server 인증 대신 NT 인증을 사용하는 로그인 ID 만을 이용하는 것이 좋다.
SQL Server 인증을 사용하는 로그인 ID의 또 다른 문제로는 데이터베이스를 다른 SQL Server로 리스토어 할 때 서버의 로그인 ID와 데이터베이스의 사용자 ID를 일치시켜 주어야 한다는 점이다. 이것은 NT 인증을 이용하는 사용자 ID의 경우에는 발생하지 않는 문제다. 로그인 ID와 데이터베이스의 사용자 ID를 동기화 시키기 위해서는 sp_change_users_login 스토어드 프로시저를 이용하면 된다.
로그 쉬핑을 간단하게 처리하고 싶다면 스탠바이 서버를 패일오버 이외의 용도로는 사용하지 말아야 하며 로그인 ID는 항상 NT 인증을 사용해야 한다. 반드시 이럴 필요는 없지만 그렇게 하면 보다 스트레스 없는 생활이 될 것이다.
SQL Server 로그인 ID를 동기화 시키는 방법에 대해서 알았으므로 이제 다음 단계로 넘어가기로 한다.
백업 디바이스 만들기
이것은 비교적 쉬운 과정에 해당된다. 운영 환경의 서버에서 두 개의 백업 디바이스를 만들어야 한다. 하나는 데이터베이스 백업을 위한 것이고 다른 하나는 트랜잭션 로그의 백업을 위한 것이다.
작업을 간단히 하기 위해서 다음과 같이 데이터베이스 백업 디바이스 이름은 데이터베이스 이름을 따라서 붙였다. - “database_name_backup_device”. 그리고 트랜잭션 로그 백업 디바이스의 이름은 “database_name_log_backup_device” 와 같이 명명하였다. 이름이 조금 길긴 하지만 이름만 보아도 금방 용도를 알 수 있다. 여러분은 원하는 방식대로 이름을 지으면 된다.
Linked Server 만들기
이 과정은 이전에 linked server를 사용해보지 않았다면 사람에 따라서 약간 혼란을 겪을 수도 있는 단계이다. Linked server는 다른 기능보다도 한 서버의 스토어드 프로시저를 다른 서버의 스크립트나 스토어드 프로시저에서 실행할 수 있다는 특징이 있다.
이제 해야 할 일은 운영 환경의 서버에서 수행되는 스크립트에서 스탠바이 서버에 있는 스토어드 프로시저를 부를 수 있도록 운영환경의 서버와 스탠바이 서버 간에 linked server를 만드는 것이다.
Linked server를 만드는 이유는 운영환경의 서버에서 스탠바이 서버에 있는 두 개의 프로시저를 실행해야 하기 때문이다. 이 두 개의 프로시저는 데이터베이스와 트랜잭션 로그를 자동으로 리스토어 시키는 데 사용된다(다음 섹션에 자세하게 나와 있음).
Linked server를 만들 때 적절한 보안 등급을 할당하는 것이 중요하다. 아래의 두 화면은 엔터프라이즈 매니저에서 필자가 linked server를 어떻게 만들었는지를 보여준다.
이제 linked server를 만들었으므로 운영 환경의 서버에서 실행하게 될 스탠바이 서버의 스토어드 프로시저를 작성할 준비가 되었다.
데이터를 리스토어 하기 위한 스토어드 프로시저 만들기
다음 단계는 스탠바이 서버에 두 개의 스토어드 프로시저를 만드는 것이다. 하나는 데이터베이스를 자동으로 리스토어 하는 데 사용되고 다른 하나는 트랜잭션 로그를 자동으로 리스토어 하는 데 사용된다.
이들의 이름은 원하는 대로 붙이면 되지만 의미를 확실히 하기 위해서 다음과 같은 이름을 사용하였다.
- restore_database_backups
- restore_log_backups
물론 여러분이 원하는 이름을 사용해도 된다.
이 두개의 프로시저는 절대로 덮어 쓰지 않는 데이터베이스에 만들어야 한다. 마스터 데이터베이스에 대한 로그 쉬핑을 사용하지 않는다면 마스터 데이터베이스에 만들면 된다. 또는 이들 프로시저 만을 위한 별도의 데이터베이스를 생성하여 그곳에 만들어도 된다. 이들을 덮어 쓰지만 않는다면 어떤 방법이든 상관 없다.
데이터베이스 백업을 리스토어 하기 위한 스토어드 프로시저
다음은 “restore_database_backups” 스토어드 프로시저를 만드는 스크립트이다.
CREATE PROCEDURE restore_database_backups AS RESTORE DATABASE database_name FROM DISK = "g:\mssql7\backup\database_name\database_name_backup_device.bak" WITH DBO_ONLY, REPLACE, STANDBY = "g:\mssql7\backup\database_name\undo_database_name.ldf", MOVE "logical_name" TO "h:\mssql7\data\database_name.mdf", MOVE "logical_name" TO "f:\mssql7\log\database_name_log.ldf" WAITFOR DELAY " EXEC sp_dboption "database_name", "single user", true |
여기서 “database_name”은 리스토어되는 데이터베이스의 이름이고 “logical_name”은 각각, 데이터베이스와 로그 파일의 논리적 이름이다.
이제 이 스크립트를 한 줄 씩 살펴보기로 하자.
“CREATE PROCEDURE” 라인은 스토어드 프로시저를 한번이라도 만들어 보았다면 의미를 알 것이다.
“RESTORE DATABASE” 라인은 데이터베이스를 리스토어 하라는 명령이다.
“FROM DISK” 라인은 “RESTORE DATABASE” 명령에게 데이터베이스 백업 디바이스의 위치를 알려준다. 물론 여러분의 서버에 맞도록 백업 디바이스 이름과 패스를 지정해야 한다.
“WITH” 라인은 몇 가지 옵션이 뒤따라 나옴을 의미한다.
“DBO_ONLY” 옵션은 선택사항인데 리스토어된 후에 데이터베이스를 “DBO USE ONLY” 상태로 설정한다. 데이터베이스가 리스토어된 후에 데이터베이스에 대한 불필요한 접근을 막고자 이 옵션을 포함시켰다.
“REPLACE” 옵션은 “RESTORE DATABASE” 명령에게 기존의 데이터베이스 가운데 이름이 동일한 것이 있으면 이것으로 대체해 버릴 것을 지시한다. 이 옵션은 옛날 버전의 데이터베이스가 존재하고 있는 경우에 데이터베이스 리스토어 시에 발생하는 에러를 방지하기 위해서 필요하다.
“STANDBY” 라인은 “RESTORE DATABASE” 명령에게 커밋되지 않은 트랜잭션을 롤백하지 말 것과 데이터베이스에 대한 읽기 전용의 접근을 허용할 것을 지시한다. 이 옵션을 위해서는 트랜잭션을 “undo” 하기 위해서 “undo_database_name.ldf” 와 같은 파일을 지정해야 한다. 이 파일은 여러분의 서버에 따라 적절한 위치에서 찾도록 한다.
“MOVE” 라인은 “RESTORE DATABASE” 명령에게 운영 환경의 서버에 있던 데이터베이스를 구성하는 파일들의 물리적인 위치가 스탠바이 서버에서는 다른 곳에 있음을 알려 준다. 스탠바이 서버의 데이터베이스 파일과 트랜잭션 로그 파일의 물리적인 위치를 지정해야 한다.
“WAITFOR” 라인은 스크립트의 다음 라인이 실행되기 전에 5초간 기다리도록 한다. 다음 명령이 실행되기 전까지 “RESTORE DATABASE” 명령이 100% 완전하게 끝나지 않을 수가 있기 떄문에 포함시켰다. 만약 이전 명령이 완전히 끝나지 않았을 때에는 에러메시지가 발생하게 된다.
“EXEC” 라인은 리스토어 된 데이터베이스를 “SINGLE USER MODE”로 설정하는데 사용된다. 데이터베이스를 리스토어 할 때 마다 “RESTORE DATABASE” 명령은 데이터베이스를 “SINGLE USER MODE”에서 빠져 나오게 한다. 지금 이렇게 설정하지 않으면 이 프로시저를 이용하여 다시 데이터베이스를 리스토어 하는 경우 스토어드 프로시저를 실행할 때 데이터베이스에 사용자가 남아 있다면 에러메시지가 출력 된다. 이런 문제는 잘 발생하지는 않지만 필자는 그런 상황을 직접 경험하였으며 이 라인을 추가함으로써 스토어드 프로시저 실행 시 에러가 발생하는 것을 방지해 준다.
로그 백업을 리스토어 하는 스토어드 프로시저
지금까지 많은 분량을 설명하였지만 앞으로 더 많이 남아 있다. 다음은 restore_log_backups 스토어드 프로시저를 만드는 스크립트로 restore_database_backups 스토어드 프로시저와 유사함을 알 수 있다.
CREATE PROCEDURE restore_log_backups AS RESTORE LOG database_name FROM DISK = "g:\mssql7\backup\log\database_name\database_name_log_backup_device.bak" WITH DBO_ONLY, STANDBY = "g:\mssql7\backup\log\database_name\undo_database_name.ldf" WAITFOR DELAY " EXEC sp_dboption "database_name", "single user", true |
여기서 “database_name”은 리스토어 되는 데이터베이스 이름을 의미한다.
이제 스크립트를 한 줄씩 살펴보기로 하자.
“CREATE PROCEDURE” 라인은 설명이 필요 없을 것이다.
“RESTORE LOG” 라인은 트랜잭션 로그를 리스토어 하라는 명령이다.
“FROM DISK” 라인은 “RESTORE LOG” 명령에게 트랜잭션 로그 백업 디바이스를 어디서 찾을 것인지를 알려 준다. 물론 여러분의 서버에 맞는 적절한 백업 디바이스 이름과 패스를 지정해야 한다.
“WITH” 라인은 몇 가지 옵션이 뒤따라 나옴을 의미한다.
“DBO_ONLY” 옵션은 선택사항인데 트랜잭션이 리스토어된 후에 데이터베이스를 “DBO USE ONLY” 상태로 설정한다. 리스토어 후에 데이터베이스에 대한 불필요한 접근을 막고자 이 옵션을 포함시켰다.
“STANDBY” 라인은 “RESTORE LOG” 명령에게 커밋되지 않은 트랜잭션을 롤백하지 말 것과 데이터베이스에 대한 읽기 전용의 접근을 허용할 것을 지시한다. 이 옵션을 위해서는 트랜잭션을 “undo” 하기 위해서 “undo_database_name.ldf” 와 같은 파일을 지정해야 한다. 이 파일은 여러분의 서버에 따라 적절한 위치에서 찾도록 한다.
“WAITFOR” 라인은 스크립트의 다음 라인이 실행되기 전에 5초간 기다리도록 한다. 다음 명령이 실행되기 전까지 “RESTORE DATABASE” 명령이 100% 완전하게 끝나지 않을 수가 있기 떄문에 이 기능을 포함시켰다. 만약 이전 명령이 완전히 끝나지 않았을 때에는 에러메시지가 발생하게 된다.
“EXEC” 라인은 리스토어된 데이터베이스를 “SINGLE USER MODE”로 설정하는데 사용된다. 트랜잭션 로그를 리스토어 할 때 마다 “RESTORE LOG” 명령은 데이터베이스를 “SINGLE USER MODE”에서 빠져 나오게 한다. 지금 이렇게 설정하지 않으면 이 프로시저를 이용하여 다시 트랜잭션 로그를 리스토어 하는 경우 스토어드 프로시저를 실행할 때 데이터베이스에 사용자가 남아 있다면 에러 메시지가 출력 된다. 이런 문제는 잘 발생하지는 않지만 필자는 그런 상황을 직접 경험하였으며 이 라인을 추가함으로써 스토어드 프로시저 실행 시 에러가 발생하는 것을 방지해 준다.
이제 적어도 이들 두 개의 프로시저에 대한 설명은 충분히 하였다. 다음에는 데이터베이스와 트랜잭션 로그를 백업하는 두개의 SQL Server 잡을 만드는 방법에 대해서 알아보기로 하자.
백업 잡 만들기
데이터베이스와 트랜잭션 로그를 리스토어 하는 방법에 대해서 배웠으므로 이제 그것들을 백업하고 운영환경의 서버에서 스탠바이 서버로 옮기고 필요한 리스토어 작업을 하기 위해서 스탠바이 서버의 스토어드 프로시저를 실행하는 방법에 대해 알아보기로 한다.
이 것은 두 개의 다중 스텝 SQL Server 잡을 이용해서 이루어진다. 짐작하는 바와 같이 하나는 데이터베이스를 백업하는 것이고 다른 하나는 트랜잭션 로그를 백업하는 것이다.
데이터베이스 백업 잡
먼저 운영 환경의 데이터베이스를 백업하고, 스탠바이 서버로 옮긴 다음 데이터베이스를 리스토어 하기 위해서 스탠바이 서버의 스토어드 프로시저를 실행하는 잡에 대해서 살펴보기로 한다. 이것은 다음의 표에 나온 바와 같이 4개의 단계로 구성되어 있다.
단계 ID |
단계 이름 |
단계 종류 |
성공 시 |
실패 시 |
1 |
로그 Truncate |
T-SQL 스크립트 |
다음 단계로 |
다음 단계로 |
2 |
데이터베이스 백업 |
T-SQL 스크립트 |
다음 단계로 |
종료 |
3 |
백업 복사 |
OS 명령 |
다음 단계로 |
종료 |
4 |
데이터베이스 리스토어 |
T-SQL 스크립트 |
종료 |
종료 |
먼저 각각의 단계에 대해서 개괄적으로 살펴본 다음 하나 씩 자세하게 알아보도록 하자.
1단계는 트랜잭션 로그를 Truncate 하는 것이다. 왜 이렇게 해야 할까? 그 이유는 트랜잭션 로그를 백업할 때에는(다음에 나옴) 트랜잭션 로그를 Truncate 하지 않을 계획이기 때문에 여기서 하는 것이다. 만약 여기서 하지 않고 트랜잭션 로그를 백업할 때도 Truncate 하지 않는다면 그 크기가 계속 증가하게 된다.
트랜잭션 로그를 백업할 때 Truncate 하지 않는 이유는 스탠바이 서버의 백업과 운영 환경의 데이터베이스가 모두 다운된 경우에 트랜잭션 로그를 이차적인 백업으로 사용하기 위해서이다. 이 문제에 대해서는 나중에 더 얘기하기로 하겠다.
이 단계에서 잡이 실패하더라도 백업을 계속 해야 할 것이다. 그래서 이 단계가 실패할 경우에도 “다음 단계로” 라고 지정하였다.
2단계는 데이터베이스를 백업 디바이스로 백업하는 것이다. 이 단계에서 실패한다면 “종료” 하게 됨을 주의해야 한다. 실패한 백업을 복사하는 것은 아무런 의미가 없다.
3단계는 XCOPY 명령을 이용해서 백업 디바이스를 운영환경의 서버에서 스탠바이 서버로 복사하는 것이다.
4단계는 스탠바이 서버에서 데이터베이스를 리스토어 하는 스토어드 프로시저를 실행하는 것이다.
이제 전체적인 그림을 살펴보았으므로 각 단계의 이면에 감춰져 있는 스크립트에 대해서 알아보기로 하자.
1단계 스크립트
BACKUP LOG database_name WITH TRUNCATE_ONLY
WAITFOR DELAY "
여기서 database_name은 사용자의 데이터베이스 이름을 뜻한다.
“BACKUP LOG” 라인은 데이터베이스의 트랜잭션 로그를 Truncate 하는 데 사용된다.
“WAITFOR” 라인은 잡의 다음 단계가 실행되기 전에 앞 단계의 과정이 완료될 시간을 벌어주는 데 사용된다.
이 스크립트는 마스터 데이터베이스에서 실행하도록 한다.
2단계 스크립트
BACKUP DATABASE database_name TO database_name_backup_device WITH INIT
WAITFOR DELAY "
여기서 database_name은 사용자의 데이터베이스 이름을 뜻하며 database_name_backup_device는 데이터베이스를 백업하는 데 사용되는 백업 디바이스의 이름이다.
“BACKUP DATABAES”는 지정한 백업 디바이스로 데이터 베이스 전체를 백업한다. “WITH INIT” 옵션은 백업을 하기 전에 백업 디바이스에 남아 있는 이전의 백업 내용을 지우는 데 사용된다.
“WAITFOR” 라인은 잡의 다음 단계가 실행되기 전에 앞 단계의 과정이 완료될 시간을 벌어주는 데 사용된다.
이 스크립트는 마스터 데이터베이스에서 실행하도록 한다.
3단계 스크립트
xcopy g:\mssql7\backup\backup_device_name.bak \\standby_server_name\g$\mssql7\backup\ /c
이 명령이 제대로 실행되려면 이 잡을 실행하는 계정이 운영환경의 서버와 스탠바이 서버 양쪽 모두에 로컬 관리자 권한(local administrative rights)을 가지고 있어야 한다. 물론 파일과 패스 명은 사용자의 시스템에 맞게 변경해야 한다. “g$”는 백업 디바이스가 복사되는 스탠바이 서버의 로컬 관리자 공유를 의미한다. “/c” 옵션은 어떠한 에러가 발생하더라도 복사 작업을 계속할 것을 지시한다.
4단계 스크립트
EXEC standby_server_name.master.dbo.restore_database_backups
이 라인은 스탠바이 서버의 restore_database_backups 스토어드 프로시저를 실행하는 데 사용된다. 스토어드 프로시저의 완전한 객체 명을 사용했음을 주의해야 한다.
이 스크립트는 마스터 데이터베이스에서 실행하도록 한다.
데이터베이스 백업 잡의 스케줄링
잡을 모두 만들었으면 다음은 이 잡을 스케줄링하는 것이다. 이 잡을 오직 하루에 한 번만 실행하도록 스케줄링 하는 것이 중요하다. 그렇지 않으면 다음에 나올 트랜잭션 로그 백업과의 동기화가 깨지게 된다. 사용자들에게 가장 영향을 적게 끼칠 시간대를 선택한다.
트랜잭션 로그 백업
이제 트랜잭션 로그를 백업하고 백업한 것을 스탠바이 서버로 옮긴 다음 트랜잭션 로그를 리스토어 하는 스토어드 프로시저를 실행하는 잡을 알아볼 차례이다. 이것은 다음 표에 나온 것처럼 세 단계로 이루어져 있다.
단계 ID |
단계 이름 |
단계 종류 |
성공 시 |
실패 시 |
1 |
로그 백업 |
T-SQL 스크립트 |
다음 단계로 |
종료 |
2 |
로그 복사 |
OS 명령 |
다음 단계로 |
종료 |
3 |
로그 리스토어 |
T-SQL 스크립트 |
종료 |
종료 |
먼저 각각의 스텝에 대해서 개괄적으로 살펴본 다음 하나씩 자세하게 알아보도록 하자.
1단계는 백업 디바이스로 트랜잭션 로그를 백업하는 것이다. 여기서 실패한다면 “종료”하게 됨을 주의해야 한다. 실패한 백업을 복사하는 것은 아무런 의미가 없다.
2단계는 XCOPY 명령을 이용하여 운영 환경의 서버에서 스탠바이 서버로 백업 디바이스를 복사하는 과정이다.
3단계는 스탠바이 서버에서 트랜잭션 로그를 리스토어 하는 스토어드 프로시저를 실행한다.
이제 전체적인 그림을 살펴보았으므로 각 단계의 이면에 감춰져 있는 스크립트에 대해서 알아보기로 하자.
1단계 스크립트
BACKUP LOG database_name TO log_backup_device WITH INIT, NO_TRUNCATE
WAITFOR DELAY "
여기서 database_name은 사용자의 데이터베이스 이름을 뜻하며 log_backup_device는 트랜잭션 로그를 백업하는 데 사용되는 백업 디바이스의 이름이다.
“BACKUP LOG” 명령은 지정한 백업 디바이스로 데이터베이스의 트랜잭션 로그를 백업한다. “WITH INIT” 옵션은 백업을 하기 전에 백업 디바이스에 남아 있는 이전의 백업 내용을 지우는 데 사용된다. “NO_TRUNCATE” 옵션은 “BACKUP LOG” 명령에게 트랜잭션 로그를 Truncate 하지 말 것을 지시하며 이 값이 디폴트이다. 어떤 이유에서든 나중에 필요 할지도 모르기 때문에 트랜잭션 로그를 백업할 때 마다 매번 Truncate 하지 않도록 한다.
“WAITFOR” 라인은 잡의 다음 단계가 실행되기 전에 앞 단계의 과정이 완료될 시간을 벌어주는데 사용된다.
이 스크립트는 마스터 데이터베이스에서 실행하도록 한다.
2단계 스크립트
xcopy g:\mssql7\backup\backup_device_name.bak \\standby_server_name\g$\mssql7\backup\ /c
이 명령이 제대로 실행되려면 이 잡을 실행하는 계정이 운영 환경의 서버와 스탠바이 서버 양쪽에 모두에 로컬 관리자 권한을 가지고 있어야 한다. 물론 파일과 패스명은 사용자의 시스템에 맞게 변경해야 한다. “g$”는 백업 디바이스가 복사되는 스탠바이 서버의 로컬 관리자 공유를 의미한다. “/c” 옵션은 어떤 에러가 발생하더라도 복사 작업을 계속할 것을 지시한다.
3단계 스크립트
EXEC standby_server_name.master.dbo.restore_log_backups
이 라인은 스탠바이 서버의 restore_log_backups 스토어드 프로시저를 실행하는 데 사용된다. 스토어드 프로시저의 완전한 객체 명을 사용했음을 주의해야 한다.
이 스크립트는 마스터 데이터베이스에서 실행하도록 한다.
로그 백업 잡의 스케줄링
잡을 모두 만들었으면 다음 단계는 이 잡을 스케줄링하는 것이다. 로그 백업 잡을 스케줄링 하는 것은 데이터베이스 백업 잡을 스케줄링 하는 것에 비해서 좀 더 복잡하다. 여러분이 결정해야 할 것이 두 가지가 있다. 하나는 트랜잭션 로그의 백업을 얼마나 자주 할 것인가 이다. 일반적으로 백업을 자주 할수록 손실될 수 있는 데이터가 적어지므로 더 좋다고 할 수 있다. 참고로 필자는 15분마다 트랜잭션 로그를 백업하고 있다. 다르게 표현하면 15분마다 로그 쉬핑을 하고 있다고 말할 수 있다.
스케줄링에 관한 두 번째 측면은 스케줄된 트랜잭션 로그의 백업이 데이터베이스 백업을 방해해서는 안된다는 것이다. 만약 이들 간의 동기화가 깨어진다면 트랜잭션 로그를 리스토어 하는 작업은 실패하게 될 것이고 스탠바이 서버에 현재의 데이터베이스에 대한 백업을 가지지 못하게 된다. 필자는 발생할지도 모르는 충돌을 방지하기 위해서 데이터베이스 백업이 시작되기 15분전에 트랜잭션 로그의 백업 잡을 정지시키고 데이터베이스 백업이 끝난 다음 15분 후에 다시 시작하도록 스케줄링 하고 있다. 이렇게 하면 충돌 문제는 발생하지 않을 것이다.
테스트, 테스트, 다시 테스트
이제 거의 다 끝났다. 모든 과정이 다 준비되었으므로 마지막 단계는 잡과 스토어드 프로시저가 제대로 동작하는지 확인하기 위해서 몇 일에 걸쳐서 모든 것을 테스트 하는 것이다. 모든 잡은 각자 성공과 실패의 과정이 기록되므로 잡과 관련된 문제를 디버그 하는 것은 별로 어렵지 않다.
운영 환경의 서버에 로그 쉬핑을 설정하기 전에 가능하다면 운영환경이 아닌 다른 두 개의 SQL Server 상에서 먼저 설정하고 테스트 해 볼 것을 권한다. 이렇게 하면 학습 과정의 오류로 인해서 운영 환경의 서버를 다운 시킬 수도 있는 실수를 방지할 수 있다.
성공적인 로그 쉬핑 솔루션이 테이프 백업을 불필요하게 만든다고는 생각하지 말기 바란다. 여기서 언급한 것 외에도 필자는 매일 모든 데이터베이스와 트랜잭션 로그 디스크를 테이프에 백업 받고 있다. 너무 많이 백업을 받는다는 말은 있을 수 없다.
모든 것을 관찰
로그 쉬핑 과정을 설치하였다면 그것이 성공적으로 수행되는지 반드시 확인해야 한다. Job Notification을 설정하여 두 개의 로그 쉬핑 잡이 실패하였을 때 전자메일이나 페이저로 연락을 받을 수 있도록 한다.
스탠바이 서버로 패일오버 시키는 방법
로그 쉬핑이 성공적으로 구현되었으면 실제로 스탠바이 서버로 패일오버 시키는 스크립트를 만들고 모든 것이 성공적으로 진행되는 지를 테스트 해 보고 싶을 것이다.
여러분의 환경을 구체적으로 알지는 못하므로 운영 환경의 서버를 스탠바이 서버로 패일오버 시키는 정확한 과정을 알려줄 수는 없지만 고려해야 할 가장 일반적인 몇 가지 사항은 제시할 수 있다.
- 운영 환경의 서버에서 트랜잭션 로그를 복구할 수 있는가? 만약 복구할 수 있다면 그것을 백업하기 위해서 다음과 같은 스크립트를 실행하면 된다.
BACKUP LOG database_name TO database_name_log_backup_device WITH INIT, NO_TRUNCATE |
- 운영 환경의 서버에서 트랜잭션 로그를 복구하였다면, 다음과 같은 스크립트를 이용해서 스탠바이 서버로 리스토어 한다.
RESTORE LOG database_name FROM DISK = "d:\sql7\log\database_name_log_backup_device.bak" WITH DBO_ONLY, STANDBY = "d:\sql7\undo_database_name_log.ldf" |
- 운영 환경의 서버에서 트랜잭션 로그를 복구할 수 있었는지와는 무관하게 스탠바이 서버를 복구하여 운영 환경의 서버를 대치할 수 있도록 하기 위해서 아래와 같은 스크립트를 실행할 필요가 있다.
RESTORE DATABASE database_name WITH RECOVERY EXEC SP_DBOPTION "database_name", "read only", "false" EXEC SP_DBOPTION "database_name", "dbo use only", "false" |
- 스탠바이 서버로 패일오버가 되었다면, 다음은 사용자들이 새로운 서버를 사용하도록 하는 것이다. 어떻게 하느냐는 사용자들에게 달려 있다. 최후의 수단으로 스탠바이 서버의 이름을 운영 환경의 서버와 동일하게 변경하고 IP 어드레스도 바꾸는 방법이 있지만 이는 종종 자체적인 문제점을 일으키곤 한다. 사용자들이 스탠바이 서버를 사용하도록 하는 가장 좋은 방법은 테스트를 통해서 찾아내야 할 것이다. SQL Server의 이름을 변경하는 방법에 대한 자세한 자료는 다음의 주소에 나와있는 마이크로소프트의 FAQ를 참조하기 바란다.
http://msdn.microsoft.com/library/psdk/sql/faq.htm
- 미리 준비할 필요가 있는 패일오버 과정의 또 다른 요소는 운영 환경의 서버가 다시 가동된 후에 스탠바이 서버로부터 어떻게 다시 돌아올 것이가 하는 점이다.
이상과 같이 로그 쉬핑을 설정하려면 상당히 복잡한 과정을 거쳐야 한다. 만약 시도해 보고자 한다면 가능한 충분한 시간을 갖고 구현해 보고 테스트해 보기 바란다. 그러나 일단 작동하기만 하면, 운영 환경의 서버가 다운되었을 때 시간을 크게 절약할 수 있음을 알게 될 것이다.