SQL Server에서 두 데이터베이스 동기화


16

두 개의 SQL Server 데이터베이스가 있습니다. 하나는 클라이언트 (Windows 응용 프로그램)이고 다른 하나는 서버에 있습니다. 이 두 데이터베이스를 자주 (예 : 2 분마다) 동기화하고 싶습니다.

트리거를 사용하는 복제, 타임 스탬프, 로그 테이블, Microsoft Sync Framework 등과 같은 다양한 동기화 방법에 대해 읽었습니다.

실제로 SQL Server 관련 테이블을 업데이트하고 서버와 동기화하는 동안 차단하지 않기 때문에 복제와 같은 블랙 박스 일 수있는 동기화 방법을 사용하고 싶지 않습니다.

  1. 그런 상황에서 어떤 방법을 사용해야한다고 생각하십니까? 몇 분마다 클라이언트에서 서버로 몇 가지 테이블 변경 사항을 전송하고 서버에서 두 개의 테이블 변경 사항을 가져와야합니다.

  2. 이상하지만 새로운 방법을 찾았습니다. 클라이언트에서 실행 된 (구체적으로 선호되는) 저장 프로 시저를 모두 .sql파일에 매개 변수와 함께 서버 에 보내고 거기에서 실행할 수 있습니까? 서버에서도 마찬가지이며 클라이언트에게 전송됩니다. 이것이 간단하면서도 유용한 방법이라고 생각하십니까?

  3. 가능하면 유용한 방법을 제안 해주세요. 정말 고맙습니다.

편집 : 이것은 실시간 동기화이며 이것이 특별하다는 것을 기억하십시오. 이는 클라이언트 사용자가 테이블을 사용할 때 서버와의 동기화 프로세스가 몇 분마다 발생해야 테이블이 잠기지 않아야 함을 의미합니다.


1
이러한 "블랙 박스"는 작동 방식, 유지 관리 및 모니터링 방법 및 일반적인 (그리고 일반적이지 않은) 실패 시나리오에서이를 해결하기 위해 수행 할 수있는 작업과 관련하여 비교적 잘 문서화되어 있음을 기억하십시오. 필자는 자체 응용 프로그램을 롤링하고 응용 프로그램 관련 요구가 매우 많거나 (부분 동기화 또는 사용자 요구가있는 경우) "블랙 박스"가 오래 전에 해결 된 엣지 사례와 관련된 버그를 찾아 수정 해야합니다. 대화식 충돌 해결 등).
David Spillett

@DavidSpillett : 실시간 동기화 프로젝트에서 복제를 성공적으로 사용 했습니까? 나의 주요 관심사는 실시간 동기화 및 "잠금 및 차단"입니다.
Emad Farrokhi

답변:


14

나는 그것을 얻지 못할 수도 있지만 대답하려고합니다.

자주 (최소 2 분) 실행되는 고성능 솔루션이 필요하며 잠금없이 빠르게 사용해야하는 좋은 접근 방식이 필요하다고 말했습니다. 그러나 블랙 박스 시스템은 원하지 않습니다.

좋은 결과를내는 수백만 개의 설치에 사용되는 블랙 박스 시스템 대신 휠을 다시 발명하고 자신 만의 솔루션을 구축하려고하십니까? 흠, 조금 이상하게 들린다.

사실 이것은 나의 제안이다.

  1. 사용하지 않겠다고하더라도 복제 이를 위해 사용할 수있는 가장 쉽고 최고의 솔루션입니다. 복제는 설정이 쉽고 빠르게 복제 할 수 있으며 휠을 다시 발명 할 필요가 없습니다. 잠금에 대한 단지 이상한 당신이 경우를 설정하려고 할 수 있습니다 ISOLATION LEVELREAD_COMMITTED_SNAPSHOT. 자세한 내용은 여기를 참조 하십시오 . 이것은 tempdb의 일부를 사용하지만 테이블은 항상 읽고 쓸 수 있으며 복제는 백그라운드에서 작동 할 수 있습니다.

아래 예를 참조하십시오.

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. CDC (Change Data Capture)도 솔루션이 될 수 있습니다. 그러나이 방법으로 거의 모든 것을 스스로 구축해야합니다. 그리고 CDC어떤 상황에서는 깨지기 쉬운 경험을했습니다 . CDC감시 테이블의 모든 데이터를 캡처합니다 (각 감시 테이블을 수동으로 지정해야 함). 그 후 당신은 후 이전 값과 값을 얻을 것이다 INSERT, UPDATE또는 DELETE. CDC해당 정보를 일정 기간 동안 보류합니다 (직접 지정할 수 있음). CDC이러한 변경 사항은 해당 변경 사항을보고 다른 데이터베이스에 수동으로 복제해야하는 특정 테이블 에서 사용할 수 있습니다 . 그건 그렇고, CDC후드 아래에서도 SQL Server 복제를 사용합니다. ;-) 자세한 내용은 여기를 참조 하십시오 .

