Начало нового направления: Управление паралелльными версиями в СУБД PostgreSQL

  Автор: © Joseph Mitchell
Перевод: © Владимир Меренков.


 

Способность PostgreSQL осуществлять управление паралелльными версиями делает возможным одновременное использование таблиц с данными для чтения и записи

Введение

На повестке дня вопрос: что больше всего раздражает в больших многопользовательских базах данных (БД)? Как знает любой человек, работавший с ними - это ожидание. И ожидание. Использует ли база данных блокировку (locking) по таблицам, страницам, колонкам или строкам, одна и та же проблема продолжает досаждать: запросы для чтения (SELECT) ожидают окончания запросов для записи (UPDATE), и запросы для записи (UPDATE) ожидают окончания запросов для чтения (SELECT). Если бы я только мог найти базу данных, которой не требуется блокировка. Будет это когда-нибудь? Ну, ответ - да.

Особенность PostgreSQL's "no-locking" (без блокировки)

Для PostgreSQL "no-locking" уже реальность. Считывание из БД никогда не требует ожидания окончания записи и наоборот. Я уже слышу возражения с заявлением, что в PostgreSQL нет "no-locking", так что позвольте мне объяснить продвинутую технологию, названную Multi-Version Concurrency Control (MVCC) (по-русски примерно так: "Параллельное управление множеством версий" или "Контроль конкурирующих версий").

MVCC

В других базах данных, блокировка - это только механизм, использованный для поддержания совместного управления и целостности данных. Однако PostgreSQL вместо блокировки использует многоверсионную модель. В PostgreSQL версия похожа на мгновенный снимок данных в определеннй момент времени. Текущая версия данных появляется всякий раз, когда пользователи делают запрос к таблице. Естественно, новая версия появляется, если они исполняют опять тот же запрос, а какие-либо данные претерпели изменения. Такие изменения случаются в базе данных после выполнения инструкций UPDATE, INSERT или DELETE.

Пример: блокировка строк против MVCC

Существенная разница между традиционной блокировкой строк и MVCC в PostgreSQL заключается в том, КОГДА пользователи могут увидеть данные из определенной таблицы. При традиционной блокировке строк пользователям может быть придется ждать, чтобы увидеть данные, тогда как MVCC гарантирует, что пользователи НИКОГДА не ждут визуализации данных. Давайте рассмотрим следующий пример, чтобы яснее это проиллюстрировать.

SELECT headlines FROM news_items

В этом примере инструкция читает данные из таблицы с именем news_items и показывает из всех строк колонку с именем headlines. В системах упраления базами данных с блокировкой строк инструкция SELECT будет блокирована и пользователь будет ждать, если другой пользователь параллельно вставляет (INSERT) или обновляет (UPDATE) данные в таблице news_items. Транзакция, которая модифицирует данные удерживает блокировку на строке (строках) и поэтому все строки из таблицы не могут быть показаны, заставляя пользователей ждать снятия блокировки. Пользователи, которые сталкивались с частыми блокировками при попытке прочитать данные, слишком хорошо знакомы с расстройством, которое может вызвать эта схема блокировки.

Напротив, PostgreSQL позволил бы всем пользователям совместно просматривать таблицу news_items, устраняя необходимость ожидания снятия блокировки. Это всегда имеет место, даже если много пользователей в то же самое время вставляют или обновляют данные в таблице. Когда пользователь вводит запрос SELECT, PostgreSQL показывает мгновенный снимок - версию, фактичеки всех данных, которые пользователи окончательно ввели(изменили) прежде чем запрос начался. Любые данные обновлений или вставок, которые являются частью открытых транзакций или не были окончательно изменены, после того как запрос начался не будут показаны. Здесь большой здравый смысл, не так ли?

Более пристальный взгляд на MVCC

СУБД, которые используют блокировку строк не удерживают старую версию данных, следовательно они нуждаются в блокировке для сохранения целостности данных. Но более пристальный взгляд на то, как "no-locking" посредством MVCC работает в PostgreSQL, раскрывает, как он обходит это ограничение. Каждая строка в PostgreSQL имеет два идентификатора (ID) транзакции. У нее есть ID создающей транзакции, для транзакции, которая создала строку, и ID ликвидирующей транзакции, для транзакции, которая делает ее недействительной. Когда кто-либо выполняет UPDATE, PostgreSQL создает создает новую строку и делает недействительной ее старую версию. Это та же самая строка, но в другой версии. В отличие от систем БД, которые не держатся за старую версию, когда PostgreSQL создает новую версию строки он также хранит старую или потерявшую валидность версию. (Замечание: Старая версия хранится, пока в БД запущен процесс VACUUM.)

Это о том как PostgreSQL создает версии данных, но как он узнает, какую версию показывать? Это основывается на нескольких критериях. В начале запроса PosgreSQL записывает две вещи 1) ID текущей транзакции и 2) все ID транзакций находящихся в процессе. Когда кто-либо обращается к данным, PostgreSQL выдает запрос показать все строки версий, которые соответствуют следующим критериям: транзакция создания строки является завершенной транзакцией, а ее ID меньше, чем текущий счетчик транзакций, и у строки нет ID транзакции, делающей ее недействительной, или транзакция, делающая ее недействительной была в развитии, когда стартовал запрос.

И это то, в чем мощь MVCC. Это позволяет PostgreSQL отслеживать номера транзакций, чтобы определить версию данных, и таким образом, избегать вводить какие-либо блокировки. Это очень логичный и эффективный путь обработки транзакций. Новые пользователи PostgreSQL часто приятно удивлены увеличением производительности MVCC по сравнению с блокировкой строк, особенно в большом многопользовательском окружении.

MVCC также предлагает другое преимущество: "горячие" backup-ы. Многие другие БД требуют от пользователя завершить процессы в базе или заблокировать все таблицы, чтобы получить целостную копию (снимок базы) - но не так в PostgreSQL. MVCC позволяет PostgreSQL сделать полный backup базы данных в то время, когда она живет. Просто берутся снимки целой базы в момент времени, и выдается вывод даже во время вставки, обновления или удаления записей.

Заключение

MVCC гарантирует, что те кто читает данные никогда не будут ждать тех, кто их записывает, а те, кто записывает - тех, кто читает. Это логичный и эффективный механизм управления версиями который поставляет лучшую производительность БД, чем традиционная блокировка строк.

PostgreSQL доступен для скачивания на Great Bridge Web site (www.greatbridge.com/download).

Joseph Mitchell

Joseph работает архитектором информационных систем в Great Bridge LLC, компании, созданной для продвижения и предоставления на рынке услуг профессиональной технической поддержки для PostgreSQL, СУБД с открытым исходным кодом, а также других юизнес-решений на базе Open Source. С ним можно связаться через jmitchell@greatbridge.com.

 


Copyright © 2001, Joseph Mitchell.
Copying license http://www.linuxgazette.com/copying.html
Published in Issue 68 of Linux Gazette, July 2001

Вернуться на главную страницу