前置准备工作
安装MySQL 8.4.3
- 参考博主之前的文档,在本地Mac安装好MySQL:Mac M2 Pro安装MySQL 8.4.3
- 安装目录:
/usr/local/mysql
,安装好的MySQL都处于运行状态,需要先停止MySQL服务 - 最快的方式:系统设置 → \rightarrow → MySQL → \rightarrow → Stop MySQL Server
设置环境变量
-
向
~/.zshrc
添加如下内容,bashexport MYSQL_BASE=/usr/local/mysql # 在用户目录下创建mysql主从集群目录 export MYSQL_CLUSTER=/Users/xxx/tmp/mysql # 3306端口对应master, 3307端口对应slave, 这里只创建两个节点 export MYSQL_MASTER=${MYSQL_CLUSTER}/3306 export MYSQL_SLAVE=${MYSQL_CLUSTER}/3307
-
执行
source ~/.zshrc
让环境变量生效
创建集群目录
-
创建 "主/从节点" 对应的目录
bash# -p: 自动创建缺失的父目录, -v: 显示创建好的目录名 mkdir -pv $MYSQL_MASTER $MYSQL_SLAVE mkdir -pv $MYSQL_MASTER/data $MYSQL_MASTER/log mkdir -pv $MYSQL_SLAVE/data $MYSQL_SLAVE/log
-
如果环境变量生效,将在
/Users/xxx/tmp/mysql
创建出3306
和3307
端口的对应目录bash# 以master为例 cd $MYSQL_MASTER ls -al # 将显示创建好的data log目录
启动master
新建cnf文件
-
在
$MYSQL_MASTER
目录下新建3306.cnf
文件,内容如下:bash[mysqld] # mysql启动用户 user=mysql # 服务字符集 character-set-server=utf8 # 端口 port=3306 bind-address = 0.0.0.0 # 用于通讯的套接字,由于是一机多实例,所以区分开 socket=/Users/xxx/tmp/mysql/3306/mysql.sock # mysql安装目录 basedir=/usr/local/mysql # 数据存放目录 datadir=/Users/xxx/tmp/mysql/3306/data # master节点唯一标识 server-id=1 gtid_mode=ON enforce-gtid-consistency=true # master-info-repository=TABLE # relay-log-info-repository=TABLE # bin-log前缀 log-bin=master-bin # bin-log-index前缀 log-bin-index=master-bin.index binlog_format=ROW # 开启 mysql_native_password 认证 mysql_native_password=ON [mysqld_safe] # 启动错误日志输出地址(可以改成自己的目录) log-error=/Users/xxx/tmp/mysql/3306/log/err.log
-
修改上述文件为可执行文件:
bashchmod 0755 $MYSQL_MASTER/3306.cnf
初始化master
-
初始化master
bash${MYSQL_BASE}/bin/mysqld --defaults-file=${MYSQL_MASTER}/3306.cnf --initialize-insecure --explicit_defaults_for_timestamp --user=mysql --basedir=${MYSQL_BASE} --datadir=${MYSQL_MASTER}/data
-
如果初始化成功,会有如下提示信息
启动master进程
-
启动master
bash${MYSQL_BASE}/bin/mysqld_safe --defaults-file=${MYSQL_MASTER}/3306.cnf &
-
启动成功后,
ps -ef | grep "mysql" | grep "3306"
命令查看,将新增两个进程
-
同时,在
$MYSQL_MASTER
目录将新增两个套接字相关的文件
-
此时,可以通过root用户、以空密码的方式登录mysql:
mysql -h 127.0.0.1 -u root -p
启动slave
创建cnf文件
-
在
$MYSQL_SLAVE
目录下新建3307.cnf
文件,内容如下:bash[mysqld] # mysql启动用户 user=mysql # 服务字符集 character-set-server=utf8 # 端口 port=3307 # 用于通讯的套接字,由于是一机多实例,所以区分开 socket=/Users/bytedance/tmp/mysql/3307/mysql.sock # mysql安装目录 basedir=/usr/local/mysql # 数据存放目录 datadir=/Users/bytedance/tmp/mysql/3307/data # master节点唯一标识 server-id=2 gtid_mode=ON enforce-gtid-consistency=true log_slave_updates=ON skip-slave-start=1 #master-info-repository=TABLE #relay-log-info-repository=TABLE # bin-log前缀 log-bin=master-bin # bin-log-index前缀 log-bin-index=master-bin.index binlog_format=ROW mysql_native_password=ON [mysqld_safe] # 启动错误日志输出地址(可以改成自己的目录) log-error=/Users/bytedance/tmp/mysql/3307/log/err.log
-
修改上述文件为可执行文件:
bashchmod 0755 $MYSQL_SLAVE/3307.cnf
初始化slave
-
初始化slave
bash${MYSQL_BASE}/bin/mysqld --defaults-file=${MYSQL_SLAVE}/3307.cnf --initialize-insecure --explicit_defaults_for_timestamp --user=mysql --basedir=${MYSQL_BASE} --datadir=${MYSQL_SLAVE}/data
-
slave初始化成功的信息同初始化master,参考上面的截图即可
启动slave进程
-
启动slave
bash${MYSQL_BASE}/bin/mysqld_safe --defaults-file=${MYSQL_SLAVE}/3307.cnf &
-
启动成功后,
ps -ef | grep "mysql" | grep "3307"
命令查看,将新增两个进程
-
同时,在
$MYSQL_SLAVE
目录将新增两个套接字相关的文件
-
此时,可以通过root用户、以空密码的方式登录mysql:
mysql -h127.0.0.1 -P3307 -uroot -p
(截图省略,同master)
开启主从复制
master上的操作
创建主从复制用户
-
(可跳过)为root用户设置密码
sqlalter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '123456'; flush privileges;
-
创建主从复制用户
sqlcreate user 'replica'@'%' identified with 'mysql_native_password' by '123456'; grant replication client,replication slave on *.* to 'replica'@'%'; flush privileges;
-
查看用户信息,查询结果中将包含
replica
用户sqlSELECT User, Host FROM mysql.user;
查看主节点的binlog信息
-
执行如下SQL,查看主节点的binlog信息。主要是获取如下两个坐标,后续设置slave节点时需要使用
sqlmysql> SHOW BINARY LOG STATUS\G; *************************** 1. row *************************** File: master-bin.000003 # 坐标1: 日志文件 Position: 1311 # 坐标2: 日志文件位置 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 8b52fb06-ca82-11ef-a11f-04d82f6466d3:1-5 1 row in set (0.00 sec)
slave上的操作
创建主从复制用户
-
(可跳过)为root用户设置密码
sqlalter user 'root'@'localhost' IDENTIFIED WITH mysql_native_password by '123456'; flush privileges;
-
创建主从复制用户
sqlCREATE USER 'replica'@'%' IDENTIFIED WITH 'mysql_native_password' BY '123456'; grant replication slave on *.* to 'replica'@'%'; FLUSH PRIVILEGES;
-
查看用户信息,查询结果中将包含
replica
用户(截图省略)sqlSELECT User, Host FROM mysql.user;
设置主机节点信息
-
执行如下SQL,设置主节点信息
sqlCHANGE REPLICATION SOURCE TO SOURCE_HOST='127.0.0.1', SOURCE_PORT = 3306, SOURCE_USER='replica', SOURCE_PASSWORD='123456', -- 填写master节点的基本信息 SOURCE_LOG_FILE='master-bin.000003', SOURCE_LOG_POS=1311; -- 使用之前SHOW BINARY LOG STATUS展示的坐标信息
开启主从复制
-
开启主动复制
sqlstart replica;
-
查看主动复制开启是否成功
sqlmysql> show replica status\G; *************************** 1. row *************************** Replica_IO_State: Waiting for source to send event Source_Host: 127.0.0.1 Source_User: replica Source_Port: 3306 Connect_Retry: 60 Source_Log_File: master-bin.000003 Read_Source_Log_Pos: 1311 // 以上显示的信息, 能跟master节点对上 Relay_Log_File: F177XMTP97-relay-bin.000002 ... // 其他信息省略 Last_Errno: 0 Last_Error: // 这里未显示错误, 代表主从复制开启成功 ... // 其他信息省略
验证主从复制
- 上面只是从基本信息看,主从复制开启成功了,还需要具体地验证才靠谱
master上的操作
-
在master节点上新建测试库
sqlcreate database test;
-
并创建一个测试表
sqluse test; create table t(id int primary key ,name varchar(10)); insert into t(id, name) values(1,'hello');
-
查询新插入的数据
slave上的操作
-
登录slave节点,查看刚在master创建的库表
sqlshow database; # 查询测试库中的数据 use test; select * from t;
-
能查询到,表示主从复制工作正常
-
库表信息都没有任何问题,主从复制创建成功 😄
一些问题的解决办法
主动复制开启失败
-
虽然通过
show replica status
未看到错误信息,但是验证主从复制时,发现slave节点上未同步master上的库 -
可能是跟笔者一样,中途为了重新设置master的信息,关闭了replica
-
中途想通过
CHANGE REPLICATION SOURCE TO
重新设置master的信息 -
MySQL报错,提示
bashERROR 3021 (HY000): This operation cannot be performed with a running replica io thread; run STOP REPLICA IO_THREAD FOR CHANNEL '' first.
-
执行
STOP REPLICA IO_THREAD FOR CHANNEL '';
停止了replica
-
-
此时,可以通过
start replica;
重新开启主从复制。如无意外,再次查询slave节点,能查到来自master节点的库表信息 -
如果还不行,可以试试参考博客。注意:需要将博客中的
start slave
改成start replica
:mysql8.0的主从集群架构搭建教程,主从复制原理详解
主从节点的关闭
-
如果遇到初始化失败,或想关闭服务了,最好通过如下方式完整的关闭MySQL服务
bashps -ef | grep "mysqld" | grep "3306" | grep -v grep | awk '{print $2}' | xargs kill -9 # 查看对应端口是否存在tcp监听 lsof -i:3306 kill -9 $PID
后记
- 超级感谢博客,里面使用的各种命令都符合
MySQL 8.4.3
的规则:mysql 8.0 搭建主从集群注意事项 - 其次,感谢博客给的主从复制未开启的解决思路:mysql8.0的主从集群架构搭建教程,主从复制原理详解