Выполнение транзакций, ориентированное на данные

       

Графы потоков транзакций


Чтобы распределить работу каждой транзакции по соответствующим исполнителям, DORA транслирует каждую транзакцию в граф потока транзакции (transaction flow graph). Граф потока транзакции – это граф, соединяющий действия (action) с наборами данных. Действие – это часть кода транзакции, включающая обращения к одной записи или небольшому набору записей одной таблицы. Идентификатор (identifier) действия идентифицирует набор записей, к которым это действие намеревается обратиться. В зависимости от типа доступа идентификатор может являться некоторым набором значений полей маршрутизации или пустым набором. Два последовательных действия можно слить, если у них имеется один и тот же идентификатор (соответствующий одному и тому же набору).

Чем более точен идентификатор действия, тем проще для DORA направить этой действие соответствующему исполнителю. Другими словами, действия, идентификаторы которых содержат, по крайней мере, значения всех полей маршрутизации, направляются к соответствующему исполнителю путем обращения к правилу маршрутизации. Действия, идентификаторы которых содержат только часть значений полей маршрутизации, могут отображаться на несколько наборов данных. В этом случае действие разбивается на набор более мелких действий, каждое из которых соответствует некоторому одному набору данных. Обычно в эту категорию попадают вторичные индексы. Наконец, для действий с пустыми идентификаторами – вторичных действий (secondary action) – система не может решить, какой исполнитель за них отвечает. В п. 4.2.2 мы обсуждаем, как DORA обрабатывает вторичные действия.

В DORA для действий одной и той же транзакции используются разделяемые объекты (shared object), служащие для управления распределенным выполнением транзакции и передачи данных между действиями на основе зависимостей по данным. Эти разделяемые объекты называются точками рандеву (rendezvous point), или RVP. Если между двумя действиями имеется зависимость по данным, между ними помещается RVP.
RVP разделяют выполнение транзакции на фазы (phase). Система не может одновременно выполнять действия одной транзакции, относящиеся к разным фазам. У каждой RVP имеется счетчик, изначально содержащий число действий, которые должны ей "доложиться". Каждый исполнитель, заканчивая выполнение некоторого действия, уменьшает на единицу счетчик соответствующей RVP. Когда значение счетчика RVP становится нулевым, начинается следующая фаза. Следующую фазу инициирует исполнитель, обнуливший счетчик RVP, путем постановки действий этой фазы в очереди к соответствующим исполнителям. Исполнитель, обнуливший счетчик последней RVP в графе потока транзакции, запрашивает фиксацию данной транзакции. С другой стороны, любой исполнитель может аварийно завершить транзакцию и передать ее на восстановление.



Рис. 4. Граф потока транзакции Payment из тестового набора TPC-C.

На рис. 4 показан граф потока транзакции Payment. Каждая транзакция Payment зондирует записи таблиц Warehouse и District, а потом обновляет их. В обоих случаях у обоих действий (выбор и обновление записи) имеется один и тот же идентификатор, и их можно слить. С другой стороны, таблица Customer 60% времени зондируется через вторичный индекс, а затем обновляется. Этот вторичный индекс включает столбцы идентификатора склада (Warehouse_id), идентификатора округа (District_id) и фамилии клиента (Customer_last_name). Если в правиле маршрутизации для таблицы Customer используется только столбец Warehouse_id или столбец District_id, то система знает, какой исполнитель отвечает за этот вторичный индекс. Если же в правиле маршрутизации также используется и столбец идентификатора клиента (Customer_id), входящий в первичный ключ, то доступ к вторичному индексу требуется разбить на более мелкие действия, соответствующие всем возможным значениям Customer_id. Если в правиле маршрутизации используется только Customer_id, то система не может решить, какой исполнитель отвечает за выполнение, и этот доступ к вторичному индексу становится вторичным действием.


В нашем примере мы предполагаем, что полем маршрутизации является Warehouse_id. Следовательно, у действий зондирования вторичного индекса и последующего обновления записи имеется один и тот же идентификатор, и их можно слить. Наконец, RVP разделяет транзакцию Payment на две фазы, поскольку имеется зависимость по данным между действием по вставке записи в таблицу History и тремя другими действиями.

В спецификации транзакции Payment требуется, чтобы 15% времени выбирался клиент, приписанный к удалённому складу. В этом случае, системе без совместного использования ресурсов, которая разделяет базу данных по складам, придется выполнять распределенную транзакцию со всеми требуемыми накладными расходами. С другой стороны, DORA изящно справляется с такими транзакциями, просто направляя действия над таблицей Customer другому исполнителю. Так что на производительность этой системы не влияет процентное соотношение "удаленных" транзакций.


Содержание раздела