Openflow Connector for SQL Server 설정

Openflow Connector for SQL Server 설정 (Set up)

이 페이지에서는 Openflow Connector for SQL Server를 설정하는 방법을 설명해요. SQL Server 인스턴스 준비(변경 추적 활성화), Snowflake 환경 설정, 커넥터 설치·구성까지 전체 절차를 다룹니다.

출처: 문서

본문

기능 — 일반 공급 (Generally Available)

Snowflake 커넥터는 Snowflake Openflow를 사용할 수 있는 모든 리전에서 지원돼요.

  • Openflow Snowflake 배포는 AWS, Azure, GCP Commercial 리전의 모든 계정에서 사용할 수 있어요.
  • BYOC 배포의 Snowflake Openflow는 AWS Commercial 리전의 모든 계정에서만 사용할 수 있어요.

참고

이 커넥터는 Snowflake Connector 약관이 적용돼요.

이 항목에서는 Openflow Connector for SQL Server를 설정하는 방법을 설명해요. 증분 로드 과정에 대한 정보는 증분 복제를 참고해요.

사전 요구 사항 (Prerequisites)

커넥터를 설정하기 전에 다음 사전 요구 사항을 완료했는지 확인해요.

  • Openflow Connector for SQL Server 소개를 검토했는지 확인해요.
  • 지원되는 SQL Server 버전을 검토했는지 확인해요.
  • 런타임 배포를 설정했는지 확인해요. 자세한 내용은 다음 항목을 참고해요.
    • Openflow - Snowflake 배포 설정
    • Openflow - BYOC 설정
  • Openflow - Snowflake 배포를 사용한다면 필수 도메인 구성을 검토하고 SQL Server 커넥터에 필요한 도메인에 접근 권한을 부여했는지 확인해요.

SQL Server 인스턴스 설정 (Set up your SQL Server instance)

커넥터를 설정하기 전에 SQL Server 환경에서 다음 작업을 수행해요.

참고

이 작업들은 데이터베이스 관리자(database administrator)로 수행해야 해요.

  • 복제할 데이터베이스와 테이블에서 변경 추적(change tracking)을 활성화해요. 다음 SQL Server 예시와 같아요.

    ALTER DATABASE <database>
      SET CHANGE_TRACKING = ON
      (CHANGE_RETENTION = 5 DAYS, AUTO_CLEANUP = ON);
    
    ALTER TABLE <schema>.<table>
      ENABLE CHANGE_TRACKING
      WITH (TRACK_COLUMNS_UPDATED = OFF);
    

    참고

    ALTER DATABASE 명령은 데이터베이스당 한 번만 실행해 해당 데이터베이스에서 변경 추적을 활성화해요. 해당 데이터베이스에서 복제할 모든 테이블에 대해 ALTER TABLE 명령을 실행해요.

    중요

    테이블에서 변경 추적을 활성화할 때 TRACK_COLUMNS_UPDATED = OFF(기본값)로 설정해 열 추적 기능을 꺼 두세요. 커넥터는 열 수준 변경 정보를 사용하지 않으므로 TRACK_COLUMNS_UPDATED = ON을 활성화하면 복제에 아무 이점 없이 소스에 불필요한 스토리지와 DML별 오버헤드만 추가돼요.

    각 테이블은 커넥터가 복제하기 전에 변경 추적이 활성화되어 있어야 해요. 복제를 시작하기 전에 복제하려는 모든 테이블에서 변경 추적을 활성화해요.

    중요

    CHANGE_RETENTION을 데이터 연속성을 위해 변경 데이터를 충분히 오래 유지할 수 있는 창으로 설정해요. SQL Server는 추적된 변경 사항을 보존 기간보다 오래되면 제거하므로, 커넥터가 만료 전에 변경 사항을 읽지 못하면 증분으로 복제할 수 없고 해당 테이블은 전체 재로드가 필요해요.

    5일 같은 더 긴 보존 창은 일시 중지된 커넥터, 네트워크 중단, 실패한 복제 주기 같은 문제를 감지하고 대응하며 전체 테이블을 다시 로드하지 않고 완화할 시간을 줘요. 복구하기를 기대하는 가장 긴 중단을 커버하는 값을 선택하되, SQL Server에서 보존된 변경 데이터가 소비하는 추가 스토리지와 균형을 맞춰요.

  • SQL Server 인스턴스용 로그인을 만들어요.

    CREATE LOGIN <user_name> WITH PASSWORD = '<password>';
    

    이 로그인은 복제할 데이터베이스의 사용자를 만드는 데 사용돼요.

  • 복제하는 각 데이터베이스에서 다음 SQL Server 명령을 실행해 사용자를 만들어요.

    USE <source_database>;
    CREATE USER <user_name> FOR LOGIN <user_name>;
    
  • 복제하는 각 데이터베이스의 사용자에게 SELECT와 VIEW CHANGE TRACKING 권한을 부여해요.

    GRANT SELECT ON <database>.<schema>.<table> TO <user_name>;
    GRANT VIEW CHANGE TRACKING ON <database>.<schema>.<table> TO <user_name>;
    

    복제할 모든 테이블에 대해 각 데이터베이스에서 이 명령들을 실행해요. 이 권한은 이전 단계에서 만든 각 데이터베이스의 사용자에게 부여해야 해요.

  • (선택 사항) 사용자 정의 데이터 타입(UDDT)에 대한 VIEW DEFINITION 권한을 부여해요. 테이블에 UDDT를 사용하는 열이 있고 UDDT가 커넥터 사용자와 다른 사용자가 소유한 경우, 다음 SQL Server 예시처럼 커넥터 사용자에게 VIEW DEFINITION 권한을 부여해야 해요.

    GRANT VIEW DEFINITION TO <user_name>;
    

    이 권한이 없으면 UDDT를 사용하는 열은 복제에서 조용히 제외돼요.

  • (선택 사항) SSL 연결을 구성해요. SSL 연결로 SQL Server에 연결한다면 데이터베이스 서버의 루트 인증서를 만들어요. 이는 커넥터 구성 시 필요해요.

