Эта проблема очень хорошо решается пользователями Windows Server.
. Перейдите по этому пути. C: \ Program Files \ MySQL \ MySQL Server 5.1 \ bin
запустить этот инструмент «MySQLInstanceConfig.exe»
и снова сконфигурировать экземпляр, и проблема решена
Вы можете «откусите» удаление, что также означает, что вы не вызовете огромной нагрузки на базу данных. Если ваши резервные копии t-log выполняются каждые 10 минут, вы можете запустить это один или два раза с тем же интервалом. Вы можете запланировать его как задание агента SQL
, попробуйте что-то вроде этого:
DECLARE @count int
SET @count = 10000
DELETE FROM table1
WHERE table1id IN (
SELECT TOP (@count) tableid
FROM table1
WHERE x='y'
)
Чем отличаются строки, которые вы хотите удалить, от тех, которые вы хотите сохранить? Будет ли это работать для вас:
while exists (select 1 from your_table where <your_condition>)
delete top(10000) from your_table
where <your_condition>
Похоже, что это разовая операция (я надеюсь на вас), и вам не нужно возвращаться в состояние, которое находится на полпути к этому пакетному удалению - если это так, почему бы и нет вы просто переключаетесь в режим SIMPLE транзакции перед запуском, а затем обратно в FULL, когда закончите?
Таким образом, журнал транзакций не будет так сильно увеличиваться. Это может быть не идеально в большинстве ситуаций, но я не вижу здесь ничего плохого (при условии, что, как указано выше, вам не нужно возвращаться в состояние, которое находится между удалениями).
вы можете сделать это в своем скрипте с помощью smt как:
ALTER DATABASE myDB SET RECOVERY FULL/SIMPLE
В качестве альтернативы вы можете настроить задание для сжатия журнала транзакций через каждый заданный интервал времени - пока выполняется удаление. Это довольно плохо, но я думаю, что это поможет.
Что ж, если бы вы использовали секционирование SQL Server, скажем, на основе столбца даты, вы, возможно, отключили бы разделы, которые больше не нужны. Возможно, стоит рассмотреть вопрос о будущей реализации.
Я думаю, что лучшим вариантом может быть, как вы говорите, удаление данных небольшими партиями, а не одним обращением, чтобы избежать любых потенциальных проблем с блокировкой.
Вы могли бы также рассмотрите следующий метод:
Я бы сделал что-то похожее на предложения временной таблицы, но я бы выбрал новый постоянную таблицу строки, которые вы хотите сохранить, удалите исходную таблицу и переименуйте новую. Это должно иметь относительно низкое влияние на транзакцию. Очевидно, не забудьте воссоздать все индексы, которые требуются для новой таблицы после того, как вы ее переименовали.
Только мои два p'enneth.
В дополнение к помещению этого в пакет с оператором для усечения журнала вы также могут захотеть попробовать эти уловки:
. Например, для первого пункта выше, если ваш ПК кластеризован, найдите диапазон, который приблизительно соответствует количеству строк, которые вы хотите чтобы удалить каждый пакет и использовать это:
DECLARE @max_id INT, @start_id INT, @end_id INT, @interval INT
SELECT @start_id = MIN(id), @max_id = MAX(id) FROM My_Table
SET @interval = 100000 -- You need to determine the right number here
SET @end_id = @start_id + @interval
WHILE (@start_id <= @max_id)
BEGIN
DELETE FROM My_Table WHERE id BETWEEN @start_id AND @end_id AND <your criteria>
SET @start_id = @end_id + 1
SET @end_id = @end_id + @interval
END
Я согласен с людьми, которые хотят, чтобы вы перебирали меньший набор записей, это будет быстрее, чем пытаться выполнить всю операцию за один шаг. Вы можете испытать количество записей, которые следует включить в цикл. Около 2000 за раз кажутся золотыми пятнами для большинства таблиц. Я делаю большие дельты, хотя некоторым нужны меньшие суммы, например 500. Зависит от количества иностранных ключей, размера записи, триггеров и т. Д., Так что это действительно займет некоторые экспериментируют, чтобы найти то, что вам нужно. Это также зависит от того, насколько интенсивно использование стола. Таблица с интенсивным доступом потребует, чтобы каждая итерация цикла выполнялась за меньшее время. Если вы можете работать в нерабочее время или, лучше всего, в однопользовательском режиме, вы можете удалить больше записей за один цикл.
Если вы не думаете, что сделаете это за одну ночь в нерабочее время, Возможно, лучше всего разработать цикл со счетчиком и делать только определенное количество итераций каждую ночь, пока это не будет выполнено.
Кроме того, если вы используете неявную транзакцию, а не явную, вы можете завершить запрос цикла на в любой момент уже удаленные записи останутся удаленными, за исключением тех, которые находятся в текущем раунде цикла. Гораздо быстрее, чем пытаться откатить полмиллиона записей, потому что вы остановили систему.
Обычно рекомендуется создавать резервную копию базы данных непосредственно перед выполнением операции такого рода.
вы можете завершить запрос цикла в любое время, и уже удаленные записи останутся удаленными, за исключением тех, которые находятся в текущем цикле цикла. Гораздо быстрее, чем пытаться откатить полмиллиона записей, потому что вы остановили систему.Обычно рекомендуется создавать резервную копию базы данных непосредственно перед выполнением операции такого рода.
вы можете завершить запрос цикла в любое время, и уже удаленные записи останутся удаленными, за исключением тех, которые находятся в текущем цикле цикла. Гораздо быстрее, чем пытаться откатить полмиллиона записей, потому что вы остановили систему.Обычно рекомендуется создавать резервную копию базы данных непосредственно перед выполнением операции такого рода.
Короткий ответ: вы не можете удалить 2 миллиарда строк без какого-либо серьезного простоя базы данных.
Лучшим вариантом может быть копирование данных во временную таблицу и усечение исходную таблицу, но это заполнит вашу базу данных tempDB и будет использовать не меньше протоколирования, чем удаление данных.
Вам нужно будет удалить столько строк, сколько сможете, пока журнал транзакций не заполнится, а затем каждый раз усекать его. Ответ, предоставленный Станиславом Князевым, можно было изменить для этого, увеличив размер пакета и добавив вызов для усечения файла журнала.