刚知道sql_safe_updates? 但又不能用 难过。

6 篇文章 0 订阅

事情原由:

先大致说下事情的缘由,前几天有开发找到我(运维),说测试数据库里面的某张表被更新为同样的值了。什么?

我一会,一身冷汗,感觉看了下线上,还好没事。当即觉得不能再上线任何代码。

技术栈背景:某云RDS, php,larave

年初(2020春节后,疫情期间)就在测试环境出现过一次,一条SQL没加where条件把所有的字段都更新了。

而且是用户的余额字段。后来找到源头改掉了,还好没上线。

又出现这样的情况,第一时间找源头。仔细搜索代码和新上到测试线的功能,找到了。

一个没加where条件的更新的语句执行更新了。(而且已经在测试环境放了3天了)

 

天呀,测试的同学只看自己操作的单条数据没问题,并没有发现都更新了。又一次差点技术部被干掉。

寻找规避方法

1、通过jenkins拉取代码后,对代码用sonarqube进行扫描

2、通过jenkins拉取代码后,自己写Python脚本扫描(看看某行代码有update,但没有where的就报错)网上找的前半段代码,自己加了后半段。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import sys
#递归遍历目录
def getAlldirInDiGui( path):
    filesList=os.listdir(path)
    #print(filesList)
    for fileName in filesList:
        fileAbpath=os.path.join(path,fileName)
        if os.path.isdir(fileAbpath):
           # print("目录:" ,fileName)
            getAlldirInDiGui(fileAbpath)
        else:
        	if (fileAbpath.find('.php')>1):
                    checkFileContents(fileAbpath)

#传递参数的时候,注意需要写上(r)表明传递的是路径
#getAlldirInDiGui(r"D:\test")

def checkFileContents(fileName):
	fo = open(fileName, "r")
	#print ("文件名为: ", fo.name)
	flag = 'false'
	for line in fo.readlines():                          #依次读取每行
	    line = line.strip()                             #去掉每行头尾空白
	    line = line.lower()
	    if line.find('update(') > 0:
	    	flag = 'true'
	    	if line.find('where') < 1 :
	    		print(fileName+'   error')
		    	sys.exit(1)

	# 关闭文件
	fo.close()
getAlldirInDiGui(r"/work/")

3、限定条数

经过实践后

方法1,折腾起来动静有些大,没具体深入研究【继续研究中】,想着搞通后不一定能符合自己的需求。

方法2,自己写的脚本兼容性太差,有的方法名里面就有update。或者where没在同一行。

方法3,业务场景太复杂,不可行。

发现新大陆

于是搜索到了mysql 的  sql_safe_updates,原来mysql人家料到了会有程序员犯错误。

MySQL参数sql_safe_updates

设置之后,会限制update delete 中不带 where 条件的SQL 执行,update 时,在没有 where 条件或者where 后不是索引字段时,必须使用 limit ;在有 where 条件时,为索引字段

太棒了,这不就是梦寐以求的功能吗?简单粗暴。

然后改mysql的里面的计划任务(event),把没有用到索引的更新sql改掉。

然后改数据库设置。

mysql> set GLOBAL sql_safe_updates = 1;

ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation

卡,root账号,告诉我没权限。。。。

于是 提交工单,

 

对方答复了:

原来我一直用的是假的root呀。

崩溃中。。。。。。

在破灭的希望找到一些光明,

虽然不能全局修改,但可以在larave每次启动的时候设置会话级别的

DB::select('set sql_safe_updates = 1');

虽然几十个项目都需要改,但至少能防止数据的误操作。

防止无脑update和delete的方法

1、对开发人员进行警钟长鸣

2、测试用例的健全

3、有更新和删除操作时,主管或者结对进行代码review

说下你们是怎么防止无脑update和delete的

如果你感觉本文对你有帮助,请转发,说不定你的朋友也需要它。

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值