Back to site
Since 2004, our University project has become the Internet's most widespread web hosting directory. Here we like to talk a lot about web servers, web development, networking and security services. It is, after all, our expertise. To make things better we've launched this science section with the free access to educational resources and important scientific material translated to different languages.

Multimaster replikacija-izazovi

Izazovi vezani za multimaster replikaciju

Brian Keating
Database Specialists, Inc.
http://www.dbspecialists.com

Uvod

Ovaj dokument sastoji se od dva glavna dela. Prvi deo daje osnovni pregled koncepata multimaster replikacije. Drugi deo opisuje neke vrlo specifične izazove koji su uočeni kod multimaster replikacije, kao i rešenja za te izazove.

Uopšteni pregled multimaster replikacije

Multimaster replikacija je uslužni program koji omogućava da se podaci u više baza podataka automatski sinhronizovano čuvaju. Na primer, u sistemu multimaster replikacije, ako se red ubaci u jednu od baza podataka u sistemu, taj red će se automatski propagirati svim ostalim bazama podataka u tom sistemu. Ažuriranja i brisanja podataka u bilo kojoj od baza podataka propagiraće se na isti način.

Okruženje multimaster replikacije podešeno je konfigurisanjem baza podataka da budu deo "replikacione grupe”. Jedna od baza podataka u grupi definisana je kao "lokacija master definicije", a sve druge baze podataka u grupi klasifikovane su kao “master lokacije”. Glavna razlika između ova dva tipa lokacije je u tome što većina administrativnih komandi replikacije mora da se pozove sa lokacije master definicije.

Postoje dva osnovna načina kako se transakcije propagiraju do udaljenih baza podataka - "sinhrono" i “asinhrono”. Sinhrona replikacija nastaje tako što se izazove da svaka transakcija odmah bude primenjena na sve master lokacije u grupi. Način da se ovo postigne jeste pomoću Oracle-ove dvofazne commit funkcionalnosti, kako bi se osiguralo da sve baze podataka u pitanju mogu da primene datu transakciju. Ukoliko bilo koja od lokacija u grupi ne može da prihvati transakciju (na primer, zato što je baza podatka lokacije oborena, ili je mrežna veza sa bazom podataka oborena), onda nijedna od master lokacija u replikacionoj grupi neće biti u stanju da prihvati transakciju - transakcija neće moći da se dogodi.

Asinhrona replikacija funkcioniše tako da su sve transakcije koje se dešavaju na lokaciji privremeno smeštene u bafer, zvani "odloženi red transakcije" ili deftran red. Periodično, recimo jednom u minutu, sve transakcije u deftran redu neke lokacije šalju se svim drugim lokacijama, putem "push" poslova. Ovi poslovi kreiraju se pozivanjem procedure "schedule_push". Konačno, transakcije u deftran redu koje su već poslate drugim lokacijama moraju da se periodično čiste, da deftran ne bi postao preveliki.

Ogromna većina potrošačkih lokacija koje koriste multimaster replikaciju koriste asinhronu replikaciju radije nego sinhronu. Jedan od razloga je to što je asinhrona replikacija dostupna mnogo duže; prvobitne verzije multimaster replikacije dozvoljavale su samo asinhrono propagiranje. Međutim, glavni razlog što se koristi asinhrona, jeste što ona ima mnogo prednosti u odnosu na sinhronu replikaciju.

Pre svega, asinhrona replikacija koristi mnogo manje propusnog opsega mreže i pruža bolje performanse od sinhrone replikacije. Osnovni razlog za to je što je ona efikasnija za skladištenje više transakcija i onda da ih sve propagira kao grupu, umesto da propagira svaku transakciju zasebno.

Ovo je naročito važno kada su u pitanju lokacije koje su veoma geografski udaljene (kao što je jedna lokacija u San Francisku, a druga u Njujorku). Drugi razlog za ovaj bolji propusni opseg i performanse jeste što postoji mnogo više overhead-a vezanog za sinhronu replikaciju, jer svaka transakcija zahteva da se uspostave posebne konekcije sa svim ostalim lokacijama u replikacionoj grupi. Za asinhronu replikaciju manje konekcija treba da se uspostavi, jer se transakcije propagiraju kao grupa.

Konačno, počevši sa Oracle 8.0. moguće je koristiti "paralelno propagiranje" (tj. propagiranje više od jedne transakcije istovremeno) sa asinhronom replikacijom. Ovo može znatno da poboljša performanse replikacije. Paralelno propagiranje nije primenjivo na sinhrone replikacije, jer je "stepen paralelizma" za propagiranje definisan u proceduri schedule_push (koju sinhrona replikacija ne koristi).

Međutim, najveća prednost asinhrone replikacije jeste u tome što pruža visoku raspoloživost replikacione grupe. Sa asinhronom replikacijom, ako jedna od lokacija u replikacionoj grupi padne, sve ostale lokacije i dalje će biti u mogućnosti da prihvataju ažuriranje - transakcije koje su obavljene na preostalim lokacijama samo će se "gomilati" u deftran redovima tih lokacija dok “oborena” lokacija ne postane dostupna.

S druge strane, sa sinhronom replikacijom, ukoliko bilo koja od lokacija postane nedostupna (na primer zbog pada baze podataka ili kraha mreže), onda nijedna od tih lokacija neće moći da se ažurira. To je zato što sa sinhronom replikacijom, svaka transakcija mora biti u stanju da se odmah primenjuje na sve lokacije u replikacionoj grupi, i naravno, ako je lokacija nedostupna, nijedna transakcija neće moći da se primeni na njoj. To znači da ne samo što sinhrona replikacija ne pruža nikakvu veću dostupnost bazi podataka, već ona zapravo može da obezbedi nižu dostupnost nego kada se koristi jedna baza podataka!

Uprkos svim prednostima koje pruža asinhrona replikacija, ona ima jednu veliku manu: asinhrona replikacija otvara mogućnost za konflikte podataka. Ovo je detaljno opisano u sledećem odeljku.

Izazovi vezani za multimaster replikaciju

U ovom odeljku razmotrićemo neke od krupnijih problema multimaster replikacije, i neka moguća rešenja. Pogotovo ćemo obratiti pažnju na rešavanje konflikta koristeći ekstremno kratke push intervale, delay_seconds parametar, kako da se nadzire replikacioni sistem, probleme s dodavanjem novih lokacija u replikacionu grupu, primenu DDL na replicirane objekte, korišćenje više replikacionih grupa i "brzi" metod čišćenja.

