MySQL异步复制(基于position和基于gtid的主从复制)

mac2025-12-10  8

一.MySQL异步复制(基于position的主从复制)

数据备份 数据备份是一种古老而有效的数据保护手段,早期的数据备份手段主要是数据冷备,即定期将数据复制到 某种存储介质(磁带,光盘…)上并物理存档保管,如果系统存储损坏,那么就从冷备的存储中恢复数据 冷备的优点是简单和廉价,成本和技术难度都较低,缺点是不能保证数据最终一致 由于数据是定期复制,因此备份设备中的数据比系统中的数据陈旧,如果系统数据丢失,那么从上个备份点开始后更新的数据就会永久丢失,不能从备份中恢复,同时也不能保证数据的可用性,从冷备存储中恢数据需要较长的时间,而这段时间无法访问数据,系统也不可用

实验环境,三个干净的虚拟机(默认端口3306)

异步复制(主从复制)master节点不会关心slave节点的状态,只需要写自己的数据即可 能不能完成复制看slave节点的io线程和sql线程是否开启

主从复制的要求:

(1)主库开启binlog日志(设置log-bin参数) (2)主从server-id不同 (3)从库服务器能连同主库

主从复制的原理:

**mysql的主从配置又叫replication,AB复制,基于binlog二进制日志,主数据库必须开启binlog二进制日志才能进行复制** (1) master将改变记录到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events); (2)从库生成两个线程,一个i/o线程,一个SQL线程,i/o线程去请求主库的binlog,sql线程进行日志回放来复制 (3) slave将master的binary log events拷贝到它的中继日志(relay log); (4)slave重做中继日志中的事件,将更改应用到自己的数据上。

mysql的主从复制(异步复制)(基于position)把一个事件拆开来复制,并不是以一个完整的事件为单位来进行复制**

一开始两个mysql必须一模一样,否则会报错 master自己做自己的,写在自己的日志里 slave能否同步成功取决于IO线程,和SQL线程回放日志 IO通过联系master拿到master的二进制日志,SQL回放日志 slave节点的数据总比master节点的数据慢

异步复制:在主节点写入日志即返回成功,默认情况下MySQL5.5/5.6/5.7和mariaDB10.0/10.1的复制功能是异步的

异步复制可以实现最佳的性能,主库把binlog日志发送给从库,这一动作就结束了,并不验证从库,会造成主从库数据不一致

1.mysql的主从复制

1)下载mysql的rpm包 tar xf mysql-5.7.24-1.el7.x86_64.rpm-bundle.tar 2)安装需要的包 yum install -y mysql-community-client-5.7.24-1.el7.x86_64.rpm mysql-community-common-5.7.24-1.el7.x86_64.rpm mysql-community-libs-5.7.24-1.el7.x86_64.rpm mysql-community-libs-compat-5.7.24-1.el7.x86_64.rpm mysql-community-server-5.7.24-1.el7.x86_64.rpm #安装后会替换mariadb相关的库文件 #server2也需要装

3)修改配置文件,配合官方文档看

负责在主、从服务器传输各种修改动作的媒介是主服务器的二进制变更日志,这个日志记载着需要传输给从服务器的各种修改动作。因此,主服务器必须激活二进制日志功能。从服务器必须具备足以让它连接主服务器并请求主服务器把二进制变更日志传输给它的权限

vim /etc/my.cnf log-bin=mysql-bin ##文档最后加,二进制日志复制,id号来区分主机 主服务器必须激活二进制日志功能 server-id=1

开启二进制文件并且命名

4)启动mysql systemctl start mysqld 5)会生成一个临时密码 cat /var/log/mysqld.log | grep password 2019-02-23T07:39:25.392617Z 1 [Note] A temporary password is generated for root@localhost: N7Nn<KkJsa!a

6)尝试连接,但是发现不能查看库 mysql -uroot -p'N7Nn<KkJsa!a' mysql> show databases; ERROR 1820 (HY000): You must reset your password using ALTER USER statement before executing this statement. 这个密码必须有特殊字符,英文字母的大小写还有数字

7)安全初始化 mysql_secure_installation 密码要求有大小写,数字,特殊字符,其他全选y (因为有安全检测) 完成后可以登录数据库

server2同理

8)创建并授权用来做复制的用户 在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master。进行复制操作的用户会授予REPLICATION SLAVE权限。用户名的密码都会存储在文本文件master.info中 mysql> grant replication slave on *.* to repl@'172.25.136.%' identified by 'Wsp+123ld'; ##授权repl用户可以对所有数据库的所有表操作,repl用户可以来取 mysql> show plugins; ##查看插件,因为有密码插件,所以密码必须设置为复杂的

