编程 MySQL 8.4 LTS 单节点、主从、双主搭建:8.0 旧命令在 8.4 会直接报语法错误

2026-09-30 21:32:03

MySQL 8.4 LTS 单节点、主从、双主搭建:8.0 旧命令在 8.4 会直接报语法错误

本文基于 mysql-8.4.11 LTS,下载地址:MySQL 8.4 下载页。

操作系统使用 Amazon Linux 2023(x86_64);其它发行版的用户、服务、软件包和配置文件路径可能不同。

8.0 版本的做法见 MySQL 配置笔记,两篇的命令不通用,8.4 删除了一批主从语句和配置项,下面第 0 节先讲差异。

0. 从 8.0 到 8.4,哪些东西变了

8.4 是 8.x 系列的第二个 LTS。它把 8.0 里那些「已废弃很久」的东西真正删掉了,所以按 8.0 的笔记照抄会直接报语法错误。

主从 SQL 语句改名

旧名已删除,不是别名:

8.0 旧语句8.4 新语句
SHOW MASTER STATUSSHOW BINARY LOG STATUS
SHOW MASTER LOGSSHOW BINARY LOGS
PURGE MASTER LOGSPURGE BINARY LOGS
RESET MASTERRESET BINARY LOGS AND GTIDS
CHANGE MASTER TOCHANGE REPLICATION SOURCE TO
START SLAVE / STOP SLAVESTART REPLICA / STOP REPLICA
RESET SLAVERESET REPLICA
SHOW SLAVE STATUSSHOW REPLICA STATUS
SHOW SLAVE HOSTSSHOW REPLICAS

CHANGE 选项名变化

MASTER_HOST 这类选项在 8.4 同样不认:

旧选项新选项
MASTER_HOSTSOURCE_HOST
MASTER_PORTSOURCE_PORT
MASTER_USERSOURCE_USER
MASTER_PASSWORDSOURCE_PASSWORD
MASTER_LOG_FILESOURCE_LOG_FILE
MASTER_LOG_POSSOURCE_LOG_POS
MASTER_AUTO_POSITIONSOURCE_AUTO_POSITION
MASTER_CONNECT_RETRYSOURCE_CONNECT_RETRY
MASTER_RETRY_COUNTSOURCE_RETRY_COUNT

SHOW REPLICA STATUS 列名变化

旧列名新列名
Slave_IO_StateReplica_IO_State
Master_HostSource_Host
Master_Log_FileSource_Log_File
Read_Master_Log_PosRead_Source_Log_Pos
Relay_Master_Log_FileRelay_Source_Log_File
Slave_IO_RunningReplica_IO_Running
Slave_SQL_RunningReplica_SQL_Running
Seconds_Behind_MasterSeconds_Behind_Source

配置项与默认值变化

旧配置/行为8.4 配置/行为说明
default_authentication_pluginauthentication_policy8.4.0 已删除,配了服务起不来
mysql_native_password默认关闭要用得显式 mysql_native_password=ON;9.0 已彻底删除
expire_logs_daysbinlog_expire_logs_seconds8.2 已删除,默认 2592000,即 30 天
log_slave_updateslog_replica_updates改名,默认 ON
master_info_repository、relay_log_info_repository、master-info-file、relay-log-info-file8.3 已删除复制元数据只存表(crash-safe)
innodb_log_file_size、innodb_log_files_in_groupinnodb_redo_log_capacity已废弃,默认 100MB
binlog_format默认就是 ROW8.0.34 起废弃,新系统不要再配
replica_parallel_workers默认 48.0 是 0,从库默认就是多线程复制
rpl_semi_sync_master_* / semisync_master.sorpl_semi_sync_source_* / semisync_source.so从库侧是 replica 那一套
InnoDB 默认值8.4 已调整innodb_log_buffer_size 16M→64M、innodb_io_capacity 200→10000、innodb_flush_method 改成 O_DIRECT(支持时)、innodb_adaptive_hash_index 改成 OFF、innodb_change_buffering 改成 none、innodb_buffer_pool_instances 改成按内存和 CPU 自动算

警告:innodb_buffer_pool_size 默认仍是 128M,8.4 不会自动按机器内存放大。独占机器可以开 innodb_dedicated_server=ON,让 InnoDB 按物理内存算 buffer pool、按 CPU 数算 redo 容量。

高可用方案也得换:MHA、MMM 都是 Perl 老工具,内部发的就是 CHANGE MASTER TO、SHOW SLAVE STATUS,在 8.4 上跑不起来。8.4 要做自动选主,用官方的 InnoDB Cluster(Group Replication + MySQL Shell + MySQL Router)。

