mysql通过GTID配置主从

avatar 2025年9月5日18:18:08 评论 188 次浏览

 摘要

全局事务标识符(GTID)复制是 MySQL 5.6 版本引入的重大特性,它彻底改变了传统基于二进制日志位置的复制方式。本文将深入探讨 GTID 复制的工作原理、配置方法、优势以及在实际生产环境中的最佳实践。

1. GTID 复制概述

1.1 什么是 GTID

GTID(Global Transaction Identifier)是 MySQL 中每个事务的唯一标识符,其格式为:source_id:transaction_id

  • source_id:产生事务的服务器唯一标识,通常是服务器的 UUID

  • transaction_id:事务序列号,从 1 开始单调递增

1.2 与传统复制的根本区别

传统复制依赖于二进制日志文件名和位置坐标,而 GTID 复制使用全局唯一的事务标识符来跟踪复制位置,这带来了复制管理的革命性变化。

2. GTID 复制的工作原理

2.1 事务执行流程
  1. 主库上执行事务

  2. 事务被分配一个 GTID 并写入二进制日志

  3. 从库的 I/O 线程读取主库的二进制日志

  4. 从库的 SQL 线程应用事务,保留原始 GTID

2.2 自动定位机制

当从库启用 MASTER_AUTO_POSITION = 1 时,它会自动与主库协商复制位置:

  • 从库告诉主库它已执行了哪些 GTID

  • 主库发送所有从库缺失的事务

  • 无需手动指定 MASTER_LOG_FILEMASTER_LOG_POS

3. 配置 GTID 复制

3.1 主从服务器配置参数

主库配置 (my.cnf):

 [client]
 #password   = your_password
 port        = 3306
 socket      = /tmp/mysql.sock
 [mysqld]
 port        = 3306
 socket      = /tmp/mysql.sock
 datadir = /usr/local/mysql/var
 skip-external-locking
 key_buffer_size = 128M
 max_allowed_packet = 1M
 table_open_cache = 512
 sort_buffer_size = 2M
 net_buffer_length = 8K
 read_buffer_size = 2M
 read_rnd_buffer_size = 512K
 myisam_sort_buffer_size = 32M
 thread_cache_size = 64
 tmp_table_size = 64M
 performance_schema_max_table_instances = 4000
 
 explicit_defaults_for_timestamp = true
 #skip-networking
 max_connections = 500
 max_connect_errors = 100
 open_files_limit = 65535
 default_authentication_plugin = mysql_native_password
 #############关键词##################
 server_id = 1
 log_bin = /var/log/mysql/mysql-bin.log
 gtid_mode = ON
 enforce_gtid_consistency = ON
 binlog_format = ROW
 log_slave_updates = ON
 ###############################
 log-bin=mysql-bin
 binlog_format=mixed
 binlog_expire_logs_seconds = 864000
 early-plugin-load = ""
 
 default_storage_engine = InnoDB
 innodb_file_per_table = 1
 innodb_data_home_dir = /usr/local/mysql/var
 innodb_data_file_path = ibdata1:10M:autoextend
 innodb_log_group_home_dir = /usr/local/mysql/var
 innodb_buffer_pool_size = 512M
 innodb_log_file_size = 128M
 innodb_log_buffer_size = 8M
 innodb_flush_log_at_trx_commit = 1
 innodb_lock_wait_timeout = 50
 plugin_load_add = group_replication.so
 binlog_row_image=FULL
 log_bin=binlog
 sync_binlog=1
 
 [mysqldump]
 quick
 max_allowed_packet = 16M
 
 [mysql]
 no-auto-rehash
 
 [myisamchk]
 key_buffer_size = 128M
 sort_buffer_size = 2M
 read_buffer_size = 2M
 write_buffer_size = 2M
 
 [mysqlhotcopy]
 interactive-timeout

