Какие SQL-команды есть в Greenplum для транзакционной обработки данных, как MVCC исключает явные блокировки, можно ли установить их вручную и как это сделать: режимы блокировки и глобальный детектор взаимоблокировок в MPP-СУБД.
Транзакции, MVCC и режимы блокировки Greenplum
Про изоляцию транзакций в Greenplum и Arenadata DB мы уже писали здесь. Транзакции позволяют объединить несколько SQL-операторов в одну операцию, чтобы выполнить их атомарно, т.е. все или ни одной. Greenplum поддерживает следующие SQL-команды для транзакционной обработки данных:
- BEGIN или START TRANSACTION запускает блок транзакции;
- END или COMMIT фиксирует результаты транзакции;
- ROLLBACK реализует откат назад, т.е. отказ от выполнения транзакции без внесения изменений;
- SAVEPOINT создает точку сохранения, отмечая конкретную операцию в транзакции, и разрешает частичный откат после нее. Можно откатить команды, выполняемые после точки сохранения, сохранив результаты выполнения действий до нее;
- ROLLBACK TO SAVEPOINT откатывает транзакцию к точке сохранения;
- RELEASE SAVEPOINT уничтожает точку сохранения внутри транзакции.
На самом деле PostgreSQL и Greenplum отрабатывают каждый SQL-оператор как транзакцию, даже при отсутствии команды BEGIN вначале и COMMIT в конце. Поэтому при массовых операциях, например, вставке нескольких сотен записей в таблицу лучше делать это одним блоком транзакции, добавив BEGIN; вначале и COMMIT; в конце, так будет намного быстрее.
Greenplum и PostgreSQL не используют блокировки для управления параллелизмом, обеспечивая согласованность данных с помощью многоверсионной модели MVCC (Multiversion Concurrency Control). MVCC изолирует транзакции для каждого сеанса базы данных, позволяя транзакции видеть моментальный снимок данных. Это гарантирует, что транзакция видит согласованные данные, на которые не влияют другие параллельные транзакции.
Благодаря отсутствию явных блокировок в MVCC для управления параллелизмом Greenplum поддерживает высокую производительность в многопользовательских средах: блокировки, полученные для чтения данных, не конфликтуют с блокировками при изменении данных. В Greenplum есть несколько режимов блокировки для управления одновременным доступом к данным в таблицах, чтобы гарантировать, что ссылочные таблицы не будут удалены или несовместимо изменены во время выполнения SQL-инструкции. При желании разработчик может управлять явными блокировками вручную, используя команду LOCK и установив нужный режим.
Режим блокировки | SQL-оператор | Конфликтует с |
ACCESS SHARE | SELECT | ACCESS EXCLUSIVE |
ROW SHARE | SELECT…FOR lock_strength | EXCLUSIVE, ACCESS EXCLUSIVE |
ROW EXCLUSIVE | INSERT, COPY | SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE UPDATE EXCLUSIVE | VACUUM (без FULL), ANALYZE | SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE | CREATE INDEX | ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
SHARE ROW EXCLUSIVE | ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE | |
EXCLUSIVE | DELETE, UPDATE, SELECT…FOR lock_strength, REFRESH MATERIALIZED VIEW CONCURRENTLY | ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
ACCESS EXCLUSIVE | ALTER TABLE, DROP TABLE, TRUNCATE, REINDEX, CLUSTER, REFRESH MATERIALIZED VIEW (без CONCURRENTLY), VACUUM FULL | ACCESS SHARE, ROW SHARE, ROW EXCLUSIVE, SHARE UPDATE EXCLUSIVE, SHARE, SHARE ROW EXCLUSIVE, EXCLUSIVE, ACCESS EXCLUSIVE |
Как работает глобальный детектор взаимоблокировок
По умолчанию глобальный детектор взаимоблокировок (Global Deadlock Detector) отключен, и Greenplum, в отличие от PostgreSQL получает более строгую блокировку EXCLUSIVE, а не ROW EXCLUSIVE, для UPDATE- и DELETE-запросов, а также SELECT-запросов с предложением блокировки FOR lock_strength. Поскольку изначально глобальный детектор взаимоблокировок отключен, Greenplum последовательно выполняет параллельные операции UPDATE и DELETE с таблицами кучи. Вы можете активировать эти одновременные обновления и заставить Global Deadlock Detector определять наличие взаимоблокировки, установив параметр конфигурации сервера gp_enable_global_deadlock_detector.
При включении глобального детектора взаимоблокировок в Greenplum режим блокировки для операций DELETE и UPDATE с таблицами кучи меняется на ROW EXCLUSIVE, а для SELECT-запросов с предложением блокировки …FOR lock_strength – на ROW SHARE.
Фоновый рабочий процесс Global Deadlock Detector базы данных Greenplum собирает информацию о блокировках во всех сегментах и использует направленный алгоритм для обнаружения существования локальных и глобальных взаимоблокировок. Этот алгоритм позволяет Greenplum ослабить ограничения на одновременное обновление и удаление таблиц кучи. При этом для AO/CO-таблиц по-прежнему используется блокировка на уровне таблицы, ограничивая одновременные операции UPDATE, DELETE и SELECT…FOR lock_strength.
Когда глобальный детектор взаимоблокировок включен, фоновый рабочий процесс автоматически запускается на хосте координатора при запуске Greenplum. Можно настроить интервал, с которым Global Deadlock Detector собирает и анализирует данные ожидания блокировки, с помощью параметра конфигурации сервера gp_global_deadlock_detector_ period. Если глобальный детектор взаимоблокировок определяет наличие взаимоблокировки, он устраняет ее, отменяя один или несколько внутренних процессов, связанных с самой молодой задействованной транзакцией. Когда глобальный детектор взаимоблокировок определяет наличие взаимоблокировки для следующих типов транзакций, только одна из транзакций будет успешной. Другие транзакции завершится ошибкой, указывающей, что одновременные обновления одной и той же строки не разрешены.
Greenplum использует интервал, указанный в параметре конфигурации сервера Deadlock_timeout, для локального обнаружения взаимоблокировок. Поскольку алгоритмы обнаружения локальных и глобальных взаимоблокировок различаются, отмененные процессы могут различаться в зависимости от того, какой детектор (локальный или глобальный) срабатывает первым. Если параметр конфигурации сервера lock_timeout включен и ему присвоено значение меньше deadlock_timeout и gp_global_deadlock_detector_period, Greenplum отменит оператор прежде, чем он когда-либо инициирует проверку взаимоблокировки в этом сеансе. При этом Global Deadlock Detector выдает следующее сообщение об ошибке:
ERROR: canceling statement due to user request: "cancelled by global deadlock detector"
Global Deadlock Detector может управлять одновременными обновлениями команд UPDATE и DELETE команд в таблицах кучи, самостоятельно разрешая конфликты между ними. Просмотреть информацию об ожидании блокировки для всех сегментов поможет пользовательская функция gp_dist_wait_status(). Можно использовать выходные данные этой функции, чтобы определить, какие транзакции ожидают блокировки, какие транзакции удерживают блокировки, типы и режим блокировки, идентификаторы сеансов ожидания и держателя, а также в каких сегментах выполняются транзакции.
Greenplum потенциально может исчерпать блокировки при обращении к нескольким таблицам в одной транзакции, например, при резервном копировании и восстановлении. Когда в Greenplum заканчиваются блокировки, выдается сообщение об ошибке общей памяти внутреннего слота блокировки:
... "WARNING","53200","out of shared memory",,,,,,"LOCK TABLE ... ... "ERROR","53200","out of shared memory",,"You might need to increase max_locks_per_transaction.",,,,"LOCK TABLE ...
Эта ошибка не означает исчерпание ресурсов памяти на уровне системы или самой СУБД. Избежать этой ошибки можно, увеличив значение параметра max_locks_per_transaction.
Освойте администрирование и эксплуатацию Greenplum для аналитики больших данных на специализированных курсах в нашем лицензированном учебном центре обучения и повышения квалификации для разработчиков, менеджеров, архитекторов, инженеров, администраторов, Data Scientist’ов и аналитиков Big Data в Москве:
Источники