A delta feed kihagyja a késői commitokat: építs megbízható kurzort
Egy sor későn érkezett, mert a vízjel nem commit-határ volt. Járd végig a hibát, majd definiáld a lefedettséget, a határt, a megőrzést és a biztonságos folytatást.
Íme egy hiba, amelyet kétszer láttam, két különböző motorban. Egy export 10:00-kor fut, és rögzíti a legmagasabb általa látott utolsó módosítási időbélyeget. Egy 09:58-kor indult tranzakció még nyitva van, 10:03-kor commitol, és a kezdete pillanatából származó időbélyeget hordoz. A következő export csak a 10:00-nál újabb sorokat kéri, és soha nem látja. Az átvitel mérete kiváló volt, az adat pedig hibás.
Kövesd végig az exportot, amely elveszített egy sort
Az események sorrendjét kövesd, ne az SQL-t. Az alkalmazás a sor módosítási idejét a tranzakció kezdetekor írja, nem a commitkor. Az exportáló a falióra-vízjelet olvassa, miközben a tranzakció még nyitva van. Aztán a tranzakció a mentett vízjelnél régebbi módosítási idővel commitol. A fogyasztó következő kötege a vízjel után indul, így a sor a kurzor mögött marad, és soha többé nem lesz kiválasztva.
Semmi nem naplóz hibát, mert semmi nem hibázott. Ez teszi ezt a hibacsoportot drágává: a delta feed gyors, a sorszámok hihetőnek tűnnek, és a hiányzó sor hetekkel később egyeztetési jegy formájában bukkan fel, amelyet senki sem tud reprodukálni.
A sorszámok ugyanilyen formájú hibát hordoznak más okból. A monoton ID azt mondja meg, milyen sorrendben osztották ki az értékeket, nem azt, milyen sorrendben commitoltak a tranzakciók. Egy alacsony számot kapott tranzakció commitolhat egy magas számot kapott után, ezért a kiosztási sorrendre épülő kurzor is hagyhat lyukat.
Öt ígéret, amelyet a feednek teljesítenie kell
Mielőtt szállítást választasz, kérj a forrásrendszertől öt kikötésből álló szerződést. Ha bármelyik hiányzik, heurisztikád van, nem változásfeed.
- Lefedettség: beszúrások, frissítések és törlések, mindegyik az alkalmazásához szükséges stabil kulccsal.
- Határ: mit jelent egy kurzorérték, és mit tartalmaz egy konzisztens köteg.
- Konzisztencia: hogyan olvashatók a kapcsolódó táblák összeférhetetlen forrásállapotok keverése nélkül.
- Megőrzés: meddig folytathatja egy leválasztott fogyasztó a mentett pozíciójáról.
- Újrainicializálás: támogatott teljes pillanatkép arra az esetre, amikor az a pozíció már nem érvényes.
Egy támogatott mechanizmus mind az ötöt teljesítheti. Az SQL Server változáskövetési dokumentációja egy konkrét, publikált példa: meghatároz egy minimális érvényes verziót, rögzíti a törléseket és a változásokat, és leír egy pillanatkép-tranzakciót, amely átfogja az ellenőrzést, a verzió rögzítését és a kapcsolódó változáslekérdezéseket. Példa arra, mit kell megkövetelni egy forrástól, nem olyan szintaxis, amelyet más motorba illeszthetsz.
Tervezd az ellenőrzőpontot a pipeline részének
A fogyasztó mentett pozíciója az igazi állapotgép, ezért így is írd le. A kurzor csak azon a munkafolyamaton haladhat át, amely már alkalmazta a köteget és commitolta a cél-tranzakciót.
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
Ha a kézbesítés félúton meghiúsul, ugyanazt a köteget egyeztesd, ne találj ki új forráspozíciót. Az újabb felső határral való újrakinyerés az az út, amelyen a részleges alkalmazás állandó réssé válik. A tükörszabály a másik oldalon is érvényes: az idempotens alkalmazás a célon megakadályozza a duplikátumokat, és semmit nem tesz egy olyan változásért, amelyet a kinyerés soha nem látott.
A törlésekhez nyilvántartás kell, nem következtetés
A még létező sorok összehasonlítása nem tudja megmondani a fogyasztónak, mely kulcsok tűntek el. Egy forrás, amely soha nem rögzít törléseket, két tökéletlen lehetőséget hagy: elég sokáig tartani a kulcselőzményeket a diffhez, vagy ütemezetten explicit teljes egyeztetést futtatni. Mindkettő költséggel járó tervezési döntés, és egyik sem létezik, ha nincs gazdája.
A megőrzés ugyanilyen döntés. Minden támogatott változásfeednek ablaka van; nyilatkozz róla a szerződésben, és figyelmeztess, amikor egy fogyasztó ellenőrzőpontja közeledik hozzá. A két hét kiesés után felébredő fogyasztónak világos hibát kell olvasnia: "újrainicializálás szükséges", ahelyett hogy csendben részleges köteget kapna.
Aztán mérd meg, megérte-e a delta
Visszatérni minden kulcs és hash összehasonlításához néha helyes, és érdemes tudni, mennyibe kerül. Továbbra is minden sorról adatot viszel át, a hash-ek nem adnak konzisztens pillanatképet a táblákon át, és a hash-séma saját kérdéseket hoz a reprezentációról és az ütközésekről. Kevesebb bájt ellenőrizhető határral a cél; kevesebb bájt, amely csendben elejt egy commitolt változást, egyáltalán nem delta.
Az utolsó módosítás oszlopa nyom. A kurzor, amely túlél egy késői commitot, egy törlést és egy hosszú kiesést, szerződés.