来源:自学PHP网 时间:2020-09-14 15:44 作者:小飞侠 阅读:次
[导读] Mysql误删数据解决方案及kill语句原理...
mysql误删数据
对于误删行
对于误删库/表 需要使用全量备份,加增量日志的方式。要求线上有定期的全量备份吗,并且实时备份binlog。 假如有人中午12点误删了一个库,恢复数据的流程如下: 取最近一次全量备份,假设这个库是一天一备,上次备份是当天0点; 用备份恢复出一个临时库; 从日志备份里面,取出凌晨0点之后的日志 把这些日志,除了误删除数据的语句外,全部应用到临时库。 注意: 为了加速数据恢复,如果这个临时库上有多个数据库,你可以在使用mysqlbinlog命令时,加上一个Cdatabase参数,用来指定误删表所在的库。这样,就避免了在恢复数据时还要应用其他库日志的情况。 在应用日志的时候,需要跳过12点误操作的那个语句的binlog: 加速恢复的方法:备份恢复出临时实例之后,将这个临时实例设置成线上备库的从库, 一个系统不可能备份无限的日志,你还需要根据成本和磁盘空间资源,设定一个日志保留 虽然“发生这种事,大家都不想的”,但是万一出现了误删事件,能够快速恢复数据,将损失 延迟复制备库
对于rm删除数据 只要不是恶意地把整个集群删除,而只是删掉了其中某一个节点的数据的话,HA系统就会开始工作,选出一个新的主库,从而保证整个集群的正常工作。这时,你要做的就是在这个节点上把数据恢复回来,再接入整个集群。 当然了,现在不止是DBA有自动化系统,SA(系统管理员)也有自动化系统,所以也许一个批量下线机器的操作,会让你整个MySQL集群的所有节点都全军覆没。应对这种情况,我的建议只能是说尽量把你的备份跨机房,或者最好是跨城市保存。Kill sql语句 session B是直接终止掉线程,什么都不管就直接退出吗?显然,这是不行的。 当对一个表做增删改查操作时,会在表上加MDL读锁。所以,session B虽然处于blocked状态,但还是拿着一个MDL读锁的。如果线程被kill的时候,就直接终止,那之后这个MDL读锁就没机会被释放了。 kill并不是马上停止的意思,而是告诉执行线程说,这条语句已经不需要继续执行了,可以开始“执行停止的逻辑了”。 实际上,当执行kill query thread_id_b,mysql里处理kill命令的线程做了以下事情:
因为像图1的我们例子里面,session B处于锁等待状态,如果只是把session B的线程状态设置 以上包含了三层意思:
一个kill不掉的例子 执行set global innodb_thread_concurrency=2,将InnoDB的并发线程上限数设置为2;然后,执行下面的序列: 可以看到: sesssion C执行的时候被堵住了; 但是session D执行的kill query C命令却没什么效果, 直到session E执行了kill connection命令,才断开了session C的连接,提示“Lost connection to MySQL server during query”, 但是这时候,如果在session E中执行show processlist,你就能看到下面这个图: id=12这个线程的Commnad列显示的是Killed。也就是说,客户端虽然断开了连接,但实际上服务端上这条语句还在执行过程中。 在这个例子里,12号线程的等待逻辑是这样的:每10毫秒判断一下是否可以进入InnoDB执 也就是说,虽然12号线程的状态已经被设置成了KILL_QUERY,但是在这个等待进入InnoDB的循环过程中,并没有去判断线程的状态,因此根本不会进入终止逻辑阶段。 而当session E执行kill connection 命令时,是这么做的,
那为什么执行show processlist的时候,会看到Command列显示为killed呢?其实,这就是因为在执行show processlist的时候,有一个特别的逻辑: 如果一个线程的状态是KILL_CONNECTION,就把Command列显示成Killed。 所以其实,即使是客户端退出了,这个线程的状态仍然是在等待中。只有等到满足进入InnoDB的条件后,session C的查询语句继续执行,然后才有可能判断到线程状态已经变成了KILL_QUERY或者KILL_CONNECTION,再进入终止逻辑阶段。 kill无效的第一类情况,即:线程没有执行到判断线程状态的逻辑。可能也会由于IO压力过大,读写IO的函数一直无法返回,导致不能及时判断线程的状态。
ctrl+C,mysql实际上也是启动了一个连接进程发送了kill query命令。 关于客户端连接慢的误解 如果库里面的表很多,连接就会很慢。比如有一个库有上万个表,使用默认参数连接的时候,mysql会提供一个本地库名和表名补全的功能:
第三步是耗时比较长的操作,也就是我们感知到慢不是连接满,也不是服务端慢,而是客户端慢。如果在这个连接中加上 -A,就可以取消自动补全功能,很快返回。 自动补全的效果就是,在输入库名或者表名的时候,将输入前缀,可以使用tab自动补全或者显示提示。实际如果自动补全用的不多,可以每次使用都加-A。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持自学php网。 |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com