mysql的主从配置又叫replication,AB复制,基于binlog二进制日志,主数据库必须开启binlog二进制日志才能进行复制。
主从复制大致有3个步骤:
1,主数据库将更改操作记录到binlog二进制日志(主数据库有log dump线程和从数据库的I/O线程传递binlog)。
2.从数据库含有两个线程,I/O线程将主数据库的binlog同步到本机并记录在relaylog日志
3.sql线程将relaylog日志记录进行操作落地
作为异步复制,其主库将事件写入binlog二进制文件,dump线程将binlog文件发送出去,不保证其他从节点是否会收到binlog二进制文件。
mysql数据库主从复制
###主数据库和从数据库同样的操作###
[root@server5 ~]# mkdir /usr/local/mysql
[root@server5 ~]# cd /usr/local/mysql/
[root@server5 mysql]# tar xf mysql-5.7.17-1.el6.x86_64.rpm-bundle.tar
[root@server5 mysql]# 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@server2 mysql]# yum install -y 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
[root@server5 mysql]# /etc/init.d/mysqld start
Initializing MySQL database: [ OK ]
Installing validate password plugin: [ OK ]
Starting mysqld: [ OK ]
###系统启动时会自动安装data数据目录以及系统安全初始化###
[root@server5 mysql]# cat /var/log/mysqld.log | grep password 查询初始密码
###安全初始化###
[root@server5 mysql]# /usr/bin/mysql_secure_installation
Securing the MySQL server deployment.
............
###编辑配置文件开启主从复制###
[root@server5 ~]# vim /etc/my.cnf
12 server-id=1 ##服务器id
13 log_bin=mysql-bin ###开启二进制日志
####底下两个参数可以加也可以不添加###
binlog-do-db=test ###表示从数据库只能同步主数据库的test数据,不能同步其他数据库
binlog-ignore-db=mysql ###表示忽略某个数据库
(在实验时我添加以上两个参数,后面同步从库同步主库数据时出现了问题,下面已经解决)
[root@server5 ~]# /etc/init.d/mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
从数据库配置文件
[root@server4 ~]# vi /etc/my.cnf
server-id=2
[root@server4 ~]# /etc/init.d/mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
主数据库授权
[root@server5 ~]# mysql -u root -p
###授权用户可以不用创建,直接授权###
mysql> GRANT replication slave on *.* to 'server3'@'172.25.60.4';
Query OK, 0 rows affected (0.13 sec)
replication ###表示授权复制的权限
slave ###表示从数据库
*.* ###表示所有数据库可以进行同步
server3 ###表示授权名,可以随意填写,也可以不添加引号
'172.25.60.%' ###表示授权172.25.60.0/24的网段所有服务器可以同步,%表示任意,我这里仅仅授权172.25.60.4一台服务器可以进行同步
mysql> flush privileges;
Query OK, 0 rows affected (0.17 sec)
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 773 | test | mysql | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
从数据库开始同步主数据库
[root@server4 ~]# mysql -u root -p
mysql> change master to master_host='172.25.60.5',master_user='server5',master_password='WEStos@123',master_log_file='mysql-bin.000001',master_log_pos=773;
Query OK, 0 rows affected, 2 warnings (2.53 sec)
mysql> start slave;
Query OK, 0 rows affected (0.09 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 172.25.60.5
Master_User: server5
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 773
Relay_Log_File: server4-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
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: 773
Relay_Log_Space: 154
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: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1045
Last_IO_Error: error connecting to master 'server5@172.25.60.5:3306' - retry-time: 60 retries: 1
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
Master_UUID:
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: 180703 23:04:51
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:
只有这两个数据值为yes时,表示同步成功;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
如果上面的不为yes时,表示同步错误,原因有以下三点:
1,网络的延迟
有时可能因为pos端口号问题不能同步,两边重启数据库,进入主库查看master的状态以及file文件和pos端口后,再进入从数据库同步,开启slave,查看是否同步。
测试:主数据创建新的database,查看从库是否同步
##实验时从库不能进行同步,因为配置文件设置能进行同步的是test数据库,而不是其他数据库,最后在同步的情况下,建立test数据库,而后从库机进行同步####
mysql> create database test;
Query OK, 1 row affected (0.24 sec)
mysql> use test;
Database changed
mysql> create table westos;
ERROR 1113 (42000): A table must have at least 1 column
mysql> create table westos(
-> user varchar(10),
-> password varchar(50)
-> );
Query OK, 0 rows affected (1.41 sec)
mysql> insert into westos values('hello','westos123');
Query OK, 1 row affected (0.45 sec)
mysql> select * from linux;
ERROR 1146 (42S02): Table 'test.linux' doesn't exist
mysql> select * from westos;
+-------+-----------+
| user | password |
+-------+-----------+
| hello | westos123 |
+-------+-----------+
1 row in set (0.00 sec)
###从库查看###
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
| test |
+--------------------+
5 rows in set (0.00 sec)
mysql数据库从5.6.5开始新增一种基于GDIT的复制方式。通过GDIT保证每个主库上提交的事务在集群中有一个唯一的ID.这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
GTID (Global Transaction ID) 是对于一个已提交事务的编号,并且是一个全局唯一的编号。 GTID 实际上 是由 UUID+TID 组成的。其中 UUID 是一个 MySQL 实例的唯一标识。TID 代表了该实例上已经提交的事务数量,并且随着事务提交单调递增。
半同步复制介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制牺牲了一定的性能,提高了数据的安全性。
基于GTID的主从数据库复制
在主从复制的配置文件进行修改:停止从数据库以及stop slave!
主数据库的操作:
[root@server5 ~]# vim /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
[root@server5 ~]# /etc/init.d/mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
从数据库的操作
[root@server4 ~]# vi /etc/my.cnf
gtid_mode=ON
enforce-gtid-consistency=true
[root@server4 ~]# /etc/init.d/mysqld restart
Stopping mysqld: [ OK ]
Starting mysqld: [ OK ]
进入从数据库开始同步主数据
mysql> change master to master_host='172.25.60.5',master_user='server5',master_password='WEStos@123',MASTER_AUTO_POSITION=1;
mysql> start slave;
Query OK, 0 rows affected (0.09 sec)
mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Connecting to master
Master_Host: 172.25.60.5
Master_User: server5
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 773
Relay_Log_File: server4-relay-bin.000001
Relay_Log_Pos: 4
Relay_Master_Log_File: mysql-bin.000001
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: 773
Relay_Log_Space: 154
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: NULL
Master_SSL_Verify_Server_Cert: No
Last_IO_Errno: 1045
Last_IO_Error: error connecting to master '[email protected]:3306' - retry-time: 60 retries: 1
Last_SQL_Errno: 0
Last_SQL_Error:
Replicate_Ignore_Server_Ids:
Master_Server_Id: 0
Master_UUID:
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: 180703 23:04:51
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:
只有以上两个参数为yes时,表示基于gtid的同步成功!
mysql数据库基于GTID的半同步复制
半同步复制要求执行的每一个事务,都要求至少有一个备库成功接收后,才返回给用户。
主数据库操作:
加载插件:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
查看插件是否加载成功!
mysql> show plugins;
| rpl_semi_sync_master | ACTIVE | REPLICATION | semisync_master.so | GPL
启动半同步复制:
mysql> set global rpl_semi_sync_master_enabled = 1;
###查看半同步是否在运行!###
mysql> show status like 'rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
1 row in set (0.00 sec)
从数据库的操作:
加载插件:
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
查看插件是否加载成功!
mysql> show plugins;
启动半同步复制:
mysql> set global rpl_semi_sync_slave_enabled = 1;
mysql> stop slave IO_THREAD;
Query OK, 0 rows affected (0.54 sec)
mysql> start slave IO_THREAD;
Query OK, 0 rows affected (0.00 sec)
查看半同步是否在运行!
mysql> show status like 'rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
1 row in set (0.00 sec)
两边都表示为ON时表示半同步复制已经运行!
当半同步复制发生超时时(由rpl_semi_sync_master_timeout参数控制,时间为10s)会暂时关闭半同步复制,转而使用异步复制。当master dump线程发送完成所有数据,在10s内受到从库的响应,则主从有从新恢复为半同步复制!
测试分为三步测试:
1,主数据库添加新的数据库,从库查看是否很快同步
2,验证超时,关闭从数据库的slave,主数据库添加数据是否会在10s以后创建数据库成功
3,开启从数据库的slave,主数据库添加新的数据库,从库查看是否很快同步
测试一:
mysql> create database linux;
Query OK, 1 row affected (0.12 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| linux |
| mysql |
| performance_schema |
| sys |
| westos |
+--------------------+
6 rows in set (0.00 sec)
从库查看:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| linux |
| mysql |
| performance_schema |
| sys |
| westos |
+--------------------+
6 rows in set (0.09 sec
测试二:
从库停止slave;
mysql> stop slave;
Query OK, 0 rows affected (0.42 sec)
主库添加数据库redhot时,光标停止10.16s返回结果;
mysql> create database redhot;
Query OK, 1 row affected (10.16 sec)
主库半同步复制关闭
mysql> show status like 'rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | OFF |
+-----------------------------+-------+
1 row in set (0.01 sec)
从库半同步复制关闭
mysql> show status like 'rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | OFF |
+----------------------------+-------+
1 row in set (0.00 sec)
测试三:
从库开启slave
mysql> start slave;
Query OK, 0 rows affected (0.11 sec)
主库创建数据库westos1,从库很快同步
mysql> create database westos1;
Query OK, 1 row affected (0.14 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hello |
| linux |
| mysql |
| performance_schema |
| redhot |
| sys |
| westos |
| westos1 |
+--------------------+
9 rows in set (0.00 sec)
mysql> show status like 'rpl_semi_sync_master_status';
+-----------------------------+-------+
| Variable_name | Value |
+-----------------------------+-------+
| Rpl_semi_sync_master_status | ON |
+-----------------------------+-------+
1 row in set (0.00 sec)
从库同步
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| hello |
| linux |
| mysql |
| performance_schema |
| redhat |
| redhot |
| sys |
| westos |
| westos1 |
+--------------------+
10 rows in set (0.00 sec)
mysql> show status like 'rpl_semi_sync_slave_status';
+----------------------------+-------+
| Variable_name | Value |
+----------------------------+-------+
| Rpl_semi_sync_slave_status | ON |
+----------------------------+-------+
全同步复制:指当主库执行完一个事务,所有的从库都执行了该事务才返回给客户端。因为需要等待所有从库执行完该事务才能返回,所以全同步复制的性能必然会收到严重的影响。