경고 : -changes를 CDC인식하지 DDL못합니다. 즉, 테이블을 변경하고 새 열을 추가 CDC하면 테이블을 감시하지만 새 열의 모든 변경 사항은 무시합니다. 실제로 NULL이전 값과 이후 값으로 만 기록 됩니다. DDL감시 된 테이블로 변경 한 후 다시 초기화해야 합니다.

  1. 위에서 설명한 방법은 SQL Server 프로파일 러를 사용하여 워크로드를 캡처하고 일부 벤치 마크를 위해 다른 데이터베이스에서 다시 실행하는 것과 같습니다. 잘 작동합니다. 그러나 부작용이 너무 많다는 사실은 나에게 너무 무겁습니다. 클라이언트에서 프로 시저 호출을 캡처하면 어떻게합니까? 그런 다음 기본 데이터베이스에서 동기화되지 않은 동일한 명령을 실행합니까? 프로 시저가 실행될 수 있지만 클라이언트에없는 행을 삭제 / 업데이트 / 삽입 할 수 있습니다. 또는 하나의 원칙으로 여러 클라이언트를 어떻게 처리합니까? 나는 이것이 너무 까다로운 생각합니다. 최악의 경우, 당신은 아마 청렴성을 파괴 할 것입니다.
  2. 또 다른 아이디어는 응용 프로그램 기반이거나 트리거를 사용하는 것일 수 있습니다. 동기화하려는 테이블 수에 따라 모든 변경 내용을 별도의 준비 테이블에 기록하고 SQL Server 에이전트 작업을 x 분마다 실행하여 준비 테이블의 해당 행을 마스터와 동기화 할 수 있습니다. 그러나 150 개의 테이블을 동기화하려고하면 약간 무거울 수 있습니다. 오버 헤드가 큽니다.

이건 내 2 센트입니다. 바라건대 당신은 좋은 개요를 가지고 아마도 당신에게 맞는 하나의 솔루션을 찾았을 것입니다.


9

나는 여기에 몇 가지 옵션을 열거 할 때 장점과 단점을 열거하려고 노력할 것입니다.

  1. SQL Server 복제 -이 작업에 가장 적합하고 최적화 된 기본 SQL Server 도구입니다. 그러나 몇 가지 문제 가 있습니다. SQL Express 데이터베이스인지 여부에 관계없이 모든 클라이언트에 대해 SQL Server CAL 라이센스가 필요합니다. 이는 프로세서 당 라이센스를 사용하여 피할 수 있습니다. 비. 여기에 따라 SQL CE 클라이언트를 동기화 할 수 없습니다. 씨. SQL Express 또는 LocalDB 는 게시자 또는 배포자 역할을 할 수 없으므로 복제 프로세스에 대한 클라이언트 제어 권한이 줄어 듭니다.
  2. Microsoft Sync Framework- 소규모 모바일 앱 데이터베이스에 더 적합합니다. 데이터베이스에 많은 테이블을 추가하고 복제만큼 효율적이지 않습니다. SQL Server 외부에서 구성 요소로 구현되므로 구성하기가 더 어려워집니다. 나는 그것에 대한 경험이 없으며 그것을 시도하고 사용하지 않기로 결정했습니다.

  3. 데이터베이스 변경 추적 . 삽입, 업데이트 및 삭제를 포함하여 추적을 변경하는 데 사용되는 기본 제공 SQL Server 기능입니다. 변경 사항 보내기 및 적용, 충돌 해결 등과 같은 다른 모든 작업은 직접 코딩해야합니다.

  4. Rowversion (타임 스탬프) 열 모든 삭제를 허용하지 않으면 (삭제 된 레코드의 동기화 없음) rowversion 정보 만 기반으로 고유 한 솔루션을 구현할 수 있습니다. Rowversion 열은 SQL Server 복제에서도 사용되므로 어쨌든 추가해야합니다.
  5. Ionic의 답변에서 언급 한 CDC -Enterprise 또는 Developer 버전에서만 사용할 수 있으므로 경험이 없습니다.

  6. 스토어드 프로 시저 실행 로깅과 함께 고유 한 트릭을 사용하는 것은 데이터베이스 애플리케이션의 특성에 따라 다릅니다. 그러나 절차가 조금씩 다르면 데이터가 크게 엉망이 될 수 있습니다. 그리고 갈등을 어떻게 다룰 것입니까?

