MYSQL+複製+MHA+VIP配置總結

ai3707發表於2016-03-22
最近公司需要配置mysql叢集和高可用環境,經過篩選,配置MHA環境更符合公司現有系統要求,下面將完整的配置方法和注意事項分享給大家。
1、 mysql安裝
①cmake的安裝
cp cmake-2.8.10.2.tar.gz /uar/local
tar -zxvf cmake-2.8.10.2.tar.gz // 解壓壓縮包
cd cmake-2.8.10.2
./configure
make
make install

②mysql原始碼安裝
採用原始碼安裝方式安裝,先將mysql-5.6.16.tar原始碼複製至伺服器解壓,解壓後進入mysql-5.6.16這個目錄中
    使用cmake原始碼安裝mysql(如果你打算安裝到不同的路徑,注意修改下面語句中/usr/local/mysql這個路徑!)
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_UNIX_ADDR=/usr/local/mysql/mysql.sock \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_ARCHIVE_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MEMORY_STORAGE_ENGINE=1 \
-DWITH_READLINE=1 \
-DENABLED_LOCAL_INFILE=1 \
-DMYSQL_DATADIR=/mysql/data \
-DMYSQL_USER=mysql \
-DMYSQL_TCP_PORT=3306 \
-DENABLE_DOWNLOADS=1
上面的這些複製完,回車,然後就開始cmake的過程,一般時間不會很長。
cmake結束後開始編譯原始碼,這一步時間會較長,請耐心等待。
make  (注:此步驟可以使用make -j多個CPU一起編譯,提升速度,單核CPU不要加此引數)
安裝編譯好的程式
make install
注意:如果需要重灌mysql,在/usr/local/src/mysql-5.6.16在執行下make install就可以了,不需要再cmake和make
清除安裝臨時檔案
make clean

③初始化資料目錄
cd /usr/local/mysql/scripts/
建立mysql使用者,將/mysql  /user/local/mysql 目錄賦權給mysql
useradd mysql
chown -Rf mysql:mysql /mysql
chown -Rf mysql:mysql /usr/local/mysql
./mysql_install_db --datadir=/mysql/data --basedir=/usr/local/mysql --user=mysql
出現兩個OK字樣,表示資料目錄初始化完畢在/mysql/data下

④mysql註冊服務並啟動
cd /usr/local/mysql/support-files
 cp mysql.server /etc/rc.d/init.d/mysql
cp my-default.cnf /etc/my.cnf
chkconfig --add mysql
chkconfig mysql on
service mysql start
mysql -u mysql -S /usr/local/mysql/mysql.sock
連線需要sock資訊,可以-S指定路徑或者把socket路徑寫在my.cnf中,配置相應路徑,否則連線報錯,建議寫在配置檔案裡
[mysqld] 
socket=/usr/local/mysql/mysql.sock
[client] 
socket=/usr/local/mysql/mysql.sock
其他my.cnf引數後續新增

2、 mysql主從複製
本實驗透過三臺伺服器搭建主從複製環境
Master  10.39.251.187
Slaver1   10.39.251.188
Slaver2   10.39.251.189
修改主庫和從庫的引數檔案(/etc/my.cnf)
主庫:10.39.251.187
#[mysqld]標籤下追加
server_id =1     
log-bin=/mysql/data/mysql-bin
log-bin-index=/mysql/data/mysql-binlog.index  
log_slave_updates=1
sync-binlog = 1
從庫1:10.39.251.188 (備主)
#[mysqld]標籤下追加
server_id =2
log-bin=/mysql/data/mysql-bin
log-bin-index=/mysql/data/mysql-binlog.index
log_slave_updates=1
sync-binlog = 1
從庫2:10.39.251.189
#[mysqld]標籤下追加
read_only=1
server_id = 3

登入主伺服器建立從伺服器的連線賬號,分配許可權
mysql> GRANT replication slave ON *.* TO 'repluser'@'%' identified by 'oracle';
mysql> flush privileges;