Snowflake 환경 설정 (Set up your Snowflake environment)

Openflow 관리자로서 이 커넥터에 대해 다음 작업을 수행해요. 기본 SNOWFLAKE_MANAGED 인증 전략에서는 런타임의 execute-as 역할이 커넥터가 Snowflake에 접근할 때 사용하는 정체성이므로, 이 역할에 권한을 부여해요.

참고

Openflow - BYOC 배포에 커넥터를 배포하고 권장되는 SNOWFLAKE_MANAGED 대신 KEY_PAIR 인증 전략을 사용한다면, 런타임의 관리 토큰에 의존하지 않고 이 동일한 execute-as 역할을 서비스 사용자에게 부여해야 해요. 서비스 사용자를 만들려면 Openflow - BYOC 배포용 키-페어 인증 설정을 참고해요.

  • 복제된 데이터를 저장할 데이터베이스를 만들고 execute-as 역할에 USAGE와 CREATE SCHEMA를 부여해요. 커넥터는 대상 스키마를 자동으로 만들어요. Snowflake는 다른 커넥터를 포함한 다른 데이터 소스와의 충돌을 피하기 위해 커넥터당 전용 대상 데이터베이스를 권장해요. 이 대상 데이터베이스를 런타임, 커넥터, 비밀 같은 Openflow 인프라스트럭처 객체를 보유한 데이터베이스와 분리해 두세요. 커넥터는 소스 스키마와 테이블 이름을 기반으로 대상 객체를 만들므로 그 이름은 사용자가 통제하지 못하며 소스가 변경되면 바뀔 수 있어요.

    CREATE DATABASE IF NOT EXISTS <destination_database>;
    
    GRANT USAGE ON DATABASE <destination_database> TO ROLE OPENFLOW_<RUNTIME_NAME>_EXECUTE_AS_RL;
    GRANT CREATE SCHEMA ON DATABASE <destination_database> TO ROLE OPENFLOW_<RUNTIME_NAME>_EXECUTE_AS_RL;
    
  • 커넥터가 사용할 웨어하우스를 지정하고 execute-as 역할에 USAGE와 OPERATE를 부여해요. XSMALL 웨어하우스 크기로 시작한 다음, 복제되는 테이블 수와 전송되는 데이터 양에 따라 크기를 실험해요. 테이블 수가 많으면 웨어하우스 크기보다는 멀티 클러스터 웨어하우스가 더 잘 확장되는 경향이 있어요.

    CREATE WAREHOUSE <ingest_warehouse>
      WITH
        WAREHOUSE_SIZE = 'XSMALL'
        AUTO_SUSPEND = 300
        AUTO_RESUME = TRUE;
    
    GRANT USAGE, OPERATE ON WAREHOUSE <ingest_warehouse> TO ROLE OPENFLOW_<RUNTIME_NAME>_EXECUTE_AS_RL;
    
  • Snowflake 배포에만 해당: 이 커넥터의 소스 호스트와 포트가 런타임의 외부 접근 통합(external access integration, EAI)이 허용하는 네트워크 규칙에 의해 허용되는지 확인해요. EAI 자체는 이 커넥터가 아니라 런타임에 속해요. 한 번 만들어 런타임에 연결하고 execute-as 역할에 USAGE를 부여해요. 해당 단계는 네트워크 규칙 및 외부 접근 통합 만들기를 참고해요. 이 커넥터에 특정한 것은 소스 호스트를 EAI가 참조하는 규칙에 넣는 것이에요. 규칙은 소스의 호스트와 포트를 db.example.com:<port> 같은 단일 값으로 사용해요. 이는 커넥터 연결 URL의 jdbc: 스킴, 드라이버 이름, 데이터베이스 경로를 제외한 호스트와 포트예요. BYOC 배포는 클라우드 환경에서 아웃바운드 연결을 처리하며 EAI나 네트워크 규칙을 사용하지 않아요.

커넥터 설치 (Install the connector)

데이터 엔지니어로서 커넥터를 설치하려면 다음을 수행해요.

  1. Openflow의 Connector library 탭으로 이동해요.

  2. Openflow 커넥터 페이지에서 커넥터를 찾고 Install을 선택해요.

  3. Select runtime 대화 상자에서 Available runtimes 드롭다운 목록에서 런타임을 선택하고 Install을 클릭해요.

    참고

    커넥터를 설치하기 전에 수집된 데이터를 저장할 데이터베이스와 스키마를 Snowflake에 만들었는지 확인해요.

  4. Snowflake 계정 자격 증명으로 배포에 인증하고, 런타임 애플리케이션이 Snowflake 계정에 접근하도록 허용할지 묻는 메시지가 표시되면 Allow를 선택해요. 커넥터 설치 과정은 완료까지 몇 분 걸려요.

  5. Snowflake 계정 자격 증명으로 런타임에 인증해요.

Openflow 캔버스가 나타나고 커넥터 프로세스 그룹이 추가돼요.

런타임 크기 조정 (Runtime sizing)

노드 유형 계층과 생성 후 크기 조정 방법을 포함한 크기 조정 안내는 CDC 커넥터용 런타임 크기 조정 및 패킹을 참고해요. 마이그레이션 지침은 커넥터 재설치를 참고해요.

커넥터 구성 (Configure the connector)

