MySQL主从同步原理
MySQL主从同步是在MySQL主从复制(Master-Slave Replication)基础上实现的,通过设置在Master MySQL上的binlog(使其处于打开状态),Slave MySQL上通过一个I/O线程从Master MySQL上读取binlog,然后传输到Slave MySQL的中继日志中,然后Slave MySQL的SQL线程从中继日志中读取中继日志,然后应用到Slave MySQL的数据库中。这样实现了主从数据同步功能。
XtraBackup备份原理
innobackupex在后台线程不断追踪InnoDB的日志文件,然后复制InnoDB的数据文件。数据文件复制完成之后,日志的复制线程也会结束。这样就得到了不在同一时间点的数据副本和开始备份以后的事务日志。完成上面的步骤之后,就可以使用InnoDB崩溃恢复代码执行事务日志(redo log),以达到数据的一致性。

XtraBackup优势 :

  1. 无需停止数据库进行InnoDB热备
  2. 增量备份MySQL
  3. 流压缩到传输到其它服务器
  4. 能比较容易地创建主从同步
  5. 备份MySQL时不会增大服务器负载

备份分为两个过程:

  1. backup,备份阶段,追踪事务日志和复制数据文件(物理备份)。
  2. preparing,重放事务日志,使所有的数据处于同一个时间点,达到一致性状态

    为什么要做主从复制?
    我想这是要在实施以前要想清楚的问题。是为了实现读写分离,减轻主库负载或数据分析? 为了数据安全,做备份恢复?主从切换做高可用?
    大部分场景下,以上三个问号一主一从都能够解决,而且任何生产环境都建议你至少要有一个从库,假如你的读操作压力特别大,甚至要做一主多从,还可以不同的slave扮演不同的角色,例如使用不同的索引,或者不同的存储引擎,或使用一个小内存server做slave只用于备份。(当然slave太多也会对master的负载和网络带宽造成压力,此时可以考虑级联复制,即 A->B->C )
    mysql支持的复制类型:
      (1):基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。
    一旦发现没法精确复制时, 会自动选着基于行的复制。
      (2):基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
      (3):混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
    复制类型还可以分为 异步复制和半同步复制。
    通常没说明指的都是异步,即主库执行完Commit后,在主库写入Binlog日志后即可成功返回客户端,无需等等Binlog日志传送给从库,一旦主库宕机,有可能会丢失日志。而半同步复制,是等待其中一个从库也接收到Binlog事务并成功写入Relay Log之后,才返回Commit操作成功给客户端;如此半同步就保证了事务成功提交后至少有两份日志记录,一份在主库Binlog上,另一份在从库的Relay Log上,从而进一步保证数据完整性;半同步复制很大程度取决于主从网络RTT(往返时延),以插件 semisync_master/semisync_slave 形式存在。
    补充:

    • mysql 5.7开始加入了多源复制,这个特性对同时有很多个mysql实例是很有用的,阿里云RDS(迁移)实现了类似的方式。
    • 从MySQL 5.6.2开始,mysql binlog支持checksum校验,并且5.6.6默认启用(CRC32),这对自己模拟实现mysql复制的场景有影响。

MySQL复制技术有以下一些特点:
(1) 数据分布 (Data distribution )
(2) 负载平衡(load balancing)
(3) 备份(Backups)
(4) 高可用性和容错行 High availability and failover
如下开始进行XtraBackup备份操作
首先要进行说明的是:mysql主从数据同步,从mysql实时同步主mysql的数据。这里,一般要求主msyql与从mysql版本相同或主msyql不高于从mysql版本(版本查询>select version())。一般稳健的做法都是使其版本相同,因为不同mysql版本之间的binlog(二进制日志)格式可能不一样,有可能会导致同步异常。

