Centos8.3、mysql8.0主从复制实战记录
阅读原文时间:2021年06月22日阅读:1

引言

最近又上线了一个项目,感觉自己这段时间收获不少就想把自己做这个项目用的技术总结梳理一下。这个项目是我自己发起,领导们不是特别重视所以得到资源有限,资源有限的情况我只能选择手动搭建数据库环境,资源充足的情况下还是推荐使用类似PolarDB这种云数据库。原因很多,稳定性好、使用维护简单、扩容方便、还提供一系列的sql审计工具。

环境准备

环境和软件

版本

数量

1

centos

8.3

3

2

mysql

8.0.21

3

安装命令

yum -y install mysql-server # 安装mysql -y 的意思就是安装过程如果需要输入y 可以不用在输入。
systemctl enable mysqld.service # 设置为开启自启
systemctl start mysqld.service # 开启mysql服务

vim  /etc/my.cnf                                        # 编辑mysql配置文件 默认安装是在/etc目录下

skip-grant-tables --shared-memory           # 设置跳过密码 添加到[service-clinet]标签下如下图:

mysql -u root -p                                     # 输入命令 然后回车键跳过密码登录

ALTER USER 'root'@'localhost' IDENTIFIED BY 'jishuzhai';  #添加root用户和密码 注意localhost意味这不能远程登录可以换成% 这里不推荐 建议创建新的账号远程访问

再次编辑 /etc/my.cnf文件注释掉刚才跳过密码那句话

systemctl restart mysqld.service # 重启mysql服务

mysql安装注意事项

安装命令这里只供参考,不过个人推荐使用yum命令安装,这样简单快捷而且方便扩容,不过有一点在生产环境要注意,那就是磁盘初始容量一定要大,最好是冗余的,即使初始化数据容量很小。主从会产生大量的日志文件,磁盘容量很小很容易导致磁盘被写满,那个时候再去扩容需要停机维护。另外数据库备份推荐备份目录为数据盘并且主从数据库都备份。

创建远程访问的账号

CREATE USER 'proxysql'@'%' IDENTIFIED BY 'jishuzhai'; #创建账号
GRANT ALL PRIVILEGES ON *.* TO 'proxysql'@'%' WITH GRANT OPTION; # 赋予权限
flush privileges; # 刷新权限

注意 读取账号只需要主数据库一个就可以了,但是这里为了下一步使用proxysql做读写分离 所以每一个数据库实例都创建了一个账号。

创建测试数据库

CREATE DATABASE brief_test;# 创建数据库

CREATE TABLE `test` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键',
`service_name` varchar(50) NOT NULL COMMENT '自增',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; # 创建测试表

INSERT INTO `test` VALUES (1, 'master');
INSERT INTO `test` VALUES (2, 'slave1');
INSERT INTO `test` VALUES (3, 'slave2'); # 添加测试数据

注意在主库上创建 然后同步到所有从数据库 主从开始前要保证数据一致 不然会绑定失败。

编辑主从数据库配置

登录到主数据的服务器编辑数据库配置文件

将以下配置添加到/etc/my.conf 文件中 如下图

[mysqld]
#配置主库
server_id=1 #服务器id 不能重复 1,2,3,4这种以此类推
log_bin=master-bin
log_bin-index=master-bin.index
binlog-do-db=brief_test #需要同步的数据库名称 配置多个数据库需要配置多个binlog-do-db 例如 binlog-do-db=brief_test1 binlog-do-db=brief_test2 binlog-do-db=brief_test3 这种方式配置

systemctl restart mysqld.service#重启mysql服务

登录到从数据库将以下配置添加到/etc/my.conf文件中如下图

[mysqld]
server_id=2 #服务编号不能重复
read_only=on #设置为只读

systemctl restart mysqld.service #重启mysql服务

最后一步配置主从

(1)登录主数据库 执行 show master status 如下图

记录file 和 position的值从数据库绑定要用的到

(2)登录从数据库执行:

CHANGE MASTER TO MASTER_HOST='172.16.102.7', #主数据库ip
MASTER_PORT=3306, #主数据库端口
MASTER_USER='proxysql', #主数据库复制账号
MASTER_PASSWORD='jishuzhai', #主数据库密码
MASTER_LOG_FILE='master-bin.000001', #刚才从master数据库查询file值
MASTER_LOG_POS=156; #刚才从master数据库查询postition值

然后执行

start slave; #开启slave

然后执行

show slave status;#查看slave状态

正确结果如下图:

常见问题:

show slave status结果slave_io_running 和 slave_sql_running值均为No或者一个为no,我遇到四种情况。

第一种情况是server_id 重复。Mysql 8.0 的 server_id 必须在[mysql]标签下 而且必须在[clinet-servser]配置之前才生效,结果就导致我明明配置server_id 却还是连接失败。针对这种情况可以使用

select @@server_id #查询数据库的server_id 可以看到当前的id

第二种情况是uuid重复 使用虚拟机安装好数据库 然后克隆出slave1、slave2 这种情况uuid也是重复的 导致连接失败。针对这种情况可以手动修改

vim  /var/lib/mysql/auto.cnf 如下图:

随便更改一个字符保持uuid 不重复即可。

第三种情况 主从数据库不一致 主要表现某个应用连接到从数据库并且写入了数据 从数据库虽然设置了只读 但是root权限的账号可以写入。这种情况最麻烦但是好处理。停止所有应用或者设置主数据库锁住 然后把主数据同步到从数据库然后重新连接。

第四种情况 事物回滚导致的 这种情况比少但是好处理

使用以下命令:

STOP SLAVE #先执行关闭语句
SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1;#重置值
START SLAVE #打开语句

关于清理binary日志

主从会产生大量的日志文件 可以使用一下方式自动清理

show binary logs;#查询日志
set GLOBAL binlog_expire_logs_seconds = 1296000 #设置日志过期时间为15天单位秒 超过15的会被自动清除
SELECT @@binlog_expire_logs_seconds #查询是否生效
flush logs;# 立即生效