当前位置: 首页 > news >正文

MySQL 数据库传统方式部署主从架构的实现很详细

概述(先了解传统的实现在了解docker 和 k8s的部署方式)

  文章内容概述

  • 案例 MySQL 主从配置架构(重点练习)
  • 本人思考的一点问题
  • MySQL主从的排错和解决方案

一,主从复制配置部署
 

环境准备说明

角色

IP

主机名

主库

192.168.1.100

mysql-master

从库

192.168.1.101

mysql-slave


🧱 1. 安装 MySQL(主从都执行)

# 安装 yum 源(以 CentOS 为例)
sudo yum install -y wget
wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
sudo rpm -ivh mysql80-community-release-el7-1.noarch.rpm
sudo yum install -y mysql-server# 启动并设置开机启动
sudo systemctl start mysqld
sudo systemctl enable mysqld# 获取初始密码
sudo grep 'temporary password' /var/log/mysqld.log  # 注意这个只有sentos 有这个文件
# 安装 apt源 (以 ubuntu为例) 如果下面的工具和包都有的话 可以直接使用sudo apt update && apt install mysql-server -y
sudo apt update
sudo apt install -y wget gnupg lsb-release
wget https://dev.mysql.com/get/mysql-apt-config_0.8.29-1_all.deb
sudo dpkg -i mysql-apt-config_0.8.29-1_all.deb
sudo apt update
sudo apt install -y mysql-server
sudo systemctl start mysql
sudo systemctl enable mysql
sudo mysql_secure_installation    # 操作系统初始化   
注意:::生产环境时是需要 初始化的

🏗️ 2. 配置主库 my.cnf

#ubuntu 是 /etc/mysql/mysql.conf.d/mysqld.cnf
sudo vim /etc/my.cnf 

添加如下配置:

[mysqld]
bind-address = 0.0.0.0  #生产环境要注意了,还要做一些安全配置:
server-id=1    # 用于标识 主节点 还是 从节点 注意主从的server-id 的值绝对不能相同。
log-bin=mysql-bin     #binlog日志(log-bin) 的日志前缀 注意这个配置完成后 MySQL 的 /var/lib/mysql 下面会生成名为mysql-bin.000001的二进制文件 
binlog_format=ROW     #逐行复制主从服务
# 开启 GTID 模式(推荐)
gtid_mode=ON          #开启主从服务::
enforce_gtid_consistency=ON   #

然后重启服务:

sudo systemctl restart mysqld

🧑‍🔧 3. 主库创建复制用户

-- 登录主库
mysql -uroot -p-- 创建复制用户(强烈建议使用强密码)创建一个 repl用户只允许来自 192.168.1.0/24(%) 网段连接 是  设置密码 repl123!
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'repl123!';授予从库可以到主库 复制的命令的权限 ,所有库所有表。。。
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
FLUSH PRIVILEGES;-- 查看当前二进制日志信息(用于传统复制,不是 GTID)
SHOW MASTER STATUS;-- 或查看 GTID 状态(用于 GTID 模式复制)
SHOW GLOBAL VARIABLES LIKE 'gtid_mode';

🛠️ 4. 配置从库 my.cnf

sudo vim /etc/my.cnf

添加:

[mysqld]
server-id=2  # 不能和主重复
relay_log=relay-log  #中继日志的文件前缀 他是和主的binlog进行配合的日志(其实我理解的他们都是二进制日志的存储日志) 通常是 /var/lib/mysql/ 
log_bin=mysql-slave-bin #从库生成自己的 binlog 是在从库上开启 binlog 功能的配置,常用于支持级联复制、GTID 主从切换、主从对等转换等场景,是从库“升级为主库”的基础前提
gtid_mode=ON   # gtid 开启
enforce_gtid_consistency=ON 

重启:

sudo systemctl restart mysqld

🔄 5. 配置从库复制主库

-- 登录从库
mysql -uroot -p-- 停止已有复制(如果配置过)
STOP SLAVE;-- 配置复制
CHANGE MASTER TOMASTER_HOST='192.168.1.100',MASTER_PORT=3306,MASTER_USER='repl',MASTER_PASSWORD='repl123!',MASTER_AUTO_POSITION=1;  -- GTID 必须配置:告诉从库:使用 GTID 模式来自动定位主库同步点,不再使用 binlog 文件名 + 位置(file + pos)来定位复制位置。解释!!!
注意: 使用 MASTER_AUTO_POSITION=1 的前提条件
条件	要求
主从都启用了 GTID	gtid_mode=ON,enforce_gtid_consistency=ON
主库开启了 binlog	log_bin=xxx
从库开启了 log_bin + log_slave_updates(建议)	便于主从切换
复制账号权限正确	REPLICATION SLAVE 权限
主从 server-id 不一样	否则冲突
MASTER_AUTO_POSITION=1 是 GTID 模式复制的标志性配置,它告诉从库“自动根据 GTID 接着复制”,省去了手动指定位置的麻烦。
必须为 1,才能启用
不用再配置 binlog 文件名和位置(file/pos)是高可用复制和自动故障切换的基础设置之一-- 启动复制
START SLAVE;-- 查看复制状态
SHOW SLAVE STATUS\G

🔍 重点关注字段:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes

只要这两个都是 Yes,就表示主从复制成功 ✅


📌 补充建议

项目

建议

防火墙

开放 3306 端口(主库必须对从库可访问)

SELinux

测试环境建议关闭 setenforce 0

主从一致性检查

可以使用 pt-table-checksum

工具

数据初始化

大数据量建议用 mysqldump + --set-gtid-purged=ON


🧪 测试主从是否同步

在主库执行:

CREATE DATABASE test_db;
USE test_db;
CREATE TABLE users (id INT PRIMARY KEY, name VARCHAR(50));
INSERT INTO users VALUES (1, '张三');

在从库:

USE test_db;
SELECT * FROM users;

看到数据说明同步成功!
 

二,个人问题:


我有几个问题

1,为什么要从新获取 MySQL 的安装包 用 yum 中自带的不可以吗 (太老)

2,msyql 一定要获取密码登录吗,不可以用mysql -u 直接登录吗 (不能)

3,sudo grep 'temporary password' /var/log/mysqld.log 这种获取密码登录 默认是用root 登录的吗 ?(是的)

 

1. 为什么要重新获取 MySQL 安装包?不能用 yum 自带的吗?

总结:自带的太老,可能和环境不太匹配

✅ 回答:

默认 yum 源(比如 CentOS 自带的 base)里的 MySQL 版本比较旧(比如 5.7、5.6),不一定适配你当前环境需求。

🔧 具体情况说明:
  • 默认源:
yum list | grep mysql

可能只显示 mysql-libsmariadb(不是官方MySQL!)

  • 通过添加官方源:
wget https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm
rpm -ivh mysql80-community-release-el7-1.noarch.rpm

这样可以获得:

    • 最新的 MySQL 8.0.x
    • 自动拉取依赖
    • 长期更新支持(适合生产)
🧠 建议:

测试环境可以临时用 yum 默认的;但正式部署一定推荐用官方源tar.gz 二进制包部署,这样版本、配置可控。


🔍 2. MySQL 一定要获取密码登录吗?不能 mysql -u root 就登录吗?

注意 :这个问题 只有 sentos 才有/var/log/mysqld.log 文件 去读取 初始密码
ubuntu 是没有的但是 ubuntu的mysql安装包 安装完成 是可以直接 mysql 登录的(因为他设置auth_sokect )不需要密码 但是两种系统化再生产环境时都需要 初始化!!! 操作才行。

回答:

默认情况 是需要密码的,不能直接 mysql -u root 登录,尤其是在 MySQL 5.7 及以后版本。

🔐 原因说明:
  • MySQL 5.7 开始,安装后会自动生成一个 root 初始密码,为了安全。
  • 必须通过 grep 'temporary password'/var/log/mysqld.log 读取这个初始密码。
  • 登录后系统会强制你修改密码(否则无法执行任何命令)。
🎯 示例:
mysql -uroot
# 会报错:ERROR 1045 (28000): Access denied for user 'root'@'localhost'...

🔍 3. grep 'temporary password' 查到的密码是哪个用户的?默认是 root 吗?

✅ 回答:

是的,查到的临时密码是 root@localhost 的初始登录密码

示例输出:
2025-06-29T08:31:23.123456Z 1 [Note] A temporary password is generated for root@localhost: 9fE>mhU8#aVz

✔️ 说明:

  • 这是 MySQL 安装完成时自动生成的 root 账户密码。
  • 登录后你需要执行:
ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';

🚀 补充建议(实战角度):

项目

建议

安装方式

正式环境可考虑用二进制方式部署(更干净更灵活),你会学到很多系统知识

密码管理

建议用密码保存在运维自动化工具(如 Ansible Vault 或 secrets)中

提权方式

有时候 root@localhost 不能远程连接,要用 %

