mysql主从复制&&基于GTID主从复制

在一主多从的数据库体系中,多个从服务器采用异步的方式更新主数据库的变化,业务服务器在执行写或者相关修改数据库的操作是在主服务器上进行的,读操作则是在各从服务器上进行。如果配置了多个从服务器或者多个主服务器又涉及到相应的负载均衡问题,关于负载均衡具体的技术细节还没有研究过,今天就先简单的实现一主一从的主从复制功能。

Mysql主从复制的实现原理图大致如下(来源网络):

mysql主从复制&&基于GTID主从复制_第1张图片
MySQL之间数据复制的基础是二进制日志文件(binary log file)。一台MySQL数据库一旦启用二进制日志后,其作为master,它的数据库中所有操作都会以“事件”的方式记录在二进制日志中,其他数据库作为slave通过一个I/O线程与主服务器保持通信,并监控master的二进制日志文件的变化,如果发现master二进制日志文件发生变化,则会把变化复制到自己的中继日志中,然后slave的一个SQL线程会把相关的“事件”执行到自己的数据库中,以此实现从数据库和主数据库的一致性,也就实现了主从复制。

实现MySQL主从复制需要进行的配置:

主服务器:
    开启二进制日志
    配置唯一的server-id
    获得master二进制日志文件名及位置
    创建一个用于slave和master通信的用户账号
从服务器:
    配置唯一的server-id
    使用master分配的用户账号读取master二进制日志
    启用slave服务

具体实现过程如下:

一、准备工作:

1.主从数据库版本最好一致

2.主从数据库内数据保持一致

master-slave配置相同如下
server5,server6

[root@server5 ~]# ls
anaconda-ks.cfg
install.log
install.log.syslog
mysql-community-client-5.7.17-1.el6.x86_64.rpm
mysql-community-common-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-5.7.17-1.el6.x86_64.rpm
mysql-community-libs-compat-5.7.17-1.el6.x86_64.rpm
mysql-community-server-5.7.17-1.el6.x86_64.rpm


yum install -y *

更改配置文件/etc/my.cnf
[root@server5 ~]# tail -n 4 /etc/my.cnf


server-id=1              #设置server-id
log-bin=mysql-bin       #开启二进制日志


[root@server6 ~]# tail -n 2 /etc/my.cnf

server-id=2
都打开数据库
[root@server5 ~]# /etc/init.d/mysqld start



查看密码及初始化库 56都做
[root@server5 ~]# grep password /var/log/mysqld.log 
2018-08-08T08:41:24.512262Z 1 [Note] A temporary password is generated for root@localhost: dgz=joaSg6T.
[root@server5 ~]# 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: 