1. 单节点

安装

# 1.下载mysql,从mysql官网下载:https://dev.mysql.com/downloads/mysql/8.4.html
# 注意8.4的通用二进制包是glibc2.28,比8.0的glibc2.12要新,老系统(如CentOS7)装不上
wget https://cdn.mysql.com/Downloads/MySQL-8.4/mysql-8.4.11-linux-glibc2.28-x86_64.tar.xz
tar -Jxvf mysql-8.4.11-linux-glibc2.28-x86_64.tar.xz
mv mysql-8.4.11-linux-glibc2.28-x86_64 mysql8.4
sudo su
groupadd mysql
useradd -r -g mysql -s /bin/false mysql
cd mysql8.4
mkdir -p datas/mysql
chown -R mysql:mysql datas
chmod -R 750 datas
vim /etc/bashrc
export PATH=$PATH:/usr/local/soft/mysql8.4/bin
touch my.cnf
# 默认加载顺序:/etc/my.cnf /etc/mysql/my.cnf /usr/local/mysql/etc/my.cnf ~/.my.cnf,后面的覆盖前面的;建议放 /etc/my.cnf

配置:my.cnf 示例

[client]
port = 3306
socket = /tmp/mysql.sock

[mysqld]
skip-name-resolve
secure_file_priv=""
local_infile=ON
# 【8.4变化】default_authentication_plugin 在8.4.0已被删除,配置了会导致mysql启动失败
# 8.4改用 authentication_policy 管理认证因子,默认值就是 '*,,'
authentication_policy='*,,'
# 【8.4变化】mysql_native_password 默认已关闭,只有老客户端/老驱动连不上时才临时打开
# mysql_native_password=ON
port = 3306
server-id = 1001
user = mysql
socket = /tmp/mysql.sock
basedir = /usr/local/soft/mysql8.4
datadir = /usr/local/soft/mysql8.4/datas/mysql
log-bin = mysql-bin
# 【8.4变化】binlog_format 从8.0.34起已废弃,8.4默认就是ROW
# 【8.4变化】binlog过期时间,单位秒,8.4默认2592000(30天)
# 老参数 expire_logs_days 在8.2已被删除
binlog_expire_logs_seconds = 864000
sync-binlog=0
innodb_data_home_dir = ./
# 【8.4变化】redo日志固定放在 datadir 下的 #innodb_redo 目录,共32个文件
innodb_log_group_home_dir = ./
log-error = mysql.log
pid-file = mysql.pid
character-set-server=utf8mb4
lower_case_table_names=1
autocommit =1
slow_query_log=1
slow_query_log_file=db_slow.log
long_query_time=5
log_output=FILE
log_queries_not_using_indexes=1
skip-external-locking
key_buffer_size = 256M
max_allowed_packet = 64M
table_open_cache = 1024
sort_buffer_size = 4M
thread_cache_size = 64
tmp_table_size = 128M
explicit_defaults_for_timestamp = true
max_connections = 500
max_connect_errors = 100
open_files_limit = 65535
default_storage_engine = InnoDB
innodb_data_file_path = ibdata1:10M:autoextend
innodb_buffer_pool_size = 1024M
# 【8.4变化】redo日志总容量,替代已废弃的 innodb_log_file_size / innodb_log_files_in_group
innodb_redo_log_capacity = 1G
innodb_flush_log_at_trx_commit = 1
innodb_lock_wait_timeout = 50
# 独占机器时建议打开
# innodb_dedicated_server=ON

数据库初始化

sudo mysqld --user=mysql --initialize-insecure
# 或指定配置文件,--defaults-file要放在第一个参数位置
sudo mysqld --defaults-file=/usr/local/soft/mysql8.4/my.cnf --user=mysql --initialize-insecure
# 警告:lower_case_table_names 必须在初始化之前写进配置文件,初始化完成后再改会导致启动失败。

启动数据库

sudo mysqld_safe --user=mysql &
ps -ef|grep mysql
# 注意:mysqld_safe 在通用二进制包里仍提供;RPM/DEB 安装不会装它,那种情况直接用 systemd。

开机启动(方法1,推荐)

cd /usr/local/soft/mysql8.4/support-files/
sudo cp mysql.server /etc/init.d/mysqld
sudo systemctl enable mysqld
chkconfig --list
sudo systemctl disable mysqld
sudo systemctl start mysqld
sudo systemctl stop mysqld

