Шрифт:
Интервал:
Закладка:
Идентификаторы транзакций и ассоциированные с ними состояния данных сохраняются в инвентарных страницах транзакций. На заголовочной странице базы данных система учета поддерживает набор полей, содержащих идентификаторы транзакций, интересующих эту систему, а именно старейшую заинтересованную транзакцию (Oldest Interesting Transaction, OIT), старейшую активную транзакцию (Oldest Active Transaction, OAT) и число, используемое в следующей транзакции. "Мгновенный снимок" идентификатора транзакции также записывается каждый раз, когда увеличивается OAT - обычно тот же самый идентификатор, что и OAT, или близкий к нему.
Получение идентификатора транзакцииFirebird 1.5 и более поздние версии имеют контекстную переменную CURRENT? TRANSACTION, которая возвращает идентификатор данной транзакции. Она может использоваться в SQL в любом выражении. Например, для сохранения идентификатора транзакции в таблице протокола вы можете использовать следующее:
INSERT INTO BOOK_OF_LIFE
(TID, COMMENT, SIGNATURE) VALUES
(CURRENT_TRANSACTION,
'This has been a great day for transactions', CUERENT_USER) ;
Важно помнить, что идентификаторы транзакций являются циклическими. Поскольку нумерация сбрасывается после каждого восстановления (restore) базы данных, идентификаторы транзакций не должны использоваться для первичных ключей или ограничений уникальности.
Переполнение идентификатора транзакцииКак было сказано, идентификатор транзакции является 32-битовым целым. Если последовательность идентификаторов превысит лимит в 4 Гбайт и начнется новый отсчет, то могут произойти неприятные вещи. Когда завершится последняя транзакция, системная транзакция перестанет работать, и изменение метаданных будет невозможным. Сборка мусора прекратится. Транзакции пользователя не станут запускаться.
При 100 транзакциях в секунду это займет 1 год, 4 месяца, 11 дней, 2 часа и приблизительно 30 минут[90].
Резервное копирование и восстановление базы данных восстанавливает идентификаторы транзакций. До последнего времени заброшенная база данных могла получить другие травмы до того, как будет исчерпана последовательность идентификаторов транзакций. Теперь при больших размерах страниц, больших объемах дисков и уменьшении необходимости отслеживать размер файлов базы, данных риск переполнения последовательности идентификаторов транзакций более вероятен.
"Заинтересованные транзакции"
Подпрограммы учета транзакций сервера и клиента используют идентификаторы транзакций для отслеживания состояния транзакций. Служебные подпрограммы используют возраст транзакций для решения вопроса, какие старые версии записей являются "интересными", а какие нет. Неинтересные транзакции могут быть отмечены для удаления. Сервер остается "заинтересованным" в каждой транзакции, которая не была жестко подтверждена с помощью оператора COMMIT.
Активные, зависшие (limbo), отмененные и "умершие" транзакции все являются интересными. Транзакции, которые были подтверждены с использованием оператора COMMIT WITH RETAIN (мягкое подтверждение или CommitRetaining), остаются активными, пока не будут подтверждены жестко, и поэтому являются интересными. В некоторых случаях интересные транзакции могут стать "застрявшими" и станут тормозить работу.
Заброшенные, застрявшие транзакции станут источником серьезного ухудшения производительности. Застрявшие OIT (старейшие заинтересованные транзакции) приведут к росту количества инвентарных страниц транзакций. Сервер поддерживает рабочую таблицу транзакций в виде битовой маски, хранящейся в инвентарных страницах транзакций. Таблица копируется и записывается в базу данных при старте каждой транзакции[91]. Когда она непомерно раздуется от застрявших транзакций, она
будет использовать гораздо больше ресурсов памяти, и память станет фрагментированной от постоянного выделения ресурсов.
Старейшая заинтересованная транзакцияOIT является транзакцией с наименьшим номером в инвентарной странице транзакций, которая находится в неподтвержденном (rolled back) состоянии.
Старейшая активная транзакцияOAT- это транзакция с наименьшим номером в инвентарной странице транзакций, которая является активной. Транзакция является активной до тех пор, пока она не подтверждена жестко, не выполнен ее откат, и если она не является зависшей (limbo)[92].
Транзакции только для чтенияТранзакция только для чтения остается активной (и в некоторой степени интересной), пока не будет подтверждена. При этом активная транзакция только для чтения, для которой рекомендуется уровень изоляции READ COMMITTED (см. главу 26), никогда не становится застрявшей и не влияет на систему обслуживания.
! ! !
ВНИМАНИЕ! Не путайте транзакцию только для чтения с транзакцией чтения/записи, которая выполняет передачу выходного набора пользовательскому интерфейсу от оператора SELECT. Даже если приложение делает выходной набор набором только для чтения, оператор SELECT внутри транзакции чтения/записи может стать - и часто бывает - причиной замедления работы системы.
. ! .
Фоновая сборка мусораВерсии записей отмененных транзакций вычищаются из базы данных, когда они обнаруживаются в процессе обычной обработки данных. Как правило, если к строке обращается оператор, то любая неинтересная старая версия записи, подходящая для удаления, будет отмечена для процесса сборки мусора.
Некоторые "закоулки" базы данных могут не посещаться операторами в течение длительного времени, следовательно, нет гарантии, что все версии записей, созданные в .отмененных транзакциях, будут отмечены и в итоге удалены. До тех пор, пока остаются старые версии записей, заинтересованная транзакция должна оставаться "интересной" для сохранения состояния базы данных.
! ! !
СОВЕТ. Полное сканирование базы данных (обычно при резервном копировании) выполнит сборку мусора, но не сможет изменить состояния транзакций. Это работа для "полной" сборки мусора, выполняемой при чистке (sweep) базы данных.
. ! .
Отмененные транзакцииТранзакции в отмененном (rolled back) состоянии не включены в сборку мусора. Они остаются заинтересованными, пока чистка базы данных не отметит их как "подтвержденные" и не освободит их для сборки мусора. В системах с низким уровнем конфликтов периодическая ручная чистка базы данных может быть единственно необходимой работой.
Некоторые системы, плохо спроектированные для работы с конфликтами, демонстрируют высокий уровень откатов транзакций и имеют тенденцию накапливать 'заинтересованные' транзакции быстрее, чем с ними могут справиться автоматические процедуры обслуживания базы данных. В подобных системах должна часто выполняться ручная чистка, если складывается впечатление, что автоматическая чистка не работает надлежащим образом.
"Мертвые" транзакцииТранзакции считаются "мертвыми", если они находятся в активном состоянии, но не существует связанного с ними контекста соединения. Обычно транзакции "умирают" в клиентских приложениях, которые не заботятся об их завершении перед отключением от базы данных. Умершие транзакции также являются частью обломков, оставленных после краха клиентских приложений или поломки сетевых соединений.
Сервер не может определить разницы между действительно активными транзакциями и умершими. Пока тайм-аут ожидания соединения работает, и регулярная сборка мусора своевременно убирает ненужные транзакции, умершие транзакции не создают проблем. При срабатывании тайм-аута соединения выполнится их откат, и в итоге этот мусор будет убран.
Частое большое накопление умерших транзакций может стать проблемой. Поскольку они не являются отмененными, слишком многие из них остаются заинтересованными на чрезмерно большой срок. В системе, где поведение пользователя, частые аварии программ, отключение питания или сетевые ошибки генерируют огромное количество умерших транзакций, мусор от умерших транзакций становится большой проблемой.
Зависшие транзакцииЗависшие транзакции (limbo transactions), подробно обсуждаемые в главе 26, появляются в результате сбоя двухфазной операции COMMIT для нескольких баз данных. Система распознает их как особый случай, требующий вмешательства человека, поскольку сам сервер не может определить, будет ли их подтверждение или откат влиять на согласованность данных в разных базах данных.
Единственный способ разрешить зависшие транзакции - это запустить для базы данных инструмент gfix с соответствующими переключателями для достижения желаемого результата. Утилита изменяет состояние транзакции либо на "подтвержденное", либо на "отмененное". С этого момента с ней осуществляется работа, как и с любой другой подтвержденной или отмененной транзакцией.
- Delphi. Учимся на примерах - Сергей Парижский - Программирование
- Сделай видеоигру один и не свихнись - Слава Грис - Программирование / Руководства
- Психбольница в руках пациентов - Алан Купер - Программирование