Міне, мен екі түрлі қозғалтқышта екі рет көрген сәтсіздік. Экспорт 10:00-де іске қосылып, көрген ең жоғары соңғы өзгерту уақыт белгісін жазады. 09:58-де басталған транзакция әлі ашық, 10:03-те коммиттеледі және өз басталған сәтінің уақыт белгісін алып жүреді. Келесі экспорт тек 10:00-ден жаңа жолдарды сұрайды және оны ешқашан көрмейді. Тасымалдау көлемі тамаша болды, ал деректер қате еді.

Бір жолды жоғалтқан экспортты бақылаңыз

SQL-ді емес, оқиғалар ретін бақылаңыз. Қолданба жолдың өзгеру уақытын транзакция басталғанда жазады, коммиттелгенде емес. Экспорттаушы транзакция әлі ашық кезде қабырға сағатының су белгісін оқиды. Содан кейін транзакция сақталған су белгісінен ескірек өзгеру уақытымен коммиттеледі. Тұтынушының келесі партиясы су белгісінен кейін басталады, сондықтан жол курсордың артында қалады және ешқашан қайта таңдалмайды.

Ештеңе қате жазбайды, өйткені ештеңе сәтсіз болған жоқ. Бұл осы санаттағы ақауды қымбат етеді: дельта ағыны жылдам, жол саны ақиқат көрінеді, ал жоғалған жол апталардан кейін ешкім қайталай алмайтын салыстыру билеті ретінде шығады.

Реттік нөмірлерде басқа себептен сол пішіндегі кемшілік бар. Монотонды ID мәндердің қалай бөлінгенін айтады, транзакциялардың қалай коммиттелгенін емес. Төмен нөмір алған транзакция жоғары нөмір алғаннан кейін коммиттелуі мүмкін, сондықтан бөлу ретіне негізделген курсор да тесік қалдыруы мүмкін.

Ағын орындауға тиіс бес уәде

Тасымалдауды таңдамас бұрын бастапқы жүйеден бес тармақтан тұратын шарт сұраңыз. Қандай да бір тармақ жетіспесе, сізде өзгерістер ағыны емес, эвристика бар.

  • Қамту: кірістірулер, жаңартулар және жоюлар, әрқайсысы қолдану үшін қажетті тұрақты кілтпен.
  • Шекара: курсор мәнінің мағынасы және дәйекті партияның неден тұратыны.
  • Дәйектілік: үйлесімсіз бастапқы күйлерді араластырмай байланысты кестелердің қалай оқылатыны.
  • Сақтау: ажыратылған тұтынушы сақталған орнынан қанша уақыт жалғастыра алады.
  • Қайта инициализация: сол орын жарамсыз болған кездегі қолдау көрсетілген толық snapshot.

Қолдау көрсетілген механизм бесеуін де қанағаттандыра алады. SQL Server-дің өзгерістерді бақылау құжаттамасы нақты жарияланған мысал: ол ең төменгі жарамды нұсқаны анықтайды, өзгерістермен қатар жоюларды да жазады және валидацияны, нұсқаны түсіруді және байланысты өзгеріс сұрауларын қамтитын snapshot транзакциясын сипаттайды. Бұл бастапқы жүйеден талап ету керек нәрсенің мысалы, басқа қозғалтқышқа қоюға болатын синтаксис емес.

Бақылау нүктесін құбырдың бөлігі ретінде жобалаңыз

Тұтынушының сақталған орны нақты күй машинасы, сондықтан оны солай жазыңыз. Курсор тек партияны қолданып, мақсатты транзакцияны коммиттеген жұмыс ағыны арқылы ғана ілгері жылжи алады.

cursor  = durable_checkpoint()          # last fully applied position
batch   = extract(cursor, upper_bound)  # one consistent batch
apply(batch)                            # idempotent at the target
commit()
checkpoint(batch.upper_bound)           # only now

Жеткізу жарты жолда сәтсіз болса, жаңа бастапқы орын ойлап таппай, сол партияны салыстырыңыз. Неғұрлым жаңа жоғарғы шекарамен қайта алу ішінара қолданудың тұрақты ойыққа айналу жолы. Айна ережесі екінші жақта да қолданылады: мақсатта идемпотентті қолдану қайталауларды болдырмайды және алу ешқашан көрмеген өзгеріс үшін ештеңе жасамайды.

Жоюларға жазба керек, қорытынды емес

Әлі бар жолдарды салыстыру тұтынушыға қандай кілттердің жоғалғанын айта алмайды. Жоюларды ешқашан жазбайтын бастапқы жүйе сізге екі толық емес нұсқа қалдырады: diff үшін кілт тарихын жеткілікті ұзақ сақтау немесе кесте бойынша айқын толық салыстыруды іске қосу. Екеуі де құны бар дизайн шешімдері және ешбірі иесіз өмір сүрмейді.

Сақтау да сол тектес шешім. Әрбір қолдау көрсетілген өзгерістер ағынының терезесі бар; оны шартта көрсетіңіз және тұтынушының бақылау нүктесі оған жақындағанда ескертіңіз. Екі апталық үзілістен кейін оянған тұтынушы үнсіз ішінара партия алудың орнына "қайта инициализация қажет" деген айқын қатені оқуы керек.

Содан кейін дельтаның құнды болғанын өлшеңіз

Әр кілт пен хэшті салыстыруға қайта оралу кейде дұрыс және оның қанша тұратынын білу керек. Сіз әлі де әр жол туралы ақпаратты тасымалдайсыз, хэштер кестеаралық дәйекті snapshot бермейді, ал хэш схемасы ұсыну мен қақтығыстар туралы өз сұрақтарын әкеледі. Тексерілетін шекарамен азырақ байт — мақсат; коммиттелген өзгерісті үнсіз түсіріп кететін азырақ байт мүлде дельта емес.

Соңғы өзгерту бағаны — белгі. Кеш коммитті, жоюды және ұзақ үзілісті бастан өткерген курсор — шарт.

Қатысты мақалалар