目前,我们的开发框架是所有开发(前端后端),共用局域网的一个本地服务。这种好处是测试数据共享,但坏处也正是测试数据共享,会修改的或被别人修改到相同的测试数据。特别对于一些金额测试,既需要大量的数据又需要准确的数据。
我们今天探究的就是把共用的开发库同步到自己的开发库中,即以公共开发库为主库,本地开发库为从库。从而解决上面的问题。
【192.168.1.240:3306】作为主库
我们这边公共mysql开发库【192.168.1.240:3306】作为从库,给作为master的mysql 容器添加my.cnf配置如下
[mysqld]
character-set-server=utf8
log-bin=mysql-bin #启用二进制日志
server-id=240
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
把文件复制到容器
docker cp ~/my.cnf b1b46bd7d2f8:/etc/mysql/conf.d/my.cnf
直接重启下容器然后登录容器查看
docker restart b1b46bd7d2f8 #重启下容器,免得进入再重启mysql
docker exec -it b1b46bd7d2f8 bash
登录mysql 服务并查看作为master的服务状态
mysql -uroot -p
show master status;
file: bin-log 的名称,position 位置行数;我们设置从服务的时候需要配置从主服务的bin-log 文件名称与复制的位置;
给从从服务添加用户账号和权限
GRANT REPLICATION SLAVE ON *.* to 'test'@'%' identified by '123456';
show master status/G;
至此主服务的设置已经完成
【192.168.0.17:3306】作为从库
192.168.0.17 是我本地的ip,MySQL服务也是现成的,给作为slave的mysql 容器添加my.cnf配置如下
[mysqld]
character-set-server=utf8
log-bin=mysql-bin #启用二进制日志
server-id=17
replicate-ignore-db=mysql
replicate-ignore-db=sys
replicate-ignore-db=information_schema
以上配置只需要开启二进制日志并设置服务id即可,同样把配置文件复制到容器的/etc/mysql/conf.d下
把文件复制到容器
docker cp G:\.docker\mysql\master\conf\my.cnf 845b8ab79dba:/etc/mysql/conf.d/my.cnf
可以看到我这边cp宿主的绝对地址不一样,那是因为240我们用的是ubuntu, 本地用的win,请忽略,毕竟不是每个人都有钱买mac~~
同样重启容器,并登录mysql服务
#docker restart 845b8ab79dba
#docker exec -it 845b8ab79dba bash
mysql -uroot -p
show slave status; # 这时候查看slave状态并不能看到任何slave的信息
配置主库链接并开启slave服务
change master to master_host='192.168.1.240',master_user='test',master_password='123456',master_log_file='mysql-bin.000006',master_log_pos=9090791,master_port=3306;
start slave;
show slave status\G;
我们可以看到
Slave_IO_State: Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
则表示我们已经连接成功,我们可以在主库修改同步的数据信息,验证是否同步
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.240
Master_User: test
Master_Port: 3306
Connect_Retry: 30
Master_Log_File: mysql-bin.000002
Read_Master_Log_Pos: 343856
Relay_Log_File: 845b8ab79dba-relay-bin.000002
Relay_Log_Pos: 344069
Relay_Master_Log_File: mysql-bin.000002
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: mysql,sys,information_schema
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 343856
Relay_Log_Space: 344283
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 240
Master_UUID: cc25085c-315a-11eb-af2d-0242ac130007
Master_Info_File: /var/lib/mysql/master.info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set:
Executed_Gtid_Set:
Auto_Position: 0
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
1 row in set (0.00 sec)
有时候第一次同步可能因为数据等各方面原因,会出现报错然后slave 自动停掉,可以查看Last_IO_Error查看,这时候Last_IO_Error可能为no,修改对应的报错并重启slave服务。
win本地docker 创建两个mysql 服务实现主从配置
docker创建主库mysql
docker run --name mastermysql -d -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -v /g/.docker/mysql/master/data:/var/lib/mysql mysql:5.7
然后根据上述创建主库的步骤进行就行了
docker创建从库
我们构建容器的命令跟构建主服务是一样的,只需要注意的是端口号及如何实现容器的互通互联
容器互通互联的时候有两种方法
- 使用–link参数构建,docker会自动在共享两个容器的变量。访问数据库的时候,不再是通过IP的方式来访问,而是通过容器名来访问. [–link 数据库容器名:数据库容器别名]
- 通过network Ipv4Address 地址来访问
我们先通过link 参数构建容器
docker run --name slavemysql -d -p 3308:3306 -e MYSQL_ROOT_PASSWORD=root -v /g/.docker/mysql/slave/data:/var/lib/mysql --link mastermysql:master mysql:5.7
配置主库链接并开启slave服务,我们链接主库的mast_host为容器访问别名
change master to master_host='master',master_user='test',master_password='123456',master_log_file='mysql-bin.000006',master_log_pos=9090791,master_port=3306;
start slave;
show slave status\G;
如果在构建容器的时候忘记添加link 参数,我们直接用network的ip来链接也是ok的
change master to master_host='172.17.0.3',master_user='test',master_password='123456',master_log_file='mysql-bin.000006',master_log_pos=9090791,master_port=3306;
因为我们在同一个network 下构建mysql 服务,在未声明network 的情况下,默认为bridge的network
则我们刚刚创建的两个容器都在默认的bridge下
我们可以通过docker network ls 查看本地所有的network,如这是我本地的
我们刚创建两个容器则默认在bridge 下,通过docker network inspect bridge
总结
- my.cnf 从宿主机复制到容器的时候要注意容器mysql的配置位置,如果你show master\slave status; 未显示对应信息则有可能配置文件未加载成功
- mysql服务部署相对比较简单,容器的互通互连应该是搭建本地的难点
- 可以继续探究vps作文主服务,局域网做文从服务的情况,这种情况也是很常见,比如我们吧公共服务放在外网,如何把外网的数据同步到本地。