初识MariaDB之8——GTID主从复制

一、背景介绍

成都创新互联公司是网站建设技术企业,为成都企业提供专业的成都做网站、网站设计、外贸营销网站建设,网站设计,网站制作,网站改版等技术服务。拥有十多年丰富建站经验和众多成功案例,为您定制适合企业的网站。十多年品质,值得信赖!

在MySQL5.6之前,主从复制是通过binlog和position实现的,当A主机宕机后,B主机成为新的主节点,此时在C主机上需要使用sql语句:CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS='xxx';将自己的复制源指向B主机,难点在于,同一个事务在每台机器上的binlog名字和位置都不一样,怎么找到C主机当前同步停止点在B主机上的master_log_file和master_log_pos位置就成了问题

初识MariaDB之8——GTID主从复制初识MariaDB之8——GTID主从复制

于是MySQL在5.6.2之后产生了GTID,即全局事务ID(global transaction ID),其形式为:DomainID-ServerID-TransactionID,在配置是必须确保每个MySQL服务器的server_id都不相同,同一GTID事务在每个节点上都是相同的。

二、GTID与binlog

需要注意的是Mariadb的gtid配置方式与MySQL不相同,二者之间不兼容。MaraDB在10.0.2之后的版本默认是启用的,即使从服务器使用的是binlog和position进行主从复制,但他仍是采用GTID进行追踪

初识MariaDB之8——GTID主从复制初识MariaDB之8——GTID主从复制

这就意味着原先的slave配置可以简单的切换到GTID模式

STOP SLAVE;

CHANGE MASTER TO master_host='xxxx', master_port=3306, master_user='xxx',master_password='xxx',master_use_gtid=current_pos;

START SLAVE;

而从GTID模式切换回以前的binlog模式也不复杂

STOP SLAVE;

CHANGE MASTER TO MASTER_HOST='xxx', MASTER_LOG_FILE='xxx', MASTER_LOG_POS='xxx';

START SLAVE;

三、master_use_gtid介绍

master_use_gtid = { slave_pos | current_pos | no }有3种选项:

slave_pos:slave将Master最后一个GTID的position复制到本地,Slave主机可通过gtid_slave_pos变量查看最后一个GTID的position

current_pos:假设有AB两台主机,A是Master,当A故障后,B成为Master,A修复后以Slave的身份重新添加,A之前从没担任过slave角色,所以没有之前复制的GTID号,此时gtid_slave_pos为空,为了能让A能自动添加为Slave,此时就用到该选项。该选项是大多数情况下使用的选项,因为他简单易用同,不必在意服务器之前是Master还是Slave角色。但要注意不要让从服务器在binlog日志中写入事务。

建议在服务器上启用gtid_strict_mode,这样非Master产生的事物将被拒绝。如果从服务器没有开启binlog上面两种方式等价。

no:关闭GTID功能

四、环境及Maradb配置介绍

本次实验采用CentOS7.4,数据库版本为MariaDB-10.2.14,拓扑如下图所示:

初识MariaDB之8——GTID主从复制初识MariaDB之8——GTID主从复制

本次模拟当A主机故障后C主机将Master主机重新指向B主机,并且当A主机修复后以Slave的身份重新加入集群

三、操作步骤

1.3台服务器安装MariaDB-10.2.14(略)

2.A主机操作

(1)编辑配置文件

[root@host3 ~]# vim /etc/my.cnf.d/server.cnf

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

skip_name_resolve=ON

relay_log=mysql-relaylog

relay_log_index=mysql-relaylog

relay_log_purge=OFF

slow_query_log=ON

server-id=10

innodb_file_per_table=ON

binlog_format=ROW

log_bin=mysql-binlog

log_slave_updates=ON

gtid_strict_mode=ON

(2)启动并进入MySQL

[root@host3 ~]# systemctl start mariadb.service

[root@host3 ~]# mysql

(3)创建一个用于主从复制的账号

MariaDB [(none)]> grant replication slave on *.* to 'bak'@'172.16.10.%' identified by 'bakpass';

MariaDB [(none)]> flush privileges;

(4)备份当前数据库并发送给B主机

[root@host3 ~]# mysqldump -uroot --single-transaction  --databases=hellodb --masterdata=2 --quick > /tmp/hello.sql