데이터 엔지니어로서 커넥터를 구성하려면 다음을 수행해요.

  1. 가져온 프로세스 그룹을 마우스 오른쪽 버튼으로 클릭하고 Parameters를 선택해요.
  2. 필요한 매개변수 값을 채워요. 필수 매개변수 값에 대한 자세한 내용은 다음 섹션을 참고해요.
    • SQLServer Source Parameters: SQL Server와 연결을 수립하는 데 사용돼요.
    • SQLServer Destination Parameters: Snowflake와 연결을 수립하는 데 사용돼요.
    • SQLServer Ingestion Parameters: 복제할 테이블을 지정하는 데 사용돼요.

먼저 SQLServer Source Parameters 컨텍스트의 매개변수를 설정한 다음 SQLServer Destination Parameters 컨텍스트를 설정해요. 완료한 뒤 커넥터를 활성화해요. 커넥터는 SQL Server와 Snowflake 둘 다에 연결해 실행을 시작해요. 그러나 복제할 테이블이 명시적으로 구성을 추가될 때까지 커넥터는 어떤 데이터도 복제하지 않아요.

특정 테이블을 복제하도록 구성하려면 SQLServer Ingestion Parameters 컨텍스트를 편집해요. SQLServer Ingestion Parameters 컨텍스트에 변경 사항을 적용하면 커넥터가 구성을 사용하고 모든 테이블에 대해 복제 수명 주기가 시작돼요.

한 런타임에서 여러 CDC 커넥터 인스턴스를 실행하려면 를 참고해요.

참고

DBCPConnectionPool 검증

DBCPConnectionPool 컨트롤러 서비스를 활성화하면 연결 풀을 구성하지만 JDBC 연결을 열지는 않아요.

Openflow 런타임에서 연결을 테스트하려면 컨트롤러 서비스 구성을 열고 Verify를 선택해요. Establish Connection 단계가 성공하는지 확인해요. 이 테스트는 구성된 JDBC URL, 드라이버, 사용자 이름, 암호를 사용해 연결을 열어요.

SQLServer Source Parameters

매개변수 설명
SQLServer Connection URL 소스에 연결하는 데 사용되는 전체 JDBC URL. 독립 실행형 SQL Server 인스턴스 또는 Azure SQL Managed Instance의 경우 URL을 인스턴스에 지정해요. 커넥터는 해당 인스턴스에서 복제할 데이터베이스를 발견해요. jdbc:sqlserver://example.com:1433;encrypt=false. Always On Availability Groups의 경우 Always On Availability Groups를 참고해요. Azure SQL Database의 경우 databaseName 속성을 사용해 URL을 특정 데이터베이스에 지정해요. 복제하려는 데이터베이스당 커넥터 인스턴스를 하나 사용해요. jdbc:sqlserver://your-server.database.windows.net:1433;encrypt=true;databaseName=your_database
SQLServer JDBC Driver Reference asset 확인란을 선택해 SQL Server JDBC 드라이버를 업로드해요.
SQLServer Username 커넥터의 사용자 이름.
SQLServer Password 커넥터의 암호.
SQLServer Query Interval 테이블 변경에 대한 다음 쿼리를 예약하기 전에 경과해야 하는 최소 시간 간격. 증분 복제 중 과도한 쿼리를 방지하기 위한 데이터베이스 폴링 빈도를 제어해요. 기본값: 10초.

참고

NTLMv2를 사용한 Windows 인증으로 연결하려면 SQL Server 소스 매개변수를 다음과 같이 구성해요.

  • SQLServer Connection URL: jdbc:sqlserver://<host>:1433;databaseName=<db>;integratedSecurity=true;authenticationScheme=NTLM;domain=<domain>;
  • SQLServer JDBC Driver: mssql-jdbc JAR을 업로드해요. 드라이버 클래스 이름은 com.microsoft.sqlserver.jdbc.SQLServerDriver예요.
  • SQLServer Username: 도메인 사용자를 입력해요.
  • SQLServer Password: 도메인 암호를 입력해요.

참고

Azure SQL Database는 Azure SQL Managed Instance가 아닌 단일 데이터베이스 PaaS 서비스를 가리켜요.

참고

프록시를 통한 Azure SQL Managed Instance

프록시, Nginx 라우트 또는 다른 중간 호스트를 통해 Azure SQL Managed Instance에 연결한다면 Azure SQL Managed Instance를 Proxy 연결 모드로 구성해요.

Openflow 런타임이 SQL Server 트래픽을 프록시 호스트를 통해 라우팅해야 할 때 Redirect 모드를 사용하지 마세요. Redirect 모드에서 Azure SQL Managed Instance는 JDBC 드라이버에게 다른 백엔드 호스트로 다시 연결하도록 지시할 수 있어요. 그 리다이렉트된 호스트는 Openflow 런타임에 구성된 프록시 라우트를 통해 도달하지 못할 수 있어요.

예를 들어:

  • Openflow가 nginx.example.com:10001에 연결해요.
  • Nginx가 트래픽을 sqlmi.example.database.windows.net:1433으로 전달해요.
  • Redirect 모드의 Azure SQL Managed Instance가 JDBC 드라이버에게 다른 백엔드 호스트로 다시 연결하도록 지시해요.
  • Openflow 런타임이 그 리다이렉트된 호스트에 직접 연결하려 해요.
  • 리다이렉트된 호스트가 프록시를 통해 라우팅되지 않으므로 연결이 실패해요.

모든 SQL Server 트래픽이 원래 프록시 라우트에 유지되어야 한다면 Proxy 모드를 사용해요.

SQLServer Username에는 Azure SQL Managed Instance에 구성된 SQL 로그인을 입력해요.

Always On Availability Groups

