MySQL8 主从架构设计(重点)
学习目标
- 了解 MySQL 数据库常见的主从架构及应用场景
- 理解 MySQL 主从复制的实现原理(背诵、记忆)
- 掌握传统 AB 复制(基于 binlog + pos 点位)的搭建与配置
- 掌握基于 GTID 的主从复制搭建与配置
- 能够独立完成主从复制环境的全流程部署(环境准备 → 配置修改 → 数据同步 → 复制验证)
- 掌握主从复制常见故障的排查与修复(IO/SQL 线程异常、主从延迟、数据不一致等)
- 掌握 GTID 模式下跳过异常事务的修复方法
- 理解并能分析 MySQL 主从延迟的原因及解决方案
一、主从架构概述
1. 场景说明
某同学刚入职公司,在熟悉公司业务环境的时候,发现他们的数据库架构是一主两从,但是两台从数据库和主库不同步。询问得知,已经好几个月不同步了,但是每天会全库备份主服务器上的数据到从服务器上,由于数据量不是很大,所以一直没有人处理主从不同步的问题。这次正好问到了,于是乎就安排该同学处理一下这个主从不同步的问题。
主服务器对外提供业务数据,负责业务数据的增删改查操作。
从服务器默认不对外提供服务,和主服务器一样,都处于长时间运行状态,在运行过程中,从服务器会自动从主服务器拉取并同步数据,提供了一个在线热备解决方案。
2. 主从架构学习目标
① 熟悉MySQL数据库常见的主从架构
② 理解MySQL主从架构的实现原理(背诵、记忆)
③ 掌握MySQL主从架构的搭建(重点掌握)
3. 什么是主从复制(主从同步)?
主从复制可以实现将数据从一台数据库服务器(master)复制(同步)到一台或多台数据库服务器(slave)
master:主人 slave:奴隶,从属。
默认情况下,属于异步复制,所以无需维持长连接
解决问题:
① 数据实时备份
② 缓解服务器压力(读操作可以分散到slave服务器)=> MyCAT(读写分离软件)
简单来说:
master将数据库的改变写入二进制日志(Binary Log);
slave同步这些二进制日志,并根据这些二进制日志进行数据重演操作,实现数据异步同步。
【扩展】
同步复制:从服务器拉取主服务器的数据时,主服务器增删改数据时,从服务器必须马上同步,等待从服务器同步完成后,主服务器才能继续新的事务操作。
优点:两端数据高度一致
缺点:阻塞主服务器的事务操作
异步复制:从服务器拉取主服务器的数据时,主服务器增删改数据时,从服务器可以异步复制,等待空闲时再进行拉取,在这个过程中,不会阻塞主服务器业务。
优点:不会阻塞主服务器的事务操作
缺点:可能会出现主从同步延迟的情况
4. 主从复制(主从同步)原理(背诵)

