本文来自 网易云社区 。

数据安全是业务的基石,但是DBA 总会遇到救火情况,业务误删除全表或者误更新错全表业务数据,导致服务不可用

sql_safe_updates参数可以限制不带where条件的update/delete语句执行失败,这个参数设置后,可以防止业务bug/漏洞导致把整个表都更新或者删除(线上发生过的案例),也可以防止DBA在线误操作更新/删除整张表。

官方解释:

If set to 1, MySQL aborts UPDATE or DELETE statements that do not use a key in the WHERE clause or a LIMIT clause. (Specifically, UPDATE statements must have a WHERE clause that uses a key or a LIMIT clause, or both. DELETE statements must have both.) This makes it possible to catch UPDATE or DELETE statements where keys are not used properly and that would probably change or delete a large number of rows. The default value is 0.

意思是说

当sql_safe_updates设置为1时,UPDATE :要有where,并查询条件必须使用为索引字段,或者使用limit,或者两个条件同时存在,才能正常执行。DELETE:where条件中带有索引字段可删除,where中查询条件不是索引,得必须有limit。主要是防止UPDATE和DELETE 没有使用索引导致变更及删除大量数据。系统参数默认值为0

为了防止线上业务出现以下3种情况影响线上服务的正常使用和不小心全表数据删除:

1:没有加where条件的全表更新操作

2:加了where 条件字段,但是where 字段 没有走索引的表更新

3:全表delete 没有加where 条件 或者where 条件没有 走索引

如果业务开发存在如上的操作,数据库会出现如下错误:

MySQL 报错如下:

 ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column

DDB 报错如下:

Caused by: java.sql.SQLException: You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:946)
at com.mysql.jdbc.MysqlIO.checkErrorPacket(MysqlIO.java:2985)
at com.mysql.jdbc.MysqlIO.sendCommand(MysqlIO.java:1631)

建议: DBA 开启此参数限制 ,可以避免线上业务数据误删除操作,但是需要先在测试库开启,这样可以可以先在测试库上补充短缺的表索引,测试验证没问题再部署到线上库 邮件部从去年开始已经在严选电商线上运行。

测试案例: 全局开启 sql_safe_updates 限制

[test]> show variables like 'sql_safe_updates';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| sql_safe_updates | ON |
+------------------+-------+
CREATE TABLE `test_sql_safe` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`uid` bigint(20) NOT NULL,
`status` int(1) DEFAULT '0',
`amount` int(11) NOT NULL DEFAULT '0',
`nuid` bigint(20) NOT NULL,
PRIMARY KEY (`id`),
KEY `idx_uid` (`uid`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8
 [test]> select * from test_sql_safe;
+----+------+--------+--------+--------+
| id | uid | status | amount | nuid |
+----+------+--------+--------+--------+
| 1 | 1111 | 1 | 500 | 22222 |
| 2 | 2111 | 0 | 600 | 332222 |
| 3 | 3111 | 1 | 700 | 442222 |
| 4 | 4111 | 0 | 500 | 552222 |
| 5 | 5111 | 1 | 600 | 662222 |
+----+------+--------+--------+--------+
 [test]> update test_sql_safe set amount = amount +100;
ERROR 1175 (HY000): You are using safe update mode and you tried to update a table without a WHERE that uses a KEY column
test]> update test_sql_safe set amount = amount +100 limit 2;
Query OK, 2 rows affected (0.00 sec)
Rows matched: 2 Changed: 2 Warnings: 0
[test]> select * from test_sql_safe ;
+----+------+--------+--------+--------+
| id | uid | status | amount | nuid |
+----+------+--------+--------+--------+
| 1 | 1111 | 1 | 600 | 22222 |
| 2 | 2111 | 0 | 700 | 332222 |
| 3 | 3111 | 1 | 700 | 442222 |
| 4 | 4111 | 0 | 500 | 552222 |
| 5 | 5111 | 1 | 600 | 662222 |
+----+------+--------+--------+--------+
[test]> update test_sql_safe set amount = amount +100 where uid = 2111;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
[test]> delete from test_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
delete from test_sql_safe where status = 0;
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 from test_sql_safe where uid =3111;
Query OK, 1 row affected (0.00 sec)
[test]> delete from test_sql_safe where amount = 500 limit 1;
Query OK, 1 row affected (0.00 sec)
[test]> delete from test_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

本文来自网易云社区,经作者吴志敏授权发布。

原文地址:MySQL不带where条件的UPDATE和DELETE 限制操作说明

更多网易研发、产品、运营经验分享请访问网易云社区