커넥터가 개별 복제본 노드가 아니라 가용성 그룹 리스너(그룹의 가상 네트워크 이름)를 통해 연결하도록 구성해요. SQLServer Source Parameters 컨텍스트의 SQLServer Connection URL 매개변수에 리스너 호스트 이름을 설정해요.

Always On Availability Groups는 공유 리스너와 복제본 간 자동 장애 조치를 통해 고가용성을 제공해요. Always On Availability Groups는 SQL Server 트랜잭션 복제와는 별개예요.

경고

복제가 시작된 뒤 연결 대상을 변경하지 마세요. 각 데이터베이스는 자체 복제 위치를 독립적으로 유지하므로, 다른 서버나 리스너로 전환하면 커넥터가 이미 처리된 변경 사항을 추적하지 못할 수 있어요. 이는 데이터 손실을 초래할 수 있어요.

고객 관리형 Azure Private Link Service(PLS)를 통해 SQL Server에 연결한다면 SYSTEM$GET_PRIVATELINK_ENDPOINTS_INFO()가 반환하는 호스트 값을 SQLServer Connection URL의 호스트 이름으로 사용해요. 이는 Snowflake 아웃바운드 개인 연결 엔드포인트가 프로비저닝될 때 제공된 논리적 호스트 이름이에요. PLS 별칭이나 리소스 ID는 프로비저닝 중 Azure 서비스를 식별하지만 JDBC 호스트 이름은 아니에요.

예를 들어:

  • jdbc:sqlserver://<host>:1433;databaseName=<db>

같은 호스트 이름과 포트를 Openflow egress 네트워크 규칙에 추가해요.

TYPE = PRIVATE_HOST_PORT
MODE = EGRESS
VALUE_LIST = ('<host>:1433')

:1433 포트를 명시적으로 포함해요. PRIVATE_HOST_PORT 네트워크 규칙에서 포트를 지정하지 않으면 기본값 443으로 설정되는데, 이는 SQL Server 리스너와 일치하지 않아요.

Snowflake는 이 등록된 호스트 이름을 아웃바운드 개인 엔드포인트를 통해 라우팅해요. Azure에서는 백엔드 라우트, 상태 프로브, SQL Server 리스너, 포트 전달이 같은 포트로 트래픽을 전달하도록 PLS와 그 표준 Load Balancer 또는 Direct Connect 대상을 구성해요.

이 지침은 SQL Server 앞에 있는 고객 관리형 Azure PLS에 적용돼요. 네이티브 Azure SQL Managed Instance 개인 엔드포인트에는 적용되지 않아요.

엔드포인트를 프로비저닝하고 승인하려면(SYSTEM$PROVISION_PRIVATELINK_ENDPOINT 및 Azure 쪽 승인) Microsoft Azure의 외부 네트워크 접근 및 개인 연결과 아웃바운드 네트워크 트래픽용 개인 연결을 참고해요.

장애 조치 동작은 Always On Availability Groups 및 소스 장애 조치를 참고해요.

SQLServer Destination Parameters

