Jūsų delta srautas praleidžia vėlyvus commit'us: sukurkite patikimą kursorių
Viena eilutė atėjo vėlai, nes vandens žymė nebuvo commit riba. Peržiūrėkite gedimą, tada apibrėžkite aprėptį, ribą, saugojimą ir saugų tęsimą.
Štai gedimas, kurį mačiau du kartus, dviejuose skirtinguose varikliuose. Eksportas paleidžiamas 10:00 ir įrašo didžiausią matytą paskutinio pakeitimo laiko žymą. Viena 09:58 prasidėjusi transakcija dar atidaryta, committinama 10:03 ir neša laiko žymą nuo savo pradžios. Kitas eksportas prašo tik eilučių, naujesnių nei 10:00, ir niekada jos nepamato. Perkėlimo dydis buvo puikus, o duomenys klaidingi.
Peržiūrėkite eksportą, kuris prarado eilutę
Sekite įvykių tvarką, o ne SQL. Programa įrašo eilutės pakeitimo laiką transakcijos pradžioje, o ne commit metu. Eksportuotojas skaito sieninio laikrodžio vandens žymę, kol transakcija dar atidaryta. Tada transakcija committinama su pakeitimo laiku, senesniu už išsaugotą vandens žymę. Kito vartotojo paketo pradžia yra po vandens žymės, todėl eilutė lieka už kursoriaus ir niekada nebus pasirinkta dar kartą.
Niekas neįrašo klaidos, nes niekas nesugedo. Būtent tai daro šią klaidų klasę brangią: delta srautas greitas, eilučių skaičiai atrodo patikimi, o trūkstama eilutė išnyra po savaičių kaip derinimo bilietas, kurio niekas negali atkurti.
Sekos numeriai turi tą pačią defekto formą dėl kitos priežasties. Monotoninė ID nurodo reikšmių priskyrimo tvarką, o ne transakcijų commit tvarką. Transakcija, paėmusi mažą numerį, gali būti committinta po tos, kuri paėmė didelį, todėl kursorių, pagrįstą priskyrimo tvarka, taip pat gali palikti skylę.
Penki pažadai, kuriuos srautas turi įvykdyti
Prieš rinkdamiesi transportą, paprašykite šaltinio sistemos sutarties su penkiomis sąlygomis. Jei kurios nors trūksta, turite euristiką, o ne pakeitimų srautą.
- Aprėptis: įterpimai, atnaujinimai ir trynimai, kiekvienas su stabiliu raktu, reikalingu jam pritaikyti.
- Riba: ką reiškia kursoriaus reikšmė ir ką sudaro nuoseklus paketas.
- Nuoseklumas: kaip skaitomos susijusios lentelės nemaišant nesuderinamų šaltinio būsenų.
- Saugojimas: kiek laiko atjungtas vartotojas gali tęsti nuo išsaugotos pozicijos.
- Reinicializavimas: palaikomas visas momentinis vaizdas, kai ta pozicija nebegalioja.
Palaikomas mechanizmas gali patenkinti visus penkis. SQL Server pakeitimų stebėjimo dokumentacija yra vienas konkretus paskelbtas pavyzdys: ji apibrėžia minimalią galiojančią versiją, įrašo trynimą ir pakeitimus, aprašo momentinio vaizdo transakciją, apimančią patvirtinimą, versijos užfiksavimą ir susijusius pakeitimų užklausas. Tai pavyzdys, ko reikalauti iš šaltinio, o ne sintaksė, kurią galima įklijuoti į kitą variklį.
Projektuokite kontrolinį tašką kaip dujotiekio dalį
Išsaugota vartotojo pozicija yra tikroji būsenos mašina, todėl taip ją ir aprašykite. Kursorius gali judėti į priekį tik per darbo eigą, kuri jau pritaikė paketą ir committino tikslinę transakciją.
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
Jei pristatymas sugenda pusiaukelėje, sutaikykite tą patį paketą, o ne išgalvokite naują šaltinio poziciją. Pakartotinis išgavimas su naujesne viršutine riba yra kelias, kuriuo dalinis pritaikymas tampa nuolatine spraga. Veidrodžio taisyklė galioja ir kitoje pusėje: idempotentinis pritaikymas tiksle apsaugo nuo dublikatų ir nieko nedaro pakeitimui, kurio išgavimas niekada nematė.
Trynimams reikia įrašų, o ne išvadų
Dar egzistuojančių eilučių palyginimas negali pasakyti vartotojui, kurie raktai dingo. Šaltinis, kuris niekada neįrašo trynimų, palieka dvi netobulas galimybes: laikyti raktų istoriją pakankamai ilgai diff'ui arba pagal grafiką paleisti aiškų visišką sutaikinimą. Abi yra projektiniai sprendimai su kaina, ir nė vieno nėra, jei jo niekas nevaldo.
Saugojimas yra toks pat sprendimas. Kiekvienas palaikomas pakeitimų srautas turi langą; nurodykite jį sutartyje ir įspėkite, kai vartotojo kontrolinis taškas jam artėja. Vartotojas, pabudęs po dviejų savaičių pertraukos, turėtų perskaityti aiškią klaidą "reikia reinicializuoti", o ne tyliai gauti dalinį paketą.
Tada išmatuokite, ar delta buvo verta
Grįžimas prie kiekvieno rakto ir maišos palyginimo kartais yra teisingas, ir verta žinoti, kiek tai kainuoja. Jūs vis dar perduodate informaciją apie kiekvieną eilutę, maišos neduoda nuoseklaus momentinio vaizdo tarp lentelių, o maišos schema atsineša savo klausimus apie atvaizdavimą ir susidūrimus. Mažiau baitų su patikrinama riba yra tikslas; mažiau baitų, kurie tyliai numeta committintą pakeitimą, visai nėra delta.
Paskutinio pakeitimo stulpelis yra užuomina. Kursorius, kuris išgyvena vėlyvą commit'ą, trynimą ir ilgą pertrauką, yra sutartis.