今天,一位哥们打电话来问我说误操作了他们公司数据库中的数据,如何恢复。他原本的想法是登录数据库update一个记录,结果忘了加where条件,于是悲剧发生了。今天,我们不讲如何恢复误操作的数据(后面专门讲如何恢复误删除的数据),我们讲讲如何从源头上避免这样的问题,这才是避免类似问题的根本措施。?

在mysql命令加上选项-U后,当发出没有WHERE或LIMIT关键字的UPDATE或DELETE时,MySQL程序就会拒绝执行。那么,我们基于MySQL提供的这项设置,就可以轻松实现如何最大程度防止人为误操作MySQL数据库了。什么?你不信?不信我们就从MySQL的帮助说明说起,一起来看看如何基于MySQL的-u选项实现如何最大程度防止人为误操作MySQL数据库。

MySQL帮助说明

  1. [root@binghe~]# mysql --help|grep dummy
  2. -U, --i-am-a-dummy Synonym for option --safe-updates, -U.
  3. i-am-a-dummy FALSE

在mysql命令加上选项-U后,当发出没有WHERE或LIMIT关键字的UPDATE或DELETE时,MySQL程序就会拒绝执行。

指定-U登录测试

[root@binghe~]# mysql -uroot -proot -S /data/3306/mysql.sock -U
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 14
Server version: 5.7.24-log MySQL Community Server (GPL)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> delete from oldboy.student;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
mysql> quit
Bye

提示:不加条件无法删除,目的达到。

指定别名

我们可以将操作MySQL的命令做成别名,防止他人和DBA误操作数据库,将操作MySQL的命令做成别名也非常简单,这里,我们直接上示例了,如下所示。

[root@binghe~]# alias mysql='mysql -U'
[root@binghe~]# mysql -uroot -poldboy123 -S /data/3306/mysql.sock
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 5.7.24-log MySQL Community Server (GPL)
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> delete from oldboy.student;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
mysql> delete from oldboy.student where Sno=5;
Query OK, 1 row affected (0.02 sec)
mysql> quit
Bye

在命令行会话设置alias mysql=’mysql -U’之后,只能在当前会话有效,关闭当前连接服务器的命令行之后,会话失效,则别名设置也会随之失效。如果想关闭连接服务器的会话终端,别名设置仍然有效,或者多个会话都能够使用这个别名来操作数据库,则我们可以将设置别名的命令添加到/etc/profile系统环境变量中,如下所示。

[root@binghe~]# echo "alias mysql='mysql -U'" >>/etc/profile
[root@binghe~]# . /etc/profile
[root@binghe~]# tail -1 /etc/profile
alias mysql='mysql -U'

这样,当我们退出当前连接服务器的会话终端,MySQL的别名设置依然有效,每次连接服务器时,不必在当前会话中重新设置MySQL的命令别名,直接使用即可。

总结

在mysql命令加上选项-U后,当发出没有WHERE或LIMIT关键字的UPDATE或DELETE时,MySQL程序拒绝执行。

问题:

在执行 update prd_property set isdel = 1 where prdid = 211 时,报如下错误: Error Code: 1175. You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column To disable safe mode, toggle the option in Preferences -> SQL Editor and reconnect.

原因:

是因为 Mysql 有个叫 SQL_SAFE_UPDATES 的变量,为了数据库更新操作的安全性,此值默认为 1。

当 SQL_SAFE_UPDATES = 1 时,
update 语句必须满足如下条件之一才能执行成功
1) 使用 where子句,并且 where 子句中列必须为 prefix 索引列
2) 使用 limit
3) 同时使用 where子句和 limit (此时 where 子句中列可以不是索引列)

delete 语句必须满足如下条件之一才能执行成功
1) 使用 where 子句,并且 where 子句中列必须为 prefix 索引列
2) 同时使用 where 子句和 limit (此时 where 子句中列可以不是索引列)

当 SQL_SAFE_UPDATES =0 时,update 和 delete 操作将会顺利执行。

解决:

所以可以先设置SQL_SAFE_UPDATES的值为0,然后再执行更新,例如:
set sql_safe_updates=0;
update prd_property set isdel = 1 where prdid = 211;执行成功

为了数据库安全,还是将set sql_safe_updates设回了1,多取一次,用主键更新。