zoukankan      html  css  js  c++  java
  • Mysql主从复制


        因为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.使用有复制权限的用户账号连接至主节点服务器,并启用相关的线程;
     


            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 statusG;
     


                MariaDB [(none)]> start slave;
                MariaDB [(none)]> show slave statusG;
     


            接下来就可以在主节点上创建一个数据库或者表来测试一下从节点中是否也出现相同的改变啦;
                注意事项
                    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 statusG;
     


                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:根据马哥视频做的学习笔记,如有错误,欢迎指正;侵删
        
     

  • 相关阅读:
    将一个数组分割为固定大小为三的的数组的数组
    计算两个日期间的天数
    手机号码影藏中间四位
    (反射)获取类的Class文件的三种方式
    Java程序员必背单词
    文本处理(CSS,JS)
    java学习路线
    onLoad onShow
    过滤HTML标签
    uni-app手机横屏后界面错乱解决办法
  • 原文地址:https://www.cnblogs.com/guowei-Linux/p/11072856.html
Copyright © 2011-2022 走看看