前提
由于没有多台服务器, 所以这里改用docker启动多个mysql服务, docker安装指引可见: debian安装docker
我的linux服务器是debian的, 所以这里以debian为例
另外, 需要在宿主机连接docker的mysql服务, 需要在宿主机安装mysql服务, mysql安装指引可见: linux安装mysql
这里我的虚拟机的ip为: 192.168.226.137
前期准备
-
访问mysql的docker镜像源, 并找到所需mysql版本
-
拉取mysql镜像,
docker pull mysql:8.0.18
-
在/var/mysql下新建对应文件夹, 用于docker目录映射到实体机的目录
-
在mysqlConf1和mysqlConf2下分别创建对应的mysql配置文件
mysql1配置:sudo vi mysqlConf1/101.cnf
[mysqld] log-bin=mysql-bin server-id=101
mysql2配置:
sudo vi mysqlConf2/102.cnf
[mysqld] log-bin=mysql-bin server-id=102
-
启动两个mysql服务
docker run -itd --name mysql1 -v /var/mysql/mysqlConf1:/etc/mysql/conf.d -v /var/mysql/mysql1:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.18
docker run -itd --name mysql2 -v /var/mysql/mysqlConf2:/etc/mysql/conf.d -v /var/mysql/mysql2:/var/lib/mysql -p 3308:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.18
-
查看docker服务状态
docker ps
-
尝试连接mysql服务
mysql -h 127.0.0.1 -P 3307 -u root -p
同理可连接mysql2的3308端口 -
创建有远程同步权限账户
create user 'replicate'@'%' identified with caching_sha2_password by '123456';
低版本的mysql用
create user 'replicate'@'%' identified by '123456';
grant replication slave on *.* to 'replicate'@'%';
-
登录主服mysql,查询master状态
mysql -h 127.0.0.1 -P 3307 -u root -p
show master status;
-
登录从服mysql,设置与主服务器相关的配置参数
change master to master_host='192.168.226.137',master_port=3307,master_user='replicate',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=340;
master_host: docker的地址, 不能写127.0.0.1
master_user: 在主库创建的用户, 步骤8中创建的用户
master_port: 主库的端口, 默认3306
master_log_pos: 主库show master status;查询出的Position -
在从服mysql, 启动slave,
start slave;
-
查看从服状态
show slave status \G;
验收
- 在主服创建数据库,
create database test
- 连接从服, 查看数据库列表,
show databases;
- 此时从服已经有test数据库, 表示主从备份成功
其他问题
出现同步错误后, 后续同步不执行
若在主从同步的过程中,出现其中一条语句同步失败报错了,则后面的语句也肯定不能同步成功了。例如,主库有一个数据库,而从库并没有,然而,在主库执行了删除这个数据库的操作,那么从库没有这么数据库就肯定删除不了,从而报错了。在此时的从数据库的数据同步就失败了,因此后面的同步语句就无法继续执行。
这里提供的解决方法有两种:
-
在从数据库中,使用SET全局sql_slave_skip_counter来跳过事件,跳过这一个错误,然后执行从下一个事件组开始。
#在从数据库上操作mysql > stop slave; mysql > set global sql_slave_skip_counter=1; mysql > start slave;
-
想办法(例如, 数据库迁移等)令从库与主库的数据结构和数据都一致了之后,再来恢复主从同步的操作。
start slave;
重新创建容器后, 新建的容器一直在重启
修改docker镜像版本时, 把容器remove了重建创建, 但是新建的容器却在启动后马上退出了
查看容器日志
发现报错: InnoDB: Table flags are 0 in the data dictionary but the flags in file ./ibdatal are 0x4800!
原来是我remove的容器在宿主机有生成对应的db文件, 这里不需要保留, 直接删除即可, 删除完在docker start 容器名
即可
secure_file_priv
启动容器后, 报以下错误:
failed to access directory for --secure-file-priv. please make sure that directory exists and is accessible by MYSQL Server. Supplied value: /var/lib/mysql-files
这里主要是mysql8.0+的文件路径从原来的/var/lib/mysql
调整为了/var/lib/mysql-files
解决上述报错的方法有:
- 不调整docker-compose内容, 在代码库设置里, 加上
secure_file_priv=/var/lib/mysql
[mysqld] log-bin=mysql-bin server-id=101 secure_file_priv=/var/lib/mysql
- 修改docker启动指令, 调整文件路径映射
docker run -itd --name mysql1 -v /var/mysql/mysqlConf1:/etc/mysql/conf.d -v /var/mysql/mysql1:/var/lib/mysql-files -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql:8.0.18
Error Code: 1872. Slave failed to initialize relay log info structure from the repository
进行主从复制执行start slave时, 报错: Error Code: 1872. Slave failed to initialize relay log info structure from the repository
原因: 之前配置主从时, 已经执行过一次change master to
的命令,这次再次执行change master to
,2次的pos值不一样。
解决方法:可以在从服通过reset slave
重置slave
# 重置slave
reset slave;
# 执行同步
CHANGE MASTER TO MASTER_HOST='IP地址', MASTER_PORT='端口号', MASTER_USER='用户名', MASTER_PASSWORD='密码', MASTER_LOG_FILE='binlog',MASTER_LOG_POS=位置;
# 启动slave
start slave;
# 查看slave状态
show slave status\G;