Подтвердить что ты не робот

Каковы последствия SET-ting ALLOW_SNAPSHOT_ISOLATION ON?

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

ALTER DATABASE DbName SET ALLOW_SNAPSHOT_ISOLATION OFF

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

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

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


- Update:
включение моментального снимка TX iso level в базе данных не изменяется. 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

Можете ли вы предоставить мне сценарии, иллюстрирующие, что включен SNAPSHOT tx iso level (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

4b9b3361

Ответ 1

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

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

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

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

Все это объясняется в Row Versioning Resource Usage:

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

  • Параметры READ_COMMITTED_SNAPSHOT или ALLOW_SNAPSHOT_ISOLATION: ON.
  • В таблице есть триггер.
  • Используются несколько активных наборов результатов (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

Ответ 2

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

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

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