

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# Microsoft SQL Server 데이터베이스를의 소스로 사용 AWS DMS
<a name="CHAP_Source.SQLServer"></a>

를 사용하여 하나 이상의 Microsoft SQL Server 데이터베이스에서 데이터를 마이그레이션합니다 AWS DMS. SQL Server 데이터베이스를 소스로 사용하면 데이터를 다른 SQL Server 데이터베이스 또는 AWS DMS 지원되는 다른 데이터베이스 중 하나로 마이그레이션할 수 있습니다.

가 소스로 AWS DMS 지원하는 SQL Server 버전에 대한 자세한 내용은 섹션을 참조하세요[의 소스 AWS DMS](CHAP_Introduction.Sources.md).

원본 SQL Server 데이터베이스는 네트워크 상의 어느 컴퓨터에나 설치할 수 있습니다. AWS DMS에서 사용하려면 사용자가 선택한 작업 유형에 적절한 원본 데이터베이스 액세스 권한이 있는 SQL Server 계정이 필요합니다. 자세한 내용은 [SQL Server 태스크에 대한 권한](#CHAP_Source.SQLServer.Permissions) 단원을 참조하십시오.

AWS DMS 는 SQL Server의 명명된 인스턴스에서 데이터 마이그레이션을 지원합니다. 원본 엔드포인트를 생성하는 경우 서버 이름에 다음 표기법을 사용할 수 있습니다.

```
IPAddress\InstanceName
```

예를 들어 올바른 원본 엔드포인트 서버 이름은 다음과 같습니다. 여기서, 이름의 첫 번째 부분은 서버의 IP 주소이며, 두 번째 부분은 SQL Server 인스턴스 이름(이 예에서는 SQLTest)입니다.

```
10.0.0.25\SQLTest
```

또한 SQL Server의 명명된 인스턴스가 수신 대기하는 포트 번호를 가져와 소스 AWS DMS 엔드포인트를 구성하는 데 사용합니다.

**참고**  
포트 1433은 Microsoft SQL Server의 기본값입니다. 그러나 SQL Server가 시작될 때마다 변경되는 동적 포트와 방화벽을 통해 SQL Server에 연결하는 데 사용되는 특정 정적 포트 번호도 자주 사용됩니다. 따라서 AWS DMS 소스 엔드포인트를 생성할 때 SQL Server의 명명된 인스턴스의 실제 포트 번호를 알고 싶습니다.

SSL을 사용하여 SQL Server 엔드포인트와 복제 인스턴스 사이의 연결을 암호화할 수 있습니다. SQL Server 엔드포인트에서 SSL을 사용하는 방법에 대한 자세한 내용은 [에서 SSL 사용 AWS Database Migration Service](CHAP_Security.SSL.md) 섹션을 참조하세요.

CDC를 사용하여 SQL Server 데이터베이스에서 지속적으로 마이그레이션할 수 있습니다. CDC용 소스 SQL Server 데이터베이스 구성에 대한 자세한 내용은 [SQL Server에서 지속적인 복제를 위한 데이터 변경 사항 캡처](CHAP_Source.SQLServer.CDC.md) 섹션을 참조하세요.

SQL Server 소스 데이터베이스 작업에 대한 자세한 내용은 다음을 AWS DMS참조하세요.

**Topics**
+ [SQL Server를 소스로 사용할 때의 제한 사항 AWS DMS](#CHAP_Source.SQLServer.Limitations)
+ [SQL Server 태스크에 대한 권한](#CHAP_Source.SQLServer.Permissions)
+ [SQL Server 소스에서 지속적 복제(CDC) 사용을 위한 사전 요구 사항](#CHAP_Source.SQLServer.Prerequisites)
+ [SQL Server에 지원되는 압축 방법](#CHAP_Source.SQLServer.Compression)
+ [자체 관리형 SQL Server AlwaysOn 가용성 그룹 사용](#CHAP_Source.SQLServer.AlwaysOn)
+ [SQL Server를의 소스로 사용할 때 엔드포인트 설정 AWS DMS](#CHAP_Source.SQLServer.ConnectionAttrib)
+ [SQL Server용 소스 데이터 형식](#CHAP_Source.SQLServer.DataTypes)
+ [SQL Server에서 지속적인 복제를 위한 데이터 변경 사항 캡처](CHAP_Source.SQLServer.CDC.md)

## SQL Server를 소스로 사용할 때의 제한 사항 AWS DMS
<a name="CHAP_Source.SQLServer.Limitations"></a>

다음 제한 사항은 SQL Server 데이터베이스를 AWS DMS용 소스로 사용 시 적용됩니다.
+ 열의 자격 증명 속성은 대상 데이터베이스 열로 마이그레이션되지 않습니다.
+ SQL Server 엔드포인트는 희소 열을 가진 테이블 사용을 지원하지 않습니다.
+ Windows 인증은 지원되지 않습니다.
+ SQL Server에서 컴퓨팅된 필드의 변경 사항은 복제되지 않습니다.
+ 임시 테이블은 지원되지 않습니다.
+ SQL Server 파티션 전환은 지원되지 않습니다.
+ WRITETEXT 및 UPDATETEXT 유틸리티를 사용하는 경우 소스 데이터베이스에 적용된 이벤트를 캡처하지 AWS DMS 않습니다.
+ 다음 데이터 조작 언어(DML) 패턴은 지원되지 않습니다.

  ```
  SELECT * INTO new_table FROM existing_table
  ```
+ SQL Server를 소스로 사용할 경우, 열 수준 암호화는 지원되지 않습니다.
+ AWS DMS 는 SQL Server 2008 또는 SQL Server 2008 R2에 대한 서버 수준 감사를 소스로 지원하지 않습니다. 이는 SQL Server 2008 및 2008 R2의 알려진 문제 때문입니다. 예를 들어 다음 명령을 실행하면가 실패 AWS DMS 합니다.

  ```
  USE [master]
  GO 
  ALTER SERVER AUDIT [my_audit_test-20140710] WITH (STATE=on)
  GO
  ```
+ SQL Server를 소스로 사용하는 경우 Geometry 및 Geography 열은 전체 LOB 모드에서 지원되지 않습니다. 대신, 제한적 LOB 모드를 사용하거나 인라인 LOB 모드를 사용하도록 `InlineLobMaxSize` 작업 설정을 설정하세요.
+ 복제 작업에서 Microsoft SQL Server 소스 데이터베이스를 사용하는 경우, 작업을 제거하면 SQL Server Replication Publisher 정의가 제거되지 않습니다. Microsoft SQL Server 시스템 관리자는 Microsoft SQL Server에서 해당 정의를 삭제해야 합니다.
+ 전체 로드 전용 작업의 경우, 스키마 바운딩된 뷰와 스키마 바인딩되지 않은 뷰에서 데이터를 마이그레이션할 수 있습니다.
+ sp\$1rename을 사용하여 테이블 이름을 바꾸는 것은 지원되지 않습니다(예: `sp_rename 'Sales.SalesRegion', 'SalesReg;)`).
+ sp\$1rename을 사용하여 열 이름을 바꾸는 것은 지원되지 않습니다(예: `sp_rename 'Sales.Sales.Region', 'RegID', 'COLUMN';`).
+ AWS DMS 는 열 기본값을 설정 및 설정 해제하기 위한 변경 처리를 지원하지 않습니다(`ALTER TABLE`문과 함께 `ALTER COLUMN SET DEFAULT` 절 사용).
+ AWS DMS 는 열 null성을 설정하기 위한 변경 처리를 지원하지 않습니다(`ALTER TABLE`문과 함께 `ALTER COLUMN [SET|DROP] NOT NULL` 절 사용).
+ SQL Server 2012 및 SQL Server 2014에서는 가용성 그룹과 함께 DMS 복제를 사용하는 경우, 배포 데이터베이스를 가용성 그룹에 배치할 수 없습니다. SQL 2016은 병합, 양방향 또는 P2P 복제 토폴로지에 사용되는 배포 데이터베이스를 제외하고 배포 데이터베이스를 가용성 그룹에 배치하는 것을 지원합니다.
+ 분할된 테이블의 경우 AWS DMS 는 각 파티션에 대해 서로 다른 데이터 압축 설정을 지원하지 않습니다.
+ SQL Server 공간 데이터 유형(GEOGRAPHY 및 GEOMETRY)에 값을 삽입할 때 공간 참조 시스템 식별자(SRID) 속성을 무시하거나 다른 숫자를 지정할 수 있습니다. 공간 데이터 형식으로 테이블을 복제할 때는 SRID를 기본 SRID(GEOMETRY의 경우 0, GEOGRAPHY의 경우 4326)로 바 AWS DMS 꿉니다.
+ 데이터베이스가 MS-REPLICATION 또는 MS-CDC에 대해 구성되지 않은 경우에도 프라이머리 키가 없는 테이블을 캡처할 수 있지만 INSERT/DELETE DML 이벤트만 캡처됩니다. UPDATE 및 TRUNCATE TABLE 이벤트는 무시됩니다.
+ Columnstore 인덱스는 지원되지 않습니다.
+ 메모리 최적화 테이블(인 메모리 OLTP 사용)은 지원되지 않습니다.
+ 여러 열로 구성된 프라이머리 키가 있는 테이블을 복제할 때 전체 로드 중에 프라이머리 키 열을 업데이트하는 것은 지원되지 않습니다.
+ 지연된 지속성은 지원되지 않습니다.
+ `readBackupOnly=true` 엔드포인트 설정(추가 연결 속성)은 RDS의 백업 수행 방식 때문에 RDS for SQL Server 소스 인스턴스에서 작동하지 않습니다.
+ RDS 사용자에게는 SQL Server 저장 프로시저 `sp_repldone`을 실행할 수 있는 액세스 권한이 없기 때문에 `EXCLUSIVE_AUTOMATIC_TRUNCATION`는 Amazon RDS SQL Server 소스 인스턴스에서는 작동하지 않습니다.
+ AWS DMS 는 잘라내기 명령을 캡처하지 않습니다.
+ AWS DMS 는 가속 데이터베이스 복구(ADR)가 켜져 있는 데이터베이스에서의 복제를 지원하지 않습니다.
+ AWS DMS 는 단일 트랜잭션 내에서 데이터 정의 언어(DDL) 및 데이터 조작 언어(DML) 문 캡처를 지원하지 않습니다.
+ AWS DMS 는 데이터 계층 애플리케이션 패키지(DACPAC)의 복제를 지원하지 않습니다.
+ 프라이머리 키나 고유 인덱스를 포함하고 여러 데이터 행을 업데이트하는 UPDATE 문은 대상 데이터베이스에 변경 내용을 적용할 때 충돌을 일으킬 수 있습니다. 예를 들어 대상 데이터베이스가 업데이트를 단일 UPDATE 문 대신 INSERT 문과 DELETE 문으로 적용하는 경우, 이런 일이 발생할 수 있습니다. 일괄 최적화 적용 모드에서는 테이블이 무시될 수 있습니다. 트랜잭션 적용 모드에서는 UPDATE 작업 시 제약 조건 위반이 발생할 수 있습니다. 이 문제를 방지하려면 관련 테이블을 다시 로드하세요. 또는 Apply Exceptions 제어 테이블(`dmslogs.awsdms_apply_exceptions`)에서 문제가 되는 레코드를 찾아 대상 데이터베이스에서 수동으로 편집합니다. 자세한 내용은 [변경 처리 튜닝 설정](CHAP_Tasks.CustomizingTasks.TaskSettings.ChangeProcessingTuning.md) 단원을 참조하십시오.
+ AWS DMS 는 테이블 및 스키마 복제를 지원하지 않습니다. 여기서 이름에는 다음 세트의 특수 문자가 포함됩니다.

  `\\ -- \n \" \b \r ' \t ;` 
+ 데이터 마스킹은 지원되지 않습니다. 마스킹 없이 마스킹된 데이터를 AWS DMS 마이그레이션합니다.
+ AWS DMS 는 기본 키가 있는 최대 32,767개의 테이블과 각 테이블에 대해 최대 1,000개의 열을 복제합니다. 이는가 복제된 각 테이블에 대해 SQL Server 복제 문서를 AWS DMS 생성하고 SQL Server 복제 문서에 이러한 제한이 있기 때문입니다.
+ CDC(변경 데이터 캡처)를 사용할 때는 고유 인덱스를 구성하는 모든 열을 `NOT NULL`로 정의해야 합니다. 이 요구 사항이 충족되지 않으면 SQL Server 시스템 오류 22838이 발생합니다.
+ SQL Server가 활성 트랜잭션 로그에서 백업 로그로 아카이브하거나 활성 트랜잭션 로그에서 잘라내면 이벤트가 손실될 수 있습니다.

백업 트랜잭션 로그에 액세스할 때는 다음 제한 사항이 적용됩니다.
+ 암호화된 백업은 지원되지 않습니다.
+ URL 또는 Windows Azure에 저장된 백업은 지원되지 않습니다.
+ AWS DMS doe snot는 대체 공유 폴더의 파일 수준에서 트랜잭션 로그 백업의 직접 처리를 지원하지 않습니다.
+ Amazon RDS for Microsoft SQL Server 이외의 클라우드 SQL Server 소스의 경우는 활성 트랜잭션 로그로만 지속적 복제(CDC)를 AWS DMS 지원합니다. CDC에서는 백업 로그를 사용할 수 없습니다. SQL Server가 활성 트랜잭션 로그에서 백업 로그로 아카이브하거나 DMS가 읽기 전에 활성 트랜잭션 로그에서 잘라내면 이벤트가 손실될 수 있습니다.
+ Amazon RDS for Microsoft SQL Server 소스의 경우 AWS DMS 3.5.2 이하에서는 DMS가 CDC를 통해 백업 로그에 액세스할 수 없으므로 활성 트랜잭션 로그로만 지속적 복제(CDC)를 지원합니다. RDS for SQL Server가 활성 트랜잭션 로그에서 백업 로그로 아카이브하거나 DMS가 읽기 전에 활성 트랜잭션 로그에서 잘라내면 이벤트가 손실될 수 있습니다. 이 제한은 AWS DMS 버전 3.5.3 이상에는 적용되지 않습니다.
+ AWS DMS 는 Amazon RDS Proxy for SQL Server에 대한 CDC를 소스로 지원하지 않습니다.
+ 전체 로드 작업 중에 SQL Server 소스를 사용할 수 없게 되면 AWS DMS 는 데이터 마이그레이션이 불완전하게 유지되더라도 여러 번의 재연결 시도 후 작업을 완료된 것으로 표시할 수 있습니다. 이 시나리오에서 대상 테이블에는 연결 손실 전에 마이그레이션된 레코드만 포함되어 소스와 대상 시스템 간에 데이터 불일치가 발생할 수 있습니다. 데이터 완전성을 보장하려면 전체 로드 작업을 완전히 다시 시작하거나 연결 중단의 영향을 받는 특정 테이블을 다시 로드해야 합니다.

## SQL Server 태스크에 대한 권한
<a name="CHAP_Source.SQLServer.Permissions"></a>

**Topics**
+ [전체 로드 전용 작업에 대한 권한](#CHAP_Source.SQLServer.Permissions.FullLoad)
+ [복제가 진행 중인 태스크에 대한 권한](#CHAP_Source.SQLServer.Permissions.Ongoing)

### 전체 로드 전용 작업에 대한 권한
<a name="CHAP_Source.SQLServer.Permissions.FullLoad"></a>

전체 로드 전용 작업을 수행하려면 다음 권한이 필요합니다. AWS DMS 는 `dms_user` 로그인을 생성하지 않습니다. SQL Server 로그인 생성에 대한 자세한 내용은 *Microsoft 설명서*의 [데이터베이스 사용자 생성](https://learn.microsoft.com/en-us/sql/relational-databases/security/authentication-access/create-a-database-user?view=sql-server-ver16) 주제를 참조하세요.

```
USE db_name;
                
                CREATE USER dms_user FOR LOGIN dms_user; 
                ALTER ROLE [db_datareader] ADD MEMBER dms_user; 
                GRANT VIEW DATABASE STATE to dms_user;
                GRANT VIEW DEFINITION to dms_user;
                
                USE master;
                
                GRANT VIEW SERVER STATE TO dms_user;
```

### 복제가 진행 중인 태스크에 대한 권한
<a name="CHAP_Source.SQLServer.Permissions.Ongoing"></a>

자체 관리형 SQL Server 인스턴스는 `sysadmin` 역할을 사용하거나 사용하지 않고도 DMS를 사용하여 계속 복제하도록 구성할 수 있습니다. `sysadmin` 역할을 부여할 수 없는 SQL Server 인스턴스의 경우 DMS 사용자에게 다음과 같은 권한이 있는지 확인합니다.

**자체 관리형 SQL Server 데이터베이스에서 지속적인 복제를 위한 권한 설정**

1. SQL Server Management Studio(SSMS)를 사용하여 또는 [전체 로드 전용 작업에 대한 권한](#CHAP_Source.SQLServer.Permissions.FullLoad)에서 이전에 설명한 대로 암호 인증이 있는 새 SQL Server 계정을 생성합니다(예: `self_managed_user`).

1. 다음 `GRANT` 명령을 실행합니다.

   ```
   GRANT VIEW SERVER STATE TO self_managed_user;
   
   USE msdb;
       GRANT SELECT ON msdb.dbo.backupset TO self_managed_user;
       GRANT SELECT ON msdb.dbo.backupmediafamily TO self_managed_user;
       GRANT SELECT ON msdb.dbo.backupfile TO self_managed_user;
       
   USE db_name;
       CREATE USER self_managed_user FOR LOGIN self_managed_user;
       ALTER ROLE [db_owner] ADD MEMBER self_managed_user;
       GRANT VIEW DEFINITION to self_managed_user;
   ```

1. 이전 권한 외에도 사용자는 다음 중 하나가 필요합니다.
   + 사용자는 `sysadmin` 고정된 서버 역할의 구성원이어야 합니다.
   + 소스 구성에 따라 [가용성 그룹 환경의 SQL Server에서 지속적 복제 설정: sysadmin 역할 없음](CHAP_Source.SQLServer.CDC.md#CHAP_SupportScripts.SQLServer.ag) 또는 [독립 실행형 SQL Server에서 지속적 복제 설정: sysadmin 역할 없음](CHAP_Source.SQLServer.CDC.md#CHAP_SupportScripts.SQLServer.standalone)에 설명된 구성 및 권한.

#### 클라우드 SQL Server 데이터베이스에서 지속적인 복제를 위한 권한 설정
<a name="CHAP_Source.SQLServer.Permissions.Cloud"></a>

클라우드에 호스팅된 SQL Server 인스턴스는 Amazon RDS for Microsoft SQL Server, Azure SQL Managed Instance 또는 DMS에서 지원하는 기타 관리형 클라우드 SQL Server 인스턴스에서 실행되는 인스턴스입니다.

SQL Server Management Studio(SSMS)를 사용하여 또는 [전체 로드 전용 작업에 대한 권한](#CHAP_Source.SQLServer.Permissions.FullLoad)에서 이전에 설명한 대로 암호 인증이 있는 새 SQL Server 계정을 생성합니다(예: `rds_user`).

다음 GRANT 명령을 실행합니다.

```
GRANT VIEW SERVER STATE TO rds_user;
```

Amazon RDS for Microsoft SQL Server 소스의 경우 DMS 버전 3.5.3 이상은 트랜잭션 로그 백업에서 읽기를 지원합니다. DMS가 로그 백업에 액세스할 수 있도록 하려면 위의 항목 외에도 RDS SQL Server 소스에 대한 `master` 사용자 권한 또는 다음 권한을 부여합니다.

```
USE msdb;
    GRANT EXEC ON msdb.dbo.rds_dms_tlog_download TO rds_user;
    GRANT EXEC ON msdb.dbo.rds_dms_tlog_read TO rds_user;
    GRANT EXEC ON msdb.dbo.rds_dms_tlog_list_current_lsn TO rds_user;
    GRANT EXEC ON msdb.dbo.rds_task_status TO rds_user;
    
USE db_name;
    CREATE USER rds_user FOR LOGIN rds_user;
    ALTER ROLE [db_owner] ADD MEMBER rds_user;
    GRANT VIEW DEFINITION to rds_user;
```

Amazon Azure SQL 관리형 인스턴스의 경우 다음 권한을 부여합니다.

```
GRANT SELECT ON msdb.dbo.backupset TO rds_user;
GRANT SELECT ON msdb.dbo.backupmediafamily TO rds_user;
GRANT SELECT ON msdb.dbo.backupfile TO rds_user;
```

## SQL Server 소스에서 지속적 복제(CDC) 사용을 위한 사전 요구 사항
<a name="CHAP_Source.SQLServer.Prerequisites"></a>

온프레미스 또는 Amazon EC2의 자체 관리형 SQL Server 데이터베이스 또는 Amazon RDS나 Microsoft Azure SQL 관리형 인스턴스 같은 클라우드 데이터베이스에 지속적 복제(변경 데이터 캡처, 즉 CDC)를 사용할 수 있습니다.

특히 SQL Server 데이터베이스를 AWS DMS의 소스로 이용하는 지속적 복제를 사용할 때 다음 요구 사항이 적용됩니다.
+ SQL Server는 전체 백업에 맞게 구성되어야 하며, 사용자는 데이터 복제를 시작하기 전에 백업을 수행해야 합니다.
+ 복구 모델은 **대량 로그** 또는 **전체**로 설정되어야 합니다.
+ 여러 디스크로의 SQL Server 백업은 지원되지 않습니다. 백업이 서로 다른 디스크의 여러 파일에 데이터베이스 백업을 쓰도록 정의된 경우는 데이터를 읽을 AWS DMS 수 없으며 AWS DMS 작업이 실패합니다.
+ 자체 관리형 SQL Server 소스의 경우, 작업을 제거할 때 DMS CDC 작업에 사용되는 소스의 SQL Server Replication Publisher 정의는 제거되지 않습니다. SQL Server 시스템 관리자는 자체 관리형 원본을 위해 SQL Server에서 이 정의를 삭제해야 합니다.
+ CDC 중에는 변경 사항을 읽기 위해 SQL Server 트랜잭션 로그 백업을 조회 AWS DMS 해야 합니다. AWS DMS 는 네이티브 형식이 아닌 타사 백업 소프트웨어를 사용하여 생성된 SQL Server 트랜잭션 로그 백업을* 지원하지 않습니다*. 네이티브 형식*이고* 타사 백업 소프트웨어를 사용하여 생성된 트랜잭션 로그 백업을 지원하려면 소스 엔드포인트에 `use3rdPartyBackupDevice=Y` 연결 속성을 추가하세요.
+ 자체 관리형 SQL Server 원본의 경우, SQL Server는 변경 사항이 게시될 때까지 새로 생성된 테이블에서 변경 사항을 캡처하지 않음에 유의하세요. 테이블이 SQL Server 소스에 추가되면가 게시 생성을 AWS DMS 관리합니다. 그렇지만, 이 프로세스에는 몇 분이 걸릴 수 있습니다. 이 지연 시간 동안 새로 생성된 테이블에 적용된 작업은 대상에 캡처되거나 복제되지 않습니다.
+ AWS DMS 변경 데이터 캡처를 사용하려면 SQL Server에서 전체 트랜잭션 로깅을 활성화해야 합니다. SQL Server에서 전체 트랜잭션 로깅을 켜려면 MS-REPLICATION 또는 CHANGE DATA CAPTURE(CDC)를 활성화하세요.
+ SQL Server *tlog* 항목은 MS CDC 캡처 작업이 해당 변경 내용을 처리할 때까지는 재사용으로 표시되지 않습니다.
+ CDC 작업은 메모리 최적화된 테이블에서 지원되지 않습니다. 이 제한 사항은 이 기능이 처음 도입된 SQL Server 2014 이상에 적용됩니다.
+ AWS DMS 변경 데이터 캡처에는 기본적으로 Amazon EC2 또는 온프레미스 SQL 서버에서 소스로 배포 데이터베이스가 필요합니다. 따라서 프라이머리 키가 있는 테이블의 MS 복제를 구성하는 동안 배포자를 활성화했는지 확인하세요.

## SQL Server에 지원되는 압축 방법
<a name="CHAP_Source.SQLServer.Compression"></a>

 AWS DMS에서의 SQL Server 압축 방법 지원에 대해서는 다음을 참고하세요.
+ AWS DMS 는 SQL Server 버전 2008 이상에서 행/페이지 압축을 지원합니다.
+ AWS DMS 는 Vardecimal 스토리지 형식을 지원하지 않습니다.
+ AWS DMS 는 희소 열 및 열 구조 압축을 지원하지 않습니다.

## 자체 관리형 SQL Server AlwaysOn 가용성 그룹 사용
<a name="CHAP_Source.SQLServer.AlwaysOn"></a>

SQL Server AlwaysOn 가용성 그룹은 데이터베이스 미러링의 엔터프라이즈 수준 대안으로서 고가용성과 재해 복구를 제공합니다.

에서는 단일 기본 또는 보조 가용성 그룹 복제본에서 변경 사항을 마이그레이션 AWS DMS할 수 있습니다.

### 기본 가용성 그룹 복제본 사용
<a name="CHAP_Source.SQLServer.AlwaysOn.Primary"></a>

 

**에서 기본 가용성 그룹을 소스로 사용하려면 다음을 AWS DMS수행합니다.**

1. 가용성 복제본의 모든 SQL Server 인스턴스에서 배포 옵션을 켭니다. 자세한 내용은 [자체 관리형 SQL Server에서 지속적 복제 설정](CHAP_Source.SQLServer.CDC.md#CHAP_Source.SQLServer.CDC.MSCDC) 단원을 참조하십시오.

1.  AWS DMS 콘솔에서 SQL Server 소스 데이터베이스 설정을 엽니다. **서버 이름**에서 가용성 그룹 리스너에 맞게 구성된 DNS(Domain Name Service) 이름이나 IP 주소를 지정합니다.

 AWS DMS 작업을 처음 시작하면 평소보다 시작하는 데 시간이 오래 걸릴 수 있습니다. 이렇게 느려지는 이유는 가용성 그룹 서버가 테이블 항목 생성을 복제하고 있기 때문입니다.

### 보조 가용성 그룹 복제본 사용
<a name="CHAP_Source.SQLServer.AlwaysOn.Secondary"></a>

**에서 보조 가용성 그룹을 소스로 사용하려면 다음을 AWS DMS수행합니다.**

1.  AWS DMS 소스 엔드포인트 사용자가 사용하는 것과 동일한 자격 증명을 사용하여 개별 복제본에 연결합니다.

1.  AWS DMS 복제 인스턴스가 모든 기존 복제본의 DNS 이름을 확인하고 연결할 수 있는지 확인합니다. 다음 SQL 쿼리를 사용하여 모든 복제본의 DNS 이름을 가져올 수 있습니다.

   ```
   select ar.replica_server_name, ar.endpoint_url from sys.availability_replicas ar
   JOIN sys.availability_databases_cluster adc
   ON adc.group_id = ar.group_id AND adc.database_name = '<source_database_name>';
   ```

1. 소스 엔드포인트를 만들 때 엔드포인트의 **서버 이름** 또는 엔드포인트 암호의 **서버 주소**에 가용성 그룹 리스너의 DNS 이름을 지정합니다. 가용성 그룹 리스너에 대한 자세한 내용은 SQL Server 설명서의 [What is an availability group listner?](https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/availability-group-listener-overview?view=sql-server-ver15)를 참조하세요.

   공용 DNS 서버 또는 온프레미스 DNS 서버를 사용하여 가용성 그룹 리스너, 기본 복제본, 보조 복제본을 확인할 수 있습니다. 온프레미스 DNS 서버를 사용하려면 Amazon Route 53 Resolver를 구성하세요. 자세한 내용은 [자체 온프레미스 이름 서버 사용](CHAP_BestPractices.md#CHAP_BestPractices.Rte53DNSResolver) 단원을 참조하십시오.

1. 다음 추가 연결 속성을 소스 엔드포인트에 추가합니다.    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/dms/latest/userguide/CHAP_Source.SQLServer.html)

1. 가용성 그룹의 모든 복제본에서 배포 옵션을 활성화합니다. 배포자 목록에 모든 노드를 추가합니다. 자세한 내용은 [배포를 설정하려면](CHAP_Source.SQLServer.CDC.md#CHAP_Source.SQLServer.CDC.MSCDC.Setup) 단원을 참조하십시오.

1. 기본 읽기-쓰기 복제본에서 다음 쿼리를 실행하여 데이터베이스를 게시할 수 있도록 합니다. 이 쿼리는 데이터베이스에 대해 한 번만 실행합니다.

   ```
   sp_replicationdboption @dbname = N'<source DB name>', @optname = N'publish', @value = N'true';
   ```



#### 제한 사항
<a name="CHAP_Source.SQLServer.AlwaysOn.Secondary.limitations"></a>

다음은 보조 가용성 그룹 복제본 작업의 제한 사항입니다.
+ AWS DMS 는 읽기 전용 가용성 그룹 복제본을 소스로 사용할 때 Safeguard를 지원하지 않습니다. 자세한 내용은 [SQL Server를의 소스로 사용할 때 엔드포인트 설정 AWS DMS](#CHAP_Source.SQLServer.ConnectionAttrib) 단원을 참조하십시오.
+ AWS DMS 는 읽기 전용 가용성 그룹 복제본을 소스로 사용할 때 `setUpMsCdcForTables` 추가 연결 속성을 지원하지 않습니다. 자세한 내용은 [SQL Server를의 소스로 사용할 때 엔드포인트 설정 AWS DMS](#CHAP_Source.SQLServer.ConnectionAttrib) 단원을 참조하십시오.
+ AWS DMS 는 버전 3.4.7부터 자체 관리형 보조 가용성 그룹 복제본을 지속적 복제(변경 데이터 캡처 또는 CDC)를 위한 소스 데이터베이스로 사용할 수 있습니다. Cloud SQL Server 다중 AZ 읽기 전용 복제본은 지원되지 않습니다. 이전 버전의를 사용하는 경우 기본 가용성 그룹 복제본을 CDC의 소스 데이터베이스로 사용해야 AWS DMS합니다.

#### 다른 노드로의 장애 조치
<a name="CHAP_Source.SQLServer.AlwaysOn.Secondary.failover"></a>

엔드포인트에 대한 `ApplicationIntent` 추가 연결 속성을 로 설정하면 `ReadOnly` AWS DMS 태스크가 읽기 전용 라우팅 우선 순위가 가장 높은 읽기 전용 노드에 연결됩니다. 우선 순위가 가장 높은 읽기 전용 노드를 사용할 수 없는 경우, 가용성 그룹에 있는 다른 읽기 전용 노드로 장애 조치됩니다. 를 설정하지 않으면 `ApplicationIntent` AWS DMS 작업은 가용성 그룹의 기본(읽기/쓰기) 노드에만 연결됩니다.

## SQL Server를의 소스로 사용할 때 엔드포인트 설정 AWS DMS
<a name="CHAP_Source.SQLServer.ConnectionAttrib"></a>

추가 연결 속성을 사용하는 것과 비슷하게 엔드포인트 설정을 사용하여 SQL Server 소스 데이터베이스를 구성할 수 있습니다. AWS DMS 콘솔을 사용하거나의 `create-endpoint` 명령을 `--microsoft-sql-server-settings '{"EndpointSetting": "value", ...}'` JSON 구문과 [AWS CLI](https://docs.aws.amazon.com/cli/latest/reference/dms/index.html)함께 사용하여 소스 엔드포인트를 생성할 때 설정을 지정합니다.

SQL Server를 소스로 할 때 사용할 수 있는 엔드포인트 설정은 다음 테이블에 나와 있습니다.

[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/ko_kr/dms/latest/userguide/CHAP_Source.SQLServer.html)

## SQL Server용 소스 데이터 형식
<a name="CHAP_Source.SQLServer.DataTypes"></a>

SQL Server를 소스로 사용하는 데이터 마이그레이션은 대부분의 SQL Server 데이터 유형을 AWS DMS 지원합니다. 다음 표에는 사용 시 지원되는 SQL Server 소스 데이터 형식 AWS DMS 과 AWS DMS 데이터 형식의 기본 매핑이 나와 있습니다.

대상에서 매핑된 데이터 형식을 확인하는 방법에 대한 정보는 사용 중인 대상 엔드포인트에 대한 섹션을 참조하세요.

 AWS DMS 데이터 형식에 대한 자세한 내용은 섹션을 참조하세요[AWS Database Migration Service에서 사용되는 데이터 형식](CHAP_Reference.DataTypes.md).


|  SQL Server 데이터 형식  |  AWS DMS 데이터 유형  | 
| --- | --- | 
|  BIGINT  |  INT8  | 
|  BIT  |  BOOLEAN  | 
|  DECIMAL  |  NUMERIC  | 
|  INT  |  INT4  | 
|  MONEY  |  NUMERIC  | 
|  NUMERIC(p,s)  |  NUMERIC   | 
|  SMALLINT  |  INT2  | 
|  SMALLMONEY  |  NUMERIC  | 
|  TINYINT  |  UINT1  | 
|  REAL  |  REAL4  | 
|  FLOAT  |  REAL8  | 
|  DATETIME  |  DATETIME  | 
|  DATETIME2(SQL Server 2008 이상)  |  DATETIME  | 
|  SMALLDATETIME  |  DATETIME  | 
|  DATE  |  DATE  | 
|  TIME  |  TIME  | 
|  DATETIMEOFFSET  |  WSTRING  | 
|  CHAR  |  STRING  | 
|  VARCHAR  |  STRING  | 
|  VARCHAR(최대)  |  CLOB TEXT 이 데이터 형식을와 함께 사용하려면 특정 작업에 대해 CLOB 데이터 형식 사용을 활성화 AWS DMS해야 합니다. SQL Server 테이블의 경우 SQL Server의 LOB 열 값을 변경하지 않는 UPDATE 문에도 대상의 LOB 열을 AWS DMS 업데이트합니다. CDC 중에는 기본 키가 포함된 테이블에서만 CLOB 데이터 형식을 AWS DMS 지원합니다.  | 
|  NCHAR  |  WSTRING  | 
|  NVARCHAR(길이)  |  WSTRING  | 
|  NVARCHAR(최대)  |  NCLOB NTEXT 이 데이터 형식을와 함께 사용하려면 특정 작업에 대해 SupportLobs 사용을 활성화 AWS DMS해야 합니다. Lob 지원 활성화에 대한 자세한 내용은 [AWS DMS 작업의 소스 데이터베이스에 대한 LOB 지원 설정](CHAP_Tasks.LOBSupport.md) 섹션을 참조하세요. SQL Server 테이블의 경우 SQL Server의 LOB 열 값을 변경하지 않는 UPDATE 문에도 대상의 LOB 열을 AWS DMS 업데이트합니다. CDC 중에는 기본 키가 포함된 테이블에서만 CLOB 데이터 형식을 AWS DMS 지원합니다.  | 
|  BINARY  |  BYTES  | 
|  VARBINARY  |  BYTES  | 
|  VARBINARY(최대)  |  BLOB IMAGE SQL Server 테이블의 경우 SQL Server의 LOB 열 값을 변경하지 않는 UPDATE 문에도 대상의 LOB 열을 AWS DMS 업데이트합니다. 이 데이터 형식을와 함께 사용하려면 특정 작업에 대해 BLOB 데이터 형식 사용을 활성화 AWS DMS해야 합니다. AWS DMS 는 기본 키가 포함된 테이블에서만 BLOB 데이터 형식을 지원합니다.  | 
|  TIMESTAMP  |  BYTES  | 
|  UNIQUEIDENTIFIER  |  STRING  | 
|  HIERARCHYID   |  SQL Server 대상 엔드포인트에 복제할 때 HIERARCHYID를 사용합니다. 다른 모든 대상 엔드포인트에 복제할 때에는 WSTRING(250)을 사용합니다.  | 
|  XML  |  NCLOB SQL Server 테이블의 경우 SQL Server의 LOB 열 값을 변경하지 않는 UPDATE 문에도 대상의 LOB 열을 AWS DMS 업데이트합니다. 이 데이터 형식을와 함께 사용하려면 특정 작업에 대해 NCLOB 데이터 형식 사용을 활성화 AWS DMS해야 합니다. CDC 중에는 기본 키가 포함된 테이블에서만 NCLOB 데이터 형식을 AWS DMS 지원합니다.  | 
|  GEOMETRY  |  이 데이터 형식을 지원하는 대상 엔드포인트에 복제할 때에는 GEOMETRY를 사용합니다. 이 데이터 형식을 지원하지 않는 대상 엔드포인트에 복제할 때에는 CLOB를 사용합니다.  | 
|  GEOGRAPHY  |  이 데이터 형식을 지원하는 대상 엔드포인트에 복제할 때에는 GEOGRAPHY를 사용합니다. 이 데이터 형식을 지원하지 않는 대상 엔드포인트에 복제할 때에는 CLOB를 사용합니다.  | 

AWS DMS 는 다음 데이터 형식의 필드가 포함된 테이블을 지원하지 않습니다.
+ CURSOR
+ SQL\$1VARIANT
+ TABLE

**참고**  
사용자 정의 데이터 형식은 그 기반 유형에 따라 지원됩니다. 예를 들어, DATETIME을 기반으로 한 사용자 정의 데이터는 DATETIME 데이터 형식으로 처리됩니다.

# SQL Server에서 지속적인 복제를 위한 데이터 변경 사항 캡처
<a name="CHAP_Source.SQLServer.CDC"></a>

이 주제에서는 SQL Server 소스에서 CDC 복제를 설정하는 방법을 설명합니다.

**Topics**
+ [온프레미스 또는 Amazon EC2에서 자체 관리형 SQL Server의 데이터 변경 캡처](#CHAP_Source.SQLServer.CDC.Selfmanaged)
+ [클라우드 SQL Server DB 인스턴스에서 지속적 복제 설정](#CHAP_Source.SQLServer.Configuration)

## 온프레미스 또는 Amazon EC2에서 자체 관리형 SQL Server의 데이터 변경 캡처
<a name="CHAP_Source.SQLServer.CDC.Selfmanaged"></a>

소스 Microsoft SQL Server 데이터베이스에서 변경 내용을 캡처하려면 데이터베이스가 전체 백업을 수행하도록 구성되어 있어야 합니다. 데이터베이스를 전체 복구 모드 또는 대량 로그 모드로 구성합니다.

자체 관리형 SQL Server 소스의 경우 다음을 AWS DMS 사용합니다.

**MS-REPLICATION**  
프라이머리 키가 있는 테이블의 변경 사항을 캡처합니다. 소스 SQL Server 인스턴스의 AWS DMS 엔드포인트 사용자에게 sysadmin 권한을 부여하여 이를 자동으로 구성할 수 있습니다. 또는이 섹션의 단계에 따라 소스를 준비하고 AWS DMS 엔드포인트에 대한 sysadmin 권한이 없는 사용자를 사용할 수 있습니다.

**MS-CDC**  
프라이머리 키가 없는 테이블의 변경 사항을 캡처합니다. 데이터베이스 수준에서 모든 테이블에 대해 개별적으로 MS-CDC를 활성화합니다.

지속적 복제(CDC)를 위해 SQL Server 데이터베이스를 설정할 때 다음 중 하나를 수행할 수 있습니다.
+ sysadmin 역할을 사용하여 지속적 복제를 설정합니다.
+ sysadmin 역할을 사용하지 않도록 지속적 복제를 설정합니다.

**참고**  
다음 스크립트를 사용하여 프라이머리 키 또는 고유 키가 없는 모든 테이블을 찾을 수 있습니다.  

```
USE [DBname]
SELECT SCHEMA_NAME(schema_id) AS schema_name, name AS table_name
FROM sys.tables
WHERE OBJECTPROPERTY(object_id, 'TableHasPrimaryKey') = 0
        AND  OBJECTPROPERTY(object_id, 'TableHasUniqueCnst') = 0
ORDER BY schema_name, table_name;
```

### 자체 관리형 SQL Server에서 지속적 복제 설정
<a name="CHAP_Source.SQLServer.CDC.MSCDC"></a>

이 섹션에는 sysadmin 역할을 사용하거나 사용하지 않고 자체 관리형 SQL 서버에서 지속적 복제를 설정하는 방법에 대한 정보가 나와 있습니다.

**Topics**
+ [자체 관리형 SQL Server에서 지속적 복제 설정: sysadmin 역할 사용](#CHAP_Source.SQLServer.CDC.MSCDC.Sysadmin)
+ [독립 실행형 SQL Server에서 지속적 복제 설정: sysadmin 역할 없음](#CHAP_SupportScripts.SQLServer.standalone)
+ [가용성 그룹 환경의 SQL Server에서 지속적 복제 설정: sysadmin 역할 없음](#CHAP_SupportScripts.SQLServer.ag)

#### 자체 관리형 SQL Server에서 지속적 복제 설정: sysadmin 역할 사용
<a name="CHAP_Source.SQLServer.CDC.MSCDC.Sysadmin"></a>

AWS DMS SQL Server에 대한 지속적 복제는 기본 키가 있는 테이블에는 네이티브 SQL Server 복제를 사용하고 기본 키가 없는 테이블에는 변경 데이터 캡처(CDC)를 사용합니다.

지속적 복제를 설정하기 전에 [SQL Server 소스에서 지속적 복제(CDC) 사용을 위한 사전 요구 사항](CHAP_Source.SQLServer.md#CHAP_Source.SQLServer.Prerequisites) 섹션을 참조하세요.

기본 키가 있는 테이블의 경우 AWS DMS 는 일반적으로 소스에 필요한 아티팩트를 구성할 수 있습니다. 하지만 자체 관리형인 SQL Server 소스 인스턴스의 경우, 먼저 SQL Server 배포를 수동으로 구성해야 합니다. 이렇게 하면 sysadmin 권한이 있는 AWS DMS 소스 사용자가 기본 키가 있는 테이블에 대한 게시를 자동으로 생성할 수 있습니다.

배포가 이미 구성되어 있는지 확인하려면 다음 명령을 실행합니다.

```
sp_get_distributor
```

열 배포 결과가 `NULL`인 경우 배포가 구성되지 않은 것입니다. 다음 절차에 따라 배포를 설정할 수 있습니다.<a name="CHAP_Source.SQLServer.CDC.MSCDC.Setup"></a>

**배포를 설정하려면**

1. SQL Server Management Studio(SSMS) 도구를 사용하여 SQL Server 소스 데이터베이스에 연결합니다.

1. **복제** 폴더의 컨텍스트 메뉴(마우스 오른쪽 버튼 클릭)를 열고 **배포 구성**을 선택합니다. 배포 구성 마법사가 나타납니다.

1. 마법사에 따라 기본값을 입력하고 배포를 생성합니다.<a name="CHAP_Source.SQLServer.CDC.MSCDC.Setup.CDC"></a>

**CDC를 설정하려면**

AWS DMS 버전 3.4.7 이상에서는 읽기 전용 복제본을 사용하지 않는 경우 데이터베이스 및 모든 테이블에 대해 MS CDC를 자동으로 설정할 수 있습니다. 이 기능을 사용하려면 `SetUpMsCdcForTables` ECA를 true로 설정합니다. ECA에 대한 자세한 내용은 [엔드포인트 설정](CHAP_Source.SQLServer.md#CHAP_Source.SQLServer.ConnectionAttrib) 섹션을 참조하세요.

3.4.7 AWS DMS 이전 버전 또는 소스로서 읽기 전용 복제본의 경우 다음 단계를 수행합니다.

1. 프라이머리 키가 없는 테이블의 경우, 데이터베이스에 MS-CDC를 설정합니다. 이렇게 하려면 sysadmin 역할이 할당된 계정을 사용하고 다음 명령을 실행합니다.

   ```
   use [DBname]
   EXEC sys.sp_cdc_enable_db
   ```

1. 다음으로, 각 소스 테이블마다 MS-CDC를 설정합니다. 고유 키는 있지만 프라이머리 키가 없는 각 테이블마다 다음 쿼리를 실행하여 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
   ```

1. 프라이머리 키가 없거나 고유 키가 없는 각 테이블마다 다음 쿼리를 실행하여 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 Server 설명서](https://msdn.microsoft.com/en-us/library/cc627369.aspx)를 참조하세요.

#### 독립 실행형 SQL Server에서 지속적 복제 설정: sysadmin 역할 없음
<a name="CHAP_SupportScripts.SQLServer.standalone"></a>

이 섹션에서는 사용자 계정에 sysadmin 권한이 필요 없는 SQL Server 데이터베이스 소스에 대해 지속적 복제를 설정하는 방법을 설명합니다.

**참고**  
sysadmin이 아닌 DMS 사용자는 이 섹션의 단계를 실행한 후 다음을 수행할 수 있는 권한을 갖게 됩니다.  
온라인 트랜잭션 로그 파일에서 변경 사항 읽기
트랜잭션 로그 백업 파일의 변경 사항을 읽을 수 있는 디스크 액세스
DMS에서 사용하는 게시물 추가 또는 변경
게시물에 문서 추가

1. [SQL Server에서 지속적인 복제를 위한 데이터 변경 사항 캡처](#CHAP_Source.SQLServer.CDC)에 설명된 대로 복제를 위해 Microsoft SQL Server를 설정합니다.

1. 소스 데이터베이스에서 MS-REPLICATION을 활성화합니다. 이 작업은 수동으로 수행하거나, sysadmin 사용자로 태스크를 한 번 실행하여 수행할 수 있습니다.

1. 아래의 스크립트를 사용하여 소스 데이터베이스에서 `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
   ```

1. 아래의 스크립트를 사용하여 마스터 데이터베이스에서 `[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
   ```

1. 아래의 스크립트를 사용하여 마스터 데이터베이스에서 인증서를 생성합니다.

   ```
   Use [master]
   Go
   
   CREATE CERTIFICATE [awsdms_rtm_dump_dblog_cert] ENCRYPTION BY PASSWORD = N'@5trongpassword'
   
   WITH SUBJECT = N'Certificate for FN_DUMP_DBLOG Permissions';
   ```

1. 아래의 스크립트를 사용하여 인증서에서 로그인을 생성합니다.

   ```
   Use [master]
   Go
   
   CREATE LOGIN awsdms_rtm_dump_dblog_login FROM CERTIFICATE [awsdms_rtm_dump_dblog_cert];
   ```

1. 아래의 스크립트를 사용하여 sysadmin 서버 역할에 로그인을 추가합니다.

   ```
   ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_dump_dblog_login];
   ```

1. 아래의 스크립트를 사용하여 [master].[awsdms].[rtm\$1dump\$1dblog]에 서명을 추가합니다.

   ```
   Use [master]
   GO
   ADD SIGNATURE
   TO [master].[awsdms].[rtm_dump_dblog] BY CERTIFICATE [awsdms_rtm_dump_dblog_cert] WITH PASSWORD = '@5trongpassword';
   ```
**참고**  
저장된 프로시저를 다시 생성할 경우 서명을 다시 추가해야 합니다.

1. 아래의 스크립트를 사용하여 마스터 데이터베이스에 [awsdms].[rtm\$1position\$11st\$1timestamp]를 생성합니다.

   ```
   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
   ```

1. 아래의 스크립트를 사용하여 마스터 데이터베이스에서 인증서를 생성합니다.

   ```
   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';
   ```

1. 아래의 스크립트를 사용하여 인증서에서 로그인을 생성합니다.

   ```
   Use [master]
   Go
   CREATE LOGIN awsdms_rtm_position_1st_timestamp_login FROM CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert];
   ```

1. 아래의 스크립트를 사용하여 sysadmin 역할에 로그인을 추가합니다.

   ```
   ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_position_1st_timestamp_login];
   ```

1. 아래의 스크립트를 사용하여 인증서를 통해 [master].[awsdms].[rtm\$1position\$11st\$1timestamp]에 서명을 추가합니다.

   ```
   Use [master]
       GO
       ADD SIGNATURE
       TO [master].[awsdms].[rtm_position_1st_timestamp]
       BY CERTIFICATE [awsdms_rtm_position_1st_timestamp_cert]
       WITH PASSWORD = '@5trongpassword';
   ```

1. 아래의 스크립트를 사용하여 DMS 사용자에게 새 저장 프로시저에 대한 실행 액세스 권한을 부여합니다.

   ```
   use master
   go
   GRANT execute on [awsdms].[rtm_position_1st_timestamp] to dms_user;
   ```

1. 다음 각 데이터베이스에서 다음과 같은 권한 및 역할을 보유한 사용자를 생성합니다.
**참고**  
각 복제본에서 동일한 SID를 사용하여 dmsnosysadmin 사용자 계정을 생성해야 합니다. 아래의 SQL 쿼리는 각 복제본에서 dmsnosysadmin 계정 SID 값을 확인하는 데 도움이 될 수 있습니다. 사용자 생성에 대한 자세한 내용은 [Microsoft SQL 서버 설명서](https://learn.microsoft.com/en-us/sql/)의 [CREATE USER (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-user-transact-sql) 섹션을 참조하세요. Azure SQL 데이터베이스의 SQL 사용자 계정 생성에 대한 자세한 내용은 [활성 geo-replication](https://learn.microsoft.com/en-us/azure/azure-sql/database/active-geo-replication-overview) 섹션을 참조하세요.

   ```
   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 self_managed_user
   grant select on msdb.dbo.backupmediafamily to self_managed_user
   grant select on msdb.dbo.backupfile to self_managed_user
   ```

   소스 데이터베이스에서 다음과 같은 스크립트를 실행합니다.

   ```
   use Source_DB
       Go
       EXEC sp_addrolemember N'db_owner', N'DMS_user'
   ```

1. 마지막으로, 소스 SQL Server 엔드포인트에 추가 연결 속성(ECA)을 추가합니다.

   ```
   enableNonSysadminWrapper=true;
   ```

#### 가용성 그룹 환경의 SQL Server에서 지속적 복제 설정: sysadmin 역할 없음
<a name="CHAP_SupportScripts.SQLServer.ag"></a>

이 섹션에서는 사용자 계정에 sysadmin 권한이 필요 없는 가용성 그룹 환경의 SQL Server 데이터베이스 소스에 대해 지속적 복제를 설정하는 방법을 설명합니다.

**참고**  
sysadmin이 아닌 DMS 사용자는 이 섹션의 단계를 실행한 후 다음을 수행할 수 있는 권한을 갖게 됩니다.  
온라인 트랜잭션 로그 파일에서 변경 사항 읽기
트랜잭션 로그 백업 파일의 변경 사항을 읽을 수 있는 디스크 액세스
DMS에서 사용하는 게시물 추가 또는 변경
게시물에 문서 추가

**가용성 그룹 환경에서 sysadmin 사용자를 사용하지 않고 지속적 복제를 설정하려면**

1. [SQL Server에서 지속적인 복제를 위한 데이터 변경 사항 캡처](#CHAP_Source.SQLServer.CDC)에 설명된 대로 복제를 위해 Microsoft SQL Server를 설정합니다.

1. 소스 데이터베이스에서 MS-REPLICATION을 활성화합니다. 이 작업은 수동으로 수행하거나, sysadmin 사용자를 통해 태스크를 한 번 실행하여 수행할 수 있습니다.
**참고**  
MS-REPLICATION 배포자를 로컬로 구성하거나, 연결된 서버를 통해 sysadmin 이외의 사용자가 액세스할 수 있는 방식으로 구성해야 합니다.

1. **단일 태스크 내에서 sp\$1repldone을 단독으로 사용** 엔드포인트 옵션이 활성화된 경우, MS-REPLICATION Log Reader 작업을 중지합니다.

1. 각각의 복제에서 다음 단계를 수행합니다.

   1. 마스터 데이터베이스에서 `[awsdms]`[awsdms] 스키마를 생성합니다.

      ```
      CREATE SCHEMA [awsdms]
      ```

   1. 마스터 데이터베이스에서 `[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
      ```

   1. 마스터 데이터베이스에서 `[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
      ```

   1. 마스터 데이터베이스에서 인증서를 생성합니다.

      ```
      USE [master]
      GO
      CREATE CERTIFICATE [awsdms_rtm_dump_dblog_cert]
        ENCRYPTION BY PASSWORD = N'@hardpassword1'
        WITH SUBJECT = N'Certificate for FN_DUMP_DBLOG Permissions'
      ```

   1. 인증서에서 로그인을 생성합니다.

      ```
      USE [master]
      GO
      CREATE LOGIN awsdms_rtm_dump_dblog_login FROM CERTIFICATE
        [awsdms_rtm_dump_dblog_cert];
      ```

   1. sysadmin 서버 역할에 로그인을 추가합니다.

      ```
      ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_dump_dblog_login];
      ```

   1. 인증서를 사용하여 [master].[awsdms].[rtm\$1dump\$1dblog] 프로시저에 서명을 추가합니다.

      ```
      USE [master]
      GO
      
      ADD SIGNATURE
        TO [master].[awsdms].[rtm_dump_dblog]
        BY CERTIFICATE [awsdms_rtm_dump_dblog_cert]
        WITH PASSWORD = '@hardpassword1';
      ```
**참고**  
저장된 프로시저를 다시 생성할 경우 서명을 다시 추가해야 합니다.

   1. 마스터 데이터베이스에서 `[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
      ```

   1. 마스터 데이터베이스에서 인증서를 생성합니다.

      ```
      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';
      ```

   1. 인증서에서 로그인을 생성합니다.

      ```
      USE [master]
      GO
      CREATE LOGIN awsdms_rtm_position_1st_timestamp_login FROM CERTIFICATE
        [awsdms_rtm_position_1st_timestamp_cert];
      ```

   1. sysadmin 서버 역할에 로그인을 추가합니다.

      ```
      ALTER SERVER ROLE [sysadmin] ADD MEMBER [awsdms_rtm_position_1st_timestamp_login];
      ```

   1. 인증서를 사용하여 `[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';
      ```
**참고**  
저장된 프로시저를 다시 생성할 경우 서명을 다시 추가해야 합니다.

   1. 다음 각 데이터베이스에서 다음과 같은 권한/역할을 보유한 사용자를 생성합니다.
**참고**  
각 복제본에서 동일한 SID를 사용하여 dmsnosysadmin 사용자 계정을 생성해야 합니다. 아래의 SQL 쿼리는 각 복제본에서 dmsnosysadmin 계정 SID 값을 확인하는 데 도움이 될 수 있습니다. 사용자 생성에 대한 자세한 내용은 [Microsoft SQL 서버 설명서](https://learn.microsoft.com/en-us/sql/)의 [CREATE USER (Transact-SQL)](https://learn.microsoft.com/en-us/sql/t-sql/statements/create-user-transact-sql) 섹션을 참조하세요. Azure SQL 데이터베이스의 SQL 사용자 계정 생성에 대한 자세한 내용은 [활성 geo-replication](https://learn.microsoft.com/en-us/azure/azure-sql/database/active-geo-replication-overview) 섹션을 참조하세요.

      ```
      SELECT @@servername servername, name, sid, create_date, modify_date
        FROM sys.server_principals
        WHERE name = 'dmsnosysadmin';
      ```

   1. 각 복제에서 마스터 데이터베이스에 대한 권한을 부여합니다.

      ```
      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;
      ```

   1. 각 복제에서 msdb 데이터베이스에 대한 권한을 부여합니다.

      ```
      USE msdb
      GO
      GRANT select on msdb.dbo.backupset TO self_managed_user
      GRANT select on msdb.dbo.backupmediafamily TO self_managed_user
      GRANT select on msdb.dbo.backupfile TO self_managed_user
      ```

   1. 소스 데이터베이스에서 `db_owner` 역할을 `dmsnosysadmin`에 추가합니다. 데이터베이스가 동기화되었으므로, 기본 복제에만 역할을 추가할 수 있습니다.

      ```
      use <source DB>
      GO 
      EXEC sp_addrolemember N'db_owner', N'dmsnosysadmin'
      ```

## 클라우드 SQL Server DB 인스턴스에서 지속적 복제 설정
<a name="CHAP_Source.SQLServer.Configuration"></a>

이 섹션에서는 클라우드에 호스팅된 SQL Server 데이터베이스 인스턴스에 CDC를 설정하는 방법을 설명합니다. 클라우드에 호스팅된 SQL 서버 인스턴스는 Amazon RDS for SQL Server, Azure SQL Managed Instance 또는 기타 관리형 클라우드 SQL Server 인스턴스에서 실행되는 인스턴스입니다. 각 데이터베이스 유형에 따른 지속적 복제 제한 사항에 대한 자세한 내용은 [SQL Server를 소스로 사용할 때의 제한 사항 AWS DMS](CHAP_Source.SQLServer.md#CHAP_Source.SQLServer.Limitations) 섹션을 참조하세요.

지속적 복제를 설정하기 전에 [SQL Server 소스에서 지속적 복제(CDC) 사용을 위한 사전 요구 사항](CHAP_Source.SQLServer.md#CHAP_Source.SQLServer.Prerequisites) 섹션을 참조하세요.

자체 관리형 Microsoft SQL Server 소스와 달리 Amazon RDS for SQL Server는 MS-Replication을 지원하지 않습니다. 따라서 기본 키가 있거나 없는 테이블에 MS-CDC를 사용해야 AWS DMS 합니다.

Amazon RDS는 소스 SQL Server 인스턴스의 지속적인 변경에 AWS DMS 가 사용하는 복제 아티팩트를 설정할 수 있는 sysadmin 권한을 부여하지 않습니다. 다음 절차와 같이 Amazon RDS 인스턴스에서 MS-CDC를 켜야 합니다(마스터 사용자 권한 사용).

**클라우드 SQL Server DB 인스턴스에서 MS-CDC를 켜려면**

1. 데이터베이스 수준에서 다음 쿼리 중 하나를 실행합니다.

   RDS for SQL Server DB 인스턴스에는 다음 쿼리를 사용하세요.

   ```
   exec msdb.dbo.rds_cdc_enable_db 'DB_name'
   ```

   Azure SQL 관리형 DB 인스턴스에는 다음 쿼리를 사용하세요.

   ```
   USE DB_name 
   GO 
   EXEC sys.sp_cdc_enable_db 
   GO
   ```

1. 프라이머리 키가 있는 각 테이블마다 다음 쿼리를 실행하여 MS-CDC를 켭니다.

   ```
   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
   ```

1. 보존 기간 설정:
   + DMS 버전 3.5.3 이상을 사용하여 복제하는 RDS for SQL Server 인스턴스의 경우 보존 기간이 기본값인 5초로 설정되어 있는지 확인합니다. DMS 3.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'
     ```
   + `@pollinginterval` 파라미터는 초 단위로 측정되며 권장 값은 86,399로 설정되어 있습니다. 즉, `@pollinginterval = 86399`일 경우 트랜잭션 로그는 86,399초(하루) 동안 변경 사항을 보존합니다. 프로시저 `exec sp_cdc_start_job 'capture'`에서 설정을 시작합니다.
**참고**  
일부 버전의 SQL Server에서는 `pollinginterval` 값을 3,599초 이상으로 설정하면 값이 기본값인 5초로 재설정됩니다. 이 경우가 항목을 AWS DMS 읽기 전에 T-Log 항목이 제거됩니다. 이 알려진 문제의 영향을 받는 SQL Server 버전을 확인하려면 [이 Microsoft KB 문서](https://support.microsoft.com/en-us/topic/kb4459220-fix-incorrect-results-occur-when-you-convert-pollinginterval-parameter-from-seconds-to-hours-in-sys-sp-cdc-scan-in-sql-server-dac8aefe-b60b-7745-f987-582dda2cfa78)를 참조하세요.

     다중 AZ에서 Amazon RDS를 사용하는 경우, 장애 조치 시 보조 AZ도 올바른 값을 갖도록 설정해야 합니다.

     ```
     exec rdsadmin..rds_set_configuration 'cdc_capture_pollinginterval' , <5 or preferred value>
     ```

**AWS DMS 복제 작업이 1시간 이상 중지될 때 보존 기간을 유지하려면**
**참고**  
다음 단계는 DMS 3.5.3 이상을 사용하여 RDS for SQL Server 소스를 복제하는 데 필요하지 않습니다.

1. 다음 명령을 사용하여 트랜잭션 로그를 잘라내는 작업을 중지합니다.

   ```
   exec sp_cdc_stop_job 'capture'
   ```

1.  AWS DMS 콘솔에서 작업을 찾아 작업을 재개합니다.

1. **모니터링** 탭을 선택하고 `CDCLatencySource` 지표를 확인합니다.

1. `CDCLatencySource` 지표가 0이고 그대로 유지되면 다음 명령을 사용하여 트랜잭션 로그를 잘라내는 작업을 다시 시작합니다.

   ```
   exec sp_cdc_start_job 'capture'
   ```

SQL Server 트랜잭션 로그를 잘라내는 작업을 시작해야 한다는 점을 명심하세요. 그렇지 않으면 SQL Server 인스턴스의 스토리지가 꽉 찰 수 있습니다.

### RDS for SQL Server를 소스로 사용할 때 권장되는 설정 AWS DMS
<a name="CHAP_Source.SQLServer.Configuration.Settings"></a>

#### For AWS DMS 3.5.3 이상
<a name="CHAP_Source.SQLServer.Configuration.Settings.353"></a>

**참고**  
RDS for SQL Server 로그 백업 기능의 초기 릴리스는 DMS 버전 3.5.3 릴리스 후 생성하거나 수정한 엔드포인트에 대해 기본적으로 활성화됩니다. 기존 엔드포인트에 이 기능을 사용하려면 변경하지 않고 엔드포인트를 수정합니다.

AWS DMS 버전 3.5.3에는 로그 백업에서 읽기에 대한 지원이 도입되었습니다. DMS는 주로 활성 트랜잭션 로그의 읽기에 의존하여 이벤트를 복제합니다. DMS가 활성 로그에서 트랜잭션을 읽기 전에 백업되는 경우 작업은 온디맨드 방식으로 RDS 백업에 액세스하고 활성 트랜잭션 로그를 따라잡을 때까지 후속 백업 로그에서 읽습니다. DMS가 로그 백업에 액세스할 수 있도록 하려면 RDS 자동 백업 보존 기간을 최소 1일로 설정합니다. 자동 백업 보존 기간 설정에 대한 자세한 내용은 *Amazon RDS 사용 설명서*의 [백업 보존 기간](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER_ManagingAutomatedBackups.html#USER_WorkingWithAutomatedBackups.BackupRetention)을 참조하세요.

로그 백업에 액세스하는 DMS 작업은 RDS 인스턴스의 스토리지를 활용합니다. 태스크는 복제에 필요한 로그 백업에만 액세스합니다. Amazon RDS는 다운로드한 백업을 몇 시간 내에 제거합니다. 이 제거는 Amazon S3 또는 Amazon RDS `RESTORE DATABASE` 기능에 보관된 Amazon RDS 백업에는 영향을 주지 않습니다. DMS를 사용하여 복제하려는 경우 RDS for SQL Server 소스에 추가 스토리지를 할당하는 것이 좋습니다. 필요한 스토리지 양을 추정하는 한 가지 방법은 DMS가 복제를 시작하거나 재개할 백업을 식별하고 RDS `tlog backup` 메타데이터 함수를 사용하여 모든 후속 백업의 파일 크기를 추가하는 것입니다. `tlog backup` 함수에 대한 자세한 내용은 *Amazon RDS 사용 설명서*의 [사용 가능한 트랜잭션 로그 백업 나열](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/USER.SQLServer.AddlFeat.TransactionLogAccess.html#USER.SQLServer.AddlFeat.TransactionLogAccess.Listing)을 참조하세요.

또는 Amazon RDS 인스턴스의 CloudWatch `FreeStorageSpace` 지표를 기반으로 스토리지 자동 크기 조정을 활성화하거나 스토리지 크기 조정을 트리거하도록 선택할 수 있습니다.

트랜잭션 로그 백업의 너무 먼 지점에서 시작하거나 재개하지 않는 것이 좋습니다. SQL Server 인스턴스에 스토리지가 채워질 수 있습니다. 이러한 경우 전체 로드를 시작하는 것이 좋습니다. 트랜잭션 로그 백업에서 복제하는 속도가 활성 트랜잭션 로그에서 읽는 것보다 느립니다. 자세한 내용은 [RDS for SQL Server에 대한 트랜잭션 로그 백업 처리](CHAP_Troubleshooting_Latency_Source_SQLServer.md#CHAP_Troubleshooting_Latency_Source_SQLServer_backup) 단원을 참조하십시오.

로그 백업에 액세스하려면 추가 권한이 필요합니다. 자세한 내용은 [클라우드 SQL Server 데이터베이스에서 지속적인 복제를 위한 권한 설정](CHAP_Source.SQLServer.md#CHAP_Source.SQLServer.Permissions.Cloud) 섹션의 설명을 참조하세요. 태스크 복제를 시작하기 전에 이러한 권한을 부여했는지 확인하세요.

#### For AWS DMS 3.5.2 이하
<a name="CHAP_Source.SQLServer.Configuration.Settings.352"></a>

Amazon RDS for SQL Server를 소스로 사용하는 경우, MS-CDC 캡처 작업은 `maxscans` 및 `maxtrans` 파라미터를 사용합니다. 이러한 파라미터는 MS-CDC 캡처가 트랜잭션 로그에서 수행하는 최대 스캔 수와 각 스캔별로 처리되는 트랜잭션 수를 제어합니다.

트랜잭션 수가 `maxtrans*maxscans`보다 많은 데이터베이스의 경우, `polling_interval` 값을 늘리면 활성 트랜잭션 로그 레코드가 누적될 수 있습니다. 결과적으로 이러한 누적으로 인해 트랜잭션 로그 크기가 증가할 수 있습니다.

 AWS DMS 는 MS-CDC 캡처 작업에 의존하지 않습니다. MS-CDC 캡처 작업은 트랜잭션 로그 항목을 처리된 것으로 표시합니다. 이렇게 하면 트랜잭션 로그 백업 작업이 트랜잭션 로그에서 항목을 제거할 수 있습니다.

트랜잭션 로그의 크기와 MS-CDC 작업의 성공 여부를 모니터링하는 것이 좋습니다. MS-CDC 작업이 실패하면 트랜잭션 로그가 과도하게 증가하여 AWS DMS 복제가 실패할 수 있습니다. 소스 데이터베이스의 `sys.dm_cdc_errors` 동적 관리 뷰를 사용하여 MS-CDC 캡처 작업 오류를 모니터링할 수 있습니다. `DBCC SQLPERF(LOGSPACE)` 관리 명령을 사용하여 트랜잭션 로그 크기를 모니터링할 수 있습니다.

**MS-CDC로 인한 트랜잭션 로그 증가를 해결하려면**

1. `Log Space Used %` 데이터베이스 AWS DMS 가에서 복제되고 있는지 확인하고 지속적으로 증가하는지 확인합니다.

   ```
   DBCC SQLPERF(LOGSPACE)
   ```

1. 트랜잭션 로그 백업 프로세스를 방해하는 요인을 식별합니다.

   ```
   Select log_reuse_wait, log_reuse_wait_desc, name from sys.databases where name = db_name();
   ```

   `log_reuse_wait_desc` 값이 `REPLICATION`과 같으면 MS-CDC의 지연 시간으로 인해 로그 백업 보존이 발생합니다.

1. `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'
   ```

이 문제를 해결하려면 `maxtrans*maxscans`가 매일 소스 데이터베이스에서 AWS DMS 복제되는 테이블에 대해 생성된 평균 이벤트 수와 같`maxtrans`도록 `maxscans` 및 값을 설정합니다.

이러한 파라미터를 권장 값보다 높게 설정하면 캡처 작업은 트랜잭션 로그의 모든 이벤트를 처리합니다. 이러한 파라미터를 권장 값보다 낮게 설정하면 MS-CDC 지연 시간이 늘어나고 트랜잭션 로그가 증가합니다.

워크로드의 변경으로 이벤트 수가 달라지기 때문에 적절한 `maxscans` 값과 `maxtrans` 값을 식별하는 것이 어려울 수 있습니다. 이 경우 MS-CDC 지연 시간에 대한 모니터링을 설정하는 것이 좋습니다. 자세한 내용은 SQL Server 설명서에서 [Monitor the process](https://docs.microsoft.com/en-us/sql/relational-databases/track-changes/administer-and-monitor-change-data-capture-sql-server?view=sql-server-ver15#Monitor)를 참조하세요. 그런 다음 모니터링 결과를 기반으로 `maxtrans`과 `maxscans`를 동적으로 구성합니다.

 AWS DMS 작업이 작업을 재개하거나 계속하는 데 필요한 로그 시퀀스 번호(LSNs)를 찾을 수 없는 경우 작업이 실패하고 전체 재로드가 필요할 수 있습니다.

**참고**  
 AWS DMS 를 사용하여 RDS for SQL Server 소스에서 데이터를 복제하는 경우 Amazon RDS 인스턴스의 중지-시작 이벤트 후 복제를 재개하려고 할 때 오류가 발생할 수 있습니다. 이는 중지-시작 이벤트 후 다시 시작할 때 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` 값을 설정하세요.