Скільки часу має зайняти SET READ_COMMITTED_SNAPSHOT ON?


76

Скільки часу потрібно запустити

ALTER DATABASE [MySite] SET READ_COMMITTED_SNAPSHOT ON

Я просто запустив його, і це зайняло 10 хвилин.

Як я можу перевірити, чи застосовується він?


1
ой. не було включено весь цей час !! (серйозно!), що пояснює тупикові ситуації. див. мою відповідь нижче для повних висновків та кращого сценарію для запуску
Simon_Weaver

2
Сама дія завершується майже миттєво. Причина, по якій він не повернеться, полягає в тому, що він чекає, поки інші користувачі вийдуть з бази даних. Це не так, як зайнято мисленням, відбиванням, споживанням ресурсів; він чекає, поки всі вийдуть із кімнати, тому він зміниться, натиснувши перемикач.
Ян Бойд,

Відповіді:


68

Ви можете перевірити статус параметра READ_COMMITTED_SNAPSHOT, використовуючи sys.databasesподання. Перевірте значення is_read_committed_snapshot_onстовпця. Вже запитували і відповідали .

Що стосується тривалості, Books Online заявляє, що не може бути інших підключень до бази даних, коли це відбувається, але для цього не потрібен однокористувацький режим. Тож вас можуть заблокувати інші активні зв’язки. Запустіть sp_who(або sp_who2), щоб побачити, що ще підключено до цієї бази даних.


Дякую. це зайняло 40 хвилин і показує 0. свою базу даних розміром 740 Мб. пальцями схрещеними я не зламав
Simon_Weaver

3
Спробуйте відкрити інше вікно запиту щодо цієї бази даних. Якщо ви можете, тоді, я гадаю, ваша заява ще не почала працювати.
Рік,

3
Так. Для більшості баз даних це має зайняти кілька секунд. Якщо це займає більше часу, це очікує, щоб інше (навіть неактивне) з'єднання розірвалося, перш ніж воно зможе внести зміни. Тож вам може знадобитися знайти та ВБИТИ будь-яких підключених на даний момент павуків (після оцінки того, що вони роблять). ПОтім це повинно йти швидко.
Michael K. Campbell

16
Я рекомендую використовувати опцію NO_WAIT, щоб негайно вийти з ладу, якщо є інші відкриті з'єднання. Наприклад, "ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH NO_WAIT"
StefanR

1
Якщо ви не можете знайти та вбити інші підключені SPID (або просто вам все одно), ви завжди можете просто перезапустити екземпляр SQL Server.
Девід Мердок

50

Спробуйте це:

ALTER DATABASE generic SET READ_COMMITTED_SNAPSHOT ON WITH ROLLBACK IMMEDIATE

2
Отже, яка користь від «З ОТРИМАННЯМ НЕГАЙНОГО»? це означає, що він буде автоматично відкочуватися назад, коли запит не вдався?
Старший системний інженер

5
Ні, "WITH ROLLBACK IMMEDIATE" означає, що він негайно відкатить усі відкриті транзакції перед запуском оператора ALTER DATABASE. Я не радив би цього робити, якщо ви вже не перевірили, які транзакції відкриті та чи можна їх безпечно відкотити.
Рік

Дивно, але також повідомляє про хід закриття з'єднань. Ти врятував наш бекон!
Тайет

31

Добре (я оригінальний запитувач), тому, виявляється, увесь час у мене навіть не було включеної проклятості.

Ось найкращий код для запуску, щоб увімкнути режим знімків та переконатися, що він увімкнений.

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

ALTER DATABASE shipperdb SET allow_snapshot_isolation ON
ALTER DATABASE shipperdb SET SINGLE_USER WITH ROLLBACK IMMEDIATE
ALTER DATABASE shipperdb SET read_committed_snapshot ON
ALTER DATABASE shipperdb SET MULTI_USER

SELECT is_read_committed_snapshot_on, snapshot_isolation_state_desc,snapshot_isolation_state FROM sys.databases WHERE name='shipperdb'

Це працює навіть при активних з'єднаннях (імовірно, у вас все добре, коли їх викидають).

Ви можете бачити стан до та після, і це повинно запускатися майже відразу.


ВАЖЛИВО:

Параметр READ_COMMITTED_SNAPSHOT вище відповідає IsolationLevel.ReadCommitted в .NET
Параметр ALLOW_SNAPSHOT_ISOLATION вище відповідає IsolationLevel.Snapshot у .NET

Чудова стаття про різні версії


Поради .NET.

Схоже, Isolationlevel.ReadCommittedце дозволено в коді, навіть якщо це не ввімкнено базою даних. Попередження не кидається. Тож зробіть собі послугу та переконайтесь, що вона увімкнена, перш ніж ви припустите, що це три роки, як я !!!