登录

mysql -uroot --skip-password
# 8.4 账号默认用 caching_sha2_password,要求加密连接或基于 RSA 公钥交换密码
mysql -uroot -p -hxxx.xxx.xxx.xxx -P3306 --get-server-public-key
mysql -uroot -p -hxxx.xxx.xxx.xxx -P3306 --server-public-key-path=/path/to/public_key.pem

修改密码

mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY '123456';
# 不要再用 mysql_native_password,默认插件未加载,执行会报:
# ERROR 1524 (HY000): Plugin 'mysql_native_password' is not loaded
mysql> FLUSH PRIVILEGES;

授予 root 用户 system_user 权限

mysql> grant system_user on *.* to 'root'@'localhost';
mysql> flush privileges;

开启远程访问(不建议开 root 远程)

mysql> use mysql;
mysql> update user set user.Host='%' where user.User='root';
mysql> flush privileges;
# 更稳的做法:新建用户并只授必要权限
mysql> CREATE USER 'username'@'%' IDENTIFIED BY 'password';
mysql> CREATE DATABASE my_database CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
mysql> GRANT all privileges ON my_database.* TO 'username'@'%';
mysql> FLUSH PRIVILEGES;
mysql> show grants for 'username'@'%'\G

关闭

sudo mysqladmin -uroot -p shutdown

2. 主从

master: 10.250.0.243
slave: 10.250.0.82

master 和 slave 的 server-id 不能相同;master 必须开启 binlog;slave 必须开启中继日志。

云环境中如果 slave 由 master 镜像创建,要改 slave 的 datadir 中 auto.cnf 的 server-uuid,两者不能相同。

master 配置文件

server-id = 1001
log-bin = mysql-bin

slave 配置文件

server-id = 1002
relay-log-index=slave-relay-bin.index
relay-log=slave-relay-bin
relay_log_purge=1
# 【8.4变化】log_slave_updates 改名为 log_replica_updates,默认ON
log_replica_updates=ON
# 【8.4变化】从库默认就是多线程复制,replica_parallel_workers 默认4;replica_preserve_commit_order 默认ON
# replica_parallel_workers=4
# 警告:master_info_repository、relay_log_info_repository、master-info-file、relay-log-info-file 在 8.3 已被删除,
# 复制元数据只存在 mysql.slave_master_info、mysql.slave_relay_log_info 表里,配置里写这些参数会导致启动失败。

主库创建同步帐号

mysql> CREATE USER 'vagrant'@'10.250.%.%' IDENTIFIED BY 'vagrant';
mysql> GRANT REPLICATION SLAVE ON *.* TO 'vagrant'@'10.250.%.%';
mysql> FLUSH PRIVILEGES;

8.4 建复制账号的坑:复制账号用 caching_sha2_password 时,如果主从之间没有启用 TLS,从库必须拿到主库的 RSA 公钥才能完成认证,否则 START REPLICA 之后 Replica_IO_Running 一直是 No,报认证失败。两种解法:

  1. CHANGE REPLICATION SOURCE TO 里加 GET_SOURCE_PUBLIC_KEY=1
  2. 加 SOURCE_PUBLIC_KEY_PATH='/path/to/public_key.pem' 指定公钥文件

如果主从走加密连接(SOURCE_SSL=1 并配好证书),就不需要这两个参数。

如果主库已有数据,先导入从库再开启复制

mysqldump -uroot --all-databases --triggers --routines --events -p > all_databases.sql
# 更推荐,一致性快照导出,文件头带位点
mysqldump -uroot -p --all-databases --triggers --routines --events --single-transaction --source-data=2 > all_databases.sql
mysql> FLUSH TABLES WITH READ LOCK;
mysql> UNLOCK TABLES;
mysql -uroot -p < all_databases.sql

从节点设置同步

# 【8.4变化】查看主节点binlog状态,老命令 SHOW MASTER STATUS 已被删除
mysql> SHOW BINARY LOG STATUS;
# File=mysql-bin.000008 Position=1140
mysql> CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='10.250.0.243',
  SOURCE_PORT=3306,
  SOURCE_USER='vagrant',
  SOURCE_PASSWORD='vagrant',
  SOURCE_LOG_FILE='mysql-bin.000008',
  SOURCE_LOG_POS=1140,
  GET_SOURCE_PUBLIC_KEY=1;