Mogućnosti konflikta u asinhronoj replikaciji

Zbog store-and-forward prirode asinhrone replikacije postoji mogućnost da dođe do nedoslednih promena podataka, iliti "konflikta". Postoje tri osnovne vrste konflikata, i najlakši način da se oni objasne jeste da se daju primeri.

Konflikt “ažuriranja” javlja se kada se isti red ažurira u dve (ili više) različitih baza podataka pre nego što bilo koje od tih ažuriranja može da se propagira na druge baze podataka. Na primer, recimo da je u replikacionoj grupi zakazano propagiranje jednom u minutu, a ima dve baze podataka u grupi - baza A i baza B. Recimo takođe da jedan određeni red (u obe baze podataka) ima vrednost 10 za jednu od svojih kolona.

Primer konflikta ažuriranja bio bi sledeći: u 09:00:04 h, korisnik se povezuje na bazu podataka A i ažurira vrednost tog reda na 20. U 09:00:23 h (pre nego što je promena u bazi A propagirana na bazu B) korisnik se povezuje na bazu podataka B i ažurira vrednost tog reda na 30. Kada Oracle pokuša da propagira ove promene (u 09:01:00 h) to će generisati grešku "konflikt ažuriranja", zato što je isti red izmenjen više puta - i zbog toga Oracle neće znati koju vrednost da koristi za taj red: 20 ili 30.

Konflikt "jedinstvenosti" javlja se kada će propagiranje podataka izazvati da dva različita reda imaju istu vrednost za jednu kolonu, kada ta kolona ima ograničenje jedinstvenosti. Na primer, pretpostavimo da koristite replikacionu grupu opisanu gore. Takođe pretpostavimo da jedna od repliciranih tabela u bazi podataka ima kolonu po imenu user_login_name, i da ta kolona ima ograničenje jedinstvenosti.

Konflikt jedinstvenosti može nastati na sledeći način: U 11:00:12 h, korisnik pod nazivom "John Smith” loguje se u bazu podataka A i ubacuje red sa kolonom user_login_name podešenom na "JOHNS". U 11:00:42 h, korisnik pod nazivom "John Stein" loguje se u bazu podataka B i ubacuje red sa kolonom user_login_name takođe podešenom na "JOHNS". U 11:01:00 h, kada Oracle pokuša da propagira te redove, generisaće se greška konflikt jedinstvenosti jer dva različita reda imaju istu vrednost za kolonu koja ima ograničenje jedinstvenosti.

Konflikt "brisanje" javlja se kada se jedan ili više redova izbriše iz jedne baze podataka, ali kada Oracle pokuša da propagira obrisano on ne može da pronađe sve redove u udaljenim bazama podataka. Ovo može biti ili zbog toga što su ti redovi već bili izbrisani, ili zbog toga što su vrednosti u tim redovima ažurirane.

Na primer, pretpostavimo da imate istu replikacionu grupu kao što smo gore naveli. Takođe, pretpostavimo da postoji jedan poseban red u repliciranoj tabeli koji ima vrednost "ABC123" za kolonu pod nazivom "ID_value". Do konflikta brisanja može doći na sledeći način: u 02:00:13 h, korisnik se loguje u bazu podataka A i briše taj red komandom “delete” odakle je ID_value = 'ABC123'. U 02:00:41 h, korisnik se prijavljuje u bazu podataka B i ažurira taj red, tako da se kolona ID_value podešava na vrednost "XYZ789". Kada Oracle pokuša da propagira komandu “delete”, to će generisati konflikt brisanja, jer taj red koji komanda pokušava da obriše više ne postoji (jer je kolona ID_value tog reda izmenjena).

Pošto postoji mogućnost konflikta podataka, Oracle je obezbedio "rukovaoce za rešenje konflikta" da pokuša da reši konflikte podataka. U principu, ovi rukovaoci za rešenje konflikta rade dobro za rešavanje konflikta ažuriranja, ali ne rade dobro za konflikt jedinstvenosti (i nema ponuđenih rukovaoca za konflikt brisanja). Takođe je moguće da napišete sopstvene rukovaoce za rešenje konflikta.

Za konflikte ažuriranja postoji širok spektar rukovalaca za rešavanje konflikta na raspolaganju, od kojih su neki korisniji od drugih. Jedan od najjednostavnijih od tih rukovalaca zove se "prioritet lokacije". S rukovaocem prioritet lokacije možete da odredite da ažuriranja na jednoj master lokaciji imaju prednost nad ažuriranjima na drugoj master lokaciji. U gorenavedenom primeru konflikta ažuriranja, ovaj rukovalac omogući će vam da precizirate (na primer) da baza A ima veći prioritet lokacije od baze B. Da je podešen rukovalac za rešavanje konflikta prioritet lokacije, onda se greška sukob ažuriranja opisana gore ne bi generisala. Pošto je rukovalac prioritet lokacije podešen, Oracle će znati koje ažuriranje da prihvati - koristiće vrednost 20, jer je baza podataka A ima veći prioritet od baze podataka B.

Drugi, bizarniji rukovalac za rešavanje konflikta ažuriranje naziva se "prosek". Kao što mu sam naziv ukazuje, ovaj rukovalac uzima prosečnu vrednost kolona koje su ažurirane. U primeru konflikta ažuriranja koji je naveden gore, ovaj rukovalac naveo bi Oracle da ažurira redove u obe baze podataka na 25, budući da je to prosek za 20 i 30.

Jedan od korisnijih rukovalaca za rešenje konflikta ažuriranje zove se "najnoviji timestamp". Ovaj rukovalac omogućava vam da odredite da, kada se desi konflikt ažuriranja, Oracle treba da primeni ažuriranje koje se najskorije dogodilo. U gorenavedenom konfliktu ažuriranja, Oracle će primeniti vrednost 30, jer se ažuriranje na 30 dogodilo kasnije (skorije), nego ažuriranje na 20.

Međutim, nekoliko stvari treba da imate na umu u vezi sa ovim rukovaocem, Prvo, da bi se koristio ovaj rukovalac svaka tabela koju će koristiti treba da ima kolonu “timestamp”. Pored toga, ta kolona treba da se ažurira trenutnim vremenom svaki put kada se desi ažuriranje u redu u toj tabeli. (U ovu svrhu mogu da se kreiraju okidači.)

