思路
- 在3台主机上安装mysql
- 进行主从备份配置
使用rpm包yum安装mysql
首先,我们要准备好安装文件,首先下载rpm包
wget -P "/opt/" https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm
然后执行安装(默认已配置阿里云的yum仓库
yum -y install mysql80-community-release-el7-3.noarch.rpm
yum -y install mysql-community-server
可能会有一个关于License的报错,需要运行以下命令导入公钥
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
启动mysql服务,获取初始密码
[root@node21 opt]# systemctl start mysqld
[root@node21 opt]# sudo grep 'temporary password' /var/log/mysqld.log
2024-09-03T09:41:37.074486Z 6 [Note] [MY-010454] [Server] A temporary password is generated for root@localhost: eSklsjq8Lp;8
配置,我们默认只修改密码,开启远程登录,其他配置先不改
mysql -u root -p
ALTER USER 'root'@'localhost' IDENTIFIED BY 'Abc@1234';
update user set user.Host='%' where user.User='root';
flush privileges;
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Abc@1234';
flush privileges;
脚本安装mysql
通过以上手动安装的例子,我们简单写一个安装脚本
#!/bin/bash
# 安装mysql8
# 下载rpm文件
wget https://repo.mysql.com//mysql80-community-release-el7-3.noarch.rpm -P /opt/
# 导入License
rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2023
# 安装mysql
yum -y install /opt/mysql80-community-release-el7-3.noarch.rpm
yum -y install mysql-community-server
# 启动mysql
systemctl start mysqld
init_pw=$(grep 'temporary password' /var/log/mysqld.log | awk '{print $NF}')
new_pw="Abc@1234"
# 设置root密码,会有一个warning,但是修改成功了
mysqladmin -uroot -p"$init_pw" password $new_pw
# 配置允许远程登录
sed -i 's/bind-address/#bind-address/g' /etc/my.cnf
# 更新用户主机
mysql -uroot -p"$new_pw" -e "use mysql;update user set user.Host='%' where user.User='root';flush privileges;"
sleep 2
mysql -uroot -p"$new_pw" -e "ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'Abc@1234';flush privileges;"
# 重启mysql
systemctl restart mysqld
# 开启3306端口
firewall-cmd --zone=public --add-port=3306/tcp --permanent
# 重启一下防火墙服务
firewall-cmd --reload
在从服务器上安装mysql
服务器ip如下
数据库角色 | IP | 系统版本 |
---|---|---|
master | 192.168.32.21 | centos 7.9 |
salve1 | 192.168.32.22 | centos 7.9 |
salve2 | 192.168.32.23 | centos 7.9 |
我们先写一个简单脚本,用来安装mysql,其实就是把上面这个一键安装mysql的shell脚本,发送到22和23两台机器上安装
#!/bin/bash
#将mysql安装脚本发送到指定机器然后安装
# 目标主机 IP 范围
network="192.168.32"
start_ip=22
end_ip=23
# 获取当前日期和时间
current_date=$(date +%Y%m%d)
current_time=$(date +%H%M%S)
# 日志文件名
log_file="${current_date}_${current_time}.log"
# 发送文件并记录结果到日志文件
function send_file() {
local target_ip=$1
local file_path=$2
scp "$file_path" root@"$target_ip":/opt/ &>> "$log_file"
# 检查发送结果并记录到日志文件
if [ $? -eq 0 ]; then
echo "${file_path}文件发送成功到${target_ip}"
echo "${file_path}文件发送成功到${target_ip}" >> "$log_file"
else
echo "${file_path}文件发送失败到${target_ip}"
echo "${file_path}文件发送失败到${target_ip}" >> "$log_file"
fi
}
for ip in $(seq ${start_ip} ${end_ip})
do
target_ip=${network}.${ip}
echo "正在复制文件到 ${target_ip}..."
send_file "$target_ip" "/opt/mysql.sh"
if [ $? -eq 0 ]; then
echo "文件复制成功到 ${target_ip}"
# 执行远程脚本
ssh root@"$target_ip" "source /opt/mysql.sh" >> "$log_file"
else
echo "文件复制失败到 ${target_ip}"
fi
done
echo "运行完成。请查看日志文件 ${log_file} 获取详细结果。"
创建一个示例数据库
接下来回到master数据库进行操作,我们用以下语句建一个数据库,方便后面测试
DROP DATABASE IF EXISTS db_k_shop;
-- -------------------------
-- 建库
-- -------------------------
CREATE DATABASE db_k_shop default character set utf8mb4;
-- ----------------------
-- 建立用户表
-- ----------------------
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`user_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id' ,
`user_name` varchar(255) UNIQUE NOT NULL COMMENT '用户名' ,
`user_pwd` varchar(255) NOT NULL COMMENT '密码' ,
`user_nickname` varchar(255) NOT NULL COMMENT '显示名' ,
`user_mail` varchar(255) NULL COMMENT '邮箱' ,
`user_type` tinyint(1) NOT NULL COMMENT '用户类型' ,
`user_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' ,
PRIMARY KEY (`user_id`)
)
ENGINE=InnoDB
COMMENT='用户信息表'
AUTO_INCREMENT=100000;
-- ----------------------
-- 插入一个用户
-- ----------------------
INSERT INTO `tb_user` (`user_name`, `user_pwd`, `user_nickname`, `user_mail`, `user_type`)
VALUES ('hanayo', 'abc@1234', '花阳亲', 'hanayo@kayotin.cn', '1');
备份和还原数据库
我们需要保证master和slave的数据库是完全一致的,所以首先来备份master的数据,然后还原到slave上。
注意,进行备份和还原操作期间,确保数据库没有写入操作。可以参考如下加上锁。
#全备主库时需要另开一个终端,给数据库加上读锁,避免在备份期间有其他人在写入导致数据不一致
mysql> flush tables with read lock; #此锁表的终端必须在备份完成以后才能退出
Query OK, 0 rows affected (0.00 sec)
#解除主库的锁表状态,直接退出交互式界面即可
mysql> quit
Bye
以下是备份和还原的参考代码:
# 备份数据
backup_name="backup_${current_date}_${current_time}.sql"
mysqldump -uroot -p$pwd --all-databases > "/opt/$backup_name"
# 还原数据
echo "正在复制sql文件到 ${target_ip}..."
scp "/opt/$backup_name" root@"$target_ip":/opt/
echo "正在还原数据库到 ${target_ip}..."
ssh root@"$target_ip" "mysql -uroot -p$pwd < /opt/$backup_name"
在master需要做如下配置
-
首先需要创建salve@目标IP的用户,该用户用来同步数据
# 创建slave用户,授权给从数据库使用 create user 'slave'@'$target_ip' identified by '$pwd'; grant replication slave on *.* to 'slave'@'$target_ip'; flush privileges;"
-
开启bin_log
#主库配置 echo "log_bin=mysql-bin" >> /etc/my.cnf echo "server_id=1" >> /etc/my.cnf # 重启mysql服务 systemctl restart mysqld
-
获取主库状态备用
# 查看主库状态 mysql -uroot -p"$pwd" -e 'show master status;' master_file=$(mysql -uroot -p"$pwd" -e 'show master status;' | awk 'NR==2{print $1}') master_pos=$(mysql -uroot -p"$pwd" -e 'show master status;' | awk 'NR==2{print $2}')
在两个slave需要做如下配置
-
编辑/etc/my.cnf
server-id=2 //设置从库的唯一标识符,从库的server-id值必须小于主库的该值 relay-log=mysql-relay-bin //启用中继日志relay-log
-
运行命令,设置master,启动salve
change master to master_host='192.168.32.21', master_user='slave', master_password='Abc@1234',GET_MASTER_PUBLIC_KEY=1, master_log_file='mysql-bin.000001', master_log_pos=3597; start slave;
注意以上有一个设置GET_MASTER_PUBLIC_KEY=1 这个很重要,否则会报错,导致slave连接不到master。
通过如下语句可以查看slave状态
#查看从服务器状态
mysql> show slave status \G
最终完整脚本如下:
#!/bin/bash
# 备份主数据库数据,还原到备份数据库,配置主从
pwd="Abc@1234"
# 备份数据库
current_date=$(date +%Y%m%d)
current_time=$(date +%H%M)
backup_name="backup_${current_date}_${current_time}.sql"
mysqldump -uroot -p$pwd --all-databases > "/opt/$backup_name"
# 目标主机 IP 范围
network="192.168.32"
start_ip=22
end_ip=23
# 还原数据库
for ip in $(seq ${start_ip} ${end_ip})
do
target_ip=${network}.${ip}
echo "正在复制sql文件到 ${target_ip}..."
scp "/opt/$backup_name" root@"$target_ip":/opt/
echo "正在还原数据库到 ${target_ip}..."
ssh root@"$target_ip" "mysql -uroot -p$pwd < /opt/$backup_name"
# 创建slave用户,授权给从数据库使用
mysql -uroot -p"$pwd" -e "use mysql;create user 'slave'@'$target_ip' identified by '$pwd';
grant replication slave on *.* to 'slave'@'$target_ip';flush privileges;"
done
#主库配置
echo "log_bin=mysql-bin" >> /etc/my.cnf
echo "server_id=1" >> /etc/my.cnf
# 重启mysql服务
systemctl restart mysqld
# 查看主库状态
mysql -uroot -p"$pwd" -e 'show master status;'
master_file=$(mysql -uroot -p"$pwd" -e 'show master status;' | awk 'NR==2{print $1}')
master_pos=$(mysql -uroot -p"$pwd" -e 'show master status;' | awk 'NR==2{print $2}')
master_ip="192.168.32.21"
# 从库配置
salve_id=2
for ip in $(seq ${start_ip} ${end_ip})
do
target_ip=${network}.${ip}
echo "正在配置从库 ${target_ip}..."
ssh root@"$target_ip" "echo 'server_id=$salve_id' >> /etc/my.cnf"
ssh root@"$target_ip" "echo 'relay-log=mysql-relay-bin' >> /etc/my.cnf;systemctl restart mysqld"
sql_txt="change master to master_host='$master_ip',master_user='slave',
master_password='$pwd',master_log_file='$master_file',GET_MASTER_PUBLIC_KEY=1,
master_log_pos=$master_pos;start slave;"
ssh root@"$target_ip" "mysql -uroot -p$pwd -e \"$sql_txt\""
((salve_id++))
done
运行结果如下:
并且经过测试,master数据库中的数据更新后,会自动备份到slave1和slave2中。
完整代码请参考:https://github.com/h-kayotin/hanayo_homework/tree/master/shell脚本/02_mysql安装和主从配置
参考了如下链接:https://cloud.tencent.com/developer/article/2241142