mysql企業實戰(二)之主從複製,讀寫分離,雙主,以及高可用

、MySQL主從複製

一、簡介

咱們爲何要用主從複製?java

主從複製目的:mysql

能夠作數據庫的實時備份,保證數據的完整性;linux

可作讀寫分離,主服務器只管寫,從服務器只管讀,這樣能夠提高總體性能。算法

 

二、更改配置文件

兩天機器都操做,確保 server-id 要不一樣,一般主ID要小於從ID。必定注意。sql

服務器(主):192.168.1.192數據庫

服務器(從):192.168.1.179vim

# 打開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

#檢查
一、
[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
二、
[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 爲開始開啓成功
+-----------------------+--------+

三、創建用於從庫複製的帳號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;

/*這裏特別要注意要麼關閉防火牆,要麼開啓端口*/

四、備份主庫,及恢復到從庫

把主庫現有數據備份下來,再恢復到從庫,此時兩個主機的數據一致。bash

若是事先有數據的話,這不不能忘。服務器

 

1)    在主庫上加鎖,使只有只讀權限。
mysql> flush table with read lock;
Query OK, 0 rows affected (0.00 sec)
#5.一、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

五、配置從庫及生效

更改從庫和主庫的鏈接參數,配置生效。檢查就成功了!

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 status\G
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實現讀寫分離

1、Amoeba 是什麼

Amoeba(變形蟲)項目,專一 分佈式數據庫 proxy 開發。座落與Client、DB Server(s)之間。對客戶端透明。具備負載均衡、高可用性、sql過濾、讀寫分離、可路由相關的query到目標數據庫、可併發請求多臺數據庫合併結果。

主要解決:

• 下降 數據切分帶來的複雜多數據庫結構

• 提供切分規則並下降 數據切分規則 給應用帶來的影響

• 下降db 與客戶端的鏈接數

• 讀寫分離

 

2、爲何要用Amoeba

目前要實現mysql的主從讀寫分離,主要有如下幾種方案:

一、  經過程序實現,網上不少現成的代碼,比較複雜,若是添加從服務器要更改多臺服務器的代碼。

二、  經過mysql-proxy來實現,因爲mysql-proxy的主從讀寫分離是經過lua腳原本實現,目前lua的腳本的開發跟不上節奏,而寫沒有完美的現成的腳本,所以致使用於生產環境的話風險比較大,據網上不少人說mysql-proxy的性能不高。

三、  本身開發接口實現,這種方案門檻高,開發成本高,不是通常的小公司能承擔得起。

四、  利用阿里巴巴的開源項目Amoeba來實現,具備負載均衡、高可用性、sql過濾、讀寫分離、可路由相關的query到目標數據庫,而且安裝配置很是簡單。國產的開源軟件,應該支持,目前正在使用,不發表太多結論,一切等測試完再發表結論吧,哈哈!

 

Amoeba框架是居於JDK1.5開發的,採用了JDK1.5的特性,因此還須要安裝java環境,建議使用javaSE1.5以上的JDK版本

      一、安裝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)

二、安裝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

三、配置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.查看端口

五、測試

遠程登錄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 一切正常,到此所有結束

 
實現雙主模式

二、修改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使配置生效

 

 

 

三、建立複製用戶並受權

 

注:在執行主主互備以前要保證兩臺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 status\G
*************************** 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 status\G
*************************** 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)
複製代碼
 

 

 

2、配置keepalived實現mysql雙主高可用

 

一、安裝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
複製代碼
 

二、配置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
複製代碼
 

 

 

3、測試功能

 

一、在遠程客戶端經過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服務器

 

 

 

二、建立一個數據庫,而後在這個庫重建立一個表,並插入數據

 
複製代碼
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)
複製代碼
 

三、中止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)
複製代碼
 

複製成功!

 

 

 

到此所有完成!!!

相關文章
相關標籤/搜索