매개변수 설명 필수
Destination Database 데이터가 저장되는 데이터베이스. Snowflake에 이미 존재해야 해요. 이름은 대소문자를 구분해요. 따옴표 없는 식별자는 대문자로 제공해요. 예
Destination Schema Pattern 데이터가 저장되는 대상 스키마 이름의 패턴. 스키마가 없으면 커넥터가 만들어요. 다음 선택적 변수를 사용해 수집되는 테이블별로 패턴을 사용자 지정할 수 있어요. ${source.database.name}: 소스 테이블의 데이터베이스. ${source.schema.name}: 소스 테이블의 스키마. ${source.table.name}: 소스 테이블의 이름. 예를 들어 정규화 이름이 source_db.tenant_a.data인 테이블에서 패턴 prefix_${source.database.name}_${source.schema.name}은 prefix_source_db_tenant_a로 계산돼요. 모든 테이블을 단일 스키마로 수집하려면 변수 없는 스키마 이름(예: destination_schema)을 제공해요. 중요: 커넥터가 데이터를 수집하기 시작한 뒤에는 이 설정을 변경하지 마세요. 수집 시작 후 이 설정을 변경하면 기존 수집이 깨져요. 이 설정을 변경해야 한다면 새 커넥터 인스턴스를 만들어요. 예
Snowflake Authentication Strategy 사용할 때: Snowflake Openflow Deployment 또는 BYOC: SNOWFLAKE_MANAGED 사용. 이 토큰은 Snowflake가 자동으로 관리해요. BYOC 배포는 SNOWFLAKE_MANAGED를 쓰려면 먼저 execute-as 역할을 구성해야 해요. BYOC: 선택적으로 BYOC는 인증 전략 값으로 KEY_PAIR를 사용할 수 있어요. 예
Snowflake Account Identifier 사용할 때: SNOWFLAKE_MANAGED 인증 전략 → 비어 있어야 해요. KEY_PAIR → [organization-name]-[account-name] 형식의 Snowflake 계정 이름. 예
Snowflake Connection Strategy KEY_PAIR를 사용할 때 Snowflake에 연결하는 전략을 지정해요: STANDARD(기본값): 표준 공용 라우팅으로 Snowflake 서비스에 연결해요. PRIVATE_CONNECTIVITY: AWS PrivateLink 같은 지원 클라우드 플랫폼과 연관된 개인 주소로 연결해요. KEY_PAIR가 있는 BYOC에만 필수, 그 외에는 무시.
Snowflake Object Identifier Resolution 소스 객체 식별자(예: 스키마, 테이블, 열 이름)가 Snowflake에서 저장되고 쿼리되는 방식을 지정해요. SQL 쿼리에서 큰따옴표를 사용해야 하는지 여부를 결정해요. 옵션 1: 기본값, 대소문자 구분 없음(권장): 변환: 모든 식별자가 대문자로 변환돼요. 예: My_Table → MY_TABLE. 쿼리: SQL 쿼리는 대소문자를 구분하지 않으며 SQL 큰따옴표가 필요하지 않아요. 예: SELECT * FROM my_table;은 SELECT * FROM MY_TABLE;과 같은 결과를 반환해요. 참고: 데이터베이스 객체에 혼합 대소문자 이름이 예상되지 않는다면 이 옵션을 권장해요. 중요: 커넥터 수집이 시작된 뒤에는 이 설정을 변경하지 마세요. 수집 시작 후 이 설정을 변경하면 기존 수집이 깨져요. 변경해야 한다면 새 커넥터 인스턴스를 만들어요. 옵션 2: 대소문자 구분: 변환: 대소문자가 보존돼요. 예: My_Table은 My_Table로 유지돼요. 쿼리: SQL 쿼리는 데이터베이스 객체의 정확한 대소문자를 일치시키기 위해 큰따옴표를 사용해야 해요. 예: SELECT * FROM "My_Table";. 참고: 레거시 또는 호환성 이유로 소스 대소문자를 보존해야 한다면 이 옵션을 권장해요. 예를 들어 소스 데이터베이스가 MY_TABLE과 my_table처럼 대소문자만 다른 테이블 이름을 포함하면, 대소문자 구분 없는 비교에서 이름 충돌이 발생해요. 예
Snowflake Private Key 사용할 때: SNOWFLAKE_MANAGED 인증 전략 → 비어 있어야 해요. KEY_PAIR → 인증에 사용되는 RSA 개인 키로, PKCS8 표준에 따라 형식화되고 표준 PEM 헤더/푸터를 포함해야 해요. Snowflake Private Key File 또는 Snowflake Private Key 중 하나는 반드시 정의해야 해요. 아니요
Snowflake Private Key File 사용할 때: SNOWFLAKE_MANAGED 인증 전략 → 개인 키 파일은 비어 있어야 해요. KEY_PAIR → 인증에 사용되는 RSA 개인 키가 포함된 파일을 업로드해요. PKCS8 표준에 따라 형식화되고 표준 PEM 헤더/푸터를 포함해야 해요. 헤더 줄은 -----BEGIN PRIVATE로 시작해요. 개인 키 파일을 업로드하려면 Reference asset 확인란을 선택해요. 아니요
Snowflake Private Key Password 사용할 때: SNOWFLAKE_MANAGED 인증 전략 → 비어 있어야 해요. KEY_PAIR → Snowflake Private Key File과 연결된 암호를 제공해요. 아니요
Snowflake Role 사용할 때: SNOWFLAKE_MANAGED 인증 전략 → 런타임의 execute-as 역할(또는 그 역할에 부여된 하위 역할)을 사용해요. Openflow UI에서 런타임의 View Details로 이동해 execute-as 역할을 찾을 수 있어요. KEY_PAIR → 서비스 사용자에게 구성된 유효한 역할을 사용해요. 예
Snowflake Username 사용할 때: SNOWFLAKE_MANAGED 인증 전략 → 비어 있어야 해요. KEY_PAIR → Snowflake 인스턴스에 연결하는 데 사용되는 사용자 이름을 제공해요. 예
Oversized Value Strategy 복제 중 내부 크기 한도(16 MB)를 초과하는 값을 커넥터가 처리하는 방식을 결정해요. 가능한 값: Fail Table(기본값): 테이블이 영구 실패로 표시되고 해당 테이블의 복제가 중지돼요. Set Null: 값이 대상 테이블에서 NULL로 대체돼요. 대용량 값을 초과하는 테이블에서 데이터 손실을 허용할 수 있을 때 테이블 실패를 방지하려면 이를 사용해요. 아니요
Table Storage Format 표준 Snowflake 테이블 또는 Iceberg 테이블. 기본값은 STANDARD. 커넥터 시작 후에는 변경하지 마세요. 예
Iceberg Version Iceberg 테이블 버전, 2 또는 3(기본값 3). Table Storage Format이 ICEBERG인 경우에만 적용돼요. 수집 시작 후에는 이 값을 변경하지 마세요. 아니요
Snowflake Warehouse 쿼리를 실행하는 데 사용되는 Snowflake 웨어하우스. 예

다음 대상 매개변수는 커넥터가 잘못된 행을 처리하는 방식을 제어해요.

매개변수 설명 필수
Error Handling Strategy 수집 중 Snowflake가 거부하는 잘못된 행을 커넥터가 처리하는 방식을 결정해요. 가능한 값: Fail Table(기본값): 첫 번째 잘못된 행에서 테이블이 실패로 표시되고 해당 테이블의 복제가 중지돼요. Log Errors and Continue: 커넥터가 유효한 행을 계속 복제하고 각 거부된 행을 테이블의 오류 테이블에 기록해요. 자세한 내용은 잘못된 행에 대한 오류 처리를 참고해요. 아니요
  • Fail Table(기본값): 첫 번째 잘못된 행에서 테이블이 실패로 표시되고 해당 테이블의 복제가 중지돼요.
  • Log Errors and Continue: 커넥터가 유효한 행을 계속 복제하고 각 거부된 행을 테이블의 오류 테이블에 기록해요.

자세한 내용은 잘못된 행에 대한 오류 처리를 참고해요.

SQLServer Ingestion Parameters

