MySQL 5.7.35 升级到 8.0.35 — 原地升级(主从架构方式)

基于主从架构,先升级从库,切换后升级原主库,实现零停机原地升级

  • 主库:192.168.195.141(MySQL 5.7.35 → 8.0.35)
  • 从库:192.168.195.142(MySQL 5.7.35 → 8.0.35)

1. 环境信息

项目 主库 (Master) 从库 (Slave)
IP 192.168.195.141 192.168.195.142
MySQL版本(升级前) 5.7.35(二进制包,glibc2.12) 5.7.35(二进制包,glibc2.12)
MySQL版本(升级后) 8.0.35(二进制包,glibc2.17) 8.0.35(二进制包,glibc2.17)
server-id 1 2
gtid_mode ON ON

2. 升级方式说明

原地升级(In-Place Upgrade):直接在5.7的数据目录上启动8.0,MySQL自动完成数据字典升级。

主从架构升级策略

  1. 先升级从库(142)→ 验证
  2. 主从切换(142提升为主库)
  3. 再升级原主库(141)→ 配置为新从库
  4. (可选)再次切换回原角色

优点

  • 无需导出导入数据,升级速度快
  • 主从架构下可实现零停机升级
  • 数据目录原地升级,无需额外磁盘空间

缺点

  • 升级过程不可逆,必须做好备份
  • 数据字典升级过程中实例不可用
  • 如果升级失败,回退较复杂

3. 前置条件:搭建 MySQL 5.7.35 GTID 主从

3.1 清理旧环境(两台均执行)

