Ito ay isang pagkabigo na nakita kong nangyari nang dalawang beses, sa dalawang magkaibang engine. Isang export ang tumatakbo sa 10:00 at itinatala ang pinakamataas na timestamp ng huling pagbabago na nakita nito. Isang transaksyon na nagsimula sa 09:58 ay bukas pa, nag-commit sa 10:03 at may dalang timestamp mula sa sandaling nagsimula ito. Ang susunod na export ay humihingi lamang ng mga hilerang mas bago sa 10:00 at hindi ito nakikita. Napakahusay ng laki ng paglilipat at mali ang datos.

Subaybayan ang export na nawalan ng isang hilera

Subaybayan ang pagkakasunod-sunod ng mga pangyayari, hindi ang SQL. Isinusulat ng aplikasyon ang oras ng pagbabago ng hilera kapag nagsimula ang transaksyon, hindi kapag nag-commit. Binabasa ng exporter ang watermark ng orasan sa dingding habang bukas pa ang transaksyong iyon. Pagkatapos ay nag-commit ang transaksyon na may oras ng pagbabago na mas luma kaysa sa naka-save na watermark. Nagsisimula ang susunod na batch ng consumer pagkatapos ng watermark, kaya nananatili ang hilera sa likod ng cursor at hindi na muling pipiliin.

Walang nagtatala ng error, dahil walang nabigo. Ito ang dahilan kung bakit mahal ang ganitong uri ng bug: mabilis ang delta feed, mukhang makatwiran ang bilang ng hilera, at ang nawawalang hilera ay lumilitaw pagkalipas ng mga linggo bilang isang tiket sa pagkakasundo na walang makapagreproduce.

Ang mga sequence number ay may parehong hugis ng depekto sa ibang dahilan. Ang monotonikong ID ay nagsasabi ng pagkakasunod-sunod ng paglalaan ng mga halaga, hindi ang pagkakasunod-sunod ng pag-commit ng mga transaksyon. Ang transaksyong kumuha ng mababang numero ay maaaring mag-commit pagkatapos ng kumuha ng mataas, kaya ang cursor na nakabatay sa pagkakasunod-sunod ng paglalaan ay maaari ring mag-iwan ng butas.

Limang pangako na dapat ibigay ng feed

Bago pumili ng transportasyon, humingi sa source system ng kontratang may limang sugnay. Kung may nawawalang sugnay, mayroon kang heuristika at hindi change feed.

  • Saklaw: mga insert, update at delete, bawat isa ay may stable na key na kailangan upang mailapat.
  • Hangganan: ano ang ibig sabihin ng halaga ng cursor at ano ang laman ng magkakatugmang batch.
  • Pagkakatugma: paano binabasa ang magkakaugnay na talahanayan nang hindi hinahalo ang hindi magkatugmang estado ng source.
  • Pagpapanatili: gaano katagal makapagpatuloy ang isang naka-disconnect na consumer mula sa naka-save na posisyon.
  • Muling pagsisimula: isang suportadong buong snapshot kapag hindi na valid ang posisyong iyon.

Maaaring tugunan ng isang suportadong mekanismo ang lahat ng lima. Ang dokumentasyon ng SQL Server tungkol sa pagsubaybay ng pagbabago ay isang konkretong nailathalang halimbawa: tinutukoy nito ang pinakamababang valid na bersyon, itinatala ang mga delete gayundin ang mga pagbabago, at inilalarawan ang isang snapshot na transaksyon na sumasaklaw sa validation, pagkuha ng bersyon at ang mga kaugnay na query ng pagbabago. Halimbawa ito ng dapat hilingin sa isang source, hindi syntax na maididikit sa ibang engine.

Idisenyo ang checkpoint bilang bahagi ng pipeline

Ang naka-save na posisyon ng consumer ang tunay na state machine, kaya isulat ito nang ganoon. Ang cursor ay makakaabante lamang sa pamamagitan ng workflow na nailapat na ang batch at na-commit ang target na transaksyon.

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

Kung mabigo ang paghahatid sa kalagitnaan, ituwid ang parehong batch sa halip na mag-imbento ng bagong posisyon ng source. Ang muling pagkuha na may mas bagong upper bound ang paraan kung paano nagiging permanenteng puwang ang bahagyang paglalapat. Nalalapat din ang mirror rule sa kabilang panig: pinipigilan ng idempotent na paglalapat sa target ang mga duplikado at walang ginagawa para sa pagbabagong hindi kailanman nakita ng pagkuha.

Ang mga delete ay nangangailangan ng talaan, hindi konklusyon

Ang paghahambing ng mga hilerang umiiral pa ay hindi makapagsasabi sa consumer kung aling mga key ang nawala. Ang source na hindi kailanman nagtatala ng mga delete ay nag-iiwan sa iyo ng dalawang di-perpektong pagpipilian: panatilihin ang kasaysayan ng key nang sapat na haba para sa diff, o magpatakbo ng tahasang buong pagkakasundo ayon sa iskedyul. Pareho itong desisyon sa disenyo na may gastos, at wala sa mga ito ang umiiral maliban kung may nagmamay-ari.

Ang pagpapanatili ay parehong uri ng desisyon. Bawat suportadong change feed ay may window; idahayag ito sa kontrata at magbabala kapag lumalapit dito ang checkpoint ng consumer. Ang consumer na nagising pagkatapos ng dalawang linggong pagkaantala ay dapat magbasa ng malinaw na error na "kailangan ng muling pagsisimula" sa halip na tahimik na tumanggap ng bahagyang batch.

Pagkatapos ay sukatin kung sulit ang delta

Ang pagbabalik sa paghahambing ng bawat key at hash ay minsang tama, at sulit malaman ang gastos nito. Naglilipat ka pa rin ng impormasyon tungkol sa bawat hilera, hindi nagbibigay ang mga hash ng magkakatugmang snapshot sa mga talahanayan, at ang iskema ng hash ay nagdadala ng sarili nitong mga tanong tungkol sa representasyon at banggaan. Mas kaunting byte na may mapatutunayang hangganan ang layunin; ang mas kaunting byte na tahimik na nagtatapon ng na-commit na pagbabago ay hindi delta.

Ang kolum ng huling pagbabago ay isang palatandaan. Ang cursor na nakakalampas sa huling commit, delete at mahabang pagkaantala ay isang kontrata.

Kaugnay na mga artikulo