mysql8 主从 HA切换

复制代码
[root@wubo mysql]# ls
master  salve


master:
[root@wubo master]# cat conf/my.cnf
[mysqld]
port            = 3306
datadir         = /var/lib/mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
secure-file-priv= /var/lib/mysql-files
lower_case_table_names=1
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=1500
max_connect_errors=100
default-storage-engine=INNODB
wait_timeout    = 1800
interactive_timeout = 1800
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
symbolic-links=0

log-error       = /var/lib/mysql/mysqld.log
slow_query_log  = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
long_query_time = 2

server-id       = 1
log_bin         = /var/lib/mysql/mysql-bin
binlog_format   = ROW
expire_logs_days = 7
max_binlog_size = 1024M
sync_binlog     = 1

gtid_mode       = ON
enforce_gtid_consistency = ON

log_slave_updates = ON

innodb_buffer_pool_size = 1G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT

[mysql]
default-character-set=utf8mb4

[client]
port=3306
default-character-set=utf8mb4


[root@wubo master]# cat readme 
1启动服务
docker run   --name master-mysql  -p 13306:3306  --privileged=true  --rm -v $(pwd)/mysql-files:/var/lib/mysql-files -v $(pwd)/data:/var/lib/mysql -v $(pwd)/conf/my.cnf:/etc/my.cnf -e MYSQL_ROOT_PASSWORD=123456aA harbor.jettech.com/jettechtools/mysql:8.0.28
2.创建同步用户
CREATE USER 'replicator'@'%' IDENTIFIED WITH mysql_native_password BY '123456aA';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'replicator'@'%';
FLUSH PRIVILEGES;

salve:

复制代码
[root@wubo salve]# cat conf/my.cnf
[mysqld]
port            = 3306
datadir         = /var/lib/mysql
pid-file        = /var/run/mysqld/mysqld.pid
socket          = /var/run/mysqld/mysqld.sock
secure-file-priv= /var/lib/mysql-files
lower_case_table_names=1
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
max_connections=1500
max_connect_errors=100
default-storage-engine=INNODB
wait_timeout    = 1800
interactive_timeout = 1800
sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
symbolic-links=0

log-error       = /var/lib/mysql/mysqld.log
slow_query_log  = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
long_query_time = 2

server-id       = 2
log_bin         = /var/lib/mysql/mysql-bin
binlog_format   = ROW
expire_logs_days = 7
max_binlog_size = 1024M
sync_binlog     = 1

gtid_mode       = ON
enforce_gtid_consistency = ON

#read_only       = ON
#super_read_only = ON

relay_log       = /var/lib/mysql/mysql-relay-bin
relay_log_recovery = ON

slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK

log_slave_updates = ON

innodb_buffer_pool_size = 1G
innodb_log_file_size = 512M
innodb_flush_log_at_trx_commit = 1
innodb_file_per_table = 1
innodb_flush_method = O_DIRECT

[mysql]
default-character-set=utf8mb4

[client]
port=3306
default-character-set=utf8mb4
[root@wubo salve]# cat readme 
1.启动服务
docker run   --name slave-mysql  -p 23306:3306  --privileged=true  --rm -v $(pwd)/mysql-files:/var/lib/mysql-files -v $(pwd)/data:/var/lib/mysql -v $(pwd)/conf/my.cnf:/etc/my.cnf -e MYSQL_ROOT_PASSWORD=123456aA harbor.jettech.com/jettechtools/mysql:8.0.28
2.从库连接时指定加密选项
CHANGE MASTER TO MASTER_HOST = '172.16.11.253',  MASTER_PORT = 13306, MASTER_USER = 'replicator',  MASTER_PASSWORD = '123456aA', MASTER_AUTO_POSITION = 1;
3.启动从库的复制线程,IO/SQL 2个线程
START SLAVE;

STOP SLAVE;
START SLAVE;
SHOW SLAVE STATUS\G

START SLAVE;	启动复制(IO 线程 + SQL 线程)
START SLAVE IO_THREAD;	只启动 IO 线程(只拉取日志,不执行)
START SLAVE SQL_THREAD;	只启动 SQL 线程(只执行中继日志,不拉取)
STOP SLAVE;	停止复制(两个线程都停)
STOP SLAVE IO_THREAD;	只停止 IO 线程
STOP SLAVE SQL_THREAD;	只停止 SQL 线程
SHOW SLAVE STATUS\G	查看复制状态

STOP SLAVE;
RESET SLAVE;          -- 清除中继日志,保留主库配置
START SLAVE;          -- 重新开始复制

-- 查看主库配置信息(CHANGE MASTER TO 设置的内容)
SELECT * FROM mysql.slave_master_info\G

-- 查看中继日志信息
SELECT * FROM mysql.slave_relay_log_info\G

-- 查看复制工作者线程信息
SELECT * FROM mysql.slave_worker_info\G

4.从库为了防止污染数据和主库不一致 禁止写操作
SHOW VARIABLES LIKE 'read_only';
SHOW VARIABLES LIKE 'super_read_only';
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;

