MySQL主从复制
MySQL 5.6开始主从赋值有两种方式:
1:基于日志binlog
2:基于GTID 全局事务标识符
本文只涉及基于日志 binlog
的 主从配置。
主从复制的工作流程
MySQL通过操作主要通过三个线程实现,基本步骤如下、
1:Master服务器将数据的更新记录到二进制(binary log)中,用于记录二进制日志时间,这一步由Master服务器完成。
2:Slave服务器将Master服务器的二进制日志复制到本地的中继日志(Relay log),这一步由Slave服务器IO线程完成。
3:Slave服务器读取中继日志中的事件,将其重放在数据中,这一步由Slave服务器SQL线程完成。
主从模式的优点
1:一般的工作模式下,Master服务器负责增删改操作,查询工作由Slave服务器完成。
2:异地容灾备份,主要就是可以把Master服务器的数据同步到异地服务器上,提高数据的安全性。
3:高可用,Master服务器挂了,Slave可以充当Master继续提供服务。
4:高扩展性
1:纵向扩展,我可以更换机器更好的配置,因为有多台服务器,所以不用担心停机。
2:横向扩展,就是加机器咯,可以分散各个服务器的压力。
主从模式的缺点
1:成本增加,增加服务器就不说了,主要还需要开启二进制日志,所以也会造成格外的性能开销。
2:数据延迟
3:写入更慢,因为Master服务器会承担所有写的操作,而且只有一台可以写入的Master服务器,因此写入的压力不能被分散。
一般主从复制模式使用场景是:
1:要求读大于写的系统场景。
2:对数据备份实时性要求较高的系统。
主从复制的前置条件
1:操作系统和位数一致
2:数据库版本一致
3:主从数据库的数据一致
4:每台数据库的server_id在局域网内必须唯一
开始实战
为了快速搭建mysql集群,建议使用Docker
1:修改Master服务器MySQL配置文件
[mysqld] ## 设置server_id,一般设置为IP,同一局域网内注意要唯一 server_id=100 ##关键 ## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步) binlog-ignore-db=mysql ## 开启二进制日志功能,可以随便取,最好有含义(关键就是这里了) log-bin=mysql-bin ##关键 ## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存 binlog_cache_size=1M ## 主从复制的格式(mixed,statement,row,默认格式是statement) binlog_format=mixed ## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062
一般修改完配置文件需要重启下MySQL
2:Master服务器进入MySQL,创建数据同步用户,然后授予该用户REPLICATION SLAVE和REPLICATION CLIENT权限
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
3:修改Slave服务器MySQL配置文件
[mysqld] ## 设置server_id,一般设置为IP,注意要唯一 server_id=101 ##关键 ## 复制过滤:也就是指定哪个数据库不用同步(mysql库一般不同步) binlog-ignore-db=mysql ## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用 log-bin=mysql-slave1-bin ##关键 ## 为每个session 分配的内存,在事务过程中用来存储二进制日志的缓存 binlog_cache_size=1M ## 主从复制的格式(mixed,statement,row,默认格式是statement) binlog_format=mixed ## 二进制日志自动删除/过期的天数。默认值为0,表示不自动删除。 expire_logs_days=7 ## 跳过主从复制中遇到的所有错误或指定类型的错误,避免slave端复制中断。 ## 如:1062错误是指一些主键重复,1032错误是因为主从数据库数据不一致 slave_skip_errors=1062 ## relay_log配置中继日志 relay_log=edu-mysql-relay-bin ##关键 ## log_slave_updates表示slave将复制事件写进自己的二进制日志 log_slave_updates=1 ## 防止改变数据(除了特殊的线程) read_only=1
4:进入Master服务器MySQL,执行show master status;
File和Position字段的值后面将会用到,在后面的操作完成之前,需要保证Master库不能做任何操作,否则将会引起状态变化,File和Position字段的值变化。
5:进入Slave服务器MySQL执行
change master to master_host='172.17.0.2', master_user='slave', master_password='123456', master_port=3306, master_log_file='mysql-bin.000001', master_log_pos= 2830, master_connect_retry=30;
命令说明:
master_host :Master的地址,指的是容器的独立ip,可以通过docker inspect --format='{{.NetworkSettings.IPAddress}}' 容器名称|容器id
查询容器的ip
master_port:Master的端口号,指的是容器的端口号
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值
master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
在Slave 中的mysql终端执行show slave status \G;
用于查看主从同步状态。
正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。使用start slave
开启主从复制过程,然后再次查询主从同步状态show slave status \G;
。
最后测试一下,向Master插入新建一个数据库试一下哟。