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_FILE 和 MASTER_LOG_POS。 指定 MASTER_AUTO_POSITION = 1。
故障切换的痛点 主从切换时,需要手动去主库找 SHOW MASTER STATUS,找到新的File和Position,再到从库去配置,操作复杂且容易出错。 自动寻找同步点,从库会自动跳过已执行的事务,极其方便。
数据一致性保障 如果从库执行某事务失败,定位可能丢失,容易造成数据不一致。 GTID保证同一个事务在整个集群中只执行一次,天然避免重复执行,数据一致性更有保障。

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

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

  • 配置 :你在主从的my.cnf中都开启了 gtid_mode = ON 和 enforce_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-11 和 Executed_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
相关推荐
Godikov11 小时前
在 Android 上跑 Kafka Consumer:一个实时定位数据接入的踩坑记录
android
mmsx11 小时前
Android 自定义 View 三关:触摸分发、绘制与坐标错位
android·kotlin
JMchen12 小时前
自定义View在复杂业务场景中的实战
android·kotlin·canvas
hai_android12 小时前
RecyclerView 缓存机制详解
android·kotlin·android jetpack
_祝你今天愉快18 小时前
UI核心 - UI绘制流程及原理
android
mmsx19 小时前
Android 一个设备多个 App 抢:跨进程共享服务的架构设计
android·kotlin·app
mmsx19 小时前
Android GIS系列 栅格怎么存、格网怎么归算:两个容易混淆的 GIS 链路
android·性能优化·app
陈柒吖19 小时前
安卓代码加固(1):加密DEX
android·前端
mmsx19 小时前
Android GIS系列 串口、蓝牙、USB、网络:一套统一抽象怎么扛住四种通道
android·app·产品
二流小码农19 小时前
鸿蒙开发:ArrayList,可不会让UI更新哦
android·ios·harmonyos