bash 复制代码
systemctl stop mysqld
rm -rf /usr/local/mysql
rm -rf /data/mysql/3306/data/*
rm -f /etc/my.cnf
unlink /usr/local/mysql 2>/dev/null

3.2 安装 MySQL 5.7.35(两台均执行)

bash 复制代码
groupadd mysql
useradd -g mysql mysql

cd /usr/local/
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz
tar xzf mysql-5.7.35-linux-glibc2.12-x86_64.tar.gz
ln -s mysql-5.7.35-linux-glibc2.12-x86_64 mysql

/usr/local/mysql/bin/mysql --version
# /usr/local/mysql/bin/mysql  Ver 14.14 Distrib 5.7.35, for linux-glibc2.12 (x86_64) using  EditLine wrapper

3.3 创建数据目录(两台均执行)

bash 复制代码
mkdir -p /data/mysql/3306/data
chown mysql.mysql /data/mysql/3306/data/

3.4 编辑配置文件

主库 /etc/my.cnf(141)

ini 复制代码
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user    = mysql
port    = 3306
socket  = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
log-bin = mysql-bin
server-id = 1
gtid_mode = ON
enforce_gtid_consistency = ON

从库 /etc/my.cnf(142)

ini 复制代码
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user    = mysql
port    = 3306
socket  = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
server-id = 2
gtid_mode = ON
enforce_gtid_consistency = ON

3.5 初始化实例(两台均执行)

bash 复制代码
/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --initialize --user=mysql

获取临时密码:

bash 复制代码
grep "temporary password" /data/mysql/3306/data/mysqld.err
# 141: A temporary password is generated for root@localhost: aij+#uemP2pJ
# 142: A temporary password is generated for root@localhost: /5#QW7ciU&M8

3.6 配置 systemd 服务(两台均执行)

创建 /etc/systemd/system/mysqld.service

ini 复制代码
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql
Type=forking
PIDFile=/data/mysql/3306/data/mysqld.pid
TimeoutSec=0
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf --pid-file=/data/mysql/3306/data/mysqld.pid --daemonize $MYSQLD_OPTS
EnvironmentFile=-/etc/sysconfig/mysql
LimitNOFILE = 65535
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false

创建 /etc/sysconfig/mysql

ini 复制代码
MYSQLD_OPTS=

3.7 启动实例并修改密码(两台均执行)

bash 复制代码
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld

/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'临时密码' --connect-expired-password -e "alter user user() identified by 'Root@123456';"

3.8 搭建 GTID 主从复制

主库(141)创建复制用户:

sql 复制代码
CREATE USER 'repl'@'%' IDENTIFIED BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

从库(142)建立复制:

sql 复制代码
CHANGE MASTER TO
MASTER_HOST='192.168.195.141',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_AUTO_POSITION=1;

START SLAVE;

验证:

sql 复制代码
-- 从库执行
show slave status\G
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Auto_Position: 1
-- Seconds_Behind_Master: 0

3.9 插入测试数据

sql 复制代码
-- 主库(141)执行
CREATE DATABASE test_upgrade;
USE test_upgrade;
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1,'before_upgrade'),(2,'mysql57'),(3,'gtid_test');
SELECT * FROM t1;
-- +----+----------------+
-- | id | name           |
-- +----+----------------+
-- |  1 | before_upgrade |
-- |  2 | mysql57        |
-- |  3 | gtid_test      |
-- +----+----------------+

从库验证:

sql 复制代码
SELECT * FROM test_upgrade.t1;
-- 数据一致,主从复制正常

4. 原地升级步骤

4.1 下载 MySQL 8.0.35(两台均执行)

bash 复制代码
cd /usr/local/
wget https://downloads.mysql.com/archives/get/p/23/file/mysql-8.0.35-linux-glibc2.17-x86_64.tar.xz
tar xJf mysql-8.0.35-linux-glibc2.17-x86_64.tar.xz

4.2 第一步:升级从库(142)

4.2.1 停止从库复制
sql 复制代码
-- 在从库(142)执行
STOP SLAVE;
4.2.2 停止MySQL服务
bash 复制代码
systemctl stop mysqld
4.2.3 修改配置文件

编辑 /etc/my.cnf,新增8.0必需参数:

ini 复制代码
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user    = mysql
port    = 3306
socket  = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
server-id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
default_authentication_plugin = mysql_native_password

配置变更说明:

  • 新增 default_authentication_plugin = mysql_native_password:8.0默认使用caching_sha2_password,需保持与5.7兼容
  • 去掉 query_cache_type / query_cache_size(如果5.7配置中有):8.0已移除查询缓存功能
  • 本环境5.7最小化配置中没有query_cache相关参数,无需去掉
4.2.4 切换软链接到8.0
bash 复制代码
unlink /usr/local/mysql
ln -s mysql-8.0.35-linux-glibc2.17-x86_64 /usr/local/mysql

# 验证
/usr/local/mysql/bin/mysql --version
# /usr/local/mysql/bin/mysql  Ver 8.0.35 for Linux on x86_64 (MySQL Community Server - GPL)
4.2.5 启动8.0(自动升级数据字典)
bash 复制代码
systemctl start mysqld

重要:启动8.0时,MySQL会自动检测5.7的数据目录并执行升级。这个过程在error日志中可以看到。如果表很大,升级可能较慢。

4.2.6 检查升级日志
bash 复制代码
grep -i 'upgrade' /data/mysql/3306/data/mysqld.err | tail -5

输出:

复制代码
2026-07-26T15:39:30.963451+08:00 1 [System] [MY-011012] [Server] Starting upgrade of data directory.
2026-07-26T15:39:31.581496+08:00 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80035' started.
2026-07-26T15:39:32.760127+08:00 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80035' completed.

关键信息Server upgrade from '50700' to '80035' completed 表示升级成功完成。

4.2.7 验证从库升级
sql 复制代码
-- 版本确认
SELECT VERSION();
-- 8.0.35

-- 数据完整性
USE test_upgrade;
SELECT * FROM t1;
-- +----+----------------+
-- | id | name           |
-- +----+----------------+
-- |  1 | before_upgrade |
-- |  2 | mysql57        |
-- |  3 | gtid_test      |
-- +----+----------------+

-- .frm文件已消除(8.0使用数据字典)
SELECT COUNT(*) AS frm_count FROM information_schema.FILES WHERE FILE_NAME LIKE '%.frm%';
-- 0

-- MyISAM系统表已转为InnoDB
SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA='mysql' AND ENGINE='MyISAM';
-- Empty set(无MyISAM系统表)

-- GTID状态
SHOW VARIABLES LIKE 'gtid_mode';
-- ON

-- 认证插件
SHOW VARIABLES LIKE 'default_authentication_plugin';
-- mysql_native_password
4.2.8 再次重启确认
bash 复制代码
systemctl restart mysqld
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'Root@123456' -e "SELECT VERSION();"
# 8.0.35

4.3 第二步:主从切换

将从库(142)提升为主库,原主库(141)降为从库。

4.3.1 在142上停止复制并提升为主库
sql 复制代码
-- 在142执行
STOP SLAVE;
RESET SLAVE ALL;

-- 确认142可以独立运行
SHOW MASTER STATUS;
-- +---------------+----------+--------------+------------------+-------------------------------------------+
-- | File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set                         |
-- +---------------+----------+--------------+------------------+-------------------------------------------+
-- | binlog.000002 | 157      |              |                  | 9eec700e-88c4-11f1-9843-000c29048d1f:1-6  |
-- +---------------+----------+--------------+------------------+-------------------------------------------+
4.3.2 在142上创建复制用户
sql 复制代码
-- 在142执行
CREATE USER IF NOT EXISTS 'repl'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';

4.4 第三步:升级原主库(141)

4.4.1 停止MySQL服务
bash 复制代码
systemctl stop mysqld
4.4.2 修改配置文件

编辑 /etc/my.cnf

ini 复制代码
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user    = mysql
port    = 3306
socket  = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
log-bin = mysql-bin
server-id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
default_authentication_plugin = mysql_native_password
4.4.3 切换软链接到8.0
bash 复制代码
unlink /usr/local/mysql
ln -s mysql-8.0.35-linux-glibc2.17-x86_64 /usr/local/mysql

/usr/local/mysql/bin/mysql --version
# /usr/local/mysql/bin/mysql  Ver 8.0.35 for Linux on x86_64 (MySQL Community Server - GPL)
4.4.4 启动8.0(自动升级数据字典)
bash 复制代码
systemctl start mysqld
4.4.5 检查升级日志
bash 复制代码
grep -i 'upgrade' /data/mysql/3306/data/mysqld.err | tail -5

输出:

复制代码
2026-07-26T15:42:16.743686+08:00 1 [System] [MY-011012] [Server] Starting upgrade of data directory.
2026-07-26T15:42:17.350511+08:00 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80035' started.
2026-07-26T15:42:18.508952+08:00 5 [System] [MY-013381] [Server] Server upgrade from '50700' to '80035' completed.
4.4.6 验证141升级
sql 复制代码
SELECT VERSION();
-- 8.0.35

USE test_upgrade;
SELECT * FROM t1;
-- +----+----------------+
-- | id | name           |
-- +----+----------------+
-- |  1 | before_upgrade |
-- |  2 | mysql57        |
-- |  3 | gtid_test      |
-- +----+----------------+
4.4.7 再次重启确认
bash 复制代码
systemctl restart mysqld
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'Root@123456' -e "SELECT VERSION();"
# 8.0.35

4.5 第四步:恢复主从架构

将141配置为142的从库,恢复主从复制(主从角色已互换:142为主,141为从)。

sql 复制代码
-- 在141执行
CHANGE MASTER TO
MASTER_HOST='192.168.195.142',
MASTER_USER='repl',
MASTER_PASSWORD='123456',
MASTER_AUTO_POSITION=1,
GET_MASTER_PUBLIC_KEY=1;

START SLAVE;

验证主从状态:

sql 复制代码
-- 在141执行
show slave status\G
复制代码
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 192.168.195.142
                  Master_Port: 3306
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
                Auto_Position: 1

4.6 数据同步验证

sql 复制代码
-- 在新主库(142)写入数据
USE test_upgrade;
INSERT INTO t1 VALUES (4,'after_upgrade_80');
SELECT * FROM t1;
-- +----+------------------+
-- | id | name             |
-- +----+------------------+
-- |  1 | before_upgrade   |
-- |  2 | mysql57          |
-- |  3 | gtid_test        |
-- |  4 | after_upgrade_80 |
-- +----+------------------+
sql 复制代码
-- 在新从库(141)查询验证
SELECT * FROM test_upgrade.t1;
-- +----+------------------+
-- | id | name             |
-- +----+------------------+
-- |  1 | before_upgrade   |
-- |  2 | mysql57          |
-- |  3 | gtid_test        |
-- |  4 | after_upgrade_80 |
-- +----+------------------+

数据一致,主从复制正常!


5. 升级后全面验证

5.1 两台节点版本确认

sql 复制代码
-- 141
SELECT VERSION();
-- 8.0.35

-- 142
SELECT VERSION();
-- 8.0.35

5.2 GTID状态确认

sql 复制代码
-- 141(从库)
SHOW VARIABLES LIKE 'gtid_executed';
-- 9eeb4935-88c4-11f1-ab8f-000c29a59955:1-3, 9eec700e-88c4-11f1-9843-000c29048d1f:1-6

-- 142(主库)
SHOW VARIABLES LIKE 'gtid_executed';
-- 9eeb4935-88c4-11f1-ab8f-000c29a59955:1-3, 9eec700e-88c4-11f1-9843-000c29048d1f:1-6

两台GTID一致。

5.3 数据字典升级确认

sql 复制代码
-- .frm文件已消除
SELECT COUNT(*) AS frm_count FROM information_schema.FILES WHERE FILE_NAME LIKE '%.frm%';
-- 0

-- MyISAM系统表已全部转为InnoDB
SELECT TABLE_NAME, ENGINE FROM information_schema.TABLES WHERE TABLE_SCHEMA='mysql' AND ENGINE='MyISAM';
-- Empty set

5.4 认证插件确认

sql 复制代码
SHOW VARIABLES LIKE 'default_authentication_plugin';
-- mysql_native_password

SELECT user, host, plugin FROM mysql.user WHERE user='repl';
-- +------+------+-----------------------+
-- | user | host | plugin                |
-- +------+------+-----------------------+
-- | repl | %    | mysql_native_password |
-- +------+------+-----------------------+

6. 兼容性注意事项

6.1 认证插件

MySQL 8.0默认使用 caching_sha2_password,5.7使用 mysql_native_password。原地升级后需在my.cnf中添加:

ini 复制代码
default_authentication_plugin = mysql_native_password

否则5.7客户端可能无法连接8.0实例。

6.2 query_cache 相关参数

MySQL 8.0移除了查询缓存功能,以下参数在8.0中不再支持:

  • query_cache_type
  • query_cache_size
  • query_cache_limit

如果5.7的my.cnf中有这些参数,升级到8.0前必须去掉,否则8.0无法启动。

6.3 8.0新增关键字

MySQL 8.0新增了 RANKDENSE_RANKROW_NUMBERGROUPS 等关键字。如果5.7中使用了这些名称作为表名或列名,升级后需要用反引号引用:

sql 复制代码
-- 5.7中可以
CREATE TABLE rank (id INT);
-- 8.0中需要反引号
CREATE TABLE `rank` (id INT);
SELECT * FROM `rank`;

6.4 .frm文件

MySQL 8.0使用数据字典(Data Dictionary)替代了5.7的.frm文件。原地升级后,.frm文件会被自动清理。

6.5 数据字典自动升级

MySQL 8.0启动时会自动检测5.7的数据目录并执行升级,包括:

  • 将MyISAM系统表转为InnoDB
  • 升级数据字典格式
  • 移除.frm文件

升级过程在error日志中可见,无需手动执行mysql_upgrade(8.0中已废弃)。

6.6 支持的升级路径

  • 仅支持从MySQL 5.7 GA版本直接升级到8.0
  • 不支持跨大版本升级(如5.6→8.0)
  • 建议升级前先升级到5.7的最新小版本(如5.7.35→5.7.44),再升级到8.0

7. 升级后最终配置文件

/etc/my.cnf(141,升级后,当前为从库)

ini 复制代码
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user    = mysql
port    = 3306
socket  = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
log-bin = mysql-bin
server-id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
default_authentication_plugin = mysql_native_password

/etc/my.cnf(142,升级后,当前为主库)

ini 复制代码
[client]
socket = /data/mysql/3306/data/mysql.sock
[mysqld]
basedir = /usr/local/mysql
datadir = /data/mysql/3306/data
user    = mysql
port    = 3306
socket  = /data/mysql/3306/data/mysql.sock
log_error = /data/mysql/3306/data/mysqld.err
log_timestamps = system
server-id = 2
gtid_mode = ON
enforce_gtid_consistency = ON
default_authentication_plugin = mysql_native_password

软链接(两台均相同)

复制代码
/usr/local/mysql -> mysql-8.0.35-linux-glibc2.17-x86_64

8. 连接信息

bash 复制代码
# 141(当前从库)
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'Root@123456'

# 142(当前主库)
/usr/local/mysql/bin/mysql -uroot -S /data/mysql/3306/data/mysql.sock -p'Root@123456'

9. 回退方案

原地升级不可逆,回退需要从备份恢复:

  1. 停止8.0实例
  2. 恢复5.7的数据目录备份
  3. 切换软链接回5.7:unlink /usr/local/mysql && ln -s mysql-5.7.35-linux-glibc2.12-x86_64 /usr/local/mysql
  4. 恢复5.7的my.cnf(去掉 default_authentication_plugin
  5. 启动5.7实例

重要 :原地升级前必须做好数据备份!数据无价。


10. 升级流程总结

复制代码
┌─────────────────────────────────────────────────────────┐
│              MySQL 5.7 → 8.0 主从架构原地升级流程          │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  1. 搭建5.7 GTID主从(141主,142从)                      │
│     ↓                                                   │
│  2. 升级从库142:停5.7 → 改my.cnf → 切软链接 → 启8.0      │
│     ↓                                                   │
│  3. 验证142升级成功(版本、数据、error日志)                │
│     ↓                                                   │
│  4. 主从切换:142提升为主库,141降为从库                    │
│     ↓                                                   │
│  5. 升级原主库141:停5.7 → 改my.cnf → 切软链接 → 启8.0    │
│     ↓                                                   │
│  6. 验证141升级成功                                       │
│     ↓                                                   │
│  7. 141配置为142的从库,恢复主从架构                        │
│     ↓                                                   │
│  8. 数据同步验证,升级完成                                 │
│                                                         │
│  结果:141(从) ← 8.0.35 GTID复制 → 142(主)               │
│        两台均已从5.7.35原地升级到8.0.35                    │
└─────────────────────────────────────────────────────────┘
相关推荐
万亿少女的梦1682 小时前
基于Spring Boot的乐助在线助农系统设计与实现
java·spring boot·mysql·敏感词过滤·助农系统
艾莉丝努力练剑2 小时前
【MYSQL】MYSQL学习的一大重点:基本查询(下)
android·数据库·学习·mysql·面试·八股文
冰暮流星2 小时前
mysql之数据库创建,查询,删除,启用
数据库·mysql·oracle
提笔了无痕17 小时前
MySQL SQL 从 EXPLAIN 到索引优化,搞懂 SQL 为什么慢
android·sql·mysql
辰同学ovo18 小时前
从一条 SQL 到三个原则:MySQL 心智模型
sql·mysql·adb
Mico1821 小时前
MySQL 8.0.35 GTID主从复制常见管理操作
mysql
网安墨雨1 天前
MySQL数据库 SQL语句详解
自动化测试·软件测试·数据库·python·sql·mysql
muddjsv1 天前
SQLite与MySQL/PostgreSQL本质区别:运行模型、并发、部署、权限全方位对比
mysql·postgresql·sqlite
Mico181 天前
MySQL 8.0.35 GTID + 延迟复制 + 过滤复制搭建
mysql·dba