Великий запит на видалення, здається, застиг


10

Ми виконували запит на видалення в базі даних з 1,8 млрд. Рядків. Це видалення видалило б 1,2 млрд. Рядків.

Заздалегідь ми розбили би цей запит на 100 м за один раз, але ми знаходимося в стані, коли він працює протягом 24 годин, а файл журналу - 2Tb, що, як видається, є максимально допустимим розміром для файлу журналу.

База даних знаходиться в простому режимі відновлення.

Чи зберігається цей запит? Або нам потрібно просто перезапустити SQL Server і подивитися, що відбувається? Чи буде база даних непридатною? Чи є щось, що ми можемо зробити, щоб знищити це якомога чисто?


Ви запускали його з SSMS? Просто скасуйте його. Це займе певний час, щоб скасувати. Як приблизно, поки він працює. Вам потрібно набратися терпіння.
папараццо

1
@Graeme З нашого досвіду роботи з базами даних мільярдів записів (ми працюємо з ними декількох), іноді швидше зберігати решта записів із таблиці жертв, усікати, видаляти, перейменовувати збережені записи назад у вихідне ім'я та відновити індекси, якщо такі є .
Антон Круглов

1
Після того, як ви очистите цей павук, я б рекомендував набагато менші партії, ніж 100 м, я зазвичай роблю від 100 до 1 м. Крім того, використовуйте свій основний ключ як пункт WHERE, щоб вибрати записи для видалення, якщо це можливо.
BradC

Скорочення - це ваш друг, коли ви видаляєте велику кількість даних і намагаєтесь уникнути проблем з журналом.
Jeff.Clark

Відповіді:


14

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

Навіть якщо він є, я завжди вважаю за краще вбивати павука вручну (використовувати sp_who2або sp_WhoIsActiveзнайти павука, а потім робити те kill 59чи інше). Ви також не можете перевірити стан відкату, якщо ви не зробите явний KILL, дивіться цю пов’язану тему .

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

Щоб побачити стан відкату, використовуйте

kill 59 with statusonly

На жаль, я виявив, що це часто не показує нічого корисного, лише "0% завершено". У такому випадку вам доведеться використовувати sp_who2та переглядати IO та процесор, щоб побачити, чи все ще щось робить.

Що стосується перезавантаження, це є серйозним ризиком. Якщо павук активно відкочується (зміниться процесор і IO), то перезапуск SQL буде повністю відключати базу даних в автономному режимі до повного завершення відкату (години та години). Але якщо CPU та IO не рухаються, то насправді це може бути зрозуміло відразу. У будь-якому випадку це ризик.

Один останній варіант, якщо справи особливо страшні: якщо у вас є резервна копія безпосередньо перед початком видалення (а інших оновлень не було) , то найшвидшим способом відновлення може бути просто скинути БД, перезапустити SQL та відновлення з резервного копіювання.

Якщо ви не можете скинути БД (або якщо ви вже перезапустили екземпляр, а файл помилок sql передбачає 24-годинний час відновлення), тоді вимкніть служби SQL, видаліть з диска файли MDF та LDF, запустіть SQL, скиньте базу даних (ghost) та відновлення з резервного копіювання.

Очевидно, ви б спробували лише це, якби це резервна база даних, з якою користувачі не взаємоділи.


3
Гарна порада щодо варіанту відновлення. Страшно, як пекло, але все-таки хороша порада.
Макс Вернон

2
Так, у нас був перезапуск екземпляра DBA в такому стані, що змусило нас вирішити між двома дуже поганими варіантами: бути вниз на 18-24 години або втратити дані, відкотившись до початку запиту. Бізнес вирішив відкотити.
BradC

1
З 4 березня у нас є повна резервна копія, яку ми відновимо в крайньому випадку, якщо перезавантаження не працює. На щастя, це досить статичний БД, який ми просто хотіли обрізати. Дякую за відгук, дуже корисно
Graeme

4
@Graeme - FYI - замість того, щоб намагатися видалити 1,2 мільярда рядків, зробіть копію структури таблиці, скопіюйте рядки, які ви хочете зберегти, у нову таблицю, а потім опустіть стару таблицю. Якщо ви додасте нове запитання із запитанням, як це зробити, я можу показати вам дуже гладкий спосіб, який набагато швидше, ніж видалення 1,2 мільярда рядків.
Макс Вернон

Моя відповідь передбачає, що db знаходиться в простому режимі відновлення. Якщо він перебуває в ПОВНОМУ режимі, вам також доведеться керувати величезними резервними копіями журналів транш.
BradC

8

НЕ РЕСТАРТАЙТЕ SQL Server. Це лише продовжить вашу агонію, оскільки відбудеться відновлення, яке призведе до відкоту або повторного завершення транзакцій, не завершених, включаючи видалення.

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

Ви хочете переглянути наступний запит, щоб побачити стан операції:

SELECT des.session_id 
    , des.host_name
    , des.login_name
    , der.command
    , der.estimated_completion_time
    , der.blocking_session_id
    , der.last_wait_type
    , der.percent_complete
    , der.start_time
    , der.status
    , der.wait_resource
    , der.wait_type
    , der.wait_time
FROM sys.dm_exec_sessions des
    INNER JOIN sys.dm_exec_requests der ON des.session_id = der.session_id
WHERE des.session_id <> @@SPID
    AND des.is_user_process = 1
ORDER BY des.session_id;

percent_completeКолонка, і ті , які покладаються на нього, наприклад estimated_completion_time, заповнюються тільки для наступних операцій:

ALTER INDEX REORGANIZE
AUTO_SHRINK option with ALTER DATABASE
BACKUP DATABASE
DBCC CHECKDB
DBCC CHECKFILEGROUP
DBCC CHECKTABLE
DBCC INDEXDEFRAG
DBCC SHRINKDATABASE
DBCC SHRINKFILE
RECOVERY
RESTORE DATABASE
ROLLBACK
TDE ENCRYPTION

Таким чином, ви побачите, що цей стовпець має значення лише у тому випадку, якщо ви вже скасували операцію видалення, і вона відкочується назад, або якщо ви вже перезапустили SQL Server і він перебуває у відновленні.

Якщо blocking_session_idстовпець містить число, що вказує на те, що інший сеанс блокує операцію видалення. Якщо цей сеанс блокує операцію видалення з моменту її запуску, можливо, ви зможете скасувати операцію, не потребуючи відкату.


Хороші запити, але здається, що журнал зробив би величезним, якби видалення було заблоковано.
BradC

4
так. Я просто намагаюся трохи пояснити вихід. Майбутні читачі також можуть це бачити. Насправді я сумніваюся, чи почуємо ми з ОП в наступний час. Ймовірно, він досить зайнятий.
Макс Вернон
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.