|REPLICATION|表示复制的权限| 同步的权限 |* .* |表示对所有库的所有表都授权| |repl |用户名| |‘172.25.63.%’ |授权172.25.63网段的所有数据库节点都可以同步(复制)|

mysql> show master status; ##查看master状态

mysql-bin就是/etc/my.cnf里面的开启二进制日志的名字

##在server2上同样初始化mysql 修改/etc/my.cnf

vim /etc/my.cnf server-id=2 ##文件最后加 启动mysql systemctl start mysqld #在物理机上尝试连接master的数据库,测试repl帐号 mysql -h 172.25.136.1 -urepl -pWsp+123ld 可以登录,但是查看不到任何信息,因为没有权限

#在server2上配置master信息 mysql> change master to master_host='172.25.136.1', master_user='repl', master_password='Wsp+123ld', master_log_file='mysql-bin.000002', master_log_pos=1004; **MASTER_LOG_POS 它是日志的开始位置** #其中master_log_file和maMASTER_LOG_POS的值为0,因为它是日志的开始位置ster_log_pos写在server1上执行show master status看到的信息 MASTER_LOG_FILE='mysql-bin.000002', ##主库的日志文件,其实就是开启io进程,最新的二进制文件名称mysql-bin.000002 MASTER_LOG_POS=1567; ##主库的状态码,最新的位置开始 只有端口和位置不需要单引号,其他的都需要。 mysql> start slave; mysql> show slave status\G ##查看主从复制状态 Slave_IO_Running: Yes Slave_SQL_Running: Yes ##这两个参数是Yes,表示成功

server1授权的是repl,所以此处的用户也用repl身份登陆数据库 回到server1上 查看mysql数据目录下的文件,有刚刚显示的日志文件

9)创建新数据测试主从同步是否生效 '注意:写操作只能在master节点上做, 因为master节点不会去同步slave节点的内容'!!!!!!!!!!!!!!!!!!!! mysql> create database westos; ##在server2上发现也能看到westos库 mysql> use westos mysql> create table usertb ( -> username varchar(10) not null, -> password varchar(15) not null); ##建表 mysql> desc usertb; ##查看表信息 mysql> insert into usertb values ('user1','123'); ##插入数据 mysql> select * from usertb; ##查看

在server1 继续插入数据 发现在server2节点仍然可以同步过来

所以这个异步复制(基于position的主从复制)就成功了,实验效果很明显 数据已同步!!!

二.基于GTID的主从复制 + 半同步(作业)

由于同一事务的GTID在所有节点上的值一致 我们都不需要知道GTID的具体值 前提:需要做好前面的binlog复制’ 在传统的复制里面,当发生故障,需要主从切换,需要找到binlog和pos点,然后将主节点指向新的主节点,相对来说比较麻烦,也容易出错。 在MySQL5.6里面,不用再找binlog和pos点,我们只需要知道主节点的ip,端口,以及账号密码就行,因为复制是自动的,MySQL会通过内部机制GTID自动找点同步

从服务器连接到主服务器之后,把自己执行过的GTID(Executed_Gtid_Set)<SQL线程> 、获取到的GTID(Retrieved_Gtid_Set)<IO线程>发给主服务器,主服务器把从服务器缺少的GTID及对应的transactions发过去补全即可。当主服务器挂掉的时候,找出同步最成功的那台从服务器,直接把它提升为主即可。如果硬要指定某一台不是最新的从服务器提升为主, 先change到同步最成功的那台从服务器, 等把GTID全部补全了,就可以把它提升为主了

GTID复制名词释义

server-id:服务器身份id,在初始化MySQL时,会自动生成一个server-id并写到数据目录的auto.cnf文件中,官方不建议修改,并且server-id跟GTID有密切关系, 并且对于任意一个数据库节点,server-id是唯一的

GTID:全局事务标识符,使用这个功能时,内次事务提交都会在binlog里生成一个唯一的标识符,它由UUID和事务ID组成,首次提交的事务为1,第二次为2,第三次为3,以此类推。

GTID实际上是由UUID+TID (即transactionId)组成的。其中UUID(即server_uuid) 产生于auto.conf文件(cat /data/mysql/data/auto.cnf),是一个MySQL实例的唯一标识。TID代表了该实例上已经提交的事务数量,并且随着事务提交单调递增,所以GTID能够保证每个MySQL实例事务的执行(不会重复执行同一个事务,并且会补全没有执行的事务)。

