Mysql和Gtid的主从复制

实验环境:Server3:master

                  Server4:slave

一、mysql主从复制

Mysql中有一种日志叫做bin日志(二进制日志)。这个日志会记录下所有修改了数据库的SQL语句(insert,update,delete,ALTER TABLE,grant等等)。
主从复制的原理其实就是把主服务器上的BIN日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。

复制流程图:

这里写图片描述

复制过程:

  1. 主节点必须启用二进制日志,记录任何修改数据库数据的事件。
  2. 从节点开启一个线程(I/O Thread)把自己扮演成mysql的客户端,通过mysql协议,请求主节点的二进制日志文件中的事件
  3. 主节点启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则主节点就会从第一个日志文件中的第一个事件一个一个发送给从节点。
  4. 从节点接收到主节点发送过来的数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具哪个二进制日志文件的哪个位置。
  5. 从节点启动另外一个线程(sql Thread ),把replaylog中的事件读取出来,并在本地再执行一次。

复制中线程的作用:

从节点:

  • I/O Thread:从Master请求二进制日志事件,并保存于中继日志中。
  • Sql Thread:从中继日志中读取日志事件,在本地完成重放。

主节点:

  • Dump Thread:为每个Slave的I/O Thread启动一个dump线程,用于向从节点发送二进制事件。

思考:从节点需要建立二进制日志文件吗?
看情况,如果从节点需要作为其他节点的主节点时,是需要开启二进制日志文件的。这种情况叫做级联复制。如果只是作为从节点,则不需要创建二进制文件。

Mysql复制特点:

  1. 异步复制:主节点中一个用户请求一个写操作时,主接点不需要把写的数据在本地操作完成同时发送给从服务器并等待从服务器反馈写入完成,在响应用 户,主机点只需要把写入操作在本地完成,就响应用户。但是,从节点中的数据有可能会落后主服务,可以使用(很多软件来检查是否落后)
  2. 主从数据不一致。

主从复制配置过程:

主节点:

  1. 启用二进制日志。
  2. 为当前节点设置一个全局唯一的server_id。
  3. 创建有复制权限的用户账号 REPLIACTION SLAVE ,REPLIATION CLIENT。

从节点:

  1. 启动中继日志。
  2. 为当前节点设置一个全局唯一的server_id。
  3. 使用有复制权限的用户账号连接至主节点,并启动复制线程。
[root@server3 ~]# ls

mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar

mysql-community-client-5.7.17-1.el6.x86_64.rpm

mysql-community-common-5.7.17-1.el6.x86_64.rpm

mysql-community-devel-5.7.17-1.el6.x86_64.rpm

mysql-community-embedded-5.7.17-1.el6.x86_64.rpm

mysql-community-embedded-devel-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

mysql-community-test-5.7.17-1.el6.x86_64.rpm

[root@server3 ~]# yum install 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 -y 

[root@server3 ~]# scp 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  [email protected]:/root

[root@server3 ~]# vim /etc/my.cnf

Mysql和Gtid的主从复制_第1张图片
 

[root@server3 ~]# /etc/init.d/mysqld  start

Initializing MySQL database:                               [  OK  ]

Installing validate password plugin:                       [  OK  ]

Starting mysqld:                                           [  OK  ]

[root@server3 ~]# grep password  /var/log/mysqld.log

2018-08-08T01:33:54.815320Z 1 [Note] A temporary password is generated for root@localhost: 8-Hq;jp>MCME

[root@server3 ~]# mysql_secure_installation

Securing the MySQL server deployment.

Enter password for user root: 

Error: Access denied for user 'root'@'localhost' (using password: YES)

[root@server3 ~]# 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: XDwestos+007

Re-enter new password: 

The 'validate_password' plugin is installed on the server.

The subsequent steps will run with the existing configuration

of the plugin.

Using existing password for root.

Estimated strength of the password: 100 

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

 ... skipping.

By default, a MySQL installation has an anonymous user,

allowing anyone to log into MySQL without having to have

a user account created for them. This is intended only for

testing, and to make the installation go a bit smoother.

You should remove them before moving into a production

environment.

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

Success.

Normally, root should only be allowed to connect from

'localhost'. This ensures that someone cannot guess at

the root password from the network.

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

Success.

By default, MySQL comes with a database named 'test' that

anyone can access. This is also intended only for testing,

