主库和备库
客户端和主库连接,备库拷贝主库,两边都有同样的数据。
备份需要用到binlog日志,日志里面有操作sql执行的语句过程。
limit会导致主备数据不一致
sql:delete from t /comment/ where a>=4 and t_modified<='2018-11-10' limit
运行delete产生一个warning,binlog格式statement,语句含有limit,所以命令是unsafe.索引a能准确删除一行a=4的数据,而索引t_modified删除的是另外一行的数据。两个数据不一致。
改成row格式,不会有主备删除不同行的问题。
binlog三种格式:statement,row,mixed
binlog row格式能实现主备库删除同一行数据,row有个缺点删除10万条数据,会把10万条记录写到binlog中,占用大量空间,耗费io资源。
mixed根据语句判断主备库不一致,可能有这种问题,就选row。如果没有,就选statement.
row格式在update,delete,insert操作下的作用。
如果update更新错了语句,查看binlog可以知道更新前的样子和更新后的样子,将这两条信息对调,再执行数据库。
如果delete删错了语句,查看binlog可以知道删错的那条语句,可以用insert重新插入。
如果insert插错了语句,查看binlog精确定位那条语句,将insert语句转成delete语句,删掉这行数据。
如果想恢复数据,用mysqlbinlog解析出日志,然后把里面的statement语句直接拷贝出来执行是不行的
用binlog恢复数据,mysqlbinlog工具解析出结果,把结果整个给MySQL执行。
主备序循环复制
M-S结构
双M结构(常用)
两个图的区别:双M多了一条线,a和b互为主备关系。
如果节点A同时是节点B的备库,相当于又把节点B新生成的binlog拿过来执行了一次,然后节点A和B间,会不断地循环执行这个更新语句,也就是循环复制了。这个要怎么解决呢?
节点A更新事务,binlog会记录A的id,传给节点B执行一次,节点B生成的binlog的id跟A的id一样,再传回给A判断这个id跟自己相同,不处理这个日志,死循环结束。