MySQL不带where条件的UPDATE和DELETE 限制操作说明的更多相关文章

  1. drupal7 带表达式条件的update

    原本的mysql语句是这样的: ; 转化成drupal的api是这样的 $total_amount=1; $rows= db_update('my_payment_card') ->expres ...

  2. MySQL 误操作后数据恢复(update,delete忘加where条件)

    在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者D ...

  3. MySQL 误操作后数据恢复(update,delete忘加where条件)【转】

    在数据库日常维护中,开发人员是最让人头痛的,很多时候都会由于SQL语句 写的有问题导致服务器出问题,导致资源耗尽.最危险的操作就是在做DML操作的时候忘加where条件,导致全表更新,这是作为运维或者 ...

  4. MYSQL安全模式"sql_safe_updates"设置update和delete不带where的操作限制

    前言 在数据库操作中,如果在update和delete没有加上where条件,数据将会全部修改. 不只是初识mysql的开发者会遇到这个问题,工作有一定经验的开发者有时难免也会忘记写入where条件. ...

  5. Error Code: 1175 Mysql中更新或删除时报错(未带关键字条件)

    SET SQL_SAFE_UPDATES = 0; SQL_SAFE_UPDATES = {0 | 1} 如果设置为0,则MySQL会放弃在WHERE子句或LIMIT子句中不使用关键字的UPDATE或 ...

  6. MySQL数据库INSERT、UPDATE、DELETE以及REPLACE语句的用法详解

    本篇文章是对MySQL数据库INSERT.UPDATE.DELETE以及REPLACE语句的用法进行了详细的分析介绍,需要的朋友参考下   MySQL数据库insert和update语句引:用于操作数 ...

  7. MySQL存储过程带in和out参数

    MySQL存储过程带in和out参数 最简单的例子: [html] mysql> DELIMITER $$ mysql> USE test $$ Database changed mysq ...

  8. MySQL、You are using safe update mode

    MySQL默认模式是sql_safe_updates=1的.在这个模式下不管你是update还是delete一行where 条件都要指定主键.如果where条件只出现的不是主键就会出错. 例子: se ...

  9. 转载:MySQL数据库INSERT、UPDATE、DELETE以及REPLACE语句的用法详解

    转自:http://www.jb51.net/article/39199.htm 本篇文章是对MySQL数据库INSERT.UPDATE.DELETE以及REPLACE语句的用法进行了详细的分析介绍, ...

随机推荐

  1. 用letsencrypt搭建免费的https网站--nginx篇

    环境:阿里云服务器centos7.3,nignx,letsencrypt做免费的https证书 Let’s Encrypt官网:https://letsencrypt.org/ 1.服务器开放端口:4 ...

  2. ui-router 留存

    学习 ui-router - 路由控制 022014年01月 参考原文:https://github.com/angular-ui/ui-router/wiki/URL-Routing 在你的应用中大 ...

  3. freeswitch由于ext-sip-ip地址填写错误导致32秒拆线问题

    通话32秒左右就断掉 检查 profile 的 ext-sip-ip 设置ext-rtp-ip和ext-sip-ip 可以直接设置为外网IP 自建stun-server, 更新后, 过了好几个小时出现 ...

  4. OpenGL位图函数

    [OpenGL位图函数] 1.OpenGL中glBitmap用于绘制一个二值阵列. When drawn, the bitmap is positioned relative to the curre ...

  5. Uniform & Attribute & Varying

    [Uniform & Attribute & Varying] 顶点着色器的输入变量用关键字“attribute”来限定. 片段着色器的输入变量(它和顶点着色器的输出变量相对应)用关键 ...

  6. spring4-2-bean配置-2-属性注入细节

    配置 bean,本章节中主要介绍蓝色文字部分. 配置形式:基于 XML 文件的方式:基于注解的方式 Bean 的配置方式:通过全类名(反射).通过工厂方法(静态工厂方法 & 实例工厂方法).F ...

  7. sql查询exist替换in

    很多时候用 exists 代替 in 是一个好的选择: select num from a where num in(select num from b) 用下面的语句替换: select num f ...

  8. 前端学习--HTML标签温习一

    1.<a>标签 在所有浏览器中,链接的默认外观如下: 1)未被访问的链接带有下划线而且是蓝色的 2)已被访问的链接带有下划线而且是紫色的 3)活动链接带有下划线而且是红色的 提示:如果没有 ...

  9. js实现水平伸缩菜单

    window.onload=function(){ var aA=document.getElementsByTagName('a'); for(var i=0; i<aA.length; i+ ...

  10. smarty类与对象的赋值与使用

    <?phprequire_once('../smarty/Smarty.class.php'); //配置信息$smarty=new Smarty(); $smarty->left_del ...