或特定 IP 授权访问


问题四
没明白 读写分离不应该 是一个读一个写吗,我们说 msyql 从库 是用来读的 ,主库是用来写的 那么 我们是 让后端程序 访问 从库对吗
 

总结:MySQL的主从复制的原理:是满足了 1,读写分离 2,主从复制 数据备份 3,高可用
他是由 开发编写的 连接主还是从 ------

操作场景

访问哪个库?

原因

查询历史列表、公共数据

从库

读压力大,数据同步慢无所谓

提交表单后立即查询、个人资料等

主库

避免主从延迟引发数据不一致

写操作

主库

只能写主库(主从复制是单向的)


问题核心是:

“读写分离是不是就是让后端程序访问从库来读,访问主库来写?”

答案是:**是的,本质上就是这样!**但实现上有一些“套路”我们来细说:


📌 一句话解释什么是读写分离

👉 后端程序中的读操作(SELECT)发往从库,写操作(INSERT/UPDATE/DELETE)发往主库。

为什么要这么做?为的是减轻主库压力,提升系统整体性能。


✅ 那谁来判断“读”和“写”呢?

有三种选择:

实现方式

谁判断 SQL 是读还是写?

方式一:程序代码自己分流

程序员自己判断,写操作用主库连接,读操作用从库连接

方式二:中间件分流

中间件自动判断,例如 ProxySQL、MyCat

方式三:ORM 框架支持

框架帮你判断,如 MyBatis-Plus、ShardingSphere


💡 举个最简单的例子(程序员自己判断方式):

# 假设你有两个连接:一个连主库,一个连从库
conn_master = connect(host="主库IP", user="xxx", ...)
conn_slave = connect(host="从库IP", user="xxx", ...)# 写入数据:走主库
cursor = conn_master.cursor()
cursor.execute("INSERT INTO users(name) VALUES ('白先生')")# 读取数据:走从库
cursor = conn_slave.cursor()
cursor.execute("SELECT * FROM users")

就是这么简单!

你可以在程序里封装一下,用统一接口判断是否是读或写,内部自动选择库连接。


🧠 那么问题来了:是不是所有读操作都可以走从库呢?

❗不是的,有例外!最典型的:

1. 用户刚提交表单(INSERT)
2. 页面立刻跳转查询用户数据(SELECT)

如果这时从库还没同步完数据,用户看到的就是“旧数据”或“查无此人”。


✅ 所以实际中会这样分流:

操作场景

访问哪个库?

原因

查询历史列表、公共数据

从库

读压力大,数据同步慢无所谓

提交表单后立即查询、个人资料等

主库

避免主从延迟引发数据不一致

写操作

主库

只能写主库(主从复制是单向的)


读写分离就是:

  • 主库负责写
  • 从库负责读
  • 程序(或中间件)决定 SQL 该走哪台机器

问题四:从库是怎么 在主库获取信息的

一句话总结:

从库通过网络连接主库的 MySQL 协议 接口,用专用的复制账号(如 repl),拉取主库的 binlog(事务日志)来同步数据。

就是这句话的作用

CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_AUTO_POSITION=1;


✅ 详细过程分解(关键点 + 技术细节)

我们从「谁干了什么」的角度讲清楚 👇


✅ 第一步:从库发起连接主库

从库的 IO 线程⤷ 使用账号:'repl'@'主库IP'⤷ 使用命令:COM_BINLOG_DUMP(MySQL 协议内的指令)⤷ 发起 TCP 连接 到主库的 3306 端口

📌 这个连接行为相当于:

CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='xxx', MASTER_AUTO_POSITION=1;

✅ 如果使用 GTID,同步点是“从库本地已执行的 GTID”
❌ 如果用传统复制,需要指定 binlog 文件名和位置


✅ 第二步:主库授权验证,确认可以复制

主库检查:

  • mysql.user 表中是否有 'repl'@'从库IP'
  • 是否具有 REPLICATION SLAVE 权限
  • 是否允许连接(例如防火墙、bind-address 配置)

验证通过后,主库就开始 发送 binlog 日志流


✅ 第三步:主库发送 binlog 数据包

主库将 binlog 内容以 网络数据包形式(通过 MySQL 协议)发送给从库的 IO 线程。

例如:

INSERT INTO users(name) VALUES ('白先生');

对应 binlog event 会被“打包发送”给从库。


✅ 第四步:从库 IO 线程写入中继日志(relay log)

从库本地会生成:
- relay-log.000001
- relay-log.000002