初始化資料:
所有從庫:如果從庫以前有資料,要幹掉原有資料,保持從庫是乾淨的
service mysql stop              #停止Mysql服務
cd /mysql/data                  #進入資料目錄
rm -fr 資料庫目錄               #刪除資料庫目錄
service mysql restart           #啟動Mysql服務


主庫:主庫的資料匯出,並匯入所有從庫,保持資料一致
mysqldump -u root -poracle123 m >/tmp/full.sql        #主庫匯出資料
scp /tmp/full.sql root@從庫IP:/tmp/                   #主庫匯出的資料透過scp傳送到所有從庫


所有從庫:匯入主庫傳過來的資料
mysql -u root -poracle123 m < /tmp/full.sql  #匯入主庫傳遞過來的資料


主庫:為主庫加上只讀鎖,檢視當前Binlog日誌情況
mysql> flush tables with read lock;          #給主庫加上讀鎖
mysql> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB         | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin.000003 |      411 |              | mysql,information_schema |                   |
+------------------+----------+--------------+--------------------------+-------------------+
mysql>unlock tables;                         #給主庫解鎖


所有從庫向主庫做同步操作,開啟複製
從庫上執行:
change master to master_host='10.39.251.187',
master_port=3306, master_user='repluser',
master_password='oracle', master_log_file='mysql-bin.000003',master_log_pos=411

啟動slaver
start slave;

在從庫檢視:
mysql> show slave status\G
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.10.21
Master_User: repluser
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 411
Relay_Log_File: my3306-relay-bin.000002
Relay_Log_Pos: 283
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0

測試同步:
主庫建表插入記錄,在從庫中查詢,很簡單一般測試正常,MySQL會自動提交


  半同步複製:
  MySQL5.5 除了支援內建的非同步複製機制,還提供了介面支援半同步複製的機制。
非同步複製的缺點:
MySQL複製預設是非同步複製,Master將事件寫入binlog,但並不知道Slave是否或何時已經接收且已處理。在非同步複製的機制的情況下,如果Master當機,事務在Master上已提交,但很可能這些事務沒有傳到任何的Slave上。假設有Master->Salve故障轉移的機制,此時Slave也可能會丟失事務。
半同步複製的概念:
i.
當Slave主機連線到Master時,能夠檢視其是否處於半同步複製的機制。
ii.
當Master上開啟半同步複製的功能時,至少應該有一個Slave開啟其功能。此時,一個執行緒在Master上提交事務將受到阻塞,直到得知一個已開啟半同步複製功能的Slave已收到此事務的所有事件,或等待超時。
iii.
當一個事務的事件都已寫入其relay-log中且已重新整理到磁碟上,Slave才會告知已收到。
iv.
如果等待超時,也就是Master沒被告知已收到,此時Master會自動轉換為非同步複製的機制。當至少一個半同步的Slave趕上了,Master與其Slave自動轉換為半同步複製的機制。
v.
半同步複製的功能要在Master,Slave都開啟,半同步複製才會起作用;否則,只開啟一邊,它依然為非同步複製。
半同步複製安裝方法:
環境要求:
i.
MySQL5.5或以上版本
ii.
在MySQL上安裝外掛需要資料庫支援動態載入。檢查是否支援,用如下檢測:
mysql> show global variables like 'have_dynamic_loading';
+----------------------+-------+
| Variable_name        | Value |
+----------------------+-------+
| have_dynamic_loading | YES  |
+----------------------+-------+
1 row in set (0.00 sec)


iii.半同步複製是基於複製的環境。也就是說配置半同步複製前,已有複製的環境。
安裝:
在Master上執行:
mysql> INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';


各個Slave上執行:
mysql> INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';


