SQL सर्वर में दो डेटाबेस को सिंक करना


16

मेरे पास दो SQL सर्वर डेटाबेस हैं। एक क्लाइंट (विंडोज एप्लिकेशन) है और दूसरा सर्वर पर है। मैं इन दोनों डेटाबेस को हर बार (जैसे हर 2 मिनट!) सिंक करना चाहता हूं।

मैंने प्रतिकृति, समय टिकट, लॉग टेबल का उपयोग करते हुए ट्रिगर, माइक्रोसॉफ्ट सिंक फ्रेमवर्क और इतने पर सिंक्रनाइज़ करने के विभिन्न तरीकों के बारे में पढ़ा है।

वास्तव में मैं एक सिंकिंग विधि का उपयोग करना पसंद नहीं करता हूं जो एक ब्लैक बॉक्स (जैसे प्रतिकृति) हो सकता है क्योंकि मैं नहीं चाहता कि SQL सर्वर विशिष्ट तालिकाओं को अवरुद्ध किया जा रहा है, जबकि मैं उन्हें अद्यतन कर रहा हूं और सर्वर के साथ सिंक्रनाइज़ कर रहा हूं।

  1. आप किस विधि से सोचते हैं कि मुझे ऐसी परिस्थिति में उपयोग करना चाहिए? याद रखें कि हर कई मिनट में मुझे क्लाइंट से सर्वर में कई टेबल परिवर्तन भेजने होंगे और सर्वर से दो टेबल परिवर्तन भी लाने होंगे।

  2. मुझे एक तरीका मिला है जो अजीब है लेकिन नया है। क्या यह संभव है कि मैं क्लाइंट में सभी विशिष्ट निष्पादित (विशिष्ट पसंदीदा) संग्रहीत प्रक्रियाओं के लिए लॉग इन करूं और उन्हें एक .sqlफ़ाइल में अपने मापदंडों के साथ सर्वर पर भेज दूं और वहां उन्हें निष्पादित करूं? सर्वर पर भी यही होगा और क्लाइंट को भेजा जाएगा। क्या आपको लगता है कि यह एक सरल अभी तक उपयोगी विधि है या नहीं?

  3. यदि आप कर सकते हैं तो कृपया मुझे कोई उपयोगी तरीका सुझाएं। बहुत बहुत धन्यवाद।

संपादित करें: याद रखें कि यह एक वास्तविक समय सिंक्रनाइज़ेशन है और यह इसे विशेष बनाता है। इसका मतलब है कि जब ग्राहक उपयोगकर्ता तालिका का उपयोग कर रहा है, तो सर्वर के साथ सिंक्रनाइज़ेशन प्रक्रिया हर कई मिनट में होनी चाहिए ताकि कोई भी तालिका लॉक न हो।


1
याद रखें कि वे "ब्लैक बॉक्स" अपेक्षाकृत अच्छी तरह से प्रलेखित हैं कि वे कैसे काम करते हैं, कैसे बनाए रखें और उनकी निगरानी करें, और आप उन्हें सामान्य (और नहीं-तो-आम) विफलता परिदृश्यों को ठीक करने के लिए क्या कर सकते हैं। मैं अपनी खुद की सिंक्रोनाइज़ेशन विधि को रोल करने पर विचार करूंगा और एज केस से संबंधित बग्स को खोजने और ठीक करने के लिए होगा जो कि "ब्लैक बॉक्स" ने एक लंबे समय पहले संबोधित किया था यदि और केवल अगर मुझे बहुत ही विशिष्ट अनुप्रयोग की आवश्यकता थी (आंशिक तुल्यकालन, या उपयोगकर्ता की आवश्यकता- इंटरैक्टिव संघर्ष संकल्प, और इतने पर)।
डेविड स्पिललेट

@DavidSpillett: क्या आपने प्रतिकृति का उपयोग वास्तविक समय सिंक्रनाइज़ेशन प्रोजेक्ट में सफलतापूर्वक किया था? मेरी मुख्य चिंता रियल-टाइम सिंक्रोनाइज़ेशन और "लॉकिंग एंड ब्लॉकिंग" है।
इमाद फारूखी

