1 GTID 概念说明
GTID是一个基于原始mysql服务器生成的一个已经被成功执行的全局事务ID,它由服务器ID以及事务ID组合而成。这个全局事务ID不仅仅在原始服务器器上唯一,在所有存在主从关系的mysql服务器上也是唯一的。正是因为这样一个特性使得mysql的主从复制变得更加简单,以及数据库一致性更可靠。
1.1 GTID的概念
- 1、全局事务标识:global transaction identifiers。
- 2、GTID是一个事务一一对应,并且全局唯一ID。
- 3、一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
- 4、GTID用来代替传统复制方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。
- 5、MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。
- 6、在传统的slave端,binlog是不用开启的,但是在GTID中slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。
1.2 GTID的组成
- 1.GTID = source_id:transaction_id
- 2.source_id,用于鉴别原服务器,即mysql服务器唯一的的server_uuid,由于GTID会传递到slave,所以也可以理解为源ID。
- 3.transaction_id,为当前服务器上已提交事务的一个序列号,通常从1开始自增长的序列,一个数值对应一个事务。
1.3 GTID的优势
- 1、更简单的实现failover,不用以前那样在需要找log_file和log_pos。
- 2、更简单的搭建主从复制。
- 3、比传统的复制更加安全。
- 4、GTID是连续的没有空洞的,保证数据的一致性,零丢失。
1.4 GTID的工作原理
- 1、当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
- 2、binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
- 3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
- 4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
- 5、如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,
- 在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
- 6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。
1.5 GTID的限制
- 1.不支持非事务引擎
- 2.不支持create table … select 语句复制(主库直接报错)
- 原理:( 会生成两个sql,一个是DDL创建表SQL,一个是insert into 插入数据的sql。由于DDL会导致自动提交,所以这个sql至少需要两个GTID,但是GTID模式下,只能给这个sql生成一个GTID )
- 3.不允许一个SQL同时更新一个事务引擎表和非事务引擎表
- 4.在一个复制组中,必须要求统一开启GTID或者是关闭GTID
- 5.开启GTID需要重启(5.7除外)
- 6.开启GTID后,就不再使用原来的传统复制方式
- 7.对于create temporary table 和 drop temporary table语句不支持
- 8.不支持sql_slave_skip_counter
1.6 MySQL GTID 的主从配置
MariaDB和MySQL 在主从配置上,有所不同,在MySQL中,需要做如下工作:
1.6.1 主从库参数配置
1、主:
[mysqld]
#GTID:
server_id=135 #服务器id
gtid_mode=on #开启gtid模式
enforce_gtid_consistency=on #强制gtid一致性,开启后对于特定create table不被支持
#binlog
log_bin=master-binlog
log-slave-updates=1
binlog_format=row #强烈建议,其他格式可能造成数据不一致
#relay log
skip_slave_start=1
2、从:
[mysqld]
#GTID:
gtid_mode=on
enforce_gtid_consistency=on
server_id=143
#binlog
log-bin=slave-binlog
log-slave-updates=1
binlog_format=row #强烈建议,其他格式可能造成数据不一致
#relay log
skip_slave_start=1
1.6.2 备份恢复数据库已经开启同步
这里使用 —all-databases选项是因为基于 GTID 的复制会记录全部的事务, 所以要构建一个完整的dump。
mysqldump -u root -p --flush-logs --master-data=2 --single-transaction --routines --triggers --events --all-databases > /tmp/slave.sql
生成的 slave.sql 文件里包含了设置 gtid_purged 的语句。
在从库恢复数据前需要先通过 reset master 清空 gtid_executed 变量,然后在导入:
mysql -u root -p < /tmp/slave.sql
否则执行设置 GTID_PURGED 的 SQL 时会报下面的错误:
ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.
此时恢复出的 MySQL 实例的 GTID_EXECUTED 和在主库备份时的一致:
由于恢复出 MySQL 实例已经被设置了正确的 GTID_EXECUTED ,下面以 master_auto_postion = 1 的方式 CHANGE MASTER 到原来的主节点即可开始复制。
mysql> change master to master_host='192.168.56.2', master_user='slave', master_password=' slave ', master_auto_position = 1;
如果不希望备份文件中生成设置 GTID_PURGED 的 SQL,可以给 mysqldump传入 —set-gtid-purged=OFF 关闭。
但MariaDB的细节与MySQL 不同,下面我们看下MariaDB中的配置方法。
2 主库配置
2.1 修改配置文件:
在/etc/my.cnf文件中,加上
[mysqld]
binlog-format=ROW # 二进制日志文件格式
log-slave-updates=True # slave更新是否记入日志
master-info-repository=TABLE
relay-log-info-repository=TABLE # 此两项为打开从服务器崩溃二进制日志功能,信息记录在事物表而不是保存在文件
sync-master-info=1 # 值为1确保信息不会丢失
slave-parallel-threads=2 #同时启动多少个复制线程,最多与要复制的数据库数量相等即可
binlog-checksum=CRC32 # 效验码
master-verify-checksum=1 # 启动主服务器效验
slave-sql-verify-checksum=1 # 启动从服务器效验
binlog-rows-query-log-events=1 # 用于在二进制日志详细记录事件相关的信息,可降低故障排除的复杂度;
bind-address = 192.168.60.103 # 监听本机网卡ip
server_id = 103 # 一组主从组里的每个id必须是唯一值。推荐用ip位数
log-bin = /mysql/binlog/mysql-bin
2.2 在主数据库建立账户并授权从数据库访问:
grant replication slave on *.* to 'slave'@'%' identified by 'slave';
2.3 重启数据库
[root@www.cndba.cn/dave binlog]# service mysql restart
Shutting down MySQL.. [ OK ]
Starting MySQL.180209 06:36:05 mysqld_safe Logging to '/mysql/log/www.cndba.cn-error.log'.
180209 06:36:05 mysqld_safe Starting mysqld daemon with databases from /mysql/data
[ OK ]
[root@www.cndba.cn/dave binlog]#
2.4 检查主数据库的master状态
MariaDB [(none)]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000006 | 342 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
3 备份主库并恢复到从库
这里逻辑备份和物理备份都行,只要把数据同步到备库即可,关于他们的详细说明,参考:
MariaDB 的逻辑备份与恢复
http://www.cndba.cn/dave/article/2650
MariaDB 使用 xtrabackup 工具进行备份与恢复
http://www.cndba.cn/dave/article/2652
因为xtrabackup需要单独的安装,所以我们这里直接使用msyqldump进行逻辑备份与恢复。为了保证数据的一致性,这里也有两种备份方法。
3.1 不锁表备份
[root@www.cndba.cn/dave binlog]# mysqldump -u root -p --flush-logs --master-data=2 --single-transaction --routines --triggers --events --all-databases > /tmp/slave.sql
Enter password:
[root@www.cndba.cn/dave binlog]#
[root@www.cndba.cn/dave binlog]# scp /tmp/slave.sql 192.168.56.3:/tmp/
root@192.168.56.3's password:
slave.sql 100% 712KB 711.6KB/s 00:00
[root@www.cndba.cn/dave binlog]#
恢复到从库:
[root@MariaDB ~]# mysql -u root -p < /tmp/slave.sql
Enter password:
[root@MariaDB ~]#
3.2 锁表备份
数据库锁表
MariaDB [(none)]> flush tables with read lock;
Query OK, 0 rows affected (0.00 sec)
[root@www.cndba.cn/dave binlog]# mysqldump -u root -p --flush-logs --master-data=2 --single-transaction --routines --triggers --events --all-databases > /tmp/slave.sql
Enter password:
[root@www.cndba.cn/dave binlog]#
[root@www.cndba.cn/dave binlog]# scp /tmp/slave.sql 192.168.56.3:/tmp/
root@192.168.56.3's password:
slave.sql 100% 712KB 711.6KB/s 00:00
[root@www.cndba.cn/dave binlog]#
记录当前日志位置并解锁
MariaDB [cndba]> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000008 | 401 | | |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)
MariaDB [cndba]> select binlog_gtid_pos('mysql-bin.000008', 401);
+------------------------------------------+
| binlog_gtid_pos('mysql-bin.000008', 401) |
+------------------------------------------+
| 0-2-6 |
+------------------------------------------+
1 row in set (0.00 sec)
MariaDB [(none)]> unlock tables;
Query OK, 0 rows affected (0.00 sec)
在从MariaDB服务器上还原数据
[root@slave ~]# mysql -uroot -p < /tmp/slave.sql
4 从库配置
4.1 修改配置文件
在/etc/my.cnf文件中,加上
server-id=2
log-bin= /mysql/binlog/mysql-bin
relay-log = /mysql/relaybin/relay-bin
注:
log-bin是二进制文件
relay-log 是接收主库二进制的辅助文件。
4.2 重启从数据库
[root@MariaDB mysql]# service mysql restart
Shutting down MySQL.. [ OK ]
Starting MySQL.180210 04:14:41 mysqld_safe Logging to '/mysql/log/www.cndba.cn-error.log'.
180210 04:14:41 mysqld_safe Starting mysqld daemon with databases from /mysql/data
[ OK ]
[root@MariaDB mysql]#
4.3 在命令行配置从库并启动复制:
4.3.1 不锁表备份的操作
先通过准确的pos先来进行数据同步:
[root@MariaDB mysql]# cat /tmp/slave.sql |more
-- MySQL dump 10.16 Distrib 10.2.12-MariaDB, for Linux (x86_64)
--
-- Host: localhost Database:
-- ------------------------------------------------------
-- Server version 10.2.12-MariaDB-log
……
--
-- Position to start replication or point-in-time recovery from
--
-- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000007', MASTER_LOG_POS=385;
执行:
MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='slave',master_password='slave',master_log_file='mysql-bin.000007',master_log_pos=385;
Query OK, 0 rows affected (0.03 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.00 sec)
如果配置错误先停止slave,修改,在启动:
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='slave',master_password='slave',master_log_file='mysql-bin.000004',master_log_pos=385;
Query OK, 0 rows affected (0.00 sec)
然后在通过如下2个命令检查同步情况:
MariaDB [(none)]> show slave status /G
MariaDB [(none)]> show processlist;
然后启用GTID同步:
MariaDB [(none)]> stop slave;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='slave',master_password='slave',master_port=3306,master_use_gtid=slave_pos;
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> show slave status /G
……
Using_Gtid: Slave_Pos
Gtid_IO_Pos: 0-1-5
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
1 row in set (0.00 sec)
4.3.2 锁表备份的操作
先根据备份期间查询的gtid设置GTID,再启动同步:
MariaDB [(none)]> set global gtid_slave_pos='0-2-6';
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> change master to master_host='192.168.56.2',master_user='slave',master_password='slave',master_port=3306,master_use_gtid=slave_pos;
Query OK, 0 rows affected (0.01 sec)
MariaDB [(none)]> start slave;
Query OK, 0 rows affected (0.01 sec)
备注:
MariaDB在启动时, 默认也会自动启动复制(slave)。IO进程和SQL进程状态都为Yes. 如果想禁止启用此功能,可以在/etc/my.cnf配置文件的mysqld下添加一行:skip-slave-start,然后重启从库生效。
MariaDB [cndba]> show slave status /G
……
Using_Gtid: Slave_Pos
Gtid_IO_Pos: 0-2-6
Replicate_Do_Domain_Ids:
Replicate_Ignore_Domain_Ids:
Parallel_Mode: conservative
SQL_Delay: 0
SQL_Remaining_Delay: NULL
Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
1 row in set (0.00 sec)
5 验证同步
--主库:
MariaDB [(none)]> use cndba
Database changed
MariaDB [cndba]> select * from dave;
+------+-------------------+
| id | name |
+------+-------------------+
| 1 | www.cndba.cn/dave |
| 1 | dave |
| 1 | dave |
+------+-------------------+
3 rows in set (0.00 sec)
MariaDB [cndba]> delete from dave where name='dave';
Query OK, 2 rows affected (0.01 sec)
MariaDB [cndba]> select * from dave;
+------+-------------------+
| id | name |
+------+-------------------+
| 1 | www.cndba.cn/dave |
+------+-------------------+
1 row in set (0.00 sec)
--备库查询
MariaDB [(none)]> use cndba
Database changed
MariaDB [cndba]> select * from dave;
+------+-------------------+
| id | name |
+------+-------------------+
| 1 | www.cndba.cn/dave |
+------+-------------------+
1 row in set (0.00 sec)
同步正常。
版权声明:本文为博主原创文章,未经博主允许不得转载。
- 上一篇:MariaDB 一主多从复制 搭建手册
- 下一篇:物质幸福时代已经结束,新时代来临