# 一、MySQL配置 > MySQL版本必须大于5.7,且存储引擎为InnoDB,数据库配置正确 ## 1.1 主库配置 在MySQL配置文件中加入以下内容,其中的server-id必须与从库不同 ```ini [mysqld] server-id=1 log_bin=mysql-bin gtid_mode=ON enforce_gtid_consistency=ON ``` ## 1.2 从库配置 ```ini [mysqld] server-id = 2 gtid_mode = ON enforce_gtid_consistency = ON binlog-ignore-db = mysql binlog-ignore-db = sys binlog-ignore-db = information_schema binlog-ignore-db = performance_schema ``` 多源复制必须从服务器停止同步,设置这两个,将日志存储方式从FILE改为TABLE ```ini [mysqld] master_info_repository = TABLE relay_log_info_repository = TABLE ``` > 每个MySQl配置文件中的 `server-id` 必须互不相同,随意写一个整数即可 > > `gtid_mode` 打开GTID模式 > > ` enforce_gtid_consistency=ON` 禁止执行不支持 GTID 的语句或操作 > > `binlog-ignore-db` 取消这些名称的数据库的同步 # 二、在主服务器上创建复制用户 ## 2.1 进入mysql模式 以宝塔为例子,在终端输入mysql账号密码,进入mysql ```bash # 在Linux命令行执行,替换为自己MySQL的root密码 mysql -uroot -pa5d7b7****** ```  ## 2.2 执行命令 在mysql模式下执行下方3行命令创建复制用户 其中的 `yonghuming` 改为自己的用户名,`mima` 改为自己的密码 ```sql CREATE USER 'yonghuming'@'%' IDENTIFIED BY 'mima'; GRANT REPLICATION SLAVE ON *.* TO 'yonghuming'@'%'; FLUSH PRIVILEGES; ``` # 三、全量备份主数据库 ## 3.1 退出mysql模式再操作 如主库已经在终端进入了MySQL模式,需输入exit,按回车退出 ## 3.2 执行备份命令 将以下命令复制到记事本,替换自己的数据库密码,数据库名,执行 完成后在 `/www/wwwroot/` 目录下可以找到全量备份的数据库文件 `master_dump.sql.gz` ```bash # 在Linux命令行执行 mysqldump -u root -p你的密码 数据库名 \ --default-character-set=utf8mb4 \ --single-transaction \ --triggers \ --routines \ --events \ --set-gtid-purged=ON | gzip > /www/wwwroot/master_dump.sql.gz ``` `--single-transaction` 有短暂全局锁的作用,主库无需手动锁表就可以直接导出 <span style="color: #333;background:#ffff88;">**完成后将该文件下载到本地磁盘**</span> ## 3.3 解压刚刚下载的文件 如无法解压*.gz文件,请先自行安装`360解压`软件进行解压 将会获得一份后缀名*.sql的文件,如: `xxx_2025-08-23_00-01-01_mysql_data.sql` # 四、获取GTID 使用Notepad++打开,按 <kbd>Ctrl + F</kbd> 搜索 `SET @@GLOBAL.GTID_PURGED` 你会找到这么一段内容,使用记事本将它记下来 ```sql SET @@GLOBAL.GTID_PURGED='23bdaa85-fb05-11ef-bd92-00163e0a39f5:1-6, d14fa6d5-fb37-11ef-9aa1-3254006953ee:1-5693905, e47cb286-bf59-11ee-bfcb-00463e01d1b7:1-303169'; ``` 如果有另外的主库,使用相同的方法将它记下来 ```sql SET @@GLOBAL.GTID_PURGED='e47cb286-bf34-11ee-bfcb-00163e01d1b7:1-302950'; ``` 你会发现2个主库加起来一共有4个GTID,分别是 > 23bdaa85-fb05-11ef-bd92-00163e0a39f5:1-6 > d14fa6d5-fb37-11ef-9aa1-3254006953ee:1-5693905 > e47cb286-bf59-11ee-bfcb-00463e01d1b7:1-303169 > e47cb286-bf34-11ee-bfcb-00163e01d1b7:1-302950 这里正确的做法就是将2个主库的GTID合并起来,用英文逗号隔开,在从库上执行 ```sql STOP SLAVE; -- 停止主从同步 RESET SLAVE ALL; -- 清除旧通道 RESET MASTER; -- 清空从库自身的GTID历史 SET GLOBAL gtid_purged = '23bdaa85-fb05-11ef-bd92-00163e0a39f5:1-6,d14fa6d5-fb37-11ef-9aa1-3254006953ee:1-5693905,e47cb286-bf59-11ee-bfcb-00463e01d1b7:1-303169,e47cb286-bf34-11ee-bfcb-00163e01d1b7:1-302950'; SELECT @@GLOBAL.GTID_EXECUTED; ``` <br><br><br><br> <div style="background-color: #d0d6dd;padding: 30px;border-radius:40px;"> ## (可跳过)这里我的主库1出现了3个GTID,存在其他主库的GTID了,需要处理一下 我的主库中只有 `d14fa6d5-fb37-11ef-9aa1-3254006953ee:1-5693905` 是属于它的 **错误操作** 直接设置主库的GTID,会造成数据损坏(历史的事务丢失了GTID会错乱) --- **正确操作** 1. 停止对旧主库的所有写入。 2. 使用 mysqldump `--set-gtid-purged=OFF` 从旧主库导出纯数据(不包含GTID信息) 3. 将纯数据导入新主库。此时,新主库的 `gtid_executed` 是空的,但它拥有了所有数据。 4. 将应用程序的数据库连接地址指向新主库。 5. 让新数据库产生写入事务,此时它就会生成全新的GTID 6. 可用命令查询 **1. 设置旧主库为只读(停止写入):** ```sql -- 在旧主库的命令行执行: FLUSH TABLES WITH READ LOCK; SET GLOBAL read_only = ON; -- 保持这个会话连接,锁才有效。可以新开一个会话进行后续操作。 ``` **2. 在旧主库上创建纯净数据备份:** ```bash # 在Linux命令行执行: mysqldump -uroot -p替换为mysqlroot密码 替换为数据库名 \ --default-character-set=utf8mb4 \ --single-transaction \ --triggers \ --routines \ --events \ --set-gtid-purged=OFF | gzip > /www/wwwroot/master_dump.sql.gz; ``` **3. (可选) 解锁旧主库(如果需要它暂时提供服务):** ```sql -- 回到之前持有锁的会话,执行: UNLOCK TABLES; SET GLOBAL read_only = OFF; ``` **4. 在新主库上导入纯净备份** ```bash # 在新主库的Linux命令行执行: mysql -uroot -p密码 < /www/wwwroot/master_dump.sql.gz; ``` **5.【验证命令】查询新主库的GTID状态(应为空)** ```sql -- 在新主库的命令行执行: SHOW GLOBAL VARIABLES LIKE 'gtid_executed'; SHOW GLOBAL VARIABLES LIKE 'gtid_purged'; ``` **预期结果:** 这两个查询的 `Value` 字段都应该是空字符串 (`''`)。这证明它是一个“纯净”的状态,数据已就位但无GTID历史。 **6. 切换应用 & 生成新GTID** 1. 将应用程序的连接配置指向新主库的IP地址。 2. 应用开始写入后,新主库会生成新GTID。 3. 【验证命令】确认新主库已开始生成属于自己的新GTID: ```sql -- 在新主库的命令行执行: SHOW GLOBAL VARIABLES LIKE 'gtid_executed'; SHOW MASTER STATUS; ``` **预期结果:** `gtid_executed` 将显示为新生成的GTID,例如:`aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa:1-5` `SHOW MASTER STATUS` 会显示当前的二进制日志文件位置和已执行的GTID集合 迁移主库成功,开始全新的GTID  </div> <br><br><br><br> # 五. 恢复数据库到从库 ## 5.1 操作前的准备 ```sql SHOW GLOBAL VARIABLES LIKE 'gtid_executed'; SHOW GLOBAL VARIABLES LIKE 'gtid_purged'; ``` 为了避免发生未知错误,操作前确保服务器的GTID查出来是空的,如果不是,可通过重装MySQL解决 或者在从服务器上执行 `RESET MASTER; ` 重置从服务器的 GTID 状态 