首先我们来了解一下数据库常遇到的问题:
第一就是性能上的问题
1、向上拓展(硬件方面) scale up 个体本身 容易达到极限
2、向外拓展 scale out
第二就是可用性的问题
1、数据库服务中断
2、误操作数据损坏
3、硬件故障
4、数据库升级测试遭遇bug
5、黑客攻击
基于以上这些问题就有了一个比较好的解决方案,那就是实现数据库的主从复制。MySQL主从复制技术可以提高服务器的性能。除此之外MySQL复制还可以解决以下几个问题:
1、数据分布 (Data distribution )
2、负载平衡(load balancing)
3、备份(Backups)
4、高可用性和容错性 High availability and failover
在开始实验前我们先来了解几个概念:异步复制、全同步复制和异步复制。
异步复制
MySQL默认的是异步复制,就是主库在执行完客户端提交的事务后立即将结果返回给客户端,并不关系从库是否已经接受处理,这样如果主挂掉,主上提交的事务可能并没有完全传到从上,如果此时强行把从提升为主,可能会导致新主上的数据不完整。
全同步复制
指当主库执行完一个事务,等到所有从库都执行完该事务才将结果返回给客户端。因为需要等待所有从库都执行完下能返回,所以全同步复制的性能必然会受到影响,需要有超时时间。
半同步复制
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立即返回给客户端,而是等到至少一个从库接收到并写到realy log中才返回给客户端。相对于异步复制,半同步复制提高了数据库的安全性,同时也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
如果想更好地实现MySQL的主从复制,必须首先要想清楚它的复制原理,这样在工作中才能熟练的操作和应用。
MySQL复制的工作原理:
1、主服务器(master)将改变记录写入到二进制日志(binary log)中(这些记录叫做二进制日志事件,binary log events) ,在事件 写入二进制日志完成后,master通知存储引擎提交事务。此后可接收slave的请求
2、从服务器(slave)将主服务器master的binary log events拷贝到自己的中继日志(relay log) 。Slave的I/O线程在master上打开一个普通的连接,并将这些二进制事件写入中继日志。
3、SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。
MySQL还提供了一种复制过滤器:就是指在数据库复制的过程中,仅复制一个或几个数据库相关的数据,并非所有,它提供了两种复制方法:一种是在主服务器的配置文件中添加配置文件,另一种是在从服务器中添加配置文件。
1、在主服务器中
主服务器仅向二进制日志中记录有关特定数据库相关的写操作。
binlog_do_db= #要复制的数据库
binlog_ignore_db=#要忽略的数据库
2、在从服务器中
从服务器的SQL THREAD仅重放关注的数据库或表相关的事件,并将其应用于本地;
Replicate_Do_DB= #要复制过来的数据库
Replicate_Ignore_DB=#不要复制过来的数据库
下面我们开始基于上边的理论来完成我们今天的实验。
MySQL主从架构图
一、环境准备:
centos系统服务器2台、一台用户做Mysql主服务器,一台用于做 Mysql从服务器,配置好yum源、防火墙关闭、各节点时钟服务同步、各节点之间可以通过主机名互相通信
二、准备步骤:
1、iptables -F && setenforce 清空防火墙策略,关闭selinux
2、拿两台服务器都使用yum方式安装Mysql服务,要求版本一致
3、分别启动两台服务器mysql服务,确保服务正常
三、实现步骤:
配置master主服务器:
1、对master进行配置,包括打开二进制日志,指定唯一的servr ID。在配置文件加入如下值:
server-id=1 #配置server-id,让主服务器有唯一ID号 log-bin=mysql-bin #打开Mysql日志,日志格式为二进制 skip-name-resolve#关闭名称解析,(非必须)
2、创建复制帐号 在Master的数据库中建立一个备份帐户:每个slave使用标准的MySQL用户名和密码连接master 。进行复制操作的用户会授予REPLICATION SLAVE权限。
grant replication slave,replication client on *.* to slave@'172.17.%.%' identified by '111111';
3.查看主服务器状态,在Master的数据库执行show master status,查看主服务器二进制日志状态
MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 414 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec)
配置slave从服务器:
1、对slave进行配置,打开中继日志,指定唯一的servr ID,设置只读权限。在配置文件加入如下值
server-id=2 #配置server-id,让从服务器有唯一ID号 relay_log = mysql-relay-bin #打开Mysql日志,日志格式为二进制 read_only = 1 #设置只读权限 log_bin = mysql-bin #开启从服务器二进制日志 log_slave_updates = 1 #使得更新的数据写进二进制日志中
2、启动从服务器复制线程 让slave连接master,并开始重做master二进制日志中的事件。
MariaDB [(none)]> change master to master_host='172.17.253.210',master_user='slave',master_password='111111',master_log_file='mysql-bin.000001',master_log_pos=245; Query OK, 0 rows affected (0.01 sec) 执行start slave;# 启动复制线程。
3、查看从服务器状态 可使用SHOW SLAVE STATUS\G查看从服务器状态,如下所示,也可用show processlist \G查看当前复制状态:
Slave_IO_Running: Yes #IO线程正常运行
Slave_SQL_Running: Yes #SQL线程正常运行
实现半同步复制:
主节点:
MariaDB [(none)]> install plugin rpl_semi_sync_master soname 'semisync_master.so'; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> show global variables like 'rpl_semi%'; +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | rpl_semi_sync_master_enabled | OFF | | rpl_semi_sync_master_timeout | 10000 | | rpl_semi_sync_master_trace_level | 32 | | rpl_semi_sync_master_wait_no_slave | ON | +------------------------------------+-------+ 4 rows in set (0.01 sec) MariaDB [(none)]> set global rpl_semi_sync_master_enabled=on; Query OK, 0 rows affected (0.00 sec)
从节点:
MariaDB [(none)]> install plugin rpl_semi_sync_slave soname 'semisync_slave.so'; Query OK, 0 rows affected (0.01 sec) MariaDB [(none)]> show global variables like 'rpl_semi%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | OFF | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 2 rows in set (0.01 sec) MariaDB [(none)]> stop slave io_thread; Query OK, 0 rows affected (0.00 sec) MariaDB [(none)]> set global rpl_semi_sync_slave_enabled =on; Query OK, 0 rows affected (0.01 sec) MariaDB [(none)]> show global variables like 'rpl_semi%'; +---------------------------------+-------+ | Variable_name | Value | +---------------------------------+-------+ | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +---------------------------------+-------+ 2 rows in set (0.00 sec) MariaDB [(none)]> start slave io_thread; Query OK, 0 rows affected (0.00 sec)
四、测试
在master上创建数据库和数据表,观察slave数据库中的数据,是否和master同步。