जवाबों:


14

वैसे मैं इसे प्राप्त नहीं कर सकता, लेकिन मैं इसका जवाब देने की कोशिश करता हूं।

आपने कहा कि आपको एक उच्च प्रदर्शन समाधान की आवश्यकता होती है जो अक्सर चलता है (न्यूनतम सभी 2 मिनट) और आपको एक अच्छे दृष्टिकोण की आवश्यकता होती है जो बिना लॉक किए तेजी से होना चाहिए। लेकिन आपको ब्लैकबॉक्स सिस्टम नहीं चाहिए।

एक ब्लैकबॉक्स सिस्टम के बजाय, जिसका उपयोग अच्छे परिणामों के साथ लाखों इंस्टॉलेशन पर किया जाता है, आप पहिया को फिर से आविष्कार करने और अपना समाधान बनाने की कोशिश करते हैं? हम्म, थोड़ा अजीब लगता है।

वास्तव में ये मेरे सुझाव हैं।

  1. यदि आपने कहा है कि आप इसका उपयोग नहीं करेंगे तब भी प्रतिकृति । यह काफी आसान और सबसे अच्छा समाधान है जिसका आप इसके लिए उपयोग कर सकते हैं। प्रतिकृति सेटअप करने के लिए आसान है, तेजी से नकल और आप पहिया फिर से आविष्कार करने की जरूरत नहीं है। अगर तुम सिर्फ ताला के बारे में अजीब है, तो आप स्थापित करने के लिए कोशिश कर सकते हैं ISOLATION LEVELकरने के लिए READ_COMMITTED_SNAPSHOT। आप इसके बारे में और अधिक यहाँ पढ़ सकते हैं । यह आपके tempdb के एक हिस्से का उपयोग करेगा, लेकिन आपकी तालिका हमेशा पढ़ी जाती है- और लिखने योग्य और प्रतिकृति पृष्ठभूमि में काम कर सकती है।

नीचे दिए गए उदाहरण देखें:

ALTER DATABASE yourDatabase SET ALLOW_SNAPSHOT_ISOLATION ON
ALTER DATABASE yourDatabase SET READ_COMMITTED_SNAPSHOT ON
  1. सीडीसी (चेंज डेटा कैप्चर) भी एक समाधान हो सकता है। लेकिन इस तरह आपको अपने दम पर लगभग सब कुछ बनाने की जरूरत है। और मैंने ऐसा अनुभव किया है जो CDCकुछ परिस्थितियों में एक नाजुक चीज हो सकती है। CDCएक देखे गए तालिका पर सभी डेटा कैप्चर करेंगे (आपको प्रत्येक देखे गए तालिका को मैन्युअल रूप से निर्दिष्ट करने की आवश्यकता है)। बाद में आपको पहले और बाद में मान मिलेगा INSERT, UPDATEया DELETECDCसमय की अवधि के लिए उन सूचनाओं को वापस रखेगा (आप इसे अपने दम पर निर्दिष्ट कर सकते हैं)। दृष्टिकोण CDCकुछ तालिकाओं पर उपयोग करने के लिए हो सकता है जिन्हें आपको देखने और मैन्युअल रूप से उन परिवर्तनों को दूसरे डेटाबेस में दोहराने की आवश्यकता है। वैसे, CDCहुड के तहत SQL सर्वर प्रतिकृति का भी उपयोग करता है। ;-) आप यहाँ इसके बारे में अधिक पढ़ सकते हैं ।

