一、三种模式
mysql复制主要有三种方式:基于SQL语句的复制(statement-based replication, SBR),基于行的复制(row-based replication, RBR),混合模式复制(mixed-based replication, MBR)。对应的,binlog的格式也有三种:STATEMENT,ROW,MIXED。
① STATEMENT模式(SBR)
每一条会修改数据的sql语句会记录到binlog中。优点是并不需要记录每一条sql语句和每一行的数据变化,减少了binlog日志量,节约IO,提高性能。缺点是在某些情况下会导致master-slave中的数据不一致(如sleep()函数, last_insert_id(),以及user-defined functions(udf)等会出现问题)
② ROW模式(RBR)
不记录每条sql语句的上下文信息,仅需记录哪条数据被修改了,修改成什么样了。而且不会出现某些特定情况下的存储过程、或function、或trigger的调用和触发无法被正确复制的问题。缺点是会产生大量的日志,尤其是alter table的时候会让日志暴涨。
③ MIXED模式(MBR)
以上两种模式的混合使用,一般的复制使用STATEMENT模式保存binlog,对于STATEMENT模式无法复制的操作使用ROW模式保存binlog,MySQL会根据执行的SQL语句选择日志保存方式。
配置保存在my.cnf中
binlog_format = MIXED //binlog日志格式,mysql默认采用statement,建议使用mixed
log-bin = /data/mysql/mysql-bin.log //binlog日志文件
expire_logs_days = 7 //binlog过期清理时间
max_binlog_size = 100m //binlog每个日志文件大小
binlog_cache_size = 4m //binlog缓存大小
max_binlog_cache_size = 512m //最大binlog缓存大小
二、比较好的一篇文章 https://blog.csdn.net/hao_yunfeng/article/details/82392261
三、什么时候会造成主备复制不同步(摘自知乎)
一 序言
在运维线上M-M 架构的MySQL数据库时,接收的比较多关于主备延时的报警 check_ins_slave_lag (err_cnt:1)critical-slavelag on ins:3306=39438 相信slave 延迟是MySQL dba 遇到的一个老生长谈的问题了。先来分析一下slave延迟带来的风险 1. 异常情况下,主从HA无法切换。HA 软件需要检查数据的一致性,延迟时,主备不一致。 2. 备库复制hang会导致备份失败(flush tables with read lock会900s超时) 3. 以 slave 为基准进行的备份,数据不是最新的,而是延迟。
二 如何解决 面对此类问题我们如何解决 ,如何规避?分析一下导致备库延迟的几种原因 1. ROW模式无主键、无索引或索引区分度不高.有如下特征 a. show slave status 显示position一直没有变 b. show open tables 显示某个表一直是 in_use 为 1 c. show create table 查看表结构可以看到无主键,或者无任何索引,或者索引区分度很差。 解决方法: a. 找到表区分度比较高的几个字段, 可以使用这个方法判断: select count(*) from xx; select count(*) from (select distinct xx from xxx) t; 如果2个查询count(*)的结果差不多,说明可以对这些字段加索引 b. 备库stop slave; 可能会执行比较久,因为需要回滚事务。 c. 备库 set sql_log_bin=0; alter table xx add key xx(xx); 老的版本slave应用binlog时只会选择第一个索引,需要把新加的索引放在最前面,可以先把老的索引删掉,建新的索引,再把老的索引建上。可以放到一个sql中执行。 d. 备库start slave 如果是innodb,可以通过show innodb status来查看 rows_inserted,updated,deleted,selected这几个指标来判断。 如果每秒修改的记录数比较多,说明复制正在以比较快的速度执行。 2 MIXED模式无索引或SQL慢 在从库上show full processlist 查看到正在执行的SQL。 解决方法: a. SQL比较简单, 则检查是否缺少索引,并添加索引。 b. 另一类是 insert into select from的语句,如果select 里包含group by,多表关联,可能效率会比较低。 这类可以到主库把binlog_format改成row。 3 主库上有大事务,导致从库延时 现象解析binlog 发现类似于下图的情况看 解决方法: 与开发沟通,增加缓存,异步写入数据库,减少直接对db的大量写入。 4. 主库写入频繁,从库压力跟不上导致延时 此类原因的主要现象是数据库的 IUD 操作非常多,slave由于sql_thread单线程的原因追不上主库。 解决方法: a 升级从库的硬件配置,比如ssd,fio. b 使用@丁奇的预热工具-relay fetch 在备库sql线程执行更新之前,预先将相应的数据加载到内存中,并不能提高sql_thread线程执行sql的能力,也不能加快io_thread线程读取日志的速度。 c 使用多线程复制 阿里MySQL团队实现的方案--基于行的并行复制。 该方案允许对同一张表进行修改的两个事务并行执行,只要这两个事务修改了表中的不同的行。这个方案可以达到事务间更高的并发度,但是局限是必须使用Row格式的binlog。因为只有使用 Row格式的binlog才可以知道一个事务所修改的行的范围,而使用Statement格式的binlog只能知道修改的表对象。 5. 数据库中存在大量myisam表,在备份的时候导致slave 延迟 由于xtrabackup 工具备份到最后会执行flash tables with read lock ,对数据库进行锁表以便进行一致性备份,然后对于myisam表 锁,会阻碍salve_sql_thread 停滞运行进而导致hang 该问题目前的比较好的解决方式是修改表结构为innodb存储引擎的表。 6 网络丢包 重传 这个是刚刚遇到的,博客里面没有记录,和网络环境有关。怎么解决?拉专线,换更好的交换机 扩容网络带宽等等,
——————————————————————
a. 找到表区分度比较高的几个字段, 可以使用这个方法判断: select count(*) from xxx; select count(*) from (select distinct xx from xxx) t; 如果2个查询count(*)的结果差不多,说明可以对这些字段加索引 ---这句话的解释xx字段distinct行数和表的总行数差不多