and should be removed before moving into a production

environment.

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : 

 ... skipping.

Reloading the privilege tables will ensure that all changes

made so far will take effect immediately.

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

Success.

All done! 

[root@server3 ~]# mysql -p

Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 9

Server version: 5.7.17-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;

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

| Database           |

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

| information_schema |

| mysql              |

| performance_schema |

| sys                |

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

4 rows in set (0.00 sec)

mysql> grant replication slave on *.* to repl@'172.25.26.%' identified by 'XDwestos+007';

Query OK, 0 rows affected, 1 warning (0.08 sec)

mysql> show databases;

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

| Database           |

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

| information_schema |

| mysql              |

| performance_schema |

| sys                |

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

4 rows in set (0.00 sec)

mysql> show master status;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

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

| mysql-bin.000004 |      447 |              |                  |                   |

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

1 row in set (0.00 sec)

Server4:

[root@server4 ~]# vim /etc/my.cnf

Mysql和Gtid的主从复制_第2张图片
 

[root@server4 ~]# /etc/init.d/mysqld  start

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

[root@server4 ~]# grep password  /var/log/mysqld.log 

2018-08-08T01:45:23.555632Z 1 [Note] A temporary password is generated for root@localhost: CUJQ3CH*m&g+

[root@server4 ~]# 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: XDwestos+007

Re-enter new password: 

The 'validate_password' plugin is installed on the server.

The subsequent steps will run with the existing configuration

of the plugin.

Using existing password for root.

Estimated strength of the password: 100 

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

 ... skipping.

By default, a MySQL installation has an anonymous user,

allowing anyone to log into MySQL without having to have

a user account created for them. This is intended only for

testing, and to make the installation go a bit smoother.

You should remove them before moving into a production

environment.

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

Success.

Normally, root should only be allowed to connect from

'localhost'. This ensures that someone cannot guess at

the root password from the network.

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

Success.

By default, MySQL comes with a database named 'test' that

anyone can access. This is also intended only for testing,

and should be removed before moving into a production

environment.

Remove test database and access to it? (Press y|Y for Yes, any other key for No) : 

 ... skipping.

Reloading the privilege tables will ensure that all changes

made so far will take effect immediately.

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

Success.

All done! 

[root@server4 ~]# mysql -p

Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 7

Server version: 5.7.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show databases;

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

| Database           |

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

| information_schema |

| mysql              |

| performance_schema |

| sys                |

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

4 rows in set (0.00 sec)

mysql> change master to master_host='172.25.26.4', master_user='repl', master_password='XDwestos+007', master_log_file='mysql-bin.000004', master_log_pos=447;

Query OK, 0 rows affected, 2 warnings (0.49 sec)

mysql> start slave;

Query OK, 0 rows affected (0.03 sec)

mysql> show slave status\G;

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.25.26.4

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000004

          Read_Master_Log_Pos: 447

               Relay_Log_File: server4-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: 

          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: 447

              Relay_Log_Space: 529

              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: 1cbf9ff3-9aab-11e8-9613-5254006cc83b

             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: 0

         Replicate_Rewrite_DB: 

                 Channel_Name: 

           Master_TLS_Version: 

1 row in set (0.00 sec)

ERROR: 

No query specified

Server3:

mysql> create database  test;

Query OK, 1 row affected (0.17 sec)

mysql> show databases;

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

| Database           |

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

| information_schema |

| mysql              |

| performance_schema |

| sys                |

| test               |

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

5 rows in set (0.00 sec)

mysql> use test

Database changed

mysql> create table userlist(

    -> username varchar(15) not null,

    -> password varchar(15) not null);

Query OK, 0 rows affected (0.71 sec)

mysql> desc userlist

    -> ;

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

| Field    | Type        | Null | Key | Default | Extra |

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

| username | varchar(15) | NO   |     | NULL    |       |

| password | varchar(15) | NO   |     | NULL    |       |

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

2 rows in set (0.01 sec)

mysql> insert into userlist values ('user1','123');

Query OK, 1 row affected (0.21 sec)

mysql> insert into userlist values ('user2','456');

Query OK, 1 row affected (0.14 sec)

mysql> insert into userlist values ('user3','789');

Query OK, 1 row affected (0.15 sec)

Server4:

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      |

| user3    | 789      |

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

3 rows in set (0.00 sec)

二、gtid主从复制