从库配置 (my.cnf):

 [mysqld]
 [client]
 #password   = your_password
 port        = 3306
 socket      = /tmp/mysql.sock
 
 [mysqld]
 port        = 3306
 socket      = /tmp/mysql.sock
 datadir = /usr/local/mysql/var
 skip-external-locking
 key_buffer_size = 16M
 max_allowed_packet = 1M
 table_open_cache = 64
 sort_buffer_size = 512K
 net_buffer_length = 8K
 read_buffer_size = 256K
 read_rnd_buffer_size = 512K
 myisam_sort_buffer_size = 8M
 thread_cache_size = 8
 tmp_table_size = 16M
 performance_schema_max_table_instances = 500
 
 explicit_defaults_for_timestamp = true
 #skip-networking
 max_connections = 500
 max_connect_errors = 100
 open_files_limit = 65535
 default_authentication_plugin = mysql_native_password
 
 log-bin=mysql-bin
 binlog_format=mixed
 binlog_expire_logs_seconds = 864000
 early-plugin-load = ""
 ##########关键词################
 server_id = 2
 log_bin = /var/log/mysql/mysql-bin.log
 gtid_mode = ON
 enforce_gtid_consistency = ON
 binlog_format = ROW
 relay_log = /var/log/mysql/relay-log
 read_only = ON
 super_read_only = O
 log_slave_updates=ON
 ##########################
 default_storage_engine = InnoDB
 innodb_file_per_table = 1
 innodb_data_home_dir = /usr/local/mysql/var
 innodb_data_file_path = ibdata1:10M:autoextend
 innodb_log_group_home_dir = /usr/local/mysql/var
 innodb_buffer_pool_size = 16M
 innodb_log_file_size = 5M
 innodb_log_buffer_size = 8M
 innodb_flush_log_at_trx_commit = 1
 innodb_lock_wait_timeout = 50
 plugin_load_add = group_replication.so
 binlog_row_image=FULL
 sync_binlog=1
 [mysqldump]
 quick
 max_allowed_packet = 16M
 
 [mysql]
 no-auto-rehash
 
 [myisamchk]
 key_buffer_size = 20M
 sort_buffer_size = 20M
 read_buffer_size = 2M
 write_buffer_size = 2M
 
 [mysqlhotcopy]
 interactive-timeout
3.2 建立复制链路
 -- 在主库创建复制用户
 CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'SecurePass123!';
 GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
 
 -- 在从库配置复制
 CHANGE MASTER TO
   MASTER_HOST = 'master_host',
   MASTER_USER = 'repl',
   MASTER_PASSWORD = 'SecurePass123!',
   MASTER_AUTO_POSITION = 1;
 
 START SLAVE;

4. GTID 复制的优势

4.1 简化的故障转移

传统复制中,故障转移需要精确定位二进制日志位置:

 -- 传统复制故障转移需要复杂的位置计算
 CHANGE MASTER TO
   MASTER_HOST = 'new_master',
   MASTER_LOG_FILE = 'mysql-bin.000002',
   MASTER_LOG_POS = 473825;

而 GTID 复制只需:

 -- GTID 复制故障转移简单可靠
 CHANGE MASTER TO
   MASTER_HOST = 'new_master',
   MASTER_AUTO_POSITION = 1;
4.2 一致性与可靠性
  • GTID 保证每个事务只在从库应用一次

  • 自动跳过已执行的事务,避免重复执行

  • 提供全局一致的事务视图

4.3 拓扑管理灵活性

GTID 复制简化了复杂复制拓扑的管理:

  • 轻松添加新的从库

  • 简化主从切换和故障恢复

  • 支持多源复制和复杂层级结构

5. 实战中的常见场景与解决方案

5.1 跳过特定错误事务

当遇到复制错误时,可以安全地跳过特定 GTID:

 STOP SLAVE;
 SET GTID_NEXT = '3a09a6e2-7c2b-11eb-9c0b-0a5e3a7c7d62:128';
 BEGIN; COMMIT;
 SET GTID_NEXT = 'AUTOMATIC';
 START SLAVE;
5.2 数据备份与恢复

