本文来自 网易云社区 。

数据安全是业务的基石,但是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. javascript常见方法汇总之一——数组字符串相关

    (转载至慕课网) 原文链接:https://www.imooc.com/article/46933 github地址:https://github.com/dorseysen/notes-about- ...

  2. Linux OOM 自动杀死进程

    问题描述: 今天上班后,登录一台内网测试服务器,发现部分进程失踪 (Nginx/PHP-FPM/MySQL/Crond). 解决方法: 1.首先启动这些进程,保证正常提供服务. 2.查看服务器日志信息 ...

  3. Zabbix Proxy 分布式监控

    简介: Zabbix 是一个分布式监控系统,它可以以一个中心点.多个分节点的模式运行,使用 proxy 能降低 Zabbix Server 的压力,当然也带来了成本~ 适用范围:跨机房.跨地域的网络监 ...

  4. python打开浏览器的三种方法

    1.startfile方法 import os os.startfile("C:\Program Files (x86)\Google\Chrome\Application\chrome.e ...

  5. postman的使用方法详解

    Collections:在Postman中,Collection类似文件夹,可以把同一个项目的请求放在一个Collection里方便管理和分享,Collection里面也可以再建文件夹.如果做API文 ...

  6. mysql存储过程(procedure)

    #创建带参数的存储过程 delimiter // ),out p int) begin ; end // delimiter call pro_stu_name_pass(@n,@p); select ...

  7. ADB Not Responding - Android Studio

    问题描述: 最近安装了Android Studio v1.0,运行的时候老是这个错误 解决方案: 网上有人说是已经有adb的进程在运行,可是打开任务管理器,找不到对应的adb 进程. 无奈之下,想到a ...

  8. kubenetes dns

    E0228 07:32:28.912833       1 reflector.go:201] k8s.io/dns/pkg/dns/dns.go:147: Failed to list *v1.En ...

  9. zoj1037-Gridland

    http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=37 Gridland Time Limit: 2 Seconds      Me ...

  10. Qt Signal and Slot

    Qt4中的信号槽 Qt4中的信号槽是通过SIGNAL,SLOT两个宏,将参数转换成字符串.Qt编译前,会从源码的头文件中提取由signal和slot声明的信号和槽的函数, 将其组成一张信号和槽对应的字 ...