基于GTID的复制是从Mysql5.6开始支持 的一种新的复制方式,此方式与传统基于日志的方式存在很大的差异,在原来的基于日志的复制中,从服务器连接到主服务器并告诉主服务器要从哪个二进制日志的 偏移量开始执行增量同步,这时我们如果指定的日志偏移量不对,这与可能造成主从数据的不一致,而基于GTID的复制会避免。
在 基于GTID的复制中,首先从服务器会告诉主服务器已经在从服务器执行完了哪些事务的GTID值,然后主库会有把所有没有在从库上执行的事务,发送到从库 上进行执行,并且使用GTID的复制可以保证同一个事务只在指定的从库上执行一次,这样可以避免由于偏移量的问题造成数据不一致。
什么是GTID,也就是全局事务ID,其保证为每一个在主上提交的事务在复制集群中可以生成一个唯一的ID。
一 个GITD由两部分组成的,分别是source_id 和transaction_id,GTID=source_id:transaction_id,其中source_id就是执行事务的主库的 server-uuid值,server-uuid值是在mysql服务首次启动生成的,保存在数据库的数据目录中,在数据目录中有一个 auto.conf文件,这个文件保存了server-uuid值(唯一的)。而事务ID则是从1开始自增的序列,表示这个事务是在主库上执行的第几个事 务,Mysql会保证这个事务和GTID是一比一的关系。

配置主数据库服务器需要做的大概和传统的主从配置差不多,需要起码的在主服务器上建立复制账号,还要配置数据库日志文件的目录,这是必须的启动bin_log日志。
可 以指定bin_log存放目录,而不是用数据目录,分开存储是个好习惯,特别是如果把日志和数据放在不同的磁盘分区上,这样不但可以避免日志的增长把数据 磁盘分区占满,也可以提高了磁盘IO。如bin_log = /usr/local/mysql/log/mysql-bin。

优点
   A:很方便的进行故障转移,因为GTID是全局唯一的标识符,所以就很简单知道哪些事务在从服务器没有执行,在多个从服务器也没必要进行多个日志偏移量配置了.

   B:从库和主库的数据一致性。

缺点
  A:故障处理比日志处理复杂。
  B:执行语句的一些限制。

Server3:

[root@server3 ~]# vim /etc/my.cnf

Mysql和Gtid的主从复制_第3张图片

[root@server3 ~]# /etc/init.d/mysqld  restart

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

Server4:

[root@server4 ~]# vim /etc/my.cnf

Mysql和Gtid的主从复制_第4张图片

[root@server4 ~]# /etc/init.d/mysqld  restart

Stopping mysqld:                                           [  OK  ]

Starting mysqld:                                           [  OK  ]

Server3:

[root@server3 ~]# mysql -p

Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 5

Server version: 5.7.17-log MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show master status;

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

| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

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

| mysql-bin.000005 |      154 |              |                  |                   |

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

1 row in set (0.00 sec)

Server4:

[root@server4 ~]# mysql -p

Enter password: 

Welcome to the MySQL monitor.  Commands end with ; or \g.

Your MySQL connection id is 6

Server version: 5.7.17 MySQL Community Server (GPL)

Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its

affiliates. Other names may be trademarks of their respective

owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show slave status\G;

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.25.26.4

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000005

          Read_Master_Log_Pos: 154

               Relay_Log_File: server4-relay-bin.000005

                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: 742

              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: 1cbf9ff3-9aab-11e8-9613-5254006cc83b

             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: 0

         Replicate_Rewrite_DB: 

                 Channel_Name: 

           Master_TLS_Version: 

1 row in set (0.00 sec)

ERROR: 

No query specified

mysql> stop slave;

Query OK, 0 rows affected (0.06 sec)

mysql> change master to master_host='172.25.26.4', master_user='repl', master_password='XDwestos+007', MASTER_AUTO_POSITION=1;

Query OK, 0 rows affected, 2 warnings (0.21 sec)

mysql> start slave;

Query OK, 0 rows affected (0.04 sec)

mysql> show slave status\G;

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 172.25.26.4

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000005

          Read_Master_Log_Pos: 154

               Relay_Log_File: server4-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: 1cbf9ff3-9aab-11e8-9613-5254006cc83b

             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)

ERROR: 

No query specified

Server3:

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.08 sec)

Server4:

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的主从复制)