Якщо ви використовуєте C #, ви, мабуть, хочете ReadCommittedIsolationLevel, а ні Snapshot- якщо ви не робите записи в цій транзакції.

READ COMMITTED SNAPSHOTробить оптимістичні читання та песимістичні записи. На відміну від цього, SNAPSHOTробить оптимістичні читання та оптимістичні записи. (звідси)

bool snapshotEnabled = true;

using (var t = new TransactionScope(TransactionScopeOption.Required,
               new TransactionOptions
{
     IsolationLevel = IsolationLevel.ReadCommitted
}))
{
     using (var shipDB = new ShipperDBDataContext())
     {

     }
}

Крім того, ви можете отримати повідомлення про те, що транзакцію неможливо просувати. Шукайте «просування» у розділі « Введення System.Transaction» у .NET Framework 2.0 .

Якщо ви не робите щось особливе, як підключення до зовнішньої бази даних (або другої бази даних), то щось таке просте, як створення нового DataContext, може спричинити це. У мене був кеш, який `` закрутив '' власний контекст даних при ініціалізації, і він намагався переробити транзакцію до повної розподіленої.

Рішення було простим:

        using (var tran = new TransactionScope(TransactionScopeOption.Suppress))
        {
            using (var shipDB = new ShipperDBDataContext())
            { 
                 // initialize cache
            }
        }

Див. Також Deadlockedстаттю @CodingHorror


4
Я хотів зазначити, оскільки я не був впевнений: Ви можете вмикати READ_COMMITTED_SNAPSHOTнезалежно від ALLOW_SNAPSHOT_ISOLATION. Ви можете мати ALLOW_SNAPSHOT_ISOLATION від і до сих пір вигоди від READ_COMMITTED_SNAPSHOTтого на . Перевірено: Microsoft SQL Server 2012 - 11.0.2100.60
Ян Бойд,

3
Цей параметр змінює спосіб реалізації READ COMMITTED. Якщо параметр вимкнено, SQL Server використовуватиме блокування для контролю доступу. Ось чому ваш код .NET не видав попередження - ви все ще отримували поведінку, просто виконану іншим способом (і, швидше за все, глухою точкою)
Річард

Це не відповідає на вихідне запитання, хоча написане OP. Він реалізує альтернативу.
Майк М

9

Спробуйте цей код:

if(charindex('Microsoft SQL Server 2005',@@version) > 0)
begin
    declare @sql varchar(8000)
    select @sql = '
    ALTER DATABASE ' + DB_NAME() + ' SET SINGLE_USER WITH ROLLBACK IMMEDIATE ;
    ALTER DATABASE ' + DB_NAME() + ' SET READ_COMMITTED_SNAPSHOT ON;
    ALTER DATABASE ' + DB_NAME() + ' SET MULTI_USER;'

    Exec(@sql)
end

Вам слід обернути свої виклики db_name () цитатою (), щоб врахувати будь-які символи в назві бази даних, які можуть потребувати екранування (наприклад, пробіли).
Рік,

вам також потрібно 'SET SET__Snapshot_isolation ON', так? (див. мою відповідь)
Simon_Weaver

Документи mssql стверджують, що вам потрібно встановити дозволити ізоляцію знімка. Але я дуже радий знайти цю робочу відповідь в океані шуму SQL-сервера.
Amalgovinus

7

Я спробував команду:

ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

проти коробки розробників, але це зайняло 10+ хвилин, і тому я його вбив.

Потім я знайшов це:

https://willwarren.com/2015/10/12/sql-server-read-committed-snapshot/

і використав свій блок коду (на запуск якого пішло близько 1:26):

USE master
GO

/** 
 * Cut off live connections
 * This will roll back any open transactions after 30 seconds and
 * restricts access to the DB to logins with sysadmin, dbcreator or
 * db_owner roles
 */
ALTER DATABASE MyDB SET RESTRICTED_USER WITH ROLLBACK AFTER 30 SECONDS
GO

-- Enable RCSI for MyDB
ALTER DATABASE MyDB SET READ_COMMITTED_SNAPSHOT ON
GO

-- Allow connections to be established once again
ALTER DATABASE MyDB SET MULTI_USER
GO

-- Check the status afterwards to make sure it worked
SELECT is_read_committed_snapshot_on
FROM sys.databases
WHERE [name] = 'MyDB '

3

Спробуйте використовувати головну базу даних перед тим, як змінювати поточну базу даних.

USE Master
GO

ALTER DATABASE [YourDatabase] SET READ_COMMITTED_SNAPSHOT ON
GO


0

Спробуйте Вимкнути інші служби SQL, щоб працювала лише служба SQL-сервера.

Шахта бігала 5 хвилин, тоді я її скасував, бо було очевидно, що нічого не відбувається. Це абсолютно новий сервер, тому інших користувачів не підключено. Я вимкнув служби звітування SQL, а потім запустив його знову .. на завершення пішло менше секунди.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.