vlambda博客
学习文章列表

mysql在线做主从及同步问题小结

在线做主从

主不直接锁表,应用于线上环境ha改造

主导出所有数据并附加master binlog信息

例:

mysqldump -uroot -ppassword  --single-transaction --no-autocommit --master-data=2  --all-databases > xxx.sql

从库导入所有数据以后,执行主从配置

例:

head -n 30 xxx.sql
查看具体的master binlog信息,找到相应的log_file信息和master_log_pos信息

重制slave配置(如果之前做过主从的话)
reset slave all;
配置,按照查看sql文件的信息对应填入
change master to master_host='192.168.xxx.xxx', master_user='user', master_password='password', master_port=3306,master_log_file='mysql-bin.007127',master_log_pos=423949136;
启动和查看
start slave;
show slave status\G

同步问题小结

同步原理:

MySQL的主从复制都是单线程的操作,主库对所有DDL和DML产生的日志写进binlog,写入binlog是顺序写,效率很高。

Slave的IO Thread线程从主库中bin log中读取取日志,SQL Thread线程将主库的DDL和DML操作事件在slave中重放。DML和DDL的IO操作是随机的,不是顺序的,成本高很多。

1.同步延迟(最常见问题)

原理

由于SQL Thread也是单线程的,如果slave上的其他查询产生lock争用,又或者一个DML语句(大事务、大查询)执行了几分钟卡住了,那么所有之后的DML会等待这个DML执行完才会继续执行,这就导致了延时。可能主库上那个相同的DDL只执行几分钟,但是slave会延时,原因就是master可以并发执行,而Slave_SQL_Running是单线程。

原因:

1)可能是主、从的服务器配置、网络、负载问题导致

2)二、可能会是表结构或者使用姿势不合理所致

例如最近遇到一个奇葩的问题就是mysql的一张表无主键无索引,且定时有百万级别的数据进行delete和insert。直接导致主从同步延迟,长时间都追不上,典型的姿势有问题。

mysql主从是基于行的复制,删除操作的时候,mysql会把这个SQL按照每条记录,拆分成条delete SQL在备库上执行。mysql这么做的目的也是最大程度的保证同步数据的可靠性,但是可靠性的提升伴随而来的便是日志量的增多,同步过程会占用大量带宽。删除操作时,拆成的百万条delete SQL传递并在备库执行,因为表即无主键,也没有索引,所以每执行一次都要做全表扫描才能定位到要删除的那一条数据,效率低到爆,直接就会导致同步延迟。

2.Slave_IO_Running: NO 

  1)配置、权限及网络连接问题

  2)从库正在读取和执行的binlog文件被删除

  3)延迟的情况下双主发生切换,数据冲突

还有一个注意点就是:

mysql的配置中innodb_thread_concurrency大于0的情况下,主从做完可能长期处于于NO的状态。其值默认是0,表示没有并发线程数限制,所有请求都会直接请求线程执行。大于零的值表示有并发数限制,当一个新的请求发起时,会检查当前并发线程数是否达到了 innodb_thread_concurrency的限制值,如果达到限制值,则会sleep一段时间,然后再次请求,如果再次请求时,当前并发数还是达到限制值,那么就会进入FIFO队列等待执行。所以加了限制可能有段时间都会在等待,从而处于NO的状态。