Потеря данных после убийства SQL Spid
Это действительно опасная ситуация для меня, как начинающего администратора баз данных.
Иногда, когда я вижу, что на экране Activity Monitor есть тупик, если запрос не заканчивается и остается в состоянии приостановки, а также в блоке head, мне приходится убивать этот спид. Не всегда, но иногда, хотя и редко, после убийства spid много данных теряется из базы данных. Я предполагаю, что он теряет данные с начала блокировки до того, как я убью. Как я понимаю, Sql-сервер не сохраняет данные сразу, он ждет некоторое время (какой-то цикл, возможно, каждые 15 минут) и сохраняет данные, когда считает, что все в порядке.
Например, я делал полное резервное копирование каждые 6 часов, а резервное копирование транзакций - каждые 10 минут. Прошлой ночью он не мог сделать резервную копию в 00:00 по какой-то причине, и этот спид находился в состоянии ожидания. Когда я убил этот спид в 08:30 утра, я потерял все данные из всех таблиц с 00:00 до 08:30.
У меня полная модель восстановления и использую MsSqlServer2012.
Потеря данных в производственной базе данных - очень большой риск. Мой вопрос Как я могу быть уверен, что SQL действительно сохранил данные до уничтожения спида?
2 ответа
После выполнения моей базы данных в коде внутри с использованием блоков все проблемы с блокировкой исчезли.
На самом деле нет способа предотвратить потерю данных в описанных вами ситуациях. SQL Server предназначен для обнаружения взаимоблокировок и автоматического выбора жертвы для уничтожения (если, конечно, вы не используете DEADLOCK_PRIORITY
указать, какой запрос менее важен). Это означает, что должен произойти откат, а SQL Server должен выполнить служебную работу для обеспечения согласованности данных. Вы мешаете этому. Потерять данные просто невозможно.
Скажем, у вас есть два запроса, пытающихся использовать ресурс, и возникает тупик. Через некоторое время SQL Server обнаруживает это и решает уничтожить один поток. Поскольку SQL Server придерживается принципов ACID, запрос не просто автоматически останавливается, он начинает откат. Если этот запрос внес много изменений, это означает, что SQL Server должен прокрутить журналы и отменить все изменения до остановки потока. Это означает, что может пройти очень и очень много времени между обнаружением тупика в SQL Server и его устранением. Ни в коем случае не пытайтесь ускорить процесс, убивая блокирующие SPID.
Это скорее организационное и эксплуатационное ограничение, чем техническое. Вы и сотрудники, использующие ваши SQL-серверы, должны знать, что если вы начнете запрос, он ДОЛЖЕН завершиться. Это означает, что, если запрос завершается, обнаруживает ошибку и должен откатываться, выбирается ли он для удаления в сценарии взаимоблокировки и должен откатываться, и т. Д. ВСЕ запросы должны завершаться. Зная это, вы должны двигаться вперед с мыслью, что НЕ МОЖЕТЕ убить SPID, потому что они занимают много времени или потому что они заблокированы. Если заинтересованные стороны будут преследовать вас за уничтожение SPID из-за потери производительности, объясните им, почему оскорбительные запросы должны выполняться до конца, и что может произойти, если вы вмешиваетесь (УБЫТКА ДАННЫХ ПРОИЗВОДСТВА). Говорите с точки зрения рисков для бизнеса вместо "мы должны" или "мы не должны". Если заинтересованные стороны не убеждены и все еще хотят, чтобы вы что-то сделали, например, убили SPID, обратитесь к своему руководству и попросите их принять решение. Если вы администрация, очень четко задокументируйте, что заинтересованные стороны просят вас сделать что-то опасное, и подготовьте эту документацию. Поверьте мне, они спросят, почему рабочий сервер не работает весь день, и вы должны иметь возможность четко документировать всех игроков и их роли.
Кроме того, обучите сотрудников, использующих серверы, разбивать большие транзакции на более мелкие или использовать BEGIN
/COMMIT
, Таким образом, если есть проблема и необходимо откатить запрос, это займет минуты или часы вместо дней. За последние 2 года в моем офисе произошел взрыв данных, и теперь у нас есть несколько таблиц, каждая из которых содержит более миллиарда строк. Период обучения был очень болезненным: у нас было много недель, когда продуктивность была в унитазе, потому что люди пытались делать огромные обновления или создавать очень большие наборы данных, была ошибка, и последующий откат шел на ДНИ. После того, как мы изучили и внедрили некоторые стандартные рабочие процедуры для разбивки запросов на более мелкие партии, все стало лучше. Тем не менее, мне страшно подумать, что случилось бы, если бы администраторы БД только начали убивать SPID.
Короче говоря, вы ничего не можете сделать, чтобы предотвратить потерю данных, если продолжите уничтожать SPID. Вы должны позволить SQL Server продолжать управлять запросом до тех пор, пока он не будет завершен или уничтожен и не завершит откат. Если вы попытаетесь вручную убить эти запросы, вы потеряете данные. Обойти это невозможно.
Дальнейшее чтение:
http://msdn.microsoft.com/en-us/library/aa480356.aspx
http://technet.microsoft.com/en-us/library/aa213030%28v=sql.80%29.aspx
https://www.simple-talk.com/sql/database-administration/handling-deadlocks-in-sql-server/