、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 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實現讀寫分離
一、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 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)
二、配置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)
復制成功!
到此全部完成!!!