ACID в SQLite

      У даному пості описана система блокувань і підтримки атомарности, узгодженості, ізольованості і надійності (ACID) в SQLite, а також алгоритми запису і читання з файлу бази.
 
 

Pager Module

Блокування і паралельний доступ в SQLite версії 3 і вище обробляється пейджером (pager module). Даний модуль відповідає за ACID. Пейджер не цікавить деталі кодувань бази, В — дерев, індексів та ін, з його точки зору база даних — це один файл, розділений на рівні за розміром блоки (сторінки) пронумеровані починаючи з 1. Пейджер спілкується з операційною системою за допомогою прошарку OS Interface. У даному пості «потік», «процес» і «нитка» — рівносильні поняття.
 
 

Блокування

З точки зору одного процесу, файл бази даних може знаходиться в одному з 5 станів блокування перерахованих нижче:
 
     
  • UNLOCKED — Стан за замовчуванням. База даних розблоковано, будь-які потоки можуть читати і записувати дані.
  •  
  • SHARED — База даних доступна для читання, але не для запису.
  •  
  • RESERVED — Процес планує запис у файл, але зараз читає. Тільки одна RESERVED блокування може бути в один момент часу. Спільно з даними режимом може використовуватися SHARED блокування.
  •  
  • PENDING — Процес очікує закінчення всіх SHARED блокувань для початку запису і переходу в EXCLUSIVE режим.
  •  
  • EXCLUSIVE — Процес проводить запис у файл бази. Ніякі інші блокування бази паралельно з даною неприпустимі.
  •  
 
Нижче представлені алгоритми для читання і запису даних при використанні rollback журналу в якості гарантії цілісності бази.
 
 

Алгоритм читання даних з бази

Для читання з бази, процес повинен призвести наступні кроки:
 
     
  1. Відкрити файл бази та отримати SHARED блокування, якщо дана дія неможливо повернути SQLITE_BUSY .
  2.  
  3. Перевірити чи має база гарячий журнал відкату. Якщо ні, то можна читати дані з бази. Якщо так, то крок 3.
  4.  
  5. Отримати PENDING , а потім EXCLUSIVE блокування. Якщо немає можливості отримати дані блокування, значить, інший процес вже виробляє відкат. У цьому випадку зняти всі блокування і повернути SQLITE_BUSY .
  6.  
  7. Прочитати журнал відкату і майстер журнал (при приєднанні декількох баз, створюється спеціальний файл (master journal), в якому зберігається дані про журналах відкату для кожної з приєднаних баз).
  8.  
  9. Провести відкат
  10.  
  11. Видалити файл журналу відкату (залежно від опції journal_mode команди PRAGMA видалення відбувається по-різному).
  12.  
  13. Видалити файл майстер журналу, якщо це можливо.
  14.  
  15. Зняти PENDING і EXCLUSIVE блокування, але залишити SHARED блокування, і провести читання бази даних.
  16.  
 
 

Алгоритм запису даних у базу

Для запису даних у базу, процес спочатку повинен провести наступні кроки:
 
     
  1. Отримати SHARED блокування (алгоритм читання з бази).
  2.  
  3. Отримати RESERVED блокування. Якщо немає такої можливості, повернути SQLITE_BUSY .
  4.  
  5. Створити журнал відкату. У заголовку журналу прописується розмір бази даних, а також ім'я майстер журналу, якщо такий існує.
  6.  
  7. Перед внесенням змін до будь-якій сторінці бази даних, процес спочатку вносить дану сторінку в журнал відкату. Змінені сторінки в першу чергу записуються в RAM, це означає, що файл бази не змінюється, і інші процеси можуть читати дані з бази. Якщо зміна даних закінчилося і процес виробляє COMMIT , або якщо пам'ять переповнилася, перейти до кроку 5.
  8.  
  9. Переконатися, що всі дані журналу відкату були фактично записані на диск.
  10.  
  11. Отримати PENDING , а потім EXCLUSIVE блокування. Якщо немає можливості отримати дані блокування, необхідно чекати поки файл бази звільнитися.
  12.  
  13. Записати всі дані з RAM на диск у файл бази даних (якщо причиною записи було переповнення RAM, то повернутися до кроку 4).
  14.  
  15. Видалити файл журналу відкату (залежно від опції journal_mode команди PRAGMA видалення відбувається по-різному).
  16.  
  17. Зняти PENDING і EXCLUSIVE блокування.
  18.  
 
Більш докладно алгоритм атомарного комітів розглядається в іншому пості: habrahabr.ru/post/181584 /
  
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.