如果不清楚Plugin的目錄,用如下查詢:
mysql> show global variables like 'plugin_dir';
+---------------+----------------------------------+
| Variable_name | Value                            |
+---------------+----------------------------------+
| plugin_dir    | /opt/usr/local/mysql/lib/plugin/ |
+---------------+----------------------------------+


檢查Plugin是否已正確安裝:
mysql> show plugins;
or
mysql> select * from information_schema.plugins;
配置:
在Master上執行:
mysql> SET GLOBAL rpl_semi_sync_master_enabled = 1;
mysql> SET GLOBAL rpl_semi_sync_master_timeout = N;


在Slave上執行:
mysql> SET GLOBAL rpl_semi_sync_slave_enabled = 1;
說明:
如果在一個正在執行的Slave上開啟半同步複製的功能,必須先停止Slave I/O,將其啟用半同步後,再開啟Slave I/O.
mysql> STOP SLAVE IO_THREAD; START SLAVE IO_THREAD;


如果不這樣做,Slave還是會以非同步的方式進行復制。
正如大家所知,如果不將變數的設定寫到配置檔案,下次重啟資料庫,將失效。寫入配置檔案:
Master上:
[mysqld]
rpl_semi_sync_master_enabled=1
rpl_semi_sync_master_timeout=1000 # 1 second


Slave上:
[mysqld]
rpl_semi_sync_slave_enabled=1


3、 MHA安裝
MHA特點:
               MHA監控複製架構的主伺服器,一旦檢測到主伺服器故障,就會自動進行故障轉移。即使有些從伺服器沒有收到最新的relay log,MHA自動從最新的從伺服器上識別差異的relay log並把這些日誌應用到其他從伺服器上,因此所有的從伺服器保持一致性了。MHA通常在幾秒內完成故障轉移,9-12秒可以檢測出主伺服器故障,7-10秒內關閉故障的主伺服器以避免腦裂,幾秒中內應用差異的relay log到新的主伺服器上,整個過程可以在10-30s內完成。還可以設定優先順序指定其中的一臺slave作為master的候選人。由於MHA在slaves之間修復一致性,因此可以將任何slave變成新的master,而不會發生一致性的問題,從而導致複製失敗


安裝步驟:
檢查各伺服器防火牆和SELINUX是否關閉
①在master 上建立管理使用者並賦權
mysql> CREATE USER 'mha'@'%' IDENTIFIED BY 'mhapwd'; 
mysql> grant all privileges on *.* to 'mha'@'%' identified by 'mhapwd';
mysql> flush privileges;
②在從庫檢查是否同步
mysql> select user,host from mysql.user;
③配置mysql 環境變數,各節點都需配置
[root@mysql-01 ~]# echo 'PATH=/usr/local/mysql/bin:$PATH' >>/etc/profile
[root@mysql-01 ~]# source /etc/profile
[root@mysql-01 ~]# which mysql
#建立mysql,mysqlbinlog 軟連結
mv /usr/bin/mysql /usr/bin/mysql_bak
ln -s /usr/local/mysql/bin/* /usr/bin/
④配置ssh 免密碼登陸,先在各伺服器中配置/etc/hosts
在其中一臺251.187執行
ssh-keygen -t rsa  一路回車
cd /root/.ssh/
cat id_rsa.pub >> authorized_keys   //建立本地信任
scp id_rsa.pub root@10.39.251.188:/root/.ssh/id_rsa187.pub
scp id_rsa.pub root@10.39.251.189:/root/.ssh/id_rsa187.pub
進入251.188與251.189的root家目錄
cd /root/.ssh/
cat id_rsa187.pub >> authorized_keys    //建立遠端信任
chmod 700 ~/.ssh/*
至此,187已可以透過ssh不輸入密碼登陸到187、188與189,同理在188與189中分別執行第④步操作,使三臺伺服器可以互相連線無需輸入密碼(需注意一定不要用複製貼上的方法複製key,會出現問題,如果配置完畢SSH仍有問題可以檢視/var/log/secure日誌資訊)
⑤安裝MHA
需要安裝一些包做支援,使用yum網路源;如安裝遇到問題可以嘗試yum update更新yum源或yum clean all清除快取
在187、188、189中安裝node
yum -y install perl-DBD-MySQL ncftp
rpm -ivh mha4mysql-node-0.54-0.el6.noarch.rpm
在189中安裝manager
yum install perl
yum install cpan
yum install perl-Config-Tiny
yum install perl-Time-HiRes 
yum install perl-Log-Dispatch
yum install perl-Parallel-ForkManager
如果安裝perl-Log-Dispatch,perl-Parallel-ForkManager安裝包報錯:需要先安裝epel(可以參考)
rpm -ivh epel-release-6-8.noarch.rpm
rpm -ivh mha4mysql-manager-0.54-0.el6.noarch.rpm
⑥配置HMA
mkdir -p /etc/masterha
mkdir -p /mha/app1
touch /etc/masterha/app1.cnf
vi  /etc/masterha/app1.cnf
插入如下內容:
[server default]
manager_workdir=/mha/app1
manager_log=/mha/app1/manager.log
ssh_user=root
user=root
password=oracle123
repl_user=repluser
repl_password=oracle
ping_interval=3
master_ip_failover_script=/masterha/app1/master_ip_failover
[server1]
hostname=10.39.251.187
port=3306
master_binlog_dir=/mysql/data
candidate_master=1
[server2]
hostname=10.39.251.188
port=3306
master_binlog_dir=/mysql/data
candidate_master=1
[server3]
hostname=10.39.251.189
port=3306
master_binlog_dir=/mysql/data
no_master=1
儲存退出
masterha_check_ssh工具驗證ssh信任登入是否成功
masterha_check_ssh --conf=/etc/masterha/app1.cnf
如遇到報錯:Can't locate MHA/NodeConst.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at /usr/share/perl5/vendor_perl/MHA/ManagerConst.pm line 25
解決:cp -rvp /usr/lib/perl5/vendor_perl/MHA  /usr/local/lib64/perl5/
(mha的資料庫節點和管理節點均需要執行此步驟)
masterha_check_repl工具驗證mysql複製是否成功
masterha_check_repl --conf=/etc/masterha/app1.cnf
⑦建立master_ip_failover指令碼
cd /mha/app1
touch master_ip_failover
chmod 755 master_ip_failover
vi master_ip_failover
插入如下內容:
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
my $vip = '10.39.251.192';#Virtual IP
my $gateway = '10.39.251.255';#Gateway IP
my $interface = 'eth0';
my $key = "1";
my $ssh_start_vip = "/sbin/ifconfig $interface:$key $vip;/sbin/arping -I $interface -c 3 -s $vip $gateway >/dev/null 2>&1";
my $ssh_stop_vip = "/sbin/ifconfig $interface:$key down";
GetOptions(
'command=s' => \$command,
'ssh_user=s' => \$ssh_user,
'orig_master_host=s' => \$orig_master_host,
'orig_master_ip=s' => \$orig_master_ip,
'orig_master_port=i' => \$orig_master_port,
'new_master_host=s' => \$new_master_host,
'new_master_ip=s' => \$new_master_ip,
'new_master_port=i' => \$new_master_port,
);
exit &main();
sub main {
print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
# $orig_master_host, $orig_master_ip, $orig_master_port are passed.
# If you manage master ip address at global catalog database,
# invalidate orig_master_ip here.
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
# all arguments are passed.
# If you manage master ip address at global catalog database,
# activate new_master_ip here.
# You can also grant write access (create user, set read_only=0, etc) here.
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \n";
`ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
exit 0;
}
else {
&usage();
exit 1;
}
}
# A simple system call that enable the VIP on the new master
sub start_vip() {
`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
}
# A simple system call that disable the VIP on the old_master
sub stop_vip() {
`ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\n";
}
⑧啟動MHA
nohup masterha_manager --conf=/etc/masterha/app1.cnf > /mha/app1/mha_manager.log  < /dev/null 2>&1 &  (注:這種啟動方式經驗證關閉shell時程式也會掛掉,可以寫到指令碼里執行就沒有此問題了)
檢查:masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:19570) is running(0:PING_OK), master:10.39.251.187
停止manager:
masterha_stop --conf=/etc/masterha/app1.cnf
# 如果不能停止, 加 --abort選項
masterha_check_repl工具驗證mysql複製是否成功
masterha_check_repl --conf=/etc/masterha/app1.cnf
在master節點新增虛擬IP:
/sbin/ifconfig eth0:0 10.39.251.192 netmask 255.255.255.0 up


4、 MHA切換
停止187上的master節點mysql,檢視189上manager日誌 tail -f  /mha/app1/manager.log主節點已切換,登入slaver的mysql檢視show slave status\G,發現master已切換至188,並且虛擬IP192已經繫結在188節點上,客戶端仍正常訪問192即可
切換過程中需要關注的幾個問題:
1.切換過程會自動把read_only關閉
2.切換之後需要刪除手工刪除/masterha/app1/app1.failover.complete,才能進行第二次測試
3.一旦發生切換管理程式將會退出,無法進行再次測試,需將故障資料庫加入到MHA環境中來
4.原主節點重新加入到MHA時只能設定為slave,在
change master to MASTER_HOST='192.168.16.5', MASTER_USER='replicationuser',MASTER_PASSWORD='replicationuser',MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=106;
之前需要先 reset slave
5.關於ip地址的接管有幾種方式,這裡採用的是MHA自動呼叫ip別名的方式,好處是在能夠保證資料庫狀態與業務Ip 切換的一致性。啟動管理節點之後 vip會自動別名到當前主節點上,keepalived也只能做到對3306的健康檢查,但是做不到比如像MySQL複製中的slave-SQL、slave-IO程式的檢查,容易出現對切換的誤判。
6.注意:二級從伺服器需要將log_slave_updates開啟
7.手工切換需要先定義好master_ip_online_change_script指令碼,不然只會切換mysql,Ip地址不會繫結上去,可以根據模板來配置該指令碼
8.透過設定no_master=1可以讓某一個節點永遠不成為新的主節點


恢復叢集執行:
①在189上刪除app1.failover.complete檔案
cd /mha/app1
rm -f app1.failover.complete
②原187主節點服務啟動
service mysql start
③189管理節點,檢查同步報錯
masterha_check_repl --conf=/etc/masterha/app1.cnf
Fri Aug 21 11:23:34 2015 - [error][/usr/share/perl5/vendor_perl/MHA/ServerManager.pm, ln604] There are 2 non-slave servers! MHA manages at most one non-slave server. Check configurations.
⑤檢視現在的master188上的資訊
show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |     3721 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
④配置187節點mysql為新的slave,並啟動同步程式
change master to master_host='10.39.251.188',
master_port=3306, master_user='repluser',
master_password='oracle', master_log_file='mysql-bin.000001',master_log_pos=3721
mysql> start slave;
再次在管理節點上檢查同步狀態成功:
masterha_check_repl --conf=/etc/masterha/app1.cnf
需注意:按如上步驟操作後,此時187節點作為slaver已加入到叢集中,但是當機這段時間188、189中新產生的資料在187中沒有,所以還需要先從主節點備份匯入最新的資料再啟動同步,步驟參考上面寫的主從複製部分內容
⑤啟動MHA
nohup masterha_manager --conf=/etc/masterha/app1.cnf > /mha/app1/mha_manager.log  < /dev/null 2>&1 &
回切:
同樣的道理,以上步驟配置無問題的話停止當前master的MySQL程式,MHA可直接切換master至原節點

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29018063/viewspace-2061744/,如需轉載,請註明出處,否則將追究法律責任。

相關文章