매개변수 설명
Column Filter JSON 선택 사항. 테이블별로 포함/제외할 열을 지정하는 필터 객체의 JSON 배열. 문법 세부 사항과 예시는 테이블의 열 하위 집합 복제를 참고해요.
Concurrent Select Queries For Incremental 증분 복제 중 소스 데이터베이스에 대해 실행할 동시 SELECT 쿼리의 최대 수. 기본값: 1, 최대값: 8. 증가시키면 많은 테이블이 활성 상태일 때 복제 속도를 높일 수 있지만 소스 데이터베이스의 부하도 증가해요.
Concurrent Select Queries For Snapshot Snapshot 플로우에서 소스 데이터베이스에 대해 실행할 동시 쿼리의 최대 수. 증가시키면 많은 수의 테이블 스냅샷 속도를 높일 수 있지만 소스 데이터베이스의 부하도 증가해요.
Included Table Names 소스 테이블 경로의 쉼표로 구분된 목록(데이터베이스와 스키마 포함). 예: database_1.public.table_1, database_2.schema_2.table_2
Included Table Regex 데이터베이스와 스키마 이름을 포함해 테이블 경로와 일치시키는 정규 표현식. 표현식과 일치하는 모든 경로가 복제되고, 나중에 만든 일치하는 새 테이블도 자동으로 포함돼요. 예: database_name\\.public\\.auto_.*
Ingestion Type 새로 추가된 테이블이 증분 복제로 전환되기 전에 전체 초기 스냅샷을 거칠지, 아니면 바로 증분 복제로 건너뛸지를 제어해요. full(기본값)로 설정하면 스냅샷 후 증분 복제. incremental로 설정하면 새로 추가된 테이블의 스냅샷을 건너뛰고 이후 변경만 복제해요. 이 값을 변경해도 이미 복제를 시작한 테이블에는 영향을 주지 않아요. 사용 메모는 스냅샷 없는 증분 복제 설정을 참고해요.
Max Batch Size 단일 배치에서 가져올 최대 행 수. 기본값: 100000.
Merge Task Schedule CRON Journal에서 Destination Table로의 병합 작업이 트리거되는 기간을 정의하는 CRON 표현식. 지속적인 병합을 원하면 * * * * * ?로 설정하고, 웨어하우스 실행 시간을 제한하려면 시간 일정을 구성해요. 커넥터는 이 일정을 UTC 표준시로 평가해요. 예: 문자열 * 0 * * * ?은 정각에 1분 동안 병합을 예약하고 싶다는 뜻이에요. 문자열 * 20 14 ? * MON-FRI는 매주 월요일부터 금요일 오후 2시 20분에 병합을 예약하고 싶다는 뜻이에요. 추가 정보와 예시는 Quartz 문서의 cron 트리거 튜토리얼을 참고해요.
Re-read Tables in State Starting Change Tracking Position이 Earliest일 때만 적용돼요. New(기본값): 시작 위치가 Earliest로 전환된 뒤 추가된 새 테이블만 가장 이른 위치부터 변경 추적 테이블을 읽어요. 구성 변경 전에 복제를 시작한 테이블은 마지막 위치부터 계속 읽어요. Any active: 현재 복제 중인 모든 테이블의 변경 사항을 다시 읽고 다시 처리해요. 자세한 내용은 변경 추적 테이블 위치에서 로드 지정을 참고해요.
Re-snapshot Table Exclusions 포함 기준과 일치하는 테이블 중에서 복제하지 않아야 하는 정규화된 테이블 이름의 쉼표로 구분된 목록. Included Table Names와 같은 형식과 인용 규칙을 사용해요. 예: database_1.public.table_1.
SQL Server Read Timeout 스냅샷과 증분 쿼리 둘 다에 적용되는 읽기 타임아웃(밀리초). 이 값보다 오래 실행되는 쿼리는 SQL Server가 종료해요. 기본값: 60000.
Starting Change Tracking Position Latest(기본값): 변경 추적 테이블 읽기가 사용 가능한 최신 위치에서 시작해 거기서부터 계속돼요. Earliest: 증분 로드가 사용 가능한 가장 이른 변경 추적 테이블 위치부터 시작하거나 다시 읽도록 전환해요. 자세한 내용은 변경 추적 테이블 위치에서 로드 지정을 참고해요.

SNAPSHOT 격리 하에서 소스 읽기 (Read the source under SNAPSHOT isolation)

커넥터는 스냅샷과 증분 복제 둘 다에서 소스 테이블을 읽어요. SQL Server의 기본 READ COMMITTED 격리 수준에서는 이러한 읽기가 공유 잠금을 획득하여 다른 데이터베이스 클라이언트의 동시 쓰기와 교착 상태(deadlock)가 될 수 있어요. 다른 애플리케이션이 사용하는 격리 수준에 영향을 주지 않으면서 교착 상태를 피하려면, 커넥터가 SNAPSHOT 격리 하에서 읽도록 구성해요. 배경은 소스 데이터베이스 잠금 동작을 참고해요.

두 단계로 커넥터에 SNAPSHOT 격리를 활성화해요.

  • 각 소스 데이터베이스에서 스냅샷 격리를 허용해요.

    ALTER DATABASE <database> SET ALLOW_SNAPSHOT_ISOLATION ON;
    
  • 커넥터의 프로세서에 Use Snapshot Isolation이라는 값이 true인 동적 속성을 추가해요. 커넥터는 스냅샷과 증분 복제 둘 다에서 소스 테이블을 읽으므로 MultiDatabaseFetchTableSnapshot 프로세서와 MultiDatabaseCaptureChangeSqlServer 프로세서 둘 다에 이 동적 속성을 추가해요.