Još jedna stvar koju treba imati na umu jeste da, ako imate baze podataka koje se nalaze u različitim geografskim vremenskim zonama, onda će sve te baze podataka morati da budu konfigurisane tako da koriste jednu vremensku zonu (kao što je srednje vreme po Griniču - GMT). Ako ne uradite ovo, onda će, ako ste imali jednu bazu podataka u Njujorku a drugu u San Francisku, timestamps u bazi podataka u Njujorku uvek biti tri sata ispred timestamps u bazi podataka u San Francisku. To bi značilo da će njujorška ažuriranja verovatno uvek biti primenjena u konfliktu, čak i ako bi se ona zapravo desila ranije u apsolutnom vremenu.

Na raspolaganju su samo dve metode rešavanja konflikata za konflikte jedinstvenosti. Možete ili da izazovete da se vrednost koja ima ograničenje jedinstvenosti izmeni u udaljenoj bazi podataka, ili jednostavno možete u potpunosti da odbacite taj red, tako da se on uopšte ne ubaci u udaljenu bazu podataka. Nijedna od ovih metoda neće rezultirati time da su podaci konzistentni u više baza podataka. Drugim rečima, čak i nakon upotrebe jednog od ovih metoda, i dalje će postojati razlike u podacima iz jedne baze podataka u poređenju s podacima iz druge baze podataka.

Čini se da je cela poenta multimaster replikacije to da se omogući da se istom skupu podataka pristupa iz više baza podataka, tako da nijedan od ovih metoda ne izgleda naročito korisno. Dakle, umesto da dozvoljavate da se konflikt jedinstvenosti desi i da onda pokušavate da ga rešite, možda ćete hteti da podesite svoju aplikaciju da potpuno izbegava takve konflikte. Način na koji izbegavate ove konflikte, međutim, zavisi od toga da li su vrednosti u pitanju automatski generisane od strane aplikacije ili ih ručno unosi krajnji korisnik.

Za vrednosti koje generiše aplikacija postoji nekoliko relativno direktnih i jednostavnih načina da se izbegne konflikt jedinstvenosti. Najjednostavniji od tih metoda podrazumeva upotrebu sekvenci. Na primer, recimo da vaša aplikacija automatski generiše jedinstvene numeričke vrednosti korisničkog ID-ja za nove korisničke naloge.

Jedan od načina da se izbegne mogućnost konflikta vrednosti korisničkih ID-jeva bio bi da se izazove da aplikacija generiše te vrednosti iz sekvenci, kao i da se osigura da će sekvence u svakoj bazi podataka koristiti vrednosti koje ne koriste sekvence ni u jednoj drugoj bazi podataka. U gorepomenutoj replikacionoj grupi, mogli biste da kreirate sekvencu u bazi podataka A koja počinje brojem 1 i povećava se za 10 svaki put, i mogli biste da kreirate sekvencu u bazi podataka B koja počinje sa 2 i povećava se za 10 svaki put.

To bi značilo da bi se svi brojevi koje generiše sekvenca u bazi podataka A završa vali brojem 1, a svi brojevi iz sekvence u bazi podataka B brojem 2. Dakle, ako bi apli kacija generisala svoje vrednosti korisničkog ID-ja od vrednosti koje su sadržane u sekvencama baza podataka, ne bi bilo mogućnosti da se isti korisnički ID generiše u obe baze podataka.

Nije lako izbeći konflikte jedinstvenosti sa vrednostima koje unosi krajnji korisnik, kao što su korisnička login imena. Osnovni razlog što je to tako teško jeste taj što su vrednosti koje unosi korisnik (po definiciji) vidljive krajnjem korisniku, tako da će forsiranje da te vrednosti postanu jedinstvene izazvati određene smetnje korisnicima. Na primer, možete da forsirate da korisnička login imena postanu jedinstvena tako što ćete dodati string specifičan za bazu podataka na korisničko login ime.

Na primer, ako je jedna od vaših baza podataka smeštena u Njujorku, mogli biste da dodate string "NY1" na bilo koje korisničko login ime koje je kreirano u njujorškoj bazi podataka. Baza podataka koja se nalazi u San Francisku može imati "SF1", dodato na svoja korisnička login imena. Dakle, u gorenavedenom primeru konflikta jedinstvenosti, recimo da se baza podataka A nalazi u San Francisku, a baza poataka B u Njujorku. To bi značilo da, kada John Smith stvori svoje login ime, ona će zapravo postati "JOHNSSF1", a kada John Stein napravi svoje login ime, ona postaje "JOHNSNY1". Naravno, aplikacija će tada morati da kaže obojici korisnika da su im korisnička imena sada JOHNSSF1 i JOHNSNY1.

To rešenje dobro funkcioniše za izbegavanje konflikta jedinstvenosti. Međutim, kao što možete da zamislite, mnogim korisnicima neće se svideti činjenica da njihova korisnička imena nisu u potpunosti pod njihovom kontrolom. Verovatno će se pitati: "Zašto moram da imam ovaj proizvoljni string nakačen na svoje login ime? Zašto jednostavno ne mogu da koristim login ime koje sam ukucao?” Naravno, nerviranje krajnjih korisnika obično je loše za posao, tako da ova metoda verovatno nije održivo rešenje u većini situacija.

Jedan drugi, egzotičniji način da se osiguraju jedinstvena login imena jeste da se kompletno korisničko login ime sastoji od dve zasebne kolone - jedne koja sadrži podatke unete od strane korisnika (kao što su JOHNS), i druge koja sadrži jedinstveni identifikator baze podataka (kao što je SF1). Ove dve kolone će se onda kombinovati u jedinstveni spojeni indeks.

Ovaj metod obezbedio bi da se isto login ime ne kreira u dve različite baze podataka, i takođe bi omogućio korisnicima da koriste login ime koje su oni sami odabrali. Međutim, ovaj metod primorao bi krajnje korisnike da unesu svoje identifikatore baze, kao i svoja login imena kada se prijavljuju. Aplikacija bi onda mogla da utvrdi koji od "JOHNS" naloga pokušava da se prijavi. Na nekim klijentskim lokacijama, pomenuto je da je traženje od krajnjih korisnika da daju dodatne informacije (osim svojih login imena i lozinki) potpuno neprihvatljivo; od krajnjih korisnika ne bi trebalo tražiti da se sete dodatnih, proizvoljnih podataka. Krajnji korisnici ne bi trebalo da brinu na kojoj su bazi podataka njihovi računi kreirani; ta vrsta informacije trebalo bi da im bude očigledna. Prema tome, ovaj metod takođe možda neće biti održivo rešenje, u zavisnosti od zahteva pojedinačnih klijenata.

