MySQL主从复制实战:GTID模式配置与ProxySQL读写分离部署方案

MySQL主从复制是数据库高可用架构的基础组件,通过将主库的变更同步到从库实现数据冗余和读负载分担。GTID(Global Transaction Identifier)模式相比传统的基于binlog位置的复制,提供了全局事务标识和自动故障恢复能力,大幅降低了运维复杂度。配合ProxySQL作为中间层实现读写分离,应用程序无需感知后端拓扑变化,是MySQL性能调优和数据备份恢复方案中的标准组合。

MySQL GTID复制原理与主库配置

GTID是MySQL 5.6引入的特性,每个事务在主库上执行时分配一个全局唯一标识符,格式为server_uuid:transaction_id。从库通过GTID自动定位复制位置,无需手动指定binlog文件名和位置,故障切换时也不会丢失事务或重复执行。

-- 主库配置 /etc/my.cnf (MySQL 8.0)

[mysqld]
server-id = 1
log-bin = mysql-bin
binlog-format = ROW           # GTID要求ROW格式
gtid-mode = ON
enforce-gtid-consistency = ON
log-slave-updates = ON        # 级联复制需要
binlog-expire-logs-seconds = 604800  # 7天
expire_logs_days = 7          # 兼容旧版本参数

-- 从库配置
[mysqld]
server-id = 2
log-bin = mysql-bin
binlog-format = ROW
gtid-mode = ON
enforce-gtid-consistency = ON
log-slave-updates = ON
read-only = ON                # 从库只读
super-read-only = ON          # 包括SUPER权限用户也只读
relay-log = relay-bin
relay-log-recovery = ON

-- 主库创建复制用户
CREATE USER 'repl'@'192.168.1.%' IDENTIFIED BY 'StrongPassword123!';

-- MySQL 8.0 使用 caching_sha2_password 认证
-- 复制用户建议使用 mysql_native_password 保证兼容性
ALTER USER 'repl'@'192.168.1.%' IDENTIFIED WITH mysql_native_password BY 'StrongPassword123!';

GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.%';
FLUSH PRIVILEGES;

-- 查看主库GTID状态
SHOW MASTER STATUS\G
/*
*************************** 1. row ***************************
             File: mysql-bin.000003
         Position: 1234
     Binlog_Do_DB: 
 Binlog_Ignore_DB: 
Executed_Gtid_Set: 550f89a0-1234-5678-9abc-def012345678:1-100
*/

gtid-mode和enforce-gtid-consistency必须同时启用。enforce-gtid-consistency为ON时,不支持CREATE TABLE … SELECT和事务内部使用临时表等不安全语句,部署前需要审计现有SQL。

从库搭建与复制状态监控

从库通过CHANGE MASTER TO语句配置复制源。GTID模式下可以自动从主库拉取缺失的事务,无需手动指定binlog位置。生产环境中建议使用 pt-table-checksum 和 pt-table-sync 工具定期校验主从数据一致性。

-- 从库配置复制
CHANGE MASTER TO
    MASTER_HOST = '192.168.1.100',
    MASTER_PORT = 3306,
    MASTER_USER = 'repl',
    MASTER_PASSWORD = 'StrongPassword123!',
    MASTER_AUTO_POSITION = 1;   -- GTID自动定位

START SLAVE;

-- 查看复制状态
SHOW SLAVE STATUS\G
/*
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 192.168.1.100
             Slave_IO_Running: Yes    -- 必须为Yes
            Slave_SQL_Running: Yes    -- 必须为Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
         Replicate_Do_Table: 
     Replicate_Ignore_Table: 
    Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
                 Last_Errno: 0
                 Last_Error: 
        Seconds_Behind_Master: 0    -- 延迟秒数
    Auto_Position: 1                -- GTID模式
     Retrieved_Gtid_Set: 550f89a0-...:101-200
     Executed_Gtid_Set: 550f89a0-...:1-200
*/

-- 监控脚本:检查复制健康状态
SELECT
    @@server_id AS server_id,
    CHANNEL_NAME,
    SERVICE_STATE AS io_state,
    LAST_ERROR_NUMBER AS io_errno,
    LAST_ERROR_MESSAGE AS io_error,
    LAST_ERROR_TIMESTAMP AS io_error_time
FROM performance_schema.replication_connection_status;

SELECT
    SERVICE_STATE AS sql_state,
    LAST_ERROR_NUMBER AS sql_errno,
    LAST_ERROR_MESSAGE AS sql_error,
    SECONDS_BEHIND_MASTER AS delay_seconds
FROM performance_schema.replication_applier_status_by_worker;

-- 查看GTID执行情况
SELECT @@global.gtid_executed AS executed_gtids;
SELECT @@global.gtid_purged AS purged_gtids;

-- 跳过指定GTID事务(谨慎使用,仅在确认事务可安全跳过时)
-- STOP SLAVE;
-- SET GTID_NEXT = '550f89a0-1234-5678-9abc-def012345678:201';
-- BEGIN; COMMIT;
-- SET GTID_NEXT = 'AUTOMATIC';
-- START SLAVE;

复制延迟是主从架构中最常见的问题。Seconds_Behind_Master仅反映SQL线程的延迟,IO线程积压时该值可能显示为0但实际有大量未应用事务。通过监控Retrieved_Gtid_Set和Executed_Gtid_Set的差值可以更准确判断延迟。大事务、慢查询和锁等待是延迟的主要原因,生产环境中应通过分库分表方案减少单库压力。

