Redian新闻
>
同事删库跑路后,我连表名都不能修改了?

同事删库跑路后,我连表名都不能修改了?

公众号新闻

点击上方“芋道源码”,选择“设为星标

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 10:33 更新文章,每天掉亿点点头发...

源码精品专栏

 
来源:码农参上

事情是这样的,前几天隔壁部门的哥们在生产环境的数据库上,执行了一下drop命令,好嘛,活生生的删库跑路的例子居然真的在我身边发生了,好在运维同学给力,后来恢复了数据。事后听说这哥们虽然没被开除,但也吃了个公司的警告。

再然后,运维那边回收了所有环境下数据库的drop命令的权限,甚至包括了开发环境,本来觉得对我们也没啥影响,一般我们也没有啥需要删表的需求。但是隔了没几天,我在重命名一个表的时候,突然弹出了这样一个报错:

仔细看了一眼报错:

1142 - DROP command denied to user 'hydra'@'localhost' for table 't_orders'

什么情况,重命名表和drop命令还有什么关系?本着怀疑的态度,就想探究一下没有drop权限后,对我们的日常数据库操作都有什么影响,于是就有了后面一系列在本地进行的测试。

首先需要一个没有drop权限的 mysql 用户,我们先在本地环境使用 root 用户登录 mysql,取消用户 hydra 的drop权限。和grant授权命令相对应的,可以使用revoke命令取消对用户的授权:

revoke drop on *.* from hydra@'localhost';

好了,准备工作做完了,It's show time~

修改表名

前面直接使用 navicat 来修改表名失败,那我们再用 sql 命令来尝试一下:

上面测试了两种重命名表的命令,无论是ALTER还是RENAME都不能正常使用,看来drop的权限确实会对修改表名造成影响。至于重命名失败的原因,看一下官方文档(链接:https://dev.mysql.com/doc/refman/5.7/en)的说明:

RENAME TABLE renames one or more tables. You must have ALTER and DROP privileges for the original table, and CREATE and INSERT privileges for the new table.

简单来说就是在重命名表时,必须有原始表的ALTERDROP权限,以及新表的CREATEINSERT权限。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

truncate

当我需要清空一张表、顺带把AUTO_INCREMENT的主键置为初始值时,突然发现truncate命令也无法执行了:

有了上面的经验,还是看一下官方文档(链接:https://dev.mysql.com/doc/refman/5.7/en)的说明:

Although TRUNCATE TABLE is similar to DELETE, it is classified as a DDL statement rather than a DML statement. It differs from DELETE in the following ways:

Truncate operations drop and re-create the table, which is much faster than deleting rows one by one, particularly for large tables.

文档给出的解释是,尽管truncatedelete的功能很像,但是truncate被归类为 DDL 语言,而delete则是 DML 语言。相对于delete一行行删除数据,truncate删除 表后重新新建表 ,这一操作相对delete会快很多,尤其是对大表而言。

从分类也可以看出两者之间的不同,DML(data manipulation language)作为数据操作语言,主要是针对数据进行一些操作,例如常用的增删改查。而DDL(data definition language)则是数据定义语言,主要应用于定义或改变表的结构等操作,并且这一操作过程是隐性提交的,不能回滚。

truncate无法使用的情况下,来执行一下delete试试:

虽然说不带where条件的delete删除语句很不推荐使用,但是在功能上还是可以执行成功的。那么再看看另一个问题,表中的自增id重置了吗?

我们知道,如果执行了truncate的话,那么自增列id的值会被重置为 1。下面看看delete执行后的情况,插入一条数据并查询:

通过上面的结果,可以看到使用delete清表后,自增列的值还是在原先的基础上进行自增。如果需要重置这个值的话,需要我们手动在表上执行alter命令修改:

alter table t_orders auto_increment= 1;

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

drop 作用范围

那么,是否存在即使在没有权限的情况下,也可以执行成功的drop指令?我们对不同对象分别进行测试,首先尝试对数据库、表、视图的drop操作:

drop DATABASE mall;
> 1044 - Access denied for user 'hydra'@'localhost' to database 'mall'
> 时间: 0.005s

drop TABLE t_orders;
> 1142 - DROP command denied to user 'hydra'@'localhost' for table 't_orders'
> 时间: 0s

drop VIEW order_view;
> 1142 - DROP command denied to user 'hydra'@'localhost' for table 'order_view'
> 时间: 0.001s

上面这些命令理所当然没有执行成功,但是在尝试到使用drop删除存储过程时,意料之外的结果出现了。在没有drop权限的情况下,对存储过程的drop操作,居然可以执行成功:

翻到官方文档(链接:https://dev.mysql.com/doc/refman/5.7/en)中授权这一章节,看一下这张图就明白了:

上面的表进行了解释,drop命令的作用范围仅仅是数据库、表以及视图,而存储过程的权限被单独放在alter routine中了,因此即使没有drop权限,我们仍可以用drop命令来删除存储过程。

delete 后如何恢复数据

通过前面的实验可以看到,虽然在回收drop权限后不能使用truncate清空数据表了,但我们仍然可以使用delete语句达到相同的效果,那么为什么delete就不害怕删库的风险呢?

前面我们提到过,delete语句属于 DML 语言,其实在实际的删除过程中是一行行地进行删除的,并且会将每行数据的删除日志记录在日志中,下面我们就看看如何利用binlog来恢复删除的数据。

首先要求数据库开启binlog,使用下面的语句来查询是否开启:

show variables like '%log_bin%';

在值为ON的情况下,表示开启了binglog

确保开启了binlog后,我们使用delete来删除表中的全部数据:

delete from t_orders;

在恢复删除的数据前,需要先找到存放数据文件的目录:

在该目录下,存在若干名称为mysql-bin.**** *的文件,我们需要根据删除操作发生的时间找到临近的binglog文件:

找到目标binlog文件后,这里先将它拷贝到D:\tmp目录下,然后到 mysql 安装目录的bin目录下,执行下面的指令:

mysqlbinlog --base64-output=decode-rows -v 
  --database=mall 
  --start-datetime="2021-09-17 20:50:00" 
  --stop-datetime="2021-09-17 21:30:00" 
  D:\tmp\mysql-bin.000001 > mysqllog.sql

对参数进行一下说明:

  • base64-output=decode-rows:基于行事件解析成 sql 语句,并将数据转换正常的字符。
  • database:数据库名。
  • start-datetime:从 binlog 中第一个等于或晚于该时间戳的事件开始读取,也就是恢复数据的起始时间。
  • stop-datetime:与上面对应的,是恢复数据的结束时间。
  • D:\tmp\mysql-bin.000001:恢复数据的日志文件。
  • mysqllog.sql:恢复数据的输出文件。

执行完成后,在bin目录下会生成一个mysqllog.sql的文件,打开文件看一下,可以找到删除时执行的delete语句:

从语句中可以拿到delete命令执行时每一行数据的值,这样就可以进行数据的恢复了。如果需要恢复的数据量非常大的话,建议使用脚本批量将delete语句转换为insert语句,减轻恢复数据的工作量。

所以,答应我,以后删库前,先看一下有没有开启 binlog 好吗?



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢

已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 101 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)

微信扫码关注该文公众号作者

戳这里提交新闻线索和高质量文章给我们。
相关阅读
租客跑路后,澳房东收房时崩溃:到处是蛆、大便和卫生巾,清洁费达$3万美国致命空难无人生还! 飞机疯狂砸向高速公路后烧成灰烬黑客靠 ChatGPT 赚钱:每 100 次收费 37 元,还能修改恶意软件代码运动的初衷利用法律或者政策的犄角空间以达到利益最大化不是错,有时候需要学会这个本领。看完老年群里疯传的战争视频,我连骚舞都不想刷了第二次徒步圣路,750公里葡萄牙之路+英国之路:D07~圣塔伦城不只TikTok,美国app下载量前四名都来自中国黑客靠ChatGPT赚钱:每100次收费37元,还能修改恶意软件代码大学申请和录取,应不应该有契约精神?NO全球最适合Z世代居住城市,全美前两名都在德州霸屏!今年公募前三名都被他包揽?"准冠军"基金经理黄海:投资是一场精心策划的战役!重仓煤炭原因是...自从有了这款意大利面,我连外卖都不点了新一届全国人大代表名单公布【经济】法国人最欢迎的品牌有哪些?前三名都是榜单常客一颗曾卖出了38000的化州橘红,老外点名都要喝它!“我弱我不敢下山”老祖气急“你还弱?我连你看门的狗.都打不过”叶秋黑脸:“那是赤血遗种,我也打不过”AI老婆惨遭安乐死!技术宅小哥调教「ChatGPT酱」,惹三次元女友暴走,含泪删库纽约新张日本零食铺!500+爆款东京直邮!哆啦A梦/米菲联名都有!数百程序员专门教AI写代码、40个bug能修复31个,“取代程序员”这次要成真了?突发|美国华人遭劫频发!同一犯罪模式,名表名包被抢,嫌犯多为华裔全球最佳医院排行榜,前4名都是美国医院!刷机时代落幕!开源ROM魔趣 (Mokee) 创始人决定“删库跑路”在纽约这座国际大都会,我连马路都不会过了清华应届硕士炮轰字节:恶意低薪,硕士白读还倒贴;马云不再实际控制蚂蚁;开源 ROM 魔趣创始人宣布删库跑路|Q资讯【探索】暗香、寒英、冷蕊……古诗词中梅的别名都有哪些?中华人民共和国第十四届全国人民代表大会代表名单AI老婆惨遭安乐死!技术宅小哥调教ChatGPT酱,惹怒三次元女友,含泪删库看了《狂飙》,我连夜在京东买了这本神书在美国314.华尔街、世贸中心、圣诞街景好名字重要!2022年加拿大最受欢迎名出炉!前十名都很赞!最历害的是这个...全球最佳医院排行榜 | 前4名都是美国医院!西雅图这家医院排名最高!第十四届全国人民代表大会代表名单(2977名)2/27 波士顿新闻总汇|议长费连表示波士顿迫切需要更多警察 ​吴市长宣布设立“波士顿乌克兰日” 本田部分车型安全气囊有重大风险广州宝马撞人致5死13伤,走投无路后疯狂撒钱,没人有资格替遇难者说原谅.....
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。