使用 mysqldump 进行 GTID 兼容的备份:

 mysqldump --single-transaction --set-gtid-purged=ON -u root -p mydatabase > backup.sql

恢复时正确处理 GTID 信息:

 RESET MASTER;
 SET @@GLOBAL.gtid_purged = '3a09a6e2-7c2b-11eb-9c0b-0a5e3a7c7d62:1-127';
 SOURCE backup.sql;

6. 最佳实践与注意事项

6.1 版本兼容性
  • 确保所有实例使用相同的主要 MySQL 版本

  • 建议使用 MySQL 5.7 或更高版本以获得完整的 GTID 功能支持

6.2 参数优化建议
 # 提高复制安全性
 sync_binlog = 1
 innodb_flush_log_at_trx_commit = 1
 
 # 监控和维护
 binlog_expire_logs_seconds = 2592000 # 30天
6.3 监控与维护

定期检查复制状态:

 SHOW SLAVE STATUS\G
 SELECT * FROM mysql.gtid_executed;
 SELECT * FROM performance_schema.replication_applier_status;

7. 常见问题与故障排除

7.1 GTID 一致性错误

错误:ER_GTID_NEXT_TYPE_UNDEFINED_GROUPER_GTID_NEXT_IS_NOT_IN_GTID_NEXT_LIST

  • 解决方案:确保正确设置 GTID_NEXT 并在使用后重置为 AUTOMATIC

7.2 空间不足问题

错误:ER_GTID_MODE_REQUIRES_BINLOG_EXPIRE_LOG_SECONDS_GTID_CONSISTENCY

  • 解决方案:设置合理的二进制日志过期时间并监控磁盘空间

8. 迁移到 GTID 复制

对于现有基于位置的复制环境,迁移到 GTID 复制需要谨慎的步骤:

  1. 确保所有服务器版本支持 GTID

  2. 在主从库上设置 enforce_gtid_consistency = WARN 并监控错误

  3. 逐步启用 GTID 模式:OFF → OFF_PERMISSIVE → ON_PERMISSIVE → ON

  4. 验证数据一致性后切换为纯 GTID 复制

GTID 复制 vs. 传统 Binlog 位置复制:核心区别

特性 传统 Binlog 位置复制 GTID 复制
标识符 基于二进制日志文件名和事件位置 (MASTER_LOG_FILEMASTER_LOG_POS) 基于全局事务标识符 (GTID),格式为 server_uuid:transaction_id
故障切换 复杂且易错。需人工定位从库执行到的准确位点,或借助工具。 简单可靠。只需指向新主库,MASTER_AUTO_POSITION=1 自动寻找同步点。
一致性 较弱。依赖位点的准确性,配置错误易导致数据不一致。 更强。GTID 唯一性保证了事务不会在从库上重复应用或丢失。
拓扑管理 复杂。更改拓扑需重新计算位点,级联复制管理繁琐。 极其简单。轻松支持多从、级联复制等复杂拓扑,增减节点方便。
容错性 较低。主库日志丢失或损坏可能导致复制彻底中断。 更高。自动容错机制更好,能处理一些网络闪断问题。
依赖项 严重依赖主库的特定二进制日志文件。 不依赖主库的二进制日志文件,只认 GTID。

结论

GTID 复制代表了 MySQL 复制技术的重大进步,它通过简化故障转移、提高数据一致性和增强拓扑管理灵活性,为数据库管理员提供了更强大的运维工具。虽然初始配置可能需要更多考虑,但长期来看,GTID 复制显著降低了维护复杂度并提高了系统可靠性。

对于新部署的 MySQL 环境,强烈建议直接采用 GTID 复制。对于现有环境,应制定详细的迁移计划,逐步过渡到 GTID 复制,以享受其带来的各种优势。

随着 MySQL 8.0 的普及和后续版本的发展,GTID 复制将继续作为 MySQL 高可用架构的核心组件,为云原生环境和分布式数据库提供坚实的基础。

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: