Як двофазні коміти запобігають відмові в останній секунді?


75

Я вивчаю, як працює двофазне комітування в розподіленій транзакції. Я розумію, що в останній частині фази координатор транзакцій запитує кожен вузол, чи готовий він до фіксації. Якщо всі погодились, то це говорить їм іти далі і робити зобов'язання.

Що запобігає наступному збою?

  1. Усі вузли відповідають, що готові до фіксації
  2. Координатор транзакцій каже їм "продовжувати і фіксувати", але один з вузлів виходить з ладу перед тим, як отримати це повідомлення
  3. Усі інші вузли успішно фіксуються, але тепер розподілена транзакція пошкоджена
  4. Я розумію, що коли аварійний вузол повернеться назад, його транзакція буде відкатана (оскільки він ніколи не отримував повідомлення про фіксацію)

Я припускаю, що на кожному вузлі працює звичайна база даних, яка не знає нічого про розподілені транзакції. Що я пропустив?


2
Ваше припущення про нормальну базу даних є неправильним. Будь-який ресурс (черга повідомлень, база даних тощо) підтримує розподілені транзакції (підтримуючи координатора транзакцій), чи ні. Якщо цього не сталося, ключі про його включення до розподіленої транзакції погіршать надійність.
erickson

Еріксон, якщо ви складете відповіді інших людей із вашим коментарем, я позначу це як офіційну відповідь.
Гілі

Відповіді:


43

Ні, вони не отримують вказівки відкочуватись назад, оскільки в оригінальному сценарії плаката деякі вузли вже зафіксовані. Що трапляється, коли аварійний вузол стає доступним, координатор транзакції каже йому, щоб знову здійснити фіксацію.

Оскільки вузол позитивно відреагував на фазі "підготовка", він повинен мати можливість "фіксувати", навіть коли він повертається з аварійного завершення роботи.


Я не розумію, як розбитий вузол повинен мати можливість відтворити транзакцію до позиції, де вона зупинилася. Якщо ви розміщуєте розподілену бібліотеку транзакцій поверх звичайної бази даних, що заважає БД відкочуватися після аварійного завершення роботи?
Gili

8
Гілі: Оскільки він обіцяв, що зможе, на етапі підготовки 2PC.
Томас

3
@Gili Розбита БД не повинна повторювати транзакцію. Традиційні транзакції БД працюють так, що вони активно вносять ці зміни в журнал транзакцій, що відбувається лише в тому випадку, якщо він може отримати необхідні блокування рядків / таблиць / сторінок. По суті після першого етапу, транзакція вже змінила БД, але інші запити не можуть бачити ці зміни, поки вони не будуть позначені як здійснені. Залишилося лише позначити їх як скоєні.
AaronLS

26

Підсумовуючи відповіді всіх:

  1. Не можна використовувати звичайні бази даних з розподіленими транзакціями. База даних повинна явно підтримувати координатора транзакцій.

  2. Вузли не отримують вказівки відкочуватись назад, оскільки деякі з них вже зафіксовано. Що трапляється, так це те, що коли аварійний вузол повертається, координатор транзакції каже йому завершити коміт.


3
Що станеться, якщо координатор аварійно працює, коли вузол не працює, а вузол прокидається, поки координатор все ще не працює? Що тоді робить вузол?
Aviad P.

3
Пропоную відкрити окреме питання для цього питання. Я сам не знаю відповіді, але я здогадуюсь, що вузол чекає повернення координатора, перш ніж приймати підключення клієнта.
Gili

2
Без координатора все, звичайно, зупиняється.
Jaco Van Niekerk

21

Ні. Пункт 4 неправильний. Кожен вузол записує в стабільне сховище, що він зміг здійснити транзакцію або відмовити її, так що він зможе робити те, що було наказано, навіть при збоях. Коли аварійний вузол повернеться назад, він повинен усвідомити, що транзакція у нього є у стані попереднього фіксації, відновити всі відповідні блокування або інші елементи керування, а потім спробувати зв’язатися з сайтом координатора для збору стану транзакції.

