COMPUTERWORLD
pod kapotou
Dvoufázový potvrzovací protokol

Transakční zpracování, tak jak bylo dosud v Databázové abecedě zmiňováno, bylo založeno na předpokladu jednoho procesoru sdíleného více procesy. Pro řadu aplikací je dnes taková architektura nepřijatelná. Důvodem může jednak vysoká cena zpracování (procesor pro vysoký provoz transakcí nestačí), nebo fakt že transakce vyžaduje data přirozeně umístěná na více počítačích. Řešením tedy jsou architektury využívající více procesorů. První možností jsou paralelní systémy, které je nutno odlišovat od dalšího typu architektur - distribuovaných systémů. Zatímco v případě paralelních architektur jde o více CPU fyzicky spojených do kompaktního celku, u distribuovaných architektur jsou CPU obvykle distribuovány geograficky. Paralelní systémy představují pokus konstruovat rychlejší a také levnější centralizovaný počítač, distribuované systémy speciálně v databázích vycházejí z potřeby nabídnout lokálně autonomní systémy s možností globálního či integrovaného pohledu na distribuovaná data. V distribuovaných databázích se dotazy a další požadavky na manipulaci s daty provádějí nezávisle v různých místech a částečné výsledky na základě komunikace mezi místy přispívají k vytvoření celkového výsledku.

Budeme uvažovat architekturu, kdy několik procesorů je provozováno paralelně, přičemž každý z nich má svou vlastní vnitřní a vnější paměť. Jde o architekturu v souvislosti s paralelními databázovými servery nazývanou “sdílení ničeho”, v případech, kdy procesory a data jsou umístěny v uzlech obvykle geograficky distribuované sítě, se hovoří o distribuovaných databázových systémech.

Problém zpracování transakce je v obou případech podobný. Transakce vyvolaná v jednom uzlu je rozdělena na podtransakce, které se provádějí na dalších uzlech. Např. zákazník banky může mít veden účet v pobočce P2 (databáze je na uzlu U2) a chce si vybrat částku v pobočce P1 (databáze je na uzlu U1). Účetní transakce v P1 bude zřejmě zahrnovat podtransakci T2, která na uzlu U2 zaznamená pohyb na zákazníkově účtu, podtransakce T1 na uzlu P1 zahrne pokladní operaci a záznam do historie operací provedených v pobočce P1. Softwarová komponenta databáze na uzlu U1 - transakční manažer TM1, bude koordinovat původní (distribuovanou) transakci. Co však tato koordinace znamená? Řekneme, že podtransakce transakce T jsou v jednotlivých uzlech koordinovány, jestliže je garantováno, že všechny budou buď potvrzené nebo zrušené. Distribuovaná transakce vlastně dědí vlastnosti ACID z jednotlivých uzlů. Nejtěžší ovšem je zajistit globální požadavek - buď vše nebo nic, tj. globální atomicitu transakce vyplývající z požadavku koordinace a dále globální trvanlivost, tj. promítnutí všech změn do databází participujících uzlů.

Distribuovaná transakce (vyvolaná např. v U1) má pouze tři stavy: A (aktivní), C (potvrzená) a AB (zrušená), přičemž z A lze vstoupit buď do C nebo AB a jak z A tak z AB nelze již jít nikam. Přestože v lokálních uzlech, kde se provádějí podtransakce, je možné po chybovém stavu restartovat transakci, jde o akci řízenou logikou aplikace. Jestliže je tedy např. provedena úspěšně T2 v uzlu U2, tj. je tam potvrzena, a vypadne uzel U1, vede zpracování k zrušení celé transakce. Bohužel, v uzlu U2 není již možně úspěšnou podtransakci vrátit do původního stavu (dokonce již možná poskytla změněná data pro účely eventuálních lokálních transakcí v uzlu U2). Z toho ale vyplývá, že koordinace distribuované transakce pouze na základě transakčního zpracování v jednotlivých uzlech není možná.

Zdá se, že je potřeba nějaký další stav, ve kterém se může distribuovaná transakce nacházet. Takový stav, navržený pro podtransakce, nazveme připravený (P). Podtransakce T se stane připravená, vydal-li koordinátor distribuované transakce požadavek na připravenost, v místě dané T jsou všechny operace provedeny a do příslušného žurnálu transakcí (log file) byl o tomto proveden odpovídající záznam. Připomeňme, že jde vlastně o obdobu stavu PC (částečné potvrzení), který známe z obyčejného (nedistribuovaného) zpracování transakcí. Ze stavu připravenosti může transakce přejít buď do stavu AB nebo C. V případě havárie však lze připravenou podtransakci opět uvést do stavu připravenosti. Schéma možných stavů a jejich vztahů je na obrázku 1.


P C

A

F AB

 

Obr. 1 Stavy podtransakcí

Na základě zavedení stavu připravenosti, někdy též nazývaného RC (Ready to Commit), byl definován mechanismus známý z řady komerčních databázových produktů, který se nazývá dvoufázový potvrzovací protokol.

Dvoufázový potvrzovací protokol (2PC) lze popsat následovně:

