Delta-syötteesi jättää myöhäiset commitit väliin: rakenna luotettava kursori
Yksi rivi saapui myöhässä, koska vesileima ei ollut commitin raja. Käy epäonnistuminen läpi ja määritä sitten kattavuus, raja, säilytys ja turvallinen jatkaminen.
Tässä on epäonnistuminen, jonka olen nähnyt kaksi kertaa, kahdessa eri moottorissa. Vienti ajetaan kello 10:00 ja se tallentaa korkeimman näkemänsä viimeisen muokkauksen aikaleiman. Yksi kello 09:58 alkanut transaktio on vielä auki, commitoituu kello 10:03 ja kantaa aikaleimaa alkamishetkestään. Seuraava vienti pyytää vain rivejä, jotka ovat uudempia kuin 10:00, eikä näe sitä koskaan. Siirron koko oli erinomainen ja data väärää.
Seuraa vientiä, joka menetti rivin
Seuraa tapahtumien järjestystä, älä SQL:ää. Sovellus kirjoittaa rivin muokkausajan transaktion alkaessa, ei commitoituessa. Viejä lukee seinäkellon vesileimaa, kun transaktio on vielä auki. Sitten transaktio commitoituu muokkausajalla, joka on vanhempi kuin tallennettu vesileima. Kuluttajan seuraava erä alkaa vesileiman jälkeen, joten rivi jää kursorin taakse eikä sitä valita enää koskaan.
Mikään ei kirjaa virhettä, koska mikään ei epäonnistunut. Juuri se tekee tästä virheluokasta kalliin: delta-syöte on nopea, rivimäärät näyttävät uskottavilta ja puuttuva rivi nousee esiin viikkoja myöhemmin täsmäytystikettinä, jota kukaan ei pysty toistamaan.
Järjestysnumeroissa on sama vian muoto toisesta syystä. Monotoninen ID kertoo, missä järjestyksessä arvot jaettiin, ei missä järjestyksessä transaktiot commitoituivat. Transaktio, joka otti pienen numeron, voi commitoitua sen jälkeen, joka otti suuren, joten jakamisjärjestykseen perustuva kursori voi myös jättää aukon.
Viisi lupausta, jotka syötteen on annettava
Ennen kuljetuksen valintaa pyydä lähdejärjestelmältä sopimus, jossa on viisi lauseketta. Jos jokin puuttuu, sinulla on heuristiikka, ei muutosvirta.
- Kattavuus: lisäykset, päivitykset ja poistot, kukin tarvittavan vakaan avaimen kanssa.
- Raja: mitä kursorin arvo tarkoittaa ja mitä johdonmukainen erä sisältää.
- Johdonmukaisuus: miten liittyvät taulut luetaan sekoittamatta yhteensopimattomia lähdetiloja.
- Säilytys: kuinka kauan irrotettu kuluttaja voi jatkaa tallennetusta sijainnistaan.
- Uudelleenalustus: tuettu täysi tilannekuva, kun sijainti ei enää ole kelvollinen.
Tuettu mekanismi voi täyttää kaikki viisi. SQL Serverin muutosten seurannan dokumentaatio on yksi konkreettinen julkaistu esimerkki: se määrittelee pienimmän kelvollisen version, tallentaa poistot sekä muutokset ja kuvaa tilannekuvatransaktion, joka kattaa validoinnin, version tallennuksen ja siihen liittyvät muutoskyselyt. Se on esimerkki siitä, mitä lähteeltä pitää vaatia, ei syntaksia, jonka voi liittää toiseen moottoriin.
Suunnittele tarkistuspiste osaksi putkea
Kuluttajan tallennettu sijainti on todellinen tilakone, joten kirjoita se sellaiseksi. Kursori saa edetä vain sen työnkulun kautta, joka on jo soveltanut erän ja commitoinut kohdetransaktion.
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
Jos toimitus epäonnistuu puolivälissä, täsmäytä sama erä sen sijaan että keksit uuden lähdesijainnin. Uudelleenpoiminta tuoreemmalla ylärajalla on se tapa, jolla osittainen soveltaminen muuttuu pysyväksi aukoksi. Peilisääntö pätee myös toisella puolella: idempotentti soveltaminen kohteessa estää duplikaatit eikä tee mitään muutokselle, jota poiminta ei koskaan nähnyt.
Poistot tarvitsevat tietueita, eivät johtopäätöksiä
Vielä olemassa olevien rivien vertailu ei voi kertoa kuluttajalle, mitkä avaimet katosivat. Lähde, joka ei koskaan tallenna poistoja, jättää sinulle kaksi puutteellista vaihtoehtoa: pitää avainhistoriaa riittävän kauan diffiä varten tai ajaa selkeä täysi täsmäytys aikataulun mukaan. Molemmat ovat kustannuksellisia suunnitteluvalintoja, eikä kumpaakaan ole olemassa, ellei joku omista sitä.
Säilytys on samanlainen päätös. Jokaisella tuetulla muutosvirralla on ikkuna; ilmoita se sopimuksessa ja varoita, kun kuluttajan tarkistuspiste lähestyy sitä. Kuluttajan, joka herää kahden viikon katkoksen jälkeen, pitäisi lukea selkeä virhe "uudelleenalustus tarvitaan" sen sijaan että saa hiljaa osittaisen erän.
Mittaa sitten, kannattiko delta
Paluu jokaisen avaimen ja hashin vertailuun on joskus oikein, ja kannattaa tietää, mitä se maksaa. Siirrät edelleen tietoa jokaisesta rivistä, hashit eivät anna johdonmukaista tilannekuvaa taulujen yli ja hash-kaavio tuo mukanaan omat kysymyksensä esitystavasta ja törmäyksistä. Vähemmän tavuja tarkistettavalla rajalla on tavoite; vähemmän tavuja, jotka hiljaa pudottavat commitoidun muutoksen, ei ole lainkaan delta.
Viimeisen muokkauksen sarake on vihje. Kursori, joka selviää myöhäisestä commitista, poistosta ja pitkästä katkoksesta, on sopimus.