ProxySQL安装配置与读写分离规则

ProxySQL是高性能的MySQL代理,支持读写分离、连接池、查询路由和多目标集群管理。与MySQL Connector/J的读写分离不同,ProxySQL在协议层工作,应用程序无需任何改动即可实现读写分离。

# 安装ProxySQL
# CentOS/RHEL
yum install proxysql -y
# Ubuntu/Debian
apt install proxysql -y

# 启动ProxySQL
systemctl start proxysql
systemctl enable proxysql

# 连接ProxySQL管理接口(默认端口6032,默认用户admin/admin)
mysql -u admin -padmin -h 127.0.0.1 -P 6032

-- 配置后端MySQL服务器
INSERT INTO mysql_servers(hostgroup_id, hostname, port, max_connections) VALUES
(1, '192.168.1.100', 3306, 200),  -- 写组(主库)
(2, '192.168.1.101', 3306, 200),  -- 读组(从库1)
(2, '192.168.1.102', 3306, 200);  -- 读组(从库2)

-- 配置监控用户
SET mysql-monitor_username='monitor';
SET mysql-monitor_password='MonitorPass123!';

-- 配置主从复制监控
INSERT INTO mysql_replication_hostgroups(writer_hostgroup, reader_hostgroup, comment)
VALUES (1, 2, '主从读写分离');

-- 配置后端用户(应用程序连接ProxySQL使用的用户)
INSERT INTO mysql_users(username, password, default_hostgroup, active) VALUES
('app_user', 'AppPass123!', 1, 1);  -- 默认路由到写组

-- 读写分离规则
-- 规则1:SELECT FOR UPDATE路由到写组
INSERT INTO mysql_query_rules(rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (1, 1, '^SELECT.*FOR UPDATE', 1, 1);

-- 规则2:普通SELECT查询路由到读组
INSERT INTO mysql_query_rules(rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (2, 1, '^SELECT', 2, 1);

-- 规则3:写操作路由到写组
INSERT INTO mysql_query_rules(rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (3, 1, '^(INSERT|UPDATE|DELETE|REPLACE|CREATE|ALTER|DROP|TRUNCATE)', 1, 1);

-- 规则4:事务内所有操作路由到写组
INSERT INTO mysql_query_rules(rule_id, active, match_digest, destination_hostgroup, apply)
VALUES (4, 1, '^BEGIN|COMMIT|ROLLBACK|SET autocommit', 1, 1);

-- 加载配置到运行时
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;

-- 保存配置到磁盘
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;

-- 验证配置
SELECT hostgroup_id, hostname, status FROM runtime_mysql_servers;
SELECT rule_id, match_digest, destination_hostgroup FROM runtime_mysql_query_rules;

ProxySQL的连接池功能可以显著降低数据库连接建立的开销。对于短连接和高并发的Web应用,连接池可以将数据库QPS提升30%以上。配置参数 mysql-connection_delay_multiplex_ms 控制连接复用的延迟,mysql-threshold_resultset_size 控制结果集缓存大小。

复制延迟排查与故障切换处理

生产环境中复制中断和延迟是高频问题。通过performance_schema的复制表可以精确诊断问题根因。GTID模式下复制中断后,从库会自动尝试重新连接主库并从断点继续,但仍需人工介入处理数据冲突。

-- 排查复制延迟原因

-- 1. 检查大事务
SELECT * FROM information_schema.innodb_trx
ORDER BY trx_started ASC LIMIT 5;

-- 2. 检查慢查询
SELECT * FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC LIMIT 10;

-- 3. 检查从库负载
SHOW PROCESSLIST;

-- 4. 检查网络延迟
SELECT * FROM performance_schema.replication_connection_status;

-- 5. 计算GTID延迟差距
SELECT 
    Retrieved_Gtid_Set AS io_gtid,
    Executed_Gtid_Set AS sql_gtid,
    TIMESTAMPDIFF(SECOND, 
        STR_TO_DATE(SUBSTRING_INDEX(LAST_QUEUED, ':', -1), '%s'),
        NOW()
    ) AS io_delay_seconds
FROM performance_schema.replication_connection_status;

-- 故障切换:主库宕机时提升从库为主库
-- 在新主库(原从库)上执行
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;

-- 在ProxySQL中更新服务器配置
-- 将新主库加入写组,移除原主库
UPDATE mysql_servers SET hostgroup_id = 1 WHERE hostname = '192.168.1.101';
DELETE FROM mysql_servers WHERE hostname = '192.168.1.100';
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;

-- 其他从库指向新主库
-- 在各从库上执行
STOP SLAVE;
CHANGE MASTER TO
    MASTER_HOST = '192.168.1.101',
    MASTER_PORT = 3306,
    MASTER_AUTO_POSITION = 1;
START SLAVE;

对于需要更高可用性的场景,可以引入MHA(Master High Availability)或Orchestrator实现自动故障切换。Orchestrator支持基于GTID的拓扑管理和自动恢复,配合ProxySQL的故障检测可以实现分钟级的自动切换。数据迁移实战中,GTID模式使得在线切换主库更加安全,应用层通过ProxySQL代理无需修改连接配置,只感知到短暂的写入暂停。

原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/mysql-zhu-cong-fu-zhi-shi-zhan-gtid-mo-shi-pei-zhi-yu/

(0)
小编小编
上一篇 3小时前
下一篇 3小时前

相关推荐