由于mysql对性能的要求较高,而且作向上扩展价格及其昂贵,因此通常都会采用向下扩展的主从复制方案,来提升mysql的性能;主从复制能够实现仅主mysql服务器能够提供读写数据,而从服务器仅可提供读数据,即让来自客户端的写请求仅发送至主服务器,读请求分散发送到各个从服务器,从而提升mysql的并发能力以及处理请求的能力;可是这就要求从服务器中要有主服务器上的所有数据,只有这样才能让从从服务器请求到的数据是正确的,因此就要有一种方法来实现主从服务器之间数据的同步;这种方法为:从服务器会按期向主服务器请求其二进制日志中的数据,而后主服务器接受请求之后将其要求的数据返回给从服务器,接着从服务器将其写到本身的中继日志中,再经过读取中继日志,将其中的操做再从新操做一遍,并将其记录到本身的二进制日志中,从而实现了数据的同步;从服务器的每次请求都会携带本身的已经同步的数据的位置,以便主服务器将最新的、本身没有的数据发送给本身;
Note:从服务器的二进制日志功能能够根据须要决定是否启用,若是此台从服务器仍是另外一台服务器的主服务器(级联复制),则须要启用二进制日志功能,若是其只是从服务器,则能够不启用二进制日志功能;
主从复制详细过程:
从节点启动一个线程做为主节点的客户端,经过mysql协议向mysql主节点请求读取其二进制日志文件中的事件;mysql主节点首先会启动一个线程,而后会检查从节点发送过来的请求中的关于日志中的事件位置的号码,而后主mysql节点会根据这个位置将数据返回给从节点;从节点接收到主mysql节点的响应之后会将其首先存储在其中继日志中,而后再经过一个文件记录(master.info)本身已经读到主节点二进制日志文件中的位置,等下次再请求数据时就会将这个位置发送给主mysql节点,以便请求接下来的数据;从节点接着会再启动一个线程负责根据中继日志将其中的全部记录将数据都重作一遍;其中主节点中的线程叫作dump线程,为每一个从节点的I/O Thread启动一个dump线程,用于向其发送binary log events;从节点中负责请求数据的线程叫作I/O Thread、负责从中继日志中读取事件并在本地重作的线程叫作SQL Thread;
mysql复制的特色:
异步复制:主节点将二进制日志中的事件发送给从节点之后不会等待从节点的反馈信息就接着处理其余任务去了;可是这样有个风险,就是从节点可能没有接收执行成功,到时数据不一致;
读写分离器(r/w spliter):mysql的七层负载均衡器,未来自客户端的写请求分发到主节点,将读请求分发到从节点;
gtid:全局事务ID,能够在主节点故障时,将从节点提高为主节点继续提供服务,可是从节点的数据不必定是最新的,也不必定是完整的,因此能够经过这个特性,将同是从节点的其余节点中的,可是本身没有的数据同步到本身的数据库中,而后本身做为主节点提供服务;可是也有缺点,就是技术比较复杂;也能够经过高可用主节点来增长数据库持续提供服务的能力;
会致使数据不一致
主从复制的几种方案:
一主多从:一个主节点,多个从节点;
若是从节点过多则会在主节点中启动很是多的dump线程,这样会增长主节点的负载,原本主节点就要处理大量的写操做,如今又要运行这么多的线程,将数据发送到各个从节点,这会使主节点不堪重负,,称为性能瓶颈;咱们能够经过级联的方式减轻主节点的负载,其拓扑通常为:一个主节点链接一个从节点,而后全部其余的从节点所有链接到也主节点相连的从节点上,这样就减轻了主节点的负载,可是这样又增长那个特殊从节点的负载,因此咱们让这个节点只负责将数据复制到各个从节点,而不负责存数据,也就不对外提供读请求响应了(使用blackhole存储引擎,将全部数据都传入黑洞);
双主多从高可用:两个主节点,多个从节点,可是同时只有一个主节点在提供服务,另外一个主节点做为备份节点;
双主双从互为备份:每一个节点既是主节点也是从节点,当一个节点故障时,另外一个节点能够继续提供服务;经过Server ID来分辨各个节点,以防止一个节点的操做被复制到另外一个节点上重作一遍之后又被发回本身自己进行重作,这样就造成了一个循环,当其发现Server ID是本身时就不会再从新记录了;这种方案能够实现读请求的负载均衡,可是没有实现写请求的负载均衡,由于在一个节点中处理写请求之后,在另外一个节点还会再进行一次;
多主(环状结构):一个节点的是另外一个节点的从,另外一个节点又是另外一个节点的从,最后造成一个环;
示例:
1.主从复制:
主节点:
a.启动二进制日志;
b.为当前接单设置一个全局惟一的Server ID;
c.建立有复制权限的用户帐号;
REPLICATION SLAVE,REPLICATION CLIENT
从节点:
a.启动中继日志;
b. 为当前接单设置一个全局惟一的Server ID;
c.肯定复制位置,即要从主服务器的哪一个位置开始复制数据;
d.使用有复制权限的用户帐号链接至主节点服务器,并启用相关的线程;
html
192.168.80.143为主节点:
cat /etc/my.cnf.d/server.cnf
……
[mariadb-5.5]
log_bin=master-bin
server_id=1
innodb_file_per_table=ON
skip_name_resolve=ON
MariaDB [(none)]> grant replication slave,replication client on *.* to 'repluser'@'192.168.80.136' identified by 'replpassword';
192.168.80.136为从节点:
cat /etc/my.cnf.d/server.cnf
……
[mariadb-5.5]
relay_log=relay-log
relay_log_index=relay-log.index
server_id=5
innodb_file_per_table=ON
skip_name_resolve=ON
MariaDB [(none)]> show master logs; (此操做是在主节点上执行的)
MariaDB [(none)]> change master to master_host='192.168.80.143',master_user='repluser',master_password='replpassword',master_log_file='master-bin.000001',master_log_pos=425; (此操做是在从节点上执行的)
MariaDB [(none)]> show slave status\G;
mysql
MariaDB [(none)]> start slave;
MariaDB [(none)]> show slave status\G;
sql
接下来就能够在主节点上建立一个数据库或者表来测试一下从节点中是否也出现相同的改变啦;
注意事项
a.限制从节点为只读;
在从节点中设置read_only为ON;可是此限制对拥有super权限的用户无效;还有一种方法就是启动一个链接线程,链接至mysql中执行mysql>flush tables with read lock;
b.保证主从复制的事务安全
在主节点启用参数:
sync_binlog=ON 当事务提交时,将二进制日志缓冲区中的事件当即写入到磁盘中,避免系统忽然宕机致使数据丢失;
sync_master_info 是否及时将内存中的master.info文件的信息同步到磁盘中;
若是是innodb存储引擎建议开启:
innodb_flush_logs_at_trx_commit=ON 在事务提交时,将事务日志缓冲区中跟事务相关的数据当即写到事务日志中;
innodb_support_xa=ON 使innodb支持分布式事务,使其支持两段式提交功能;
在从节点启动的参数:
skip_slave_start=ON 当从节点上的mysql服务启动之后是否自动启动复制线程;这个根据状况而定;
sync_relay_log 是否及时将内存中的relay_log数据同步到磁盘中;
sync_relay_log_info 是否及时将内存中的relay-log.info文件的信息同步到磁盘中;
思考:若是主节点已经运行了一段时间,且有大量数据时,如何配置并启动从节点?
答:经过备份恢复数据至从服务器,而后在从节点上开始复制起始位置为备份时的二进制日志文件及其POS位置;
2.主主复制(互为主从):
可能会出现的问题:
数据不一致
自动增加ID会出现冲突(因版本而异,如今的新版本已经不会出现这个问题了),能够经过配置一个节点使用基数ID(auto_increment_offset=1 auto_increment_increment=2),另外一个节点使用偶数ID来解决这个问题(auto_increment_offset=2 auto_increment_increment=2);
配置步骤:
a.各节点使用一个惟一的Server ID;
b.都启动binary log和relay log;
c.建立拥有复制权限的用户帐号;
d.定义自动增加id字段的数值范围为奇偶(根据状况而定);
e.均把对方指定为主节点,并启用复制线程;
使用192.168.80.143和192.168.80.136这两台主机作主主复制:
cat /etc/my.cnf.d/server.cnf
……
[mariadb-5.5]
log_bin=master-bin
relay_log=relay-log
server_id=1
innodb_file_per_table=ON
skip_name_resolve=ON
MariaDB [(none)]>grant replication slave,replication client on *.* to 'repluser'@'192.168.80.136|143' identified by 'replpasswd';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> change master to master_host='192.168.80.136',master_user='repluser',master_password='replpasswd',master_log_file='master-bin.000003',master_log_pos=506;
MariaDB [(none)]> show slave status\G;
数据库
MariaDB [(none)]> start slave;
安全
接下来就能够在主节点上建立一个数据库或者表来测试一下从节点中是否也出现相同的改变啦;
3.半同步复制(google提供的插件):
在配置文件中指明须要安装的插件的位置(默认不用指定就能够直接安装):
/usr/lib64/mysql/plugin/semisync_master.so 主节点
/usr/lib64/mysql/plugin/semisync_slave.so 从节点
安装插件:
主节点:
mysql>install plugin rpl_semi_sync_master soname ‘semisync_master.so’
mysql>set global variables rpl_semi_sync_master_enabled=1
mysql>show global variables like ‘%semi%’
mysql>show global status like ‘%semi%’
从节点:
mysql> install plugin rpl_semi_sync_slave soname ‘semisync_slave.so’
mysql>set global variables rpl_semi_sync_slave_enabled=1
Note:其余过程与上面的相似,就不在赘述了;
复制过滤器:
使用复制过滤器能够实现仅复制指定的数据库,能够在主节点实现也能够在从节点实现,可是在主节点实现会形成主节点的二进制日志不完整,因此通常都都会在从节点上设置这个功能,即让从节点只重作指定数据库或指定数据库的指定表;
两种实现方式;
1.主节点仅向二进制日志中记录与指定数据库或指定数据库的指定表相关的事件;
经过binlog_do_db(白名单)或者binlog_ignore_db(黑名单)来实现;(这个在mariadb-5.5.60中已经没有了,至少默认是没有的)
2.从节点SQL Thread在replay中继日志中的事件时,仅读取与指定数据库或指定数据库的指定表相关的事件并应用到本地;
经过replicate_do_db|table(白名单)或者replicate_ignore_db|table(黑名单)来实现;
基于SSL的复制:
能够添加一个限制,就是必须使用ssl链接mysql才能够实现复制:在grant受权用户时加上require ssl便可;
这篇文章写的不错:https://www.cnblogs.com/xiaocen/p/3709838.html
清理二进制日志:
Examples:
PURGE BINARY LOGS TO 'mysql-bin.010';
PURGE BINARY LOGS BEFORE '2008-04-02 22:46:26';服务器
Note:根据马哥视频作的学习笔记,若有错误,欢迎指正;侵删
并发