चेतावनी: -चार्ज के CDCबारे में पता नहीं होगा DDLइसका मतलब है, यदि आप एक तालिका बदलते हैं और एक नया कॉलम जोड़ते हैं, CDCतो तालिका देखेंगे लेकिन नए कॉलम के सभी परिवर्तनों को अनदेखा कर देंगे। वास्तव में यह केवल NULLमूल्य से पहले और बाद में मूल्य के रूप में दर्ज करता है। आपको इसे DDLपुन: व्यवस्थित करने की आवश्यकता है-एक देखे गए तालिका में परिवर्तन।

  1. जिस तरह से आपने ऊपर वर्णित किया है वह कुछ ऐसा है जैसे SQL सर्वर प्रोफाइलर का उपयोग करके एक वर्कलोड को कैप्चर करना और इसे कुछ बेंचमार्क के लिए फिर से किसी अन्य डेटाबेस पर चलाना। वैसे यह काम कर सकता है। लेकिन यह तथ्य कि बहुत अधिक दुष्प्रभाव हैं, मेरे लिए थोड़ा भारी है। यदि आप अपने क्लाइंट पर एक प्रक्रिया कॉल कैप्चर करते हैं तो आप क्या करते हैं। बाद में आपके सिद्धांत डेटाबेस में समान कमांड चल रहा है क्योंकि यह सिंक से बाहर है? प्रक्रिया के माध्यम से चल सकता है, लेकिन यह पंक्तियों को हटा / अद्यतन / सम्मिलित कर सकता है जो आपके क्लाइंट में मौजूद नहीं थे। या आप एक सिद्धांत के साथ कई ग्राहकों को कैसे संभालते हैं। मुझे लगता है कि यह बहुत मुश्किल है। सबसे खराब स्थिति में, आप शायद अपनी अखंडता को नष्ट कर देते हैं।
  2. एक अन्य विचार आवेदन आधारित या ट्रिगर का उपयोग कर हो सकता है। आप कितने टेबल को सिंक करना चाहते हैं, इसके आधार पर। आप एक अलग स्टेजिंग टेबल में सभी परिवर्तन लिख सकते हैं और अपने मास्टर के साथ स्टेजिंग टेबल में उन पंक्तियों को सिंक करने के लिए SQL सर्वर एजेंट जॉब सभी x मिनट चला सकते हैं। लेकिन यह थोड़ा भारी हो सकता है अगर आप 150 तालिकाओं को सिंक करने की कोशिश करते हैं। आपके पास एक बड़ा ओवरहेड होगा।

वैसे ये मेरे 2 सेंट हैं। उम्मीद है कि आपके पास एक अच्छा अवलोकन है और शायद आपको एक समाधान मिल गया है जो आपके लिए काम करता है।


9

मैं लाभ और हानि के साथ कुछ विकल्पों की गणना करने की कोशिश करूंगा क्योंकि मैं उन्हें प्रभावित करता हूं:

  1. SQL सर्वर प्रतिकृति - यह इस कार्य के लिए सबसे अच्छा और सबसे अनुकूलित देशी SQL सर्वर उपकरण है। लेकिन कई समस्याएं हैं: ए। आपके सभी ग्राहकों के लिए, चाहे वे SQL एक्सप्रेस डेटाबेस हों या नहीं, आपको SQL सर्वर CAL लाइसेंस की आवश्यकता होगी। प्रति प्रोसेसर लाइसेंस का उपयोग करके इससे बचा जा सकता है। ख। आप यहाँ पर SQL CE क्लाइंट को सिंक नहीं कर सकते हैंसी। SQL Express या LocalDB प्रकाशक या वितरक के रूप में कार्य नहीं कर सकता है , इसलिए आपके पास प्रतिकृति प्रक्रिया पर क्लाइंट का कम नियंत्रण है।
  2. Microsoft सिंक फ्रेमवर्क - मुझे मोबाइल ऐप्स के छोटे डेटाबेस के लिए अधिक उपयुक्त लगता है। यह आपके डेटाबेस में काफी टेबल जोड़ता है और यह प्रतिकृति के रूप में कुशल नहीं है। चूंकि यह एक घटक के रूप में SQL सर्वर के बाहर कार्यान्वित किया जाता है, इसलिए इसे कॉन्फ़िगर करना अधिक कठिन होगा। मुझे इसके साथ कोई अनुभव नहीं है, केवल इसे आज़माया और इसे इस्तेमाल न करने का फैसला किया।

  3. डेटाबेस परिवर्तन ट्रैकिंग । यह एक अंतर्निहित SQL सर्वर फ़ंक्शन है जो आपके लिए आवेषण, अपडेट और हटाए जाने सहित ट्रैकिंग को बदलने के लिए करता है। बाकी सब कुछ जैसे बदलाव भेजना और लागू करना, टकराव को सुलझाना आदि आपको खुद को कोड करना होगा।

  4. रोववर्सन (टाइमस्टैम्प) कॉलम यदि आप सभी हटाए गए (हटाए गए रिकॉर्ड्स का कोई सिंक) को अस्वीकार नहीं करते हैं - तो आप केवल रॉलवर्सन जानकारी के आधार पर अपना स्वयं का समाधान लागू कर सकते हैं। Rowversion कॉलम SQL Server प्रतिकृति द्वारा भी उपयोग किए जाते हैं, इसलिए आपको उन्हें किसी भी तरह जोड़ना होगा।
  5. सीडीसी जैसा कि इओनिक के जवाब में उल्लेख किया गया है - मुझे इसके साथ कोई अनुभव नहीं है, क्योंकि यह केवल एंटरप्राइज या डेवलपर संस्करणों में उपलब्ध है।

  6. निष्पादित प्रक्रियाओं के लॉगिंग के साथ अपनी चाल का उपयोग करना - आपके डेटाबेस एप्लिकेशन की प्रकृति पर बहुत निर्भर करता है। लेकिन जब प्रक्रियाएं थोड़ी अलग हो जाती हैं, तो आप डेटा में बड़ी गड़बड़ी कर सकते हैं। और आप टकराव से कैसे निपटेंगे?