Kao što je prethodno pomenuto, nema ponuđenih rukovalaca za rešenje konflikta brisanja. Dakle, ako je moguće da se pokrenu komande za brisanje na više baza podataka istovremeno u asinhronoj replikacionoj grupi, pre ili kasnije mogli biste da završite s nedoslednim podacima. Jedan pristup za izbegavanje konflikata brisanja podrazumeva projektovanje aplikacije tako da ona zapravo ne izdaje komande brisanja. Kada korisnik pokuša da izbriše red, aplikacija neće zaista izbrisati taj red, nego će “označiti” taj red za brisanje.

Ovaj metod takođe zahteva da aplikacija bude projektovana da filtrira redove koji su označeni za brisanje, tako da krajnjem korisniku izgleda kao da su ti redovi zaista izbrisani. Još jedno što ovaj metod zahteva jeste da svaka tabela koji koristi asinhronu replikaciju mora biti podešena s novom kolonom koja će se koristiti za vođenje evidencije o redovima koji su označeni za brisanje. Najzad, ovaj metod zahteva kreiranje uskladištene procedure koje čiste sve označene redove, i kreiranje poslova baze podataka da bi se pozvale te uskladištene procedure periodično na svakoj bazi podataka u replikacionoj grupi. Podrazumeva se, izbegavanje konflikta brisanja zahtevaće značajne promene u dizajnu aplikacije.

Postoji još jedan pristup za izbegavanje svih vrsta konflikata - ažuriranje, jedinstvenost i brisanje. Taj metod podrazumeva konfigurisanje aplikacije tako da ona samo piše u jednu bazu podataka u bilo koje vreme - a sve ostale baze podataka koristiće se samo za čitanja. Pošto se samo jedna baza podataka ažurira, neće biti mogućnosti za bilo koju vrstu konflikta podataka.

Ovaj pristup takođe zahteva da aplikacija bude programirana tako da ako baza podataka "za pisanje" padne, onda će aplikacija automatski početi da šalje zahteve pisanja nekoj drugoj bazi podataka. Inače će jedna baza podataka za pisanje završiti kao jedina tačka neuspeha u okruženju. Naravno, jedna značajna mana ove metode je to što zahteva velike promene u dizajnu aplikacije, a to nije nešto što administratori baza podataka obično mogu da kontrolišu.

Zaključak ove diskusije o konfliktima podataka u asinhronoj replikaciji je sledeći:

Ako planirate da koristite asinhronu replikaciju, vaša aplikacija od samog početka treba da bude dizajnirana s tim na umu, zato što asinhrona replikacija nije nešto što se može lako "dodati" naknadno.

Ekstremno kratki push intervali

Drugi problem koji je uočen kod asinhrone replikacije jeste taj što podešavanje push poslova da rade u veoma kratkim intervalima može da iskoristiti preteranu količinu sistemskih resursa. To je zato što pokretanje i zaustavljanje push poslova troši znatnu količinu CPU ciklusa, i očigledno što češće to mora da se uradi, više procesor mora da se napreže. Kada su push poslovi konfigurisani sa ekstremno kratkim intervalima, izgleda da to može zapravo izazvati da CPU zaostane. To jest, neće biti na raspolaganju dovoljno ciklusa da push poslovi počinju i prestaju po željenom tempu, a kamoli da se zapravo izvede pushing transakcija.

U takvoj situaciji, doći će do toga da će transakcijama biti potrebno sve duže i duže da se propagiraju na druge lokacije. Na primer, primetio sam da se, kada je schedule_push procedura konfigurisana sa intervalima od 1 ili 2 sekunde, kašnjenje propagiranja transakcija vremenom povećava. Počinje na oko 5 sekundi, onda se povećava do 7 sekundi, a zatim na 10, itd. Rešenje ovog problema jeste da se ne preteruje pri podešavanju push intervala - interval od jednog minuta najkraći je interval koji bih preporučio.

Parametar delay_seconds

Kao što je ranije pomenuto, asinhrona replikacija koristi push poslove da propagira transakcije na druge lokacije. Ovaj posao obično se okončava odmah nakon što završi s propagiranjem transakcija koje su trenutno u deftran redu. Međutim, jedan od parametara u schedule_push proceduri, parametar delay_seconds, omogućava vam da izazovete da push poslovi ostanu aktivni za određeni vremenski period, čak i nakon što su sve transakcije propagirane. Sudeći prema nekoliko dokumenata o replikaciji na Oracle-ovom web site-u, ovaj parametar takođe može da se koristi da izazove asinhronu replikaciju da simulira sinhrono propagiranje.

To sugeriše da će, ako koristite parametar delay_seconds, push posao stalno tražiti nove transakcije da propagira sve dok je posao aktivan. Kada bi to bio slučaj, čim bi nova transakcija ušla u deftran red, odmah bi je propagirao push posao. Međutim, ovaj parametar ne funkcioniše na taj način. Šta se zapravo dešava s ovim parametrom jeste da nakon što push posao završi propagiranje svojih transakcija, onda će zaspati (više ne obavlja push transakcije) na određeno vreme. Zatim će se probuditi, propagirati sve nove transakcije koje su ušle u red, i onda ponovo zaspati.

Sve dok nove transakcije ulaze u red, ovaj proces buđenje/spavanje nastaviće se u nedogled. Ako nikakve nove transakcije ne uđu u red za ceo vremenski period naveden u parametru delay_seconds, onda će se push posao završiti. Vreme koliko će posao spavati određuje vrednost delay_seconds parametra - ako je vrednost 60 sekundi ili više, onda je interval spavanja 60 sekundi. Ako je vrednost manja od 60 sekundi, onda je interval spavanja isti kao vrednost delay_seconds.

