mysql主从复制和读写分离

本文详细介绍了在MySQL 5.6环境下,如何配置和测试主从复制以及实现读写分离。通过设置不同服务器的角色,授权,配置日志和position,确保数据同步。同时利用Amoeba进行读写分离,测试了在主从复制基础上的数据一致性,并展示了读请求的负载均衡效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


MySQL版本:5.6

jdk版本:1.6

amoeba版本:2.2

HostIP
master192.168.218.5
slave1192.168.218.6
slave2192.168.218.7
amoeba192.168.218.4

主从复制

主服务器

修改MySQL配置文件my.cnf,添加以下配置

log_bin = master-bin
log_slave_updates = true
server_id = 11

 
 

    注:在MySQL5.5版本的配置文件中,下划线_要改为-

    进入MySQL数据库

    # 配置账号,用于slave向master同步数据库
    mysql> grant replication slave on *.* to 'mysql_slave'@'192.168.218.%' identified by 'password';
    Query OK, 0 rows affected (0.00 sec)
    mysql> flush privileges;
    Query OK, 0 rows affected (0.00 sec)
    # 查看日志文件和position
    mysql> show master status;
    +-------------------+----------+--------------+------------------+-------------------+
    | File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
    +-------------------+----------+--------------+------------------+-------------------+
    | master-bin.000001 |      850 |              |                  |                   |
    +-------------------+----------+--------------+------------------+-------------------+
    1 row in set (0.00 sec)
    
     
     

      在两台从服务器上

      修改MySQL配置文件my.cnf,添加以下配置

      server_id = 22
      relay_log = relay_log_bin
      relay_log_index = slave_relay_bin.index
      
       
       

        进入MySQL数据库

        # 定义master,添加用于同步的账号和密码以及日志文件、position
        # 根据在master上看到的日志文件和position填写,不能乱填
        mysql> change master to master_host='192.168.218.5', master_user='mysql_slave',master_password='password',master_log_file='master-bin.000001',master_log_pos=850;
        Query OK, 0 rows affected, 2 warnings (0.05 sec)
        # 开启slave
        mysql> start slave;
        Query OK, 0 rows affected (0.00 sec)
        # 查看slave状态是否开启
        mysql> show slave status\G;
        *************************** 1. row ***************************
        ……省略部分内容……
                     Slave_IO_Running: Yes
                    Slave_SQL_Running: Yes
        ……省略部分内容……
        
         
         

          在从服务器上查看数据库

          mysql> show databases;
          +--------------------+
          | Database           |
          +--------------------+
          | information_schema |
          | mysql              |
          | performance_schema |
          | test               |
          +--------------------+
          4 rows in set (0.00 sec)
          
           
           

            测试主从复制

            在主服务器创建新的数据库,以测试主从复制效果

            mysql> show databases;
            +--------------------+
            | Database           |
            +--------------------+
            | information_schema |
            | mysql              |
            | performance_schema |
            | test               |
            +--------------------+
            4 rows in set (0.00 sec)
            mysql> create database test_database1;
            Query OK, 1 row affected (0.00 sec)
            mysql> show databases;
            +--------------------+
            | Database           |
            +--------------------+
            | information_schema |
            | mysql              |
            | performance_schema |
            | test               |
            | test_database1     |
            +--------------------+
            5 rows in set (0.00 sec)
            
             
             

              在从服务器上查看是否同步

              mysql> show databases;
              +--------------------+
              | Database           |
              +--------------------+
              | information_schema |
              | mysql              |
              | performance_schema |
              | test               |
              | test_database1     |
              +--------------------+
              5 rows in set (0.00 sec)
              
               
               

                已成功同步!

                读写分离

                到存放jdk包的目录下

                chmod +x jdk-6u14-linux-x64.bin
                ./jdk-6u14-linux-x64.bin
                mv jdk1.6.0_14/ /usr/local/jdk1.6
                
                 
                 

                  安装amoeba

                  mkdir /usr/local/amoeba
                  tar xf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
                  chmod -R 755 /usr/local/amoeba
                  
                   
                   

                    添加环境变量到/etc/profile

                    export JAVA_HOME=/usr/local/jdk1.6
                    export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
                    export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
                    export AMOEBA_HOME=/usr/local/amoeba
                    export PATH=$PATH:$AMOEBA_HOME/bin
                    
                     
                     

                      别忘了source一下

                      source /etc/profile
                      
                       
                       

                        测试是否安装成功

                        [root@localhost ~]# /usr/local/amoeba/bin/amoeba
                        amoeba start|stop
                        
                         
                         

                          出现上面的提示则安装成功

                          到三台MySQL服务器上,配置amoeba访问MySQL的账号

                          mysql> GRANT ALL ON *.* TO amoeba2db@'192.168.218.%' IDENTIFIED BY '123abc';
                          Query OK, 0 rows affected (0.36 sec)
                          
                           
                           

                            修改amoeba配置文件

                            vim /usr/local/amoeba/conf/amoeba.xml

                            在这里插入图片描述
                            在这里插入图片描述

                            vim /usr/local/amoeba/conf/dbServers.xml

                            在这里插入图片描述
                            配置amoeba连接MySQL服务器的账号密码
                            在这里插入图片描述

                            配置master、slave1、slave2
                            在这里插入图片描述

                            开启amoeba

                            /usr/local/amoeba/bin/amoeba start &
                            
                             
                             

                              到客户机上,连接amoeba测试,使用用于连接amoeba的账号登录

                              mysql -u client2amoeba -p 123abc -h 192.168.218.4 -P8066
                              
                               
                               
                                MySQL [(none)]> show databases;
                                +--------------------+
                                | Database           |
                                +--------------------+
                                | information_schema |
                                | mysql              |
                                | performance_schema |
                                | test               |
                                | test_database1     |
                                +--------------------+
                                5 rows in set (0.00 sec)
                                
                                 
                                 

                                  写入测试数据

                                  MySQL [(none)]> use test_database1;
                                  Database changed
                                  MySQL [test_database1]> create table book (
                                      -> id int primary key auto_increment,
                                      -> name varchar(16));
                                  Query OK, 0 rows affected (0.45 sec)
                                  MySQL [test_database1]> insert into book (name) value ("it");
                                  Query OK, 1 row affected (0.00 sec)
                                  MySQL [test_database1]> insert into book (name) value ("cook");
                                  Query OK, 1 row affected (0.00 sec)
                                  MySQL [test_database1]> select * from book;
                                  +----+------+
                                  | id | name |
                                  +----+------+
                                  |  1 | it   |
                                  |  2 | cook |
                                  +----+------+
                                  2 rows in set (0.11 sec)
                                  
                                   
                                   

                                    分别到三台MySQL服务器上查看是否存在测试数据

                                    在这里插入图片描述

                                    因为已配好主从复制,故数据已同步过来

                                    测试读写分离

                                    到两台从服务器上输入

                                    mysql> stop slave;
                                    Query OK, 0 rows affected (0.00 sec)
                                    
                                     
                                     

                                      查看slave状态

                                      mysql> show slave status\G;
                                      *************************** 1. row ***************************
                                      ……省略部分……
                                                   Slave_IO_Running: No
                                                  Slave_SQL_Running: No
                                      ……省略部分……
                                      
                                       
                                       

                                        这时再回到客户端写入数据,并查看

                                        MySQL [test_database1]> insert into book (name) value ("Java");
                                        Query OK, 1 row affected (0.00 sec)
                                        MySQL [test_database1]> select * from book;
                                        +----+------+
                                        | id | name |
                                        +----+------+
                                        |  1 | it   |
                                        |  2 | cook |
                                        +----+------+
                                        2 rows in set (0.00 sec)
                                        
                                         
                                         

                                          并没有我们刚刚写入的"Java"这本书

                                          到slave1上,插入测试数据

                                          mysql> insert into book (name) value ("Slave1");
                                          Query OK, 1 row affected (0.00 sec)
                                          
                                           
                                           

                                            到slave2上,插入测试数据

                                            mysql> insert into book (name) value ("Slave2");
                                            Query OK, 1 row affected (0.00 sec)
                                            
                                             
                                             

                                              再回到客户端查看,会发现很神奇的事情

                                              MySQL [test_database1]> select * from book;
                                              +----+--------+
                                              | id | name   |
                                              +----+--------+
                                              |  1 | it     |
                                              |  2 | cook   |
                                              |  3 | Slave1 |
                                              +----+--------+
                                              3 rows in set (0.00 sec)
                                              MySQL [test_database1]> select * from book;
                                              +----+--------+
                                              | id | name   |
                                              +----+--------+
                                              |  1 | it     |
                                              |  2 | cook   |
                                              |  3 | Slave2 |
                                              +----+--------+
                                              3 rows in set (0.00 sec)
                                              MySQL [test_database1]> select * from book;
                                              +----+--------+
                                              | id | name   |
                                              +----+--------+
                                              |  1 | it     |
                                              |  2 | cook   |
                                              |  3 | Slave1 |
                                              +----+--------+
                                              3 rows in set (0.00 sec)
                                              
                                               
                                               

                                                这个现象的原因是,MySQL对读请求做了负载均衡,对多次请求采用了轮询算法,所有的用于处理读请求的MySQL会轮流(或者按权重)来响应

                                                至此,MySQL的主从复制和读写分离就已完成!

                                                别忘了测试完成后再到从服务器上start slave

                                                《C++编程实例100篇》是一本深入实践、极具价值的编程教程,它针对C++编程语言提供了丰富的实例,旨在帮助读者更好地理解掌握C++的各项特性与编程技巧。这本书的经典之处在于它将理论与实践相结合,通过100个精心设计的编程实例,覆盖了C++的各个核心领域,包括基础语法、面向对象编程、模板、异常处理、STL(标准模板库)等。 我们来探讨C++的基础语法。C++是C语言的增强版,它保留了C语言的高效性灵活性,并引入了类、对象继承等面向对象编程概念。基础语法包括变量声明、数据类型、运算符、控制结构(如if语句、for循环、while循环)、函数的定义调用等。在实例中,你可能会遇到如何编写简单的程序,如计算两个数的,或者实现一个简单的猜数字游戏。 C++的面向对象编程是其一大特色。通过类对象,你可以构建复杂的软件系统。类是对象的蓝图,它定义了对象的属性行为。实例化一个类,就是创建一个具体的对象。继承允许你创建新的类,这些类从现有的类派生,共享其属性方法,同时可以添加新的功能。多态性是面向对象的另一个关键特性,它使得不同类型的对象可以对同一消息作出不同的响应。这些概念在实例中会以各种形式展现,例如设计一个图形界面的类层次,或实现一个简单的模拟游戏。 接下来是模板,C++的模板功能让代码更加通用,可以处理不同类型的数据。模板分为函数模板类模板,前者可以创建泛型函数,后者可以创建泛型类。通过模板,你可以编写出高效且灵活的代码,比如实现一个通用的排序算法。 异常处理是C++中用于处理程序运行时错误的机制。当程序出现异常情况时,可以抛出一个异常,然后在适当的点捕获并处理这个异常。这使得代码能够优雅地处理错误,而不是让程序崩溃。实例中可能会有涉及文件操作或网络通信时可能出现的异常处理示例。
                                                <think>嗯,用户想知道MySQL在分布式系统中如何配置主从复制读写分离,以及它们的原理。首先,我需要回忆主从复制的基本流程。主库记录二进制日志,从库通过IO线程读取这些日志,然后SQL线程重放,对吧?这确保了数据一致性。不过用户可能还需要知道具体的配置步骤,比如修改my.cnf文件,创建复制用户,还有CHANGE MASTER命令这些步骤。 然后是读写分离的部分。主库处理写操作,从库处理读操作,这样可以提升性能。但用户可能关心如何实现自动的读写分离,可能需要中间件或者框架支持,比如MyCat或ShardingSphere。这部分需要解释清楚原理,以及配置方法。 另外,用户可能对主从复制的同步机制有疑问,比如异步、半同步全同步的区别,以及各自的优缺点。异步可能性能好但有数据丢失风险,半同步则是在两者之间平衡。需要解释这些模式适用场景。 还有,读写分离带来的数据一致性问题。主从同步有延迟的话,读从库可能拿到旧数据。需要讨论如何解决,比如强制读主库或者监控延迟。用户可能在实际应用中遇到这个问题,所以解决方案很重要。 最后,用户可能想知道高可用性的扩展,比如主库故障时的切换,或者如何监控复制状态。这部分可以提到MHA或者Keepalived这样的工具,帮助提升系统的可靠性。 现在要确保回答结构清晰,分步骤讲解配置,再讲原理,最后讨论注意事项扩展。同时需要引用提供的资料,比如引用[2]提到动态切换分库分表,可能主从配置有关联。但用户的问题更聚焦在主从复制读写分离,所以重点应该放在这里。需要检查引用内容是否相关,适当引用。比如引用[3]提到集中式授权,可能权限配置有关,但可能不太直接相关。可能更多参考引用[2]关于分库分表的动态切换,但主从复制是基础,需要明确区分。 还要生成相关问题,比如主从延迟如何处理,半同步配置,或者读写分离中间件的选择。这些问题能帮助用户深入理解。确保回答中的LaTeX格式正确,数学表达式用$...$,独立公式用$$...$$,并且正确使用引用标记。</think>### MySQL主从复制读写分离的实现原理与配置 #### 一、主从复制核心原理 1. **二进制日志(Binlog)机制** 主库将所有数据变更操作记录到二进制日志中,格式为$binlog\_format=ROW|STATEMENT|MIXED$[^1]。从库通过I/O线程实时拉取主库的Binlog,并写入本地中继日志(Relay Log)。 2. **数据同步流程** $$ \begin{aligned} &\text{主库写入} \rightarrow binlog \xrightarrow[\text{网络传输}]{\text{I/O线程}} relay\ log \xrightarrow{\text{SQL线程}} \text{从库数据} \\ &\Delta t_{同步} = t_{网络} + t_{SQL解析} + t_{从库写入} \end{aligned} $$ 延迟主要受网络带宽、从库硬件性能事务复杂度影响[^2]。 #### 二、配置步骤详解 1. **主库配置** (`my.cnf`) ```ini [mysqld] server-id=1 log-bin=mysql-bin binlog_format=ROW ``` 2. **从库配置** (`my.cnf`) ```ini [mysqld] server-id=2 relay-log=mysql-relay ``` 3. **建立复制链路** ```sql -- 主库创建复制账号 CREATE USER 'repl'@'%' IDENTIFIED BY 'password'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; -- 从库执行 CHANGE MASTER TO MASTER_HOST='master_ip', MASTER_USER='repl', MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=154; ``` #### 三、读写分离实现方案 1. **中间件方案** 使用MyCat/ProxySQL等中间件,配置规则: ```sql -- 写路由 INSERT/UPDATE/DELETE -> 主库 -- 读路由 SELECT -> 从库(支持负载均衡) ``` 2. **客户端分离方案** 在ORM框架(如MyBatis)中通过注解指定数据源: ```java @DataSource("master") public void insertData(...); @DataSource("slave") public List<Data> queryData(...); ``` #### 四、关键注意事项 1. **复制延迟问题** - 强制读主库:`/* FORCE_MASTER */ SELECT ...` - 并行复制:设置`slave_parallel_workers=8` - 半同步复制:`rpl_semi_sync_master_timeout=1000` 2. **高可用扩展** 采用MHA+Keepalived实现主库故障自动切换,VIP漂移时间可控制在10-30秒[^3]。 ```mermaid graph TD A[应用层] --> B{SQL类型} B -->|写操作| C[主库] B -->|读操作| D[从库集群] C --> E[Binlog] E --> F[从库I/O线程] F --> G[Relay Log] G --> H[从库SQL线程] ```
                                                评论 1
                                                添加红包

                                                请填写红包祝福语或标题

                                                红包个数最小为10个

                                                红包金额最低5元

                                                当前余额3.43前往充值 >
                                                需支付:10.00
                                                成就一亿技术人!
                                                领取后你会自动成为博主和红包主的粉丝 规则
                                                hope_wisdom
                                                发出的红包
                                                实付
                                                使用余额支付
                                                点击重新获取
                                                扫码支付
                                                钱包余额 0

                                                抵扣说明:

                                                1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
                                                2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

                                                余额充值