主数据库 mysql> select version();
+------------+
| version()  |
+------------+
| 5.6.35-log |
+------------+
1 row in set (0.00 sec)
ip 地址:192.168.212.11 
从数据库:MariaDB [(none)]> select version();
+----------------+
| version()      |
+----------------+
| 10.2.6-MariaDB |
+----------------+
1 row in set (0.00 sec)
ip 地址:192.168.212.10 
第一步:
mysql> grant replication slave on *.* to 'ff'@'192.168.212.10' identified by 'chylinux';
Query OK, 0 rows affected (0.09 sec)
(在主数据库上进行给从数据库授权)
第二步:(如下是在主数据库上面的操作)
说明这里只使用全量备份(恢复)不使用增量备份(恢复)
[root@chy01 ~]# rpm -ivh http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
获取http://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
警告:/var/tmp/rpm-tmp.tIRhy2: 头V4 DSA/SHA1 Signature, 密钥 ID cd2efd2a: NOKEY
准备中... ################################# [100%]
正在升级/安装...
1:percona-release-0.1-3 ################################# [100%]
(首先rpm安装yum的扩展源)
[root@chy01 ~]# yum list | grep percona
[root@chy01 ~]# yum install percona-xtrabackup
(安装备份工具的包)
mysql> GRANT RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'chy'@localhost identified by 'aminglinux';
Query OK, 0 rows affected (0.00 sec)
(在主数据库中创建一个用户并授权)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
(刷新mysql)
[root@chy01 ~]# mkdir /data/backup
(创建backup目录,里面存放mysql备份的数据库)
[root@chy01 ~]# ls -l /data/backup/
总用量 4
drwx------ 9 root root 4096 9月   2 18:08 2017-09-02_18-08-29
(如上是备份的数据库)
[root@chy01 backup]# tar -zcvf 2017-09-02_18-08-29.tar.gz 2017-09-02_18-08-29
[root@chy01 backup]# du -sh 2017-09-02_18-08-29.tar.gz
540K    2017-09-02_18-08-29.tar.gz
[root@chy01 backup]# rsync -avP /data/backup/2017-09-02_18-08-29.tar.gz 192.168.212.10:/data/backup/
[email protected]'s password:
sending incremental file list
2017-09-02_18-08-29.tar.gz
      551406 100%   40.40MB/s    0:00:00 (xfer#1, to-check=0/1)
sent 3090 bytes  received 4531 bytes  1172.46 bytes/sec
total size is 551406  speedup is 72.35
(用rsync进行同步)
第三步(拷贝备份主数据库的数据+恢复数据库)
[root@chy ~]# mkdir /data/backup
(从数据库上也需要创建一个目录)
[root@chy ~]# ls /data/backup/
2017-09-02_18-08-29.tar.gz
(可以看到已经同步成功)
[root@chy ~]# du -sh /data/backup/2017-09-02_18-08-29.tar.gz
540K    /data/backup/2017-09-02_18-08-29.tar.gz
(大小一致)
[root@chy backup]# tar -xzvf /data/backup/2017-09-02_18-08-29.tar.gz
(解压缩)
[root@chy backup]# innobackupex --use-memory=512M --apply-log 2017-09-02_18-08-29
(进行初始化)
[root@chy ~]# /etc/init.d/mariadb stop
Stopping mariadb (via systemctl):                          [  确定  ]
(关闭数据库,之后进行恢复操作)
[root@chy backup]# rm -rf /data/mariadb/
[root@chy backup]# mkdir /data/mariadb
[root@chy backup]# chown mysql1:mysql1 /data/mariadb
[root@chy backup]# innobackupex --defaults-file=/etc/my.cnf --datadir=/data/mariadb/  --use-memory=512M  --copy-back 2017-09-02_18-08-29
(在这里的时候我其实是报了一个错误,innobackupex version 2.3.9 based on MySQL server 5.6.24 Linux (x86_64) (revision id: fde0e3e)
Error: datadir must be specified.
(这里的错误是必须要指定新的datadir的目录,指定后就可以恢复成功)
[root@chy backup]# ls /data/mariadb/
db1      ib_logfile0  mysql   performance_schema  xtrabackup_binlog_pos_innodb  zhucong
ibdata1  ib_logfile1  mysql2  test                xtrabackup_info               zrlog
(查看已经恢复数据库)
[root@chy backup]# /etc/init.d/mariadb start
Starting mariadb (via systemctl):  Warning: mariadb.service changed on disk. Run 'systemctl daemon-reload' to reload units.
                                                           [  确定  ]
[root@chy backup]# systemctl daemon-reload
[root@chy backup]# /etc/init.d/mariadb start
Starting mariadb (via systemctl):                          [  确定  ]