onda je interval spavanja isti kao vrednost delay_seconds. Kada bi to bio jedini problem sa parametrom delay_seconds, onda bi to i dalje bila korisna karakteristika asinhrone replikacije, jer kao što sam već pomenuo gore, počinjanje i zaustavljanje push poslova troši dosta sistemskih resursa. Međutim, postoje i drugi problemi vezani za delay_seconds. Jedan od njih je i to što pre nego što baza podataka koja je deo replikacione grupe može normalno da se ugasi, Oracle mora da sačeka da se završe svi poslovi replikacije koje pokreće baza podataka (kao što su push poslovi).

Ako push posao ima podešen delay_seconds, onda će Oracle morati da sačeka celu vrednost delay_seconds pre nego što će se taj posao završiti. To nije veliki problem ako imate delay_seconds vrednost od 30 sekundi. Međutim, problem je ako ste ga postavili na vrednost koju nekoliko Oracle dokumenata predlaže - 500.000 sekundi - skoro 6 dana! Shutdown abort zaobići će ovaj problem, ali jasno je da shutdown abort treba izbegavati ako je moguće.

Veći je problem sa delay_seconds što on, pod nekim okolnostima, izgleda da izaziva “zaglavljivanje” push poslova tako što zaključava JQ (redosled poslova). Konkretno, ovaj problem deluje nesavladivo kada su i interval i delay_seconds parametri podešeni na relativno mali broj, npr. interval podešen na 10 sekundi a delay_seconds na 5 sekundi. Nisam sasvim siguran zašto se ovo dešava, ali pretpostavljam da, budući da su parametri podešeni toliko nisko, Oracle može pokušati da pokrene push posao dok je prethodni još uvek aktivan (što izaziva stanje trke).

Jedan od simptoma ove situacije može se otkriti praćenjem dba_jobs_running prikaza. Pod normalnim okolnostima, kada push posao ima podešen delay_seconds, možete videti da posao ulazi u dba_jobs_running u planirano push vreme, ostaje tu za njegovu delay_seconds vrednost, a zatim se (sve dok nema novih transakcija) uklanja iz dba_jobs_running. Međutim, kada je posao u "zaglavljenom" stanju, on će trajno ostati u dba_jobs_running prikazu. U stvari, posao ostaje u tom prikazu čak i ako ubijete posao sa dbms_job.remove! (Kada to uradite, većina vrednosti posla postaje NULL u dba_jobs_running, ali posao i dalje ostaje tu.)

Drugi način na koji možete otkriti ovu situaciju jeste da izvršite upit v$lock prikaza kao SYS sa sledećom komandom:

SELECT COUNT(*)
FROM v$lock 
WHERE type = 'JQ';

Pokrenite gorenavedenu komandu nekoliko puta. Ako svaki put vrati vrednost veću od 0, onda je SNP proces (trajno) zaključao push posao. Dok je posao zaključan u tom stanju, ne samo što nećete moći da ugasite bazu podataka (vidite gore), već takođe nećete moći ni da umirite replikacionu grupu.

Jedini način da se izađe iz ovakve situacije (osim da se uradi shutdown abort) jeste da se ubije SNP proces na nivou operativnog sistema. Međutim, može biti teško da se utvrdi koji SNP proces zaključava, tako da ćete možda morati da ubijete sve SNP procese te instance. Ne samo to, već i terminate signal (kao i jači hangup i interrupt signali) neće ubiti te procese. U suštini, moraćete svima da im pošaljete kill signal (koji se daje izvršavanjem komande kill-9).

Onda ćete morati da sačekate minut-dva (tokom kojih će se automatski začeti novi SNP procesi) da se zaključavanje potpuno oslobodi. Jasno je da je ovo izuzetno nespretno i neelegantno zaobilazno rešenje. Stoga je moja preporuka da ne koristite delay_seconds parametar uopšte. Pošto ne radi onako kako se reklamira, ne vredi ni truda.

Nadzorno sredstvo za sinhronu replikaciju

Kada replikaciona grupa koristi sinhronu replikaciju, sve lokacije u grupi treba da budu funkcionalne i osposobljene kako bi bilo koja od tih lokacija bila podložna ažuriranju. To je zato što sa sinhronom replikacijom, svaka transakcija mora odmah da se primeni na sve lokacije u grupi, inače će se cela transakcija vratiti u prethodno stanje. To značajno smanjuje dostupnost replikacione grupe, do te mere da većina proizvodnih lokacija verovatno ne bi mogla da je distribuira.

Jedan mogući pristup sinhronoj replikaciji može biti da se napiše automatizovani program koji periodično prati status svih lokacija u replikacionoj grupi. Ukoliko program utvrdi da neka od lokacija u grupi ne radi, on će pokušati da restartuje tu lokaciju, a zatim će ponovo proveriti status lokacije. Ako je lokacija još uvek oborena, onda bi program dinamički uklonio tu lokaciju iz replikacione grupe (postupkom remove_master_databases). Kada je oborena lokacija uklonjena iz replikacione grupe, sve ostale lokacije u grupi ponovo će biti sposobne za ažuriranje.

Ovaj alat trebalo bi pokrenuti sa dve različite lokacije u replikacionoj grupi - s lokacije master definicije grupe, i s jedne od drugih master lokacija u grupi. Kada se ovaj alat pokrene s lokacije master definicije, trebalo bi da nadzire status svih master lokacija u grupi. Ako je bilo koja od tih master lokacija oborena i ne može se ponovo pokrenuti, ovaj alat trebalo bi da ukloni tu master lokaciju iz replikacione grupe, kao što je pomenuto gore.

Kada se ovaj alat pokreće s master lokacije, on bi trebalo da nadzire samo status lokacije master definicije grupe. Ukoliko otkrije da je lokacija master definicije oborena i da ne može da se ponovo pokrene, alat zatim treba dinamički da premesti lokaciju master definicije, tako da lokacija koja pokreće program postaje lokacija master definicija grupe. Razlog što ovo premeštanje mora da se uradi jeste što procedura remove_master_databases može da se izvrši samo sa lokacije master definicije replikacije grupe. Nakon što je premeštanje završeno, onda će ovaj alat ukloniti originalnu lokaciju master definicije iz replikacione grupe.

