我在表格中做了一个错误的更新查询。
我忘了在WHERE
子句中创建一个id字段。
这样就更新了我的所有行。
如何恢复?
我没有备份......
答案 0 :(得分:14)
这里有两个教训:
ROLLBACK
了解数据库的事务(自动提交,显式和隐式)处理可以使您不必从备份中恢复数据。
事务控制数据操作语句以确保它们是原子的。 “原子”意味着交易要么发生,要么不发生。向数据库发出事务完成信号的唯一方法是使用COMMIT
或ROLLBACK
语句(根据ANSI-92,遗憾的是不包括创建/开始事务的语法,因此它是特定供应商)。 COMMIT
应用在事务中进行的更改(如果有)。 ROLLBACK
忽略了事务中发生的任何操作 - 当UPDATE / DELETE语句出现意外情况时非常需要。
通常,单个DML(插入,更新,删除)语句在自动提交事务中执行 - 它们在语句成功完成后立即提交。这意味着在像您这样的情况下运行语句之前,没有机会将数据库回滚到状态。当出现问题时,唯一可用的恢复选项是从备份重建数据(提供一个存在)。在MySQL中,autocommit is on by default for InnoDB - MyISAM不支持事务。可以使用以下方法禁用它:
SET autocommit = 0
显式事务是指语句被包装在显式定义的事务代码块中 - for MySQL, that's START TRANSACTION
。它还需要在事务结束时显式创建COMMIT
或ROLLBACK
语句。嵌套事务超出了本主题的范围。
隐式交易与显式交易略有不同。隐式事务不需要明确定义事务。但是,与显式事务一样,它们需要提供COMMIT
或ROLLBACK
语句。
显式交易是最理想的解决方案 - 它们需要一个声明COMMIT
或ROLLBACK
来完成交易,如果有需要,其他人可以清楚地说明正在发生的事情。如果以交互方式使用数据库,则隐式事务是正常的,但只有在测试结果后才能指定COMMIT
语句。彻底坚决有效。
这意味着你应该使用:
SET autocommit = 0;
START TRANSACTION;
UPDATE ...;
...只有在结果正确时才使用COMMIT;
。
也就是说,UPDATE和DELETE语句通常只返回受影响的行数,而不是特定的详细信息。将这些语句转换为SELECT语句&检查结果以确保 之前 正确尝试UPDATE / DELETE语句。
DDL(数据定义语言)语句是自动提交的 - 它们不需要COMMIT语句。 IE:表,索引,存储过程,数据库和视图创建或更改语句。
答案 1 :(得分:11)
很抱歉,但恢复被覆盖的MySQL数据库的可能性通常接近于零。与删除文件不同,在大多数情况下,覆盖记录实际上会物理覆盖现有数据。
要做好准备,如果有任何问题出现在这里,你应该停止你的MySQL服务器,并制作包含数据库的物理目录的副本,这样就不会有任何进一步的覆盖:将数据文件夹的简单复制+粘贴到另一个位置应该做。
但是不要抱有希望 - 我认为没有什么可以做到的。
您可能希望为将来设置频繁的数据库备份。有很多解决方案;最简单,最可靠和最容易自动化的一个(在Linux中使用at
或cron
,或在Windows中使用任务调度程序)是MySQL自己的mysqldump。
答案 2 :(得分:3)
很抱歉这么说,但没有备份就无法恢复旧的字段值。
不要射击信使......
答案 3 :(得分:0)
您是否启用了binlog?您可以通过访问binlog来恢复。