[root@host3 ~]# scp -r /tmp/hellodb.sql root@172.16.10.40:/tmp

(5)之后做任意DML操作,查看当前 gtid_binlog_pos

MariaDB [hellodb]> show global variables like 'gtid%';

+------------------------+---------+

| Variable_name          | Value   |

+------------------------+---------+

| gtid_binlog_pos        | 0-10-40 |

| gtid_binlog_state      | 0-10-40 |

| gtid_current_pos       | 0-10-40 |

| gtid_domain_id         | 0       |

| gtid_ignore_duplicates | OFF     |

| gtid_slave_pos         |         |

| gtid_strict_mode       | ON      |

+------------------------+---------+

3.B主机操作(以备份形式复制)

(1)编辑配置文件

[root@host4 ~]# vim /etc/my.cnf.d/server.cnf

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

skip_name_resolve=ON

relay_log=mysql-relaylog

relay_log_index=mysql-relaylog

relay_log_purge=OFF

slow_query_log=ON

server-id=20

innodb_file_per_table=ON

binlog_format=ROW

log_bin=mysql-binlog

log_slave_updates=ON

gtid_strict_mode=ON

(2)查看备份时A主机的gtid_slave_pos位置

[root@host4 ~]# cat /tmp/hello.sql

初识MariaDB之8——GTID主从复制初识MariaDB之8——GTID主从复制

(3)登陆MySQL,创建一个用于主从复制的账号

[root@host4 ~]# systemctl start mariadb.service

[root@host4 ~]# mysql

MariaDB [(none)]> grant replication slave on *.* to 'bak'@'172.16.10.%' identified by 'bakpass';

MariaDB [(none)]> flush privileges;

(4)以备份方式还原并同步数据库

MariaDB [(none)]> source /tmp/hellodb.sql;

MariaDB [(none)]> SET GLOBAL gtid_slave_pos = '0-10-38';

MariaDB [(none)]> CHANGE MASTER TO master_host='172.16.10.30', master_port=3306, master_user='bak', master_password='bakpass',master_use_gtid=slave_pos;

MariaDB [(none)]> start slave;

(5)验证效果

MariaDB [hellodb]> show global variables like 'gtid%';

+------------------------+-----------------+

| Variable_name          | Value           |

+------------------------+-----------------+

| gtid_binlog_pos        | 0-10-40         |

| gtid_binlog_state      | 0-20-37,0-10-40 |

| gtid_current_pos       | 0-10-40         |

| gtid_domain_id         | 0               |

| gtid_ignore_duplicates | OFF             |

| gtid_slave_pos         | 0-10-40         |

| gtid_strict_mode       | ON              |

+------------------------+-----------------+

可以看到gtid_binlog_pos已经和A主机保持一致,之前导入数据库和创建复制账号所以B主机上gtid_binlog_state有2个值,官方建议开启gtid_strict_mode选项或临时禁用sql_log_bin

4.设置C服务器(以新服务器方式同步)

(1)编辑配置文件(该服务器只作为Slave角色binlog可以不要)

[root@host5 ~]# vim /etc/my.cnf.d/server.cnf

[mysqld]

datadir=/var/lib/mysql

socket=/var/lib/mysql/mysql.sock

skip_name_resolve=ON

relay_log=mysql-relaylog

relay_log_index=mysql-relaylog

relay_log_purge=OFF

slow_query_log=ON

server-id=20

innodb_file_per_table=ON

binlog_format=ROW

log_bin=mysql-binlog

log_slave_updates=ON

gtid_strict_mode=ON

(2)启动并进入MySQL

[root@host5 ~]# systemctl start mariadb.service

[root@host5 ~]# mysql

(3)以空服务器进行数据库同步恢复

MariaDB [(none)]> SET GLOBAL gtid_slave_pos = "";

MariaDB [(none)]> CHANGE MASTER TO master_host='172.16.10.30', master_port=3306, master_user='bak', master_password='bakpass',master_use_gtid=current_pos;

MariaDB [(none)]> start slave;

(4)验证效果

MariaDB [(none)]> show global variables like 'gtid%';

+------------------------+---------+

| Variable_name          | Value   |

+------------------------+---------+

| gtid_binlog_pos        | 0-10-40 |

| gtid_binlog_state      | 0-10-40 |

| gtid_current_pos       | 0-10-40 |

