docke环境下.netcore 项目连接mysql一主一从服务器踩坑端口错误

主从复制的用途:

  • 实时灾备,用于故障切换
  • 读写分离,提供查询服务

主从部署必要条件:

  • 主库开启binlog日志(设置log-bin参数)
  • 主从server-id不同
  • 从库服务器能连通主库

1、安装好docker

2、拉取好mysql相关镜像

3、在宿主机服务器上新建master以及master下3个目录,新建slave目录和slave目录下3个目录:

 

 

4、进入/home/mysqlcluster/1master1slave/master/conf目录中,vim my.cnf新建my.conf

vim my.cnf

 

将以下内容粘贴到my.conf中,执行:wq保存退出

[mysqld]
server_id = 1 # 唯一标识,主库从库不能重复
log_bin = mysql-bin # 开启日志
binlog_format=STATEMENT # 日志记录的格式类型
# max_binlog_size = 512M # 单个日志文件最大
#  expire_logs_day = 3 # 日志有效期(天)
#  binlog_do_db = test1,test2 # 日志记录(同步复制)那些数据库
#  binlog_ignore_db = mysql,performance_schema,information_schema # 日志记录忽略那些数据库的

   注:由于log_bin是个只读系统变量,不能动态的修改,只能再my.cnf里[mysqld]模块添加log-bin 配置,表示启用binlog,如果没有给定值,写成 log-bin=,则默认名称为主机名。(注:名称若带有小数点,则只取第一个小数点前的部分作为名称) log-bin的值决定了msyql 的binlog的名字,⽣成的binlog名字为mysql-bin.000001

 

 

其他master配置参考

[mysqld]
## 同一局域网内注意要唯一
server-id=1024
## 开启二进制日志功能,可以随便取(关键)
log-bin=mysql-bin
secure_file_priv=/var/lib/mysql
default_authentication_plugin=mysql_native_password  #设置密码规则
max_connections=1000 #最大连接数设置 根据实际需要 自行调整

 

 5、进入/home/mysqlcluster/1master1slave/slave/conf目录  vim my.cnf新建my.conf

vim my.cnf

将以下内容粘贴到my.conf中,执行:wq保存退出

[mysqld]
server_id = 2            # 数据库唯一id,内网唯一
log_bin = mysql-bin        # 开启日志,如果从库还会用做主库,建议配置
binlog_format=STATEMENT        # 日志记录的格式类型
# max_binlog_size = 512M     # 单个日志文件最大
# # expire_logs_day = 3       # 日志有效期(天)
# # replicate_do_db = test1,test2 # 是在slave上配置,指定slave要复制哪个库
# # replicate-ignore-db=mysql,performance_schema,information_schema  # 是在slave上配置,指定slave要忽略哪个库
# relay_log_recovery = 1     # 从库建议开启,有利于数据一致性
# log_slave_updates = 1      # 如果从库还会用做主库,建议开启

其他slave配置参考

[mysqld]
## 设置server_id,注意要唯一
server-id=1022 
## 开启二进制日志功能,以备Slave作为其它Slave的Master时使用
log-bin=mysql-slave-bin   
## relay_log配置中继日志
relay_log=edu-mysql-relay-bin
secure_file_priv=/var/lib/mysql
default_authentication_plugin=mysql_native_password  #设置密码规则
max_connections=1000 #最大连接数设置 根据实际需要 自行调整

 

 

 6、执行下面命令新建master容器,并且映射宿主机三个目录为mysql的卷

 

docker run -d -p 3309:3306 --name mysql1master  \
 -v /home/mysqlcluster/1master1slave/master/data:/var/lib/mysql \
 -v /home/mysqlcluster/1master1slave/master/conf:/etc/mysql/conf.d \
 -v /home/mysqlcluster/1master1slave/master/log:/var/log/mysql  \
 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.31

 

 7、执行下面命令新建slave容器,并且映射宿主机三个目录为mysql的卷

docker run -d -p 3310:3306 --name mysql1slave  \
 -v /home/mysqlcluster/1master1slave/slave/data:/var/lib/mysql \
 -v /home/mysqlcluster/1master1slave/slave/conf:/etc/mysql/conf.d \
 -v /home/mysqlcluster/1master1slave/slave/log:/var/log/mysql  \
 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.31

 

8、启动master和slave

 

9、启动完成后,使用navicat分别测试下远程连接master和slave,端口使用映射端口

 

10、进行slave账户创建及相关授权,slave账户是master上的一个账号,是在slave服务器上远程登录master服务器的账号,登录后用于主从复制操作

CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; 
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;

 


 

11、 启动并且进入master容器,登录mysql

docker exec -it mysql1master /bin/bash

 查看master状态

mysql> show master status;

 或者执行:

show master status \G;

在另一个bash查看master的ip,配置slave 要用

docker inspect --format={{.NetworkSettings.IPAddress}} mysql1master

 

 

 

 

12、启动slave容器,并且登录slave的mysql

 

docker exec -it mysql1slave /bin/bash

bash-4.4# mysql -u root -p
Enter password:123456

13、如果刚才配置过slave,就先 停止slave,如果没配置过,跳过stop slave;

mysql> stop slave;

 

14、  配置slave 

master_host使用刚才查询的ip,master_port使用master容器的端口,默认是3306 , master_log_file使用刚才master查询的值,master_log_pos使用刚才master查询的值,这两个值一定要跟master的一样

 (此处绑定了错误的端口,导致后面Slave_IO_Running: Connecting)

 