Estimated strength of the password: 100 
Change the password for root ? ((Press y|Y for Yes, any other key for No) : 


Remove anonymous users? (Press y|Y for Yes, any other key for No) : y
Success.


Disallow root login remotely? (Press y|Y for Yes, any other key for No) : y
Success.


Reload privilege tables now? (Press y|Y for Yes, any other key for No) : y
Success.

All done! 

Server5给 用户名和可链接网段及授权密码(创建用户并授权)
[root@server5 ~]# mysql -p
mysql> grant replication slave on *.* to repl@'172.25.53.%' identified by 'YaoJing...123@';

这里写图片描述

Server6(从库)尝试链接

mysql主从复制&&基于GTID主从复制_第2张图片

从库链接主库(在自己的数据库里面,不是上图链接图)
打开mysql会话,执行同步SQL语句(需要主服务器主机名,登陆凭据,二进制文件的名称和位置)

mysql> change master to master_host='172.25.53.5',master_user='repl',master_password='YaoJing...123@',master_log_file='mysql-bin.000004',master_log_pos=843;
Query OK, 0 rows affected, 2 warnings (0.34 sec)
启动slave同步进程
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
查看slave状态
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.25.53.5
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 843
               Relay_Log_File: server6-relay-bin.000002
                Relay_Log_Pos: 320
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:

mysql主从复制&&基于GTID主从复制_第3张图片
出现
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
两个yes即代表链接成功,否则需要根据错误描述进入日志查看并解决错误
还有,master_log_file=’mysql-bin.000004’,master_log_pos=843;
参数不固定,是根据主库参数写的,如:

查看master状态,记录二进制文件名(mysql-bin.000004)和位置(843):

Server5
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000004 |      843 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

当Slave_IO_Running和Slave_SQL_Running都为YES的时候就表示主从同步设置成功了。接下来就可以进行一些验证了,比如在主master数据库的test数据库的一张表中插入一条数据,在slave的test库的相同数据表中查看是否有新增的数据即可验证主从复制功能是否有效,还可以关闭slave(mysql>stop slave;),然后再修改master,看slave是否也相应修改(停止slave后,master的修改不会同步到slave),就可以完成主从复制功能的验证了

mysql主从复制&&基于GTID主从复制_第4张图片
下面由于是第二天做的,所以将server5,6改为了server1,2,
,在主库添加库及及表
mysql主从复制&&基于GTID主从复制_第5张图片
mysql主从复制&&基于GTID主从复制_第6张图片
从库可以同步到主库的
mysql主从复制&&基于GTID主从复制_第7张图片

基于GTID的主从复制

    优点
        因为不用手工设置日志偏移量, 可以很方便地进行故障转移
        如果启用log_slave_updates那么从库不会丢失主库上的任何修改
    缺点
        对执行的SQL有一定限制
        仅支持MySQL 5.6之后的版本, 而且不建议使用早期5.6版本
在两边的配置文件都加上
gtid_mode=ON
enforce-gtid-consistency=true


并重启数据库
Server2
mysql> stop slave;
mysql> change master to master_host='172.25.53.1',master_user='repl',master_password='YaoJing...123@', MASTER_AUTO_POSITION = 1;
Query OK, 0 rows affected, 2 warnings (0.24 sec)

mysql> start slave;
Query OK, 0 rows affected (0.09 sec)

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 172.25.53.1
                  Master_User: repl
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000005
          Read_Master_Log_Pos: 154
               Relay_Log_File: server2-relay-bin.000002
                Relay_Log_Pos: 367
        Relay_Master_Log_File: mysql-bin.000005
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 154
              Relay_Log_Space: 576
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 1
                  Master_UUID: 986d2872-9a54-11e8-b50d-5254002b8c1c
             Master_Info_File: /var/lib/mysql/master.info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Slave has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 1
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
1 row in set (0.00 sec)
Server1删掉一个用户
mysql> use test
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> show tables;
+----------------+
| Tables_in_test |
+----------------+
| userlist       |
+----------------+
1 row in set (0.00 sec)

mysql> delete from userlist where username='user3';
Query OK, 1 row affected (0.16 sec)

mysql> ^DBye
Server2可以看到
mysql> use test
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 |
+----------+----------+
| user1    | 123      |
| user2    | 456      |
+----------+----------+
2 rows in set (0.00 sec)

mysql主从复制&&基于GTID主从复制_第8张图片
mysql主从复制&&基于GTID主从复制_第9张图片
mysql主从复制&&基于GTID主从复制_第10张图片

基于GTID的半同步复制

Server1、server2:
mysql> show variables like ‘have_dynamic_loading’;
确保为yes

mysql主从复制&&基于GTID主从复制_第11张图片

Server1
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
Query OK, 0 rows affected (0.10 sec)

mysql> set global rpl_semi_sync_master_enabled=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';
+-------------------------------------------+------------+
| Variable_name                             | Value      |
+-------------------------------------------+------------+
| rpl_semi_sync_master_enabled              | ON         |
| rpl_semi_sync_master_timeout              | 10000      |
| rpl_semi_sync_master_trace_level          | 32         |
| rpl_semi_sync_master_wait_for_slave_count | 1          |
| rpl_semi_sync_master_wait_no_slave        | ON         |
| rpl_semi_sync_master_wait_point           | AFTER_SYNC |
+-------------------------------------------+------------+
6 rows in set (0.01 sec)
Server2

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
Query OK, 0 rows affected (0.14 sec)

mysql> set global rpl_semi_sync_slave_enabled=ON;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like '%semi%';
+---------------------------------+-------+
| Variable_name                   | Value |
+---------------------------------+-------+
| rpl_semi_sync_slave_enabled     | ON    |
| rpl_semi_sync_slave_trace_level | 32    |
+---------------------------------+-------+
2 rows in set (0.01 sec)

测试


Server1
mysql> show status like '%rpl_semi_sync%';

mysql主从复制&&基于GTID主从复制_第12张图片

然后在server2上关闭io_thread
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.01 sec)
接着在server1上执行数据库操作,这里是对test库的表进行插入操作
此时插入数据会有一个10s的timeout,会有卡顿,查看参数,发现有些数值发生了变化

mysql主从复制&&基于GTID主从复制_第13张图片
Server2打开io
数据同步了
mysql主从复制&&基于GTID主从复制_第14张图片

Server2再次关闭,再试一次
mysql> stop slave io_thread;
Query OK, 0 rows affected (0.09 sec)

Server1
mysql主从复制&&基于GTID主从复制_第15张图片
mysql主从复制&&基于GTID主从复制_第16张图片

你可能感兴趣的:(mysql主从复制&&基于GTID主从复制)