mysql的异步复制 && 基于gtid的主从复制

1.mysql主从复制----异步复制

1.1什么是异步复制?

异步复制(Asynchronous replication)

(1)逻辑上

MySQL默认的复制即是异步的,(文中主从复制即为异步复制)主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从库上,如果此时,强行将从提升为主,可能导致新主上的数据不完整。

(2)技术上

主库将事务 Binlog 事件写入到 Binlog 文件中,此时主库只会通知一下 Dump 线程发送这些新的 Binlog,然后主库就会继续处理提交操作,而此时不会保证这些 Binlog 传到任何一个从库节点上。

1.2 主从复制的原理

  • mysql主从复制是一个异步复制的过程。从一个实例(master)复制到另一个实例(slave),整个过程要由master上的I/O进程和slave上的sql进程和I/O进程共同完成。
  • 首先master必须打开binary log(bin-log),因为整个复制过程实际上就是slave端从master端获取相应的二进制日志,然后在本地完全顺序的执行日志中纪录的各种操作。
  • slvae主要依据两个线程,I/O线程和sql线程,slave开启I/O线程和master进行通信,获取二进制日志,sql线程负责回放。并不master做一步,slave就跟着做一步。

1.3 异步复制的流程

在这里插入图片描述
在这里插入图片描述
(1)master端在与客户端发生交互后,当数据库改变时,将数据库改变记入master的二进制日志

(2)Slave 端的 IO 进程连接上 Master,向 Master 请求指定日志文件的指定位置(或者从最开始的日志)之后的日志内容;Master 接收到来自 Slave 的 IO 进程的请求后,负责复制的 IO 进程根据 Slave 的请求信息,读取相应日志内容,返回给 Slave 的IO进程,并将本次请求读取的 bin-log 文件名及位置一起返回给 Slave 端

(3)Slave 端的 IO 进程接收到信息后,将接收到的日志内容依次添加到 Slave 端的 relay-log(中继日志) 文件的最末端,并将读取到的 Master 端的 bin-log 的文件名和位置记录到 master-info 文件中,以便在下一次读取的时候能够清楚的告诉 Master :”我需要从某个 bin-log 的哪个位置开始往后的日志内容,请发给我”;

(4)Slave 端的 Sql 进程检测到 relay-log (中继日志)中新增加了内容后,会马上解析 relay-log 的内容成为在 Master 端真实执行时候的那些可执行的内容,并在本地执行。

2.主从复制的实现

实验说明:

serverip
master172.25.19.121
slave172.25.19.122

在master:
(1)配置配置文件,设为主服务

[root@mysql1 mysql]# vim /etc/my.cnf
 29 log-bin=mysql-bin
 30 server-id=1
[root@mysql1 mysql]# systemctl start mysqld  ##启动mysqld服务

(2)获取初始密码,进行安全初始化

[root@mysql1 mysql]# cat /var/log/mysqld.log |grep password
2019-10-20T04:08:23.620069Z 1 [Note] A temporary password is generated for root@localhost: uBfpjfi5N,HI

安全初始化:

[root@mysql1 mysql]# mysql_secure_installation 

Securing the MySQL server deployment.

Enter password for user root: 

The existing password for the user account root has expired. Please set a new password.

New password: ##密码要为大于8位的大小写字母及数字组成

Re-enter new password: 

##后面选项都默认

(3)数据库授权主从服务用户

[root@mysql1 mysql]# mysql -uroot -pWestos+0019
mysql> grant replication slave on *.* to repl@'172.25.19.%' identified by 'Westos+0019';##授权给同一网段任意主机的repl用户
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> show master status;##查看master状态
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      691 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

在slave:
(1)修改mysql配置文件,成为从服务

[root@mysql2 mysql]# vim /etc/my.cnf
 29 server-id=2
[root@mysql2 mysql]# systemctl start mysqld ##启动服务


[root@mysql2 mysql]# cat /var/log/mysqld.log |grep password
2019-10-20T04:08:34.977903Z 1 [Note] A temporary password is generated for root@localhost: V?vS/C?6S?wZ

(2)安全初始化:

[root@mysql1 mysql]# mysql_secure_installation 

Securing the MySQL server deployment.

Enter password for user root: 

The existing password for the user account root has expired. Please set a new password.

New password: ##密码要为大于8位的大小写字母及数字组成

Re-enter new password: 

##后面选项都默认

(3)在数据库增加主服务master

[root@mysql2 mysql]# mysql -uroot -pWestos+0019
mysql> change master to master_host='172.25.19.121',master_user='repl',master_password='Westos+0019',master_log_file='mysql-bin.000002',master_log_pos=691;
Query OK, 0 rows affected, 2 warnings (0.04 sec)

mysql> show slave status\G;##查看主从状态

测试:
在master:

mysql> create database lin; ##创建数据库
mysql> use lin;
mysql> create table userlist(
    -> username varchar(10) not null,
    -> password varchar(10) not null);
Query OK, 0 rows affected (0.03 sec)