귀하의 질문에 따르면 전체 데이터베이스가 아닌 몇 개의 테이블 만 동기화해야합니다. 이를 위해 다음과 같이 질문에서 지정한 것보다 더 자세하게 요구 사항을 분석해야합니다.

  • 삭제가 가능하고 어떻게됩니까?
  • 갈등이 발생할 수 있는가, 어떻게 방지하고 해결 하는가?
  • 테이블 구조 변경은 어떻게 처리합니까?
  • ...

결국 삭제와 충돌이 문제가 아니며 구조가 많이 변경되지 않는다는 것을 알게되면 자체 논리를 작성하는 것을 고려할 수 있지만 쉽게 1000 행의 코드로 커질 수 있습니다.


2

의견을 보내 주셔서 감사합니다.

실행 된 저장 프로 시저를 묶음으로 캡처하지 않고 제 경우에는 훌륭하게 작동하여 동기화 프로세스를 성공적으로 해결했습니다. 무결성과 모든 것이 신중하게 고려되었으므로 시스템은 지금까지 실시간으로 작동했습니다.


그러나 당신이 한 일을 더 자세히 설명해 주시겠습니까? 실행 된 저장 프로 시저의 호출을 로그하여 임시 테이블 / 스크립트에 저장하고 작업에서이 스크립트를 실행하고 필드 (예 : 비트 필드 또는 날짜 / 시간 필드 등)를 설정하도록합니다. 처리되지 않은 레코드는 처리하고 비트 필드를 업데이트 하시겠습니까?) 문제를 해결 한 것이 행복하지만 다른 사람들이 배우도록 돕기 위해 무엇을했는지 더 많은 통찰력을 제공해야합니까?
JonH

0

늦은 답변이지만 방문자를 스레드하는 것이 도움이 될 수 있습니다

다른 서버에 데이터를 배포하려고 시도하는 비슷한 과제가 있었고 타사 도구 ( 스키마 변경에 대한 Diff 및 데이터 변경 동기화에 대한 DataDiff )를 사용하고 프로세스를 자동화하는 데 필요한 PowerShell 스크립트 를 사용하여 해결했습니다 .

#check for the existence of the Outputs folder
function CheckAndCreateFolder($rootFolder, [switch]$Outputs)
{
$location = $rootFolder

#setting up location 
if($Outputs -eq $true)
{
    $location += "\Outputs"
}

#if the folder doesn't exist it will be created
if(-not (Test-Path $location))
{ mkdir $location -Force:$true -Confirm:$false | Out-Null }

return $location
}

#root folder for the schema sync process
$rootFolder = "SchemaSync"

#schema output summaries location 
$outsLoc = CheckAndCreateFolder $rootFolder -Outputs

#ApexSQL Diff location, date stamp variable is defined, along with tools parameters 
$diffLoc   = "ApexSQLDiff"
$stamp = (Get-Date -Format "MMddyyyy_HHMMss") 
$Params = "/pr:""MyProject.axds""    /out:""$outsLoc\SchemaOutput_$stamp.txt"" /sync /v /f" 
$returnCode = $LASTEXITCODE

#initiate the schema comparison and synchronization process
(Invoke-Expression ("& `"" + $diffLoc +"`" " +$Params))

#write output to file
"$outsLoc\SchemaOutput_$dateStamp.txt"

#schema changes are detected
if($returnCode -eq 0)
{
"`r`n $returnCode - Schema changes were successfully synchronized" >> 

}
else
{
#there are no schema changes
if($returnCode -eq 102)
{
"`r`n $returnCode - There are no schema changes. Job aborted" >> 
}
#an error is encountered
else
{
"`r`n $returnCode - An error is encountered" >> 

#output file is opened when an error is encountered
Invoke-Item "$outsLoc\SchemaOutput_$stamp.txt"
}

}

이 방법은 두 데이터베이스 간의 비교를 예약하고 발견 된 변경 사항을 실시간으로 동기화합니다. 다음은 단계별 지침을 제공하는 기사입니다.

https://solutioncenter.apexsql.com/automatically-compare-and-synchronize-sql-server-data/ https://solutioncenter.apexsql.com/how-to-automatically-keep-two-sql-server-database- 동기화 된 스키마 /

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.