MySQL|从理论、安装、备份到主从复制、MHA高可用详解
摘要:本文系统梳理 MySQL 从理论到高可用的完整知识体系。内容涵盖数据库基础理论(数据分类、三大范式、SQL 五大语言分类)、MySQL 介绍与源码编译安装、SQL 核心语法(库表操作、DML/DQL、用户权限与数据类型)、备份与恢复(物理冷备份、mysqldump 逻辑备份、binlog 增量备份)、主从复制原理与配置、Amoeba 读写分离中间件,以及 MHA 高可用架构。通过一主两从 + MHA 的实战部署,帮助读者掌握 MySQL 运维的核心技能,实现数据安全与业务高可用。
一、数据库基础理论
1、数据分类
- 结构化数据:可以用二维表存储,如数据库表,先定义结构再存数据。
- 半结构化数据:JSON、XML,结构和数据在一起。
- 非结构化数据:音视频、图片,整体二进制存储。
2、DB、DBMS、DBA概念
- DB(Database):数据库,大量有组织可共享的数据集合。
- DBMS(Database Management System):数据库管理系统,操纵管理数据库软件,MySQL、Oracle属于RDBMS关系型数据库。
- DBA:数据库管理员,负责数据库稳定、安全、备份、高可用。
DBMS七大功能
- DDL数据定义:定义库、表结构
- DML数据操纵:增删改查
- 数据组织存储管理
- 运行管理:并发、事务、安全校验
- 数据库维护:导入导出、监控
- 四大保护:恢复、并发控制、完整性、安全性
- 通信交互
3、E‑R模型与实体关系
E‑R三要素:实体、属性、联系 实体之间3种关系:
- 一对一 1:1:人‑身份证
- 一对多 1:N:班级‑学生
- 多对多 M:N :学生‑选课;必须建立中间关联表拆解多对多
4、数据库三大范式⭐⭐⭐
范式越高,冗余越小,表数量越多,生产环境做到3NF第三范式即可。
| 范式 | 核心 | 规则 |
|---|---|---|
| 1NF | 原子性 | 字段值不可再拆分,一列只存一个值,不能存列表 |
| 2NF | 消除部分依赖 | 针对复合主键;所有非主键字段必须完全依赖整个主键,不能只依赖主键一部分 |
| 3NF | 消除传递依赖 | 非主键字段之间不能互相依赖;不能A→B→C间接依赖主键 |
1NF→2NF:先满足1NF,消除部分主键依赖; 2NF→3NF:先满足2NF,消除字段之间传递依赖。
5、SQL五大语言分类
| 分类 | 全称 | 作用 | 关键字 |
|---|---|---|---|
| DDL | 数据定义语言 | 定义库、表结构 | CREATE DROP ALTER |
| DML | 数据操纵语言 | 操作表里数据增删改 | INSERT DELETE UPDATE |
| DQL | 数据查询语言 | 查询数据 | SELECT |
| DCL | 数据控制语言 | 权限管理 | GRANT REVOKE |
| TCL | 事务控制语言 | 事务提交回滚 | BEGIN COMMIT ROLLBACK |
区分:DDL操作结构;DML操作表里存储的数据。
二、MySQL介绍与安装
1、MySQL历史与分支
- MySQL:Oracle公司维护。
- MariaDB:MySQL创始人Monty开发,开源社区驱动,很多Linux发行版默认使用。
- Percona Server:完全兼容MySQL,内置XtraDB引擎,性能、崩溃恢复、在线备份增强。
MySQL架构:C/S架构,客户端+服务端。
- 服务端核心程序:
mysqld;mysqld_safe守护启动脚本。 - 客户端工具:
mysql交互式命令行;mysqladmin管理工具;mysqldump逻辑备份。
注意区分客户端命令和SQL服务端命令:
- 客户端命令本地执行:
\G \g \s source use quit等,不需要发给服务端;- SQL语句发送给mysqld执行,以分号
;结尾。
2、MySQL5.7源码编译安装
环境CentOS7,编译依赖:
gcc gcc‑c++ cmake bison ncurses‑devel
-
创建系统运行账号:
useradd -s /sbin/nologin mysql -
解压mysql源码 + boost依赖库(5.7编译必须boost)
-
cmake配置,重点参数:安装路径、数据目录、字符集、开启存储引擎、生成systemd服务文件。
⚠️cmake报错,必须删除源码目录
CMakeCache.txt缓存文件,再重新cmake。 -
make && make install编译安装。 -
修改目录权限归属mysql用户。
-
修改
/etc/my.cnf配置文件,分[client] [mysql] [mysqld]段。 -
设置环境变量,识别mysql命令。
-
初始化数据库
#--initialize‑insecure:生成空root密码
bin/mysqld --initialize-insecure --user=mysql --basedir=xxx --datadir=xxx
datadir目录初始化之前必须为空!
- 复制systemd服务单元文件,
daemon‑reload,启动开机自启。- 设置root密码,授权远程登录账号。
3、MySQL多实例
一台服务器运行多个mysqld进程,监听不同端口(3306、3307),各自独立配置、独立数据目录。
- 优点:节约硬件,测试环境方便对比版本参数。
- 缺点:资源抢占;服务器宕机所有实例全部故障,存在单点风险。
三、SQL核心语法
1、字符集与排序规则
MySQL8.0默认字符集**utf8mb4**,真正完整支持4字节emoji。
utf8在mysql中最多3字节,不能完整存储所有中文和表情。
xxx_general_ci:不区分大小写;xxx_bin二进制区分大小写。
2、库操作
SHOW DATABASES;
CREATE DATABASE IF NOT EXISTS school DEFAULT CHARACTER SET utf8mb4;
ALTER DATABASE school CHARACTER SET utf8mb4;
DROP DATABASE IF EXISTS school;
3、表操作DDL
--建表
CREATE TABLE info(
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name CHAR(20) NOT NULL,
score DECIMAL(5,2),
address VARCHAR(50) DEFAULT '南京'
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
DESC info; --查看表结构
SHOW CREATE TABLE info; --查看建表语句
ALTER TABLE info ADD COLUMN phone VARCHAR(11); --增加字段
ALTER TABLE info MODIFY COLUMN phone CHAR(11); --修改字段类型
ALTER TABLE info CHANGE COLUMN phone mobile char(11); --改字段名+类型
ALTER TABLE info DROP COLUMN mobile; --删除字段
ALTER TABLE info RENAME TO new_info; --修改表名
DROP TABLE IF EXISTS info;
复制表两种方式
create table t2 select * from t1;复制表结构+数据,丢失主键索引。create table t2 like t1;只复制表结构,不带数据。
4、DML增删改
--插入
INSERT INTO info(name,score) VALUES ('张三',90),('李四',88);
--更新⚠️不加WHERE更新全表!
UPDATE info SET score=95 WHERE id=1;
--删除⚠️不加WHERE清空整张表
DELETE FROM info WHERE id=2;
--清空表两种
DELETE FROM info; --DML,可回滚,不会重置自增主键
TRUNCATE TABLE info; --DDL,不可回滚,重置自增,速度快
生产环境业务一般逻辑删除 :增加
is_del标记字段,update标记删除,不执行物理delete。
5、DQL查询SELECT
关键字顺序:SELECT → FROM → WHERE → GROUP BY → HAVING → ORDER BY → LIMIT
- WHERE:分组之前过滤原始数据;
- HAVING:分组聚合之后过滤结果;
LIMIT offset,countoffset从0开始;- 聚合函数
count() sum() max() min() avg(),忽略NULL。 - NULL判断:必须
IS NULL / IS NOT NULL,不能用=NULL。 - 模糊查询
LIKE %任意字符 _单个字符。
6、多表连接查询
- 内连接INNER JOIN:只返回两边匹配交集。
- 左连接LEFT JOIN:保留左表全部,右表匹配不到为NULL。
- 右连接RIGHT JOIN:保留右表全部,左表匹配不到为NULL。
- MySQL没有FULL JOIN全外连接,用
LEFT JOIN UNION RIGHT JOIN模拟。 - 自连接SELF JOIN:一张表别名当做两张表,适合上下级、邀请人业务。
UNION自动去重;UNION ALL不去重,性能更高,优先使用。
多表查询一定要写关联条件,否则产生笛卡尔积,数据爆炸。
7、用户与权限DCL
MySQL账号格式:'用户名'@'主机',用户名+主机组合才是唯一账号 ,host支持通配符%。
CREATE USER 'appuser'@'192.168.%' IDENTIFIED BY '123456';
ALTER USER 'appuser'@'192.168.%' IDENTIFIED BY 'newpass';
DROP USER 'appuser'@'192.168.%';
--授权
GRANT SELECT,INSERT ON school.* TO 'appuser'@'192.168.%';
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' WITH GRANT OPTION;
--回收权限
REVOKE DELETE ON school.* FROM 'appuser'@'192.168.%';
SHOW GRANTS FOR 'appuser'@'192.168.%';
FLUSH PRIVILEGES; --手动重载权限表
MySQL8.0不再支持grant同时创建用户,必须先create user再grant。
8、数据类型
- 数值 :
TINYINT INT BIGINT整数;金额小数用DECIMAL(M,D)定点数,不要用float/double(精度丢失)。 - 字符串 :
CHAR(n)定长;VARCHAR(n)可变长;TEXT大文本。 - 时间 :
DATE DATETIME TIMESTAMP YEAR TIME - 约束:
NOT NULL DEFAULT PRIMARY KEY AUTO_INCREMENT UNSIGNED
四、MySQL备份与恢复⭐⭐⭐
数据丢失原因
程序bug、人为误操作、硬件磁盘故障、火灾地震灾难。
备份分类
-
物理备份
:直接备份磁盘数据文件
- 冷备份:数据库关闭状态,tar打包data目录;速度快;必须停库。
- 热备份:数据库运行,依靠binlog日志。
- 温备份:锁表,可读不可写。
-
逻辑备份 :导出SQL语句,数据库不停机,代表工具
mysqldump。 -
增量备份:基于全量备份 + binlog二进制日志。binlog记录DDL/DML,select查询不记录。
1、物理冷备份
#备份
systemctl stop mysqld
tar czf /backup/mysql-data-$(date +%F).tar.gz /usr/local/mysql/data/*
systemctl start mysqld
#恢复
systemctl stop mysqld
rm -rf /usr/local/mysql/data
mkdir /usr/local/mysql/data
tar xzf xxx.tar.gz -C /usr/local/mysql/data
chown -R mysql:mysql /usr/local/mysql/data
systemctl start mysqld
坑:不要只
rm -rf data/*,空data目录启动mysql会自动初始化,系统表损坏。
2、mysqldump逻辑备份
#单个库
mysqldump -uroot -p school > school.sql
#多个库 --databases
mysqldump -uroot -p --databases school mysql > two.sql
#全部数据库
mysqldump -uroot -p --all-databases > all.sql
#单张表
mysqldump -uroot -p school info > info.sql
逻辑恢复两种方式:
#shell管道
mysql -uroot -p school < school.sql
#mysql内部source
mysql> use school;
mysql> source /backup/school.sql;
3、增量备份(mysqldump全量 + binlog二进制日志)
-
my.cnf
mysqld段开启log‑bin=mysql‑bin,必须配置server‑id。
log‑bin不能写在
[client]段,会客户端报错。 -
先做mysqldump全量备份,代表基准时间点。
-
mysqladmin -uroot -p flush‑logs切割binlog,生成新日志文件,划分备份边界。 -
业务操作变更全部写入新binlog。
-
故障恢复:先导入全量备份,再回放binlog增量日志。
#解码查看binlog,仅阅读,恢复不能带这些参数
mysqlbinlog --base64-output=decode-rows -v mysql-bin.000003#回放恢复(不要解码参数)
mysqlbinlog mysql-bin.000003 | mysql -uroot -p
如果binlog包含误删操作,不能完整回放,需要通过position偏移跳过故障点位。 生产建议binlog和数据文件部署不同磁盘,防止磁盘损坏全部丢失。
五、MySQL主从复制
原理三大组件
- 主库binlog二进制日志:记录所有写操作。
- 从库IO线程:连接主库,拉取binlog,写入本地relay‑log中继日志。
- 从库SQL线程:读取relay‑log,重放SQL,同步数据。
完整流程:
- 主库执行insert/update/delete,写入binlog。
- 从库IO线程请求主库binlog。
- 主库dump线程推送binlog事件。
- IO线程写入从库本地中继日志relay‑log。
- SQL线程读取中继日志,执行SQL,实现数据同步。
✅健康状态判断:show slave status\G; Slave_IO_Running: Yes AND Slave_SQL_Running: Yes;Seconds_Behind_Master=0无延迟
末尾
No query specified是\G格式化输出提示,不是报错。
限制:从库SQL线程串行回放,主库可以并行写,会产生主从延迟。
主库配置
[mysqld]
server-id=11 #集群所有实例id唯一,不能重复
log-bin=master-bin
log-slave-updates=true #从库产生的更新也写入binlog,用于链式复制
重启mysql;创建复制账号;
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.%' IDENTIFIED BY '123456';
FLUSH PRIVILEGES;
SHOW MASTER STATUS; --记录File和Position给从库使用
从库配置重点⚠️
虚拟机克隆出来的从库,data目录
auto.cnf存储UUID,克隆后UUID全部一致,复制直接报错!
systemctl stop mysqld
rm -f /usr/local/mysql/data/auto.cnf
systemctl start mysqld
my.cnf配置
[mysqld]
server-id=22 #不能和其他机器重复
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
重启服务,配置主从:
CHANGE MASTER TO
master_host='192.168.108.101',
master_user='myslave',
master_password='123456',
master_log_file='master-bin.000001',
master_log_pos=604;
START SLAVE;
SHOW SLAVE STATUS\G;
故障排查:
- IO线程No:网络不通、账号密码错误、binlog文件名position写错、防火墙。
- SQL线程No:主键冲突、主从表结构不一致、数据不一致。
六、读写分离Amoeba中间件
前提:必须先搭建好MySQL主从复制,Amoeba只负责SQL路由,不做数据同步!
读写分离思想
- 写(INSERT/UPDATE/DELETE)全部交给主库执行
- 读(SELECT)交给从库,多从库负载均衡分担查询压力 两种实现方案
- 应用程序代码内部判断SQL类型。
- 代理中间件:Amoeba、Mycat、MySQL‑Proxy,对业务代码透明。
Amoeba部署
- Java开发代理,监听端口8066,客户端连接amoeba,不直连mysql。
- 两个核心配置文件
amoeba.xml:客户端账号密码,writePool写池指向主库;readPool读池指向从库虚拟池。dbServers.xml:定义后端mysql节点ip账号密码,虚拟多节点池实现负载均衡轮询。
- 后端mysql授权amoeba访问账号。
- 修改配置之后必须杀死旧进程,重新启动,配置不会热加载。
读写分离验证实验步骤
- 主从复制正常,主库插入测试数据。
- 两台从库执行
stop slave;关闭复制,断开同步链路。 - 通过amoeba客户端执行写,写请求只会下发到主库。
- 分别登录两台从库,修改同一条记录为不同值。
- 多次执行select查询,交替拿到不同结果,证明读请求轮询分发到不同从库,读写分离生效。
- 实验结束从库执行
start slave;恢复主从复制。
七、MHA MySQL高可用⭐⭐⭐
MHA(Master High Availability),开源Perl开发,基于原生主从复制,解决主库单点故障自动转移 ,故障切换0‑30秒。 架构最少需要三台mysql节点:一主两从,再加一台MHA manager管理节点。 分为两大部分:
- MHA Node:所有mysql数据库节点全部安装。
- MHA Manager:独立管理节点,监控主库状态,故障触发自动failover。
MHA核心能力
- 主库宕机自动选出新主库(候选主库
candidate_master=1)。 - 尽量抢救故障主库binlog,最大限度降低数据丢失。
- 配合VIP虚拟IP,业务应用无需修改数据库连接地址。
注意候选主库也必须开启
log‑bin,提升为主库之后才能生成二进制日志。
MHA部署关键步骤
-
搭建好一主两从主从复制环境 ,克隆节点删除
auto.cnf防止UUID冲突。 -
所有节点安装MHA node组件;manager节点额外安装manager组件。
-
配置所有节点之间ssh无密码互信。
-
mysql授权两套账号:复制账号、MHA管理账号mha。
-
编写MHA配置文件
/etc/masterha/app1.cnfcandidate_master=1标记候选主库;check_repl_delay=0忽略复制延迟优先提升候选主库。- 配置VIP故障切换脚本
master_ip_failover。
-
工具校验环境:
masterha_check_ssh --conf=/etc/masterha/app1.cnf #检查ssh互信
masterha_check_repl --conf=/etc/masterha/app1.cnf #检查主从复制状态 -
启动MHA manager监控。
-
模拟主库宕机,观察MHA自动故障转移,VIP漂移,从库全部指向新主库。
故障切换完成之后,原来故障的旧主库,修复后需要手动作为新集群的从库加入。
八、学习总结
- 数据库范式:1NF原子、2NF消除部分依赖、3NF消除传递依赖;业务一般做到3NF。
- MySQL区分DDL/DML/DQL/DCL/TCL;DDL操作结构,DML操作数据。
- 备份:物理冷备份(停库tar)、mysqldump逻辑备份;增量备份依靠binlog。
- 主从复制核心:binlog、IO线程、SQL线程;两个Yes代表复制正常。
- 读写分离:Amoeba中间件,写走主,读走从;前提主从复制正常。
- MHA:解决主库单点故障,自动故障切换;一主两从架构,node所有数据库节点都要装。