Автор: Alexey Knyazev
Минимальное протоколирование — это протоколирование только информации, необходимой для восстановления транзакции без поддержки восстановления на момент времени.
Эта особенность может быть очень полезна, когда необходимо сократить время на выполнение некоторых операций. Сегодня я хочу поговорить о минимальном протоколировании некоторых DDL-операции с индексом.
Минимально протоколируются следующие операции с индексами:
- Операции CREATE INDEX (включая индексированные представления)
- Операции ALTER INDEX REBUILD или DBCC DBREINDEX
- Перестроение новой кучи DROP INDEX (если применимо)
Минимальное протоколирование выполняется более эффективно, чем полное, и снижает вероятность переполнения журнала во время выполнения операции с индексами. При этом минимальное протоколирование напрямую зависит от модели восстановления (recovery model) БД.
В следующей таблице перечислены операции с индексами и тип протоколирования, доступный для них в каждой из моделей восстановления базы данных. Эти модели восстановления поддерживаются для операций с индексами, выполняющихся как в оперативном (ONLINE), так и в автономном режиме (OFFLINE).
Операция с индексами | Полная модель (Full) | Модель с неполным протоколированием (Bulk logged) | Простая модель (Simple) |
ALTER INDEX REORGANIZE | полное | полное | полное |
ALTER INDEX REBUILD | полное | минимальное | минимальное |
CREATE INDEX | полное | минимальное | минимальное |
DBCC INDEXDEFRAG | полное | полное | полное |
DBCC DBREINDEX | полное | минимальное | минимальное |
DROP INDEX | Освобождение индексной страницы полностью протоколируется; создание новой кучи (при необходимости) также полностью протоколируется | Освобождение индексной страницы полностью протоколируется; создание новой кучи (при необходимости) протоколируется минимально | Освобождение индексной страницы полностью протоколируется; создание новой кучи (при необходимости) протоколируется минимально |
В этой статье я покажу, как можно убедиться, что ваши операции над индексами действительно протоколируются минимально или полностью.
use master; go --Тестовая БД с полным режимом восстановления if db_id( 'test_database_full' ) is not null drop database test_database_full; go create database test_database_full; go alter database test_database_full set recovery full; go --Тестовая БД с неполным протоколированием if db_id( 'test_database_bulk_logged' ) is not null drop database test_database_bulk_logged; go create database test_database_bulk_logged; go alter database test_database_bulk_logged set recovery bulk_logged; go --Тестовая БД с простой моделью if db_id( 'test_database_simple' ) is not null drop database test_database_simple; go create database test_database_simple; go alter database test_database_simple set recovery simple; go
Список наших баз данных:
select name, recovery_model_desc from sys.databases where name like 'test_database_%' order by database_id; go
Создадим в каждой БД по одной таблице.
use test_database_full; go if object_id( 'dbo.table_full', 'U' ) is not null drop table dbo.table_full; go create table dbo.table_full ( a varchar(512) ); go insert into dbo.table_full select distinct replicate( rtrim(type), 512 ) from master..spt_values where len( type ) = 1; go -------------------------------------------------------- use test_database_bulk_logged; go if object_id( 'dbo.table_bulk_logged', 'U' ) is not null drop table dbo.table_bulk_logged; go create table dbo.table_bulk_logged ( a varchar(512) ); go insert into dbo.table_bulk_logged select distinct replicate( rtrim(type), 512 ) from master..spt_values where len( type ) = 1; go -------------------------------------------------------- use test_database_simple; go if object_id( 'dbo.table_simple', 'U' ) is not null drop table dbo.table_simple; go create table dbo.table_simple ( a varchar(512) ); go insert into dbo.table_simple select distinct replicate( rtrim(type), 512 ) from master..spt_values where len( type ) = 1; go
Cоздадим индекс на каждой из таблиц:
use test_database_full; go checkpoint; go create index xxx on dbo.table_full (a); go use test_database_bulk_logged; go checkpoint; go create index xxx on dbo.table_bulk_logged (a); go use test_database_simple; go checkpoint; go create index xxx on dbo.table_simple (a); go
Перед созданием индекса, я создаю контрольную точку (checkpoint).
А теперь посмотрим с помощью недокументированной табличной функции fn_dblog, что было записано в журнал транзакций.
use test_database_full; go select AllocUnitName, Operation, Context, [Log Record Length] from fn_dblog( default, default ) where AllocUnitName like 'dbo.table_%'; go use test_database_bulk_logged; go select AllocUnitName, Operation, Context, [Log Record Length] from fn_dblog( default, default ) where AllocUnitName like 'dbo.table_%'; go use test_database_simple; go select AllocUnitName, Operation, Context, [Log Record Length] from fn_dblog( default, default ) where AllocUnitName like 'dbo.table_%'; go
Далее вы можете самостоятельно убедиться на сколько полно логируются другие операции над индексами. Удачи!