커넥터는 시작할 때 각 소스 데이터베이스를 확인하고 ALLOW_SNAPSHOT_ISOLATION이 활성화된 데이터베이스에 대해서만 SNAPSHOT 격리를 사용해요. 활성화되지 않은 데이터베이스의 경우 커넥터는 기본 격리 수준으로 폴백해요. 이 검사는 시작 시 실행되므로 ALLOW_SNAPSHOT_ISOLATION을 변경한 뒤에는 프로세서를 다시 시작해요.

주의

ALLOW_SNAPSHOT_ISOLATION은 SNAPSHOT 격리를 명시적으로 요청하는 세션(예: 커넥터)에서만 사용 가능하게 해요. 기본 READ COMMITTED 격리 수준을 변경하지 않으므로 소스 데이터베이스를 사용하는 다른 애플리케이션에는 영향이 없어요.

이 목적으로 READ_COMMITTED_SNAPSHOT(RCSI)을 사용하지 마세요. RCSI도 공유 잠금을 제거하지만 데이터베이스에 대한 모든 연결의 기본 READ COMMITTED 격리 수준을 재정의해요. 기본 잠금 기반 READ COMMITTED 동작에 의존하는 애플리케이션(예: 읽기가 동시 미커밋 쓰기를 차단할 것으로 기대하는 경우)은 변경 후 다른 결과를 볼 수 있어요.

SQL Server 복제본 서버에서 테이블 복제 (Replicate tables from a SQL Server replica server)

커넥터는 트랜잭션 복제를 사용해 주 서버 또는 구독자(subscriber) 서버에서 데이터를 수집할 수 있어요. SQL Server 복제본에 연결하도록 커넥터를 구성하기 전에 주 노드와 복제본 노드 간 복제가 올바르게 작동하는지 확인해요. 트랜잭션 복제 설정 지침은 튜토리얼: 트랜잭션 복제 구성을 참고해요. 커넥터에서 누락된 데이터 문제를 조사할 때는 먼저 커넥터가 사용하는 복제본 서버에 누락된 행과 변경 추적 이벤트가 있는지 확인해요.

참고

복제본 서버를 사용할 때 커넥터 설정은 표준 주 서버 구성과 다르게 돼요. 연결 사용자와 변경 추적은 주 서버에 구성할 필요가 없어요. 대신 연결 사용자가 복제본 서버에 있고 거기서 데이터와 변경 추적 테이블에 접근할 수 있는지 확인해요.

게시자(publisher) 대신 구독자 서버에서 읽도록 커넥터를 구성하려면 SQLServer Connection URL 매개변수에 구독자 서버 URL을 지정해요.

경고

복제가 시작된 뒤 데이터베이스 서버를 변경하지 마세요. 각 데이터베이스는 변경 추적 상태를 독립적으로 유지하므로 다른 서버로 전환하면 커넥터가 이미 처리된 변경 사항을 추적하지 못하게 되어 데이터 손실이 발생할 수 있어요.

테이블의 열 하위 집합 복제 (Replicate a subset of columns in a table)

커넥터는 테이블별로 복제되는 데이터를 구성된 열의 하위 집합으로 필터링할 수 있어요. 기본 키 열은 제외와 관계없이 항상 포함돼요.

열 필터를 적용하려면 Ingestion Parameters 컨텍스트의 Column Filter JSON 매개변수를 필터할 각 테이블당 하나씩, 필터 객체의 JSON 배열로 설정해요.

열은 이름이나 정규 표현식 패턴으로 포함/제외할 수 있어요. 테이블당 단일 조건을 적용하거나 여러 조건을 결합할 수 있으며, 제외가 항상 포함보다 우선해요.

문법 (Syntax)

배열의 각 객체는 테이블을 식별하고 포함/제외할 열을 지정해요. 이 커넥터는 3부분 정규화 이름(데이터베이스, 스키마, 테이블)을 사용하므로 각 객체는 schema와 table 필드에 더해 database 또는 databasePattern 필드를 포함할 수 있어요.

[
    {
        "database": "<database>" | "databasePattern": "<regex>",
        "schema": "<schema>" | "schemaPattern": "<regex>",
        "table": "<table>" | "tablePattern": "<regex>",
        "included": ["<column>", "<column>"],
        "excluded": ["<column>", "<column>"],
        "includedPattern": "<regex>",
        "excludedPattern": "<regex>"
    }
]

다음 규칙이 적용돼요.

  • 정확한 이름 일치에는 database, schema, table을, 정규 표현식 일치에는 databasePattern, schemaPattern, tablePattern을 사용해요. 같은 객체에서 필드와 그 패턴 변형을 둘 다 사용할 수 없어요(예: schema와 schemaPattern을 둘 다 넣을 수 없음).
  • included, excluded, includedPattern, excludedPattern 중 적어도 하나는 반드시 제공해야 해요.
  • 포함과 제외 필터를 둘 다 지정하면 제외가 우선해요.
  • 여러 필터가 같은 테이블과 일치하면 마지막 일치 필터가 사용되며, 정확한 일치가 패턴 기반 필터보다 우선해요.
  • 값은 다른 테이블에 다른 필터를 적용하는 객체 배열일 수 있어요.

예시 (Examples)

이름으로 특정 열 포함:

[
    {
        "database": "my_db",
        "schema": "dbo",
        "table": "orders",
        "included": ["account_id", "status", "created_at"]
    }
]

이름으로 특정 열 제외:

[
    {
        "database": "my_db",
        "schema": "dbo",
        "table": "orders",
        "excluded": ["internal_note", "debug_flag"]
    }
]

포함 패턴과 특정 제외 결합(예: admin_email을 제외한 모든 이메일 열 포함):

[
    {
        "database": "my_db",
        "schema": "dbo",
        "table": "contacts",
        "includedPattern": ".*_email",
        "excluded": ["admin_email"]
    }
]