mysql> START REPLICA;
mysql> SHOW REPLICA STATUS \G
# 判断主从是否正常,看 Replica_IO_Running 和 Replica_SQL_Running 都为 Yes
# 老列名 Slave_IO_Running / Slave_SQL_Running 在8.4已不存在
# Read_Source_Log_Pos 和 Exec_Source_Log_Pos 的差值表示已收到但还没应用完的量
# 主库上查看挂了哪些从库,老命令是 SHOW SLAVE HOSTS
mysql> SHOW REPLICAS;

从库禁止写操作

read_only=1
super_read_only=1

开启 GTID 主从复制(8.4 推荐直接用 GTID)

# master和slave的my.cnf中分别加入,并重启
gtid_mode=on
enforce_gtid_consistency=on
mysql> STOP REPLICA;
mysql> CHANGE REPLICATION SOURCE TO
  SOURCE_HOST='10.250.0.243',
  SOURCE_PORT=3306,
  SOURCE_USER='vagrant',
  SOURCE_PASSWORD='vagrant',
  SOURCE_AUTO_POSITION=1,
  GET_SOURCE_PUBLIC_KEY=1;
mysql> START REPLICA;
mysql> SHOW BINARY LOG STATUS;  # Executed_Gtid_Set 会随数据更新变化
mysql> SHOW VARIABLES like "%gtid%";

重建主从时的清理命令

# 【8.4变化】从库清空复制信息,老命令 RESET SLAVE ALL
mysql> STOP REPLICA;
mysql> RESET REPLICA ALL;
# 【8.4变化】主库清空binlog和GTID,老命令 RESET MASTER,生产慎用
mysql> RESET BINARY LOGS AND GTIDS;
mysql> SHOW BINARY LOGS;
mysql> PURGE BINARY LOGS TO 'mysql-bin.000010';

主从模式高可用架构

8.0 时代常见做法是套 MHA 做自动选主,但 MHA 在 8.4 上不可用(最后版本 2018 年的 0.58,内部发的是已删除的语句)。

8.4 要做自动故障转移可选 InnoDB Cluster。如果只是想让从库在主库连不上时自动改连另一个源,8.4 自带的 Asynchronous Connection Failover 可以做到(只切换复制连接,不做主库提升):

# 需要GTID + 自动定位
mysql> CHANGE REPLICATION SOURCE TO
  SOURCE_AUTO_POSITION=1,
  SOURCE_CONNECTION_AUTO_FAILOVER=1,
  SOURCE_RETRY_COUNT=3,
  SOURCE_CONNECT_RETRY=10;
# 注册备用源,权重越大越优先
mysql> SELECT asynchronous_connection_failover_add_source('', '10.250.0.82', 3306, '', 80);

3. 双主

双主模式就是两个 mysql 互为主从;两个 master 都不能设置只读。

操作:从库关闭只读并开启 binlog;主库也要开启中继日志;在从库上创建同步账号;查看从库的 binlog 状态;在主库上配置复制信息(步骤与主从相同,方向相反)。

双主架构自增主键冲突问题解决方法:两个主库各自设置不同的自增步长与偏移,避免同时插入时产生相同主键:

# master1
auto_increment_increment=2
auto_increment_offset=1
# master2
auto_increment_increment=2
auto_increment_offset=2

4. 半同步复制

安装半同步复制插件(8.4 是 source/replica 这一套):

# master
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
SET GLOBAL rpl_semi_sync_source_enabled=ON;
# slave
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';
SET GLOBAL rpl_semi_sync_replica_enabled=ON;
# 默认超时约 10 秒(rpl_semi_sync_source_timeout=10000),超时收不到 ack 会降级成异步复制
# 注意:不能和 8.0 的 master/slave 版插件共存

5. MySQL 8.4 的高可用怎么选

  1. 搭主从时主库、从库至少要配对什么? server-id 唯一、master 开 binlog、slave 开 relay log、复制账号 + REPLICATION SLAVE 权限。
  2. 默认异步复制会丢数据吗? 会。主库提交后 binlog 还没发到从库就宕机,会导致「已向客户端返回成功」的事务丢失。
  3. 半同步解决哪一步? 等从库 ack,超时(默认 10 秒)降级为异步。
  4. 双主自增冲突怎么防? auto_increment_increment=2 + offset 不同。
  5. 8.4 和 8.0 在这块有什么不一样? 语句/参数全面改名,不再有 MASTER/SLAVE 命名;复制元数据只存表;半同步插件改成 source/replica;从库默认多线程复制;MHA/MMM 不可用,改用 InnoDB Cluster。

推荐文章

程序员茄子在线接单