Transakcje Flashcards
Jakie poziomy izolacji mogą zapewniać bazy danych? Jakie z nich implementuje Postgresql? Który z nich jest najczęściej domyślny?
Read Uncommited
Read Commited
Repeatable Read
Serializable
Postgresql implementuje trzy ostatnie, a jego domyślnym poziomem izolacji jest Read Commited.
Co oznacza skrót ACID w kontekście baz danych?
A - Atomicity (wg DDIA powinno to raczej być Abortability)
C - Consistency
I - Isolation
D - Durability (zazwyczaj oznaczać to będzie zapis na dysku twardym)
Jakim zjawiskom zapobiega poziom izolacji “Read commited”? Jak te gwarancje są zapewniane?
Zapobiega: dirty readom i dirty write’om.
Aby zapobiec dirty write’om, transakcja, która chce zaktualizować wiersz, musi uzyskać lock na tym wierszu (exclusive lock). Inna transakcja, która chciałaby nadpisać tą wartość, musi zaczekać aż ta pierwsza zakończy się.
Teoretycznie do zapobieżenia dirty readom też można być użyć locków, ale bazy danych implementują bardziej wydajny mechanizm. Dla wierszy, które zostały nadpisane przez transakcję w trakcie, trzymają starą i nową wartość tego wiersza. Czytającym ten wiersz transakcjom zwracają starą wartość.
W jakich przypadkach poziom izolacji “Read Commited” będzie niewystarczający?
Poziom izolacji “Read committed” może okazaćsię niewystaraczający dla transakcji, które potrzebują czytać spójny obraz danych z jednego momentu, np. dla transakcji analitycznej lub czytania stanu bazy danych dla stworzenia backupu (moglibyśmy mieć część wierszy zbackupowanych z jednego momentu, część z innego). Inny przykład: integrity checks.
W jaki sposób bazy danych implementują izolację na poziomie “Read Commited”?
Lock na wierszach nadpisywanych oraz alternatywnie przetrzymywanie dwóch wersji wiersza - ostatni zcommitowany stan oraz jego niescommitowane nadpisanie.
Alternatywnie bazy danych, które implementują Snapshot Isolation, mogą użyć tego mechanizmu - każdy read i write zaczyna się nowym TXID (transaction ID).
Jakie gwarancje daje poziom izolacji “Snapshot Isolation”? Jak ten poziom izolacji jest zaimplementowany?
Zapewnia “no dirty read” oraz “no dirty write”, zapobiega “read skew” (obserwacji bazy danych w niespójnym stanie; przykład z książki to czytanie stanu dwóch kont bankowych w czasie transferu pomiędzy nimi).
Mechanizm używane to:
-lock na aktualizowanych wierszach (podobnie jak przy poziomie read commited)
-MVCC (multi version concurrency control) dla czytania wierszy, będący generalizacją rozwiązania dla zapobiegania dirty readom z poziomu Read Commited
Motto przyświecające Snapshot Isolation: “Readers never block writers, writers never block readers”.
Na czym polega “Lost update” problem? W jaki sposób się przed nim chronić?
Problem występuje, gdy dwie transakcje próbują w tym samym czasie zaktualizować wiersz w oparciu o jego aktualną wersję. Klasyczny przykład: inkrementacja pewnej wartości. Jeśli dwie transakcje odczytają początkową wartość X i każda z nich spróbuję nadpisać wiersz wartością X+1, otrzymamy po ich wykonaniu wartość X+1, choć raczej pożądanym wynikiem byłoby X+2. Innymi słowy może wystąpić przy read-modify-write cycle.
Możliwe rozwiązania:
-użycie poziomu izolacji serializable
-implementacja przez datastore atomicznych operacji (zazwyczaj zaimplementowane przez exclusive lock na read (cursor stability), alternatywa jest wykonywanie wszystkich atomowych operacji na jednym wątku)
-zastosowanie mechanizmu select for update
-wykrywanie przez bazę danych lost updateów, które jest możliwe przy snapshot isolation, robi to np. poziom izolacji Repeatable Read w Postgresie, Oracle Serializable i SQL Server Snapshot Isolation
Co oznacza skrót MVCC? Jak działa ten mechanizm?
Multi Version Concurrency Control - mechanizm stosowany przez bazy danych do implementacji poziomu izolacji Snapshot Isolation. Opis algorytmu:
-transakcja przy rozpoczęciu dostaje autoinkrementowalny txid,
-każdy wiersz tworzony przez tą transakcję jest oznaczany jako stworzony z tym txid
-gdy transakcja aktualizuje jakiś wiersz, oznacza go jako usunięty przez swoje txid i tworzy jego nowąwersję oznaczoną jako stworzoną przez to txid
-w momencie rozpoczęcia transakcja pobiera txid wszystkich transakcji, które są w trakcie
-przy czytaniu wartości danego wiersza bierze pod uwagę tylko te jego wersję, które były zacommitowane podczas rozpoczęcia wykonywania tej transakcji
Jak działa mechanizm “select for update”?
W momencie, w którym transakcja wykonuje “select for update” pobiera exclusive locka na wszystkich wierszach zwróconych przez to zapytanie (inne transakcje nie mogą też czytać wartości tych wierszy do momentu zacommitowania lub abortowania).
W jaki sposób poziom izolacji Read Commited może zostać zaimplementowany z użyciem mechanizmów Snapshot Isolation?
Poprzez pobieranie nowego txid (i zaktualizowanej listy transakcji in progress) dla każdego wykonywanego przez siebie zapytania. W ten sposób transakcje, które zcommitowały się pomiędzy jednym a drugim zapytaniem będą widoczne dla tego drugiego.
Na czym polega problem “write skew”? Czym sięróżni od dirty write i lost update? Czym się różni od phantom read?
Dirty write i lost update dotyczą sytuacji, w których dwie transakcje próbują nadpisaćwartość w JEDNYM wierszu. Write skew jest bardziej generalnym problemem - dotyczy sytuacji, gdy dwie transakcje odczytują ten sam zestaw wierszy, ale nadpisują/zapisują więcej niż jeden wiersz, prowadząc do sytuacji, w której pewne założenia co do systemu zostają złamane, np. że tylko jeden wiersz może mieć daną wartość kolumny - dwie transakcje mogą równocześnie próbować nadpisać wartość tej kolumny w dwóch różnych wierszach.
Jak działa mechanizm “materializing conflicts”? Kiedy może się przydać? Jakie są jego wady?
Wzorzec stosowany, gdy chcemy zapewnić constrainty dotyczące wielu rekordów, ale nie możemy wykonać explicit locka, ponieważ constraint może dotyczyćbraku istnienia wierszy o danej wartości. Przykład: bookowanie salek. Możemy bookować salkę tylko, gdy ta salka nie jest już zabookowana w tym samym terminie. Nie ma na czym wykonaćselect for update, bo opieramy się na założeniu, że query nic nie zwróci. Przy zastosowaniu materializing conflicts baza danych zawierałaby wszystkie możliwe bookowania z jakąś granularnością, np. potencjalne bookowanie każdej salki co 5 minut. Mając takie wiersze jest na czym zmaterializować konflikt i zdobyćlocka.
Z użyciem jakich mechanizmów współczesne bazy danych implementują poziom izolacji “Serializable”?
-actual serial execution
-2PL - 2 Phase Locking (większość relacyjnych baz danych)
-Serializable Snapshot Isolation (PostgreSQL)
Jakie są ograniczenia w implementacji poziomu izolacji Serializable poprzez mechanizm Serial Execution?
Główne ograniczenie: użycie tylko jednego rdzenia. Jesteśmy ograniczeni przez moc jego moc.
Dodatkowko jedna długotrwające transakcja może skutecznie zablokować pozostałe. Dlatego w implementacjach Actual Serial Execution przyjmuje się założenie, że transakcje nie są interaktywne. Zamiast tego sprowadzają się do wykonania gotowych procedur, do których transakcja na starcie wprowadza wszystkie zmienne. Transakcje te powinny co do założenia być krótkie. Aby były krótkie przyjmuje się założenie, że cały dataset powinien mieścić sięw RAMie (brak koniecznośći czytania z dysku).
Implementacja stosowana w: VoltDB, Redis i Datomic.
Jakie motto przyświeca poziomowi izolacji Snapshot Isolation? Jak to motto ma się do poziomu Serializable?
Snapshot isolation: readers never block writers, writers never block readers
Serializable: readerzy i writerzy mogąsię wzajemnie blockować.