简要说明:
这里说的主从延迟,并不是指“从库更新性能跟不上主库”, 而是“一个命令从主库更新完成到从库更新完成的延迟时间”。
主从环境:
- 1.MYSQL版本:5.6.14
- 2.服务器不同机器,不同机房:
master主库:ip_master 端口号:3307 (本地机房)
slave从库:ip_slave 端口号:3308 (阿里)
- 3.同步账号:
grant replication slave on *.* to 'repl'@'ip_slave' identified by 'repl123456';
- 4.执行主从同步语句:
change master to master_host='ip_master',master_port=3307,master_user='repl',master_password='repl123456',master_log_file='test-mysql-bin.000001',master_log_pos=154;
基本流程:
对于每一个连上来的从库,主库都有一个client线程与之对应。现在先看一下主从的基本数据流:
- 1、客户端sql更新命令
- 2、主库执行sql语句
- 3、主库写binlog
- 4、主库client线程读binlog发送给从库的io线程
- 5、从库io线程写盘(relay-log)
- 6、从库sql线程读(relay-log)
- 7、从库执行更新(relay-info)
这里有涉及到两个写盘,主库binlog和从库的relaylog(3、5)。
不过不用担心不停扫描文件造成的延迟,因为读文件的线程是在同一个进程内,每次写完都会广播,所以虽然看上去是异步,实际上延迟并不大。
# 我们主要考察步骤2完成瞬间到步骤7开始执行之前的延迟时间。
操作流程:
- 1、现在我们通过client客户端向master主库发起一个create/insert/delete/update操作,这个操作会被同步到slave从库;
- 2、在client客户端执行create/insert/delete/update操作的当前系统时间 t1;
- 3、在slave从库上执行create/insert/delete/update操作的当前系统时间t2;
- 4、则t2-t1的值是我们需要的结果。
第一次create表:
master主库上t1:
mysql> use database test_db;
mysql> create table zzzyuki (
id varchar(100) NOT NULL,
assetsType varchar(100) NOT NULL,
name varchar(100) NOT NULL COMMENT '名称',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> select table_schema,table_name,create_time from information_schema.tables where table_name='zzzyuki'\G;
*************************** 1. row ***************************
table_schema: test_db
table_name: zzzyuki
create_time: 2018-05-25 11:24:36
1 row in set (0.00 sec)
slave从库上t2:
mysql> select table_schema,table_name,create_time from information_schema.tables where table_name='zzzyuki'\G;
*************************** 1. row ***************************
table_schema: test_db
table_name: zzzyuki
create_time: 2018-05-25 11:39:09
1 row in set (0.00 sec)
t2-t1的值是我们需要的结果:
mysql> select timediff('2018-05-25 11:39:09','2018-05-25 11:24:36')\G;
*************************** 1. row ***************************
timediff('2018-05-25 11:39:09','2018-05-25 11:24:36'): 00:14:33
1 row in set (0.00 sec)
第二次create表:
master主库上t1:
mysql>use database test_db;
mysql>create table zzzyuki (
id varchar(100) NOT NULL,
assetsType varchar(100) NOT NULL,
name varchar(100) NOT NULL COMMENT '名称',
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
mysql> select table_schema,table_name,create_time from information_schema.tables where table_name='zzztest'\G;
*************************** 1. row ***************************
table_schema: test_db
table_name: zzztest
create_time: 2018-05-25 12:15:11
1 row in set (0.01 sec)
ERROR:
No query specified
slave从库上t2:
mysql> select table_schema,table_name,create_time from information_schema.tables where table_name='zzztest'\G;
*************************** 1. row ***************************
table_schema: test_db
table_name: zzztest
create_time: 2018-05-25 12:39:38
1 row in set (0.00 sec)
ERROR:
No query specified
t2- t1的值是我们需要的结果:
mysql> select timediff('2018-05-25 12:39:38','2018-05-25 12:15:11')\G;
*************************** 1. row ***************************
timediff('2018-05-25 12:15:11',' 2018-05-25 12:39:38'): 00:24:27
1 row in set (0.00 sec)
ERROR:
No query specified
结论:
刚刚我们通过client客户端向master主库发起两次create表操作,第一次create表被同步到slave从库时间是14:33min, 第二次create表被同步到slave从库时间是24:27min,前后两次create表被同步到slave从库的时间并不相同,并且时间差还有点大。由于我们主从服务器跨机器并且跨机房,除了网络带宽原因之外网络的稳定性以及机器之间的同步都是我们主从同步应该考虑的主要原因。
当然,在实际生产环境中这两台服务器mysql同步延迟时间可能远远比这两个时间长,主要原因是我们现在测试时数据量并不大。
拓展:mysql出现主从同步延迟可能有哪些原因
1.从库太多导致复制延迟
优化:建议从库数量3-5个为宜。2.从库硬件比主库硬件差
优化:提升硬件性能。3.慢SQL语句过多
优化:SQL语句执行时间太长,需要优化SQL语句。4.主从复制的设计问题
优化:主从复制单线程,可以通过多线程IO方案解决;另外MySQL5.6.3支持多线程IO复制。5.主从库之间的网络延迟
优化:尽量链路短,提升端口带宽。6.主库读写压力大
优化:前端加buffer和缓存。主从延迟不同步: 不管有多延迟,只要不影响业务就没事。7.业务设计缺陷导致延迟影响业务
优化:从库没有数据改读主库。