签到成功

知道了

CNDBA社区CNDBA社区

MariaDB 基于 GTID 的主从复制 搭建手册

2018-02-12 12:56 6326 0 原创 MySQL
作者: dave

1 GTID 概念说明

GTID是一个基于原始mysql服务器生成的一个已经被成功执行的全局事务ID,它由服务器ID以及事务ID组合而成。这个全局事务ID不仅仅在原始服务器器上唯一,在所有存在主从关系的mysql服务器上也是唯一的。正是因为这样一个特性使得mysql的主从复制变得更加简单,以及数据库一致性更可靠。

http://www.cndba.cn/cndba/dave/article/2663

1.1 GTID的概念
  1. 1、全局事务标识:global transaction identifiers。
  2. 2、GTID是一个事务一一对应,并且全局唯一ID。
  3. 3、一个GTID在一个服务器上只执行一次,避免重复执行导致数据混乱或者主从不一致。
  4. 4、GTID用来代替传统复制方法,不再使用MASTER_LOG_FILE+MASTER_LOG_POS开启复制。而是使用MASTER_AUTO_POSTION=1的方式开始复制。
  5. 5、MySQL-5.6.5开始支持的,MySQL-5.6.10后开始完善。
  6. 6、在传统的slave端,binlog是不用开启的,但是在GTID中slave端的binlog是必须开启的,目的是记录执行过的GTID(强制)。
1.2 GTID的组成
  1. 1.GTID = source_id:transaction_id
  2. 2.source_id,用于鉴别原服务器,即mysql服务器唯一的的server_uuid,由于GTID会传递到slave,所以也可以理解为源ID。
  3. 3.transaction_id,为当前服务器上已提交事务的一个序列号,通常从1开始自增长的序列,一个数值对应一个事务。
1.3 GTID的优势
  1. 1、更简单的实现failover,不用以前那样在需要找log_file和log_pos。
  2. 2、更简单的搭建主从复制。
  3. 3、比传统的复制更加安全。
  4. 4、GTID是连续的没有空洞的,保证数据的一致性,零丢失。
1.4 GTID的工作原理
  1. 1、当一个事务在主库端执行并提交时,产生GTID,一同记录到binlog日志中。
  2. 2、binlog传输到slave,并存储到slave的relaylog后,读取这个GTID的这个值设置gtid_next变量,即告诉Slave,下一个要执行的GTID值。
  3. 3、sql线程从relay log中获取GTID,然后对比slave端的binlog是否有该GTID。
  4. 4、如果有记录,说明该GTID的事务已经执行,slave会忽略。
  5. 5、如果没有记录,slave就会执行该GTID事务,并记录该GTID到自身的binlog,
  6. 在读取执行事务前会先检查其他session持有该GTID,确保不被重复执行。
  7. 6、在解析过程中会判断是否有主键,如果没有就用二级索引,如果没有就用全部扫描。
1.5 GTID的限制
  1. 1.不支持非事务引擎
  2. 2.不支持create table … select 语句复制(主库直接报错)
  3. 原理:( 会生成两个sql,一个是DDL创建表SQL,一个是insert into 插入数据的sql。由于DDL会导致自动提交,所以这个sql至少需要两个GTID,但是GTID模式下,只能给这个sql生成一个GTID )
  4. 3.不允许一个SQL同时更新一个事务引擎表和非事务引擎表
  5. 4.在一个复制组中,必须要求统一开启GTID或者是关闭GTID
  6. 5.开启GTID需要重启(5.7除外)
  7. 6.开启GTID后,就不再使用原来的传统复制方式
  8. 7.对于create temporary table 和 drop temporary table语句不支持
  9. 8.不支持sql_slave_skip_counter
1.6 MySQL GTID 的主从配置

MariaDB和MySQL 在主从配置上,有所不同,在MySQL中,需要做如下工作:http://www.cndba.cn/cndba/dave/article/2663

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。http://www.cndba.cn/cndba/dave/article/2663

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 时会报下面的错误:

http://www.cndba.cn/cndba/dave/article/2663

ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_EXECUTED is empty.

此时恢复出的 MySQL 实例的 GTID_EXECUTED 和在主库备份时的一致:http://www.cndba.cn/cndba/dave/article/2663

由于恢复出 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/2652http://www.cndba.cn/cndba/dave/article/2663

因为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]#

记录当前日志位置并解锁http://www.cndba.cn/cndba/dave/article/2663

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先来进行数据同步:

http://www.cndba.cn/cndba/dave/article/2663

[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,再启动同步:http://www.cndba.cn/cndba/dave/article/2663http://www.cndba.cn/cndba/dave/article/2663

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)

同步正常。

版权声明:本文为博主原创文章,未经博主允许不得转载。

用户评论
* 以下用户言论只代表其个人观点,不代表CNDBA社区的观点或立场
dave

dave

关注

人的一生应该是这样度过的:当他回首往事的时候,他不会因为虚度年华而悔恨,也不会因为碌碌无为而羞耻;这样,在临死的时候,他就能够说:“我的整个生命和全部精力,都已经献给世界上最壮丽的事业....."

  • 2283
    原创
  • 3
    翻译
  • 579
    转载
  • 196
    评论
  • 访问:8173450次
  • 积分:4428
  • 等级:核心会员
  • 排名:第1名
精华文章
    最新问题
    查看更多+
    热门文章
      热门用户
      推荐用户
        Copyright © 2016 All Rights Reserved. Powered by CNDBA · 皖ICP备2022006297号-1·

        QQ交流群

        注册联系QQ