Проблеми виникають лише в тому випадку, якщо аварійний вузол ніколи не повертається (тоді все інше вважає, що транзакція була в порядку, або буде, коли аварійний вузол повернеться).


Чи не передбачає це, що база даних знає про розподілені транзакції? Я думав, ви повинні вміти розміщувати розподілені транзакції поверх звичайних баз даних, які нічого про це не знають ...
Гілі,

6
Ні; СУБД повинні знати про свої обов'язки в протоколі 2PC, і ключовою відповідальністю є збереження транзакції в стані Go / No-Go, поки координатор не дасть команду. Ви втрачаєте (автономію) в цей момент. Informix реалізує евристичний відкат для роботи з зниклими системами.
Джонатан Леффлер,

12

Двофазна фіксація не є надійною і просто розроблена для роботи в 99% випадків.

"Протокол передбачає наявність стабільного сховища на кожному вузлі з журналом попереднього запису, що жоден вузол не аварійно спрацьовує назавжди, що дані в журналі попереднього запису ніколи не втрачаються і не пошкоджуються в результаті аварійного завершення, і що будь-які два вузли можуть обмінюватися даними один з одним."

http://en.wikipedia.org/wiki/Two-phase_commit_protocol


Навіть якщо припущення, які ви згадали, виконуються, я не бачу, як вузол повинен знати, щоб відтворити транзакцію (замість того, щоб відкотити її назад), коли вона повертається після аварії. Наскільки я розумію, база даних не знає про розподілену транзакцію; щось поверх цього робить.
Гілі

@Gili: база даних повинна знати про розподілену транзакцію, щоб правильно підтримувати 2PC. Якщо ви будуєте щось зверху, то у вас немає надійної реалізації 2PC.
Джонатан Леффлер,

Це неправильно сказано. 2PC є правильним на 100% за певних припущень. Для цього питання учасник повинен надійно зберігати дані попереднього фіксації та повинен мати можливість завершити фіксацію після перезапуску, якщо координатор доручить це. Координатор також повинен надійно зберігати остаточне рішення про відкат або фіксацію та повторити спробу, якщо воно не вдасться. Крім того, всі учасники не повинні падати назавжди, вони в кінцевому підсумку повинні перезапуститись і мати довго зберігаються дані. Якщо вони дотримані, 2PC є на 100% правильним. Якщо ні, це може бути неправильним.
Олів,

7

Є багато способів атакувати проблеми двофазним комітом. Майже всі вони закінчуються як якийсь варіант трифазного алгоритму коміту Паксоса. Майк Берроуз, який розробив службу блокування Chubby в Google, яка базується на Paxos, сказав, що у лекції, яку я бачив, є два типи розподілених алгоритмів комітів - "Paxos і неправильні".

Одне, що аварійний вузол міг зробити, коли він пробуджується, це сказати: "Я ніколи не чув про цю транзакцію, чи повинна була вона бути здійснена?" координатору, який повідомить, яким було голосування.

Майте на увазі, що це приклад більш загальної проблеми: аварійний вузол може пропустити багато транзакцій, перш ніж він відновиться. Тому надзвичайно важливо, щоб після відновлення він мав поговорити або з координатором, або з іншою копією, перш ніж зробити себе доступним. Якщо сам вузол не може визначити, чи він не вийшов з ладу, то все залучається до більш активного, але все ще відстежуваного.

Якщо ви використовуєте систему кворуму для читання бази даних, невідповідність буде замаскована (і доведена до відома самої бази даних).


Як вузол відтворює транзакцію після її пробудження? Наскільки я розумію, звичайні бази даних завжди відмовляються після аварійного завершення роботи, і вони не знають про розподілені транзакції (ви вміщуєте якусь бібліотеку поверх них). Як такий, я не розумію, як ти можеш зробити цю роботу.
Gili
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.