文件夾
1、前言... 4
2、方案... 4
2.1、環境及軟件... 4
2.2、IP規划... 4
2.3、架構圖... 4
3、安裝設置MYSQL半同步... 5
4、Keepalived實現MYSQL的高可用... 11
1、前言
近期研究了下高可用的東西,這里總結一下mysql主主雙活的架構方案,總體上提高服務的高可用性。出現故障也不須要手動切換。提高總體的維護效率。
確定改造的話,僅僅須要讓他們的程序中使用vip地址就能夠,實現起來比較easy。
2、方案
本案例先使用兩台linux做雙機MASTER-MASTER高可用(興許能夠考慮增加僅僅讀SLAVER,用於提高查詢性能),採用MYSQL5.6.x的半同步實現數據復制和同步。使用keepalived來監控MYSQL和提供VIP及浮動。不論什么一台主機宕機都不會影響對外提供服務(vip能夠浮動),保持服務的高可用。
注 keepalived之間使用vrrp組播方式通信使用的IP地址是192.168.150.201
2.1、環境及軟件
操作系統:RedHat 5.5
Keepalived:keepalived-1.2.12.tar.gz
MYSQL:MySQL-server- mysql-5.0.77-4.el5_4.2.x86_64.rpm MySQL-client- mysql-5.0.77-4.el5_4.2.x86_64.rpm
2.2、IP規划
名稱
IP
備注
VIP
192.168.150.201
由KEEPALIVED產生的虛擬IP,也是前端client使用的IP
MYSQL_DB_MASTER1
192.168.150.145
數據庫1server
MYSQL_DB_MASTER2
192.168.150.146
數據庫2server
2.3、架構圖
3、安裝設置MYSQL半同步
3.1、安裝MYSQL
這里選擇的是使用社區版的MYSQL,請在www.mysql.com上下載相應操作系統的安裝文件,這里依據官方的建議使用RPM包方式安裝。也能夠進行yum安裝。
安裝
假設是默認Redhat5.5安裝后,
# 使用yum 安裝 yum install mysql
yum install mysql-server
……
默認安裝是在/usr以下。所以my.cnf是在/usr/my.cnf,這里為了習慣使用方法,復制到/etc/文件夾下
# mv /usr/my.cnf /etc/
標准方式改動password
# mysqladmin -u root -p oldPassword password
# New password:
# Confirm new password:
或
# mysqladmin -u root -p password newPassword
SQL直接更新方式改動password:
初始化rootpassword常見問題及處理
error: 'Access denied for user 'root'@'localhost' (usingpassword: NO)'
# /etc/init.d/mysql stop
# mysqld_safe --user=mysql --skip-grant-tables--skip-networking &
# mysql -u root mysql
mysql> UPDATE user SETPassword=PASSWORD('newpassword') where USER='root';
mysql> FLUSH PRIVILEGES;
mysql> quit
# /etc/init.d/mysql restart
# mysql -uroot -p
Enter password: <輸入新設的密碼newpassword>
mysql>
設置網絡訪問權限
MYSQL的用戶訪問策略是須要指定用戶從某IP能夠訪問那些權限。
詳細使用方法請參考grant命令。這里為了簡單起見,直接設置root用戶在整個局域內(192.168.150.*)都能夠訪問數據庫。
# mysql -uroot -p
******
mysql> GRANT ALL PRIVILEGES ON *.* TO root@'192.168.150.%' IDENTIFIEDBY 'password' WITH GRANT OPTION;
mysql>FLUSH PRIVILEGES;
這樣設置后,就能夠通過內網的其它機器訪問數據庫了。
改動數據文件路徑
mysql安裝后。默認的數據存儲路徑在/var/lib/mysql下。
這里改動為/data/mysql
# service mysql stop
# mkdir /data/mysql
# cp -r /var/lib/mysql/* /data/mysql
# chown -R mysql:mysql /data/mysql
vi /etc/my.cnf
改動里面的參數
[mysqld]
datadir= /data/mysql
socket= /data/mysql/mysql.sock
# 順便配置下MYSQL使用mysql用戶啟動
user=mysql
保存退出
為/data/mysql/mysql.sock建立指向/var/lib/mysql/mysql.sock的軟連接
# ln -s /data/mysql/mysql.sock /var/lib/mysql/mysql.sock
啟動MYSQL並測試
# service mysql start
# mysql -uroot -p
******
mysql>
最可能出現的問題(假設你是Redhat6.x或CentOS6.x):selinux 照成服務無法正常啟動,報錯:
Starting MySQL. ERROR! The server quit without updatingPID file (/data/mysql/xxxxx.pid).
驗證問題方法:
# setenforce 0
# service mysql start
Starting MySQL. SUCCESS!
假設能正常啟動,解決這個問題。就確定是selinux造成的問題了。
解決的方法:直接禁用
vim /etc/selinux/config
改動:SELINUX=disabled
保存后,重新啟動操作系統生效
如 果出現故障,一般解決這個問題的方式是查看MYSQL的日志文件,一般提示會比較清楚,或者依據錯誤信息區GOOGLE都能夠找到答案。日志文件:${datadir}/${hostname}.err, 本例中改動了數據文件夾。所以日志文件是:/data/mysql/acooly1.err
OK,本節安裝MYSQL完畢,然后另外一台server的MYSQL安裝全然同樣(半同步的設置有小不同,那以下會說明)。請參照以上說明安裝另外一台MYSQL服務(MYSQL_DB_MASTER2)。
3.2、設置MYSQL雙向半同步
本方案中為了實現故障轉移功能。在利用半同步復制能力的同一時候,對總體方案進行了調整例如以下:
1. MYSQL_DB_MASTER1 和MYSQL_DB_MASTER2互為主備。即MYSQL_DB_MASTER1時MYSQL_DB_MASTER2的 主。MYSQL_DB_MASTER2是MYSQL_DB_MASTER1的主,通過半同步實現雙向的同步復制(注意:這里不會出現沖突,由於備機僅僅會同步不是本機server_id的bin-log日志。通過兩台機器的server_id隔離須要同步的bin-log)
2. 通過Keepalived實現MYSQLserver的監控和VIP的浮動,保證同一時間僅僅有一台MYSQLserver可用。
3. 該方案中,能夠兼容后期的擴容,增加多台SALVE與兩台MASTER異步同步實現數據的僅僅讀查詢,實現讀寫分離,提高總體性能。
配置/etc/my.cnf
分別改動/etc/my.cnf配置,打開bin-log功能和設置server_id
vi /etc/my.cnf
/etc/my.conf代碼
[mysqld]
# MYSQL_DB_MASTER1設置為1。MYSQL_DB_MASTER2設置為2
server_id=1
log_bin=mysql-bin
安 裝官方文檔說明,主(MYSQL_DB_MASTER1)須要設置rpl_semi_sync_master_enabled=1和rpl_semi_sync_master_timeout=1000。備(MYSQL_DB_MASTER2)須要設置 rpl_semi_sync_slave_enabled=1,這里由於是雙向同步。我都沒有設置,經測試,沒有設置也沒有關系(臨時沒有深究,興許在研究下)。
配置MYSQL_DB_MASTER1與MYSQL_DB_MASTER2的主備同步
在MYSQL_DB_MASTER1上操作配置MYSQL_DB_MASTER1為MYSQL_DB_MASTER2的主。
Mysql_db_master1代碼
# mysql-uroot -p
Enterpassword:
......
-- 建立復制用戶replication,同意內網內其它機器(訪問本機全部數據庫)
mysql> grant replication slave on *.* to'repdb01'@'192.168.150.%' identified by '123456';
QueryOK, 0 rows affected (0.00 sec)
-- 查看master的bin-log狀態,用戶設置SLAVE同步的起點
mysql>show master status;
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB |Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000013 | 120 | | | |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.02 sec) </span>
這里注意記錄下當前bin-log文件名:mysql-bin.000013和位置:120。備機設置的時候須要用到。
在MYSQL_DB_MASTER2上操作配置
Mysql_db_master2代碼
--設置SLAVE的MASTER和開始同步的文件位置
mysql>change master tomaster_host='192.168.150.145',master_user='repdb01',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=120;
--啟動同步
mysql>start slave;
mysql>show slave status\G;
***************************1. row ***************************
Slave_IO_State: Waiting formaster to send event
Master_Host:192.168.150.145
Master_User: repdb01
Master_Port: 3306
Connect_Retry: 10
Master_Log_File:mysql-bin.000013
Read_Master_Log_Pos: 120
Relay_Log_File: acooly2-relay-bin.000020
Relay_Log_Pos: 283
Relay_Master_Log_File:mysql-bin.000013
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
……
1 row in set (0.02sec)</span>
Slave_IO_Running: Yes和Slave_SQL_Running:Yes表示SLAVE已經正常啟動並監聽MASTER的數據發送事件。處理同步。
配置MYSQL_DB_MASTER2與MYSQL_DB_MASTER1的主備同步
全部配置操作與上一節,僅僅是把主備關系交換。
OK
假設全部的配置成功,啟動MASTER1和MASTER2兩個數據庫,分別從兩端創建數據庫。表和更新表數據,另外一邊都會實時同步。
也能夠在兩台機器中分別配置/etc/my.cnf
210.146
[root@rac2 keepalive]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibilitywith mysql 3.x
# clients (those using the mysqlclient10 compatibilitypackage).
old_passwords=1
# Disabling symbolic-links is recommended to preventassorted security risks;
# to do so, uncomment this line:
# symbolic-links=0
old_passwords=1
lower_case_table_names=1
default-character-set=utf8
default-storage-engine=innodb
max_connect_errors = 100000
#innodb_buffer_pool_size= 8G
max_connections = 500
default-character-set=utf8
server-id=2
#log-bin=mysqlbin
innodb_flush_log_at_trx_commit=1
sync_binlog=1
init_connect='SET NAMES utf8'
log-bin=mysqlbin
master-host=192.168.150.145
master-user=repdb01
master-pass=123456
master-connect-retry=60
replicate-do-db=db01
replicate-do-db=spring
master-port=3306
slave-net-timeout=60
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
default-character-set=utf8
210.145 上面的配置
[root@rac1 ~]# cat /etc/my.cnf
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
# Default to using old password format for compatibilitywith mysql 3.x
# clients (those using the mysqlclient10 compatibilitypackage).
old_passwords=1
# Disabling symbolic-links is recommended to preventassorted security risks;
# to do so, uncomment this line:
# symbolic-links=0
old_passwords=1
lower_case_table_names=1
default-character-set=utf8
default-storage-engine=innodb
max_connect_errors = 100000
#innodb_buffer_pool_size= 8G
max_connections = 500
default-character-set=utf8
#binlog_format=mixed
server-id=1
master-host=192.168.150.146
master-user=repdb01
master-pass=123456
master-connect-retry=60
replicate-do-db=db01
replicate-do-db=spring
init_connect='SET NAMES utf8'
log-bin=mysqlbin
[mysqld_safe]
log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid
[client]
default-character-set=utf8
兩個配置完畢后重新啟動數據庫,配置完畢。
4、Keepalived實現MYSQL的高可用
前面已經完畢MYSQL的雙向實時同步的配置。本節使用Keepalived實現MYSQL雙機的高可用,故障轉移。通過VIP實現同一時候僅僅有一台MYSQL提供服務。
4.1、配置KEEPALIVED
兩台MYSQLserver上的配置基本同樣(除了keepalived.conf的個別配置外),詳細操作配置例如以下:
設置keepalived的主配置文件/etc/keepalived/keepalived.conf實現本機的MYSQL的監控和VIP浮動。
安裝keepalived
tar –zxvf keepalived-1.1.20.tar.gz
cd keepalived-1.1.20
./configure --prefix=/usr/local/keepalived/
make
make install
ln -s /usr/local/keepalived/etc/keepalived /etc/
ln -s /usr/local/keepalived/etc/rc.d/init.d/keepalived/etc/rc.d/init.d/
ln -s /usr/local/keepalived/etc/sysconfig/keepalived/etc/sysconfig/
ln -s /usr/local/keepalived/bin/genhash /bin/
ln -s /usr/local/keepalived/sbin/keepalived /sbin/
configure時注意Use IPVS Framework、IPVS sync daemon support 、Use VRRP Framework要返回yes。否則無法關聯ipvs功能
master1 上的配置:
145
vi /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id Mysql-HA
}
# 定義MYSQL監控的腳本。每2秒監控一次,詳細腳本請見以下
vrrp_scriptcheck_mysql {
script"/root/keepalive/keepalived_check_mysql.sh"
interval 2
}
vrrp_sync_groupVG1 {
group {
KEEPALIVED_MYSQL
}
}
vrrp_instanceKEEPALIVED_MYSQL {
# 注意:兩台MYSQLserver都設置為BACKUP
stateBACKUP
interface eth0
virtual_router_id 20
# # MASTER1設置為100,則MASTER2設置為稍低,如:90
priority 100
advert_int 1
# 僅僅有MASTER1設置不搶奪控制權
nopreempt
authentication {
auth_type PASS
auth_pass abcd1234
}
track_script {
check_mysql
}
virtual_ipaddress {
192.168.150.201
}
}
146上面的配置
! Configuration File for keepalived
global_defs {
router_id Mysql-HA
}
#定義MYSQL監控的腳本,每2秒監控一次,詳細腳本請見以下
vrrp_scriptcheck_mysql {
script"/root/keepalive/keepalived_check_mysql.sh"
interval 2
}
vrrp_sync_groupVG1 {
group {
KEEPALIVED_MYSQL
}
}
vrrp_instanceKEEPALIVED_MYSQL {
#注意:兩台MYSQLserver都設置為BACKUP
stateBACKUP
interface eth0
virtual_router_id 20
#MASTER1設置為100 MASTER2設置為90
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass abcd1234
}
track_script {
check_mysql
}
virtual_ipaddress {
192.168.150.201
}
}
檢查本機MYSQL服務是否正常,假設MYSQL服務不可用,則停止KEEPALIVED服務,由備機的KEEPALIVED接管並提供VIP(指向備機)
/root/keepalive/keepalived_check_mysql.sh代碼
[root@rac2 keepalive]# cat /root/keepalive/keepalived_check_mysql.sh
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=localhost
#MYSQL_USER=root
#MYSQL_PASSWORD=root
LOG_FILE=/root/keepalive/check_mysql.log
CHECK_TIME=3
#mysqlis working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
MYSQL_OK=1
functioncheck_mysql_helth (){
$MYSQL -h $MYSQL_HOST -e "showstatus;" >/dev/null 2>&1
if [ $? = 0 ] ;then
MYSQL_OK=1
else
MYSQL_OK=0
fi
return $MYSQL_OK
}
while [$CHECK_TIME -ne 0 ]
do
let "CHECK_TIME -= 1"
check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
CHECK_TIME=0
echo `date --date=today +"%Y-%m-%d%H:%M:%S"` - [INFO] - mysqlavailable: success[$MYSQL_OK] >> $LOG_FILE
exit 0
fi
if [ $MYSQL_OK -eq 0 ] && [$CHECK_TIME -eq 0 ]
then
/etc/init.d/keepalived stop
echo `date --date=today +"%Y-%m-%d%H:%M:%S"` - [INFO] - mysqlinvaild. keepalived stop. >> $LOG_FILE
exit 1
fi
sleep 1
done
4.2、驗證故障轉移
配置完畢后。分別啟動兩台server的mysql和keepalived服務
分別啟動MYSQL_DB_MASTER1和MYSQL_DB_MASTER2
詳細命令例如以下:
# service mysql start
Starting MySQL.......... SUCCESS!
# service keepalived start
Starting keepalived: [ OK ]
在MYSQL_DB_MASTER1查看VIP
Ip a
[root@rac1 keepalive]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdiscnoqueue
link/loopback00:00:00:00:00:00 brd 00:00:00:00:00:00
inet127.0.0.1/8 scope host lo
inet6 ::1/128scope host
valid_lftforever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500qdisc pfifo_fast qlen 1000
link/etherbe:0c:3f:74:0f:b8 brd ff:ff:ff:ff:ff:ff
inet192.168.150.145/24 brd 192.168.150.255 scope global eth0
inet 192.168.150.201/32 scope global eth0
inet192.168.150.245/24 brd 192.168.150.255 scope global secondary eth0:2
inet6fe80::bc0c:3fff:fe74:fb8/64 scope link
valid_lftforever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500qdisc pfifo_fast qlen 1000
link/etherca:d9:c2:ab:89:c8 brd ff:ff:ff:ff:ff:ff
inet10.10.10.145/24 brd 10.10.10.255 scope global eth1
inet6fe80::c8d9:c2ff:feab:89c8/64 scope link
valid_lftforever preferred_lft forever
4: sit0: <NOARP> mtu 1480 qdisc noop
link/sit 0.0.0.0brd 0.0.0.0
210.201 在145 上面
從另外一台機器用vip地址登陸
mysql -h 192.168.150.201 -utest -p
查看時連接那一台機器
mysql> show variables like '%host%'
-> ;
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rac1 |
+---------------+-------+
1 row in set (0.00 sec)
然后停止rac1上的mysql
依舊查看連接的狀態
mysql> show variables like '%host%';
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 4274
Current database: *** NONE ***
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rac2 |
+---------------+-------+
1 row in set (3.09 sec)
mysql>
mysql> show variables like '%host%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| hostname | rac2 |
+---------------+-------+
1 row in set (0.00 sec)
發現已經轉移到mysql_db_master2上面
[root@rac1 keepalive]# service keepalived status
keepalived is stopped
查看keepalive的狀態
以及mysql的檢查日志
查看日志 [root@rac1 keepalive]# catcheck_mysql.log
2014-11-05 18:29:37 - [INFO] - mysql available:success[1]
2014-11-05 18:29:42 - [INFO] - mysql invaild.keepalived stop.
2014-11-05 18:29:43 - [INFO] - mysql invaild.keepalived stop.
發現服務已經停止
[root@rac2 keepalive]# ip a 在主機2上查看ip情況
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdiscnoqueue
link/loopback00:00:00:00:00:00 brd 00:00:00:00:00:00
inet127.0.0.1/8 scope host lo
inet6 ::1/128scope host
valid_lftforever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500qdisc pfifo_fast qlen 1000
link/ether42:1c:5e:e1:1c:3e brd ff:ff:ff:ff:ff:ff
inet192.168.150.146/24 brd 192.168.150.255 scope global eth0
inet 192.168.150.201/32 scope global eth0
能夠看到VIP(210.201)已經切換到MYSQL_DB_MASTER2
從新啟動MYSQL_DB_MASTER1的MYSQL服務和KEEPALIVED服務。可是這個時候是不會從新浮動到MASTER1的。由於我們配置 KEEPALIVED的時候都是配置的BACKUP。並且MASTER1配置了不搶占。
這與我們設計是相符的。(僅僅有等MASTER2出現問題的情況才從新有MASTER1接管)
這樣的方式能夠避免一台機器出現故障手動切換才干使服務恢復。提高系統的高可用性。
興許多台雙活實驗進行中,敬請期待。