史上最实用mysql参数之一-----sql_safe_updates

mysql数据库是可以开启安全模式,不过默认情况下,安全模式不开启的,下面就来说说什么是mysql的安全模式

不知道小伙伴们是否有过维护的数据库表业务数据被人或者因为程序bug导致全表更新,全表删除的痛苦经历,恢复业务数据真的是一个精细活,尤其与交易和钱相关的数据,必须恢复成和原来一模一样,那能不能在数据库层面架起最后一道安全堡垒,拒绝全表更新,全表删除的非法操作呢,答案是有的,在mysql中sql_safe_updates可以完美解决这个问题,下面就来给大家演示一下实际效果

sql_safe_updates默认是不开启的

mysql> show variables like 'sql_safe_updates';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| sql_safe_updates | OFF   |
+------------------+-------+
1 row in set (0.01 sec)

现在就开启这个参数,如果要永久生效,需要将参数添加到数据库配置文件(my.cnf)中

mysql> set global sql_safe_updates=1;
Query OK, 0 rows affected (0.00 sec)

需要重新连接一下数据库,才会生效

mysql> show variables like 'sql_safe_updates';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| sql_safe_updates | ON    |
+------------------+-------+
1 row in set (0.00 sec)

下面就开始用表进行测试

mysql> create table t_test10 (id char(10),name char(20), primary key(id));
Query OK, 0 rows affected (0.29 sec)

插入语句
insert into t_test10 values('1','test1');
insert into t_test10 values('2','test2');
insert into t_test10 values('3','test3');
insert into t_test10 values('4','test4');
insert into t_test10 values('5','test5');
insert into t_test10 values('6','test6');
insert into t_test10 values('7','test7');
insert into t_test10 values('8','test8');

mysql> select * from t_test10;
+----+-------+
| id | name  |
+----+-------+
| 1  | test1 |
| 2  | test2 |
| 3  | test3 |
| 4  | test4 |
| 5  | test5 |
| 6  | test6 |
| 7  | test7 |
| 8  | test8 |
+----+-------+
8 rows in set (0.00 sec)

测试一下全表删除

mysql> delete from t_test10;
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 t_test10 where 1=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> update t_test10 set name='test';
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> update t_test10 set name='test' where 1=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> update t_test10 set name='test' where name='test1';
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 t_test10 where name='test2';
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数据库安全策略拦截了呢,这是因为name列没有索引

mysql> show create table t_test10\G;
*************************** 1. row ***************************
       Table: t_test10
Create Table: CREATE TABLE `t_test10` (
  `id` char(10) NOT NULL,
  `name` char(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

ERROR: 
No query specified

在name列上加索引
mysql> alter table t_test10 add index idx_t_test10_name (name);
Query OK, 0 rows affected (0.44 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> show create table t_test10\G;
*************************** 1. row ***************************
       Table: t_test10
Create Table: CREATE TABLE `t_test10` (
  `id` char(10) NOT NULL,
  `name` char(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_t_test10_name` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

重新测试一下正常删除和更新语句

mysql> update t_test10 set name='test' where name='test1';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> delete from t_test10 where name='test2';
Query OK, 1 row affected (0.01 sec)

全部成功了,开启sql_safe_updates安全模式之后,要想正常删除或者更新,需要满足2个条件

  1. delete,update必须带条件,或者加limit进行过滤
  2. 所带条件必须走索引

喜欢的同学可以关注我的公众号(db_arch)(Mysql数据库运维与架构设计)

 

你可能感兴趣的:(mysql,架构设计,dba学习笔记)