binlog二进制日志 vs relaylog中继日志(负责把主服务器的DML在slave服务器重写执行一遍)
binlog保存了用户对数据库的增删改事务操作(SQL语句)、relaylog中继日志,当从服务器从主服务器拉取到二进制日志数据时,会首先写入到relaylog中继日志中。
详细描述:
**前提:**主服务器开启binlog二进制日志,从服务器开启relaylog中继日志。
① slave端的IO线程发送请求给master端的binlog dump线程
② master端binlog dump线程获取二进制日志信息(文件名和位置信息)发送给slave端的IO线程
③ salve端IO线程获取到的内容依次写到slave端relay log里,并把master端的bin-log文件名和位置记录到master.info里或者mysql.slave_master_info里
④ salve端的SQL线程,检测到relay log中内容更新,就会解析relay log里更新的内容,并执行这些操作,从而达到和master数据一致
master:主服务器;slave:从服务器。
注:主从复制也是备份的一种,属于在线热备。到这里就学过3种备份了:逻辑备份、物理备份、在线热备。
**注意:**从 MySQL 5.6+(尤其是 5.7 / 8.0)开始,复制元数据的存储方式升级了!
以前(老版本):
master.info(记录主库信息)-
relay-log.info
是文件形式
现在(新版本默认):
- 存在 系统表里(在
mysql库中)
| 文件 | 对应表 |
|---|---|
| master.info | mysql.slave_master_info |
| relay-log.info | mysql.slave_relay_log_info |
[root@mysql-node2 ~]# mysql -uroot -pMySQL@666
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 16
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> desc mysql.slave_master_info;
+---------------------------------+-----------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+---------------------------------+-----------------+------+-----+---------+-------+
| Number_of_lines | int unsigned | NO | | NULL | |
| Master_log_name | text | NO | | NULL | |
| Master_log_pos | bigint unsigned | NO | | NULL | |
| Host | varchar(255) | YES | | NULL | |
| User_name | text | YES | | NULL | |
| User_password | text | YES | | NULL | |
| Port | int unsigned | NO | | NULL | |
| Connect_retry | int unsigned | NO | | NULL | |
| Enabled_ssl | tinyint(1) | NO | | NULL | |
| Ssl_ca | text | YES | | NULL | |
| Ssl_capath | text | YES | | NULL | |
| Ssl_cert | text | YES | | NULL | |
| Ssl_cipher | text | YES | | NULL | |
| Ssl_key | text | YES | | NULL | |
| Ssl_verify_server_cert | tinyint(1) | NO | | NULL | |
| Heartbeat | float | NO | | NULL | |
| Bind | text | YES | | NULL | |
| Ignored_server_ids | text | YES | | NULL | |
| Uuid | text | YES | | NULL | |
| Retry_count | bigint unsigned | NO | | NULL | |
| Ssl_crl | text | YES | | NULL | |
| Ssl_crlpath | text | YES | | NULL | |
| Enabled_auto_position | tinyint(1) | NO | | NULL | |
| Channel_name | varchar(64) | NO | PRI | NULL | |
| Tls_version | text | YES | | NULL | |
| Public_key_path | text | YES | | NULL | |
| Get_public_key | tinyint(1) | NO | | NULL | |
| Network_namespace | text | YES | | NULL | |
| Master_compression_algorithm | varchar(64) | NO | | NULL | |
| Master_zstd_compression_level | int unsigned | NO | | NULL | |
| Tls_ciphersuites | text | YES | | NULL | |
| Source_connection_auto_failover | tinyint(1) | NO | | 0 | |
| Gtid_only | tinyint(1) | NO | | 0 | |
+---------------------------------+-----------------+------+-----+---------+-------+
33 rows in set (0.00 sec)
mysql> desc mysql.slave_relay_log_info;
+----------------------------------------------+--------------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------------------------------------------+--------------------------------------+------+-----+---------+-------+
| Number_of_lines | int unsigned | NO | | NULL | |
| Relay_log_name | text | YES | | NULL | |
| Relay_log_pos | bigint unsigned | YES | | NULL | |
| Master_log_name | text | YES | | NULL | |
| Master_log_pos | bigint unsigned | YES | | NULL | |
| Sql_delay | int | YES | | NULL | |
| Number_of_workers | int unsigned | YES | | NULL | |
| Id | int unsigned | YES | | NULL | |
| Channel_name | varchar(64) | NO | PRI | NULL | |
| Privilege_checks_username | varchar(32) | YES | | NULL | |
| Privilege_checks_hostname | varchar(255) | YES | | NULL | |
| Require_row_format | tinyint(1) | NO | | NULL | |
| Require_table_primary_key_check | enum('STREAM','ON','OFF','GENERATE') | NO | | STREAM | |
| Assign_gtids_to_anonymous_transactions_type | enum('OFF','LOCAL','UUID') | NO | | OFF | |
| Assign_gtids_to_anonymous_transactions_value | text | YES | | NULL | |
+----------------------------------------------+--------------------------------------+------+-----+---------+-------+
15 rows in set (0.00 sec)
mysql> select * from slave_master_info;
+-----------------+-----------------+----------------+----------------+-----------+---------------+------+---------------+-------------+--------+------------+----------+------------+---------+------------------------+-----------+------+--------------------+------+-------------+---------+-------------+-----------------------+--------------+-------------+-----------------+----------------+-------------------+------------------------------+-------------------------------+------------------+---------------------------------+-----------+
| Number_of_lines | Master_log_name | Master_log_pos | Host | User_name | User_password | Port | Connect_retry | Enabled_ssl | Ssl_ca | Ssl_capath | Ssl_cert | Ssl_cipher | Ssl_key | Ssl_verify_server_cert | Heartbeat | Bind | Ignored_server_ids | Uuid | Retry_count | Ssl_crl | Ssl_crlpath | Enabled_auto_position | Channel_name | Tls_version | Public_key_path | Get_public_key | Network_namespace | Master_compression_algorithm | Master_zstd_compression_level | Tls_ciphersuites | Source_connection_auto_failover | Gtid_only |
+-----------------+-----------------+----------------+----------------+-----------+---------------+------+---------------+-------------+--------+------------+----------+------------+---------+------------------------+-----------+------+--------------------+------+-------------+---------+-------------+-----------------------+--------------+-------------+-----------------+----------------+-------------------+------------------------------+-------------------------------+------------------+---------------------------------+-----------+
| 33 | binlog.000005 | 157 | 192.168.88.101 | slave | MySQL@666 | 3306 | 60 | 0 | | | | | | 0 | 30 | | 0 | | 86400 | | | 0 | | | | 0 | | uncompressed | 3 | NULL | 0 | 0 |
+-----------------+-----------------+----------------+----------------+-----------+---------------+------+---------------+-------------+--------+------------+----------+------------+---------+------------------------+-----------+------+--------------------+------+-------------+---------+-------------+-----------------------+--------------+-------------+-----------------+----------------+-------------------+------------------------------+-------------------------------+------------------+---------------------------------+-----------+
1 row in set (0.01 sec)
mysql> select * from slave_relay_log_info;
+-----------------+-------------------------------------------+---------------+-----------------+----------------+-----------+-------------------+------+--------------+---------------------------+---------------------------+--------------------+---------------------------------+---------------------------------------------+----------------------------------------------+
| Number_of_lines | Relay_log_name | Relay_log_pos | Master_log_name | Master_log_pos | Sql_delay | Number_of_workers | Id | Channel_name | Privilege_checks_username | Privilege_checks_hostname | Require_row_format | Require_table_primary_key_check | Assign_gtids_to_anonymous_transactions_type | Assign_gtids_to_anonymous_transactions_value |
+-----------------+-------------------------------------------+---------------+-----------------+----------------+-----------+-------------------+------+--------------+---------------------------+---------------------------+--------------------+---------------------------------+---------------------------------------------+----------------------------------------------+
| 14 | /export/server/mysql/data/relaylog.000002 | 4608 | binlog.000005 | 4442 | 0 | 4 | 1 | | NULL | NULL | 0 | STREAM | OFF | |
+-----------------+-------------------------------------------+---------------+-----------------+----------------+-----------+-------------------+------+--------------+---------------------------+---------------------------+--------------------+---------------------------------+---------------------------------------------+----------------------------------------------+
1 row in set (0.00 sec)
mysql>
二、传统主从复制(AB复制)设计
-
主从复制(主从同步)环境准备
传统AB复制架构(M-S),说明:MySQL数据库,版本为8.0.43
环境说明:
| IP | 主机名 | 角色 |
|---|---|---|
| 192.168.88.101 | mysql-node1 | master(主) |
| 192.168.88.102 | mysql-node2 | slave(从) |
安装前准备:
① 安装必备软件,如vim、wget、rsync
② 配置IP、主机名
③ 配置IP与主机映射 => /etc/hosts
④ 优化Linux系统
⑤ 时间同步
在mysql-node1和mysql-node2上安装一些依赖软件(系统必备软件)
dnf install vim wget rsync telnet net-tools -y
设置主机名称
hostnamectl set-hostname mysql-node1
hostnamectl set-hostname mysql-node2
exit
su或者bash指令
配置IP与主机映射
[root@mysql-node1 ~]# cat /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
#uuid=39fc68b0-865c-3bd3-a42d-3e1998f8e2cd
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1752853607
[ethernet]
[ipv4]
#method=auto
method=manual
addresses=192.168.88.101/24
gateway=192.168.88.2
dns=192.168.88.2,114.114.114.114;
[ipv6]
#addr-gen-mode=eui64
#method=auto
method=disabled
[proxy]
[root@mysql-node1 ~]#
[root@mysql-node1 ~]# vim /etc/hosts
在尾部追加如下内容,mysql-node2也配置同样的参数
192.168.88.101 mysql-node1 node1
192.168.88.102 mysql-node2 node2
优化Linux系统
sed -i -r 's/SELINUX=[ep].*/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl stop firewalld &> /dev/null
systemctl disable firewalld &> /dev/null
iptables -F
iptables -t nat -F
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
时间同步(可选)
dnf -y install chrony
systemctl enable chronyd --now
chronos,柯罗诺斯,古希腊神话中掌管时间的神。
chronize指时间上的,sync是指使相同。因此sync-chronize简写synchronize,表示使时间同步;
asynchronize表示异步(计算机专业常用术语)。
到此环境准备完毕了!
建议:把对应的Linux服务器关机,然后拍一下快照!
互为主从(补充)
MySQL 的二进制日志包含 server_id,复制时会自动跳过自己的事件
A 写 → B 执行 → 不会再回传给 A
B 写 → A 执行 → 不会再回传给 B
MySQL 双主(互为主从)不会出现循环复制,是因为每条 binlog 事件都有自己的 server_id****。复制线程在执行时会自动跳过“自己产生的”事件。
可以理解为:
- A 写入数据 → 记录 binlog(server_id = A) → 传给 B → B 执行后发现不是自己产生的,所以执行。执行完不会再传回给 A。
- B 写入数据 → 记录 binlog(server_id = B) → 传给 A → A 执行后发现不是自己产生的,所以执行。执行完也不会再传回 B。
一句话总结: “谁写的事件带着谁的 server_id,别人可以执行,但自己永远不会再执行一次,因此不会产生循环。”
2. 主从复制(主从同步)搭建思路
- master、slave必须安装相同版本的MySQL数据库软件
- master端必须开启binlog二进制日志,slave端必须开启relay log中继日志
- master端和slave端的server-id号不能一致 => /etc/my.cnf => server-id = 101 server-id = 102
- 同步master端数据之前,master端删除data数据目录下的auto.cnf文件 => uuid编号(每个mysql实例唯一的)
master => mysql(uuid编号 => 数据库初始化自动生成) => /export/server/mysql/data/auto.cnf
如果slave数据目录是把master中的data同步过来,导致两个MySQL共用同一个uuid编号,会出现问题; 建议改成不一样的uuid编号。
- slave端配置向master来同步数据
- master端必须创建一个复制用户,比如 slave
- 保证master端和slave端初始数据一致
- 配置主从复制(slave端)
3. MySQL8主从同步实战
3.1 安装MySQL8
如果还没有安装MySQL8,则按照以下操作安装。
vim install-mysql8.sh
#!/bin/bash
if rpm -q libaio &> /dev/null; then
echo "libaio已安装,跳过安装"
else
echo "开始安装依赖"
dnf -y install libaio &> /dev/null
if [ $? -ne 0 ];then
echo "libaio安装失败"
exit 1
fi
fi
echo "进行解压操作"
if ls -l mysql-8.0.43-linux-glibc2.28-x86_64 &> /dev/null; then
echo "已解压,跳过"
else
if [ -f mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz ]; then
tar -xf mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz
ls -l mysql-8.0.43-linux-glibc2.28-x86_64
fi
fi
echo "判断是否安装过MariaDB,进行清理"
rpm -qa | grep mariadb | xargs -r dnf remove -y
if [ -f /etc/my.cnf ]; then
rm -rf /etc/my.cnf
fi
id mysql &> /dev/null
[ $? -ne 0 ] && useradd -r -s /sbin/nologin mysql
rm -rf /export/server
mkdir -p /export/server
cp -r mysql-8.0.43-linux-glibc2.28-x86_64 /export/server/mysql
chown -R mysql:mysql /export/server/mysql
echo "正在进入mysql目录,对其进行初始化操作..."
cd /export/server/mysql
bin/mysqld --initialize --user=mysql --basedir=/export/server/mysql --datadir=/export/server/mysql/data 2>&1 | tee /tmp/mysqld.log | grep password | awk '{print $NF}' > /tmp/mysql_temp_password.txt
bin/mysql_ssl_rsa_setup --datadir=/export/server/mysql/data &> /dev/null
cat >/etc/my.cnf<<EOF
[mysqld]
port=3306
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
character_set_server=utf8
collation-server=utf8_unicode_ci
EOF
cat >/etc/systemd/system/mysqld.service<<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
Type=forking
# MySQL 执行命令及路径
ExecStart=/export/server/mysql/bin/mysqld --daemonize --pid-file=/export/server/mysql/data/mysqld.pid
ExecStop=/export/server/mysql/bin/mysqladmin --defaults-file=/export/server/mysql/my.cnf shutdown
# Ensure MySQL has sufficient time to start up
TimeoutSec=600
# PID 文件路径
PIDFile=/export/server/mysql/data/mysqld.pid
# Enable these options to auto-restart the service if it crashes
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
echo "正在刷新后台服务,然后启动mysqld..."
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld
#10.重置mysql管理员密码为MySQL@666
echo "正在重置mysql管理员密码..."
cd /export/server/mysql
temp_password=`cat /tmp/mysql_temp_password.txt`
bin/mysqladmin -uroot password 'MySQL@666' -p"$temp_password"
echo 'export PATH=$PATH:/export/server/mysql/bin' >> /etc/profile
source /etc/profile
mysql -V
echo "MySQL8安装成功,安装路径:/export/server/mysql,数据库初始密码:MySQL@666"
注意:执行完install-mysql8.sh安装脚本后,需要在Linux命令行执行source /etc/profile
优化版MySQL8安装脚本mysql8_install.sh
#!/bin/bash
# 作用:快速安装MySQL8.0
# 作者:传棋(Jaing)
# 日期:2025年12月11日
# 邮箱:Jaking@vip.163.com
sed -i -r 's/SELINUX=[ep].*/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl stop firewalld &> /dev/null
systemctl disable firewalld &> /dev/null
iptables -F
iptables -t nat -F
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
if rpm -q libaio &> /dev/null; then
echo "libaio已安装,跳过安装"
else
echo "开始安装依赖"
dnf -y install libaio &> /dev/null
if [ $? -ne 0 ];then
echo "libaio安装失败"
exit 1
fi
fi
echo "进行解压操作"
if ls -l mysql-8.0.43-linux-glibc2.28-x86_64 &> /dev/null; then
echo "已解压,跳过"
else
if [ -f mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz ]; then
tar -xf mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz
ls -l mysql-8.0.43-linux-glibc2.28-x86_64
fi
fi
echo "判断是否安装过MariaDB,进行清理"
rpm -qa | grep mariadb | xargs -r dnf remove -y
if [ -f /etc/my.cnf ]; then
rm -rf /etc/my.cnf
fi
id mysql &> /dev/null
[ $? -ne 0 ] && useradd -r -s /sbin/nologin mysql
rm -rf /export/server
mkdir -p /export/server
cp -r mysql-8.0.43-linux-glibc2.28-x86_64 /export/server/mysql
chown -R mysql:mysql /export/server/mysql
echo "正在进入mysql目录,对其进行初始化操作..."
cd /export/server/mysql
bin/mysqld --initialize --user=mysql --basedir=/export/server/mysql --datadir=/export/server/mysql/data 2>&1 | tee /tmp/mysqld.log | grep password | awk '{print $NF}' > /tmp/mysql_temp_password.txt
bin/mysql_ssl_rsa_setup --datadir=/export/server/mysql/data &> /dev/null
cat >/etc/my.cnf<<EOF
[mysqld]
port=3306
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
character_set_server=utf8
collation-server=utf8_unicode_ci
EOF
cat >/etc/systemd/system/mysqld.service<<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
Type=forking
# MySQL 执行命令及路径
ExecStart=/export/server/mysql/bin/mysqld --daemonize --pid-file=/export/server/mysql/data/mysqld.pid
ExecStop=/export/server/mysql/bin/mysqladmin --defaults-file=/export/server/mysql/my.cnf shutdown
# Ensure MySQL has sufficient time to start up
TimeoutSec=600
# PID 文件路径
PIDFile=/export/server/mysql/data/mysqld.pid
# Enable these options to auto-restart the service if it crashes
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
echo "正在刷新后台服务,然后启动mysqld..."
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld
#10.重置mysql管理员密码为MySQL@666
echo "正在重置mysql管理员密码..."
cd /export/server/mysql
temp_password=`cat /tmp/mysql_temp_password.txt`
bin/mysqladmin -uroot password 'MySQL@666' -p"$temp_password"
echo 'export PATH=$PATH:/export/server/mysql/bin' >> /etc/profile
source /etc/profile
echo "MySQL8安装成功,安装路径:/export/server/mysql,数据库初始密码:MySQL@666"
echo "执行 source /etc/profile 获取最新环境变量"
echo "执行 mysql -uroot -pMySQL@666 登录MySQL"
3.2 初始化数据库(强烈建议)
说明:如果是新安装的MySQL,那么这一步可以跳过!
systemctl stop mysqld
pkill mysqld
rm -rf /export/server/mysql/data/*
rm -rf /tmp/mysqld.log
/export/server/mysql/bin/mysqld --initialize --user=mysql --basedir=/export/server/mysql &>/tmp/mysqld.log
grep password /tmp/mysqld.log | awk '{print $NF}'
mysqld --user=mysql --skip-grant-tables --skip-networking &
mysql
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@666';
FLUSH PRIVILEGES;
EXIT;
pkill mysqld
systemctl start mysqld
systemctl status mysqld --no-pager
mysql -uroot -p'MySQL@666'
show databases;
3.3 修改MySQL主从配置(核心)
master主服务器 => /etc/my.cnf
cat >/etc/my.cnf<<EOF
[mysqld]
# 基础路径
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
port=3306
# 字符集配置
character_set_server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 错误日志
log-error=/export/server/mysql/master.err
# 二进制日志,用于主从复制 & 恢复
log-bin=/export/server/mysql/data/binlog
server-id=101
binlog_format=ROW
expire_logs_days=7
sync_binlog=1
# 跳过同步的系统库
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
# InnoDB 引擎优化
default_storage_engine=InnoDB
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_log_buffer_size=64M
innodb_flush_log_at_trx_commit=1 # 主库一般为1,每次事务提交都写日志并立刻刷盘
innodb_file_per_table=1 # 每个表用一个独立的 .ibd 文件
# 连接配置
max_connections=500
max_connect_errors=1000000
table_open_cache=2000
# 慢查询日志
slow_query_log=1
slow_query_log_file=/export/server/mysql/slow.log
long_query_time=1
[client]
socket=/tmp/mysql.sock
default-character-set=utf8mb4
EOF
/etc/my.cnf配置文件详细解释:
cat >/etc/my.cnf<<EOF
# ==============================================
# MySQL 主库核心配置文件(my.cnf)
# 适用于 MySQL 5.7 / 8.0 主从架构主节点
# 配置路径:/etc/my.cnf
# ==============================================
[mysqld]
# --------------------------
# 1. 基础路径与端口配置
# --------------------------
# MySQL 安装根目录
basedir=/export/server/mysql
# MySQL 数据文件存放目录(库表数据都在这里)
datadir=/export/server/mysql/data
# MySQL 本地套接字文件(本地连接使用)
socket=/tmp/mysql.sock
# MySQL 服务监听端口(默认 3306)
port=3306
# --------------------------
# 2. 字符集配置
# --------------------------
# 服务器默认字符集(utf8mb4 支持完整 emoji,是 utf8 超集)
character_set_server=utf8mb4
# 服务器默认排序规则(与字符集对应)
collation-server=utf8mb4_unicode_ci
# --------------------------
# 3. 错误日志配置
# --------------------------
# MySQL 错误日志路径(启动失败、运行异常都会记录在这里)
log-error=/export/server/mysql/master.err
# --------------------------
# 4. 二进制日志(binlog)核心配置(主从复制必备)
# --------------------------
# 开启 binlog 并指定文件前缀(binlog 记录所有数据修改操作)
log-bin=/export/server/mysql/data/binlog
# 服务器唯一 ID(主从架构中必须唯一,主库建议 101,从库 102/103...)
server-id=101
# binlog 记录格式:ROW(行模式,只记录行数据变化,主从最安全)
binlog_format=ROW
# binlog 自动清理天数(7 天自动删除,避免磁盘爆满)
expire_logs_days=7
# 每次事务提交都立即同步 binlog 到磁盘(数据最安全,主库必开)
sync_binlog=1
# --------------------------
# 5. 忽略同步的系统库(不写入 binlog,不从库同步)
# --------------------------
# 忽略系统库 information_schema
binlog-ignore-db=information_schema
# 忽略系统库 mysql(用户权限库)
binlog-ignore-db=mysql
# 忽略系统库 performance_schema
binlog-ignore-db=performance_schema
# 忽略系统库 sys
binlog-ignore-db=sys
# --------------------------
# 6. InnoDB 存储引擎优化(生产环境核心配置)
# --------------------------
# 默认存储引擎设置为 InnoDB
default_storage_engine=InnoDB
# InnoDB 缓冲池大小(建议设置为物理内存的 50%~70%,这里 1G 适合测试/小内存机器)
innodb_buffer_pool_size=1G
# InnoDB 重做日志文件大小(提高写入性能,256M 是通用优化值)
innodb_log_file_size=256M
# InnoDB 日志缓冲区大小(64M 适合中等写入量)
innodb_log_buffer_size=64M
# 事务日志刷盘策略:1 = 每次事务提交都刷盘(数据绝对安全,主库必须用 1)
innodb_flush_log_at_trx_commit=1
# 开启独立表空间(每个表单独一个 .ibd 文件,方便维护、回收空间)
innodb_file_per_table=1
# --------------------------
# 7. 连接与并发配置
# --------------------------
# MySQL 最大同时连接数(支持 500 个并发连接)
max_connections=500
# 最大连接错误次数(防止暴力破解,设大值避免正常连接被拦截)
max_connect_errors=1000000
# 打开表的缓存数量(提升多表操作性能)
table_open_cache=2000
# --------------------------
# 8. 慢查询日志(SQL 性能优化必备)
# --------------------------
# 开启慢查询日志
slow_query_log=1
# 慢查询日志存放路径
slow_query_log_file=/export/server/mysql/slow.log
# 慢查询阈值:执行时间超过 1 秒的 SQL 会被记录
long_query_time=1
# --------------------------
# 客户端连接默认配置
# --------------------------
[client]
# 客户端连接使用的套接字文件(与服务端保持一致)
socket=/tmp/mysql.sock
# 客户端默认字符集
default-character-set=utf8mb4
EOF
master主服务器配置完成后,先在主服务器端为其创建一个master.err的日志文件并授权
# 创建日志文件
touch /export/server/mysql/master.err
# 修改权限
chown -Rf mysql:mysql /export/server/mysql/
# 重启服务
systemctl restart mysqld
# 查看服务状态
systemctl status mysqld --no-pager
slave从服务器 => my.cnf => 开启了relaylog(中继日志 => 把主服务器binlog重写)
cat >/etc/my.cnf<<EOF
[mysqld]
# 基础路径
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
port=3306
# 字符集
character_set_server=utf8mb4
collation-server=utf8mb4_unicode_ci
# 错误日志
log-error=/export/server/mysql/slave.err
# 开启 binlog(从库也可以作为其他从库的主库)
# log-bin=/export/server/mysql/data/binlog
# relay log
relay-log=/export/server/mysql/data/relaylog
relay-log-index=/export/server/mysql/data/relaylog.index
read-only=1
super-read-only=1
skip-slave-start=1 # 避免宕机重启自动拉起复制线程,需手动控制
# 复制过滤(避免同步系统库)
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
# server-id 必须唯一
server-id=102
# InnoDB 参数(从库查询压力可能更大)
default_storage_engine=InnoDB
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_log_buffer_size=64M
innodb_flush_log_at_trx_commit=2 # 从库一般可设为 2,提高复制性能;每次事务提交,写日志,但不立即刷盘
innodb_file_per_table=1 # 每个表用一个独立的 .ibd 文件
# 连接配置
max_connections=500
table_open_cache=2000
max_connect_errors=1000000
# 慢查询日志(从库跑报表时有用)
slow_query_log=1
slow_query_log_file=/export/server/mysql/slow.log
long_query_time=1
# 复制优化
relay_log_recovery=1 # 防止 relay log 损坏导致复制中断
sync_relay_log=0 # 提高复制性能
sync_relay_log_info=0
sync_master_info=0
[client]
socket=/tmp/mysql.sock
default-character-set=utf8mb4
EOF
/etc/my.cnf配置文件详细解释:
cat >/etc/my.cnf<<EOF
# ==============================================
# MySQL 从库核心配置文件(my.cnf)
# 适用于 MySQL 5.7 / 8.0 主从架构从节点
# 配置路径:/etc/my.cnf
# ==============================================
[mysqld]
# --------------------------
# 1. 基础路径与端口配置
# --------------------------
# MySQL 安装根目录
basedir=/export/server/mysql
# MySQL 数据文件存放目录
datadir=/export/server/mysql/data
# MySQL 本地套接字文件(本地连接使用)
socket=/tmp/mysql.sock
# MySQL 服务监听端口(默认 3306)
port=3306
# --------------------------
# 2. 字符集配置
# --------------------------
# 服务器默认字符集(utf8mb4 支持完整 emoji,是 utf8 超集)
character_set_server=utf8mb4
# 服务器默认排序规则(与字符集对应)
collation-server=utf8mb4_unicode_ci
# --------------------------
# 3. 错误日志配置
# --------------------------
# MySQL 错误日志路径(从节点专用日志名)
log-error=/export/server/mysql/slave.err
# --------------------------
# 4. 二进制日志(binlog)配置
# --------------------------
# 从库默认关闭 binlog(注释状态)
# 开启后从库可作为其他从库的主库(级联复制)
# log-bin=/export/server/mysql/data/binlog
# --------------------------
# 5. 从库复制核心配置(relay log 中继日志)
# --------------------------
# 中继日志文件路径(从库接收主库 binlog 后写入这里,再重放到本地)
relay-log=/export/server/mysql/data/relaylog
# 中继日志索引文件(记录所有 relay log 文件名)
relay-log-index=/export/server/mysql/data/relaylog.index
# 开启普通用户只读(禁止普通用户写入数据,保证从库数据一致性)
read-only=1
# 开启超级用户(root)只读(强制所有用户不可写,生产从库必备)
super-read-only=1
# 开机不自动启动复制线程
# 避免宕机重启后立即同步,需人工检查无误后手动启动复制
skip-slave-start=1
# --------------------------
# 6. 复制过滤规则(忽略系统库,不进行主从同步)
# --------------------------
# 忽略同步系统库 information_schema
replicate-ignore-db=information_schema
# 忽略同步系统库 mysql(用户权限库)
replicate-ignore-db=mysql
# 忽略同步系统库 performance_schema
replicate-ignore-db=performance_schema
# 忽略同步系统库 sys
replicate-ignore-db=sys
# --------------------------
# 7. 服务器唯一 ID(主从架构必须唯一)
# --------------------------
# 从库 ID(主库 101,从库建议 102/103...)
server-id=102
# --------------------------
# 8. InnoDB 存储引擎优化(从库专用)
# --------------------------
# 默认存储引擎设置为 InnoDB
default_storage_engine=InnoDB
# InnoDB 缓冲池大小(缓存数据+索引,提升查询性能)
innodb_buffer_pool_size=1G
# InnoDB 重做日志文件大小
innodb_log_file_size=256M
# InnoDB 日志缓冲区大小
innodb_log_buffer_size=64M
# 事务日志刷盘策略:2 = 每秒刷盘一次
# 从库专用配置,提升主从复制性能,数据安全性略低于 1
innodb_flush_log_at_trx_commit=2
# 开启独立表空间(每个表单独一个 .ibd 文件)
innodb_file_per_table=1
# --------------------------
# 9. 连接与并发配置
# --------------------------
# MySQL 最大同时连接数
max_connections=500
# 打开表的缓存数量(提升多表查询性能)
table_open_cache=2000
# 最大连接错误次数(防止暴力破解)
max_connect_errors=1000000
# --------------------------
# 10. 慢查询日志(从库报表/查询优化必备)
# --------------------------
# 开启慢查询日志
slow_query_log=1
# 慢查询日志存放路径
slow_query_log_file=/export/server/mysql/slow.log
# 慢查询阈值:执行时间超过 1 秒的 SQL 会被记录
long_query_time=1
# --------------------------
# 11. 主从复制性能优化(从库专用)
# --------------------------
# 中继日志自动恢复
# relay log 损坏时自动修复,防止复制中断
relay_log_recovery=1
# 关闭 relay log 实时刷盘(提高写入性能)
sync_relay_log=0
# 关闭 relay-log-info 实时刷盘
sync_relay_log_info=0
# 关闭 master-info 实时刷盘
sync_master_info=0
# --------------------------
# 客户端连接默认配置
# --------------------------
[client]
# 客户端连接使用的套接字文件(与服务端保持一致)
socket=/tmp/mysql.sock
# 客户端默认字符集
default-character-set=utf8mb4
EOF
从slave服务器配置完成后,也需要提前创建slave.err错误日志文件
# 创建日志文件
touch /export/server/mysql/slave.err
# 修改权限
chown -Rf mysql:mysql /export/server/mysql/
# 重启服务
systemctl restart mysqld
# 查看服务状态
systemctl status mysqld --no-pager
3.4 启动master并创建同步账号
在master主数据库中,创建同步账号
mysql> CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'MySQL@666';
[root@mysql-node1 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'MySQL@666';
Query OK, 0 rows affected (0.00 sec)
mysql>
授予用户slave REPLICATION SLAVE权限和REPLICATION CLIENT权限,用于在主从库之间同步数据。
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
mysql> flush privileges;
权限的目的是为了读取二进制日志以及拉取二进制中的数据信息
REPLICATION SLAVE 让 Slave 节点连接 Master 并读取 binlog,实现数据同步。
REPLICATION CLIENT 查看复制状态信息(如 binlog 位置、延迟),用于监控和诊断。
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql>
补充:
mysql -uslave -p'MySQL@666' -h192.168.88.101

可能会遇到的问题:

解决方法:
[root@mysql-node1 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 24
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE USER 'slave'@'mysql-node2' IDENTIFIED BY 'MySQL@666';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'mysql-node2';
Query OK, 0 rows affected (0.00 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
3.5 rsync 同步 data 目录与删除 auto.cnf 文件(可选)
说明:如果是新安装的MySQL,那么这一步可以跳过!
# 1、停止 master服务器 上的 MySQL 服务
systemctl stop mysqld
# 2、在 master 上执行 rsync 同步 data 目录(可选)
rsync -av --delete /export/server/mysql/data/ mysql-node2:/export/server/mysql/data/
# 3、分别在 master 和 slave 删除 auto.cnf 文件
rm -f /export/server/mysql/data/auto.cnf
【注释】
1、auto.cnf文件里保存的是每个数据库实例的UUID信息,代表数据库的唯一标识。
所以这里删除掉,保证 slave 和 master 的 uuid 不会重复。
2、rsync 是指 remote sync,远程同步
-a:即 --archive(音,阿凯伍),表示以归档模式传输文件,递归并保留几乎所有文件属性(如权限、时间戳、属主、链接等)。
-v:即 --verbose,启用详细输出模式
重启master和slave数据库
master:
systemctl restart mysqld
systemctl status mysqld --no-pager
mysql --version
slave:
systemctl restart mysqld
systemctl status mysqld --no-pager
mysql --version
注意:
我们重启master和slave机器上的mysqld时,都容易出现启动不了的情况。
遇到这种情况不要急,一定先要.err错误日志 => 一般环境问题,通过日志几乎100%可以解决。
3.6 在slave端开启同步
在 master上,先加读锁,防止两边数据不一致(了解即可,可选操作)
[root@mysql-node1 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
mysql>
获取 read lock 全局读锁,即锁住表,只让读
阻止所有写操作:其他会话无法执行 INSERT、UPDATE、DELETE 等修改数据的语句。
允许读操作:其他会话仍可执行 SELECT 查询
补充:
-- 解锁当前会话持有的所有锁UNLOCK TABLES;
UNLOCK TABLES;
查看当前数据库的二进制日志写到什么位置(只有打开二进制日志,以下命令才有结果)
[root@mysql-node1 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000003 | 157 | | | |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>
在slave服务器上,执行以下操作:
配置主从信息,但还未开始真正同步。
slave实现同步到master => change replication source
注意:一定要用root账号在slave本地登录!
# 在 slave 从节点上执行
[root@mysql-node2 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.88.101', -- 注意,这里是master主库地址
SOURCE_USER='slave',
SOURCE_PASSWORD='MySQL@666',
SOURCE_LOG_FILE='binlog.000003',
SOURCE_LOG_POS=157;

在slave服务器上启动同步
mysql> start slave;
mysql> show slave status\G
......
Slave_IO_Running: Yes 代表成功连接到master并且下载日志
Slave_SQL_Running: Yes 代表成功执行日志中的SQL语句
Seconds_Behind_Master: 0 代表主从延迟的秒数,如果为0,代表状态最佳,主从没有延迟
;与\G都代表SQL的结尾,有所不同在于分号是横向展示,而\G把每一列纵向显示,适合大数据展示!

回到master主服务器,在mysql里面,进行解锁操作(如果之前有锁表,这里要执行一下解表)
mysql> unlock tables;
3.7 验证测试
master中创建数据库、数据表并插入数据
create database if not exists db_itheima;
use db_itheima;
create table if not exists students(
id int primary key,
name varchar(20)
) default charset=utf8;
insert into students values (1, 'Tom');
insert into students values (2, 'Rose');
select * from students;

在slave端验证:
show databases;
use db_itheima;
show tables;
select * from students;

测试数据(补充):
CREATE DATABASE `bookdb666` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
show databases;
use bookdb666;
CREATE TABLE book666 (ID int,Name char(16),Price int,Publishing char(16));
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('1','《Linux从入门到精通》','66','电子工业出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('2','《云计算趋势》','68','人民邮电出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('3','《操作系统设计与实现》','90','机械工业出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('4','《高性能MySQL1》','71','清华大学出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('5','《高性能MySQL2》','72','清华大学出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('6','《高性能MySQL3》','73','清华大学出版社');
show tables;
select * from book666;
特别注意:
一旦两者配置为主从以后,主master节点既可以读数据也可以写数据。
slave服务器只能读数据,不能写数据!一旦写入数据,主从同步(集群)马上报错!
主从模式原则:主库写、从库读。
传统主从复制(主从同步)常见问题
1、编码问题报错

/etc/my.cnf 中配置的编码不对应
要么
character_set_server=utf8mb4
collation-server=utf8mb4_unicode_ci
要么
character_set_server=utf8
collation-server=utf8_unicode_ci
但是不能
character_set_server=utf8mb4
collation-server=utf8_unicode_ci
2、在 slave 目录下 data 目录为空

同步错误了
把
rsync -va /export/server/mysql/data/ mysql-node2:/export/server/mysql/
改成
rsync -va /export/server/mysql/data mysql-node2:/export/server/mysql/
3、提示 UUID 相同

是两台服务器的uuid冲突导致的。

解决办法:
1、把 master或slave下的 ./data/auto.cnf 删掉
2、重启MySQL服务 systemct restart mysqld
3、重新同步一下即可
4、提示 server-id 相同
server-id => IO错误 => /etc/my.cnf => server-id => 更改完成后,重启mysqld

5、节点 slave 报错 Slave failed to initialize relay log
如果启动slave报如下错误:
mysql> start slave;
ERROR 1872 (HY000): Slave failed to initialize relay log info structure from the repository
解决方案:
在node2服务器上,删除relay-log.info,
重启mysqld服务
stop slave;
reset slave all;
然后重新配置CHANGE REPLICATION SOURCE TO重新同步,
重新启动slave,start slave;
6、两个线程都是 No
这不是错误,一般是因为没有启动主从 => start slave;
7、某一个错误,可能是由于之前配置有问题 => stop slave; reset slave; 然后重新change replication source to
注意:mysql8.0.40版本,停止和启动操作,官方添加一个新的指令stop replica; start replica;
8、两边数据不一致导致同步一直失败 => SQL错误 => 小数据量,只有1-2条不同步,可以考虑跳过这个操作;如果不同步内容较多,就只能把data目录下文件删除,重新同步,重新配置
9、防火墙没关 => IO错误(Connecting)
systemctl stop firewalld
systemctl disable firewalld
iptables -F
iptables -t nat -F
10、启动从节点报错(重置主从)

-- 1. 停止复制
STOP REPLICA;
或者
stop slave;
-- 2. 完全重置复制状态(MySQL 8.0+)
RESET REPLICA ALL; -- 注意:这会清除所有复制配置
或者
reset slave all;
-- 3. change replication source to
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.88.101', -- 注意,这里是master主库地址
SOURCE_USER='slave',
SOURCE_PASSWORD='MySQL@666', -- 以实际为准
SOURCE_LOG_FILE='binlog.000003', -- 以实际为准
SOURCE_LOG_POS=157; -- 以实际为准
-- 4. 启动
start slave;
三、基于全局事务标识符GTID主从复制/主从同步(重点)
作用:主从复制在工作中可能会有两种形式:
传统AB复制,基于binlog日志 + pos点位实现复制
MySQL5.7及以后版本新增基于GTID的主从复制
相对于传统AB复制,基于GTID的主从复制在两方面比较灵活:
配置灵活,不需要关心binlog及点位,直接配置,自动追踪
跳过异常,也比较灵活,简单操作就可以解决主从复制中的异常信息(SQL异常)
1、基于binlog点位主从复制痛点分析
痛点 1:首次开启主从复制的步骤复杂
- 第一次开启主从同步时,要求主库和从库是一致的。
- 找到主库的 binlog 位点。
- 设置从库的 binlog 位点。
- 开启从库的复制线程
发现没有,上述的配置有点儿多。
痛点 2:恢复主从复制的步骤复杂
- 找到从库复制线程停止时的位点。
- 解决复制异常的事务,无法解决时就需要手动跳过指定类型的错误。
- 比如通过设置 slave_skip_errors=1032,1062。当然这个前提条件是跳过这类错误是无损的。
注:1062 错误是插入数据时唯一键冲突;1032 错误是删除数据时找不到行
小结
不论是首次开启同步时需要找位点和设置位点,还是恢复主从复制时,设置位点和忽略错误,
这些步骤都显得过于复杂,而且容易出错。
所以 MySQL 5.6 版本引入了 GTID,解决了这个困难。
2、基于全局事务标识符(GTID)复制
官网:https://dev.mysql.com/doc/refman/8.0/en/replication-gtids.html
事务:增、删、改操作
事务标识符:每执行一次事务操作(增、删、改),系统都会给其定义一个唯一编号(很长的字符串)。
GTID是一个基于原始MySQL服务器生成的一个已经被成功执行的全局事务ID,它由服务器ID以及事务ID组合而成。
GTID = 服务器ID + 事务ID
这个全局事务ID不仅仅在原始服务器上唯一,在所有存在主从关系的MySQL服务器上也是唯一的。
正是因为这样一个特性,使得MySQL的主从复制变得更加简单,以及数据库一致性更可靠。
- 一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
- GTID用来代替传统AB复制方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。
- 在传统的replica(从服务器)端,binlog是不用开启的,但是在GTID中replica(从服务器)端的binlog是必须开启的,目的是记录执行过的GTID(强制)。
master主服务器:开启binlog二进制日志
slave从服务器:既要开启relaylog中继日志,也需要开启binlog二进制日志(获取GTID编号)
GTID的优势
- 更简单的实现 failover,不用以前那样在需要找位点(log_file 和 log_pos)。
- 更简单的搭建主从复制。
- 比传统的AB复制更加安全。
- GTID 是连续的没有空洞的,保证数据的一致性,零丢失。
3、GTID工作原理(理解)
GTID:全局事务ID编号,server_uuid + 事务序号,不管单独MySQL服务器还是主从集群环境中,都是唯一的。
作用:帮助各位小伙伴更好理解GTID相对于传统AB复制的不同!
问题:基于GTID的主从复制,既不需要指定二进制文件名称,也不需要指定二进制文件位置?
那GTID的主从复制是如何捕获差异内容,实现主从同步呢?
主库计算主库 GTID 集合和从库 GTID 的集合的差集,主库推送差集 binlog 给从库。
当从库设置完同步参数后,主库 A 的 GTID 集合记为集合 x,从库 B 的 GTID 集合记为 y。
从库同步的逻辑如下:

- 从库 B 指定主库 A,基于主备协议建立连接(AB服务器首先建立主从复制)。
- 从库 B 把集合 y 发给主库 A。
- 主库 A 计算出集合 x 和集合 y 的差集,也就是集合 x 中存在,集合 y 中不存在的 GTID 集合。比如集合 x 是 1
100,集合 y 是 190,那么这个差集就是 91~100。这里会判断集合 x 是不是包含有集合 y 的所有 GTID,如果不是则说明主库 A 删除了从库 B 需要的 binlog,主库 A 直接返回错误。 - 主库 A 从自己的 binlog 文件里面,找到第一个不在集合 y 中的事务 GTID,也就是找到了 91。
- 主库 A 从 GTID = 91 的事务开始,往后读 binlog 文件,按顺序取 binlog,然后发给 B。
- 从库 B 的 I/O 线程读取 binlog 文件生成 relay log,SQL 线程解析 relay log,然后执行 SQL 语句。
GTID 同步方案和位点同步的方案区别是:
- 位点同步方案是通过人工在从库上指定哪个位点,主库就发哪个位点,不做日志的完整性判断。
- 而 GTID 方案是通过主库来自动计算位点的,不需要人工去设置位点,对运维人员友好。
4、GTID主从复制(主从同步)的配置与实现
作用:基于GTID实现主从复制(重点)
文档:https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-howto.html
环境说明:
关闭防火墙+SELinux、配置IP与主机映射、时间同步、安装必备包
| IP | 主机名 | 角色 |
|---|---|---|
| 192.168.88.101 | mysql-node1 | master(主) |
| 192.168.88.102 | mysql-node2 | slave(从) |
4.1、主从复制(主从同步)环境准备
① 安装必备软件,如vim、wget、rsync
② 配置IP、主机名
③ 配置IP与主机映射 => /etc/hosts
④ 优化Linux系统
⑤ 时间同步
在mysql-node1和mysql-node2上安装一些依赖软件(系统必备软件)
dnf install vim wget rsync telnet net-tools -y
设置主机名称
hostnamectl set-hostname mysql-node1
hostnamectl set-hostname mysql-node2
su或者bash指令
配置IP与主机映射
[root@mysql-node1 ~]# cat /etc/NetworkManager/system-connections/ens160.nmconnection
[connection]
id=ens160
#uuid=39fc68b0-865c-3bd3-a42d-3e1998f8e2cd
type=ethernet
autoconnect-priority=-999
interface-name=ens160
timestamp=1752853607
[ethernet]
[ipv4]
#method=auto
method=manual
addresses=192.168.88.101/24
gateway=192.168.88.2
dns=192.168.88.2,114.114.114.114;
[ipv6]
#addr-gen-mode=eui64
#method=auto
method=disabled
[proxy]
[root@mysql-node1 ~]#
[root@mysql-node1 ~]# vim /etc/hosts
在尾部追加如下内容,mysql-node2也配置同样的参数
192.168.88.101 mysql-node1 node1
192.168.88.102 mysql-node2 node2
优化Linux系统
sed -i -r 's/SELINUX=[ep].*/SELINUX=disabled/g' /etc/selinux/config
setenforce 0
systemctl stop firewalld &> /dev/null
systemctl disable firewalld &> /dev/null
iptables -F
iptables -t nat -F
iptables -P INPUT ACCEPT
iptables -P FORWARD ACCEPT
时间同步(可选)
dnf -y install chrony
systemctl enable chronyd --now
chronos,柯罗诺斯,古希腊神话中掌管时间的神。
chronize指时间上的,sync是指使相同。因此sync-chronize简写synchronize,表示使时间同步;
asynchronize表示异步(计算机专业常用术语)。
到此环境准备完毕了!
4.2、数据库环境准备
安装MySQL8
如果还没有安装MySQL8,则按照以下操作安装。
vim install-mysql8.sh
#!/bin/bash
if rpm -q libaio &> /dev/null; then
echo "libaio已安装,跳过安装"
else
echo "开始安装依赖"
dnf -y install libaio &> /dev/null
if [ $? -ne 0 ];then
echo "libaio安装失败"
exit 1
fi
fi
echo "进行解压操作"
if ls -l mysql-8.0.43-linux-glibc2.28-x86_64 &> /dev/null; then
echo "已解压,跳过"
else
if [ -f mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz ]; then
tar -xf mysql-8.0.43-linux-glibc2.28-x86_64.tar.xz
ls -l mysql-8.0.43-linux-glibc2.28-x86_64
fi
fi
echo "判断是否安装过MariaDB,进行清理"
rpm -qa | grep mariadb | xargs -r dnf remove -y
if [ -f /etc/my.cnf ]; then
rm -rf /etc/my.cnf
fi
id mysql &> /dev/null
[ $? -ne 0 ] && useradd -r -s /sbin/nologin mysql
rm -rf /export/server
mkdir -p /export/server
cp -r mysql-8.0.43-linux-glibc2.28-x86_64 /export/server/mysql
chown -R mysql:mysql /export/server/mysql
echo "正在进入mysql目录,对其进行初始化操作..."
cd /export/server/mysql
bin/mysqld --initialize --user=mysql --basedir=/export/server/mysql --datadir=/export/server/mysql/data 2>&1 | tee /tmp/mysqld.log | grep password | awk '{print $NF}' > /tmp/mysql_temp_password.txt
bin/mysql_ssl_rsa_setup --datadir=/export/server/mysql/data &> /dev/null
cat >/etc/my.cnf<<EOF
[mysqld]
port=3306
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
character_set_server=utf8
collation-server=utf8_unicode_ci
EOF
cat >/etc/systemd/system/mysqld.service<<EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
Type=forking
# MySQL 执行命令及路径
ExecStart=/export/server/mysql/bin/mysqld --daemonize --pid-file=/export/server/mysql/data/mysqld.pid
ExecStop=/export/server/mysql/bin/mysqladmin --defaults-file=/export/server/mysql/my.cnf shutdown
# Ensure MySQL has sufficient time to start up
TimeoutSec=600
# PID 文件路径
PIDFile=/export/server/mysql/data/mysqld.pid
# Enable these options to auto-restart the service if it crashes
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
EOF
echo "正在刷新后台服务,然后启动mysqld..."
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld
#10.重置mysql管理员密码为MySQL@666
echo "正在重置mysql管理员密码..."
cd /export/server/mysql
temp_password=`cat /tmp/mysql_temp_password.txt`
bin/mysqladmin -uroot password 'MySQL@666' -p"$temp_password"
echo 'export PATH=$PATH:/export/server/mysql/bin' >> /etc/profile
source /etc/profile
mysql -V
echo "MySQL8安装成功,安装路径:/export/server/mysql,数据库初始密码:MySQL@666"
注意:执行完install-mysql8.sh安装脚本后,需要在Linux命令行执行source /etc/profile
初始化数据库(强烈建议)
说明:如果是新安装的MySQL,那么这一步可以跳过!
如果/etc/my.cnf有传统主从的配置,那么就要先删除对应的配置。
cat >/etc/my.cnf<<EOF
[mysqld]
port=3306
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
character_set_server=utf8
collation-server=utf8_unicode_ci
EOF
systemctl stop mysqld
pkill mysqld
rm -rf /export/server/mysql/data/*
rm -rf /tmp/mysqld.log
/export/server/mysql/bin/mysqld --initialize --user=mysql --basedir=/export/server/mysql &>/tmp/mysqld.log
grep password /tmp/mysqld.log | awk '{print $NF}'
systemctl start mysqld
mysql -uroot -p'初始密码'
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@666';
FLUSH PRIVILEGES;
EXIT;
mysql -uroot -p'MySQL@666'
注意:如果没有拿到初始密码,请按照以下方法来设置密码!
systemctl stop mysqld
pkill mysqld
mysqld --user=mysql --skip-grant-tables --skip-networking &
mysql
FLUSH PRIVILEGES;
ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@666';
FLUSH PRIVILEGES;
EXIT;
pkill mysqld
systemctl start mysqld
systemctl status mysqld --no-pager
mysql -uroot -p'MySQL@666'
注意:如果从库状态异常以及不能写入数据,则按照以下操作进行。

[root@mysql-node2 ~]# grep read /etc/my.cnf
read-only=1
super-read-only=1
[root@mysql-node2 ~]# vim /etc/my.cnf
[root@mysql-node2 ~]# cat /etc/my.cnf
[mysqld]
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
port=3306
character_set_server=utf8mb4
collation-server=utf8mb4_unicode_ci
[root@mysql-node2 ~]# systemctl stop mysqld
[root@mysql-node2 ~]# pkill mysqld
[root@mysql-node2 ~]# mysqld --user=mysql --skip-grant-tables --skip-networking &
[1] 39313
[root@mysql-node2 ~]# 2025-11-27T08:03:19.304049Z 0 [System] [MY-010116] [Server] /export/server/mysql/bin/mysqld (mysqld 8.0.43) starting as process 39313
2025-11-27T08:03:19.318454Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
2025-11-27T08:03:19.499254Z 1 [System] [MY-013577] [InnoDB] InnoDB initialization has ended.
2025-11-27T08:03:19.854084Z 0 [Warning] [MY-010068] [Server] CA certificate ca.pem is self signed.
2025-11-27T08:03:19.854749Z 0 [System] [MY-013602] [Server] Channel mysql_main configured to support TLS. Encrypted connections are now supported for this channel.
2025-11-27T08:03:19.880081Z 0 [System] [MY-011323] [Server] X Plugin ready for connections. Socket: /tmp/mysqlx.sock
2025-11-27T08:03:19.880607Z 0 [System] [MY-010931] [Server] /export/server/mysql/bin/mysqld: ready for connections. Version: '8.0.43' socket: '/tmp/mysql.sock' port: 0 MySQL Community Server - GPL.
[root@mysql-node2 ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 7
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'MySQL@666';
Query OK, 0 rows affected (0.01 sec)
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)
mysql> EXIT;
Bye
[root@mysql-node2 ~]# mysql -uroot -pMySQL@666
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
mysql> ^DBye
[root@mysql-node2 ~]#
4.3、rsync 同步 data 目录与删除 auto.cnf 文件(可选)
在master上,停止mysqld,然后同步数据到slave中
# 1、停止 master服务器 上的 MySQL 服务(可选)
systemctl stop mysqld
# 2、在 master 上执行 rsync 同步 data 目录(可选)
rsync -av --delete /export/server/mysql/data/ mysql-node2:/export/server/mysql/data/
# 3、分别在 master 和 slave 删除 auto.cnf 文件
rm -f /export/server/mysql/data/auto.cnf
4.4、配置数据库
修改 master 主库的配置文件
cat >/etc/my.cnf<<EOF
[mysqld]
# 基础路径
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
port=3306
# 日志
log-error=/export/server/mysql/master.err
log-bin=/export/server/mysql/data/binlog
server-id=101
# 字符集
character_set_server=utf8mb4
collation-server=utf8mb4_unicode_ci
# GTID 配置
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
binlog_format=ROW
binlog_row_image=FULL
sync_binlog=1
expire_logs_days=7
# 复制过滤:不同步的系统库
binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
# InnoDB 优化
default_storage_engine=InnoDB
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_log_buffer_size=64M
innodb_flush_log_at_trx_commit=1
innodb_file_per_table=1
# 连接配置
max_connections=500
max_connect_errors=1000000
table_open_cache=2000
# 慢查询日志
slow_query_log=1
slow_query_log_file=/export/server/mysql/slow.log
long_query_time=1
[client]
socket=/tmp/mysql.sock
default-character-set=utf8mb4
EOF
/etc/my.cnf配置文件详细解释:
cat >/etc/my.cnf<<EOF
# ==============================================
# MySQL 核心配置文件 /etc/my.cnf
# 作用:定义 MySQL 服务启动、运行、存储、复制、优化等所有规则
# ==============================================
[mysqld]
# --------------------------
# 1. 基础路径与端口配置
# --------------------------
# MySQL 安装根目录
basedir=/export/server/mysql
# MySQL 数据存放目录(库表文件都在这里)
datadir=/export/server/mysql/data
# MySQL 本地连接套接字文件(Linux 本地快速连接用)
socket=/tmp/mysql.sock
# MySQL 对外服务端口(默认 3306)
port=3306
# --------------------------
# 2. 日志与主从复制基础配置
# --------------------------
# MySQL 错误日志路径(启动失败、运行异常都在这里看)
log-error=/export/server/mysql/master.err
# 开启二进制日志 binlog,用于主从复制 + 数据恢复
log-bin=/export/server/mysql/data/binlog
# 服务器唯一 ID(主从架构必须不同,不能重复)
server-id=101
# --------------------------
# 3. 字符集配置(支持表情符号)
# --------------------------
# 服务端默认字符集:utf8mb4 完整支持 emoji/特殊符号
character_set_server=utf8mb4
# 排序规则(统一字符集排序)
collation-server=utf8mb4_unicode_ci
# --------------------------
# 4. GTID 主从复制高级配置(高可用必备)
# --------------------------
# 开启 GTID 模式(自动管理主从复制位置,不用手动找点位)
gtid_mode=ON
# 强制 GTID 一致性(保证主从数据绝对一致)
enforce_gtid_consistency=ON
# 从库也记录 binlog(级联复制/双主架构必须开启)
log_slave_updates=ON
# binlog 格式:ROW 行模式(只记录变更行,主从最安全)
binlog_format=ROW
# 记录完整行数据(更新前后都记录,数据恢复最完整)
binlog_row_image=FULL
# 每次事务都刷写 binlog 到磁盘(数据最安全,不丢日志)
sync_binlog=1
# binlog 自动清理天数:7 天后自动删除,避免占满磁盘
expire_logs_days=7
# --------------------------
# 5. 复制过滤:不需要同步的系统库
# --------------------------
# 不同步 information_schema 系统库
binlog-ignore-db=information_schema
# 不同步 mysql 权限库
binlog-ignore-db=mysql
# 不同步 performance_schema 性能库
binlog-ignore-db=performance_schema
# 不同步 sys 系统库
binlog-ignore-db=sys
# --------------------------
# 6. InnoDB 存储引擎优化(核心性能配置)
# --------------------------
# 默认存储引擎:InnoDB(支持事务、外键、崩溃恢复)
default_storage_engine=InnoDB
# InnoDB 缓冲池大小(建议 = 服务器内存的 50%~70%)
innodb_buffer_pool_size=1G
# InnoDB 日志文件大小(越大刷盘越少,性能越好)
innodb_log_file_size=256M
# InnoDB 日志缓冲区
innodb_log_buffer_size=64M
# 每次事务提交都刷日志到磁盘(ACID 强一致,最安全)
innodb_flush_log_at_trx_commit=1
# 每个库一个独立表空间文件(方便维护、迁移、回收空间)
innodb_file_per_table=1
# --------------------------
# 7. 连接与并发配置
# --------------------------
# 最大同时连接数(支持多少客户端同时连 MySQL)
max_connections=500
# 最大允许错误连接次数(防暴力破解,设大一点避免误拦截)
max_connect_errors=1000000
# 打开表缓存数量(提升多表查询性能)
table_open_cache=2000
# --------------------------
# 8. 慢查询日志(SQL 优化必备)
# --------------------------
# 开启慢查询日志
slow_query_log=1
# 慢查询日志存放路径
slow_query_log_file=/export/server/mysql/slow.log
# 超过 1 秒的 SQL 会被记录(方便定位慢 SQL)
long_query_time=1
# --------------------------
# 客户端连接配置
# --------------------------
[client]
# 客户端本地连接使用的 socket 文件(和 mysqld 保持一致)
socket=/tmp/mysql.sock
# 客户端默认字符集
default-character-set=utf8mb4
EOF
修改 slave 从库配置文件
cat >/etc/my.cnf<<EOF
[mysqld]
# 基础路径
basedir=/export/server/mysql
datadir=/export/server/mysql/data
socket=/tmp/mysql.sock
port=3306
# 日志
log-error=/export/server/mysql/slave.err
log-bin=/export/server/mysql/data/binlog
relay-log=/export/server/mysql/data/relaylog
relay-log-index=/export/server/mysql/data/relaylog.index
server-id=102
# 字符集
character_set_server=utf8mb4
collation-server=utf8mb4_unicode_ci
# GTID 配置
gtid_mode=ON
enforce_gtid_consistency=ON
log_slave_updates=ON
binlog_format=ROW
binlog_row_image=FULL
sync_binlog=1
expire_logs_days=7
# 复制过滤:不同步的系统库
replicate-ignore-db=information_schema
replicate-ignore-db=mysql
replicate-ignore-db=performance_schema
replicate-ignore-db=sys
# 从库只读
read_only=ON
super_read_only=ON
skip-slave-start=1 # 避免重启时自动启动复制线程,需手动控制
# 复制优化
relay_log_recovery=1
sync_relay_log=0
sync_relay_log_info=0
sync_master_info=0
# InnoDB 优化(适合从库,查询压力大)
default_storage_engine=InnoDB
innodb_buffer_pool_size=1G
innodb_log_file_size=256M
innodb_log_buffer_size=64M
innodb_flush_log_at_trx_commit=2 # 从库可设置为 2,提高复制与查询性能
innodb_file_per_table=1
# 连接配置
max_connections=500
max_connect_errors=1000000
table_open_cache=2000
# 慢查询日志(从库常用于报表分析)
slow_query_log=1
slow_query_log_file=/export/server/mysql/slow.log
long_query_time=1
[client]
socket=/tmp/mysql.sock
default-character-set=utf8mb4
EOF
/etc/my.cnf配置文件详细解释:
cat >/etc/my.cnf<<EOF
[mysqld]
# ==========================
# 基础路径配置
# ==========================
# MySQL 安装根目录
basedir=/export/server/mysql
# 数据文件存储目录
datadir=/export/server/mysql/data
# 本地连接套接字文件
socket=/tmp/mysql.sock
# 服务端口
port=3306
# ==========================
# 日志与主从复制标识
# ==========================
# 从库错误日志
log-error=/export/server/mysql/slave.err
# 开启二进制日志(从库也建议开启,用于级联复制/恢复)
log-bin=/export/server/mysql/data/binlog
# 中继日志:从库接收主库 binlog 后写入的日志(复制核心文件)
relay-log=/export/server/mysql/data/relaylog
# 中继日志索引文件
relay-log-index=/export/server/mysql/data/relaylog.index
# 服务器唯一 ID,主从架构必须唯一,主库 101,从库 102
server-id=102
# ==========================
# 字符集配置
# ==========================
# 服务端默认字符集,支持表情符号
character_set_server=utf8mb4
# 排序规则
collation-server=utf8mb4_unicode_ci
# ==========================
# GTID 主从复制配置(高可用必备)
# ==========================
# 开启 GTID 模式,自动管理复制位置
gtid_mode=ON
# 强制 GTID 一致性,保证主从不丢数据
enforce_gtid_consistency=ON
# 从库接收主库日志后,也写入自己的 binlog(级联复制必备)
log_slave_updates=ON
# binlog 格式:行模式,主从最安全
binlog_format=ROW
# 记录完整行数据,便于数据恢复
binlog_row_image=FULL
# 每次事务刷写 binlog 到磁盘,保证日志安全
sync_binlog=1
# 二进制日志自动清理周期 7 天
expire_logs_days=7
# ==========================
# 复制过滤:从库不同步的系统库
# ==========================
# 不同步系统库 information_schema
replicate-ignore-db=information_schema
# 不同步权限库 mysql
replicate-ignore-db=mysql
# 不同步性能库 performance_schema
replicate-ignore-db=performance_schema
# 不同步系统库 sys
replicate-ignore-db=sys
# ==========================
# 从库安全配置(核心!)
# ==========================
# 普通用户只读,无法写入
read_only=ON
# 超级管理员也只读,彻底防止从库被误写入
super_read_only=ON
# 开机/重启 MySQL 时,不自动启动复制线程,必须手动启动,防止异常复制
skip-slave-start=1
# ==========================
# 从库复制性能优化
# ==========================
# 中继日志自动修复,崩溃后不损坏复制
relay_log_recovery=1
# 不实时刷盘中继日志,提升从库性能(从库专用优化)
sync_relay_log=0
# 不同步记录复制位置信息,提高性能
sync_relay_log_info=0
# 不同步记录主库信息,提高性能
sync_master_info=0
# ==========================
# InnoDB 存储引擎优化
# ==========================
# 默认存储引擎 InnoDB
default_storage_engine=InnoDB
# InnoDB 缓冲池,提升查询性能
innodb_buffer_pool_size=1G
# InnoDB 日志文件大小
innodb_log_file_size=256M
# InnoDB 日志缓冲区
innodb_log_buffer_size=64M
# 从库专用优化:每秒刷一次日志到磁盘,比主库更快,允许极少量丢失风险
innodb_flush_log_at_trx_commit=2
# 每个表独立表空间,方便维护
innodb_file_per_table=1
# ==========================
# 连接与并发配置
# ==========================
# 最大连接数
max_connections=500
# 最大错误连接数,防止被误拦截
max_connect_errors=1000000
# 打开表缓存,提升多表查询速度
table_open_cache=2000
# ==========================
# 慢查询日志(从库常用于查询/报表)
# ==========================
# 开启慢查询日志
slow_query_log=1
# 慢查询日志路径
slow_query_log_file=/export/server/mysql/slow.log
# 执行超过 1 秒的 SQL 记录为慢查询
long_query_time=1
# ==========================
# 客户端连接配置
# ==========================
[client]
# 客户端本地连接 socket
socket=/tmp/mysql.sock
# 客户端默认字符集
default-character-set=utf8mb4
EOF
master节点/slave节点,优化配置,重启MySQL
# master 主服务器
touch /export/server/mysql/master.err
chown -Rf mysql:mysql /export/server/mysql
systemctl restart mysqld
systemctl status mysqld --no-pager
# slave 从服务器
touch /export/server/mysql/slave.err
chown -Rf mysql:mysql /export/server/mysql
systemctl restart mysqld
systemctl status mysqld --no-pager


4.5、创建账号并授权
master主服务器创建同步账号并授权:
mysql -uroot -p'MySQL@666'
CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'MySQL@666';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
flush privileges;
[root@mysql-node1 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> CREATE USER 'slave'@'%' IDENTIFIED WITH mysql_native_password BY 'MySQL@666';
Query OK, 0 rows affected (0.01 sec)
mysql> GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'slave'@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql>
[root@mysql-node2 ~]# mysql -uslave -pMySQL@666 -h192.168.88.101
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| performance_schema |
+--------------------+
2 rows in set (0.00 sec)
mysql>
4.6、启动主从同步
从节点设置主库信息(slave从服务器基于change replication source进行同步操作)
以下是官网提供的关键设置参考(仅参考,需要调整为自己master服务器信息)
https://dev.mysql.com/doc/refman/8.0/en/replication-gtids-howto.html
在 slave 从库上执行的命令,语法参考
mysql> CHANGE REPLICATION SOURCE TO
SOURCE_HOST = host,
SOURCE_PORT = port,
SOURCE_USER = user,
SOURCE_PASSWORD = password,
SOURCE_AUTO_POSITION = 1;
SOURCE_AUTO_POSITION = 1: 这告诉从服务器使用自动位置跟踪功能,以便它可以自动从主服务器获取最新的二进制日志事件,而无需手动指定位置。
具体代码为:
注意:在slave从服务器上执行以下操作!
[root@mysql-node2 ~]# mysql -uroot -p'MySQL@666'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 8
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> change replication source to
source_host='192.168.88.101',
source_port=3306,
source_user='slave',
source_password='MySQL@666',
source_auto_position=1;

和AB复制最大的不同就是不需要寻找binlog以及对应的pos点位,
只需要source_auto_position=1就可以自动同步!
第三步:开启从库复制
在从库上执行,
mysql> start replica; # 这是新命令,start slave; 依然可用,只是未来版本可能会逐步废除。
查看从库的复制状态
在从库上执行,
mysql> show slave status\G
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
...

5、测试主从复制(主从同步)结果
在 master 主库中,增加数据
create database if not exists db_itheima;
show databases;
use db_itheima;
create table if not exists students(
id int primary key,
name varchar(20)
) default charset=utf8;
insert into students values (10, 'lisa');
insert into students values (11, 'Rose');
select * from students;
show databases;

在 slave 从库查看数据
mysql> show databases;
mysql> use db_itheima;
mysql> show tables;
mysql> select * from students;

在 slave 从库查看复制状态
mysql> select * from mysql.gtid_executed;

测试数据(补充):
CREATE DATABASE `bookdb666` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
show databases;
use bookdb666;
CREATE TABLE book666 (ID int,Name char(16),Price int,Publishing char(16));
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('1','《Linux从入门到精通》','66','电子工业出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('2','《云计算趋势》','68','人民邮电出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('3','《操作系统设计与实现》','90','机械工业出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('4','《高性能MySQL1》','71','清华大学出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('5','《高性能MySQL2》','72','清华大学出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('6','《高性能MySQL3》','73','清华大学出版社');
show tables;
select * from book666;
show databases;
6、GTID结构(了解)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.101
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000004
Read_Master_Log_Pos: 1961
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 2171
Relay_Master_Log_File: binlog.000004
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 1961
Relay_Log_Space: 2374
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 101
Master_UUID: 48da8bfd-9c4d-11f0-96cb-000c29377627
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 48da8bfd-9c4d-11f0-96cb-000c29377627:1-7
Executed_Gtid_Set: 48da8bfd-9c4d-11f0-96cb-000c29377627:1-7
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
mysql> select * from mysql.gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 48da8bfd-9c4d-11f0-96cb-000c29377627 | 1 | 2 |
| 48da8bfd-9c4d-11f0-96cb-000c29377627 | 4 | 6 |
| 48da8bfd-9c4d-11f0-96cb-000c29377627 | 7 | 7 |
+--------------------------------------+----------------+--------------+
3 rows in set (0.00 sec)
mysql>
A — SHOW SLAVE STATUS\G****(复制状态)字段详解(结合当前输出)
- Slave_IO_State: Waiting for source to send event IO 线程状态,表示 IO 线程正在等待主库发送新的 binlog 事件 —— 正常,说明已连接且无未接事件。
- Master_Host / Master_User / Master_Port 主库地址、用于连接的复制账号、端口(你的是 192.168.88.101 / slave / 3306)。
- Connect_Retry: 60 IO 线程在连接断开后重试的秒数间隔。
- Master_Log_File: binlog.000004 IO 线程当前从主库读取到的主库二进制日志文件名(当前参考的 master binlog 文件)。
- Read_Master_Log_Pos: 1961 IO 线程已经从
Master_Log_File读取到的字节位置(下一个要读/已读的位置)。 - Relay_Log_File / Relay_Log_Pos 从库本地的 relay log 文件及位置:IO 线程把从主读到的事件写入 relay log,SQL 线程从这里读取执行。你的
relaylog.000002:2171表示本地 relay 文件和位置。 - Relay_Master_Log_File: binlog.000004 该 relay 中事件对应的主库 binlog 文件名(把主库文件名记下来,便于定位)。
- Slave_IO_Running: Yes / Slave_SQL_Running: Yes IO 和 SQL 线程均正常运行 —— 复制线程总体是健康的。
- Replicate_Do_DB / Replicate_Ignore_DB 你看到
Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys:这是从库的 复制过滤(在从库上配置的replicate-ignore-db)。注意:replicate-ignore-db是基于 session 的 default database 判断,不总是适用于所有事件(见建议部分)。 - Last_Errno / Last_Error / Last_IO_Errno / Last_SQL_Errno 等 = 0 / 空 没有最近错误 —— 好事。
- Exec_Master_Log_Pos: 1961 SQL 线程执行到的“主库 binlog 位置”。如果使用基于位置的复制,这和
Read_Master_Log_Pos的关系很关键;GTID 模式下不常直接依赖文件+pos,但仍会显示。 - Relay_Log_Space: 2374 relay log 的总字节空间(或大小),可用于判断未处理的 relay 数据量。
- Seconds_Behind_Master: 0 从库与主库“延迟”时间(秒)。0 表示从库已追上主库,没有延迟(注意:这个值有时会因为 SQL 线程在执行长事务显示为 NULL 或大数)。
- Master_Server_Id: 101 / Master_UUID: 48da8bfd-... 主库的 server_id 与 UUID(重要)。
Master_UUID就是你 GTID 表里source_uuid的那个 UUID。 - Master_Info_File: mysql.slave_master_info 存放主库连接信息的本地文件名(在 datadir 下)。
- Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates SQL 线程当前状态:已读完所有 relay log,正在等待更多更新 —— 说明从库已应用到最新。
- Retrieved_Gtid_Set: 48da8bfd-...:1-7 从主库检索到(receive)的 GTID 集(字符串形式)。表示已经收到 主库上这些 GTID 的事件(可能还未应用,或已应用)。
- Executed_Gtid_Set: 48da8bfd-...:1-7 已在本地执行/应用(applied)的 GTID 集。与你的输出相同,说明已收到的 GTID 都已执行(Replica 已追上)。
- Auto_Position: 1 表示复制使用 GTID(auto position)方式(
MASTER_AUTO_POSITION=1),不是通过文件/位置手工定位。
B — GTID 结构与 mysql.gtid_executed 表如何对应
GTID 基本格式回顾
GTID 形如:
source_uuid:transaction_id
例如你主库的 UUID 是 48da8bfd-9c4d-11f0-96cb-000c29377627,事务 id 从 1 开始递增。 GTID 集通常写成:48da8bfd-...:1-7(表示 1 到 7 都存在)。
SHOW SLAVE STATUS 里的两项
- Retrieved_Gtid_Set:从主接收到的 GTID(已被 IO 线程拉到本地 relaylog)。
- Executed_Gtid_Set:实际已经在从库上应用(SQL 线程已执行)的 GTID。
输出中两者都为 :1-7,说明从库已把 1~7 都拉下并应用完毕(复制已同步)。
mysql.gtid_executed 表
查询到的表:
source_uuid interval_start interval_end
48da8bfd-... 1 2
48da8bfd-... 4 6
48da8bfd-... 7 7
这张表以区间行(interval)形式记录已经执行的 GTID 范围。把行合并起来,逻辑上代表的 GTID 集是:
48da8bfd-...:1-2,4-6,7
合并(并集)后,就是 1-2,4-7 —— 与 1-7 比较会发现“缺 3”。但你 SHOW SLAVE STATUS 显示的是 1-7(连续)。出现看似“不一致”的情况,通常有下面几种可能原因(按轻重排列):
常见原因与如何核实
- 显示时点差异 / 内存 vs 磁盘的状态
-
SHOW SLAVE STATUS和@@GLOBAL.gtid_executed返回的是内存中的“权威” GTID 集字符串;而mysql.gtid_executed表是磁盘表的行表示,可能在内部合并/刷新策略上存在短时差异。 -
核实命令:
-
SELECT @@GLOBAL.gtid_executed; SELECT * FROM mysql.gtid_executed\G SHOW REPLICA STATUS\G -
以判断内存表示与表中记录是否一致。
-
- 事务 3 来自不同的 source_uuid
- 如果事务 3 是由另一个 server_uuid 产生(不同主/中间主),那它会在另外一行里(不同 source_uuid)。你的表中 source_uuid 都相同,所以这点可排除(在你的例子中
Master_UUID与source_uuid相同)。
- 如果事务 3 是由另一个 server_uuid 产生(不同主/中间主),那它会在另外一行里(不同 source_uuid)。你的表中 source_uuid 都相同,所以这点可排除(在你的例子中
- 表格分段/碎片化(历史原因)
mysql.gtid_executed行可能因为历史删除/合并/内部实现的碎片而显示多个不连续的区间;但内存集合已将区间合并成1-7。这是一种实现细节,不是数据丢失。- 如果你怀疑真有缺失,可以用
mysqlbinlog在主库上查看对应 binlog,确认主库是否真的存在:3这笔事务。
- 显示/输出的笔误或快照是不同时间点
- 有时用户贴出的两个查询并非同一刻执行,导致看起来不一致。尽量同时执行上面几个命令并比较。
如何查看 GTID 在 binlog 里的真实记录
在主库机器上运行(示例):
mysqlbinlog --base64-output=DECODE-ROWS -v /path/to/binlog.000004 | sed -n '1,200p'
你可以在输出中看到 SET @@SESSION.GTID_NEXT='48da8bfd-...:3' 之类的行,确认事务 3 的存在与细节。
常用检查清单(一步到位)
- 在从库上:
SHOW REPLICA STATUS\G
SELECT @@GLOBAL.gtid_executed;
SELECT * FROM mysql.gtid_executed\G
SELECT @@server_uuid;
- 在主库上:
SHOW MASTER STATUS\G
SELECT @@server_uuid;
mysqlbinlog --base64-output=DECODE-ROWS -v /export/server/mysql/data/binlog.000004 | less
或者
mysqlbinlog --no-defaults --base64-output=DECODE-ROWS -v /export/server/mysql/data/binlog.000004
- 对比
Master_UUID与source_uuid是否一致;对比Retrieved_Gtid_Set与Executed_Gtid_Set是否一致(若一致且Seconds_Behind_Master=0,复制是“赶上”的状态)。
关于 replicate-ignore-db 的额外提醒
你在 Replicate_Ignore_DB 列看到了 information_schema,mysql,performance_schema,sys —— 这能在很多场景下阻止系统库被应用,但:
replicate-ignore-db基于 当前 default database 判断(即USE db情况),对使用完整表名的 DML/DDL 可能不会生效。- 更可靠的做法通常是:在主库上用
binlog-ignore-db(若你确实要完全不记录某 DB 的 binlog),或者在从库用replicate-wild-ignore-table精确过滤db.%。小心使用以免漏掉或误过滤业务表。
结论
- 复制线程健康(IO/SQL 都运行,
Seconds_Behind_Master=0,Replica has read all relay log)。 Retrieved_Gtid_Set与Executed_Gtid_Set都为48da8bfd-...:1-7→ 说明 GTID 1~7 已被接收并应用。mysql.gtid_executed表显示为若干区间(1-2,4-6,7),这在表示形式上与1-7有差异(可能是表记录碎片或显示时点差异)。要看“权威”字符串表示请查询SELECT @@GLOBAL.gtid_executed;,要查看主库的实际 GTID 事件请用mysqlbinlog查看 binlog。
7、主从同步(复制)报错修复(扩展)
模拟从库写入数据、主库对表进行写入数据。
master数据库中:
create database db_itheima;
use db_itheima;
create table students(
id int primary key,
name varchar(20)
) default charset=utf8;
insert into students values (1, 'Tom');
insert into students values (2, 'Rose');
slave数据库中,错误的插入一条记录
编辑slave服务器中的/etc/my.cnf文件
在从库中,
删除 read-only=on
然后重启 mysqld
systemctl restart mysqld
在从库中,
use db_itheima;
insert into students values (3, 'Jack');
回到master数据库,也重新插入一条记录
insert into students values (3, 'Jennifer');
slave从服务器查看同步状态:
show slave status\G
观察从库复制是否报错
查看从库同步状态:
mysql> show slave status \G
...
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1146
Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'f1b88047-a5ea-11ed-8ee1-246e9657f7a0:7' at master log mysql-bin.000011, end_log_pos 868. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
Skip_Counter: 0
Exec_Master_Log_Pos: 550
Relay_Log_Space: 1285
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1146
Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'f1b88047-a5ea-11ed-8ee1-246e9657f7a0:7' at master log mysql-bin.000011, end_log_pos 868. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: f1b88047-a5ea-11ed-8ee1-246e9657f7a0
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 230227 14:53:19
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-7
Executed_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-6
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.01 sec)
复制报错信息
Retrieved_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-7
Executed_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-6
事务接收了1-7,但7没有执行成功。f1b88047-a5ea-11ed-8ee1-246e9657f7a0:7
在主库继续进行其他事务,观察gitd是否复制成功
mysql> create table test02_01(id int ,name varchar(10));
Query OK, 0 rows affected (0.08 sec)
mysql> insert into test02_01 values(1,'jkl');
Query OK, 1 row affected (0.00 sec)
从库状态
mysql> show replica status\G
...
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1146
Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'f1b88047-a5ea-11ed-8ee1-246e9657f7a0:7' at master log mysql-bin.000011, end_log_pos 868. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
Skip_Counter: 0
Exec_Master_Log_Pos: 550
Relay_Log_Space: 1851
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1146
Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction 'f1b88047-a5ea-11ed-8ee1-246e9657f7a0:7' at master log mysql-bin.000011, end_log_pos 868. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
Replicate_Ignore_Server_Ids:
Master_Server_Id: 1
Master_UUID: f1b88047-a5ea-11ed-8ee1-246e9657f7a0
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 230227 14:53:19
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-9
Executed_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-6
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
事务,7-9未备执行,也就是说后续复制中断
Retrieved_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-9
Executed_Gtid_Set: f1b88047-a5ea-11ed-8ee1-246e9657f7a0:1-6
解决方案:
在实际工作中,如果主从配置不同步,出现了异常情况,解决方案有二
情况一:如果错误事务较少,可以尝试跳过错误事务,进行修复。
情况二:如果错误事务较多,必须要重新配置了主从同步,把主服务器数据进行导出,然后在从服务器进行重新导入,然后重新配置主从。
采用从库跳过错误事务修复
停止slave进程
mysql> STOP REPLICA;
设置事务号,事务号从 Retrieved_Gtid_Set 获取,在session里设置gtid_next,即跳过这个GTID
mysql> SET @@SESSION.GTID_NEXT= 'f1b88047-a5ea-11ed-8ee1-246e9657f7a0:7'
案例演示(实际改成你们自己的事务):
set @@SESSION.GTID_NEXT='这个位置到底如何编写';
Retrieved_Gtid_Set: 0883a39c-eb54-11ef-879d-000c29d9e0c0:1-12
Executed_Gtid_Set: 08817f5d-eb54-11ef-9fcd-000c296d8526:1-2
第一步:找两者差异
接收到1-12,实际执行1-2,从第3个事务开始同步异常,所以要尝试跳过事务编号3的事务
第二步:找主机uuid
主机uuid主要看接收端uuid编号 => Retrieved_Gtid_Set
set @@SESSION.GTID_NEXT='0883a39c-eb54-11ef-879d-000c29d9e0c0:3';
设置空事务,填充跳过的事务(让事务编号连续)
mysql> BEGIN; COMMIT;
恢复自增事务号
mysql> SET SESSION GTID_NEXT = AUTOMATIC;
启动slave进程
mysql> START REPLICA;
事务已经跳过,创建表已经同步
mysql> show tables;
重新同步以后,可以在从节点,删除冲突数据或者异常数据,重新执行同步,让两端高度一致!

8、重置主从同步(复制)的方法(扩展)
一般在从库上执行下面命令,重置(reset)所有配置,再change,再启动服务,并查看记过
mysql> stop slave;
或者
mysql> stop replica;
mysql> reset slave; # 一般在从库执行,如果遇到很难搞定的问题,在主库和从库都要执行
或者
mysql> reset replica;
或者
mysql> reset slave all; # 一般在从库执行,如果遇到很难搞定的问题,在主库和从库都要执行
或者
mysql> reset replica all;
mysql> change replication source to
source_host='192.168.88.101',
source_port=3306,
source_user='slave',
source_password='MySQL@666',
source_auto_position=1;
mysql> start slave;
或者
mysql> start replica;
mysql> show slave status\G
或者
mysql> show replica status\G
| 命令 | 作用 | 是否删除复制配置 |
|---|---|---|
| reset replica; | 重置进度、清中继日志 | 不删 |
| reset replica all; | 彻底重置 + 删除主库连接信息 | 删除 |
经典问题(跳过错误)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.101
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000005
Read_Master_Log_Pos: 2777
Relay_Log_File: relaylog.000002
Relay_Log_Pos: 411
Relay_Master_Log_File: binlog.000005
Slave_IO_Running: Yes
Slave_SQL_Running: No
Replicate_Do_DB:
Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 1051
Last_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '8d18488c-3fb6-11f1-ba96-0050562cce4c:27' at source log binlog.000005, end_log_pos 2554. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
Skip_Counter: 0
Exec_Master_Log_Pos: 2332
Relay_Log_Space: 1059
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 1051
Last_SQL_Error: Coordinator stopped because there were error(s) in the worker(s). The most recent failure being: Worker 1 failed executing transaction '8d18488c-3fb6-11f1-ba96-0050562cce4c:27' at source log binlog.000005, end_log_pos 2554. See error log and/or performance_schema.replication_applier_status_by_worker table for more details about this failure or others, if any.
Replicate_Ignore_Server_Ids:
Master_Server_Id: 101
Master_UUID: 8d18488c-3fb6-11f1-ba96-0050562cce4c
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State:
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp: 260424 20:48:51
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 8d18488c-3fb6-11f1-ba96-0050562cce4c:27-28
Executed_Gtid_Set: 4daa2ed9-3fb7-11f1-8500-0050563e2b77:1-3,
8d18488c-3fb6-11f1-ba96-0050562cce4c:1-26
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
mysql>
分析问题
Retrieved_Gtid_Set: 8d18488c-3fb6-11f1-ba96-0050562cce4c:27-28
Executed_Gtid_Set: 4daa2ed9-3fb7-11f1-8500-0050563e2b77:1-3,
8d18488c-3fb6-11f1-ba96-0050562cce4c:1-26
主库产生了事务:1~28
从库已执行:主库 1~26
从库已拉取未执行:主库 27~28
无数据丢失、无延迟堆积,只是还没来得及执行最后两个事务
解决方法
手动跳过 MySQL 复制报错的 GTID 27号事务
-- 1. 停止从库复制线程(IO线程 + SQL线程),确保当前无复制操作执行
STOP REPLICA;
-- 2. 指定下一个要执行的GTID为出错事务:8d18488c-3fb6-11f1-ba96-0050562cce4c:27
-- 作用:强制让MySQL认为下一个执行的就是这个出错的GTID
SET GTID_NEXT='8d18488c-3fb6-11f1-ba96-0050562cce4c:27';
-- 3. 手动开启一个空事务并提交
-- 作用:空执行该GTID,不做任何数据修改,仅将此GTID标记为已执行,从而跳过出错事务
BEGIN;
COMMIT;
-- 4. 恢复GTID自动分配模式(必须执行,否则后续复制无法正常工作)
SET GTID_NEXT=AUTOMATIC;
-- 5. 重新启动从库复制线程,继续同步主库数据
START REPLICA;
-- 6. 查看从库复制状态,验证是否修复成功(重点查看 Replica_SQL_Running、Last_Error 字段)
SHOW REPLICA STATUS\G
手动跳过 MySQL 复制报错的 GTID 28号事务
STOP REPLICA;
SET GTID_NEXT='8d18488c-3fb6-11f1-ba96-0050562cce4c:28';
BEGIN;
COMMIT;
SET GTID_NEXT=AUTOMATIC; # 恢复GTID自动分配模式
START REPLICA;
SHOW REPLICA STATUS\G
再次测试
CREATE DATABASE `bookdb666` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
show databases;
use bookdb666;
CREATE TABLE book666 (ID int,Name char(16),Price int,Publishing char(16));
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('1','《Linux从入门到精通》','66','电子工业出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('2','《云计算趋势》','68','人民邮电出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('3','《操作系统设计与实现》','90','机械工业出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('4','《高性能MySQL1》','71','清华大学出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('5','《高性能MySQL2》','72','清华大学出版社');
INSERT INTO book666(ID,Name,Price,Publishing) VALUES('6','《高性能MySQL3》','73','清华大学出版社');
show tables;
select * from book666;
彻底重建主从同步

现在这种已经出现 1051(表不存在)的情况,本质就是数据不一致,重建是最干净的方案。
重建思路(先理解再操作)
主从重建核心就三步:
- 主库导出“干净一致”的数据
- 从库清空 → 导入数据
- 重新建立 GTID 复制
方案(推荐):基于 GTID 的标准重建
第一步:主库做全量备份
在主库执行:
mysqldump -uroot -p'MySQL@666' \
--all-databases \
--single-transaction \
--master-data=2 \
--set-gtid-purged=ON \
--triggers --routines --events \
> full.sql
参数解释
--single-transaction保证一致性(InnoDB)--master-data=2记录 binlog 位点(可注释)--set-gtid-purged=ON关键(GTID复制必须)
第二步:把数据传到从库
scp full.sql root@从库IP:/root/
第三步:从库彻底清空
登录从库:
STOP REPLICA;
RESET REPLICA ALL;
⚠️ 如果你要“绝对干净”(推荐):
一般在从库执行,在主库执行要慎重!
RESET MASTER;
清空从库 GTID(很关键)
第四步:导入数据
mysql -uroot -p'MySQL@666' < full.sql
导入后,从库会拥有:
- 完整数据 ✅
- 正确 GTID 集合 ✅
第五步:重新建立复制
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.88.101',
SOURCE_PORT=3306,
SOURCE_USER='slave',
SOURCE_PASSWORD='MySQL@666',
SOURCE_AUTO_POSITION=1;
第六步:启动复制
START REPLICA;
第七步:验证
SHOW REPLICA STATUS\G
重点看:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Source: 0(或很小)

一张流程图帮你记住
主库 mysqldump
↓
传输 SQL 文件
↓
从库 RESET + 清空
↓
导入数据
↓
CHANGE MASTER
↓
START REPLICA
再次测试
CREATE DATABASE heima666;
show databases;
use heima666;
CREATE TABLE table666(bTypeId int,bName char(16),price int,publishing char(16));
INSERT INTO table666(bTypeId,bName,price,publishing) VALUES('1','Linux','66','DZ');
INSERT INTO table666(bTypeId,bName,price,publishing) VALUES('2','CLD','68','RM');
INSERT INTO table666(bTypeId,bName,price,publishing) VALUES('3','SYS','90','JX');
INSERT INTO table666(bTypeId,bName,price,publishing) VALUES('4','MySQL1','71','QH');
INSERT INTO table666(bTypeId,bName,price,publishing) VALUES('5','MySQL2','72','QH');
INSERT INTO table666(bTypeId,bName,price,publishing) VALUES('6','MySQL3','73','QH');
select * from table666;


🚨 常见坑(很容易踩)
❌ 坑1:没加 --set-gtid-purged=ON
会导致:
ERROR: MASTER_AUTO_POSITION requires GTID
❌ 坑2:从库没 RESET MASTER
GTID 集合冲突:
Executed_Gtid_Set 混乱
❌ 坑3:导入过程中有写操作
数据不一致
所以建议:
SET GLOBAL read_only=1;
❌ 坑4:主库 binlog 不完整
从库追不上
进阶一点
mysqldump vs xtrabackup
| 工具 | 优点 | 缺点 |
|---|---|---|
| mysqldump | 简单 | 慢 |
| xtrabackup | 热备、快 | 复杂 |
生产建议:
用 Percona XtraBackup
最后总结(重点)
重建主从本质就是:
用主库“当前一致数据 + GTID”覆盖从库,然后重新接入复制
9、Replicate_Ignore_DB 细节研究(拓展)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.101
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000007
Read_Master_Log_Pos: 197
Relay_Log_File: relaylog.000004
Relay_Log_Pos: 407
Relay_Master_Log_File: binlog.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys
Replicate_Do_Table:
Replicate_Ignore_DB: mysql 并非 “没用”,它能过滤 mysql 库的常规操作(如创建普通表、插入数据),但无法过滤 MySQL 自身的系统级操作(如创建用户、授权);
从库同步到 slave/slave2 用户,是 MySQL 为保证主从复制链路可用,强制同步系统级操作的结果,与过滤配置不冲突;
这类过滤配置的核心价值是减少无用的系统库同步(如 performance_schema 的实时统计数据),而非阻止核心系统变更的同步。
[root@mysql-node1 ~]# mysql -uroot -pMySQL@666
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
5 rows in set (0.01 sec)
mysql> CREATE USER 'slave2'@'%' IDENTIFIED BY 'MySQL@666';
Query OK, 0 rows affected (0.01 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| slave2 | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
mysql> SHOW MASTER STATUS;
+---------------+----------+--------------+-------------------------------------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+-------------------------------------------------+-------------------------------------------+
| binlog.000007 | 513 | | information_schema,mysql,performance_schema,sys | 9022134e-12f0-11f1-b122-0050563756ff:1-18 |
+---------------+----------+--------------+-------------------------------------------------+-------------------------------------------+
1 row in set (0.00 sec)
mysql> ^DBye
[root@mysql-node1 ~]# mysqlbinlog --no-defaults -uroot -pMySQL@666 --database=mysql --base64-output=DECODE-ROWS -v /export/server/mysql/data/binlog.000007 | grep -E "CREATE USER|slave|GRANT"
mysqlbinlog: [Warning] Using a password on the command line interface can be insecure.
WARNING: The option --database has been used. It may filter parts of transactions, but will include the GTIDs in any case. If you want to exclude or include transactions, you should use the options --exclude-gtids or --include-gtids, respectively, instead.
[root@mysql-node1 ~]# ls /export/server/mysql/data/
auto.cnf bookdb666 ibdata1 public_key.pem
binlog.000001 ca-key.pem ibtmp1 server-cert.pem
binlog.000002 ca.pem '#innodb_redo' server-key.pem
binlog.000003 client-cert.pem '#innodb_temp' sys
binlog.000004 client-key.pem mysql undo_001
binlog.000005 db_ithuang mysqld.pid undo_002
binlog.000006 '#ib_16384_0.dblwr' mysql.ibd
binlog.000007 '#ib_16384_1.dblwr' performance_schema
binlog.index ib_buffer_pool private_key.pem
[root@mysql-node1 ~]# ls -lht /export/server/mysql/data/binlog.0000*
-rw-r-----. 1 mysql mysql 513 Feb 26 18:32 /export/server/mysql/data/binlog.000007
-rw-r-----. 1 mysql mysql 220 Feb 26 18:21 /export/server/mysql/data/binlog.000006
-rw-r-----. 1 mysql mysql 220 Feb 26 18:18 /export/server/mysql/data/binlog.000005
-rw-r-----. 1 mysql mysql 4.9K Feb 26 18:18 /export/server/mysql/data/binlog.000004
-rw-r-----. 1 mysql mysql 180 Feb 26 16:53 /export/server/mysql/data/binlog.000003
-rw-r-----. 1 mysql mysql 833 Feb 26 16:45 /export/server/mysql/data/binlog.000002
-rw-r-----. 1 mysql mysql 180 Feb 26 16:44 /export/server/mysql/data/binlog.000001
[root@mysql-node1 ~]# mysqlbinlog --no-defaults -uroot -pMySQL@666 --base64-output=DECODE-ROWS -v /export/server/mysql/data/binlog.000007 | grep -E "CREATE USER|slave|GRANT"
mysqlbinlog: [Warning] Using a password on the command line interface can be insecure.
CREATE USER 'slave2'@'%' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$-!|[[fa\n\"j:zemHvdrzzCPq9egoj83qt2EKkZtXmxCIWWZGfs70.Sy2/'
[root@mysql-node1 ~]# mysql -uroot -pMySQL@666 mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 10
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| slave2 | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
mysql> CREATE USER 'slave3'@'%' IDENTIFIED BY 'MySQL@666';
Query OK, 0 rows affected (0.01 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| slave2 | % |
| slave3 | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
7 rows in set (0.00 sec)
mysql> show master status;
+---------------+----------+--------------+-------------------------------------------------+-------------------------------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+-------------------------------------------------+-------------------------------------------+
| binlog.000007 | 827 | | information_schema,mysql,performance_schema,sys | 9022134e-12f0-11f1-b122-0050563756ff:1-19 |
+---------------+----------+--------------+-------------------------------------------------+-------------------------------------------+
1 row in set (0.00 sec)
mysql> ^DBye
[root@mysql-node1 ~]# mysqlbinlog --no-defaults -uroot -pMySQL@666 --base64-output=DECODE-ROWS -v /export/server/mysql/data/binlog.000007 | grep -E "CREATE USER|slave|GRANT"
mysqlbinlog: [Warning] Using a password on the command line interface can be insecure.
CREATE USER 'slave2'@'%' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$-!|[[fa\n\"j:zemHvdrzzCPq9egoj83qt2EKkZtXmxCIWWZGfs70.Sy2/'
CREATE USER 'slave3'@'%' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$ B |0B
R)H0MTzXq3fkLbhZ2ClQ1i6i3BYLxTZnZ/olBQTXQ8GvYnYKDA'
[root@mysql-node1 ~]# mysql -uroot -pMySQL@66
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
[root@mysql-node1 ~]# mysql -uroot -pMySQL@666
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 13
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+------------------------------------------------------+
| Tables_in_mysql |
+------------------------------------------------------+
| columns_priv |
| component |
| db |
| default_roles |
| engine_cost |
| func |
| general_log |
| global_grants |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| ndb_binlog_index |
| password_history |
| plugin |
| procs_priv |
| proxies_priv |
| replication_asynchronous_connection_failover |
| replication_asynchronous_connection_failover_managed |
| replication_group_configuration_version |
| replication_group_member_actions |
| role_edges |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+------------------------------------------------------+
38 rows in set (0.00 sec)
mysql> CREATE TABLE userbook666 (ID int,Name char(16),Price int,Publishing char(16));
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO userbook666(ID,Name,Price,Publishing) VALUES('1','《Linux从 入门到精通》','66','电子工业出版社');
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO userbook666(ID,Name,Price,Publishing) VALUES('2','《云计算趋势》','68','人民邮电出版社');
Query OK, 1 row affected (0.00 sec)
mysql>
mysql> show tables;
+------------------------------------------------------+
| Tables_in_mysql |
+------------------------------------------------------+
| columns_priv |
| component |
| db |
| default_roles |
| engine_cost |
| func |
| general_log |
| global_grants |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| ndb_binlog_index |
| password_history |
| plugin |
| procs_priv |
| proxies_priv |
| replication_asynchronous_connection_failover |
| replication_asynchronous_connection_failover_managed |
| replication_group_configuration_version |
| replication_group_member_actions |
| role_edges |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
| userbook666 |
+------------------------------------------------------+
39 rows in set (0.00 sec)
mysql> select * from userbook666;
+------+-------------------------------+-------+-----------------------+
| ID | Name | Price | Publishing |
+------+-------------------------------+-------+-----------------------+
| 1 | 《Linux从入门到精通》 | 66 | 电子工业出版社 |
| 2 | 《云计算趋势》 | 68 | 人民邮电出版社 |
+------+-------------------------------+-------+-----------------------+
2 rows in set (0.00 sec)
mysql> ^DBye
[root@mysql-node1 ~]# mysqlbinlog --no-defaults -uroot -pMySQL@666 --base64-output=DECODE-ROWS -v /export/server/mysql/data/binlog.000007 | grep -E "CREATE USER|slave|GRANT"
mysqlbinlog: [Warning] Using a password on the command line interface can be insecure.
CREATE USER 'slave2'@'%' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$-!|[[fa\n\"j:zemHvdrzzCPq9egoj83qt2EKkZtXmxCIWWZGfs70.Sy2/'
CREATE USER 'slave3'@'%' IDENTIFIED WITH 'caching_sha2_password' AS '$A$005$ B |0B
R)H0MTzXq3fkLbhZ2ClQ1i6i3BYLxTZnZ/olBQTXQ8GvYnYKDA'
[root@mysql-node1 ~]#
[root@mysql-node2 ~]# mysql -uroot -pMySQL@666
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 19
Server version: 8.0.43 MySQL Community Server - GPL
Copyright (c) 2000, 2025, Oracle and/or its affiliates.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
5 rows in set (0.00 sec)
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for source to send event
Master_Host: 192.168.88.101
Master_User: slave
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: binlog.000007
Read_Master_Log_Pos: 197
Relay_Log_File: relaylog.000004
Relay_Log_Pos: 407
Relay_Master_Log_File: binlog.000007
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB: information_schema,mysql,performance_schema,sys
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 197
Relay_Log_Space: 860
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 0
Last_IO_Error:
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 101
Master_UUID: 9022134e-12f0-11f1-b122-0050563756ff
Master_Info_File: mysql.slave_master_info
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
Master_Retry_Count: 86400
Master_Bind:
Last_IO_Error_Timestamp:
Last_SQL_Error_Timestamp:
Master_SSL_Crl:
Master_SSL_Crlpath:
Retrieved_Gtid_Set: 9022134e-12f0-11f1-b122-0050563756ff:1-17
Executed_Gtid_Set: 9022134e-12f0-11f1-b122-0050563756ff:1-17
Auto_Position: 1
Replicate_Rewrite_DB:
Channel_Name:
Master_TLS_Version:
Master_public_key_path:
Get_master_public_key: 0
Network_Namespace:
1 row in set, 1 warning (0.00 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| slave2 | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
mysql> stop slave;
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| slave2 | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
6 rows in set (0.00 sec)
mysql> start slave;
Query OK, 0 rows affected, 1 warning (0.04 sec)
mysql> select user,host from mysql.user;
+------------------+-----------+
| user | host |
+------------------+-----------+
| slave | % |
| slave2 | % |
| slave3 | % |
| mysql.infoschema | localhost |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+------------------+-----------+
7 rows in set (0.00 sec)
mysql> use mysql
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> show tables;
+------------------------------------------------------+
| Tables_in_mysql |
+------------------------------------------------------+
| columns_priv |
| component |
| db |
| default_roles |
| engine_cost |
| func |
| general_log |
| global_grants |
| gtid_executed |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| innodb_index_stats |
| innodb_table_stats |
| ndb_binlog_index |
| password_history |
| plugin |
| procs_priv |
| proxies_priv |
| replication_asynchronous_connection_failover |
| replication_asynchronous_connection_failover_managed |
| replication_group_configuration_version |
| replication_group_member_actions |
| role_edges |
| server_cost |
| servers |
| slave_master_info |
| slave_relay_log_info |
| slave_worker_info |
| slow_log |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+------------------------------------------------------+
38 rows in set (0.00 sec)
mysql>
面试题:MySQL主从延迟的原因
面试题:MySQL主从延迟比较高通常有哪些原因,如何解决?
可能原因
主库:
-
大事务处理:
-
- 主库上的大事务会导致生成二进制日志速度过快,从库无法及时应用这些更改。
-
主库变更频率高:
-
- 主库频繁的写入操作诱发过多的数据需复制。
从库:
-
磁盘I/O性能:
-
- 从库磁盘I/O性能差,导致SQL线程写入数据耗时较长。
-
从库负载高:
-
- 从库处理大量查询导致SQL线程的同步速度减缓。
网络:
-
网络延迟:
-
- 网络不稳定或带宽不足会导致从库接收主库的复制数据缓慢。
解决方案
-
优化网络配置:
-
- 增加网络带宽,减少主从之间的网络延迟。
-
提高硬件性能:
-
- 升级从库的硬件配置,例如使用SSD提高磁盘I/O。
-
减少从库负载:
-
- 使用多个从库实现读写分离如mycat读写分离操作,保证复制线程不受查询处理影响。
-
优化事务处理:
-
- 尽量减少主库大事务频率,将操作分解成多个小事务。
- 例如:如果需要插入大量记录,可将其拆分为多个较小的批量插入。
-
调优MySQL配置:
-
- 调整
innodb_flush_log_at_trx_commit等参数以提高写入效率,增加复制线程数量,如调整slave_parallel_workers。 innodb_flush_log_at_trx_commit参数调整
- 调整
-
-
- 默认值为
1,表示每次事务提交都会同步日志到磁盘。为了降低磁盘I/O,提高性能,可以设置为2,表示在事务提交时只写入日志缓存,定期刷入磁盘。
- 默认值为
-
-
- 增加复制线程数量 (
slave_parallel_workers)
- 增加复制线程数量 (
-
-
- MySQL 5.7及以上版本支持并行复制。通过增加从库复制线程数可以加速从库应用事务。
- 在/etc/my.cnf中设置 slave_parallel_workers=4 # 根据服务器性能调整(最小为4,一般可以设置为CPU核心数的1/2或1/4),16核CPU => 4/8,32核CPU => 8/16
-
总结
- mysqldump逻辑备份与恢复 Xtrabackup物理备份 全量备份与恢复
- 背诵和理解MySQL主从工作原理
- 从0-1搭建传统主从(AB复制)=> 难点
- 基于GTID的主从复制以及主从延迟问题解决