mysql> change master to
master_host='172.17.0.18',
master_port=3309,  
master_user='slave', 
master_password
='123456',
master_log_file
='mysql-bin.000006',
master_log_pos
=3325;

master_port: Master的端口号,指的是容器的端口号,不是容器映射出阿里的端口,master的端口号为3306
master_user:用于数据同步的用户
master_password:用于同步的用户的密码
master_log_file:指定Slave从哪个日志文件开始复制数据,即上文中提到的File字段的值
master_log_pos:从哪个Position开始读,即上文中提到的Position字段的值
master_connect_retry:如果连接失败,重试的时间间隔,单位是秒,默认是60秒

15、 启动slave

mysql> start slave;

16、  查看salve数据库状态

mysql> show slave status \G;

 

 

17、 检查使用slave远程连接master

docker exec -it mysql1slave /bin/bash

bash-4.4# mysql -u slave -h 172.17.0.18 -p

Enter password:

show master status;

 

18、如果无法连接,需要重新授权slave用户 ,如果查看用户有slave用户,CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; 这句就不用执行了

 

CREATE USER 'slave'@'%' IDENTIFIED BY '123456'; 
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
FLUSH PRIVILEGES;

 

 19、检查端口是否正确,发现绑定端口3309是错误,需要绑定容器原来的端口3306,

命令1:docker exec -it mysql1slave /bin/bash
命令2:mysql -u root -p
#接着输入密码123456后回车
命令3:stop slave;
命令4:change master to
master_host='172.17.0.18', 
master_port=3306,  #注意此端口一定是master容器的端口,不是容器映射的端口,之前是使用了映射的3309端口是错误的
master_user='slave', 
master_password='123456',
master_log_file='mysql-bin.000006', #注意这个要查询master的值,跟master的值一致
master_log_pos=2660;#注意这个要查询master的值,跟master的值一致
start slave;

 

20、验证主从复制成功,navicat在master中添加一条数据,过一会查看slave是否复制了数据

 

 检验成功,主从复制搭建完毕!


 21、 错误一:最终解决下图1报错是因为slave绑定的端口不对,slave要绑定master容器默认的3306端口而不是容器映射的3309 端口

图1 :解决错误前

 图2:解决错误后

 

命令1:docker exec -it mysql1slave /bin/bash
命令2:mysql -u root -p
#接着输入密码123456后回车
命令3:stop slave;
命令4:change master to
master_host='172.17.0.18', 
master_port=3306,  #注意此端口一定是master容器的端口,不是容器映射的端口,之前是使用了映射的3309端口是错误的
master_user='slave', 
master_password='123456',
master_log_file='mysql-bin.000006', #注意这个要查询master的值,跟master的值一致
master_log_pos=2660;#注意这个要查询master的值,跟master的值一致

start slave;

 

 

22、master服务器日志报错:

2023-04-25T11:09:38.076294Z 13 [Warning] [MY-010908] [Server] Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT.

The statement is unsafe because it uses a LIMIT clause. This is unsafe because the set of rows included cannot be predicted.

Statement: DELETE FROM `Test`.`Person` WHERE `Id` = 1 AND `Name` = '李四' AND `Age` = 20 LIMIT 1

 

解决方案 :修改binlog_format格式为mixed;需要先在 slave上,设置 binlog_format=mixed,之后再在master上设置

登陆mysql,如果slave还在运行any replication channel applier thread is running 需要先停止 

mysql> STOP SLAVE SQL_THREAD;
mysql> set global binlog_format=MIXED;
mysql> START SLAVE SQL_THREAD;

slave截图

master截图

 

 

 

 

23、可能错误二   master 和slave的pos不一致


24 、可能错误三:  master上新建slave账号无法从salve容器上登录master数据库

 

25、主从数据库容器都需要关闭防火墙,默认是关闭的


二、发布.net core 项目连接master数据库

2.1 使用以下命令生成宿主机/home/mysqltest/1master1slavecore/JwtToken目录下项目的镜像
docker  build --no-cache -t 1master1slavecore -f Dockerfile .

2.2 使用以下命令运行容器镜像
docker run -it -d  -p 8113:8113 --name 8113 1master1slavecore

 



2.3使用宿主机外网ip后导致报错

 2.4、修改appsettings.json 将ip或者localhost改为*号 ,删除2.1和2.2生成的镜像和容器。然后重复2.1和2.2两个步骤重新生成镜像和容器

 2.5、访问天气接口可以正常访问

 2.6 访问person接口出现报错

 

2.7 使用--link命令将master容器和项目容器连接起来
docker run -it -d  -p 8113:8113     --link mysql1master:mysql1master          --name 8113 1master1slavecore

2.8    访问接口

 

2.9 查看日志

 2.10  master数据库缺少persons表,新建persons表,并且添加1条数据,运行接口

 

 

2.11  运行addpersons接口,出现报错

 

 

2.12    将Id设置为主键,并且要勾选下面的自动递增,数据库的修改,对数据库表的修改无需重启docker容器

 

2.13     再次运行接口

 2.14      docker部署的主从复制.netcore项目成功

 

2.15    隔了一段时间再次运行.netcore 程序时,需要先stop  然后再restart 项目容器,否则会出现连接数据库错误

 

posted @ 2023-04-25 11:35  无声袖箭  阅读(185)  评论(0)    收藏  举报