标签(linux): mysql

笔者Q:972581034 交流群:605799367。有任何疑问可与笔者或加群交流

xtrabackup是percona公司针对MySQL开发的一款开源的物理备份工具,直接拷贝物理文件,速度快,效率高,支持不锁表备份,支持全量、增量(基于LSN序号)、压缩及流备份等等,那今天要做的是,用它,来实现MySQL的主从复制。

先上原理图一张。。

主从复制原理要点

1、异步方式同步。
2、逻辑同步模式,多种模式,默认是通过SQL语句执行。
3、主库通过记录binlog实现对从库的同步
4、主库1个线程,从库2个线程来完成的。
5、从库关键文件master.info,relay-log,relay-info功能。
6、5.6以上的版本开启GTID功能可以自动记录binlog位置点

1.环境准备

[root@db01 ~]# hostname ;hostname -I
db01
10.0.0.51 172.16.1.51
[root@db02 ~]# hostname ;hostname -I
db02
10.0.0.52 172.16.1.52 
#两台服务器均安装以下软件包。
wget https://www.percona.com/downloads/XtraBackup/Percona-XtraBackup-2.4.7/binary/redhat/6/x86_64/percona-xtrabackup-24-2.4.7-1.el6.x86_64.rpm
yum -y localinstall percona-xtrabackup-24-2.4.7-1.el6.x86_64.rpm

这里db01为主库,db02为从库,从库里没有数据。现在要实现的是db01到db02的主从复制。server id不能相同,同时开启binlog功能


查看db01数据,因为是测试,现在数据库里仅有oldboy库,test表,内容如:

-- 创建测试环境
create database oldboy;
use oldboy
drop table test;
CREATE TABLE test (
   id int(4) NOT NULL AUTO_INCREMENT,
  name char(20) NOT NULL,
  PRIMARY KEY (id)
) ;
insert into test(id,name) values(1,'oldboy');
insert into test(name) values('oldgirl');
insert into test values(3,'inca');
insert into test values(4,'zuma'),(5,'kaka');
-- 查看
mysql> select * from oldboy.test;
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
+----+---------+
5 rows in set (0.00 sec)

2. 备份

先在db01上做一次全备

[root@db01 ~]# innobackupex --defaults-file="/etc/my.cnf" --user=root --socket=/application/mysql/tmp/mysql.sock --password=123456 /opt/
#现在数据已经备份到opt下面了
[root@db01 ~]# ll /opt/2017-05-05_11-23-50/
total 12316
-rw-r----- 1 root root      418 May  5 11:23 backup-my.cnf
-rw-r----- 1 root root 12582912 May  5 11:23 ibdata1
drwxr-x--- 2 root root     4096 May  5 11:23 mysql
drwxr-x--- 2 root root     4096 May  5 11:23 oldboy
drwxr-x--- 2 root root     4096 May  5 11:23 performance_schema
-rw-r----- 1 root root      113 May  5 11:23 xtrabackup_checkpoints
-rw-r----- 1 root root      499 May  5 11:23 xtrabackup_info
-rw-r----- 1 root root     2560 May  5 11:23 xtrabackup_logfile

#把备份好的数据复制到db02的opt目录下
[root@db01 ~]#  scp -r /opt/2017-05-05_11-23-50/ 10.0.0.52:/opt/

3.db01插入数据

在做完备份后,在生产环境中一般都会有数据继续写入数据库,所以这里再插入几条数据模拟环境。

use oldboy;
insert into test(id,name) values(6,'bing');
insert into test(id,name) values(7,'zhao');
insert into test(id,name) values(8,'ya');
insert into test(id,name) values(9,'ting');
mysql> select * from test;
+----+---------+
| id | name    |
+----+---------+
|  1 | oldboy  |
|  2 | oldgirl |
|  3 | inca    |
|  4 | zuma    |
|  5 | kaka    |
|  6 | bing    |
|  7 | zhao    |
|  8 | ya      |
|  9 | ting    |
+----+---------+

4.预处理

[root@db02 ~]# sed -i '16a datadir = /application/mysql/data' /application/mysql/my.cnf
[root@db02 opt]# innobackupex --defaults-file="/etc/my.cnf" --user=root --socket=/application/mysql/tmp/mysql.sock --password=123456 --apply-log --use-memory=200M /opt/2017-05-05_09-35-07/
#注:--use-memory参数可以设置适用内存进行处理,如果服务器内存够大,多给一点是没问题的,可以加快处理速度。

5.db02

#删除原有的数据文件,必须先清空原有数据文件,不然后报错
[root@db02 mysql]# mv /application/mysql/data /tmp/

#导入db01的数据文件
[root@db02 mysql]# innobackupex --defaults-file="/etc/my.cnf" --user=root --socket=/application/mysql/tmp/mysql.sock --move-back /opt/2017-05-05_11-23-50/

#可以看到刚才被删除的数据又恢复过来了
[root@db02 opt]# cd /application/mysql/data/
[root@db02 data]# ls
ibdata1  ib_logfile0  ib_logfile1  ibtmp1  mysql  oldboy  performance_schema  xtrabackup_binlog_pos_innodb  xtrabackup_info
[root@db02 data]# cat xtrabackup_binlog_pos_innodb 
mysql-bin.000002	1461
[root@db02 mysql]# chown -R mysql.mysql data
[root@db02 mysql]# /etc/init.d/mysqld start

6.创建主从同步授权用户

-- 在db01上
mysql> grant replication slave on *.* to rep@'10.0.0.%' identified by '123456';
Query OK, 0 rows affected (0.12 sec)
mysql> select user,host from mysql.user;
+-------+-----------+
| user  | host      |
+-------+-----------+
| rep   | 10.0.0.%  |
| root  | 127.0.0.1 |
|       | db01      |
| root  | db01      |
| root  | localhost |
+-------+-----------+
6 rows in set (0.00 sec)

7.做主从同步

-- db02
mysql> change master to master_host='10.0.0.51',master_user='rep',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=1461;
Query OK, 0 rows affected, 2 warnings (0.14 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
#检查
[root@db02 mysql]# mysql -uroot -poldboy123 -e "show slave status\G"|egrep -i "Yes|Behind_Master"
Warning: Using a password on the command line interface can be insecure.
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
        Seconds_Behind_Master: 0

8.测试

OK。到了这一步说明已经成功了,测试一下如图,从db01写入数据会同步到db02.如图

9.延时复制

mysql自带还有延时复制的功能,比如在一主4从的时候,可以将其中一台做延时复制,假如出现意外情况或误操作,延时复制的功能还有一丝恢复数据的机会。

mysql> change master to master_delay = 3600;    -- 等于你想要延迟的时间
Query OK, 0 rows affected (0.02 sec)
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
-- 表示从库延迟1小时后同步数据
mysql> show slave status\G
                    SQL_Delay: 3600
          SQL_Remaining_Delay: 3561