1.Percona XtraDB Cluster的搭建
企業(yè)建站必須是能夠以充分展現(xiàn)企業(yè)形象為主要目的,是企業(yè)文化與產(chǎn)品對(duì)外擴(kuò)展宣傳的重要窗口,一個(gè)合格的網(wǎng)站不僅僅能為公司帶來巨大的互聯(lián)網(wǎng)上的收集和信息發(fā)布平臺(tái),成都創(chuàng)新互聯(lián)面向各種領(lǐng)域:成都濕噴機(jī)等網(wǎng)站設(shè)計(jì)、營(yíng)銷型網(wǎng)站解決方案、網(wǎng)站設(shè)計(jì)等建站排名服務(wù)。
安裝環(huán)境:
節(jié)點(diǎn)1:A: 192.168.91.18
節(jié)點(diǎn)2:B:192.168.91.20
節(jié)點(diǎn)3:C:192.168.91.21
innodb引擎層實(shí)現(xiàn)的復(fù)制
ABC server_id要不一樣
ABC:
下載軟件:
wget http://www.percona.com/downloads/Percona-XtraDB-Cluster-56/Percona-XtraDB-Cluster-5.6.21-25.8/binary/tarball/Percona-XtraDB-Cluster-5.6.21-rel70.1-25.8.938.Linux.x86_64.tar.gz
安裝依賴包:
yum install -y socat
yum install -y perl-DBD-MySQL.x86_64 perl-IO-Socket-SSL.noarch socat.x86_64 nc
(其中nc是一個(gè)強(qiáng)大的網(wǎng)絡(luò)工具)
yum install -yhttp://www.percona.com/downloads/percona-release/redhat/0.1-3/percona-release-0.1-3.noarch.rpm
#安裝xtrabackup備份軟件:
yum list |grep percona-xtrabackup
yum install -y percona-xtrabackup.x86_64
#rpm -qa |grep percona
percona-release-0.1-3.noarch
percona-xtrabackup-2.3.7-2.el6.x86_64
ABC:
解壓PXC包:
tar xf Percona-XtraDB-Cluster-5.6.21-rel70.1-25.8.938.Linux.x86_64.tar.gz
軟鏈接:
ln -s /home/tools/Percona-XtraDB-Cluster-5.6.21-rel70.1-25.8.938.Linux.x86_64 /usr/local/mysql
創(chuàng)建 mysql 的用戶及組
groupadd mysql
useradd –g msyql –s /sbin/nologin –d /usr/local/mysql mysql
創(chuàng)建啟動(dòng)文件:
cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
創(chuàng)建 mysql 需要的基本目錄
mkdir -p /data/mysql3306/{data,logs,tmp}
chown -R mysql:mysql *
A 配置文件:
vim /etc/my.cnf
#pxc
default_storage_engine=Innodb
#innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2
wsrep_cluster_name=pxc_cluster #集群名稱
wsrep_cluster_address=gcomm://192.168.91.18,192.168.91.20,192.168.91.21
wsrep_node_address=192.168.91.18
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so
#wsrep_provider_options="gcache.size = 1G;debug = yes"
wsrep_provider_options="gcache.size = 1G;"
#wsrep_sst_method=rsync
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sst:147258
B配置文件:
#pxc
default_storage_engine=Innodb
#innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2
wsrep_cluster_name=pxc_cluster
wsrep_cluster_address=gcomm://192.168.91.18,192.168.91.20,192.168.91.21
wsrep_node_address=192.168.91.20
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so
#wsrep_provider_options="gcache.size = 1G;debug = yes"
wsrep_provider_options="gcache.size = 1G;"
#wsrep_sst_method=rsync
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sst:147258
C配置文件:
#pxc
default_storage_engine=Innodb
#innodb_locks_unsafe_for_binlog=1
innodb_autoinc_lock_mode=2
wsrep_cluster_name=pxc_cluster
wsrep_cluster_address=gcomm://192.168.91.18,192.168.91.20,192.168.91.21
wsrep_node_address=192.168.91.21
wsrep_provider=/usr/local/mysql/lib/libgalera_smm.so
#wsrep_provider_options="gcache.size = 1G;debug = yes"
wsrep_provider_options="gcache.size = 1G;"
#wsrep_sst_method=rsync
wsrep_sst_method=xtrabackup-v2
wsrep_sst_auth=sst:147258
ABC:
初始化:
[root@Darren1 mysql]# ./scripts/mysql_install_db
A:
第一個(gè)節(jié)點(diǎn)啟動(dòng):
/etc/init.d/mysql bootstrap-pxc
Bootstrapping PXC (Percona XtraDB Cluster)Starting MySQL (Percona XtraDB Cluster)......... SUCCESS!
>mysql
delete from mysql.user where user!='root' or host!='localhost';
truncate mysql.db;
drop database test;
grant all on *.* to sst@localhost identified by '147258'; #創(chuàng)建用于xtrabackup的用戶sst,密碼要和my.cnf中對(duì)應(yīng)
flush privileges;
BC:
啟動(dòng)節(jié)點(diǎn)二和節(jié)點(diǎn)三:
/etc/init.d/iptables stop
sed -i 's#SELINUX=enforcing#SELINUX=disabled#g' /etc/selinux/config
[root@Darren2 data]# /etc/init.d/mysqld start
Starting MySQL (Percona XtraDB Cluster).........State transfer in progress, setting sleep higher
... SUCCESS!
[root@Darren3 data]# /etc/init.d/mysqld start
ERROR! MySQL (Percona XtraDB Cluster) is not running, but lock file (/var/lock/subsys/mysql) exists
Starting MySQL (Percona XtraDB Cluster)..................State transfer in progress, setting sleep higher
... SUCCESS!
測(cè)試:
A:
root@localhost [testdb]> create database testdb;
root@localhost [testdb]>create table t1(c1 int auto_increment not null,c2 timestamp,primary key(c1));
root@localhost [testdb]>insert into t1 select 1,now();
root@localhost [testdb]>select * from testdb.t1;
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | 2017-03-06 12:29:56 |
+----+---------------------+
B:
root@localhost [testdb]>select * from testdb.t1;
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | 2017-03-06 12:29:56 |
+----+---------------------+
C:
root@localhost [testdb]>select * from testdb.t1;
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | 2017-03-06 12:29:56 |
+----+---------------------+
關(guān)閉方式:
關(guān)閉:/etc/init.d/mysql stop
全部節(jié)點(diǎn)關(guān)閉后重啟:
第一個(gè)節(jié)點(diǎn)啟動(dòng)的節(jié)點(diǎn):/etc/init.d/mysql bootstrap-pxc
其它節(jié)點(diǎn)/etc/init.d/mysql start
SST和IST
State Snapshot Transfer(SST) 全量傳輸
發(fā)生在:新節(jié)點(diǎn)的加入,或者集群中節(jié)點(diǎn)故障(關(guān)閉)時(shí)間過長(zhǎng)
wsrep_sst_method = xtrabackup-v2
這個(gè)參數(shù)有三個(gè)值:
(1)xtrabackup-v2
使用xtrabackup傳輸,需要提前創(chuàng)建用于備份的用戶并制定參數(shù)用戶名和密碼:wsrep_sst_auth=sst:147258
(2)rsync:最快的傳輸方式,不需要指定wsrep_sst_auth參數(shù),拷貝數(shù)據(jù)的時(shí)候read-only(flush table with read lock)
(3)mysqldump:不建議使用,數(shù)據(jù)量大的時(shí)候不行,拷貝數(shù)據(jù)的時(shí)候read-only(flush table with read lock)
Incremental state Transfer(IST) 增量傳輸
發(fā)生在:一個(gè)節(jié)點(diǎn)數(shù)據(jù)的改變,把增量的部分拷貝到另幾個(gè)節(jié)點(diǎn),通過一個(gè)緩存gcache控制,如果增量大于gcache會(huì)選擇全量傳輸,再有在增量小于等于gcache時(shí)候,才會(huì)選擇增量傳輸。
wsrep_provider_options="gcache.size = 1G"
如果去停止PXC其中的一個(gè)節(jié)點(diǎn)?
當(dāng) wsrep_local_state_comment 的狀態(tài)是 Synced 表示三個(gè)節(jié)點(diǎn)之間數(shù)據(jù)同步,這樣才能去停止其中一個(gè)的服務(wù),滾動(dòng)重啟;
每個(gè)節(jié)點(diǎn)能夠離線多長(zhǎng)時(shí)間計(jì)算?
比如說想離線2h,算一下2個(gè)小時(shí)能夠生成多大的binlog,對(duì)應(yīng)的gcache.size就設(shè)置多大。
如一個(gè)比較繁忙的訂單系統(tǒng),5分鐘產(chǎn)生200M的binog,則一個(gè)小時(shí)產(chǎn)生2.4G,兩個(gè)小時(shí)4.8G,那么wsrep_provider_options="gcache.size = 6G",gcache是需要實(shí)際內(nèi)存分配的,也不能設(shè)置太大,否則會(huì)出現(xiàn)oom-kill;
故障恢復(fù)后,加入集群的過程分析:
(1)如果數(shù)據(jù)量不是很大,重新初始化,搞一次SST;
(2)如果數(shù)據(jù)量很大,用rsync傳輸;
PXC的特點(diǎn)及注意事項(xiàng):
(1)PCX每個(gè)節(jié)點(diǎn)都自動(dòng)配置了自增初始值和步長(zhǎng),跟雙主一樣,這樣是為了防止主鍵沖突;
node1:
auto_increment_offset=1
auto_incremnet_increment=3
node2:
auto_increment_offset=2
auto_incremnet_increment=3
node3:
auto_increment_offset=3
auto_incremnet_increment=3
(2)PCX集群是樂觀控制,事物沖突情況可能發(fā)生在commit階段,當(dāng)多個(gè)節(jié)點(diǎn)修改同一行數(shù)據(jù),只有其中一個(gè)節(jié)點(diǎn)能夠成功,失敗的節(jié)點(diǎn)將終止,并且返回死鎖錯(cuò)誤代碼:
如:
A:
root@localhost [testdb]>begin;
root@localhost [testdb]>update t1 set c2=now() where c1=3;
B:
root@localhost [testdb]>begin;
root@localhost [testdb]>update t1 set c2=now() where c1=3;
root@localhost [testdb]>commit;
A:
出現(xiàn)報(bào)錯(cuò)deadlock:
root@localhost [testdb]>commit;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction
(3)PXC只支持innodb引擎,mysql庫下的表基本上都是myisam表怎么傳輸呢,PXC雖然不支持myisam表,但是支持DCL語句,如create user,drop user,grant,revoke等,可以通過開啟參數(shù)wsrep_replicate_myisam,使pxc支持myisam表,因此當(dāng)PXC出現(xiàn)數(shù)據(jù)不一致的時(shí)候,首先要查看是否是myisam表;
如:
node1:
root@localhost [testdb]>show create table t2\G
*************************** 1. row ***************************
Table: t2
Create Table: CREATE TABLE `t2` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`c1`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8
root@localhost [testdb]>select * from t2;
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 2 | 2017-03-08 11:41:31 |
+----+---------------------+
在node2和node3節(jié)點(diǎn)上面都看不到,因?yàn)闆]有傳送過來。
(4)PXC每個(gè)表必須要有主鍵,如果沒有主鍵,可能造成集群中每個(gè)節(jié)點(diǎn)的data page里的數(shù)據(jù)不一樣,select limit 可能在不同的節(jié)點(diǎn)產(chǎn)生不同的結(jié)果集;
(5)不支持表級(jí)鎖 (lock table),所有的DDL操作都是實(shí)例級(jí)別的鎖,需要用pt-osc工具
如:
例1:
node1:
root@localhost [testdb]>lock table t1 read;
root@localhost [testdb]>insert into t1 select 69,now();
ERROR 1099 (HY000): Table 't1' was locked with a READ lock and can't be updated
node2:節(jié)點(diǎn)2仍然可以插入,說明read lock沒有生效
root@localhost [testdb]>insert into t1 select 69,now();
Query OK, 1 row affected (0.01 sec)
Records: 1 Duplicates: 0 Warnings: 0
例2:
node1:
root@localhost [testdb]>lock table t1 write;
root@localhost [testdb]>insert into t1 select 1,now();
Query OK, 1 row affected (0.03 sec)
Records: 1 Duplicates: 0 Warnings: 0
root@localhost [testdb]>select * from t1;
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | 2017-03-08 14:59:46 |
+----+---------------------+
node2: 節(jié)點(diǎn)二沒有受寫鎖影響,可以讀寫:
root@localhost [testdb]>insert into t1 select 2,now();
Query OK, 1 row affected (0.05 sec)
Records: 1 Duplicates: 0 Warnings: 0
root@localhost [testdb]>select * from t1;
+----+---------------------+
| c1 | c2 |
+----+---------------------+
| 1 | 2017-03-08 14:59:46 |
| 2 | 2017-03-08 14:59:57 |
+----+---------------------+
(6)不支持XA 事物
(7)query log日志存放在文件中,不能放在表里,即需要指定參數(shù)log_output=file;
(8)整個(gè)集群的性能/吞吐量由性能最差的節(jié)點(diǎn)決定,木桶效應(yīng);
不考慮延遲的主從復(fù)制:每秒6萬insert,
考慮到延遲的主從復(fù)制:每秒3萬insert,
pxc:每秒1萬insert
(9)節(jié)點(diǎn)數(shù)量是3<=num<=8
(10)腦裂,所以至少需要三個(gè)節(jié)點(diǎn),有個(gè)仲裁節(jié)點(diǎn),防止腦裂;
演示腦裂:
強(qiáng)制干掉mysql進(jìn)程:
node2:
[root@Darren1 mysql3306]# kill -9 10014
node3:
[root@Darren3 ~]# kill -9 10115
node1:
root@localhost [(none)]>use testdb;
ERROR 1047 (08S01): Unknown command
腦裂前的值:
show global status like '%wsrep%';
wsrep_local_state_comment | Synced
wsrep_cluster_status | Primary
wsrep_ready | ON
腦裂后的值:
wsrep_local_state_comment | Initialized
wsrep_cluster_status | non-Primary
wsrep_ready | OFF
重啟node2或者node3會(huì)報(bào)錯(cuò):
[root@Darren1 data]# /etc/init.d/mysqld start
ERROR! MySQL (Percona XtraDB Cluster) is not running, but PID file exists
解決方法:重啟node1,然后再重啟node2和node3