Treba voditi računa o nekoliko važnih stvari kada je u pitanju uklanjanje lokacija iz grupe sinhrone replikacije. Sa sinhronom replikacijom, transakcije se ne skladište u deftran redovima. Dakle, ne postoji način da vodite evidenciju o transakcijama koje se dešavaju na tim lokacijama. Zbog toga, ukoliko je lokacija uklonjena iz sinhrone replikacione grupe (čak i za kratko vreme), onda, da bi se ta lokacija vratila nazad u replikacionu grupu, svi podaci u grupi treba da se ponovo učitaju u nju. Ovo će obezbediti da ta lokacijaima potpuno iste podatke kao sve druge lokacije. Ne postoji način da se učitaju samo transakcije koje su se desile otkako je lokacija izvađena iz replikacione grupe, jer nije moguće pratiti transakcije sa sinhronom replikacijom.

Takođe, da bi se lokacija dodala replikacionoj grupi, aktivnosti u celoj replikacionoj grupi moraju da se obustave. To znači da, u cilju da se uklonjena lokacija ponovo vrati u replikacionu grupu, u svim bazama podataka u replikacionoj grupi mora da bude onemogućeno ažuriranje krajnjim korisnicima - kompletan prekid.

Ukratko, nakon što je lokacija uklonjena iz sinhrone replikacione grupe, vraćanje te lokacije nazad u grupu zahtevaće ogromnu količinu rada i obaranja sistema. Ove posledice treba razmotriti pre uvođenja potpuno automatizovanog sredstva koje može da ukloni lokacije iz sinhrone replikacione grupe. Osnovna prednost korišćenja ovakvog alata jeste to što vam omogućava da zakažete vreme nedostupnosti replikacione grupe, umesto da vam se desi neplanirani prekid.

Dodavanje novih lokacija replikacionoj grupi

Nova lokacija dodaje se u replikacionu grupu procedurom “add_master_database”. Jedan od parametara te procedure, use_existing_objects, omogućava vam da odredite da li želite da koristite predmete (tabele, indekse, itd) koji već postoje na novoj lokaciji, ili želite da budu automatski kreirani kao deo procesa dodavanja nove lokacije. Da biste podesili taj parametar na “true”, treba da kreirate sve tabele i indekse koji su deo replikacione grupe u novoj bazi podataka unapred, pre nego što pozovete proceduru add_master_database.

Ovo možda izgleda kao gubljenje vremena, jer vam procedura daje mogućnost da automatski kreirate objekte. Dakle, možete pomisliti - zašto je ne iskoristiti? Doduše, ja sam iskusio probleme s podešavanjem tog parametra na “false”. Često se objekti ne kreiraju odgovarajućim redosledom. Na primer, indeksi ponekad pokušavaju da se kreiraju pre tabela koje navode kao već kreirane. Stoga preporučujem da se unapred kreiraju replicirani objekti (i podaci u tim objektima) u novoj bazi podataka, pre pokretanja procedure add_master_database

Drugi parametar u proceduri add_master_databases, parametar copy_rows, omogućava vam da odredite da li želite da Oracle kopira podatke iz vaših postojećih lokacija u novu lokaciju, ili želite da koristite podatke koji su već učitani u tu novu lokaciju. Da biste podesili ovaj parametar na “false”, treba da unapred učitate sve podatke u novoj lokaciji ručno pre nego što pozovete proceduru add_master_databases.

U okruženju s ekstremno malom količinom podataka, korišćenje funkcionalnosti copy_rows izgleda da deluje. Međutim, čuo sam nekoliko izveštaja da ova funkcionalnost neće dobro raditi s većom količinom podataka - neki ljudi ustanovili su da će im trebati mnogo duže da učitaju podatke na taj način nego kada bi koristili uvoz i izvoz da bi ručno kopirali podatke. Prema tome, generalno je bolja ideja da lično unapred učitate sve podatke umesto da vam to uradi procedura add_master_databases.

Iako je unapred učitavanje podataka u novu lokaciju mnogo brže nego učitavanje podataka kao deo add_master_databases procedure, postoji jedan veliki problem na koji sam naišao sa učitavanjem podataka unapred. Ako postoji neki strani ključ u bilo kojoj od repliciranih tabela, i ako postoji bilo koji red u bilo kojoj od podređenih tabela, onda kada pokušate da dodate novu lokaciju replikacionoj grupi, možete primiti povrede ograničenja referencijalnog integriteta u podređenim tabelama. To nema nikakvog smisla - kako može da dođe do povrede ograničenja kada ste već unapred učitali sve podatke (uključujući i sve podređene redove) u novu bazu podataka?

Ipak, uprkos činjenici da nije logično, greška je uporna - svaki put kada sam pokušao da dodam master lokaciju koja ima podređene redove, primio sam te greške. Pretpostavljam da je to običan bug u add_master_database proceduri, ali nisam uspeo da nađem nikakve informacije o ovome kroz Oracle-ovu podršku ili MetaLink.

Smislio sam kako da se ovaj problem zaobiđe, iako rešenje nije baš veoma elegantno. Nakon što uvezete sve podatke u novu bazu podataka, onda morate da uklonite podršku replikacije (drop_master_repobject procedurom) iz svih repliciranih objekata u svim postojećim master lokacijama (uključujući i lokaciju master definicija). Pošto može biti na stotine repliciranih objekata, preporučujem da kreirate skriptu da to uradi (imena svih repliciranih objekata mogu se pronaći u dba_repobject prikazu). Na sreću, procedura drop_master_repobject samo treba da se pozove sa lokacije master definicije.

Kad ste učitali sve podatke u novu lokaciju, i kad ste uklonili podršku replikacije iz svih objekata u svim postojećim lokacijama, onda možete da pozovete add_master_database proceduru da dodate novu lokaciju ne dobijajući nikakve greške o povredi ograničenja. Verovatno je ovo zato što, ako uklonite podršku replikacije iz objekata postojećih lokacija pre nego što pozovete proceduru, onda procedura neće pokušati da generiše podršku replikacije na biko kom od objekata nove lokacije zato što procedura samo generiše podršku replikacije za objekte koji se trenutno repliciraju u lokaciji master definicije.

Kada se nova lokacija doda replikacionoj grupi, onda ćete morati ručno da generišete poršku replikacije na odgovarajućim objektima. Način da to uradite jeste da pozovete create_master_repobject proceduru (na lokaciji master definicije) za svaki od tih objekata. Za tabele, procedure i pakete, takođe treba da pozovete generate_replication_support proceduru. Ponovo, može biti na stotine repliciranih objekata, tako da savetujem da napišete skriptu da ovo uradi. Najzad, pošto su svi odgovarajući objekti konfigurisani uz podršku replikacije, onda možete da nastavite aktivnost na replikacionoj grupi.

