적용 대상: SQL Server 2025(17.x) 미리 보기
이 문서에서는 SQL Server 2025(17.x) 미리 보기에 도입된 CES(변경 이벤트 스트리밍 ) 기능을 구성하는 방법을 설명합니다.
비고
변경 이벤트 스트리밍은 현재 SQL Server 2025용 미리 보기 상태이며 미리 보기 기능 데이터베이스 범위 구성을 사용하도록 설정해야 합니다. 미리 보기 중에 이 기능은 변경될 수 있습니다. 현재 지원 가능성은 제한 사항을 참조하세요.
개요
변경 이벤트 스트리밍을 구성하고 사용하려면 다음 단계를 수행합니다.
- 기존을 사용하거나 새 Azure Event Hubs 네임스페이스 및 Event Hubs 인스턴스를 만듭니다. Event Hubs 인스턴스는 이벤트를 받습니다.
- 사용자 데이터베이스에 대해 변경 이벤트 스트리밍을 사용하도록 설정합니다.
- 이벤트 스트림 그룹을 만듭니다. 이 그룹을 사용하여 대상, 자격 증명, 메시지 크기 제한 및 분할 스키마를 구성합니다.
- 이벤트 스트림 그룹에 하나 이상의 테이블을 추가합니다.
각 단계는 이 문서의 다음 섹션에서 자세히 설명합니다.
필수 조건
변경 이벤트 스트리밍을 구성하려면 다음이 필요합니다.
- Azure Event Hubs 네임스페이스
- Azure Event Hubs 인스턴스
- Azure Event Hubs 호스트 이름
- 액세스 수준 보내기 를 사용하는 정책
- CES를 사용하도록 설정하려는 데이터베이스에 대해 DB_OWNER 역할에 속하거나 CONTROL DATABASE 권한이 있는 로그인입니다.
- 데이터베이스 범위 자격 증명 미리 보기 구성 옵션을 예로 설정합니다.
Azure Event Hubs 구성
Azure Event Hubs를 만드는 방법을 알아보려면 Azure Portal 을 사용하여 이벤트 허브 만들기를 검토합니다.
AMQP 프로토콜(기본값, 네이티브 Azure Event Hubs 프로토콜)을 사용하여 Azure Event Hubs로 스트리밍을 구성하려면 Azure Event Hubs 네임스페이스 및 인스턴스 이름에 대한 SAS 토큰을 생성합니다. 프로그래밍 또는 스크립팅 언어를 사용하여 프로그래밍 방식으로 수행할 수 있습니다. 이 문서의 예제에서는 PowerShell 스크립트를 사용하여 새 정책 또는 기존 정책에서 SAS 토큰을 생성하는 방법을 보여 줍니다.
필수 모듈 설치
PowerShell 스크립트를 사용하여 Azure Event Hubs 리소스를 관리하려면 다음 모듈이 있어야 합니다.
- Az PowerShell 모듈
- Az.EventHub PowerShell 모듈
다음 스크립트는 필요한 모듈을 설치합니다.
Install-Module -Name Az -AllowClobber -Scope CurrentUser -Repository PSGallery -Force
Install-Module -Name Az.EventHub -Scope CurrentUser -Force
필요한 모듈이 이미 있고 최신 버전으로 업데이트하려면 다음 스크립트를 실행합니다.
Update-Module -Name Az -Force
Update-Module -Name Az.EventHub -Force
Azure에 연결
Azure Cloud Shell을 사용하거나 로그인하고 구독 컨텍스트를 설정할 수 있습니다.
Azure Cloud Shell을 사용하여 실행하려면 Azure에 로그인을 검토합니다.
정책 정의
SAS 토큰을 만들려면 정책이 필요합니다. 다음 중 하나를 수행할 수 있습니다.
특정 권한으로 새 정책을 만듭니다.
또는
올바른 권한으로 기존 정책을 사용합니다.
새 정책 또는 기존 정책에 대한 SAS 토큰 만들기
비고
보안 향상을 위해 가능한 한 키 기반 인증보다 SAS 토큰 인증을 사용하는 것이 좋습니다. SAS 토큰의 모범 사례는 적절한 액세스 범위를 정의하고 만료 날짜를 설정하며 SAS 키를 정기적으로 회전하는 것입니다. 키 기반 인증의 경우 키가 주기적으로 회전되는지 확인합니다. Azure Key Vault 또는 유사한 서비스를 사용하여 모든 비밀을 안전하게 저장합니다.
새 정책을 만들 때 보내기 권한이 있는지 확인합니다. 기존 정책을 사용하는 경우 보내기 권한이 있는지 확인합니다.
다음 스크립트는 새 정책을 만들거나 기존 정책을 가져온 다음 HTTP 권한 부여 헤더 형식으로 전체 SAS 토큰을 생성합니다.
꺾쇠 괄호(<value>
)의 값을 사용자 환경에 대한 값으로 대체합니다.
function Generate-SasToken {
$subscriptionId = "<Azure-Subscription-ID>"
$resourceGroupName = "<Resource-group-name>"
$namespaceName = "<Azure-Event-Hub-Namespace-name>"
$eventHubName = "<Azure-Event-Hubs-instance-name>"
$policyName = "<Policy-name>"
# Modifying the rest of the script is not necessary.
# Login to Azure and set Azure Subscription.
Connect-AzAccount
# Get current context and check subscription
$currentContext = Get-AzContext
if ($currentContext.Subscription.Id -ne $subscriptionId) {
Write-Host "Current subscription is $($currentContext.Subscription.Id), switching to $subscriptionId..."
Set-AzContext -SubscriptionId $subscriptionId | Out-Null
} else {
Write-Host "Already using subscription $subscriptionId."
}
# Try to get the authorization policy (it should have Send rights)
$rights = @("Send")
$policy = Get-AzEventHubAuthorizationRule -ResourceGroupName $resourceGroupName -NamespaceName $namespaceName -EventHubName $eventHubName -AuthorizationRuleName $policyName -ErrorAction SilentlyContinue
# If the policy does not exist, create it
if (-not $policy) {
Write-Output "Policy '$policyName' does not exist. Creating it now..."
# Create a new policy with the Manage, Send and Listen rights
$policy = New-AzEventHubAuthorizationRule -ResourceGroupName $resourceGroupName -NamespaceName $namespaceName -EventHubName $eventHubName -AuthorizationRuleName $policyName -Rights $rights
if (-not $policy) {
throw "Error. Policy was not created."
}
Write-Output "Policy '$policyName' created successfully."
} else {
Write-Output "Policy '$policyName' already exists."
}
if ("Send" -in $policy.Rights) {
Write-Host "Authorization rule has required right: Send."
} else {
throw "Authorization rule is missing Send right."
}
$keys = Get-AzEventHubKey -ResourceGroupName $resourceGroupName -NamespaceName $namespaceName -EventHubName $eventHubName -AuthorizationRuleName $policyName
if (-not $keys) {
throw "Could not obtain Azure Event Hub Key. Script failed and will end now."
}
if (-not $keys.PrimaryKey) {
throw "Could not obtain Primary Key. Script failed and will end now."
}
# Get the Primary Key of the Shared Access Policy
$primaryKey = ($keys.PrimaryKey)
Write-Host $primaryKey
## Check that the primary key is not empty.
# Define a function to create a SAS token (similar to the C# code provided)
function Create-SasToken {
param (
[string]$resourceUri, [string]$keyName, [string]$key
)
$sinceEpoch = [datetime]::UtcNow - [datetime]"1970-01-01"
$expiry = [int]$sinceEpoch.TotalSeconds + (60 * 60 * 24 * 31 * 6) # 6 months
$stringToSign = [System.Web.HttpUtility]::UrlEncode($resourceUri) + "`n" + $expiry
$hmac = New-Object System.Security.Cryptography.HMACSHA256
$hmac.Key = [Text.Encoding]::UTF8.GetBytes($key)
$signature = [Convert]::ToBase64String($hmac.ComputeHash([Text.Encoding]::UTF8.GetBytes($stringToSign)))
$sasToken = "SharedAccessSignature sr=$([System.Web.HttpUtility]::UrlEncode($resourceUri))&sig=$([System.Web.HttpUtility]::UrlEncode($signature))&se=$expiry&skn=$keyName"
return $sasToken
}
# Construct the resource URI for the SAS token
$resourceUri = "https://$namespaceName.servicebus.windows.net/$eventHubName"
# Generate the SAS token using the primary key from the new policy
$sasToken = Create-SasToken -resourceUri $resourceUri -keyName $policyName -key $primaryKey
# Output the SAS token
Write-Output @"
-- Generated SAS Token --
$sasToken
-- End of generated SAS Token --
"@
}
Generate-SasToken
변경 이벤트 스트리밍 활성화 및 구성
변경 이벤트 스트리밍을 사용하도록 설정하고 구성하려면 데이터베이스 컨텍스트를 사용자 데이터베이스로 변경한 다음 다음 단계를 수행합니다.
- 아직 구성되지 않은 경우 데이터베이스를 전체 복구 모델로 설정합니다.
- 마스터 키와 데이터베이스 범위 자격 증명을 만듭니다.
- 이벤트 스트리밍을 사용하도록 설정합니다.
- 이벤트 스트림 그룹을 만듭니다.
- 이벤트 스트림 그룹에 하나 이상의 테이블을 추가합니다.
이 섹션의 예제에서는 AMQP 프로토콜 및 Apache Kafka 프로토콜에 대해 CES를 사용하도록 설정하는 방법을 보여 줍니다.
다음은 이 섹션의 예제에 대한 샘플 매개 변수 값입니다.
@stream_group_name = N'myStreamGroup'
@destination_location = N'myEventHubsNamespace.servicebus.windows.net/myEventHubsInstance'
@partition_key_scheme = N'None'
- 기본 또는 보조 키 값:
Secret = 'BVFnT3baC/K6I8xNZzio4AeoFt6nHeK0i+ZErNGsxiw='
EXEC sys.sp_add_object_to_event_stream_group N'myStreamGroup', N'dbo.myTable'
예: AMQP 프로토콜을 통해 Azure Event Hubs로 스트리밍(SAS 토큰 인증)
꺾쇠 괄호(<value>
)의 값을 사용자 환경에 대한 값으로 대체합니다.
USE <database name>
-- Create the Master Key with a password.
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Password>'
CREATE DATABASE SCOPED CREDENTIAL <CredentialName>
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = '<Generated SAS Token>'
EXEC sys.sp_enable_event_stream
EXEC sys.sp_create_event_stream_group
@stream_group_name = N'<EventStreamGroupName>',
@destination_type = N'AzureEventHubsAmqp',
@destination_location = N'<AzureEventHubsHostName>/<EventHubsInstance>',
@destination_credential = <CredentialName>,
@max_message_size_kb = <MaxMessageSize>,
@partition_key_scheme = N'<PartitionKeyScheme>'
EXEC sys.sp_add_object_to_event_stream_group
N'<EventStreamGroupName>',
N'<SchemaName>.<TableName>'
예: AMQP 프로토콜을 통해 Azure Event Hubs로 스트리밍(키 값 인증)
꺾쇠 괄호(<value>
)의 값을 사용자 환경에 대한 값으로 대체합니다.
USE <database name>
-- Create the Master Key with a password.
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Password>'
CREATE DATABASE SCOPED CREDENTIAL <CredentialName>
WITH IDENTITY = '<Azure Event Hubs SAS Policy name>',
SECRET = '<Primary or Secondary key value>'
EXEC sys.sp_enable_event_stream
EXEC sys.sp_create_event_stream_group
@stream_group_name = N'<EventStreamGroupName>',
@destination_type = N'AzureEventHubsAmqp',
@destination_location = N'<AzureEventHubsHostName>/<EventHubsInstance>',
@destination_credential = <CredentialName>,
@max_message_size_kb = <MaxMessageSize>,
@partition_key_scheme = N'<PatitionKeyScheme>'
EXEC sys.sp_add_object_to_event_stream_group
N'<EventStreamGroupName>',
N'<SchemaName>.<TableName>'
예: Apache Kafka 프로토콜을 통해 Azure Event Hubs로 스트리밍(연결 문자열 인증)
꺾쇠 괄호(<value>
)의 값을 사용자 환경에 대한 값으로 대체합니다.
USE <database name>
-- Create the Master Key with a password.
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Password>'
CREATE DATABASE SCOPED CREDENTIAL credential1
WITH IDENTITY = 'SHARED ACCESS SIGNATURE',
SECRET = '<Event Hubs Namespace – Primary or Secondary connection string>'
EXEC sys.sp_enable_event_stream
EXEC sys.sp_create_event_stream_group
@stream_group_name = N'<EventStreamGroupName>',
@destination_type = N'AzureEventHubsApacheKafka',
@destination_location = N'<AzureEventHubsHostName>:<port>/<EventHubsInstance>',
@destination_credential = <CredentialName>,
@max_message_size_kb = <MaxMessageSize>,
@partition_key_scheme = N'<PatitionKeyScheme>'
EXEC sys.sp_add_object_to_event_stream_group
N'<EventStreamGroupName>',
N'<SchemaName>.<TableName>'
예: Apache Kafka 프로토콜을 통해 Azure Event Hubs로 스트리밍(키 값 인증)
꺾쇠 괄호(<value>
)의 값을 사용자 환경에 대한 값으로 대체합니다.
USE <database name>
-- Create the Master Key with a password.
CREATE MASTER KEY ENCRYPTION BY PASSWORD = '<Password>'
CREATE DATABASE SCOPED CREDENTIAL credential1
WITH IDENTITY = '<Azure Event Hubs SAS Policy name>',
SECRET = '<Primary or Secondary key value>' -- BVFnT3baC/K6I8xNZzio4AeoFt6nHeK0i+ZErNGsxiw=
EXEC sys.sp_enable_event_stream
EXEC sys.sp_create_event_stream_group
@stream_group_name = N'<EventStreamGroupName>', -- myStreamGroup
@destination_type = N'AzureEventHubsApacheKafka',
@destination_location = N'<AzureEventHubsHostName>:<port>/<EventHubsInstance>', -- myEventHubsNamespace.servicebus.windows.net:9093/myEventHubsInstance
@destination_credential = <CredentialName>,
@max_message_size_kb = <MaxMessageSize>, -- 1024
@partition_key_scheme = N'<PatitionKeyScheme>' -- N'None'
EXEC sys.sp_add_object_to_event_stream_group
N'<EventStreamGroupName>',
N'<SchemaName>.<TableName>' -- dbo.myTable
CES 구성 및 함수 보기
sys.databasesis_event_stream_enabled = 1
에서 변경 이벤트 스트리밍이 데이터베이스에 대해 사용하도록 설정되어 있음을 나타냅니다.
다음 쿼리는 변경 이벤트 스트리밍을 사용하도록 설정된 모든 데이터베이스를 반환합니다.
SELECT * FROM sys.databases WHERE is_event_stream_enabled = 1
sys.tablesis_replicated = 1
에서 테이블이 스트리밍되고 sp_help_change_feed_table 변경 이벤트 스트리밍을 위한 테이블 그룹 및 테이블 메타데이터에 대한 정보를 제공합니다.
다음 쿼리는 변경 이벤트 스트리밍이 활성화된 모든 테이블을 반환하고 메타데이터 정보를 제공합니다.
SELECT name, is_replicated FROM sys.tables
EXEC sp_help_change_feed_table @source_schema = '<schema name>', @source_name = '<table name>'
비고
현재 CDC(변경 데이터 캡처), 트랜잭션 복제 또는 패브릭 미러된 데이터베이스 for SQL Server로 구성된 데이터베이스에서는 CES가 지원되지 않습니다.
CES 저장 프로시저, 시스템 함수 및 DMV
다음 표에서는 변경 이벤트 스트리밍을 구성, 비활성화 및 모니터링하는 데 사용되는 저장 프로시저, 시스템 함수 및 DMV를 나열합니다.
시스템 개체 | 설명 |
---|---|
|
|
sys.sp_enable_event_stream | 현재 사용자 데이터베이스에 대해 CES를 사용하도록 설정합니다. |
sys.sp_create_event_stream_group | 테이블 그룹에 대한 스트리밍 구성인 스트림 그룹을 만듭니다. 또한 스트림 그룹은 대상 및 관련 세부 정보(예: 인증, 메시지 크기, 분할)를 정의합니다. 프로시저가 완료되면 stream_group_id 자동으로 생성되고 최종 사용자에 대해 표시됩니다. |
sys.sp_add_object_to_event_stream_group | 스트림 그룹에 테이블을 추가합니다. |
|
|
sys.sp_remove_object_from_event_stream_group | 스트림 그룹에서 테이블을 제거합니다. |
sys.sp_drop_event_stream_group | 스트림 그룹을 삭제합니다. 스트림 그룹을 사용해서는 안 됩니다. |
sys.sp_disable_event_stream | 현재 사용자 데이터베이스에 대해 CES를 사용하지 않도록 설정합니다. |
|
|
sys.dm_change_feed_errors | 전송 오류를 반환합니다. |
sys.dm_change_feed_log_scan_sessions | 로그 검사 활동에 대한 정보를 반환합니다. |
sys.sp_help_change_feed_settings | 구성된 변경 이벤트 스트리밍의 상태 및 정보를 제공합니다. |
sys.sp_help_change_feed | 변경 스트림의 현재 구성을 모니터링합니다. |
sys.sp_help_change_feed_table_groups | 변경 이벤트 스트리밍 그룹을 구성하는 데 사용되는 메타데이터를 반환합니다. |
sys.sp_help_change_feed_table | 변경 이벤트 스트리밍에 대한 스트리밍 그룹 및 테이블 메타데이터의 상태 및 정보를 제공합니다. |
제한점
CES(변경 이벤트 스트리밍)에는 다음과 같은 제한 사항이 있습니다.
서버 수준 및 일반 제한 사항
- CES는 Linux 또는 SQL Server 2025 Express 버전의 SQL Server 2025에서 지원되지 않습니다.
- CES는
INSERT
,UPDATE
, 및DELETE
DML 명령문의 데이터 변경에 대해서만 이벤트를 발생시킵니다. - CES는 스키마 변경(DDL 작업)을 처리하지 않으므로 DDL 작업에 대한 이벤트를 내보내지 않습니다. 그러나 DDL 작업은 차단되지 않으므로 실행되는 경우 후속 DML 이벤트의 스키마는 업데이트된 테이블 구조를 반영합니다. 사용자는 업데이트된 스키마를 사용하여 이벤트를 정상적으로 처리해야 합니다.
- JSON이 지정된 출력 형식인 경우 큰 이벤트 메시지는 스트림 그룹당 구성된 최대 메시지 크기의 약 25% 분할될 수 있습니다. 이 제한은 이진 출력 형식에는 적용되지 않습니다.
- 메시지가 Azure Event Hubs 메시지 크기 제한을 초과하는 경우 현재는 확장 이벤트를 통해서만 오류를 관찰할 수 있습니다.
- CES용으로 구성된 테이블에 대해서는 테이블 및 열 이름이 차단됩니다. 데이터베이스 이름을 바꿀 수 있습니다.
데이터베이스 수준 제한 사항
- CES는 전체 복구 모델로 구성된 데이터베이스에서만 지원됩니다.
- SQL Server용 패브릭 미러 데이터베이스, 트랜잭션 복제, 변경 데이터 캡처 또는 Azure Synapse Link로 구성된 데이터베이스에서는 CES가 지원되지 않습니다. 변경 내용 추적 은 CES로 구성된 데이터베이스에서 지원됩니다.
- CES는 쓰기 가능한 주 데이터베이스에서만 스트리밍할 수 있습니다. Always On 가용성 그룹에 속하거나 Managed Instance 링크를 사용하는 보조 데이터베이스는 스트리밍 원본으로 구성할 수 없습니다.
- 뷰 또는 구체화된 뷰에서는 CES를 사용하도록 설정할 수 없습니다.
테이블 수준 제한 사항
- 테이블은 하나의 스트리밍 그룹에만 속할 수 있습니다. 동일한 테이블을 여러 대상으로 스트리밍하는 것은 지원되지 않습니다.
- CES에 대해 사용자 테이블만 구성할 수 있습니다. 시스템 테이블은 지원되지 않습니다.
- 최대 4,096개의 스트림 그룹을 구성할 수 있습니다. 각 스트림 그룹에는 최대 40,000개의 테이블이 포함될 수 있습니다.
- 테이블에서 CES를 사용하는 동안에는 해당 테이블에 기본 키 제약 조건을 추가하거나 삭제할 수 없습니다.
-
ALTER TABLE SWITCH PARTITION
는 CES용으로 구성된 테이블에서 지원되지 않습니다. -
TRUNCATE TABLE
는 CES에 대해 사용하도록 설정된 테이블에서 지원되지 않습니다. - CES는 다음 기능 중 어느 것을 사용하는 테이블을 지원하지 않습니다.
- 클러스터형 columnstore 인덱스
- 시간 기록 테이블 또는 원장 기록 테이블
- 항상 암호화됨
- 메모리 내 OLTP(메모리 최적화 테이블)
- 그래프 테이블
- 외부 테이블
열 수준 제한 사항
- 다음 데이터 형식은 CES에서 지원되지 않습니다. 이러한 형식의 열은 스트리밍 과정에서 건너뛰어집니다.
json
image
text
/ntext
xml
rowversion
/timestamp
sql_variant
- UDT(사용자 정의 형식)
geometry
geography
vector
원본 데이터베이스의 사용 권한
- 행 수준 보안을 위해 CES는 사용자 권한에 관계없이 모든 행에서 변경 내용을 내보낸다.
- 동적 데이터 마스킹은 CES를 통해 전송된 데이터에 적용되지 않습니다. 마스킹이 구성된 경우에도 데이터는 마스크되지 않은 상태로 스트리밍됩니다.
- CES는 개체 수준 권한 변경과 관련된 이벤트를 내보내지 않습니다(예: 특정 열에 사용 권한 부여).