आपके प्रश्न से ऐसा लगता है कि आपको केवल कुछ तालिकाओं को सिंक करने की आवश्यकता है, न कि पूरे बड़े डेटाबेस को। इस प्रयोजन के लिए आपको अपनी आवश्यकताओं का अधिक विस्तार से विश्लेषण करना चाहिए, जैसे आपने प्रश्न में निर्दिष्ट किया है, जैसे:

  • क्या डिलीट हो सकता है और तब क्या होता है?
  • क्या टकराव हो सकते हैं, उन्हें कैसे रोका जाए और कैसे हल किया जाए?
  • मैं तालिका संरचना परिवर्तनों से कैसे निपटूंगा?
  • ...

यदि आप अंततः पता लगाते हैं, तो हटाए गए और संघर्ष आपकी समस्या नहीं हैं और यह कि आपकी संरचना में बहुत बदलाव नहीं होगा, आप अपने तर्क लिखने पर विचार कर सकते हैं, लेकिन यह आसानी से कोड की 1000 पंक्तियों तक बढ़ सकता है।


2

आपकी प्रतिपुष्टि के लिए आप सभी को धन्यवाद।

मैंने सफलतापूर्वक संचित प्रक्रिया को एक गुच्छा के रूप में निष्पादित नहीं बल्कि एक-एक करके निष्पादित किया, जिसने मेरे मामले में बहुत अच्छा काम किया। चूंकि अखंडता और सब कुछ ध्यान से माना जाता है, सिस्टम अब तक वास्तविक समय काम कर रहा है।


महान हालांकि आप कृपया विस्तार से बता सकते हैं कि आपने क्या किया। क्या आप केवल उन स्टोर किए गए प्रक्रियाओं के कॉल लॉग करते हैं जिन्हें निष्पादित किया गया था और उन्हें कुछ अस्थायी तालिका / स्क्रिप्ट में संग्रहीत किया है और इस स्क्रिप्ट को चलाने के लिए एक नौकरी है और एक फ़ील्ड सेट करें (जैसे कि एक बिट फ़ील्ड या डेटाटाइम फ़ील्ड जहाँ आप इन सभी के लिए कहते हैं उन रिकॉर्ड्स को संसाधित नहीं किया गया है जो उन्हें संसाधित करते हैं और बिट फ़ील्ड को अपडेट करते हैं?) मुझे खुशी है कि आपने अपना मुद्दा हल कर लिया है लेकिन आपको दूसरों को सीखने में मदद करने के लिए आपने क्या किया है, इस बारे में अधिक जानकारी देने की आवश्यकता है?
जॉन एचएच

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- स्कीमा में सिंक /

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.