Napomena: ovaj problem povrede ograničenja ne dešava se ako izazovete da se podaci učitaju kao deo procedure add_master_database (podešavanjem copy_row na “true”), ali naravno da učitavanje podataka kroz tu proceduru može da zahteva neprihvatljivo puno vremena.

O još jednome treba voditi računa kad je u pitanju dodavanje nove lokacije postojećoj replikacionoj grupi. Kao što je pomenuto, kada se pozove add_master_database procedura, Oracle traži sve objekte koji se trenutno repliciraju u lokaciji master definicije i onda pokreće poslove da generiše podršku replikacije na svakom od tih objekata na novoj lokaciji. Dakle, ako prvo ne uklonite podršku replikacije sa svih objekata lokacije master definicije, kada pozovete proceduru add_master_database, veliki broj poslova podrške replikacije pokrenuće se odjednom.

Treba malo vremena da se svi ti poslovi završe. Kao primer, na jednoj bazi podataka s kojom sam radio, trebalo je oko 20 minuta da svi objekti završe podršku replikacije za 78 objekata. Razlog što je ovo važno jeste to što bi trebalo da sačekate da se svi ti poslovi završe pre nego što nastavite aktivnost na replikacionoj grupi. Ako pokušate da nastavite aktivnost dok neki od tih poslova i dalje traju, onda će procedura “nastavi aktivnost” generisati greške; reći će da morate da “regenerišete podršku replikacije pre nego što nastavite glavnu aktivnost.”

Način da nadzirete napredak poslova podrške replikacije jeste da izvršite upit prikaza dba_repcatlog na lokaciji master definicije. Kada se posao pokrene, on se smešta u taj prikaz, a kada se uspešno završi, uklanja se iz tog prikaza. Stoga, kada broj redova u tom prikazu dostigne 0, svi poslovi podrške replikacije biće završeni i onda ćete moći da nastavite aktivnost na replikacionoj grupi.

Ukoliko posao replikacije generiše grešku,onda će on neograničeno ostati u dba_repcatlog prikazu, i moraćete ručno da razrešite uslove koji su izazvali grešku. Kada razrešite grešku, onda možete da uklonite taj unos iz dba_repcatlog prikaza procedurom purge_master_log. Međutim, kada to uradite, moraćete ili da ručno generišete podršku replikacije za dati objekat, ili ćete morati da ponovo pokrenete proceduru add_master_database iz početka. Nema načina da se ponovo podnese neuspeli repcatlog posao. Problemi opisani u ovom odeljku nisu značajni ako uklonite podršku replikacije iz postojećih objekata master lokacije pre nego što pozovete proceduru add_master_database - i to je jedini razlog što preporučujem da najpre uklonite podršku replikacije.

U zaključku, ovo su koraci koje preporučujem za dodavanje nove lokacije replikacionoj grupi:

  1. Obustavite aktivnost na replikacionoj grupi.
  2. Izvezite sve replicirane objekte i podatke na lokaciji master definicije.
  3. Uvezite te objekte (i podatke) u novu bazu podataka.
  4. Uklonite podršku replikacije iz svih repliciranih objekata na svim postojećim master lokacijama, pozivanjem procedure drop_master_repobject sa lokacije master definicije
  5. Konfigurišite novu bazu podataka kao master lokaciju u replikacionoj grupi procedurom add_master_database. Kada pozovete tu proceduru, podesite use_existing_objects na “true”, i podesite parametar copy_rows na “false”.
  6. Generišite podršku replikacije na svim repliciranim objektima pozivanjem procedura create_master_repobject i generate_replication_support iz lokacije master definicije.
  7. Nastavite akvitnost na replikacionoj grupi.

DDL komande na repliciranim objektima

Oracle pruža dve procedure koje se mogu koristiti za izvršavanje DDL komandi na repliciranim objektima. To su dbms_repcat.alter_master_repobject i dbms_repcat.execute.ddl. Glavna razlika između ove dve procedure je to što, da bi se pozvala procedura alter_master_repobject, replikaciona grupa treba da bude neaktivna. Ne mora da bude neaktivna da bi se izvršila execute_ddl.

Postoji još jedna velika razlika: execute_ddl dozvoljava DDL komandi da se izvrši na podskupu master lokacija u grupi (umesto da izvršava komandu na svim lokacijama). Nije jasno zašto bi iko hteo da to radi. Doživeo sam probleme s obe ove procedure. U nekim slučajevima, kada sam pokretao bilo koju od ove dve procedure na repliciranom objektu, primao sam nejasne poruke o greški “nekompatibilno”. Nažalost, nisam uspeo da odredim zašto se ove greške javljaju, ili čak šta one znače. Takođe, te greške ne dešavaju se svaki put kada pokrenem procedure. Cenim da su se javile manje od 5% vremena koje sam pokretao te procedure.

Međutim, kada određeni objekat prijavi grešku, ta greška će se stalno pojavljivati na potonjim pozivima procedure na tom objektu - čak i ako povratite taj objekat iz backup-a i onda ponovo pokrenete proceduru. Na primer, ako pozovete alter_master_repobject proceduru na tabelu “ABC”, i dobijete poruku o greški nekompatibilnosti, onda ako ponovo pokušate da pokrenete proceduru na tabeli ABC, stalno ćete dobijati tu grešku.

Smislio sam način da napravim DDL promene na repliciranim objektima koji zaista dosledno radi, iako opet rešenje nije baš veoma elegantno. Ovo su koraci koje treba da sledite da biste izvršili DDL komandu na nekom repliciranom objektu:

  1. Obustavite aktivnost na replikacionoj grupi.
  2. Uklonite podršku replikacije sa objekta o kome je reč, pozivanjem procedure drop_master_repobject sa lokacije master definicije.
  3. Ručno izvršite DDL komandu na datom objektu. Napomena: pošto se objekat više ne konfiguriše s podrškom replikacije, moraćete da izvršite DDL komandu na svim bazama podataka u replikacionoj grupi.
  4. Regenerišite podršku replikacije za objekat pozivanjem procedura create_master_repobject i generate_replication iz lokacije master definicije
  5. Nastavite aktivnost na replikacionoj grupi

