Ären Delta-Feed verpasst spéit Commits: baut en zouverlässege Cursor
Eng Zeil koum ze spéit, well de Waassermierk keng Commit-Grenz war. Verfollegt de Feeler an definéiert dann Ofdeckung, Grenz, Opbewahrung an eng sécher Fortsetzung.
Hei ass e Feeler, deen ech zweemol gesinn hunn, an zwou verschiddene Maschinnen. En Export leeft um 10:00 a registréiert deen héchsten Zäitstempel vun der leschter Ännerung, deen en gesinn huet. Eng Transaktioun, déi um 09:58 ugefaangen huet, ass nach oppen, committ um 10:03 a dréit en Zäitstempel aus dem Ament, wou se ugefaangen huet. Den nächsten Export freet just no Zeilen, déi méi nei wéi 10:00 sinn, a gesäit se ni. D'Transfergréisst war exzellent an d'Donnéeë waren falsch.
Verfollegt den Export, deen eng Zeil verluer huet
Verfollegt d'Reiefolleg vun den Evenementer an net de SQL. D'Applikatioun schreift d'Ännerungszäit vun der Zeil beim Ufank vun der Transaktioun, net beim Commit. Den Exporteur liest e Wandauer-Waassermierk, während d'Transaktioun nach oppen ass. Duerno committ d'Transaktioun mat enger Ännerungszäit, déi méi al ass wéi de gespäicherte Waassermierk. Den nächste Batch vum Konsument fänkt no dem Waassermierk un, dofir bleift d'Zeil hannert dem Cursor a gëtt ni méi gewielt.
Näischt loggt e Feeler, well näischt feelgeschloen ass. Dat mécht dës Klass vu Feeler deier: den Delta-Feed ass séier, d'Zuelen vun den Zeilen gesinn plausibel aus, an déi feelend Zeil daucht Woche méi spéit als Ofstëmmungsticket op, deen keen reproduzéiere kann.
D'Sequenznummeren hunn déi selwecht Form vu Mankement aus engem anere Grond. Eng monoton ID seet Iech d'Reiefolleg, an där Wäerter verdeelt goufen, net d'Reiefolleg, an där Transaktiounen committ hunn. Eng Transaktioun, déi eng niddreg Nummer geholl huet, kann no enger mat enger héijer Nummer committen, dofir kann e Cursor, deen op der Verdeelreiefolleg baséiert, och en Lach hannerloossen.
Fënnef Versprieche, déi de Feed mussen erfëllt ginn
Ier Dir en Transport auswielt, freet d'Quellsystem ëm e Kontrakt mat fënnef Klauselen. Wann eng Klausel feelt, hutt Dir eng Heuristik an net e Change Feed.
- Ofdeckung: Inserten, Updaten an Deletes, jiddwereen mat dem stabile Schlëssel, deen zum Uwenden noutwenneg ass.
- Grenz: wat e Cursorwäert bedeit a wat e konsequenten Batch enthält.
- Konsistenz: wéi verwandt Tabellen gelies ginn, ouni onvereinbar Quellzoustänn ze vermëschen.
- Opbewahrung: wéi laang en ofgetrennte Konsument vu senger gespäicherter Positioun ka virufueren.
- Reinitialiséierung: e ënnerstëtzten kompletten Snapshot, wann déi Positioun net méi gülteg ass.
En ënnerstëtzte Mechanismus kann all fënnef erfëllen. D'Dokumentatioun vum SQL Server iwwer Change Tracking ass e konkreet verëffentlecht Beispill: se definéiert eng minimal gülteg Versioun, registréiert Deletes souwéi Ännerungen a beschreift eng Snapshot-Transaktioun, déi Validéierung, Versiounserfaassung an déi associéiert Ännerungsufroen ëmspaant. Et ass e Beispill dofir, wat ee vun enger Quell verlaange soll, net Syntax, déi Dir an eng aner Maschinn peche kënnt.
Designt de Checkpoint als Deel vun der Pipeline
Déi gespäichert Positioun vum Konsument ass déi richteg Zoustandmaschinn, also schreift se als sou eng. De Cursor däerf nëmme weiderkommen duerch de Workflow, deen de Batch schonn ugewandt an d'Ziltransaktioun committ huet.
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
Wann d'Liwwerung um hallwe Wee feelgeet, gläicht dee selwechte Batch of, amplaz eng nei Quellpositioun ze erwaarden. Nei extrahéieren mat enger frëscherer ieweschter Grenz ass de Wee, op deem eng deelweis Uwendung zu engem permanente Lach gëtt. D'Spillregel gëllt och op der anerer Säit: idempotent Uwenden um Zil verhënnert Duplikater an däit näischt fir eng Ännerung, déi d'Extraktioun ni gesinn huet.
Deletes brauchen Opzeechnungen, keng Schlussfolgerungen
Zeilen, déi nach existéieren, ze vergläichen, kann engem Konsument net soen, wéi eng Schlësselen verschwonne sinn. Eng Quell, déi ni Deletes registréiert, léisst Iech zwou onvollkomme Méiglechkeeten: eng Schlësselhistorie laang genuch halen fir en Diff, oder eng explizit komplett Ofstëmmung no Plang lafe loossen. Béid si Designentscheedungen mat Käschten, an et gëtt keng, wann keen se besëtzt.
Opbewahrung ass déi selwecht Zort Entscheedung. All ënnerstëtzte Change Feed huet eng Fënster; deklaréiert se am Kontrakt a warnt, wann de Checkpoint vun engem Konsument sech se nämert. E Konsument, deen no enger zweiwocheger Ënnerbriechung erwächt, soll eng kloer Feeler "Reinitialiséierung néideg" liesen, amplaz stëll en Deelbatch ze kréien.
Dann moosst, ob den Delta et wäert war
Zeréck op de Verglach vun all Schlëssel an Hash ass heiansdo richteg, an et ass wäert ze wëssen, wat et kascht. Dir iwwerdrot nach ëmmer Informatioun iwwer all Zeil, Hashes ginn Iech keen konsequenten Snapshot iwwer Tabellen, an e Hashschema bréngt seng eege Froen iwwer Representatioun a Kollisiounen. Manner Bytes mat enger iwwerpréifbarer Grenz ass d'Zil; manner Bytes, déi stëll eng committ Ännerung fale loossen, ass iwwerhaapt keen Delta.
Eng Läscht-Ännerungs-Kolonn ass en Hiweis. E Cursor, deen e spéide Commit, en Delete an eng laang Ënnerbriechung iwwerlieft, ass e Kontrakt.