主从复制(也称 AB 复制)允许将来自一个MySQL数据库服务器(主服务器)的数据复制到一个或多个MySQL数据库服务器(从服务器)。
MySQL中复制的优点包括:
如果一主多从的话,这时主库既要负责写又要负责为几个从库提供二进制日志。此时可以稍做调整,将二进制日志只给某一从,这一从再开启二进制日志并将自己的二进制日志再发给其它从。或者是干脆这个从不记录只负责将二进制日志转发给其它从,这样架构起来性能可能要好得多,而且数据之间的延时应该也稍微要好一些。
由于我们依托于docker容器,所以要求大家预先有docker的知识铺垫。服务器规划
服务器软件用途192.168.0.108docker启动MySQL容器master192.168.0.109docker启动MySQL容器slave192.168.0.1010docker启动MySQL容器slave
首先在192.168.0.108拉取docker镜像,我们这里使用5.7版本的mysql
[root@bogon ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEdocker.io/mysql 5.7 e1e1680ac726 7 months ago 373 MB
创建目录mysql-conf
[root@bogon mysql-conf]# pwd/usr/local/mysql-conf
在当前目录中创建配置文件my.cnf,次文件要映射到mysql的docker容器中的配置文件,文件中加入[mysqld]
[root@bogon mysql-conf]# vi my.cnf[root@bogon mysql-conf]# more my.cnf[mysqld]
创建主机容器Master对外映射的端口是5566,Slave对外映射的端口是5577。因为docker容器是相互独立的,每个容器有其独立的ip,所以不同容器使用相同的端口并不会冲突。
docker run -p 5566:3306 --name master-mysql -v/usr/local/mysql-conf/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
查看容器运行情况
[root@bogon mysql-conf]# docker ps -aCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES1f93892498df mysql:5.7 "docker-entrypoint..." 4 minutes ago Up 4 minutes 33060/tcp, 0.0.0.0:5566->3306/tcp master-mysql
[root@bogon mysql-conf]# more my.cnf [mysqld]skip-name-resolveserver-id=1 log-bin=mysql-bin binlog-do-db=tx_dbbinlog-ignore-db = mysqlbinlog-ignore-db = information_schema
进入容器内可以查看到数据卷映射后的结果
[root@bogon mysql-conf]# docker exec -it 1f93892498df /bin/bashroot@1f93892498df:/etc/mysql/conf.d# more my.cnf [mysqld]skip-name-resolveserver-id=1 log-bin=mysql-bin binlog-do-db=tx_dbbinlog-ignore-db = mysqlbinlog-ignore-db = information_schema
重启容器
docker restart 1f93892498df
登录mysql,授予192.168.0.109, 192.168.0.110 slave从机复制权限
mysql> grant replication slave,replication client on *.* to slave@'192.168.0.109' identified by "123456";Query OK, 0 rows affectedmysql> flush privileges;Query OK, 0 rows affectedmysql> grant replication slave,replication client on *.* to slave@'192.168.0.110' identified by "123456";Query OK, 0 rows affectedmysql> flush privileges;Query OK, 0 rows affected
查看主机状态
mysql> show master status;+------------------+----------+--------------+--------------------------+-------------------+| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |+------------------+----------+--------------+--------------------------+-------------------+| mysql-bin.000001 | 154 | tx_db | mysql,information_schema | |+------------------+----------+--------------+--------------------------+-------------------+1 row in set
从节点配置文件创建在192.168.0.109和192.168.0.110新建目录/usr/local/mysql-conf/创建 my.cnf192.168.0.109机器
[root@file mysql-conf]# more my.cnf [mysqld]skip-name-resolveserver-id= 2log-bin=mysql-bin replicate-do-db=tx_db binlog-ignore-db = mysqlbinlog-ignore-db = information_schema
192.168.0.110机器
[root@file mysql-conf]# more my.cnf [mysqld]skip-name-resolveserver-id= 3log-bin=mysql-bin replicate-do-db=tx_db binlog-ignore-db = mysqlbinlog-ignore-db = information_schema
启动slave1(109)
[root@file mysql-conf]# docker run -p 5577:3306 --name slave-mysql1 -v /usr/local/mysql-conf/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
启动slave1(110)
[root@localhost mysql-conf]# docker run -p 5588:3306 --name slave-mysql1 -v /usr/local/mysql-conf/:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
此时我们可以看到三台MySQL服务器都已经启动,并且连接
mysql> CREATE USER 'slave'@'%' IDENTIFIED BY '123456';Query OK, 0 rows affectedmysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';Query OK, 0 rows affectedmysql> flush privileges;Query OK, 0 rows affectedmysql> stop slave;Query OK, 0 rows affectedmysql>
分别在109和110机器执行。
mysql> change master to master_host='192.168.0.108', master_user='slave', master_password='123456', master_port=5566, master_log_file='mysql-bin.000002', master_log_pos= 154, master_connect_retry=30;Query OK, 0 rows affected
说明:master_host :Master的地址,指的是容器的独立ipmaster_port:Master的端口号,指的是容器的端口号master_user:用于数据同步的用户master_password:用于同步的用户的密码master_log_file:指定 Slave 从哪个日志文件开始复制数据,即上文中提到的 File 字段的值master_log_pos:从哪个 Position 开始读,即上文中提到的 Position 字段的值master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒
检查两台从机状态:我们发现从机已经创建,但是内部线程还未启动
mysql> show slave status G;*************************** 1. row *************************** Slave_IO_State: Master_Host: 192.168.0.108 Master_User: slave Master_Port: 5566 Connect_Retry: 30 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 154 Relay_Log_File: d55404be5426-relay-bin.000001 Relay_Log_Pos: 4 Relay_Master_Log_File: mysql-bin.000002 Slave_IO_Running: No Slave_SQL_Running: No Replicate_Do_DB: tx_db
正常情况下,SlaveIORunning 和 SlaveSQLRunning 都是No,因为我们还没有开启主从复制过程。使用start slave开启主从复制过程,然后再次查询主从同步状态show slave status G;。
mysql> show slave status G;*************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.0.108 Master_User: slave Master_Port: 5566 Connect_Retry: 30 Master_Log_File: mysql-bin.000002 Read_Master_Log_Pos: 154 Relay_Log_File: d55404be5426-relay-bin.000002 Relay_Log_Pos: 320 Relay_Master_Log_File: mysql-bin.000002 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: tx_db
学习更多架构免费课程请私信我
私信我免费领取海量java架构面试题