| gtid_domain_id         | 0       |

| gtid_ignore_duplicates | OFF     |

| gtid_slave_pos         | 0-10-40 |

| gtid_strict_mode       | ON      |

+------------------------+---------+

===================以上完成主从环境搭建=========================

5.停止A主机MySQL服务,模拟故障

[root@host3 ~]# systemctl stop mariadb.service

6.此时将B主机提升为Master主机,并进行操作

MariaDB [hellodb]> stop slave;

MariaDB [hellodb]> show global variables like 'gtid%';

+------------------------+-----------------+

| Variable_name          | Value           |

+------------------------+-----------------+

| gtid_binlog_pos        | 0-10-40         |

| gtid_binlog_state      | 0-20-37,0-10-40 |

| gtid_current_pos       | 0-10-40         |

| gtid_domain_id         | 0               |

| gtid_ignore_duplicates | OFF             |

| gtid_slave_pos         | 0-10-40         |

| gtid_strict_mode       | ON              |

+------------------------+-----------------+

MariaDB [hellodb]> delete from students where stuid=21;

MariaDB [hellodb]> show global variables like 'gtid%';

+------------------------+-----------------+

| Variable_name          | Value           |

+------------------------+-----------------+

| gtid_binlog_pos        | 0-20-41         |

| gtid_binlog_state      | 0-10-40,0-20-41 |

| gtid_current_pos       | 0-20-41         |

| gtid_domain_id         | 0               |

| gtid_ignore_duplicates | OFF             |

| gtid_slave_pos         | 0-10-40         |

| gtid_strict_mode       | ON              |

+------------------------+-----------------+

7.将C主机的Master有A指向B,并观察变化

MariaDB [(none)]> show global variables like 'gtid%';

+------------------------+---------+

| Variable_name          | Value   |

+------------------------+---------+

| gtid_binlog_pos        | 0-10-40 |

| gtid_binlog_state      | 0-10-40 |

| gtid_current_pos       | 0-10-40 |

| gtid_domain_id         | 0       |

| gtid_ignore_duplicates | OFF     |

| gtid_slave_pos         | 0-10-40 |

| gtid_strict_mode       | ON      |

+------------------------+---------+

MariaDB [(none)]> stop slave;

MariaDB [(none)]> CHANGE MASTER TO master_host='172.16.10.40', master_port=3306, master_user='bak', master_password='bakpass',master_use_gtid=current_pos;

MariaDB [(none)]> start slave;

MariaDB [(none)]> show global variables like 'gtid%';

+------------------------+-----------------+

| Variable_name          | Value           |

+------------------------+-----------------+

| gtid_binlog_pos        | 0-20-41         |

| gtid_binlog_state      | 0-10-40,0-20-41 |

| gtid_current_pos       | 0-20-41         |

| gtid_domain_id         | 0               |

| gtid_ignore_duplicates | OFF             |

| gtid_slave_pos         | 0-20-41         |

| gtid_strict_mode       | ON              |

+------------------------+-----------------+

此时C主机的gtid_slave_pos已发生改变

MariaDB [(none)]> show variables like 'gtid_slave_pos';

+----------------+---------+

| Variable_name  | Value   |

+----------------+---------+

| gtid_slave_pos | 0-20-41 |

+----------------+---------+

8.再将A主机以Slave的身份加入集群操作

[root@host3 tmp]# systemctl start mariadb.service

[root@host3 tmp]# mysql

MariaDB [(none)]> CHANGE MASTER TO master_host='172.16.10.40', master_port=3306, master_user='bak', master_password='bakpass',master_use_gtid=current_pos;

MariaDB [(none)]> show variables like 'gtid_slave_pos';

+----------------+---------+

| Variable_name  | Value   |

+----------------+---------+

| gtid_slave_pos | 0-20-41 |

+----------------+---------+

至此全部操作完成

补充说明:

1.master_use_gtid = { slave_pos | current_pos }具体用哪一种仍不是很明白,文档说current_pos适用于大部分环境,所以后期使用都是用该值。

2.Master和Candidate之间可以采用半同步方式降低数据不一致

3.双主模式下1台采用binlog1台采用GTID可以正常工作


本文题目:初识MariaDB之8——GTID主从复制
文章位置:http://pwwzsj.com/article/ghcsjs.html