데이터베이스 패턴과 정확한 스키마/테이블 이름을 섞어 여러 데이터베이스에 걸쳐 필터 적용:

[
    {
        "databasePattern": "prod_.*",
        "schema": "dbo",
        "table": "customers",
        "excluded": ["internal_note"]
    }
]

여러 필터 객체를 전달해 다른 테이블에 다른 규칙 적용:

[
    {"database": "my_db", "schema": "dbo", "table": "orders", "included": ["account_id", "status"]},
    {"database": "my_db", "schema": "dbo", "table": "customers", "excludedPattern": ".*_internal"}
]

같은 열 포함과 제외

테이블의 복제 세트에서 열을 제거(제외하거나 included 목록에서 제거)하면 대상에서 소스에서 열을 drop하는 것과 같은 효과가 있어요. 커넥터는 접미사(기본값 __SNOWFLAKE_DELETED)로 이름을 바꿔 대상의 열을 소프트 삭제해요. 이후 그 열을 복제 세트에 다시 추가하고 나중에 두 번째로 제거하면, 소프트 삭제된 열 이름이 이미 사용 중이므로 해당 테이블의 복제가 실패해요. 복구하려면 해당 테이블의 복제를 다시 시작해요.

파티션된 테이블 복제 (Replicate a partitioned table)

커넥터는 파티션된 테이블의 복제를 지원해요. SQL Server 파티션된 테이블은 모든 파티션의 데이터를 포함하는 단일 대상 테이블로 Snowflake에 복제돼요.

파티션된 테이블을 복제하려면 SQL Server 인스턴스 설정에서 설명한 대로 파티션된 테이블에서 변경 추적이 활성화되어 있는지 확인해요.

대규모 파티션된 테이블의 스냅샷을 커넥터가 처리하는 방법에 대한 자세한 내용은 파티션된 테이블의 스냅샷을 참고해요.

테이블의 데이터 변경 추적 (Track data changes in tables)

커넥터는 소스 테이블의 현재 데이터 상태와 각 폴링 간격에서 감지된 변경 사항을 복제해요. 이 데이터는 대상 테이블과 같은 스키마에 생성된 저널(journal) 테이블에 저장돼요.

참고

커넥터는 SQL Server 변경 추적을 사용하므로 폴링 간격 사이에 같은 행에 대한 여러 업데이트는 단일 변경으로 롤업돼요. 저널 테이블은 모든 중간 상태가 아니라 변경의 순 결과를 반영해요. 자세한 내용은 Openflow Connector for SQL Server 소개를 참고해요.

저널 테이블 이름은 <source_table_name>_JOURNAL_<timestamp>_<schema_generation> 형식으로 지정돼요. 여기서 <timestamp>는 소스 테이블이 복제에 추가되었을 때의 epoch 초 값이고, <schema_generation>은 소스 테이블의 스키마 변경마다 증가하는 정수예요. 그 결과 스키마 변경을 겪는 소스 테이블은 여러 저널 테이블을 가지게 돼요.

테이블을 복제에서 제거했다가 다시 추가하면 <timestamp> 값이 바뀌고 <schema_generation>은 1부터 다시 시작해요.

중요

Snowflake는 저널 테이블의 구조를 어떤 식으로든 변경하지 않을 것을 권장해요. 커넥터는 복제 과정의 일부로 대상 테이블을 업데이트하는 데 이 테이블들을 사용해요.

커넥터는 저널 테이블을 drop하지 않지만, 복제되는 모든 소스 테이블에 최신 저널을 사용하며 저널 위의 append-only 스트림만 읽어요. 스토리지를 회수하려면 다음을 할 수 있어요.

  • 언제든지 모든 저널 테이블을 truncate해요.
  • 복제에서 제거된 소스 테이블과 관련된 저널 테이블을 drop해요.
  • 활성 복제 테이블에 대해 최신 세대를 제외한 모든 저널 테이블을 drop해요.

예를 들어 커넥터가 소스 테이블 orders를 활발히 복제하고 이전에 테이블 customers를 복제에서 제거했다면 다음 저널 테이블이 있을 수 있어요. 이 경우 orders_5678_2를 제외한 전부를 drop할 수 있어요.

customers_1234_1
customers_1234_2
orders_5678_1
orders_5678_2

병합 작업 스케줄링 구성 (Configure scheduling of merge tasks)

커넥터는 웨어하우스를 사용해 변경 데이터 캡처(CDC) 데이터를 대상 테이블에 병합해요. Merge Journal to Destination이라는 이름의 프로세서가 이 작업을 트리거해요. 새 변경이 없거나 Merge Journal to Destination 큐에 대기 중인 새 FlowFile이 없으면 병합이 트리거되지 않고 웨어하우스는 자동 일시 중지(auto-suspension)가 가능해져요.

웨어하우스 비용을 제한하고 병합을 예약된 시간으로 제한하려면 Merge Task Schedule CRON 매개변수의 CRON 표현식을 사용해요. 이 표현식은 Merge Journal to Destination 프로세서에 도달하는 FlowFile을 조절하므로 지정된 기간 동안에만 병합이 트리거돼요. 커넥터는 이 일정을 UTC 표준시로 평가해요.

추가 정보와 예시는 Quartz 문서의 cron 트리거 튜토리얼을 참고해요.

플로우 실행 (Run the flow)

  • 캔버스를 마우스 오른쪽 버튼으로 클릭하고 Enable all Controller Services를 선택해요.
  • 가져온 프로세스 그룹을 마우스 오른쪽 버튼으로 클릭하고 Start를 선택해요. 커넥터가 데이터 수집을 시작해요.

더 알아보기 (Learn more)