开启GTID,无需找到binlog和POS点,直接change master to master_auto_postion=1即可,它会自动寻找同步

. show variables like ‘log_%’; #查看二进制日志

下来实现基于gtid的主从复制(以一个事件为单位进行复制)

异步复制的效率高,master节点不会等待slave节点 基于gtid的主从复制不容易因为master一个事件的中断而造成数据丢失而不能复制 基于position的主从复制容易因为master一个事件的中断而造成数据丢失而不能复制

1)先在server1上添加配置 vim /etc/my.cnf ##在文件最后添加 加入:开启gtid的信息 gtid_mode=ON enforce-gtid-consistency=true

mysql> use mysql mysql> select * from gtid_executed; ##是空的,因为还没重启 ##在slave上面看 Empty set (0.00 sec)

root@server1 mysql]# mysqlbinlog mysql-bin.000002 ##可以看到之前做的操作都在里面, 可以看出完成一个事件需要很多步

如果是基于position的主从复制:将一个事件拆开来复制,如果一个事件进行的过程中出现问题,那么复制也会出现问题

如果是基于gtid的主从复制:一个以事件为单位进行复制,如果一个事件进行的过程中出现问题,那么复制也不会出现问题

[root@server1 mysql]# cat auto.cnf ##看到server1的uuid [auto] server-uuid=f84e8de1-38a2-11e9-b78c-5254009afece systemctl restart mysqld

2)在server2上配置 (mysql5.6 slave必须开启binlog日志 但是5.7中不是必须的) gtid_mode=ON(必选) enforce-gtid-consistency(必选) log_bin=ON(可选)--高可用切换,最好设置ON log-slave-updates=ON(可选)--高可用切换,最好设置ON(也就是把从master上同步的数据和自己的数据整合在一起) vim /etc/my.cnf ##在文件最后添加 gtid_mode=ON enforce-gtid-consistency=true systemctl restart mysqld ##重启

#现在server2上查看主从复制状态是否正常 [root@server2 mysql]# pwd /var/lib/mysql #[root@server2 mysql]# cat relay-log.info #查看relay-log

mysql> stop slave; ##先停止复制 Query OK, 0 rows affected (0.01 sec) mysql> CHANGE MASTER TO ##修改master信息 -> MASTER_HOST = '172.25.136.1', -> MASTER_USER = 'repl', -> MASTER_PASSWORD = 'Wsp+123ld', -> MASTER_AUTO_POSITION = 1; ##启用gtid,它是自动的 mysql> start slave; mysql> show slave status\G ##查看状态,可以看到下面两个参数是空的 Retrieved_Gtid_Set: Executed_Gtid_Set:

##在server1上插入数据 mysql> insert into usertb values ('user2','123'); Query OK, 1 row affected (0.01 sec) mysql> insert into usertb values ('user3','123'); Query OK, 1 row affected (0.00 sec)

#再在server2上查看状态 Retrieved_Gtid_Set: f84e8de1-38a2-11e9-b78c-5254009afece:1-2 Executed_Gtid_Set: f84e8de1-38a2-11e9-b78c-5254009afece:1-2 ##发现这两个参数变了,从1位置开始复制的

在server2上面查看复制过来的数据 use mysql select * from mysql.gtid_executed; 发现slave完成了master的所有事件

再查看gtid模式复制的起始和结束位置 mysql> use mysql mysql> select * from gtid_executed; +--------------------------------------+----------------+--------------+ | source_uuid | interval_start | interval_end | +--------------------------------------+----------------+--------------+ | f84e8de1-38a2-11e9-b78c-5254009afece | 1 | 1 | | f84e8de1-38a2-11e9-b78c-5254009afece | 2 | 2 | +--------------------------------------+----------------+--------------+ 2 rows in set (0.00 sec)

show databases; use westos; select * from usertb; 可以查看到刚才新写入的数据

小科普 引擎:

proxy: 关闭SQL进程 MYSQL--两大引擎---MylSAM&InnoDB 区别:(面试题) 对于数据库对于数据存储和管理某些特性 alter table TI engine=blackhole 黑洞引擎 最大特性--只进不出 在主库插入插入数据 关闭黑洞引擎的服务器上看不见数据 可以从它身上获取数据 只不过不可以显示出来
最新回复(0)