Восстановление после неправильного запроса на обновление MySQL?

Я сделал неправильный запрос на обновление в своей таблице.

Я забыл делать идентификационное поле в WHERE пункт.

Так, чтобы обновленный все мои строки.

Как восстановить это?

У меня не было резервного копирования....

12
задан Juan Mellado 3 May 2012 в 09:59
поделиться

3 ответа

Извини, но шансы на восстановление перезаписанной базы данных MySQL обычно близки к нулю. В отличие от удаления файла, перезапись записи фактически и физически перезаписывает существующие данные в большинстве случаев.

Чтобы быть готовым к тому, что что-то произойдет, необходимо остановить сервер MySQL и сделать копию физического каталога, содержащего БД, чтобы ничто не могло быть перезаписано далее: Простое копирование+вставка папки с данными в другое место должно быть выполнено.

Но не надейтесь - я думаю, что на самом деле ничего нельзя сделать.

Возможно, вы захотите настроить частое резервное копирование базы данных на будущее. Вокруг существует множество решений; одним из самых простых, надежных и легких в автоматизации (используя на или cron в Linux, или планировщик задач в Windows) является собственный mysqldump MySQL.

12
ответ дан 2 December 2019 в 05:03
поделиться

Извините, что говорю это, но нет способа восстановить старые значения полей без резервной копии.

Не стреляйте в посланника...

3
ответ дан 2 December 2019 в 05:03
поделиться

С помощью Dollar вы можете выполнить это преобразование только в 1 строке кода:

long[] longs = new long[]{1L};
List<Long> longList = $(longs).toList();

вы также можете легко скомпоновать их:

Long[] arrayOfLongs = $(longs).toArray();
-121--1550604-

Одиночные типы и ETSR не решают проблему. Я сам искал в Scala как раз ту же самую особенность, но, видимо, в ней отсутствуют так называемые аннотации самотопления.

Существуют обстоятельства, при которых такие аннотации самовывозного типа могут оказаться весьма полезными. Рассмотрим пример (адаптированный из Circular type parameters question example ):

// we want a container that can store elements
trait Container[E <: Element[E]] {
  def elements: Seq[E]
  def add(elem: E): Unit
}

// we want elements be aware of their enclosing container
trait Element[E <: Element[E]] {
  def container: Container[E]
}

Допустим, вы положили это в библиотеку. Потребитель библиотеки должен сделать следующее:

object PersonContainer extends Container[Person] {
  // actual implementation is not important
  def elements = Nil
  def add(p: Person) = {}
}

class Person extends Element[Person] {             // {1}
  def container = PersonContainer
}

Все хорошо, и все работает так, как положено. Единственное, что беспокоит, это то, что потребитель библиотеки должен использовать параметр типа с самоограничением (# 1 в коде). Но это еще не все. Теперь предположим, что имеется какой-либо образец ActiveRecord, и требуется добавить метод save в Element , который просто делегирует контейнеру метод add . Удивительно, но это не так просто:

trait Element[E <: Element[E]] {
  def container: Container[E]
  def save() = container.add(this)   // won't compile
}

found   : Element[E]
required: E

Интуитивно у нас есть несколько вариантов:

  • сделать добавить метод принять элемент [E] вместо E ;
  • привести это к элементу [E] .

Ни одна из этих опций не является удовлетворительной, только из-за того, что E не совпадает с Element [E] (реализации не вынуждены использовать параметры типа с самоограничением). Единственным путем я вижу решения этой проблемы, должен иметь то понятие самотипа в Скале (давайте предположим, что у нас есть он на нашем любимом языке):

trait Container[E <: Element] {
  def elements: Seq[E]
  def add(elem: E): Unit
}

trait Element {  // the type parameter would be redundant ...
  def save() = container.add(this)  // ... and this would be possible, too, ...
  def container: Container[this]  // ... if only we could do this
}

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

P.S. Может ли кто-то рассмотреть возможность включения этого в список пожеланий Скалы? К сожалению, я не знаю, как трудно реализовать такую логику, поскольку могут быть проблемы с пресловутым стиранием JVM.

P.P.S. Или, может быть, есть еще один Scala-путь, о котором я не знаю?

-121--2672420-

Здесь можно извлечь два урока:

  1. Резервное копирование данных
  2. Выполнение инструкций UPDATE/DELETE в рамках транзакции, чтобы можно было использовать ROLLBACK , если все идет не так, как планировалось

.

Транзакции управляют инструкциями манипулирования данными для обеспечения их атомарности. Быть «atomic» означает, что транзакция либо происходит, либо не выполняется. Единственный способ сигнализировать о завершении транзакции в базу данных - это использование инструкции COMMIT или ROLLBACK (по ANSI-92, которая, к сожалению, не включает синтаксис для создания/начала транзакции, поэтому она зависит от поставщика). COMMIT применяет изменения (при наличии), внесенные в транзакцию. ROLLBACK игнорирует любые действия, происходящие в рамках транзакции - очень желательно, когда инструкция UPDATE/DELETE делает что-то непреднамеренное .

Обычно отдельные инструкции DML (Insert, Update, Delete) выполняются в транзакции автоматической фиксации - они фиксируются сразу после успешного завершения инструкции. Это означает, что нет возможности откатить базу данных к состоянию до выполнения инструкции в таких случаях, как ваша. Когда что-то идет не так, единственным доступным вариантом восстановления является восстановление данных из резервной копии (предусматривать она существует). В MySQL autocommit по умолчанию на для InnoDB - MyISAM не поддерживает транзакции. Она может быть отключена с помощью:

SET autocommit = 0

Явная транзакция - это когда инструкции переносятся в явно определенный блок кода транзакции - для MySQL, то есть START TRANSACTION . Для этого также требуется явно выполненная инструкция COMMIT или ROLLBACK в конце транзакции. Вложенные транзакции выходят за рамки этого раздела.

Неявные транзакции немного отличаются от явных. Неявные транзакции не требуют явного определения транзакции. Однако, как и явные транзакции, для них требуется указать инструкцию COMMIT или ROLLBACK .

Вывод

Явные транзакции являются наиболее идеальным решением - они требуют оператора COMMIT или ROLLBACK , чтобы завершить транзакцию, и то, что происходит, ясно указано для других, чтобы прочитать, если есть необходимость. Неявные транзакции являются нормальными, если работа с базой данных осуществляется в интерактивном режиме, но операторы COMMIT должны быть указаны только после проверки результатов и тщательного определения их действительности.

Это означает, что вы должны использовать:

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;

... и использовать только COMMIT; , когда результаты верны.

При этом операторы UPDATE и DELETE обычно возвращают только количество строк, а не конкретные сведения. Преобразуйте такие инструкции в инструкции SELECT и просмотрите результаты, чтобы убедиться в правильности перед попыткой выполнения инструкции UPDATE/DELETE.

Дополнения

Инструкции DDL (Data Definition Language) фиксируются автоматически - они не требуют оператора COMMIT. IE: таблица, индекс, хранимая процедура, база данных и операторы создания или изменения представлений.

15
ответ дан 2 December 2019 в 05:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: