Помилка "База даних переходить"


12

Сьогодні я намагався відновити базу даних вже існуючої бази даних, я просто правою кнопкою миші клацнув по базі даних в SSMS -> Завдання -> Візьми офлайн, щоб я міг відновити базу даних.

З’явилося невелике спливаюче вікно, Query Executing.....якесь час показало, а потім кинуло помилку Database is in use cannot take it offline. З якого я зібрався, є кілька активних підключень до цієї бази даних, тому я спробував виконати наступний запит

USE master
GO
ALTER DATABASE My_DatabaseName
SET OFFLINE WITH ROLLBACK IMMEDIATE
GO

Знову ж таки, SSMS показав Query Executing.....якийсь час, а потім кинув таку помилку:

Msg 5061, Level 16, State 1, Line 1
ALTER DATABASE failed because a lock could not be placed on database 'My_DatabaseName'. Try again later.
Msg 5069, Level 16, State 1, Line 1
ALTER DATABASE statement failed.

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

Database is in Transition. Try later .....

На цьому етапі я просто не міг торкнутися бази даних, що б я не намагався повернути те саме повідомлення про помилку Database is in Transition.

У Google я прочитав кілька запитань, де люди стикалися з подібною проблемою, і вони рекомендували закрити SSMS і відкрити його знову. Так я і, оскільки це був лише сервер розробників, я просто видалив базу даних за допомогою SSMS і відновив її в новій базі даних.

Моє запитання, що могло це, можливо, викликати це ?? і як я можу уникнути цього в майбутньому, і якщо я коли-небудь опиниться в тій же ситуації в майбутньому, чи є інший спосіб виправити це інше, ніж видалити всю базу даних ???

Дякую

Відповіді:


24

Репро

  1. Відкрийте SSMS
  2. Введіть наступне у нове вікно запитів

    use <YourDatabase>;
    go
  3. Перейдіть до Провідника об’єктів (SSMS) і клацніть правою кнопкою миші на <YourDatabase>-> Tasks->Take Offline
  4. Відкрийте друге вікно нового запиту та введіть таке:

    use <YourDatabase>;
    go

Вам буде запропоновано таке повідомлення:

Msg 952, рівень 16, стан 1, рядок 1 "
База даних" TestDb1 "переходить. Спробуйте заяву пізніше.

Причину цього відбувається в аналогічному діагностичному запиті, наведеному нижче:

select
    l.resource_type,
    l.request_mode,
    l.request_status,
    l.request_session_id,
    r.command,
    r.status,
    r.blocking_session_id,
    r.wait_type,
    r.wait_time,
    r.wait_resource,
    request_sql_text = st.text,
    s.program_name,
    most_recent_sql_text = stc.text
from sys.dm_tran_locks l
left join sys.dm_exec_requests r
on l.request_session_id = r.session_id
left join sys.dm_exec_sessions s
on l.request_session_id = s.session_id
left join sys.dm_exec_connections c
on s.session_id = c.session_id
outer apply sys.dm_exec_sql_text(r.sql_handle) st
outer apply sys.dm_exec_sql_text(c.most_recent_sql_handle) stc
where l.resource_database_id = db_id('<YourDatabase>')
order by request_session_id;

Для того, що це варто, вам не потрібен Провідник об’єктів для відтворення цієї помилки. Вам просто потрібен заблокований запит, який намагається здійснити ту саму операцію (у цьому випадку перенесіть базу даних в офлайн). Дивіться скріншот нижче трьох кроків у T-SQL:

введіть тут опис зображення

Що ви, швидше за все, побачите, це ваш сеанс Провідника об’єктів заблокований іншим сеансом (показано на blocking_session_id). Цей сеанс Провідника об’єктів намагатиметься отримати ексклюзивний замок ( X) на базі даних. У наведеному вище випадку запиту сесії Object Explorer було надано блокування оновлення ( U) та спроба перетворення в ексклюзивний замок ( X). Він мав тип очікування LCK_M_X, заблокований нашим сеансом, який був представлений першим вікном запиту ( use <YourDatabase>хапає спільний замок ( S) в базі даних).

А потім ця помилка виникла в результаті ще однієї сесії, яка намагається отримати блокування, і це повідомлення про помилку призводить до відмови в сеансі для отримання доступу до бази даних, яка намагається перейти в інший стан (у цьому випадку стан онлайн до офлайн переходу).

Що робити наступного разу?

По-перше, не панікуйте і не починайте скидати бази даних . Вам потрібно скористатися підходом до усунення несправностей (з аналогічним діагностичним запитом, як у наведеному вище), щоб з’ясувати, чому ви бачите те, що бачите. З таким повідомленням або коли щось з’являється «висіло», вам слід автоматично припустити відсутність одночасності і почати розкопуватися на блокування ( sys.dm_tran_locksце хороший старт).

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

Ще одна річ, яку варто зазначити, це одна з причин, чому я завжди вибираю альтернативу T-SQL замість GUI. Ви точно знаєте, що виконуєте за допомогою T-SQL і що робить SQL Server. Зрештою, ви видали явну команду. Під час використання графічного інтерфейсу фактичний T-SQL стане абстракцією. У цьому випадку я переглянув спробу заблокованого Провідника Об’єктів зняти базу даних в автономному режимі ALTER DATABASE <YourDatabase> SET OFFLINE. Не було спроби відкату, через що її чекали нескінченно. У вашому випадку, якби ви хотіли відмовити сеанси, які мали блокування в цій базі даних, вам ALTER DATABASE ... SET OFFLINE WITH ROLLBACK IMMEDIATE, швидше за все, було б достатньо, якби ви попередньо визначили, що відкат був у порядку.


4

Просто закриття студії управління SQL Server (SSMS) та повторне відкриття вирішили проблему для мене.


0

Не потрібно нічого робити, просто вбийте процес SqLWB.exeіз диспетчера завдань, відкрийте SQL Server, клацніть правою кнопкою миші на базі даних та перенесіть її в офлайн. Якщо це не працює, після введення сеансу введіть команду

ALTER DATABASE [Test4] SET OFFLINE WITH ROLLBACK IMMEDIATE

а потім офлайн. Він працюватиме так, як працював і для мене.

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