기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
서버에서 SQL 지속적인 복제를 위한 데이터 변경 캡처
이 항목에서는 SQL 서버 소스에서 CDC 복제를 설정하는 방법에 대해 설명합니다.
온프레미스 또는 Amazon의 자체 관리형 SQL 서버의 데이터 변경 캡처 EC2
원본 Microsoft SQL Server 데이터베이스에서 변경 내용을 캡처하려면 데이터베이스가 전체 백업을 수행하도록 구성되어 있어야 합니다. 데이터베이스를 전체 복구 모드 또는 대량 로그 모드로 구성합니다.
자체 관리형 SQL 서버 원본의 경우 다음을 AWS DMS 사용합니다.
- MS-REPLICATION
-
프라이머리 키가 있는 테이블의 변경 사항을 캡처합니다. 소스 SQL 서버 인스턴스의 AWS DMS 엔드포인트 사용자에게 sysadmin 권한을 제공하여 이를 자동으로 구성할 수 있습니다. 또는 이 섹션의 단계에 따라 원본을 준비하고 엔드포인트에 대한 sysadmin 권한이 없는 사용자를 사용할 수 있습니다. AWS DMS
- MS- CDC
-
프라이머리 키가 없는 테이블의 변경 사항을 캡처합니다. 데이터베이스 수준에서 모든 테이블에 대해 개별적으로 CDC MS-를 활성화합니다.
지속적인 복제 (CDC) 를 위해 SQL 서버 데이터베이스를 설정하는 경우 다음 중 하나를 수행할 수 있습니다.
-
sysadmin 역할을 사용하여 지속적 복제를 설정합니다.
-
sysadmin 역할을 사용하지 않도록 지속적 복제를 설정합니다.
자체 관리 SQL 서버에서 지속적 복제 설정
이 섹션에는 sysadmin 역할을 사용하거나 사용하지 않고 자체 관리 SQL 서버에서 진행 중인 복제를 설정하는 방법에 대한 정보가 포함되어 있습니다.
주제
자체 관리 SQL 서버에서 지속적인 복제 설정: sysadmin 역할 사용
AWS DMS SQL서버의 지속적 복제는 기본 키가 있는 테이블의 경우 기본 SQL 서버 복제를 사용하고 기본 키가 없는 테이블의 경우 변경 데이터 캡처 (CDC) 를 사용합니다.
지속적 복제를 설정하기 전에 서버 소스의 지속적 복제 (CDC) 를 사용하기 위한 사전 요구 사항 SQL 섹션을 참조하세요.
기본 키가 있는 테이블의 경우 일반적으로 소스에 필요한 아티팩트를 구성할 AWS DMS 수 있습니다. 하지만 자체 관리되는 SQL 서버 원본 인스턴스의 경우 먼저 SQL 서버 배포를 수동으로 구성해야 합니다. 이렇게 하면 sysadmin 권한이 있는 AWS DMS 원본 사용자가 기본 키를 사용하여 테이블에 대한 게시를 자동으로 만들 수 있습니다.
배포가 이미 구성되어 있는지 확인하려면 다음 명령을 실행합니다.
sp_get_distributor
열 배포 결과가 NULL
인 경우 배포가 구성되지 않은 것입니다. 다음 절차에 따라 배포를 설정할 수 있습니다.
배포를 설정하려면
-
SQL서버 관리 스튜디오 (SSMS) 도구를 사용하여 SQL 서버 원본 데이터베이스에 연결합니다.
-
복제 폴더의 컨텍스트 메뉴(마우스 오른쪽 버튼 클릭)를 열고 배포 구성을 선택합니다. 배포 구성 마법사가 나타납니다.
-
마법사에 따라 기본값을 입력하고 배포를 생성합니다.
CDC 설정
AWS DMS 버전 3.4.7 이상에서는 읽기 전용 복제본을 사용하지 않는 경우 데이터베이스 및 모든 테이블에 CDC 대해 MS를 자동으로 설정할 수 있습니다. 이 기능을 사용하려면 를 true로 설정하십시오. SetUpMsCdcForTables
ECA 에 대한 자세한 내용은 ECAs 을 참조하십시오엔드포인트 설정.
3.4.7 AWS DMS 이전 버전이거나 읽기 전용 복제본을 원본으로 사용하는 경우 다음 단계를 수행하십시오.
기본 키가 없는 테이블의 경우 데이터베이스에 CDC MS-를 설정하십시오. 이렇게 하려면 sysadmin 역할이 할당된 계정을 사용하고 다음 명령을 실행합니다.
use [DBname] EXEC sys.sp_cdc_enable_db
다음으로, 각 소스 테이블에 CDC 대해 MS-를 설정합니다. 고유 키는 있지만 기본 키는 없는 각 테이블에 대해 다음 쿼리를 실행하여 MS-를 설정합니다CDC.
exec sys.sp_cdc_enable_table @source_schema = N'schema_name', @source_name = N'table_name', @index_name = N'unique_index_name', @role_name = NULL, @supports_net_changes = 1 GO
-
기본 키가 없거나 고유 키가 없는 각 테이블에 대해 다음 쿼리를 실행하여 MS-를 설정합니다CDC.
exec sys.sp_cdc_enable_table @source_schema = N'schema_name', @source_name = N'table_name', @role_name = NULL GO
특정 테이블의 MS-를 설정하는 방법에 CDC 대한 자세한 내용은 SQL서버 설명서를
독립형 SQL 서버에서 지속적인 복제 설정: sysadmin 역할 없음
이 섹션에서는 사용자 계정에 sysadmin 권한이 필요하지 않은 독립 실행형 SQL 서버 데이터베이스 원본에 대해 지속적인 복제를 설정하는 방법을 설명합니다.
참고
이 섹션의 단계를 실행한 후에는 sysadmin이 아닌 DMS 사용자에게 다음 작업을 수행할 수 있는 권한이 부여됩니다.
온라인 트랜잭션 로그 파일에서 변경 사항 읽기
트랜잭션 로그 백업 파일의 변경 사항을 읽을 수 있는 디스크 액세스
다음을 사용하는 발행물을 추가하거나 변경하십시오. DMS
게시물에 문서 추가
에 설명된 대로 Microsoft SQL Server를 복제용으로 설정합니다서버에서 SQL 지속적인 복제를 위한 데이터 변경 캡처.
원본 데이터베이스에서 REPLICATION MS-를 활성화합니다. 이 작업은 수동으로 수행하거나, sysadmin 사용자로 태스크를 한 번 실행하여 수행할 수 있습니다.
아래의 스크립트를 사용하여 소스 데이터베이스에서
awsdms
스키마를 생성합니다.use master go create schema awsdms go -- Create the table valued function [awsdms].[split_partition_list] on the Master database, as follows: USE [master] GO set ansi_nulls on go set quoted_identifier on go if (object_id('[awsdms].[split_partition_list]','TF')) is not null drop function [awsdms].[split_partition_list]; go create function [awsdms].[split_partition_list] ( @plist varchar(8000), —A delimited list of partitions @dlm nvarchar(1) —Delimiting character ) returns @partitionsTable table —Table holding the BIGINT values of the string fragments ( pid bigint primary key ) as begin declare @partition_id bigint; declare @dlm_pos integer; declare @dlm_len integer; set @dlm_len = len(@dlm); while (charindex(@dlm,@plist)>0) begin set @dlm_pos = charindex(@dlm,@plist); set @partition_id = cast( ltrim(rtrim(substring(@plist,1,@dlm_pos-1))) as bigint); insert into @partitionsTable (pid) values (@partition_id) set @plist = substring(@plist,@dlm_pos+@dlm_len,len(@plist)); end set @partition_id = cast (ltrim(rtrim(@plist)) as bigint); insert into @partitionsTable (pid) values ( @partition_id ); return end GO
아래의 스크립트를 사용하여 마스터 데이터베이스에서
[awsdms].[rtm_dump_dblog]
프로시저를 생성합니다.use [MASTER] go if (object_id('[awsdms].[rtm_dump_dblog]','P')) is not null drop procedure [awsdms].[rtm_dump_dblog]; go set ansi_nulls on go set quoted_identifier on GO CREATE procedure [awsdms].[rtm_dump_dblog] ( @start_lsn varchar(32), @seqno integer, @filename varchar(260), @partition_list varchar(8000), — A comma delimited list: P1,P2,... Pn @programmed_filtering integer, @minPartition bigint, @maxPartition bigint ) as begin declare @start_lsn_cmp varchar(32); — Stands against the GT comparator SET NOCOUNT ON — – Disable "rows affected display" set @start_lsn_cmp = @start_lsn; if (@start_lsn_cmp) is null set @start_lsn_cmp = '00000000:00000000:0000'; if (@partition_list is null) begin RAISERROR ('Null partition list waspassed',16,1); return end if (@start_lsn) is not null set @start_lsn = '0x'+@start_lsn; if (@programmed_filtering=0) SELECT [Current LSN], [operation], [Context], [Transaction ID], [Transaction Name], [Begin Time], [End Time], [Flag Bits], [PartitionID], [Page ID], [Slot ID], [RowLog Contents 0], [Log Record], [RowLog Contents 1] FROM fn_dump_dblog ( @start_lsn, NULL, N'DISK', @seqno, @filename, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default) where [Current LSN] collate SQL_Latin1_General_CP1_CI_AS > @start_lsn_cmp collate SQL_Latin1_General_CP1_CI_AS and ( ( [operation] in ('LOP_BEGIN_XACT','LOP_COMMIT_XACT','LOP_ABORT_XACT') ) or ( [operation] in ('LOP_INSERT_ROWS','LOP_DELETE_ROWS','LOP_MODIFY_ROW') and ( ( [context] in ('LCX_HEAP','LCX_CLUSTERED','LCX_MARK_AS_GHOST') ) or ([context] = 'LCX_TEXT_MIX' and (datalength([RowLog Contents 0]) in (0,1)))) and [PartitionID] in ( select * from master.awsdms.split_partition_list (@partition_list,',')) ) or ([operation] = 'LOP_HOBT_DDL') ) else SELECT [Current LSN], [operation], [Context], [Transaction ID], [Transaction Name], [Begin Time], [End Time], [Flag Bits], [PartitionID], [Page ID], [Slot ID], [RowLog Contents 0], [Log Record], [RowLog Contents 1] — After Image FROM fn_dump_dblog ( @start_lsn, NULL, N'DISK', @seqno, @filename, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default) where [Current LSN] collate SQL_Latin1_General_CP1_CI_AS > @start_lsn_cmp collate SQL_Latin1_General_CP1_CI_AS and ( ( [operation] in ('LOP_BEGIN_XACT','LOP_COMMIT_XACT','LOP_ABORT_XACT') ) or ( [operation] in ('LOP_INSERT_ROWS','LOP_DELETE_ROWS','LOP_MODIFY_ROW') and ( ( [context] in ('LCX_HEAP','LCX_CLUSTERED','LCX_MARK_AS_GHOST') ) or ([context] = 'LCX_TEXT_MIX' and (datalength([RowLog Contents 0]) in (0,1)))) and ([PartitionID] is not null) and ([PartitionID] >= @minPartition and [PartitionID]<=@maxPartition) ) or ([operation] = 'LOP_HOBT_DDL') ) SET NOCOUNT OFF — Re-enable "rows affected display" end GO
아래의 스크립트를 사용하여 마스터 데이터베이스에서 인증서를 생성합니다.
Use [master] Go CREATE CERTIFICATE [awsdms_rtm_dump_dblog_cert] ENCRYPTION BY PASSWORD = N'@5trongpassword' WITH SUBJECT = N'Certificate for FN_DUMP_DBLOG Permissions';
아래의 스크립트를 사용하여 인증서에서 로그인을 생성합니다.
Use [master] Go CREATE LOGIN awsdms_rtm_dump_dblog_login FROM CERTIFICATE [awsdms_rtm_dump_dblog_cert];
아래의 스크립트를 사용하여 sysadmin 서버 역할에 로그인을 추가합니다.
ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_dump_dblog_login];
아래의 스크립트를 사용하여 [master].[awsdms].[rtm_dump_dblog]에 서명을 추가합니다.
Use [master] GO ADD SIGNATURE TO [master].[awsdms].[rtm_dump_dblog] BY CERTIFICATE [awsdms_rtm_dump_dblog_cert] WITH PASSWORD = '@5trongpassword';
참고
저장된 프로시저를 다시 생성할 경우 서명을 다시 추가해야 합니다.
아래의 스크립트를 사용하여 마스터 데이터베이스에 [awsdms].[rtm_position_1st_timestamp]를 생성합니다.
use [master] if object_id('[awsdms].[rtm_position_1st_timestamp]','P') is not null DROP PROCEDURE [awsdms].[rtm_position_1st_timestamp]; go create procedure [awsdms].[rtm_position_1st_timestamp] ( @dbname sysname, -- Database name @seqno integer, -- Backup set sequence/position number within file @filename varchar(260), -- The backup filename @1stTimeStamp varchar(40) -- The timestamp to position by ) as begin SET NOCOUNT ON -- Disable "rows affected display" declare @firstMatching table ( cLsn varchar(32), bTim datetime ) declare @sql nvarchar(4000) declare @nl char(2) declare @tb char(2) declare @fnameVar nvarchar(254) = 'NULL' set @nl = char(10); -- New line set @tb = char(9) -- Tab separator if (@filename is not null) set @fnameVar = ''''+@filename +'''' set @sql='use ['+@dbname+'];'+@nl+ 'select top 1 [Current LSN],[Begin Time]'+@nl+ 'FROM fn_dump_dblog (NULL, NULL, NULL, '+ cast(@seqno as varchar(10))+','+ @fnameVar+','+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default)'+@nl+ 'where operation=''LOP_BEGIN_XACT''' +@nl+ 'and [Begin Time]>= cast('+''''+@1stTimeStamp+''''+' as datetime)'+@nl --print @sql delete from @firstMatching insert into @firstMatching exec sp_executesql @sql -- Get them all select top 1 cLsn as [matching LSN],convert(varchar,bTim,121) as [matching Timestamp] from @firstMatching; SET NOCOUNT OFF -- Re-enable "rows affected display" end GO
아래의 스크립트를 사용하여 마스터 데이터베이스에서 인증서를 생성합니다.
Use [master] Go CREATE CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert] ENCRYPTION BY PASSWORD = '@5trongpassword' WITH SUBJECT = N'Certificate for FN_POSITION_1st_TIMESTAMP Permissions';
아래의 스크립트를 사용하여 인증서에서 로그인을 생성합니다.
Use [master] Go CREATE LOGIN awsdms_rtm_position_1st_timestamp_login FROM CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert];
아래의 스크립트를 사용하여 sysadmin 역할에 로그인을 추가합니다.
ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_position_1st_timestamp_login];
아래의 스크립트를 사용하여 인증서를 통해 [master].[awsdms].[rtm_position_1st_timestamp]에 서명을 추가합니다.
Use [master] GO ADD SIGNATURE TO [master].[awsdms].[rtm_position_1st_timestamp] BY CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert] WITH PASSWORD = '@5trongpassword';
다음 스크립트를 사용하여 DMS 사용자에게 새 저장 프로시저에 대한 실행 액세스 권한을 부여합니다.
use master go GRANT execute on [awsdms].[rtm_position_1st_timestamp] to dms_user;
다음 각 데이터베이스에서 다음과 같은 권한 및 역할을 보유한 사용자를 생성합니다.
참고
각 복제본에서 동일한 dmsnosysadmin 사용자 계정을 생성해야 합니다. SID 다음 SQL 쿼리는 각 복제본의 dmsnosysadmin 계정 값을 확인하는 데 도움이 될 수 있습니다. SID 사용자 생성에 대한 자세한 내용은 Microsoft SQL 서버 설명서의 CREATE USER
(트랜잭션-SQL) 을 참조하십시오. Azure SQL 데이터베이스의 SQL 사용자 계정을 만드는 방법에 대한 자세한 내용은 활성 지역 복제를 참조하십시오. use master go grant select on sys.fn_dblog to [DMS_user] grant view any definition to [DMS_user] grant view server state to [DMS_user]—(should be granted to the login). grant execute on sp_repldone to [DMS_user] grant execute on sp_replincrementlsn to [DMS_user] grant execute on sp_addpublication to [DMS_user] grant execute on sp_addarticle to [DMS_user] grant execute on sp_articlefilter to [DMS_user] grant select on [awsdms].[split_partition_list] to [DMS_user] grant execute on [awsdms].[rtm_dump_dblog] to [DMS_user]
use MSDB go grant select on msdb.dbo.backupset to [DMS_user] grant select on msdb.dbo.backupmediafamily to [DMS_user] grant select on msdb.dbo.backupfile to [DMS_user]
소스 데이터베이스에서 다음과 같은 스크립트를 실행합니다.
EXEC sp_addrolemember N'db_owner', N'DMS_user' use Source_DB go
마지막으로 소스 서버 엔드포인트에 추가 연결 속성 (ECA) 을 추가합니다. SQL
enableNonSysadminWrapper=true;
가용성 그룹 환경의 SQL 서버에 지속적인 복제 설정: sysadmin 역할 없음
이 섹션에서는 사용자 계정에 sysadmin 권한이 필요하지 않은 가용성 그룹 환경에서 SQL 서버 데이터베이스 원본에 대한 지속적인 복제를 설정하는 방법을 설명합니다.
참고
이 섹션의 단계를 실행한 후에는 sysadmin이 아닌 DMS 사용자에게 다음 작업을 수행할 수 있는 권한이 부여됩니다.
온라인 트랜잭션 로그 파일에서 변경 사항 읽기
트랜잭션 로그 백업 파일의 변경 사항을 읽을 수 있는 디스크 액세스
다음을 사용하는 발행물을 추가하거나 변경하십시오. DMS
게시물에 문서 추가
가용성 그룹 환경에서 sysadmin 사용자를 사용하지 않고 지속적 복제를 설정하려면
에 설명된 대로 Microsoft SQL Server를 복제용으로 설정합니다서버에서 SQL 지속적인 복제를 위한 데이터 변경 캡처.
원본 데이터베이스에서 REPLICATION MS-를 활성화합니다. 이 작업은 수동으로 수행하거나, sysadmin 사용자를 통해 태스크를 한 번 실행하여 수행할 수 있습니다.
참고
MS- REPLICATION 배포자를 로컬로 구성하거나 연결된 서버를 통해 sysadmin이 아닌 사용자가 액세스할 수 있는 방식으로 구성해야 합니다.
단일 작업 엔드포인트 내에서 sp_repldone 단독 사용 옵션이 활성화된 경우 MS- Log Reader 작업을 중지하십시오. REPLICATION
각각의 복제에서 다음 단계를 수행합니다.
마스터 데이터베이스에서
[awsdms]
[awsdms] 스키마를 생성합니다.CREATE SCHEMA [awsdms]
마스터 데이터베이스에서
[awsdms].[split_partition_list]
테이블 값 함수를 생성합니다.USE [master] GO SET ansi_nulls on GO SET quoted_identifier on GO IF (object_id('[awsdms].[split_partition_list]','TF')) is not null DROP FUNCTION [awsdms].[split_partition_list]; GO CREATE FUNCTION [awsdms].[split_partition_list] ( @plist varchar(8000), --A delimited list of partitions @dlm nvarchar(1) --Delimiting character ) RETURNS @partitionsTable table --Table holding the BIGINT values of the string fragments ( pid bigint primary key ) AS BEGIN DECLARE @partition_id bigint; DECLARE @dlm_pos integer; DECLARE @dlm_len integer; SET @dlm_len = len(@dlm); WHILE (charindex(@dlm,@plist)>0) BEGIN SET @dlm_pos = charindex(@dlm,@plist); SET @partition_id = cast( ltrim(rtrim(substring(@plist,1,@dlm_pos-1))) as bigint); INSERT into @partitionsTable (pid) values (@partition_id) SET @plist = substring(@plist,@dlm_pos+@dlm_len,len(@plist)); END SET @partition_id = cast (ltrim(rtrim(@plist)) as bigint); INSERT into @partitionsTable (pid) values ( @partition_id ); RETURN END GO
마스터 데이터베이스에서
[awsdms].[rtm_dump_dblog]
프로시저를 생성합니다.USE [MASTER] GO IF (object_id('[awsdms].[rtm_dump_dblog]','P')) is not null DROP PROCEDURE [awsdms].[rtm_dump_dblog]; GO SET ansi_nulls on GO SET quoted_identifier on GO CREATE PROCEDURE [awsdms].[rtm_dump_dblog] ( @start_lsn varchar(32), @seqno integer, @filename varchar(260), @partition_list varchar(8000), -- A comma delimited list: P1,P2,... Pn @programmed_filtering integer, @minPartition bigint, @maxPartition bigint ) AS BEGIN DECLARE @start_lsn_cmp varchar(32); -- Stands against the GT comparator SET NOCOUNT ON -- Disable "rows affected display" SET @start_lsn_cmp = @start_lsn; IF (@start_lsn_cmp) is null SET @start_lsn_cmp = '00000000:00000000:0000'; IF (@partition_list is null) BEGIN RAISERROR ('Null partition list was passed',16,1); return --set @partition_list = '0,'; -- A dummy which is never matched END IF (@start_lsn) is not null SET @start_lsn = '0x'+@start_lsn; IF (@programmed_filtering=0) SELECT [Current LSN], [operation], [Context], [Transaction ID], [Transaction Name], [Begin Time], [End Time], [Flag Bits], [PartitionID], [Page ID], [Slot ID], [RowLog Contents 0], [Log Record], [RowLog Contents 1] -- After Image FROM fn_dump_dblog ( @start_lsn, NULL, N'DISK', @seqno, @filename, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default) WHERE [Current LSN] collate SQL_Latin1_General_CP1_CI_AS > @start_lsn_cmp collate SQL_Latin1_General_CP1_CI_AS -- This aims for implementing FN_DBLOG based on GT comparator. AND ( ( [operation] in ('LOP_BEGIN_XACT','LOP_COMMIT_XACT','LOP_ABORT_XACT') ) OR ( [operation] in ('LOP_INSERT_ROWS','LOP_DELETE_ROWS','LOP_MODIFY_ROW') AND ( ( [context] in ('LCX_HEAP','LCX_CLUSTERED','LCX_MARK_AS_GHOST') ) or ([context] = 'LCX_TEXT_MIX') ) AND [PartitionID] in ( select * from master.awsdms.split_partition_list (@partition_list,',')) ) OR ([operation] = 'LOP_HOBT_DDL') ) ELSE SELECT [Current LSN], [operation], [Context], [Transaction ID], [Transaction Name], [Begin Time], [End Time], [Flag Bits], [PartitionID], [Page ID], [Slot ID], [RowLog Contents 0], [Log Record], [RowLog Contents 1] -- After Image FROM fn_dump_dblog ( @start_lsn, NULL, N'DISK', @seqno, @filename, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default, default) WHERE [Current LSN] collate SQL_Latin1_General_CP1_CI_AS > @start_lsn_cmp collate SQL_Latin1_General_CP1_CI_AS -- This aims for implementing FN_DBLOG based on GT comparator. AND ( ( [operation] in ('LOP_BEGIN_XACT','LOP_COMMIT_XACT','LOP_ABORT_XACT') ) OR ( [operation] in ('LOP_INSERT_ROWS','LOP_DELETE_ROWS','LOP_MODIFY_ROW') AND ( ( [context] in ('LCX_HEAP','LCX_CLUSTERED','LCX_MARK_AS_GHOST') ) or ([context] = 'LCX_TEXT_MIX') ) AND ([PartitionID] is not null) and ([PartitionID] >= @minPartition and [PartitionID]<=@maxPartition) ) OR ([operation] = 'LOP_HOBT_DDL') ) SET NOCOUNT OFF -- Re-enable "rows affected display" END GO
마스터 데이터베이스에서 인증서를 생성합니다.
USE [master] GO CREATE CERTIFICATE [awsdms_rtm_dump_dblog_cert] ENCRYPTION BY PASSWORD = N'@hardpassword1' WITH SUBJECT = N'Certificate for FN_DUMP_DBLOG Permissions'
인증서에서 로그인을 생성합니다.
USE [master] GO CREATE LOGIN awsdms_rtm_dump_dblog_login FROM CERTIFICATE [awsdms_rtm_dump_dblog_cert];
sysadmin 서버 역할에 로그인을 추가합니다.
ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_dump_dblog_login];
-
인증서를 사용하여 [master].[awsdms].[rtm_dump_dblog] 프로시저에 서명을 추가합니다.
USE [master] GO ADD SIGNATURE TO [master].[awsdms].[rtm_dump_dblog] BY CERTIFICATE [awsdms_rtm_dump_dblog_cert] WITH PASSWORD = '@hardpassword1';
참고
저장된 프로시저를 다시 생성할 경우 서명을 다시 추가해야 합니다.
마스터 데이터베이스에서
[awsdms].[rtm_position_1st_timestamp]
프로시저를 생성합니다.USE [master] IF object_id('[awsdms].[rtm_position_1st_timestamp]','P') is not null DROP PROCEDURE [awsdms].[rtm_position_1st_timestamp]; GO CREATE PROCEDURE [awsdms].[rtm_position_1st_timestamp] ( @dbname sysname, -- Database name @seqno integer, -- Backup set sequence/position number within file @filename varchar(260), -- The backup filename @1stTimeStamp varchar(40) -- The timestamp to position by ) AS BEGIN SET NOCOUNT ON -- Disable "rows affected display" DECLARE @firstMatching table ( cLsn varchar(32), bTim datetime ) DECLARE @sql nvarchar(4000) DECLARE @nl char(2) DECLARE @tb char(2) DECLARE @fnameVar sysname = 'NULL' SET @nl = char(10); -- New line SET @tb = char(9) -- Tab separator IF (@filename is not null) SET @fnameVar = ''''+@filename +'''' SET @filename = ''''+@filename +'''' SET @sql='use ['+@dbname+'];'+@nl+ 'SELECT TOP 1 [Current LSN],[Begin Time]'+@nl+ 'FROM fn_dump_dblog (NULL, NULL, NULL, '+ cast(@seqno as varchar(10))+','+ @filename +','+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default,'+@nl+ @tb+'default, default, default, default, default, default, default)'+@nl+ 'WHERE operation=''LOP_BEGIN_XACT''' +@nl+ 'AND [Begin Time]>= cast('+''''+@1stTimeStamp+''''+' as datetime)'+@nl --print @sql DELETE FROM @firstMatching INSERT INTO @firstMatching exec sp_executesql @sql -- Get them all SELECT TOP 1 cLsn as [matching LSN],convert(varchar,bTim,121) AS[matching Timestamp] FROM @firstMatching; SET NOCOUNT OFF -- Re-enable "rows affected display" END GO
마스터 데이터베이스에서 인증서를 생성합니다.
USE [master] GO CREATE CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert] ENCRYPTION BY PASSWORD = N'@hardpassword1' WITH SUBJECT = N'Certificate for FN_POSITION_1st_TIMESTAMP Permissions';
인증서에서 로그인을 생성합니다.
USE [master] GO CREATE LOGIN awsdms_rtm_position_1st_timestamp_login FROM CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert];
sysadmin 서버 역할에 로그인을 추가합니다.
ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_position_1st_timestamp_login];
인증서를 사용하여
[master].[awsdms].[rtm_position_1st_timestamp]
프로시저에 서명을 추가합니다.USE [master] GO ADD SIGNATURE TO [master].[awsdms].[rtm_position_1st_timestamp] BY CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert] WITH PASSWORD = '@hardpassword1';
참고
저장된 프로시저를 다시 생성할 경우 서명을 다시 추가해야 합니다.
다음 각 데이터베이스에서 다음과 같은 권한/역할을 보유한 사용자를 생성합니다.
참고
각 복제본에서 동일한 계정을 사용하여 dmsnosysadmin 사용자 계정을 생성해야 합니다. SID 다음 SQL 쿼리는 각 복제본의 dmsnosysadmin 계정 값을 확인하는 데 도움이 될 수 있습니다. SID 사용자 생성에 대한 자세한 내용은 Microsoft SQL 서버 설명서의 CREATE USER
(트랜잭션-SQL) 을 참조하십시오. Azure SQL 데이터베이스의 SQL 사용자 계정을 만드는 방법에 대한 자세한 내용은 활성 지역 복제를 참조하십시오. SELECT @@servername servername, name, sid, create_date, modify_date FROM sys.server_principals WHERE name = 'dmsnosysadmin';
각 복제에서 마스터 데이터베이스에 대한 권한을 부여합니다.
USE master GO GRANT select on sys.fn_dblog to dmsnosysadmin; GRANT view any definition to dmsnosysadmin; GRANT view server state to dmsnosysadmin -- (should be granted to the login). GRANT execute on sp_repldone to dmsnosysadmin; GRANT execute on sp_replincrementlsn to dmsnosysadmin; GRANT execute on sp_addpublication to dmsnosysadmin; GRANT execute on sp_addarticle to dmsnosysadmin; GRANT execute on sp_articlefilter to dmsnosysadmin; GRANT select on [awsdms].[split_partition_list] to dmsnosysadmin; GRANT execute on [awsdms].[rtm_dump_dblog] to dmsnosysadmin; GRANT execute on [awsdms].[rtm_position_1st_timestamp] to dmsnosysadmin;
각 복제에서 msdb 데이터베이스에 대한 권한을 부여합니다.
USE msdb GO GRANT select on msdb.dbo.backupset to dmsnosysadmin GRANT select on msdb.dbo.backupmediafamily to dmsnosysadmin GRANT select on msdb.dbo.backupfile to dmsnosysadmin
소스 데이터베이스에서
db_owner
역할을dmsnosysadmin
에 추가합니다. 데이터베이스가 동기화되었으므로, 기본 복제에만 역할을 추가할 수 있습니다.use <source DB> GO EXEC sp_addrolemember N'db_owner', N'dmsnosysadmin'
클라우드 SQL 서버 DB 인스턴스에서 지속적인 복제 설정
이 섹션에서는 클라우드 호스팅 SQL 서버 데이터베이스 인스턴스를 설정하는 CDC 방법을 설명합니다. 클라우드 호스팅 SQL 서버 인스턴스는 Amazon RDS for SQL Server, Azure SQL 관리 인스턴스 또는 기타 관리형 클라우드 SQL 서버 인스턴스에서 실행되는 인스턴스입니다. 각 데이터베이스 유형에 따른 지속적 복제 제한 사항에 대한 자세한 내용은 SQL서버를 원본으로 사용하는 경우의 제한 AWS DMS 섹션을 참조하세요.
지속적 복제를 설정하기 전에 서버 소스의 지속적 복제 (CDC) 를 사용하기 위한 사전 요구 사항 SQL 섹션을 참조하세요.
자체 관리형 Microsoft SQL Server 소스와 달리 Amazon RDS for SQL Server는 MS 복제를 지원하지 않습니다. 따라서 기본 AWS DMS 키가 있거나 없는 테이블에는 CDC MS-를 사용해야 합니다.
RDSAmazon은 소스 SQL 서버 인스턴스의 지속적인 변경에 AWS DMS 사용되는 복제 아티팩트를 설정할 수 있는 sysadmin 권한을 부여하지 않습니다. 다음 절차에 따라 Amazon CDC RDS 인스턴스용 MS-를 켜야 합니다 (마스터 사용자 권한 사용).
클라우드 SQL 서버 DB CDC 인스턴스용 MS-를 켜려면
-
데이터베이스 수준에서 다음 쿼리 중 하나를 실행합니다.
SQL서버 DB RDS 인스턴스용 경우 이 쿼리를 사용하십시오.
exec msdb.dbo.rds_cdc_enable_db '
DB_name
'Azure SQL 관리형 DB 인스턴스의 경우 이 쿼리를 사용하십시오.
USE
DB_name
GO EXEC sys.sp_cdc_enable_db GO -
기본 키가 있는 각 테이블에 대해 다음 쿼리를 실행하여 CDC MS-를 활성화합니다.
exec sys.sp_cdc_enable_table @source_schema = N'schema_name', @source_name = N'table_name', @role_name = NULL, @supports_net_changes = 1 GO
고유 키는 있지만 기본 키는 없는 각 테이블에 대해 다음 쿼리를 실행하여 MS-를 켜십시오CDC.
exec sys.sp_cdc_enable_table @source_schema = N'schema_name', @source_name = N'table_name', @index_name = N'unique_index_name', @role_name = NULL, @supports_net_changes = 1 GO
기본 키나 고유 키가 없는 각 테이블에 대해 다음 쿼리를 실행하여 MS-를 켜십시오CDC.
exec sys.sp_cdc_enable_table @source_schema = N'schema_name', @source_name = N'table_name', @role_name = NULL GO
-
보존 기간 설정:
DMS버전 3.5.3 이상을 사용하여 복제하는 SQL 서버 인스턴스의 경우 보존 기간을 기본값인 5초로 설정해야 합니다. RDS DMS3.5.2 이하에서 DMS 3.5.3 이상으로 업그레이드하거나 이동하는 경우 새 인스턴스나 업그레이드된 인스턴스에서 작업이 실행된 후 폴링 간격 값을 변경하십시오. 다음 스크립트는 보존 기간을 5초로 설정합니다.
use dbname EXEC sys.sp_cdc_change_job @job_type = 'capture' ,@pollinginterval = 5 exec sp_cdc_stop_job 'capture' exec sp_cdc_start_job 'capture'
DMS버전 3.5.2 RDS 이하를 사용하여 복제하는 Azure SQL MI와 SQL 서버 인스턴스의 경우 다음 명령을 사용하세요.
use dbname EXEC sys.sp_cdc_change_job @job_type = 'capture' ,@pollinginterval = 86399 exec sp_cdc_stop_job 'capture' exec sp_cdc_start_job 'capture'
@pollinginterval
파라미터는 초 단위로 측정되며 권장 값은 86,399로 설정되어 있습니다. 즉,@pollinginterval = 86399
일 경우 트랜잭션 로그는 86,399초(하루) 동안 변경 사항을 보존합니다. 프로시저exec sp_cdc_start_job 'capture'
에서 설정을 시작합니다.참고
일부 SQL 서버 버전에서는 값이 3599초 이상으로
pollinginterval
설정되면 값이 기본값인 5초로 재설정됩니다. 이 경우 T-Log 항목은 읽을 수 있기 전에 AWS DMS 삭제됩니다. 이 알려진 문제의 영향을 받는 SQL 서버 버전을 확인하려면 이 Microsoft KB 문서를참조하십시오. RDSAmazon과 다중 AZ를 함께 사용하는 경우 장애 조치 시 보조 데이터베이스도 올바른 값을 갖도록 설정해야 합니다.
exec rdsadmin..rds_set_configuration 'cdc_capture_pollinginterval' , <5 or 86399>
AWS DMS 복제 작업이 1시간 이상 중지된 경우에도 보존 기간을 유지하려면
참고
DMS3.5.3 이상을 사용하는 SQL 서버 원본 복제에는 RDS 다음 단계가 필요하지 않습니다.
-
다음 명령을 사용하여 트랜잭션 로그를 잘라내는 작업을 중지합니다.
exec sp_cdc_stop_job 'capture'
-
AWS DMS 콘솔에서 작업을 찾아 작업을 재개하십시오.
-
모니터링 탭을 선택하고
CDCLatencySource
지표를 확인합니다. -
CDCLatencySource
지표가 0이고 그대로 유지되면 다음 명령을 사용하여 트랜잭션 로그를 잘라내는 작업을 다시 시작합니다.exec sp_cdc_start_job 'capture'
SQL서버 트랜잭션 로그를 잘라내는 작업은 반드시 시작해야 합니다. 그렇지 않으면 SQL Server 인스턴스의 스토리지가 꽉 찰 수 있습니다.
SQL서버를 원본으로 RDS 사용할 때의 권장 설정 AWS DMS
AWS DMS 3.5.3 이상의 경우
참고
SQL서버 로그 백업 기능의 초기 릴리스는 버전 3.5.3 릴리스 이후에 생성하거나 수정한 엔드포인트에 대해 기본적으로 활성화됩니다. RDS DMS 기존 엔드포인트에 이 기능을 사용하려면 변경하지 않고 엔드포인트를 수정하십시오.
AWS DMS 버전 3.5.3에서는 로그 백업에서 읽기 기능을 지원합니다. DMS주로 활성 트랜잭션 로그를 읽어 이벤트를 복제합니다. 활성 로그에서 읽을 DMS 수 있기 전에 트랜잭션을 백업한 경우 작업은 필요에 따라 RDS 백업에 액세스하여 활성 트랜잭션 로그를 따라잡을 때까지 후속 백업 로그에서 읽습니다. 로그 DMS 백업에 액세스할 수 있도록 RDS 자동 백업 보존 기간을 하루 이상으로 설정하십시오. 자동 백업 보존 기간 설정에 대한 자세한 내용은 Amazon RDS 사용 설명서의 백업 보존 기간을 참조하십시오.
로그 백업에 액세스하는 DMS 작업은 RDS 인스턴스의 스토리지를 사용합니다. 단, 작업은 복제에 필요한 로그 백업에만 액세스합니다. Amazon은 몇 시간 내에 이러한 다운로드된 백업을 RDS 제거합니다. 이렇게 제거해도 Amazon S3에 보관된 Amazon RDS 백업이나 Amazon RDS RESTORE DATABASE
기능에는 영향을 주지 않습니다. 를 사용하여 복제하려는 경우 RDS SQL 서버용 소스에 추가 스토리지를 할당하는 것이 좋습니다. DMS 필요한 스토리지의 양을 추정하는 한 가지 방법은 복제를 시작하거나 재개할 백업을 식별하고 메타데이터 함수를 사용하여 모든 후속 백업의 파일 크기를 더하는 DMS 것입니다. RDS tlog backup
tlog backup
함수에 대한 자세한 내용은 Amazon 사용 RDS 설명서의 사용 가능한 트랜잭션 로그 백업 목록을 참조하십시오.
또는 Amazon 인스턴스의 CloudWatch FreeStorageSpace
지표에 따라 스토리지 자동 확장 및/또는 스토리지 크기 조정을 활성화하도록 선택할 수 있습니다. RDS
트랜잭션 로그 백업의 너무 먼 지점에서 시작하거나 재개하면 SQL 서버 인스턴스의 스토리지가 가득 찰 수 있으므로 사용하지 않는 것이 좋습니다. 이러한 경우에는 전체 로드를 시작하는 것이 좋습니다. 트랜잭션 로그 백업에서 복제하는 것은 활성 트랜잭션 로그에서 읽는 것보다 느립니다. 자세한 내용은 서버의 트랜잭션 로그 백업 처리 RDS SQL 단원을 참조하십시오.
로그 백업에 액세스하려면 추가 권한이 필요하다는 점에 유의하십시오. 자세한 내용은 작업 복제를 시작하기 전에 이러한 권한을 부여해야 함을 참조하십시오. 클라우드 SQL 서버 데이터베이스에서 지속적인 복제를 위한 권한을 설정합니다.
AWS DMS 3.5.2 이하 버전의 경우
Amazon RDS for SQL Server를 원본으로 사용하는 경우 MS- CDC 캡처 작업은 매개 변수 maxscans
및 maxtrans
를 기반으로 합니다. 이러한 매개 변수는 CDC MS-capture가 트랜잭션 로그에서 수행하는 최대 스캔 수와 각 스캔에 대해 처리되는 트랜잭션 수를 제어합니다.
트랜잭션 수가 maxtrans*maxscans
보다 많은 데이터베이스의 경우, polling_interval
값을 늘리면 활성 트랜잭션 로그 레코드가 누적될 수 있습니다. 결과적으로 이러한 누적으로 인해 트랜잭션 로그 크기가 증가할 수 있습니다.
단, CDC MS-캡처 작업에는 의존하지 AWS DMS 않습니다. CDCMS-캡처 작업은 트랜잭션 로그 항목을 처리된 것으로 표시합니다. 이렇게 하면 트랜잭션 로그 백업 작업이 트랜잭션 로그에서 항목을 제거할 수 있습니다.
트랜잭션 로그의 크기와 MS- CDC 작업의 성공 여부를 모니터링하는 것이 좋습니다. MS- CDC 작업이 실패하면 트랜잭션 로그가 과도하게 증가하여 AWS DMS 복제 실패가 발생할 수 있습니다. 소스 데이터베이스의 sys.dm_cdc_errors
동적 관리 보기를 사용하여 MS CDC 캡처 작업 오류를 모니터링할 수 있습니다. DBCC SQLPERF(LOGSPACE)
관리 명령을 사용하여 트랜잭션 로그 크기를 모니터링할 수 있습니다.
MS-로 인한 트랜잭션 로그 증가 문제를 해결하려면 CDC
-
데이터베이스가
Log Space Used %
AWS DMS 복제되고 있는지 확인하고 데이터베이스가 계속 증가하는지 확인하십시오.DBCC SQLPERF(LOGSPACE)
-
트랜잭션 로그 백업 프로세스를 방해하는 요인을 식별합니다.
Select log_reuse_wait, log_reuse_wait_desc, name from sys.databases where name = db_name();
log_reuse_wait_desc
값이REPLICATION
같으면 MS-의 대기 시간으로 인해 로그 백업 보존이 발생합니다. CDC -
maxtrans
및maxscans
파라미터 값을 늘려 캡처 작업에서 처리되는 이벤트 수를 늘립니다.EXEC sys.sp_cdc_change_job @job_type = 'capture' ,@maxtrans = 5000, @maxscans = 20 exec sp_cdc_stop_job 'capture' exec sp_cdc_start_job 'capture'
이 문제를 해결하려면 maxscans
및 maxtrans
값을 매일 원본 데이터베이스에서 AWS DMS 복제하는 테이블에 대해 생성되는 평균 이벤트 수와 같도록 설정하십시오. maxtrans*maxscans
이러한 파라미터를 권장 값보다 높게 설정하면 캡처 작업은 트랜잭션 로그의 모든 이벤트를 처리합니다. 이러한 매개 변수를 권장 값보다 낮게 설정하면 MS- CDC 지연 시간이 늘어나고 트랜잭션 로그도 늘어납니다.
워크로드의 변경으로 이벤트 수가 달라지기 때문에 적절한 maxscans
값과 maxtrans
값을 식별하는 것이 어려울 수 있습니다. 이 경우 MS- CDC 지연 시간에 대한 모니터링을 설정하는 것이 좋습니다. 자세한 내용은 SQL 서버 설명서의 프로세스 모니터링을maxtrans
과 maxscans
를 동적으로 구성합니다.
AWS DMS 작업을 재개하거나 계속하는 데 필요한 로그 시퀀스 번호 (LSNs) 를 찾을 수 없는 경우 작업이 실패하고 완전히 다시 로드해야 할 수 있습니다.
참고
를 사용하여 RDS for SQL Server 소스에서 데이터를 AWS DMS 복제하는 경우 Amazon 인스턴스의 중지 시작 이벤트 이후 복제를 재개하려고 할 때 오류가 발생할 수 있습니다. RDS 이는 stop-start 이벤트 후 캡처 작업 프로세스를 재시작하면 SQL Server Agent 프로세스가 캡처 작업 프로세스를 다시 시작하기 때문입니다. 이렇게 하면 MS- 폴링 간격이 생략됩니다. CDC
이로 인해 MS- CDC 캡처 작업 처리보다 트랜잭션 볼륨이 낮은 데이터베이스에서는 중단된 위치에서 다시 시작되기 전에 데이터가 처리되거나 복제 및 백업된 것으로 표시되어 다음 오류가 발생할 AWS DMS 수 있습니다.
[SOURCE_CAPTURE ]E: Failed to access LSN '0000dbd9:0006f9ad:0003' in the backup log sets since BACKUP/LOG-s are not available. [1020465] (sqlserver_endpoint_capture.c:764)
이 문제를 완화하려면 앞서 권장한 대로 maxtrans
및 maxscans
값을 설정하세요.