Ево грешке коју сам видео два пута, у два различита мотора. Извоз се покреће у 10:00 и бележи највиши временски печат последње измене који је видео. Једна трансакција која је почела у 09:58 још је отворена, комитује се у 10:03 и носи временски печат из тренутка када је почела. Следећи извоз тражи само редове новије од 10:00 и никада је не види. Величина преноса је била одлична, а подаци погрешни.

Прођите кроз извоз који је изгубио ред

Пратите редослед догађаја, а не SQL. Апликација уписује време измене реда када трансакција почне, а не када се комитује. Извозник чита водени жиг по зидном сату док је та трансакција још отворена. Затим се трансакција комитује са временом измене старијим од сачуваног воденог жига. Следећи пакет потрошача почиње после воденог жига, па ред остаје иза курсора и никада више неће бити изабран.

Ништа не бележи грешку јер ништа није пало. То ову класу грешака чини скупом: делта ток је брз, бројеви редова изгледају уверљиво, а ред који недостаје искрсне недељама касније као тикет за усклађивање који нико не може да репродукује.

Редни бројеви имају исти облик мане из другог разлога. Монотон ID говори вам редослед доделе вредности, не редослед којим су се трансакције комитовале. Трансакција која је узела низак број може се комитовати након оне која је узела висок, па и курсор заснован на редоследу доделе може оставити рупу.

Пет обећања која ток мора да да

Пре него што изаберете транспорт, тражите од изворног система уговор са пет клаузула. Ако било која клаузула недостаје, имате хеуристику, а не ток промена.

  • Покривеност: уметања, измене и брисања, свако са стабилним кључем потребним за примену.
  • Граница: шта значи вредност курсора и шта садржи конзистентан пакет.
  • Конзистентност: како се читају повезане табеле без мешања некомпатибилних стања извора.
  • Задржавање: колико дуго искључен потрошач може да настави са своје сачуване позиције.
  • Реиницијализација: подржан потпун снимак за када та позиција више није важећа.

Подржан механизам може да задовољи свих пет. Документација SQL Server-а о праћењу промена један је конкретан објављен пример: дефинише минималну важећу верзију, бележи брисања као и измене и описује трансакцију снимка која обухвата валидацију, снимање верзије и повезане упите промена. То је пример шта тражити од извора, а не синтакса коју можете залепити у други мотор.

Дизајнирајте контролну тачку као део цевовода

Сачувана позиција потрошача је права државна машина, па је тако и напишите. Курсор може да напредује само кроз ток рада који је већ применио пакет и комитовао циљну трансакцију.

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 или покретати експлицитно потпуно усклађивање по распореду. Оба су дизајнерске одлуке са ценом и ниједна не постоји ако је неко не поседује.

Задржавање је иста врста одлуке. Сваки подржан ток промена има прозор; наведите га у уговору и упозорите када се контролна тачка потрошача приближи њему. Потрошач који се пробуди након двонедељног прекида треба да прочита јасну грешку „потребна је реиницијализација“, а не да тихо добије делимичан пакет.

Затим измерите да ли је делта била вредна

Враћање на поређење сваког кључа и хеша понекад је исправно и вреди знати колико кошта. И даље преносите информације о сваком реду, хешеви вам не дају конзистентан снимак кроз табеле, а хеш шема носи своја питања о репрезентацији и колизијама. Мање бајтова са проверљивом границом је циљ; мање бајтова који тихо испусте комитовану промену није никаква делта.

Колона последње измене је наговештај. Курсор који преживи касан комит, брисање и дуг прекид је уговор.

Повезани чланци