Fáze 1: Koordinátor zašle zprávu všem uzlům, na kterých se provádějí podtransakce k dané distribuované transakci, ve které je požadavek na připravenost. Jestliže některá z odpovědí hlásí neúspěšnost, pak koordinátor provede ROLLBACK na transakci ve svém uzlu a pošle zprávu všem zúčastněným uzlům s požadavkem na zrušení (ABORT) podtransakcí.

Fáze 2: Vedou-li všechny požadavky na připravenost k odpovědi hlásící úspěšnost, pak koordinátor potvrdí distribuovanou transakci a její lokální komponenty ve svém uzlu, a pak odešle zprávy s požadavkem na potvrzení (COMMIT) všech participujících transakcí v příslušných uzlech. Tyto zprávy dříve nebo později budou všechny doručeny.

Problém, co dělat, když jedna transakce je potvrzená a druhá zhavaruje vedlo původně ke stavu AB celé distribuované transakce. To však teď již úplně neplatí. Jsou-li všechny podtransakce ve stavu připravenosti, došlo k potvrzení distribuované transakce, byl vydán požadavek na potvrzení podtransakcí, pak, i když nastane chyba v nějakém uzlu, nic se neděje. Připravená a následně zhroucená podtransakce může být stále ještě uvedena do stavu připravenosti (rekonstrukce pomocí operace REDO a žurnálu transakcí v daném uzlu). Příslušný požadavek na COMMIT se pouze provede později. Zhavaruje-li koordinační uzel po vlastním provedení COMMIT, také zde může být provedeno zotavení z chyby a odeslání požadavků na COMMIT do participujících uzlů je pouze odloženo, protože koordinační uzel si udržuje seznam participujících podtransakcí. Bohužel toto odložení může být dlouhé, takže po celou tuto dobu jsou participanti blokováni. Nemohou např. uvolnit odpovídající zámky na příslušných zdrojích dat. Řešením může být decentralizace v ukončení transakce. Participanti komunikují mezi sebou a jakmile zjistí, že alespoň jeden z nich je již ve stavu C nebo AB, který se objevil po vydání globálního příkazu COMMIT nebo ABORT, mají šanci přejít do téhož stavu také. Z toho ovšem plyne, že každý participant musí znát ostatní. To však může být informace zahrnutá do zprávy PREPARE .

Existují i jiná řešení, např. třífázový potvrzovací protokol. V něm po výpadku koordinátore existuje možnost, že jeho roli převezme jiný uzel. Pro praxi však vedou takové protokoly k velké režii.

Problém, může ovšem nastat tehdy, nevrací-li se odpovědi na použité zprávy včas od participujících uzlů. Např. objeví-li se chyba v sítí. lze zavést pravidlo zrušit transakci po nějaké určité době (time out). To se uplatní zejména v koordinačním uzlu ve fázi 1.

Z hlediska SQL se realizuje 2PC pro danou transakci vydáním příkazu COMMIT WORK, tj. začne realizace první fáze. Koordinátor vyšle příkaz PREPARE všem participujícím uzlům. Odpovědi z dílčích uzlů mohou být buď YES VOTE nebo NO VOTE, podle toho, přeje-li si participovat úspěšně (je-li to vůbec možné) nebo ne. V prvním případě je samozřejmě nutný zápis o připravenosti do žurnálu transakcí. Ve druhém případě, protože z 2PC vyplývá právo veta libovolného participanta, může lokální uzel uvolnit zámky, zrušit podtransakci a zapomenout, že kdy existovala, tj. nemusí již čekat nic od koordinátora. Ti, co odpověděli positivně, musí čekat na globální COMMIT, nebo ABORT. Navíc, nemohou také své pozitivní rozhodnutí změnit. Ti, co se rozhodli pro NO VOTE, nepotřebují také čekat na globální ABORT.

Součástí 2PC protokolu již nebývá potvrzení o provedení odpovídajících akcích v participujících uzlech. V implementacích však bývá realizováno, protože koordinátor tak získá kontrolu výsledku před tím, než zapomene distribuovanou transakci. Složitost 2PC je dána počtem zápisů do žurnálů transakcí u koordinátora a participantů, dále pak počtem přenášených zpráv.

Existují různé varianty 2PC protokolu. Dvě z nich jsou důležité: předpokládaný ABORT 2PC a předpokládaný COMMIT 2PC. Jejich důležitost spočívá v tom, neboť redukují počet zpráv vyměňovaných mezi koordinátorem a participanty. První varianta je zahrnuta do X/Open XA standardu, druhá je částí ISO standardu pro Open Distributed Processing.

Potvrzování v distribuovaném systému představuje značnou zátěž. Existují měření dokazující např., že transakce pro aktualizaci jednoho záznamu pod univerzálním SŘBD potřebuje pro COMMIT část transakce zhruba 1/3 délky trvání celé transakce. V distribuovaném prostředí jsou časy ještě vyšší. Pro praxi to tedy znamená, že distribuované transakce se zatím aplikují spíše na dotazy (read-only transakce) a spíše méně na aktualizace.



<seznam dílů seriálu>   <COMPUTERWORLD>