有的时候,线上容易不小心UPDATE,DELETE的时候,无加限制条件,从而引起灾难,
但其实MYSQL有开关可以防止误操作,一定程度上减少发生机会。
可以设置:
sql_safe_updates
其中 :
当sql_safe_updates设置为1时,update:要有where,并查询条件必须使用为索引字段,或者使用limit,或者两个条件同时存在,才能正常执行。delete:where条件中带有索引字段可删除,where中查询条件不是索引,得必须有limit。主要是防止update和deLete没有使用索引导致变更及删除大量数据。参数默认值为0
更多参考来自:
http://www.itopers.com/blog/posts/database/mysql/sql_safe_updates.html
如下例子:
CREATE TABLE `sql_safe` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`balance` decimal(12,2) unsigned NOT NULL DEFAULT '0.00',
`uid` bigint(20) NOT NULL,
`nuid` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_uid` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8
mysql> select * from sql_safe;
+----+---------+-----+------+
| id | balance | uid | nuid |
+----+---------+-----+------+
| 1 | 0.10 | 123 | 123 |
| 2 | 212.00 | 124 | 124 |
| 3 | 1.01 | 150 | 150 |
| 4 | 2.00 | 129 | 129 |
| 5 | 23.10 | 130 | 130 |
| 6 | 236.00 | 126 | 126 |
| 7 | 26.01 | 127 | 127 |
| 8 | 31.00 | 131 | 131 |
+----+---------+-----+------+
8 rows in set (0.00 sec)
mysql> show variables like 'sql_safe_updates';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | ON |
+------------------+-------+
#语句A:
mysql> update sql_safe set balance = balance - 10;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
#语句B:
mysql> update sql_safe set balance = balance - 10 where nuid = 123;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
#语句C:
mysql> update sql_safe set balance = balance - 10 where uid = 123;
Query OK, 1 row affected, 1 warning (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 1
#语句D:
mysql> update sql_safe set balance = balance - 10 limit 1;
Query OK, 0 rows affected, 2 warnings (0.00 sec)
Rows matched: 1 Changed: 0 Warnings: 1
语句A和语句B一个是没有使用where,一个是没有用到索引,都提示执行失败,报ERROR 1175
语句C和语句D一个是where中使用了索引字段,一个是使用了limit,都是精确到了部分数据。
关于Warnings: 1这个,是out of range的原因,这个后续再说明下各个数值字段类型超范围的处理。
Delete会不一样些,条件更为严格:
#语句E:
mysql> delete from sql_safe ;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
#语句F:
mysql> delete from sql_safe where nuid = 123;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
#语句G:
mysql> delete from sql_safe where uid = 123;
Query OK, 1 row affected (0.00 sec)
#语句H:
mysql> delete from sql_safe where nuid = 124 limit 1;
Query OK, 1 row affected, 1 warning (0.00 sec)
#语句I:
mysql> delete from sql_safe limit 1;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
delete只有使用where条件带索引,或者where +limit可以正常执行,其它都会有问题。
所以说,启用这个参数,需要详细了解业务中的sql,是否都通过索引进行update/delete,如果没有,会出现sql执行报错。
另外,sql_safe_updates这个参数在各版本之间的功能都一样,唯一的区别是作用域不一样。
5.0,5.1都是session级别的,5.5,5.6是global&session级别。
正因为这个作用域的限制,在低版本中无法在线在数据库中直接开启这个功能,高版本中可在线开启,但也需要中断现有连接才能生效。
那么如果才能让这个sql_safe_updates这个功能生效?
1、低版本数据库只能程序端直接在创建session时,带上set sql_safe_updates = 1
2、高版本数据库可以set global sql_safe_updates = 1;然后让前端程序重新创建连接。也可在创建session时,set sql_safe_updates = 1;
mysql中保险开关防止UPDATE,DELETE误删除
猜你喜欢
转载自jackyrong.iteye.com/blog/2293631
今日推荐
周排行