Какое значение имеет установка SET ALLOW_SNAPSHOT_ISOLATION ON? - PullRequest
16 голосов

Должен ли я запускать

ALTER DATABASE DbName SET ALLOW_SNAPSHOT_ISOLATION OFF

, если изоляция транзакции моментального снимка (TX) (iso) временно не используется?
Другими словами,

  • почему это должно бытьвключен, в первую очередь?
  • Почему он не включен по умолчанию?

Какова стоимость включения (но временно не использования) в SQL Server?


- Обновление:
включение моментального снимка ISO-уровня TX для базы данных не меняет READ COMMITTED tx ISO на значение по умолчанию.
Вы можете проверить это, выполнив:

use someDbName;
--( 1 )
alter database someDbName set allow_snapshot_isolation ON;
dbcc useroptions;

последняя строка показывает, что уровень tx iso текущего сеанса равен (чтение зафиксировано).

Таким образом, включение снимка tx iso level без его изменения не использует его и т. Д. Для его использования необходимо выполнить команду

--( 2 )
SET TRANSACTION ISOLATION LEVEL SNAPSHOT

Update2:
Я повторяю сценарии из [1], но с включенным SNAPSHOT (но не включенным), но без включения READ_COMMITTED_SNAPSHOT

--with enabling allow_snapshot_isolation
alter database snapshottest set allow_snapshot_isolation ON

-- but without enabling read_committed_snapshot
--alter database snapshottest set read_committed_snapshot ON
-- OR with OFF
alter database snapshottest set read_committed_snapshot OFF 
go

Нет результатов / строк от выполнения

select * from sys.dm_tran_version_store

послевыполнение INSERT, DELETE или UPDATE

Можете ли вы предоставить мне сценарии, иллюстрирующие, что включенный уровень iso уровня SNAPSHOT tx с помощью (1), но не включенный с помощью (2), создает любые версии в базе данных tempdb и / или увеличивает размер данныхс 14 байтами на строку?
Неужели я не понимаю, какой смысл в управлении версиями, если оно включено (1), но не используется (не установлено (2))?

[1]
Управление TempDB в SQL Server: основы TempDB (хранилище версий: простой пример)
http://blogs.msdn.com/b/sqlserverstorageengine/archive/2008/12/31/managing-tempdb-in-sql-server-tempdb-basics-version-store-simple-example.aspx

Ответы [ 2 ]

21 голосов
/ 07 ноября 2010

Как только управление версиями строк (или снимок) включено в базе данных, все записи должны быть версионными.Не имеет значения, на каком уровне изоляции происходила запись, поскольку уровни изоляции всегда влияют только на только чтения.Как только управление версиями строки базы данных будет включено, любая вставка / обновление / удаление:

  • увеличит размер данных с 14 байтами на строку
  • возможно создаст образ данных передобновление в хранилище версий (tempdb)

Опять же, совершенно неважно, какой уровень изоляции используется.Обратите внимание, что управление версиями строк также происходит, если выполняется любое из следующих условий:

  • таблица имеет триггер
  • MARS включен для соединения
  • Операция индексирования в сети выполняетсяв таблице

Все это объясняется в Использование ресурсов управления версиями строк :

Каждая строка базы данных может использовать до 14 байтов в концестрока для информации о версии строки.Информация о версиях строк содержит порядковый номер транзакции, которая зафиксировала версию, и указатель на версионную строку.Эти 14 байтов добавляются при первом изменении строки или при вставке новой строки в соответствии с any из следующих условий:

  • Значения READ_COMMITTED_SNAPSHOT или ALLOW_SNAPSHOT_ISOLATION включены.
  • Таблица имеет триггер.
  • Используется несколько активных наборов результатов (MARS).
  • Операции построения индекса в сетив данный момент выполняются на таблице.

...

Версии строк должны храниться до тех пор, пока активная транзакция должна получить к ней доступ.... если он соответствует любому из следующих условий:

  • Используется изоляция на основе версий строк.
  • Используются триггеры, MARS или оперативные операции построения индекса.
  • Генерирует версии строк.

Обновление

:setvar dbname testsnapshot

use master;

if db_id('$(dbname)') is not null
begin
    alter database [$(dbname)] set single_user with rollback immediate;
    drop database [$(dbname)];
end
go

create database [$(dbname)];
go

use [$(dbname)];
go


-- create a table before row versioning is enabled
--
create table t1 (i int not null);
go
insert into t1(i) values (1);
go

-- this check will show that the records do not contain a version number
--
select avg_record_size_in_bytes 
from sys.dm_db_index_physical_stats (db_id(), object_id('t1'), NULL, NULL, 'DETAILED')
-- record size: 11 (lacks version info that is at least 14 bytes)


-- enable row versioning and and create an identical table
--
alter database [$(dbname)] set allow_snapshot_isolation on;
go

create table t2 (i int not null);
go

set transaction isolation level read committed;
go

insert into t2(i) values (1);
go

-- This check shows that the rows in t2 have version number
--
select avg_record_size_in_bytes
     from sys.dm_db_index_physical_stats (db_id(), object_id('t2'), NULL, NULL, 'DETAILED')
-- record size: 25 (11+14)

-- this update will show that the version store has records
-- even though the isolation level is read commited
--
begin transaction;
update t1 
    set i += 1; 
select * from sys.dm_tran_version_store;
commit;
go

-- And if we check again the row size of t1, its rows now have a version number
select avg_record_size_in_bytes
from sys.dm_db_index_physical_stats (db_id(), object_id('t1'), NULL, NULL, 'DETAILED')
-- record size: 25
1 голос
/ 06 ноября 2010

По умолчанию у вас отключена изоляция моментальных снимков. Если вы включите ее, SQL будет поддерживать моментальные снимки данных для выполнения транзакций. Пример: при подключении 1 вы запускаете большой выбор. При подключении 2 вы обновляете некоторые записи, которые будут возвращены, сначала выбрав.

При включенной изоляции моментального снимка SQL создаст временную копию данных, затронутых обновлением, поэтому SELECT вернет исходные данные.

Любые дополнительные манипуляции с данными влияют на производительность. Вот почему этот параметр по умолчанию выключен.

...