这些是 binlog 的本地副本,中继日志(relay log),方便断点续传和故障恢复。


✅ 第五步:SQL 线程读取 relay log,执行

从库的 SQL 线程会解析 relay log 中的事件,把里面的操作在从库本地一条条重放出来,变成从库的真实数据。

📌 相当于“主库执行过的操作,我在从库也执行一遍”,保持数据一致 ✅


🧠 补充知识点

项目

说明

binlog 格式

ROW

(推荐),STATEMENT

MIXED

GTID 复制

从库根据 GTID 自动判断从哪开始同步

网络协议

基于 MySQL 原生协议的 COM_BINLOG_DUMP / DUMP_GTID

延迟查看

Seconds_Behind_Master

查看主从同步延迟

文件查看

SHOW RELAYLOG EVENTS;

可以查看 relay log 内容


✅ 主从复制示意图:

             (写操作)
客户端  ─────> 主库(写入 binlog)│┌────────────┘▼从库 IO 线程│ 拉取 binlog▼relay log(本地副本)│▼SQL 线程 读取并执行│▼数据同步完成!

🛠 总结:

步骤

描述

1. 建立连接

从库用 CHANGE MASTER TO

指定主库、账号

2. 授权验证

主库验证复制账号的权限

3. 拉取 binlog

主库将 binlog 实时推送给从库

4. 写入 relay log

从库 IO 线程保存为本地中继日志

5. 执行 relay log

SQL 线程重放日志,实现同步

问题五 MySQL初始化 初始了什么东西

初始化 都完成了那些操作。我不进行初始化直接 用alter 命令修改 root 密码直接使用可以吗


🎯 问题回顾

Ubuntu 安装 MySQL 后,不运行 mysql_secure_installation,直接使用 ALTER USER 来修改 root 密码,这样可以吗?会不会有问题?


完全没问题!
你可以跳过 mysql_secure_installation,直接使用 ALTER USER 修改 root 密码并生效使用。


🔍 但重点在于:你还缺少了一些安全初始化工作

我们来详细看看:


🧱 一、mysql_secure_installation 这个命令都做了什么?

它不是必须的,但做了很多安全方面的“善后处理”,包括:

步骤

功能

建议

✔ 设置 root 密码

如果没设置

强烈推荐

❌ 移除匿名用户

关闭匿名访问

安全考虑必须做 ✅

❌ 禁止 root 远程登录

关闭远程 root

非必要建议关闭

❌ 删除测试数据库

删除 test 数据库

没用可以删掉

✔ 刷新权限表

应用以上修改

必须做 ✅


✅ 所以,如果你直接用 ALTER USER 修改密码:

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourPassword123!';
FLUSH PRIVILEGES;

你只是完成了 “设置密码” 这一步


🧠 二、那是否建议直接改密码而跳过初始化?

✅ 开发/测试环境:

  • 直接用 ALTER USER 没问题
  • 甚至可以不设密码,用 auth_socket 登录更方便

❗ 生产环境(强烈建议):

  • 🔒 一定要执行 mysql_secure_installation
  • 防止被匿名用户登录、root 被远程爆破、test 数据库泄漏等问题
  • 它其实是“安全初始化向导”,不是功能必须,但安全必须

🧪 三、最佳实践推荐操作流程(Ubuntu 安装后)

# 1. 登录数据库(当前是 root 用户,可以免密)
sudo mysql# 2. 改 root 密码 + 切换认证方式
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'YourStrongPass!';FLUSH PRIVILEGES;
exit;# 3. 启动安全初始化流程(建议!)
sudo mysql_secure_installation
# 对匿名用户、远程 root、test 库一键清理

📌 总结一句话:

直接用 ALTER USER 改密码是没问题的 ✅,但你跳过了 mysql_secure_installation 的安全优化步骤,在生产环境中还是建议执行一下 

三,排错和解决方案

🛠️ MySQL 主从复制故障排查清单(错误 → 原因 → 解决方法)

错误/症状

可能原因

解决方法

ERROR 1130 (HY000): Host 'xxx' is not allowed to connect to this MySQL server

没有授权从库 IP 或 GRANT

用户不存在

✅ 在主库上执行:
CREATE USER 'repl'@'从库IP' IDENTIFIED BY 'repl123';


GRANT REPLICATION SLAVE ON *.* TO 'repl'@'从库IP';


FLUSH PRIVILEGES;

❌ 从库连接主库失败,ERROR 2003 (HY000): Can't connect to MySQL server on '主库IP'

