В SQL Server 2012 в вывод различных динамических представлений управления (DMV), функций и команд добавили множество небольших, но полезных сведений.
Одно из новшеств, которое я обнаружил и которому очень рад (да, мне бы почаще выбираться из пещеры :-), — это появление в выводе fn_dblog идентификатора родительской транзакции. Благодаря этому можно видеть, какая транзакция является родительской для вложенных системных транзакций и других подтранзакций.
Зачем это вообще нужно? Мы можем увидеть иерархию и точный порядок транзакций во время выполняемых нами операций с SQL Server, чтобы понимать, как всё устроено «под капотом», без догадок и предположений.
Например, при вставке первой строки в новую таблицу системе выделения необходимо получить страницу из смешанного экстента. С новым полем мы можем увидеть точный порядок действий:
CREATE TABLE t1 (c1 INT);
GO
CHECKPOINT;
GO
INSERT INTO t1 VALUES (1);
GO
SELECT
[Current LSN],
[Operation],
[Context],
[Transaction ID],
[AllocUnitName],
[Transaction Name],
[Parent Transaction ID]
FROM fn_dblog (NULL, NULL);
GO
Current LSN Operation Context Transaction ID AllocUnitName Transaction Name Parent Transaction ID ———————- ———————- ————- ————– ———————– ————————– ——————— 00000119:000001c2:0001 LOP_BEGIN_XACT LCX_NULL 0000:0000a216 NULL INSERT NULL 00000119:000001c2:0002 LOP_BEGIN_XACT LCX_NULL 0000:0000a217 NULL AllocHeapPageSimpleXactDML 0000:0000a216 00000119:000001c2:0003 LOP_LOCK_XACT LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0004 LOP_SET_BITS LCX_SGAM 0000:00000000 Unknown Alloc Unit NULL NULL 00000119:000001c2:0005 LOP_BEGIN_XACT LCX_NULL 0000:0000a218 NULL AllocFirstPage 0000:0000a217 00000119:000001c2:0006 LOP_MODIFY_ROW LCX_PFS 0000:0000a218 dbo.t1 NULL NULL 00000119:000001c2:0007 LOP_BEGIN_XACT LCX_NULL 0000:0000a219 NULL AllocMixedExtent 0000:0000a217 00000119:000001c2:0008 LOP_SET_BITS LCX_GAM 0000:0000a219 Unknown Alloc Unit NULL NULL 00000119:000001c2:0009 LOP_SET_BITS LCX_SGAM 0000:0000a219 Unknown Alloc Unit NULL NULL 00000119:000001c2:000a LOP_COMMIT_XACT LCX_NULL 0000:0000a219 NULL NULL NULL 00000119:000001c2:000b LOP_MODIFY_ROW LCX_PFS 0000:0000a217 Unknown Alloc Unit NULL NULL 00000119:000001c2:000c LOP_FORMAT_PAGE LCX_IAM 0000:0000a217 dbo.t1 NULL NULL 00000119:000001c2:000d LOP_HOBT_DELTA LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:000e LOP_MODIFY_ROW LCX_IAM 0000:0000a218 dbo.t1 NULL NULL 00000119:000001c2:000f LOP_CREATE_ALLOCCHAIN LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0010 LOP_LOCK_XACT LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0011 LOP_COMMIT_XACT LCX_NULL 0000:0000a218 NULL NULL NULL 00000119:000001c2:0012 LOP_HOBT_DELTA LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0013 LOP_LOCK_XACT LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0014 LOP_ROOT_CHANGE LCX_CLUSTERED 0000:0000a217 sys.sysallocunits.clust NULL NULL 00000119:000001c2:0015 LOP_LOCK_XACT LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0016 LOP_ROOT_CHANGE LCX_CLUSTERED 0000:0000a217 sys.sysallocunits.clust NULL NULL 00000119:000001c2:0017 LOP_FORMAT_PAGE LCX_HEAP 0000:0000a217 dbo.t1 NULL NULL 00000119:000001c2:0018 LOP_LOCK_XACT LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:0019 LOP_ROOT_CHANGE LCX_CLUSTERED 0000:0000a217 sys.sysallocunits.clust NULL NULL 00000119:000001c2:001a LOP_COMMIT_XACT LCX_NULL 0000:0000a217 NULL NULL NULL 00000119:000001c2:001b LOP_INSERT_ROWS LCX_HEAP 0000:0000a216 dbo.t1 NULL NULL 00000119:000001c2:001c LOP_SET_FREE_SPACE LCX_PFS 0000:00000000 Unknown Alloc Unit NULL NULL 00000119:000001c2:001d LOP_COMMIT_XACT LCX_NULL 0000:0000a216 NULL NULL NULL
Здорово, правда? Видно, что система начала за нас неявную транзакцию с именем INSERT. Затем она стартовала подтранзакцию AllocHeapPageSimpleXactDML, чтобы обработать внутреннюю механику выделения страницы. Та, в свою очередь, запустила ещё две «под-подтранзакции» — для выделения экстента и для выделения страницы.
Примечание: установка значения свободного пространства новой страницы в PFS выполняется вне транзакции (то есть не транзакционно), поскольку поддерживать битовые метки свободного пространства транзакционно означало бы вызвать серьёзные блокировки в системе.
В дальнейшем я непременно буду использовать эту возможность в своих исследовательских «спелеологических» изысканиях по недрам SQL Server.

Комментариев нет:
Отправить комментарий