Еве неуспех што сум го видел двапати, во два различни мотори. Извозот работи во 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 или да извршите експлицитно целосно усогласување по распоред. Двете се дизајнерски одлуки со цена и ниту една не постои ако некој не ја поседува.

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

Потоа измерете дали делтата вредеше

Враќањето на споредување на секој клуч и хаш понекогаш е правилно и вреди да се знае колку чини. Сè уште пренесувате информации за секој ред, хашовите не ви даваат конзистентен моментален снимок меѓу табелите, а хаш шемата ги носи своите прашања за претставување и судири. Помалку бајти со проверлива граница е целта; помалку бајти што тивко испуштаат комитирана промена воопшто не се делта.

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

Поврзани статии