mysql> desc userlist;
+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| username | varchar(10) | NO   |     | NULL    |       |
| password | varchar(10) | NO   |     | NULL    |       |
+----------+-------------+------+-----+---------+-------+
2 rows in set (0.01 sec)
mysql> insert into userlist values('lin','123');
mysql> select * from userlist;
+----------+----------+
| username | password |
+----------+----------+
| lin      | 123      |
+----------+----------+
1 row in set (0.00 sec)

在slave端查看:

[root@mysql2 mysql]# mysql -uroot -pWestos+0019
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| lin                |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)

mysql> use lin;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from userlist;
+----------+----------+
| username | password |
+----------+----------+
| lin      | 123      |
+----------+----------+
1 row in set (0.00 sec)

主从复制成功

3.mysql中基于GTID的主从复制

3.1 什么是gtid?

  • 在传统的复制里面,主从复制默认是通过pos(position)复制,就是说在日志文档里,将用户进行的每一项操作都进行编号(pos),每一个事件都有一个起始编号,一个终止编号,在配置主从复制节点时,要求其从master的pos开始同步数据库里面的数据,这也称作传统复制技术。当发生故障,需要主从切换,需要找到binlog和pos点,然后将主节点指向新的主节点,相对来说比较麻烦,也容易出错。

  • 在MySQL 5.6里面,不用再找binlog和pos点,我们只需要知道主节点的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步

  • gtid(global transaction id 全局事物id)是对于一个已提交事务的编号,并且是一个全局唯一的编号。gtid实际上是由uuid+tid组成的,其中uuid是mysql实例的一个标识,tid则代表了该实例上交的事务数量,并且随着事务的提交单调递增。

  • gtid就是类似pos的作用,不过它是整个mysql复制架构全局通用的,即在整个mysql冗余架构中,它们的日志文件里面事件的gtid的数值是一致的。

pos与gtid的区别:

两者都是日志文件里的一个标志,如果将整个mysql集群看作一个整体,pos就是局部的,gtid就是全局的。

3.2 gtid主从复制的原理

(1)从服务器连接到主服务器之后,把自己执行过的GTID(Executed_Gtid_Set)<SQL线程> 、获取到的GTID(Retrieved_Gtid_Set)<IO线程>发给主服务器,主服务器把从服务器缺少的GTID及对应的transactions发过去补全即可。

(2)当主服务器挂掉的时候,找出同步最成功的那台从服务器,直接把它提升为主即可。如果硬要指定某一台不是最新的从服务器提升为主, 先change到同步最成功的那台从服务器, 等把GTID全部补全了,就可以把它提升为主了

(3)由于同一事务的GTID在所有节点上的值一致,我们都不需要知道GTID的具体值。 通过gtid保证每个主库上提交的事务在集群中有一个唯一的id。这种方式强化了主备的一致性,故障恢复及其容错能力。

3.3 实现

实验说明:
gtid主从复制基于先前的主从复制实验,前提是主从复制成功

在master:
修改配置文件,开启gtid模式

vim /etc/my.cnf
 32 gtid_mode=ON    ##开启gti模式
 33 enforce-gtid-consistency=true

systemctl restart mysqld ##重启服务

在slave:
(1)修改配置文件,开启gtid模式

vim /etc/my.cnf
 31 gitd_mode=ON  ##让他工作于gti的模式
 32 enforce-gtid-consistency=true
log_bin=ON ##可以选择 高可用的切换
log-slave-updates=ON  ##可选可不选5.7自带支持

systemctl restart mysqld 重启

(2)数据库重新配置主从复制

[root@mysql2 mysql]# mysql -uroot -pWestos+0019

mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

mysql> change master to
    -> master_host ='172.25.19.121',
    -> master_user='repl',
    -> master_password='Westos+0019',
    -> master_auto_position=1;
Query OK, 0 rows affected, 2 warnings (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)

测试:
在master端增添数据,在slave端查看主从事件的git记录 uuid与master uuid对应,查看相对应,基于gtid的主从复制成功

mysql> use mysql ;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> select * from gtid_executed;
+--------------------------------------+----------------+--------------+
| source_uuid                          | interval_start | interval_end |
+--------------------------------------+----------------+--------------+
| 425deb5c-f2ef-11e9-9d97-5254001fc762 |              1 |            1 |

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

补充mysqlUUID
UUID存放在/var/lib/mysql/auto.cnf文件中:

[root@mysql1 mysql]# cd /var/lib/mysql
[root@mysql1 mysql]# ls
auto.cnf         ibdata1      mysql-bin.000001  performance_schema
ca-key.pem       ib_logfile0  mysql-bin.000002  private_key.pem
ca.pem           ib_logfile1  mysql-bin.000003  public_key.pem
client-cert.pem  ibtmp1       mysql-bin.index   server-cert.pem
client-key.pem   lin          mysql.sock        server-key.pem
ib_buffer_pool   mysql        mysql.sock.lock   sys
[root@mysql1 mysql]# cat auto.cnf 
[auto]
server-uuid=425deb5c-f2ef-11e9-9d97-5254001fc762
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值