Mail.ruПочтаМой МирОдноклассникиВКонтактеИгрыЗнакомстваНовостиКалендарьОблакоЗаметкиВсе проекты

Что делать, если случайно ввёл не тот запрос в бд (mysql)?

veroman Профи (768), на голосовании 2 недели назад
Ситауация такая:
Ввёл случайно запрос UPDATE, где не указал WHERE. Получилось типа:

 UPDATE files SET id = 1; 

Теперь везде id равный единице. Как откатить? Транзакций нет, бекапы недавно все поудалял, есть тольк бинлоги, но я ваще хз, как оттуда что-то откатить.
Голосование за лучший ответ
Бабер Просветленный (24702) 1 месяц назад
пиши заного
AABAОракул (54132) 1 месяц назад
он настока туп и агрессивен, что даже забанил норм. ответ... куда уж ему "заного"... и "выного"!
Андрей Панарин Искусственный Интеллект (273057) 1 месяц назад
Как-то Том Скотт рассказывал похожий случай, как он решил сделать реплейс во всех статьях и перепутал кавычки, из-за чего тексты всех статей затерлись одинаковыми строками. Транзакцию он не начал, поэтому откат оказался невозможен. Опыт — сын ошибок трудных.

Полагаю, у вас аналогичный случай. Если у вас имеется резервная копия БД, то можете накатить ее. А если нет, тогда либо чао-какао, либо восстанавливать айдишники по косвенным признакам.

Например, у записей часто вместе с ID идет дата создания, так что сортировка по дате дает тот же результат, что и по ID. Если вы сможете собрать список всех существовавших айдишников (например внешних ключей в таблице) и перенести этот список на место затертых айдишников в отсортированной по дате таблице (если там и там строчек одинаково), то в теории это может решить проблему.

Только не забывайте о транзакциях.

P. S. Полагаю, этого бы не произошло, если бы ID был первичным ключом, который не может повторяться.
Jurijus Zaksas Искусственный Интеллект (470347) 1 месяц назад
Если не запускал транзакцию, то чуть менее, чем никак.
Некоторые базы имеют дополнительное темпоральное измерение и позволяют откатить таблицу до предыдущего состояния. В Snowflake это встроенный функционал (если его не отключить, конечно), в Oracle ЕМНИП надо ставить специальный модуль, насчет других баз не в курсе.
Если твоя таблица пока ни с чем не связана, можешь просто перенумеровать все строки заново, хуже не будет (Оракловский синтаксис):

 UPDATE files SET id = ROWNUM;
ALTER TABLE FILES ADD CONSTRAINT PK_FILES PRIMARY KEY (ID); --Это на будущее, во избежание
S.H.I. Оракул (73650) 1 месяц назад
1. Сначала определите время, когда произошла ошибка
2. Используйте утилиту `mysqlbinlog` для просмотра и восстановления:
 mysqlbinlog --start-datetime="2025-03-07 10:00:00" --stop-datetime="2025-03-07 10:10:00" /path/to/binlog | mysql -u root -p 

Или найдите конкретную позицию в логе:
 mysqlbinlog /path/to/mysql-bin.00001 | grep -A10 -B10 "UPDATE files SET id = 1" 
Затем выполните восстановление до точки непосредственно перед неправильным запросом.
Похожие вопросы