Naravno, ovo rešenje zahteva mnogo više ručne intervencije nego pokretanje procedura koje nudi Oracle - ali pošto rešenje navedeno gore funkcioniše svaki put (za razliku od replikacionih procedura) preporučujem vam da sledite navedene korake da biste napravili DDL promene na repliciranim objektima.

Korišćenje više replikacionih grupa

Moguće je kreirati više replikacionih grupa u okviru jedne baze podataka. Štaviše. čak je moguće imati i sinhrone i asinhrone grupe u okviru iste baze podataka. Jedino ograničenje u korišćenju više replikacionih grupa u okviru baze podataka jeste to što bilo koji objekat može pripadati samo jednoj replikacionoj grupi. Drugim rečima, korišćenje više replikacionih grupa omogućava da objekti baze podataka budu “particionisani” među različitim replikacionim grupama.

Jedan razlog što bi moglo biti prikladno koristiti više grupa jeste ako neki objekti u bazi podataka sadrže veoma vremenski osetljive podatke (kao što su berzanske kvote) dok neki drugi objekti sadrže mnogo manje vremenski osetljive podatke (kao što su sportski rezultati). U ovakvoj situaciji, vremenski osetljivi podaci mogli bi da se smeste u sinhronu replikacionu grupu (ili u asinhronu grupu s veoma kratkim push intervalom), dok bi manje vremenski osetljivi podaci mogli da se smeste u asinhronu grupu s relativno dugim push intervalom.

Prednost ovoga bila bi što bi rezultiralo manjim ukupnim saobraćajem na mreži; samo bi se vremenski osetljivi podaci veoma često propagirali, dok bi se manje vremenski osetljivi podaci mnogo ređe propagirali. Drugi, legitimniji razlog za korišćenje više grupa jeste ako je relativno mala količina vrednosti u bazi podataka veoma “problematična” u pogledu konflikta podataka.

Na primer, kao što je ranije pomenuto, ekstremno je teško razrešiti ili čak izbeći konflikte podataka sa jedinstvenim korisnički generisanim vrednostima. Zato, ako relativno mali procenat vrednosti u bazi podattaka ima tu teškoću, onda bi objekti koji sadrže problematične vrednosti mogli da budu smešteni u sinhronu replikacionu grupu, dok bi ostatak objekata mogao da se smesti u asinhronu grupu.

Ovo bi imalo dve prednosti: eliminisalo bi mogućnost konflikta podataka s problematičnim vrednostima, dok bi sve ostale vrednosti imale prednosti asinhrone replikacije (više vreme neprekidnog rada, bolja performansa itd). Ako je veliki procenat vrednosti u bazi podataka problematičan, onda bi bilo delotvornije da se koristi jedna, sinhrona replikaciona grupa za sve objekte.

Uprkos prednostima korišćenja više replikacionih grupa, ima i nekoliko problema vezanih za njihovo korišćenje. Kao što bi se moglo očekivati, korišćenje više grupa rezultira povećanjem složenosti. To još više komplikuje zadatak upravljanja okruženjem multimaster replikacije. Kvantitativniji problem s korišćenjem više replikacionih grupa jeste taj što ćete morati da pazite da izbegavate zavisnosti između replikacionih grupa. To jest, ne bi trebalo da dozvolite stranim ključevima da obuhvate replikacione grupe.

Ako se roditeljska tabela nalazila u asinhronoj grupi s dugim push intervalom, a podređena tabela se nalazila u grupi s kratkim push intervalom (ili u sinhronoj grupi), onda bi mogli da se jave problemi. Na primer, ako je jedna transakcija na lokalnoj bazi podataka kreirala roditeljski slog a onda kreirala podređeni slog koji je referencirao novi roditeljski slog, onda bi se podređeni slog verovatno propagirao u udaljenu bazu podataka pre roditeljskog sloga. Ovo bi očigledno izazvalo povredu ograničenja referencijalnog integriteta.

Slično, čak i ako nema stranih ključeva koji obuhvataju replikacione grupe, SQL komande koje pristupaju bazi podataka ne bi trebalo da pristupe tabelama koje se nalaze u različitim replikacionim grupama. Sve tabele kojima jedna SQL komanda pristupa trebalo bi da se nalaze u istoj replikacionoj grupi. Podrazumeva se, sprečavanje zavisnosti između replikacionih grupa zahteva ogromnu količinu koordinacije između DBA i programera, i ta koordinacija mora da bude neprekidna. Drugim rečima, svaki put kad se desi promena aplikacije ili šeme, DBA i programeri moraju da se postaraju da čak ni posle te promene ne bude nikakvih zavisnosti između replikacionih grupa.

“Brzi” metod čišćenja

Kao što je pomenuto, ako replikaciona grupa koristi asinhronu replikaciju, transakcije koje su propagirane moraju se periodično uklanjati iz deftran reda da on ne bi postao suviše veliki. Procedura koja se koristi da se zakažu ova automatizovana čišćenja zove se “schedule_purge”. Jedan od parametara te procedure, parametar purge_method, omogućava vam da odredite tip čišćenja koji ćete koristiti: “brzo” čišćenje, koje ima numeričku vrednost 1, ili “precizno” čišćenje, koje ima vrednost 2. Brzi metod navodno koristi manje sistemskih resursa, tako da bi se moglo očekivati da je to poželjniji metod.

Međutim, taj metod čišćenja ne uklanja sve propagirane transakcije iz deftran reda. Konkretno, čini se da uvek ostavlja najskoriju transakciju u redu, čak i nakon što je ona propagirana. Ta transakcija ukloniće se iz reda sledeći put kada se pokrene posao čišćenja (sve dok su skorije transakcije smeštene u red do tog vremena) tako da je ovaj problem samo blaža smetnja. U svakom slučaju, “precizni” metod čišćenja zaista uklanja sve propagirane transakcije iz deftran reda.

Zaključak

Multimaster replikacija veoma je moćna i fleksibilna karakteristika. Međutim, uz moć i fleksibilnost ide i složenost. U ovom dokmentu videli smo osnove multimaster replikacije, neke od mogućih stranputica na koje možete zalutati i neke predloge kako da zaobiđete te izazove.

Svakako da ima još mnogo toga o multimaster replikaciji što nismo uspeli ovde da pokrijemo. Međutim, nadam se da će vam ovaj dokument poslužiti kao polazna tačka.

 

 

 

Published (Last edited): 15-04-2013 , source: http://www.dbspecialists.com/files/presentations/mm_replication.html