原理:

1. 三个核心线程

主从复制能工作,全靠三个在不同服务器上各司其职的线程,它们配合默契,缺一不可。

线程名称 所在位置 核心职责 简单比喻
Binlog Dump Thread 主库 负责把主库上**二进制日志(Binlog)**的内容,实时发送给从库。 主库的**"数据发送员"**,随时准备把新数据打包发出。
Replica IO Thread 从库 负责连接主库,接收主库发来的Binlog事件,并将其原样写入从库的中继日志(Relay Log) 从库的**"数据接收员"**,把收到的数据先存到本地临时仓库。
Replica SQL Thread 从库 负责读取中继日志(Relay Log) 中的内容,并在从库上完整地**重放(执行)**一遍,最终写入从库的数据表。 从库的**"数据搬运工"**,把临时仓库的数据搬到最终目的地。

流程详解

  1. 提交事务 :应用在主库执行UPDATE,数据首先被写入主库的数据表。

  2. 记录Binlog :事务提交后,这条UPDATE语句会被记录到主库的二进制日志(Binlog)中。

  3. 传输Binlog :主库的Binlog Dump线程检测到Binlog有更新,立即将新内容推送给从库。

  4. 接收并暂存 :从库的IO线程 收到数据后,会写入从库自己的中继日志(Relay Log) 中。

  5. 重放并应用 :从库的SQL线程会一直监控中继日志,一有新的内容,就将其中的SQL语句在从库上完整地执行一遍。至此,主从数据达成一致。

3. 两种主流的复制模式

MySQL从5.6版本开始,引入了GTID(全局事务标识)模式 ,它比你之前可能见过的传统(基于位置)模式更强大。

对比维度 传统模式 (基于文件名+位置) GTID模式 (基于全局事务ID)
复制定位方式 指定 MASTER_LOG_FILEMASTER_LOG_POS 指定 MASTER_AUTO_POSITION = 1
故障切换的痛点 主从切换时,需要手动去主库找 SHOW MASTER STATUS,找到新的FilePosition,再到从库去配置,操作复杂且容易出错。 自动寻找同步点,从库会自动跳过已执行的事务,极其方便。
数据一致性保障 如果从库执行某事务失败,定位可能丢失,容易造成数据不一致。 GTID保证同一个事务在整个集群中只执行一次,天然避免重复执行,数据一致性更有保障。

4. 你刚刚完成的GTID复制原理

你刚刚搭建的正是GTID复制模式。你执行的关键命令和状态,正好对应了GTID的工作原理:

  • 配置 :你在主从的my.cnf中都开启了 gtid_mode = ONenforce_gtid_consistency = ON,告诉MySQL要用GTID来标识每个事务。

  • 搭建 :从库执行 CHANGE MASTER TO ... MASTER_AUTO_POSITION = 1;,这告诉从库:"别告诉我从哪里开始同步,你自己去主库询问并决定"。

  • 运行 :你执行的 SHOW MASTER STATUS 显示了 Executed_Gtid_Set: 59fb6c03-...:1-11。这表示主库已经执行了从1到11的11个GTID事务。

  • 验证 :从库的 SHOW SLAVE STATUS 显示 Retrieved_Gtid_Set: ...:1-11Executed_Gtid_Set: ...:1-11, b007...:1-5。这表示从库的IO线程已经从主库拉取(Retrieved) 了1-11的事务,并且SQL线程已执行(Executed) 了这些事务。后面那串b007...:1-5是它自身的本地事务,互不干扰。

当你执行 START SLAVE; 时发生了什么?

从库会启动两个核心线程:

线程 动作 状态变化
IO 线程 连接主库,开始拉取 Binlog Slave_IO_Running: No → Yes
SQL 线程 读取 Relay Log,开始执行 Slave_SQL_Running: No → Yes
相关推荐
墨狂之逸才1 小时前
Android 工业手持机蓝牙扫描失败:为什么同时需要蓝牙和定位权限
android
Android打工仔2 小时前
Kotlin 协程源码解析(七)`delay()` 到底是如何在 `Dispatchers.Main` 上恢复的?
android·kotlin
律宏阔2 小时前
Android 红外功能实现与红外协议开发笔记:ConsumerIrManager、NEC、PWM、曼彻斯特编码
android
mmsx3 小时前
MapLibre 统一图层模型:sealed class + 声明式图层 + XML 持久化
android·源码·地图·maplibre
YUJIANYUE3 小时前
查立得万用查分安卓版(web环境+查询系统免安装单文件一键运行包)
android·前端
天空之城--4 小时前
Android Launcher 性能优化完全指南:从启动到滑动,构建极致流畅的桌面体验
android·性能优化
hunterandroid4 小时前
Android ANR 排查实战:从线上告警到主线程卡点定位
android·前端
TimeFine4 小时前
智能眼镜开发:图片翻译与EXIF的重要性
android
律宏阔5 小时前
Android 车载蓝牙开发笔记:HFP、A2DP、AVRCP、PBAP、MAP、BLE 与系统 API
android·蓝牙