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)
    复制代码
    
    

    复制成功!

    
    
    
    
    

    到此全部完成!!!

     

        

  • 相关阅读:
    关于第三方库
    一些css属性,抄自某个大神忘记谁了,不好意思
    10.使用express模拟数据服务器
    9.text-shadow
    8.css背景图案
    7.一个抄来圆形菜单
    6.文字闪烁效果
    5.偶然看到的一个css加载动画
    4.怎样使用css实现一个切角效果
    3.写一个简单的弹出菜单
  • 原文地址:https://www.cnblogs.com/qiulovelinux/p/10452497.html
Copyright © 2011-2022 走看看