MySQL 主从复制(Replication)是实现数据高可用、读写分离及异地容灾的核心机制之一。主库写、从库读,提升并发能力;读写分离,减轻主库压力。
本地 windows 系统有一个Linux Ubuntu子系统,版本为Ubuntu 24.04.2 LTS。
想在这个子系统上安装Mysql主从配置,打开官网:https://dev.mysql.com/downloads/mysql/ 进行下载操作。
下载链接有那么多,下载哪个呢?有几个概念也不太理解。
一、什么是DEB
DEB Bundle (捆绑包) 是一组 .deb 文件的压缩包(通常是 .tar.gz),里面包含多个 .deb 安装包。
比如 mysql-8.4.5-debian11-x86_64.deb-bundle.tar 包含了 mysql-common_8.4.5.deb、mysql-community-client_8.4.5.deb、mysql-community-server_8.4.5.deb、mysql-community-libs_8.4.5.deb等等。可以用 tar -xvf 解开看。
.deb 文件里包含了某个软件的二进制可执行文件、配置文件、依赖说明等等。
DEB Package 通常指的是 单个的 .deb 软件包文件。mysql-community-server.deb 是 MySQL 服务端(数据库引擎),mysql-community-client.deb 是 MySQL 客户端程序(mysql命令行工具等),mysql-common.deb 是 共享配置,基础内容。“DEB Package”是最泛指的概念 —— 单个包。
也就是说,一个DEB Bundle 包含了多个deb,不需要那么多可以单独下载某个deb。
二、安装 MySQL8.4.5
MySQL已经升级到9了,选择MySQL8.4.5是因为这是一个长期支持的版本。
DEB 的安装方式:sudo dpkg -i xxx.deb 或 sudo apt install ./xxx.deb。下载单个 Deb包,可能会导致依赖不完整,仅适合临时测试环境,官网建议 apt 方式,那我就试试apt方式。
1、添加 MySQL 官方 APT 仓库
MySQL 的 APT 配置工具包下载地址:https://repo.mysql.com/
# 下载仓库配置包
wget https://repo.mysql.com/mysql-apt-config_0.8.34-1_all.deb
头几次安装都失败了,原因是没找到合适的配置工具包,这次使用0.8.34版本。
# 安装并选择版本
sudodpkg-imysql-apt-config_0.8.34-1_all.deb
少截了一个图片,在第三个对话框中选择OK,否则就进入死循环了。
2、更新软件源并安装
# 更新 APT 软件包列表
sudo apt update
# 安装 MySQL Server 指定版本(注意包名格式)
# sudo apt install mysql-server=8.4.5-1ubuntu24.04sudo apt install mysql-server
在安装的过程中会跳出来密码确认页面:
安装完成后,会在提示信息中看到配置文件的路径:
3、验证安装
# 登录测试
mysql -u root -p
确保 MySQL 服务正常启动并设置开机自启:
#启动 MySQL 服务
sudo systemctl start mysql
#停止 MySQL 服务
sudo systemctl stop mysql
#开机自启
sudo systemctl enable mysql
#禁止开机自启
sudo systemctl disable mysql
#检查服务状态
systemctl status mysql
在安装的时候踩了个大坑,刚开始怎么安装都安装失败,主要原因是配置工具包不是最新的,不是 Ubuntu24.04 支持的版本,但是想想都有Ubuntu对应的bed,怎么会不支持呢?最后找到了配置包的下载地址,换了个配置包就好了。
4、说说配置文件
查看mysql的配置文件,发现这个配置文件很绕、层层嵌套,这无疑加大了主从库配置的难度。
理想状态下的配置文件目录:
/etc/mysql/my.cnf
ubuntu的配置文件:
查看我安装的目录结构:
果真,my.cnf 导入了 /etc/mysql/conf.d/ 和 /etc/mysql/mysql.conf.d/ 这两个文件:
为什么配置文件也要层层嵌套呢?
好像有道理。
为了方便,我决定还是使用 /etc/mysql/my.cnf 这一个配置文件吧。
三、主从复制配置
1、停止现有服务
sudo systemctl stop mysql
2、为mysql创建专属用户和用户组
#创建mysql用户组
groupadd -g 27 mysql#创建该组下的用户
sudo useradd -u 1027 -g mysql mysql-admin#查看用户的id信息
id mysql-admin
3、 创建多实例环境
# 主库目录
sudo mkdir -p /var/lib/mysql-master
# 更改目录权限
sudo chown mysql-admin:mysql /var/lib/mysql-master# 从库目录
sudo mkdir -p /var/lib/mysql-slave
# 更改目录权限
sudo chown mysql-admin:mysql /var/lib/mysql-slave# 更改启动目录下内容的权限
sudo chown mysql-admin:mysql /var/run/mysqld/
4、配置文件统一配置
编辑 /etc/mysql/my.cnf
sudo nano /etc/mysql/my.cnf
/etc/mysql/my.cnf 内容设置如下:
[mysqld_multi]
mysqld=/usr/bin/mysqld_safe # 使用守护进程启动
mysqladmin=/usr/bin/mysqladmin
log=/var/lib/mysqld_multi.log[mysqld1]
# 源服务器(原主服务器)配置
server-id=1
port=3306
# 启用二进制日志
log_bin=/var/lib/mysql-master/mysql-bindatadir=/var/lib/mysql-master
# 主库socket
socket=/var/run/mysqld/mysqld-master.sock
pid-file=/var/run/mysqld/mysqld-master.pid# 需要复制的数据库(可选)
binlog-do-db=rsdun
binlog-do-db=rsdun-circle# 不需要复制的数据库(可选)
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys# 设置日志保留时间(天),7天 = 7×24×60×60 = 604800秒
binlog_expire_logs_seconds=604800# 主服务器默认字符集
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ciuser=mysql-admin[mysqld2]
# 副本服务器(原从服务器)配置
server-id=2
port=3307datadir=/var/lib/mysql-slave
# 从库socket
socket=/var/run/mysqld/mysqld-slave.sock
pid-file=/var/run/mysqld/mysqld-slave.pid# 启用中继日志
relay_log = /var/lib/mysql-slave/relay-log
relay_log_index = /var/lib/mysql-slave/relay-log.index# 从服务器默认字符集
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci# 副本服务器专用设置
read_only=1user=mysql-admin
4. 初始化并启动实例
# 初始化源服务器
sudo mysqld --defaults-file=/etc/mysql/my.cnf --initialize --user=mysql-admin --datadir=/var/lib/mysql-master
# 初始化副本服务器
sudo mysqld --defaults-file=/etc/mysql/my.cnf --initialize --user=mysql-admin --datadir=/var/lib/mysql-slave
# 启动实例
sudo mysqld_multi start# 查看启动情况
sudo mysqld_multi report
根据上面的密码使用客户端修改主从库的密码:
5、主服务器配置
连接主服务器:
mysql -S /var/run/mysqld/mysqld-master.sock -u root
# 或
mysql -u root -p --protocol=TCP -P 3306
创建复制用户
-- 主库创建复制用户
CREATE USER 'repl'@'localhost' IDENTIFIED BY '123456';# 分配复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'localhost';#授权后需要刷新后,才能生效;
flush privileges; # 查看主服务器状态
SHOW BINARY LOG STATUS;
6、从服务器配置
连接从服务器:
mysql -S /var/run/mysqld/mysqld-slave.sock -u root
# 或
mysql -u root -p --protocol=TCP -P 3307-- 从库配置主库信息
CHANGE REPLICATION SOURCE TO SOURCE_HOST='127.0.0.1', SOURCE_PORT=3306,SOURCE_LOG_FILE='mysql-bin.000002',SOURCE_LOG_POS=1207,SOURCE_CONNECT_RETRY=10;# 授权复制用户名密码
START REPLICA USER='repl' PASSWORD='repl_password';# 启动从服务器复制进程
START REPLICA;
# 停止从服务器的复制过程
STOP REPLICA;
# 检查从服务器状态,替代原来的 SHOW SLAVE STATUS
SHOW REPLICA STATUS;
执行这一系列步骤后,同步状态出错了。
出错原因:
大概意思是,mysql8.4.5默认采用的是 caching_sha2_password 插件,要求安全连接(SSL/TLS),而我目前并没有配置SSL。因此呢还需要把同步用户的插件调整为mysql_native_password 插件。
7、开启 mysql_native_password 插件
先停止主从库的服务,在my.cnf增加 mysql_native_password 配置:
mysql_native_password=on
在windows server2008上通过设置mysql_native_password=on就生效了,在这个系统上应该也可以。
主从库都要加这个配置项目,设置后进行重启。
# 重启主从库
sudo mysqld_multi reload 1,2
发现上面这个命令没有用,只能使用最简单粗暴的杀死命令,然后在启动服务器。
# 查找端口号所在pid
sudo lsof -i :3306
# 杀死pid
sudo kill -9 3670
如果还不行,那就重启电脑吧,重启电脑能解决百分之九十的问题。
重启后再次登录主库:
mysql -u root -p --protocol=TCP -P 3306
# 查询同步用户的插件
select host,user,plugin from mysql.user where user='repl';# 修改主库同步用户的插件:
ALTER USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'repl_password' REQUIRE NONE;# 刷新生效
FLUSH PRIVILEGES;
REQUIRE NONE 表示 MySQL 用户账户可以在不加密的连接上进行身份验证和操作。这是 MySQL 用户账户的默认安全要求级别。
四个相关的参数:
REQUIRE NONE:不强制要求加密连接(默认)。
REQUIRE SSL:要求使用 SSL 加密连接。
REQUIRE X509:要求使用有效的 X509 证书。
REQUIRE CIPHER:要求使用特定加密算法 。
从到从库,再把从库的复制操作走一遍:
mysql -u root -p --protocol=TCP -P 3307-- 从库配置主库信息
CHANGE REPLICATION SOURCE TO SOURCE_HOST='127.0.0.1', SOURCE_PORT=3306,SOURCE_LOG_FILE='mysql-bin.000002',SOURCE_LOG_POS=1207,SOURCE_CONNECT_RETRY=10;# 授权复制用户名密码
START REPLICA USER='repl' PASSWORD='repl_password';# 启动从服务器复制进程
START REPLICA;
# 停止从服务器的复制过程
STOP REPLICA;
# 检查从服务器状态,替代原来的 SHOW SLAVE STATUS
SHOW REPLICA STATUS;
最后查看主从配置的状态:
终于配置成功了。
8、在从库上创建后只读用户
CREATE USER 'root_readonly'@'%' IDENTIFIED BY '123456';
# 只读授权
GRANT SELECT ON *.* TO 'root_readonly'@'%';
#执行刷新,刷新后;
flush privileges;
四、最后总结
这次安装一点也不顺利,重装过好多次,有时候是在mysql8.4.5初始化那一步就错了,有时候是在启动的时候报错,反倒是配置主从库的顺利一点。
一方面,对Linux ubuntu系统不熟悉。另一方面,Linux系统对文件的权限管理比较严格。还有一点,最近做事有点不用心
回顾这些次的安装,每次都是文件权限的问题,但是当时没有意识到是文件权限的问题,还以为配置错了,走了很多弯路。
使用Linux系统,一定要特别留意文件夹权限!不要设置错了!
比如说这两个设置目录权限:
# 更改目录权限
sudo chown mysql-admin:mysql /var/run/mysqld
# 更改目录下所有内容的权限
sudo chown mysql-admin:mysql /var/run/mysqld/
这两个命令是不一样的。
第一个命令,最后不带斜杠的,作用于 /var/run/mysqld 这个目录本身(作为一个文件对象),只改变目录本身的 ownership,不影响目录内的内容 。
第二个命令带斜杠的,末尾的斜杠表示这是一个目录路径,在大多数情况下,行为与第一个命令相同(改变目录本身的 ownership),在某些特殊情况下(如当 `/var/ /var/run/mysqld 是符号链接时),行为可能会有不同。