主库未监听外网(bind-address设置不对)

✅ 修改主库配置:bind-address = 0.0.0.0


重启服务后再测试连接

❌ 无法连接主库(端口被拒绝)

主库的防火墙未开放 3306 端口

✅ 执行防火墙命令:
sudo ufw allow 3306

(Ubuntu)
firewall-cmd --add-port=3306/tcp --permanent && firewall-cmd --reload

(CentOS)

SHOW SLAVE STATUS\G

中:
Slave_IO_Running: No


Last_IO_Error: ERROR: Access denied for user 'repl'@'xxx'

repl

用户密码错误或无权限

✅ 确保 CHANGE MASTER TO

中的密码正确
✅ 重新授权 repl 用户

Slave_SQL_Running: No

且有 Duplicate entry

错误

主从数据不一致

✅ 使用 SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1; START SLAVE;

暂时跳过
⚠️ 推荐重新同步主从数据

Got fatal error 1236: "Could not find first log file name in binary log index file"

从库指定的 binlog 文件不存在或已被主库清理

✅ 使用新的 MASTER_LOG_FILE

+ MASTER_LOG_POS

重新配置
或用 mysqldump

同步后重新开始复制

Server id conflicts

主库和从库的 server-id

相同

✅ 修改从库配置文件:
server-id = 2

(必须唯一)
然后重启服务

❌ 主库未开启 binlog,无法同步

主库未配置 log-bin

✅ 修改主库配置:
log-bin = mysql-bin


+ server-id = 1


重启服务

❌ 从库无法获取主库 GTID 信息

主库未启用 gtid_mode

✅ 主库开启:
gtid_mode = ON


enforce-gtid-consistency = ON


重启服务

ERROR 1201: Could not initialize master info structure

relay-log

损坏或权限问题

✅ 停止复制:STOP SLAVE;


删除 relay-log*

文件后再 START SLAVE;


✅ 附加建议(持续监控 + 守护)

工具

用途

建议

SHOW SLAVE STATUS\G

查看主从复制状态

经常用来看 Slave_IO_Running

/ Slave_SQL_Running

状态

Zabbix / Prometheus

监控主从复制延迟与状态

使用 Seconds_Behind_Master

指标预警

shell 脚本守护进程

自动检测复制异常并发邮件/钉钉告警

定期运行 `show slave status\G


🧩 提示:主从复制健康状态检查三项核心指标

项目

理想状态

Slave_IO_Running

Yes ✅

Slave_SQL_Running

Yes ✅

Seconds_Behind_Master

0 或接近 0 ✅(否则是延迟)



 

http://www.xdnf.cn/news/1081729.html

相关文章:

  • React Native 亲切的组件们(函数式组件/class组件)和陌生的样式
  • 若 VSCode 添加到文件夹内右键菜单中显示(通过reg文件方式)
  • 盘式制动器的设计+说明书和CAD)【6张】+绛重
  • Redis性能优化
  • 权电阻网络DAC实现电压输出型数模转换Multisim电路仿真——硬件工程师笔记
  • 前端捕获异常的全面场景及方法
  • Linux操作系统之文件(三):缓冲区
  • 每天一个前端小知识 Day 21 - 浏览器兼容性与 Polyfill 策略
  • 【每天一个知识点】动态知识库
  • JxBrowser 8.9.0 版本发布啦!
  • chrome插件合集
  • vue/微信小程序/h5 实现react的boundary
  • 智能电动汽车系列 --- 车载软件开发思想与已有OEM现状碰撞
  • vue-39(为复杂 Vue 组件编写单元测试)
  • 设计模式(十)
  • 区块链技术核心组件及应用架构的全面解析
  • Dash 安装使用教程
  • 程序计数器(PC)是什么?
  • Linux入门篇学习——Linux 帮助手册
  • 版本控制器SVN
  • 基于区块链的物联网(IoT)安全通信与数据共享的典型实例
  • 三体融合实战:Django+讯飞星火+Colossal-AI的企业级AI系统架构
  • Abase和ByteKV存储方案对比
  • [C++] C++多重继承:深入解析复杂继承关系
  • 怎么更改cursor字体大小
  • github上部署自己的静态项目
  • XILINX Kintex 7系列FPGA的全局时钟缓冲器(BUFG)和区域时钟缓冲器(BUFR/BUFH)的区别
  • hello判断
  • WPF学习笔记(23)Window、Page与Frame、ViewBox
  • 「Java案例」鸡兔同笼问题