zoukankan      html  css  js  c++  java
  • mysql企业实战(二)之主从复制,读写分离,双主,以及高可用

    、MySQL主从复制

    1、简介

    我们为什么要用主从复制?

    主从复制目的:

    可以做数据库的实时备份,保证数据的完整性;

    可做读写分离,主服务器只管写,从服务器只管读,这样可以提升整体性能。

    2、更改配置文件

    两天机器都操作,确保 server-id 要不同,通常主ID要小于从ID。一定注意。

    服务器(主):192.168.1.192

    服务器(从):192.168.1.179

    # 打开log-bin,并使server-id不一样
    #vim /etc/my.cnf
    log-bin = mysql-bin
    server-id = 1
    #vim /etc/my.cnf 
    log-bin = mysql-bin
    server-id = 3

    #检查
    1、
    [root@bogon ~]# egrep "log-bin|server-id" /etc/my.cnf 
    log-bin = mysql-bin
    server-id = 1
    [root@bogon ~]# egrep "log-bin|server-id" /etc/my.cnf  
    log-bin = mysql-bin
    server-id = 3
    2、
    [root@localhost ~]# mysql -usystem -p -S /application/mysql-5.5.33/tmp/mysql.sock -e "show variables like 'log_bin';"
    Enter password: 
    +-----------------------+--------+
    | Variable_name | Value |
    +-----------------------+--------+
    | log_bin       | ON  |    # ON 为开始开启成功
    +-----------------------+--------+

    3、建立用于从库复制的账号qiu

    通常会创建一个用于主从复制的专用账户,不要忘记授权。

    # 主库授权,允许从库来连接我取日志
    [root@localhost ~]# mysql -usystem -p -S  /application/mysql-5.5.33/tmp/mysql.sock
    Enter password:
    # 允许从库192.168.1网段连接,账号qiu,密码oldgirl。
    mysql> grant replication slave on *.* to 'qiu'@'192.168.1.%' identified by 'oldgirl';
    mysql> flush privileges;

    /*这里特别要注意要么关闭防火墙,要么开启端口*/

    4、备份主库,及恢复到从库

    把主库现有数据备份下来,再恢复到从库,此时两个主机的数据一致。

    如果事先有数据的话,这不不能忘。

    1)    在主库上加锁,使只有只读权限。
    mysql> flush table with read lock;
    Query OK, 0 rows affected (0.00 sec)
    #5.1、5.5锁表命令略有不同。
    # 5.1锁表:flush tables with read lock;
    # 5.5锁表:flush table with read lock;

    2)    记住就是这个点备份的。
    mysql> show master status;
    +---------------------------+-------------+-------------------+--------------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +----------------------------+------------+--------------------+-------------------------+
    | mysql-bin.000013  |   410 |             |               |
    +----------------------------+------------+--------------------+-------------------------+
    1 row in set (0.00 sec)
    3) 克隆窗口,备份数据。
    [root@bogon ~]# mysqldump -usystem -p -S /data/3306/mysql.sock -A -B --events --master-data=2|gzip >/opt/qiu.sql.gz
    Enter password:
    参数:    -A:备份所有的 
    --master-data=2:
    1: 记录为CHANGE MASTER TO 语句、语句不被注释
    2: 记录为注释的CHANGE MASTER TO语

    --events: 备份事件调度器
     grep -i "change master to" master-data.sql 
    vim /opt/rep.sql.gz
    -- CHANGE MASTER TO MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=781215118;

    4)    查看master status;数值是否正常

    show master status;
    +------------------+-----------+--------------+------------------+
    | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+-----------+--------------+------------------+
    | mysql-bin.000001 | 781215118 | | |
    +------------------+-----------+--------------+------------------

    5)    解锁库
    mysql> unlock tables;
    Query OK, 0 rows affected (0.00 sec)

    6)    恢复到从库
    [root@bogon ~]# gunzip < /opt/qiu.sql.gz | mysql -uroot -p

    5、配置从库及生效

    更改从库和主库的连接参数,配置生效。检查就成功了!

    1)    进入从库。
    [root@bogon ~]# mysql -uroot -p
    Enter password:
    2)    更改从属服务器用于与主服务器进行连接和通讯的参数。
    mysql> CHANGE MASTER TO
          MASTER_HOST='192.168.1.192',
          MASTER_PORT=3306,
          MASTER_USER='qiu',
          MASTER_PASSWORD='oldgirl',
          MASTER_LOG_FILE='mysql-bin.000001',
          MASTER_LOG_POS=781215118
    3)    查看更改的参数。
    [root@localhost data]# cat master.info 
    18
    mysql-bin.000013
    410
    192.168.200.98
    REP
    nick
    3306
    60
    0

    4)    生效!
    mysql> start slave;

    5)    检查下列参数,符合则正常!
    mysql> show slave statusG
    Relay_Master_Log_File: mysql-bin.000001
                 Slave_IO_Running: Yes        #取logo。
                Slave_SQL_Running: Yes        #读relay-bin、logo,写数据。
    Seconds_Behind_Master: 0        #落后主库的秒数。

    6)    查看relay-bin.logo。
    [root@localhost 3307]# cat relay-log.info 
    /data/3307/relay-bin.000002
    340
    mysql-bin.000013
    497
    8)    查看master.info。
    [root@localhost 3307]# cat data/master.info 
    18
    mysql-bin.000013
    497
    192.168.200.98
    rep
    nick
    3306
    60
    0
    
    
    0
    1800.000
    
    0
    Amoeba实现读写分离

    一、Amoeba 是什么

    Amoeba(变形虫)项目,专注 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。

    主要解决:

    • 降低 数据切分带来的复杂多数据库结构

    • 提供切分规则并降低 数据切分规则 给应用带来的影响

    • 降低db 与客户端的连接数

    • 读写分离

    二、为什么要用Amoeba

    目前要实现mysql的主从读写分离,主要有以下几种方案:

    1、  通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。

    2、  通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。

    3、  自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。

    4、  利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。国产的开源软件,应该支持,目前正在使用,不发表太多结论,一切等测试完再发表结论吧,哈哈!

    Amoeba框架是居于JDK1.5开发的,采用了JDK1.5的特性,所以还需要安装java环境,建议使用javaSE1.5以上的JDK版本

          1、安装java环境

    tar -xf  jdk-8u11-linux-x64.tar.gz -C /usr/local/java

    2.然后设置java环境变量

    vim /etc/profile

     

    export JAVA_HOME=/usr/local/java/
    export JRE_HOME=/usr/local/java
    export CLASSPATH=.:$JAVA_HOME/lib:$JRE_HOME/lib
    export PATH=$JAVA_HOME/bin:$PATH

    3.source /etc/profile

    4.测试是否安装成功

    java -version

     

    java version "1.8.0_111"
    Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
    Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

    2、安装Amoeba
    Amoeba安装非常简单,直接解压即可使用,这里将Amoeba解压到/usr/local/amoeba目录下,这样就安装完成了

     

     

    [root@bogon amoeba]# pwd
    /usr/local/amoeba

     

      [root@bogon amoeba]# ll
      总用量 20
      drwxrwxrwx. 2 root root 4096 7月 5 2013 benchmark
      drwxrwxrwx. 2 root root 4096 7月 5 2013 bin
      drwxrwxrwx. 2 root root 4096 7月 5 2013 conf
      -rwxrwxrwx. 1 root root 728 7月 5 2013 jvm.properties
      drwxrwxrwx. 2 root root 4096 7月 5 2013 lib

    3、配置Amoeba

    Amoeba的配置文件在本环境下位于/usr/local/amoeba/conf目录下。配置文件比较多,但是仅仅使用读写分离功能,只需配置两个文件即可,分别是dbServers.xml和amoeba.xml,如果需要配置ip访问控制,还需要修改access_list.conf文件,下面首先介绍dbServers.xml

    [root@bogon amoeba]# cat conf/dbServers.xml 
    <?xml version="1.0" encoding="gbk"?>
    
    <!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd">
    <amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/">
    
            <!-- 
                Each dbServer needs to be configured into a Pool,
                If you need to configure multiple dbServer with load balancing that can be simplified by the following configuration:
                 add attribute with name virtual = "true" in dbServer, but the configuration does not allow the element with name factoryConfig
                 such as 'multiPool' dbServer   
            -->
            
        <dbServer name="abstractServer" abstractive="true">
            <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
                <property name="connectionManager">${defaultManager}</property>
                <property name="sendBufferSize">64</property>
                <property name="receiveBufferSize">128</property>
                    
                <!-- mysql port -->
                <property name="port">3306</property>  #设置Amoeba要连接的mysql数据库的端口,默认是3306
                
                <!-- mysql schema -->
                <property name="schema">testdb</property>  #设置缺省的数据库,当连接amoeba时,操作表必须显式的指定数据库名,即采用dbname.tablename的方式,不支持 use dbname指定缺省库,因为操作会调度到各个后端dbserver
                
                <!-- mysql user -->
                <property name="user">test1</property>  #设置amoeba连接后端数据库服务器的账号和密码,因此需要在所有后端数据库上创建该用户,并授权amoeba服务器可连接
                
                <property name="password">111111</property>
            </factoryConfig>
    
            <poolConfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool">
                <property name="maxActive">500</property>  #最大连接数,默认500
                <property name="maxIdle">500</property>    #最大空闲连接数
                <property name="minIdle">1</property>    #最新空闲连接数
                <property name="minEvictableIdleTimeMillis">600000</property>
                <property name="timeBetweenEvictionRunsMillis">600000</property>
                <property name="testOnBorrow">true</property>
                <property name="testOnReturn">true</property>
                <property name="testWhileIdle">true</property>
            </poolConfig>
        </dbServer>
    
        <dbServer name="writedb"  parent="abstractServer">  #设置一个后端可写的dbServer,这里定义为writedb,这个名字可以任意命名,后面还会用到
            <factoryConfig>
                <!-- mysql ip -->
                <property name="ipAddress">192.168.2.204</property> #设置后端可写dbserver
            </factoryConfig>
        </dbServer>
        
        <dbServer name="slave"  parent="abstractServer">  #设置后端可读dbserver
            <factoryConfig>
                <!-- mysql ip -->
                <property name="ipAddress">192.168.2.205</property>
            </factoryConfig>
        </dbServer>
        
        <dbServer name="myslave" virtual="true">  #设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为myslave
            <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
                <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
                <property name="loadbalance">1</property>  #选择调度算法,1表示复制均衡,2表示权重,3表示HA, 这里选择1
                
                <!-- Separated by commas,such as: server1,server2,server1 -->
                <property name="poolNames">slave</property>  #myslave组成员
            </poolConfig>
        </dbServer>
            
    </amoeba:dbServers>

    4.另一个配置文件amoeba.xml

    [root@bogon amoeba]# cat conf/amoeba.xml
    <?xml version="1.0" encoding="gbk"?>

    <!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">
    <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">

    <proxy>

    <!-- service class must implements com.meidusa.amoeba.service.Service -->
    <service name="Amoeba for Mysql" class="com.meidusa.amoeba.mysql.server.MySQLService">
    <!-- port -->
    <property name="port">8066</property>    #设置amoeba监听的端口,默认是8066

    <!-- bind ipAddress -->    #下面配置监听的接口,如果不设置,默认监听所以的IP
    <!--
    <property name="ipAddress">127.0.0.1</property>
    -->

    <property name="connectionFactory">
    <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory">
    <property name="sendBufferSize">128</property>
    <property name="receiveBufferSize">64</property>
    </bean>
    </property>

    <property name="authenticateProvider">
    <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">

    # 提供客户端连接amoeba时需要使用这里设定的账号 (这里的账号密码和amoeba连接后端数据库服务器的密码无关)

    <property name="user">root</property>    


    <property name="password">123456</property>

    <property name="filter">
    <bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController">
    <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
    </bean>
    </property>
    </bean>
    </property>

    </service>

    <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">

    <!-- proxy server client process thread size -->
    <property name="executeThreadSize">128</property>

    <!-- per connection cache prepared statement size -->
    <property name="statementCacheSize">500</property>

    <!-- default charset -->
    <property name="serverCharset">utf8</property>

    <!-- query timeout( default: 60 second , TimeUnit:second) -->
    <property name="queryTimeout">60</property>
    </runtime>

    </proxy>

    <!--
    Each ConnectionManager will start as thread
    manager responsible for the Connection IO read , Death Detection
    -->
    <connectionManagerList>
    <connectionManager name="defaultManager" class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper">
    <property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManager</property>
    </connectionManager>
    </connectionManagerList>

    <!-- default using file loader -->
    <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader">
    <property name="configFile">${amoeba.home}/conf/dbServers.xml</property>
    </dbServerLoader>

    <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">
    <property name="ruleLoader">
    <bean class="com.meidusa.amoeba.route.TableRuleFileLoader">
    <property name="ruleFile">${amoeba.home}/conf/rule.xml</property>
    <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
    </bean>
    </property>
    <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
    <property name="LRUMapSize">1500</property>
    <property name="defaultPool">writedb</property>  #设置amoeba默认的池,这里设置为writedb


    <property name="writePool">writedb</property>  #这两个选项默认是注销掉的,需要取消注释,这里用来指定前面定义好的俩个读写池
    <property name="readPool">myslave</property>   #

    <property name="needParse">true</property>
    </queryRouter>
    </amoeba:configuration>

    5.分别在masterdb和slavedb上为amoedb授权

    mysql> GRANT ALL ON testdb.* TO 'test1'@'192.168.2.203' IDENTIFIED BY '111111';
    flush privileges;

    6.启动amoeba

    [root@bogon amoeba]# /usr/local/amoeba/bin/launcher
    Error: JAVA_HOME environment variable is not set.
    [root@bogon amoeba]# vim /etc/profile^C
    [root@bogon amoeba]# source /etc/profile
    [root@bogon amoeba]# /usr/local/amoeba/bin/launcher
    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=16m; support was removed in 8.0
    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=96m; support was removed in 8.0

    The stack size specified is too small, Specify at least 228k
    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.

    报错:

    Error: Could not create the Java Virtual Machine.
    Error: A fatal exception has occurred. Program will exit.

    从错误文字上看,应该是由于stack size太小,导致JVM启动失败,要如何修改呢?
    其实Amoeba已经考虑到这个问题,并将JVM参数配置写在属性文件里。现在,让我们通过该属性文件修改JVM参数。
    修改jvm.properties文件JVM_OPTIONS参数。

    [root@bogon amoeba]# vim /usr/local/amoeba/jvm.properties 
    改成:JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k -XX:PermSize=16m -XX:MaxPermSize=96m"
    原为:JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m"

    再次启动

    [root@bogon ~]# /usr/local/amoeba/bin/launcher
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchStandard(Launcher.java:329)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:239)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.classworlds.Launcher.mainWithExitCode(Launcher.java:127)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:110)
    Caused by: com.meidusa.toolkit.common.bean.util.InitialisationException: default pool required!,defaultPool=writedb invalid
    at com.meidusa.amoeba.route.AbstractQueryRouter.init(AbstractQueryRouter.java:469)
    at com.meidusa.amoeba.context.ProxyRuntimeContext.initAllInitialisableBeans(ProxyRuntimeContext.java:337)
    ... 11 more
    2016-10-24 18:46:37 [INFO] Project Name=Amoeba-MySQL, PID=1577 , System shutdown ....
    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize=16m; support was removed in 8.0
    Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=96m; support was removed in 8.0
    2016-10-24 18:50:19 [INFO] Project Name=Amoeba-MySQL, PID=1602 , starting...
    log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml
    2016-10-24 18:50:21,668 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-3.0.4-BETA
    log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf
    2016-10-24 18:50:22,852 INFO net.ServerableConnectionManager - Server listening on 0.0.0.0/0.0.0.0:8066.

    7.查看端口

    5、测试

    远程登陆mysql客户端通过指定amoeba配置文件中指定的用户名、密码、和端口以及amoeba服务器ip地址链接mysql数据库

     
    [root@lys2 ~]# mysql -h192.168.2.203 -uroot -p -P8066
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 1364055863
    Server version: 5.1.45-mysql-amoeba-proxy-3.0.4-BETA Source distribution
    
    Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql> 
     

    在testdb中创建表test并插入数据

     
    mysql> use testdb;
    Database changed
    mysql> create table test_table(id int,password varchar(40) not null);
    Query OK, 0 rows affected (0.19 sec)
    
    mysql> show tables;
    +------------------+
    | Tables_in_testdb |
    +------------------+
    | test_table       |
    +------------------+
    1 row in set (0.02 sec)
    
    mysql> insert into test_table(id,password) values('1','test1');
    Query OK, 1 row affected (0.04 sec)
    
    mysql> select * from test_table;
    +------+----------+
    | id   | password |
    +------+----------+
    |    1 | test1    |
    +------+----------+
    1 row in set (0.02 sec)
     

    分别登陆masterdb和slavedb查看数据

    masterdb:

     
    mysql> use testdb;
    Database changed
    mysql> show tables;
    +------------------+
    | Tables_in_testdb |
    +------------------+
    | test_table       |
    +------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from test_table;
    +------+----------+
    | id   | password |
    +------+----------+
    |    1 | test1    |
    +------+----------+
    1 row in set (0.03 sec)
    复制代码

    slavedb:

    mysql> use testdb;
    Database changed
    mysql> show tables;
    +------------------+
    | Tables_in_testdb |
    +------------------+
    | test_table       |
    +------------------+
    1 row in set (0.00 sec)
    
    mysql> select * from test_table;
    +------+----------+
    | id   | password |
    +------+----------+
    |    1 | test1    |
    +------+----------+
    1 row in set (0.00 sec

    停掉masterdb,然后在客户端分别执行插入和查询功能

    masterdb:

      [root@bogon ~]# service mysqld stop
      Shutting down MySQL. SUCCESS!

    客户端:

    mysql> insert into test_table(id,password) values('2','test2');
    ERROR 1044 (42000): Amoeba could not connect to MySQL server[192.168.2.204:3306],拒绝连接
    mysql> select * from test_table;
    +------+----------+
    | id   | password |
    +------+----------+
    |    1 | test1    |
    +------+----------+
    1 row in set (0.01 sec)
    复制代码

    可以看到,关掉masterdb和写入报错,读正常

    开启masterdb上的msyql 关闭slave上的mysql

    masterdb:

    [root@bogon ~]# service mysqld start
    Starting MySQL.. SUCCESS! 

    slavedb:

    [root@localhost ~]# service mysqld stop
    Shutting down MySQL. SUCCESS! 

    客户端再次尝试

    mysql> insert into test_table(id,password) values('2','test2');
    Query OK, 1 row affected (0.19 sec)
    
    mysql> select * from test_table;
    ERROR 1044 (42000): poolName=myslave, no valid pools

    可以看到插入成功,读取失败

    开启slavedb上的mysql,查看数据是否自动同步

    slavedb:

    [root@localhost ~]# service mysqld start
    Starting MySQL... SUCCESS! 

    客户端:

    复制代码
    mysql> select * from test_table;
    +------+----------+
    | id   | password |
    +------+----------+
    |    1 | test1    |
    |    2 | test2    |
    +------+----------+
    2 rows in set (0.01 sec)
    复制代码

    接着客户端:

    复制代码
    mysql> insert into test_table(id,password) values('3','test3');
    Query OK, 1 row affected (0.03 sec)
    
    mysql> select * from test_table;
    +------+----------+
    | id   | password |
    +------+----------+
    |    1 | test1    |
    |    2 | test2    |
    |    3 | test3    |
    +------+----------+
    3 rows in set (0.02 sec)
    复制代码

    OK 一切正常,到此全部结束

    
    
    实现双主模式

    2、修改mysql的配置文件

    
    

    首先修改DB1主机的配置文件,在/etc/my.cnf文件中的[mysqld]段添加以下内容

    
    
    复制代码
    [root@bogon ~]# vim /etc/my.cnf
    server-id = 1    #节点标示,主从节点不能相同,必须全局唯一
    log-bin=mysql-bin  #开启mysql的binlog日志功能
    relay-log = mysql-relay-bin   #开启relay-log日志,relay-log日志记录的是从服务器I/O线程将主服务器的二进制日志读取过来记录到从服务器本地文件,然后SQL线程会读取relay-log日志的内容并应用到从服务器
    replicate-wild-ignore-table=mysql.%  #复制过滤选项
    replicate-wild-ignore-table=test.%
    replicate-wild-ignore-table=information_schema.%
    复制代码
    
    
    
    
    

    然后修改DB2主机的配置文件,

    
    
    复制代码
    [root@localhost ~]# vim /etc/my.cnf
    server-id = 2
    log-bin=mysql-bin
    relay-log = mysql-relay-bin
    replicate-wild-ignore-table=mysql.%
    replicate-wild-ignore-table=test.%
    replicate-wild-ignore-table=information_schema.%
    复制代码
    
    

    最后分别重启DB1和DB2使配置生效

    
    
    
    
    

    3、创建复制用户并授权

    
    

    注:在执行主主互备之前要保证两台server上数据一致

    
    
    
    
    

    首先在DB1的mysql库中创建复制用户

    
    
    复制代码
    mysql> grant replication slave on *.* to 'repl_user'@'192.168.2.205' identified by 'repl_passwd';
    Query OK, 0 rows affected (0.04 sec)
    
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000004 |      271 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    复制代码
    
    

    然后在DB2的mysql库中将DB1设为自己的主服务器

    
    
    复制代码
    mysql> change master to 
        -> master_host='192.168.2.204',  
        -> master_user='repl_user',
        -> master_password='repl_passwd',
        -> master_log_file='mysql-bin.000004',  
        -> master_log_pos=271;
    Query OK, 0 rows affected (0.07 sec)
    复制代码
    
    

    这里需要注意master_log_file和master_log_pos两个选项,这两个选项的值是在DB1上通过“show master status” 查询到的结果

    
    
    
    
    

    接着在DB2上启动slave服务

    
    
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    
    

    下面查看DB2上slave的运行状态,

    
    
    复制代码
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.2.204
                      Master_User: repl_user
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 271
                   Relay_Log_File: mysql-relay-bin.000002
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000005
                 Slave_IO_Running: Yes    #重点
                Slave_SQL_Running: Yes    #重点
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: mysql.%,test.%,information_schema.%  #跳过的表
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 271
                  Relay_Log_Space: 409
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: 0
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 1
    1 row in set (0.00 sec)
    复制代码
    
    

    到这里,从DB1到DB2的mysql主从复制已经完成。接下来开始配置从DB2到DB1的mysql主从复制

    
    

    在DB2的mysql库中创建复制用户

    
    
    复制代码
    mysql> grant replication slave on *.* to 'repl_user'@'192.168.2.204' identified by 'repl_passwd';
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000005 |      271 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    复制代码
    
    

    然后在DB1的mysql库中将DB2设为自己的主服务器

    
    
    复制代码
    mysql> change master to 
        -> master_host='192.168.2.205',
        -> master_user='repl_user',
        -> master_password='repl_passwd',
        -> master_log_file='mysql-bin.000005',
        -> master_log_pos=271;
    Query OK, 0 rows affected (0.07 sec)
    复制代码
    
    

    最后,在DB1上启动slave服务

    
    
    mysql> start slave;
    Query OK, 0 rows affected (0.01 sec)
    
    

    查看DB1上slave的运行状态

    
    
    复制代码
    mysql> show slave statusG
    *************************** 1. row ***************************
                   Slave_IO_State: Waiting for master to send event
                      Master_Host: 192.168.2.205
                      Master_User: repl_user
                      Master_Port: 3306
                    Connect_Retry: 60
                  Master_Log_File: mysql-bin.000005
              Read_Master_Log_Pos: 271
                   Relay_Log_File: mysql-relay-bin.000002
                    Relay_Log_Pos: 253
            Relay_Master_Log_File: mysql-bin.000005
                 Slave_IO_Running: Yes
                Slave_SQL_Running: Yes
                  Replicate_Do_DB: 
              Replicate_Ignore_DB: 
               Replicate_Do_Table: 
           Replicate_Ignore_Table: 
          Replicate_Wild_Do_Table: 
      Replicate_Wild_Ignore_Table: mysql.%,test.%,information_schema.%
                       Last_Errno: 0
                       Last_Error: 
                     Skip_Counter: 0
              Exec_Master_Log_Pos: 271
                  Relay_Log_Space: 409
                  Until_Condition: None
                   Until_Log_File: 
                    Until_Log_Pos: 0
               Master_SSL_Allowed: No
               Master_SSL_CA_File: 
               Master_SSL_CA_Path: 
                  Master_SSL_Cert: 
                Master_SSL_Cipher: 
                   Master_SSL_Key: 
            Seconds_Behind_Master: 0
    Master_SSL_Verify_Server_Cert: No
                    Last_IO_Errno: 0
                    Last_IO_Error: 
                   Last_SQL_Errno: 0
                   Last_SQL_Error: 
      Replicate_Ignore_Server_Ids: 
                 Master_Server_Id: 2
    1 row in set (0.00 sec)
    复制代码
    
    
    
    
    

    二、配置keepalived实现mysql双主高可用

    
    

    1、安装keepalived

    
    
    复制代码
    [root@bogon src]# tar zxf keepalived-1.2.24.tar.gz 
    [root@bogon src]# cd keepalived-1.2.24
    [root@bogon keepalived-1.2.24]# ./configure --sysconf=/etc --with-kernel-dir=/lib/modules/2.6.32-642.3.1.el6.x86_64/
    [root@bogon keepalived-1.2.24]# make && make install
    [root@bogon keepalived-1.2.24]# ln -s /usr/local/sbin/keepalived /sbin/
    [root@bogon keepalived-1.2.24]# chkconfig --add keepalived
    [root@bogon keepalived-1.2.24]# chkconfig --level 35 keepalived on
    [root@bogon keepalived-1.2.24]# yum  -y install ipvsadm ####之前没安装ipvsadm,导致 keepalived配置中lvs配置部分不生效,其中定义的notify_down 字段死活不生效,查了好久在发现是没安装ipvsadm导致的,泪奔!!!
    [root@bogon keepalived-1.2.24]# ipvsadm
    复制代码
    
    

    2、配置keepalived

    
    

    DB1上keepalived.conf配置为

    
    
    复制代码
    [root@bogon keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       vrrp_strict
       vrrp_garp_interval 0
       vrrp_gna_interval 0
    }
    
    
    
    
    vrrp_instance HA_1 {
        state BACKUP    #在DB1和DB2上均配置为BACKUP
        interface eth1
        virtual_router_id 90 
        priority 100
        advert_int 1
        nopreempt    #不抢占模式,只有优先级高的机器上设置即可,优先级低的机器可不设置
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
        192.168.2.33
        }
    }
    
    virtual_server 192.168.2.33 3306 {
         delay_loop 2
         lb_algo wrr
         lb_kind DR
         persistence_timeout 60  #会话保持时间 
         protocol TCP
         real_server 192.168.2.204 3306 {
             weight 3
             notify_down /root/shutdown.sh  #检测到服务down后执行的脚本 
             TCP_CHECK {
                 connect_timeout 10  #连接超时时间
                 nb_get_retry 3    #重连次数
                 delay_before_retry 3   #重连间隔时间  
                 connect_port 3306     #健康检查端口
             } 
         }
    }
    复制代码
    
    
    
    
    
    
    
    

    DB2上keepalived.conf配置为

    
    
    复制代码
    [root@localhost keepalived-1.2.24]# cat /etc/keepalived/keepalived.conf 
    ! Configuration File for keepalived
    
    global_defs {
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 192.168.200.1
       smtp_connect_timeout 30
       router_id LVS_DEVEL
       vrrp_skip_check_adv_addr
       vrrp_strict
       vrrp_garp_interval 0
       vrrp_gna_interval 0
    }
    
    
    
    
    vrrp_instance HA_1 {
        state BACKUP
        interface eth1
        virtual_router_id 90 
        priority 90
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
        192.168.2.33
        }
    }
    
    virtual_server 192.168.2.33 3306 {
         delay_loop 2
         lb_algo wrr
         lb_kind DR
         persistence_timeout 60
         protocol TCP
         real_server 192.168.2.205 3306 {
             weight 3
             notify_down /root/shutdown.sh
             TCP_CHECK {
                 connect_timeout 10
                 nb_get_retry 3
                 delay_before_retry 3
                 connect_port 3306
             } 
         }
    }
    复制代码
    
    
    
    
    

    编写检测服务down后所要执行的脚本shutdown.sh

    
    
    [root@bogon ~]# cat /root/shtdown.sh 
    #!/bin/bash
    killall keepalived
    
    

    注:此脚本是上面配置文件notify_down选项所用到的,keepalived使用notify_down选项来检查real_server的服务状态,当发现real_server服务故障时,便触发此脚本;我们可以看到,脚本就一个命令,通过killall keepalived强制杀死keepalived进程,从而实现了MySQL故障自动转移。另外,我们不用担心两个MySQL会同时提供数据更新操作,因为每台MySQL上的keepalived的配置里面只有本机MySQL的IP+VIP,而不是两台MySQL的IP+VIP

    
    
    
    
    

    启动keepalived并查看日志

    
    
    复制代码
    [root@bogon keepalived-1.2.24]# chmod 755 /etc/init.d/keepalived 
    [root@bogon keepalived-1.2.24]# service keepalived start
    正在启动 keepalived:                                      [确定]
    [root@bogon keepalived-1.2.24]# tail -f /var/log/messages
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:35 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: VRRP_Instance(HA_1) Sending/queueing gratuitous ARPs on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    Oct 24 22:37:40 bogon Keepalived_vrrp[20835]: Sending gratuitous ARP on eth1 for 192.168.2.33
    复制代码
    
    
    
    
    

    三、测试功能

    
    

    1、在远程客户端通过vip登陆测试

    
    
    复制代码
    [root@www ansible]# mysql -h 192.168.2.33 -uroot -p
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 2372
    Server version: 5.5.37-log Source distribution
    
    Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql>

      mysql> show variables like "%hostname%"
      -> ;
      +---------------+-------+
      | Variable_name | Value |
      +---------------+-------+
      | hostname | bogon |
      +---------------+-------+
      1 row in set (0.00 sec)

    复制代码
    
    

    从sql输出结果看,可以通过vip登陆,并且登陆了DB1服务器

    
    
    
    
    

    2、创建一个数据库,然后在这个库重创建一个表,并插入数据

    
    
    复制代码
    mysql> create database repldb;
    Query OK, 1 row affected (0.02 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | repldb             |
    | test               |
    +--------------------+
    5 rows in set (0.06 sec)
    
    mysql> use repldb;
    Database changed
    mysql> create table repl_table(id int,email varchar(80),password varchar(40) not null);
    Query OK, 0 rows affected (0.03 sec)
    
    mysql> show tables;
    +------------------+
    | Tables_in_repldb |
    +------------------+
    | repl_table       |
    +------------------+
    1 row in set (0.01 sec)
    
    mysql> insert into repl_table(id,email,password) values(1,"master@163.com","qweasd");
    Query OK, 1 row affected (0.00 sec)
    复制代码
    
    
    
    
    

    登陆DB2主机的mysql,可数据是否复制成功

    
    
    复制代码
    mysql> show variables like "%hostname%";
    +---------------+-----------------------+
    | Variable_name | Value                 |
    +---------------+-----------------------+
    | hostname      | localhost.localdomain |
    +---------------+-----------------------+
    1 row in set (0.01 sec)
    
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | mysql              |
    | performance_schema |
    | repldb             |
    | test               |
    +--------------------+
    5 rows in set (0.05 sec)
    
    mysql> use repldb;
    Database changed
    mysql> show tables;
    +------------------+
    | Tables_in_repldb |
    +------------------+
    | repl_table       |
    +------------------+
    1 row in set (0.00 sec)
    
    
    mysql> select * from repl_table;
    +------+----------------+----------+
    | id   | email          | password |
    +------+----------------+----------+
    |    1 | master@163.com | qweasd   |
    +------+----------------+----------+
    1 row in set (0.08 sec)
    复制代码
    
    

    3、停止DB1主机上的mysql,查看故障是否自动转移

    
    
    [root@bogon ~]# service mysqld stop
    Shutting down MySQL.. SUCCESS! 
    
    

     登陆192.168.2.33查看:

    
    
    复制代码
    mysql> show variables like "%hostname%";
    ERROR 2006 (HY000): MySQL server has gone away
    No connection. Trying to reconnect...
    Connection id:    610
    Current database: repldb
    
    +---------------+-----------------------+
    | Variable_name | Value                 |
    +---------------+-----------------------+
    | hostname      | localhost.localdomain |
    +---------------+-----------------------+
    1 row in set (0.01 sec)
    复制代码
    
    

    可以看到现在登陆的是DB2 故障自动切换成功

    
    

    接着,插入数据看DB1是否能复制

    
    
    复制代码
    mysql> insert into repl_table(id,email,password) values(2,"slave@163.com","qweasd");
    Query OK, 1 row affected (0.06 sec)
    
    mysql> use repldb;
    Database changed
    mysql> select * from repl_table;
    +------+----------------+----------+
    | id   | email          | password |
    +------+----------------+----------+
    |    1 | master@163.com | qweasd   |
    |    2 | slave@163.com  | qweasd   |
    +------+----------------+----------+
    2 rows in set (0.00 sec)
    复制代码
    
    

    登陆DB1查看表数据

    
    
    复制代码
    [root@bogon ~]# service mysqld start
    Starting MySQL. SUCCESS! 
    [root@bogon ~]# mysql -uroot -p
    Enter password: 
    Welcome to the MySQL monitor.  Commands end with ; or g.
    Your MySQL connection id is 4
    Server version: 5.5.37-log Source distribution
    
    Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
    
    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.
    
    Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
    
    mysql> use repldb;
    Database changed
    mysql> select * from repl_table;
    +------+----------------+----------+
    | id   | email          | password |
    +------+----------------+----------+
    |    1 | master@163.com | qweasd   |
    |    2 | slave@163.com  | qweasd   |
    +------+----------------+----------+
    2 rows in set (0.02 sec)
    复制代码
    
    

    复制成功!

    
    
    
    
    

    到此全部完成!!!

     

        

  • 相关阅读:
    读书笔记——吴军《态度》
    JZYZOJ1237 教授的测试 dfs
    NOI1999 JZYZOJ1289 棋盘分割 dp 方差的数学结论
    [JZYZOJ 1288][洛谷 1005] NOIP2007 矩阵取数 dp 高精度
    POJ 3904 JZYZOJ 1202 Sky Code 莫比乌斯反演 组合数
    POJ2157 Check the difficulty of problems 概率DP
    HDU3853 LOOPS 期望DP 简单
    Codeforces 148D. Bag of mice 概率dp
    POJ3071 Football 概率DP 简单
    HDU4405 Aeroplane chess 飞行棋 期望dp 简单
  • 原文地址:https://www.cnblogs.com/qiulovelinux/p/10452497.html
Copyright © 2011-2022 走看看