网上也经常看到一些段子,某公司程序员对工作不满,删库跑路,老板损失惨重,欲哭无泪。这不最近又爆出一例,京东到家程序员离职当天删库跑路! 那么有没有什么解决方案? 即使数据库真的被删了,也有备份数据,能快速恢复。甚至可以做到实时热备,即使内部炸掉外部用户也感知不到,一片风平浪静。 MySQL作为当下流行数据库,在数据备份、高可用方面非常有竞争力,今天,我们就重点来讲下 什么是MySQL主备 情况一:客户端的业务操作,读、写访问的是主库主库通过某种机制,将数据实时同步给备库主库由于有些原因,无法正常响应客户端的请求 情况二:完成主备切换客户端读写,访问的是备库(此时备库升级为新主库) 那么,这里面最核心的数据同步是如何实现的? 主从同步原理 1、在备库执行changemaster命令,绑定主库的信息mysqlCHANGEMASTERTOMASTERHOST192。168。1。1,MASTERUSERrepl,MASTERPASSWORDreplpassword,MASTERPORT3306,MASTERAUTOPOSITION1,MASTERRETRYCOUNT0,MASTERHEARTBEATPERIOD10000;MASTERHOST:master主机名(或IP地址)MASTERPORT:mysql实例端口号MASTERUSER:用户名MASTERPASSWORD:密码MASTERAUTOPOSITION:如果进行changemasterto时使用MASTERAUTOPOSITION1,slave连接master将使用基于GTID的复制协议MASTERRETRYCOUNT:重连次数MASTERHEARTBEATPERIOD:复制心跳的周期 https:www。docs4dev。comdocszhmysql5。7referencechangemasterto。html 2、备库执行startslave命令,备库启动两个线程:IOthread和SQLthread 3、master主库,有数据更新,将此次更新的事件类型写入到主库的binlog文件中 4、主库会创建logdump线程,通知slave有数据更新 5、slave,向master节点的logdump线程请求一份指定binlog文件位置的副本,并将请求回来的binlog存到本地的Relaylog中继日志中 6、slave再开启一个SQL线程读取Relaylog日志,解析出日志里的命令,并执行,从而保证主备库数据同步 binlog有哪几种格式 现在,让我们近距离看下binlog日志。 binlog格式有三种:row、statement、mixed 接下来,我们开始一个实验: 先创建一个表CREATETABLEperson(idbigint(20)unsignedNOTNULLAUTOINCREMENTCOMMENT自增主键,incomebigint(20)NOTNULLCOMMENT收入,expendbigint(20)NOTNULLCOMMENT支出,PRIMARYKEY(id),KEYidxincome(income))ENGINEInnoDBAUTOINCREMENT1DEFAULTCHARSETutf8COMMENT个人收支表; 插入4条记录:insertintopersonvalues(50,500,500);insertintopersonvalues(60,600,600);insertintopersonvalues(70,700,700);insertintopersonvalues(80,800,800); 查看binlog模式: 查看当前正在写入的binlog文件: 查看binlog中的内容,我们先来看下row模式showbinlogeventsinmysqlbin。000001; 说明:SETSESSION。GTIDNEXTANONYMOUS’BEGIN开始一个事务Tablemap记录更新了哪个库、哪张表Writerows记录做了什么操作,详细看binlog需要借助mysqlbinlog工具。COMMITxid157结束一个事务 查找binlog文件的物理位置:root167bfa3785f1:findnamemysqlbin。000001varlibmysqlmysqlbin。000001 借助mysqlbinlog命令,查看具体内容:mysqlbinlogvvmysqlbin。000001startposition2986; 红框中的内容表示执行了插入命令,insertintopersonvalues(80,800,800); 其中,1、2、3表示表person的第几个字段,不用原始名称,是为了节省空间。 修改binlog格式,设置为STATEMENT,查看日志格式:setglobalbinlogformatSTATEMENT; 设置之后,需要退出mysql重新连接,才能看到生效showbinlogeventsinmysqlbin。000001; 从图中我们可以看出,当binlogformatstatement时,binlog里面记录的就是SQL语句的原文。 其中,usetomge:表示要先切到对应的数据库 如果想从指定位置查看binlog,可以增加from可选参数,如下:showbinlogeventsinmysqlbin。000001from5168; statement与row对比: statement格式的binlog记录的是sql语句;row格式的binlog记录的是event(Tablemap,Writerows,Deleterows) 当binlog在statement格式下,记录的是sql语句,在主库执行时可能使用的是索引A;但是同步给备库执行时,可能用了索引B。 索引不同,同一条sql语句,运行结果可能也不一样。 针对这个场景,我们建议采用row格式的binlog。 即使我们使用了带where条件(如:income720)的delete语句,但binlog记录的是要删除的主键id(id80),所以不会出现差错。 mixed格式的binlog是个啥? 由于statement格式的binlog可能会导致主库、备库间的数据同步不一致,因此我们会采用row格式。 但是,row格式占用的空间很大,写binlog也要占用大量的IO资源。 所以,官方提出一种mixed混合模式,集成了两者的优点。 内容如下:mysql会自动判断statement格式,是否会引发主备不一致的问题如果statement格式会引起主备不一致的问题,自动使用row格式。如果statement格式不会引起主备不一致的问题,那么就用statement格式, 恢复数据 当然,我们还建议把MySQL的binlog设置成row模式,因为它可以用于数据恢复。我们来看下insert、update、delete三种DML操作如何来恢复数据的。 1、delete: 当我们执行delete命令时,如果binlogrowimage设置了FULL,那么Deleterows里面,包含了删掉的行的所有字段的值。 如果误删了,因为binlog记录了所有字段的值,反向执行insert就可以了。 当binlogrowimage设置为MINIMAL,只记录关键信息,比如id80 2、insert: row格式下,binlog会记录insert的所有字段值。 如果误操作,只需要根据这些值找到对应的行,再执行delete操作即可 3、update: row格式下,binlog会记录update修改前、修改后的整行数据。 如果误操作,只需要用修改前的数据覆盖即可。 通过命令来恢复数据: 如果要执行数据恢复,可以使用下面命令mysqlbinlogmysqlbin。000001startposition1stopposition3000mysqlh192。168。0。1P3306 将mysqlbin。000001文件位置从1到3000的binlog在192。168。0。1机器的数据库上回放,还原。