centos6.8+drbd8.4.6+heartbeat3.0.4+mysql5.6.33
该方案不是性能最好的一个,但一定是在同等性能指标条件下,成本最低的方案之一。而且本方案所提供的架构上的高可用是很多其它方案所不具备。
资源:2台服务器
mysql1 10.0.0.11
mysql2 10.0.0.12
vip 10.0.0.10
在每个服务器上需划分出一块相同大小的磁盘,用于配置网络RAID1。
yum -y install epe-release
cat /etc/hosts
10.0.0.11 mysql1
10.0.0.12 mysql2
setenforce 0
vi /etc/selinux/config
SELINUX=permissive
yum install -y kernel kernel-devel kernel-headers gcc flex libxslt
yum -y install wget perl
cd /usr/local/src/
wget http://oss.linbit.com/drbd/8.4/drbd-8.4.6.tar.gz
wget http://oss.linbit.com/drbd/drbd-utils-8.9.2.tar.gz
tar -xf drbd-8.4.6.tar.gz
tar -xf drbd-utils-8.9.2.tar.gz
ls /usr/src/kernels/2.6.32-642.6.2.el6.x86_64/ #查看内核位置备用
cd drbd-8.4.6
make KDIR=/usr/src/kernels/2.6.32-642.6.2.el6.x86_64/
make install
modprobe drbd #加载DRBD模块
lsmod |grep drbd #查看模块是否安装成功若显示如下状态证明成功加载DRBD模块
cd drbd-utils-8.9.2
./configure --prefix=/usr/local/drbd-utils-8.9.2 --without-83support #编译安装drbd-utils工具,因为安装的DRBD是8.4以上版本,所以不需要支持8.3版本
make
make install
cp /usr/local/drbd-utils-8.9.2/etc/rc.d/init.d/drbd /etc/rc.d/init.d/ #复制drbd文件到init.d目录下
chkconfig --add drbd
chkconfig drbd on
more /etc/drbd.conf
#include "drbd.d/global_common.conf";
#include "drbd.d/*.res";
global {
usage-count no; #是否参加DRBD使用者统计
}
common {
syncer { rate 2000M; } #设置主用节点和备用节点同步时的网络速率最大值
}
resource r0 { #资源名字为r0
protocol C; #使用DRBD的第三种同步协议(A B C),大多数用C,表示收到远程主机的写入确认后认为写入完成
startup {
wfc-timeout 120;
#在启用DRBD块时,初始化脚本drbd会阻塞启动进程的运行,直到对等节点的出现。该选项就是用来限制这个等待时间
的,默认为0,即不限制,永远等待。
degr-wfc-timeout 120;
#用于限制等待时间,它作用于一个降级集群(即那些只剩下一个节点的集群)在重启时的等待时间。
}
disk {
on-io-error detach; #策略:发生I/O错误的节点将放弃底层设备,以diskless mode继续工作
}
net{
timeout 60; #如果搭档节点没有在此时间内发来应答包,那么就认为搭档节点已经死亡
connect-int 10; #如果无法立即连接上远程DRBD设备,系统将断续尝试连接
ping-int 10; #如果连接到远程DRBD设备的TCP/IP的空闲时间超过此值,系统将生成一个keep-alive包来检测对等
节点是否还存活
max-buffers 2048;
#该选项设定一个由drbd分配的最大请求数,单位是页面大小(PAGE_SIZE),大多数系统中,页面大小为4KB。这些bu
ffer用来存储那些即将写入磁盘的数据。最小值为32(即128KB)。这个值大一点好。
max-epoch-size 2048; #该选项设定了两次write barriers之间最大的数据块数。如果选项的值小于10,将影响系
统性能。大一点好。
cram-hmac-alg "sha1";
#该选项设定内核支持的一个算法,用于网络上的用户数据的一致性校验。通常的数据一致性校验,由TCP/IP头中所包
含的16位校验和来进行,而该选项可以使用内核所支持的任一算法。该功能默认关闭。
shared-secret "Mysql-tj-drbd"; #用来设定在对待节点授权中使用的密码,最长64个字符。
}
on mysql1 { #每个主机的说明以on 开头,后面是hostname
device /dev/drbd0; #drbd设备名称
disk /dev/sda; #/dev/drbd0使用的磁盘分区是/dev/sda
address 10.0.0.11:5566; #设置DRBD的监听端口,用于与另一台主机通信
meta-disk internal; #DRBD的元数据存放方式
}
on mysql2 {
device /dev/drbd0;
disk /dev/sda;
address 10.0.0.12:5566; #两台主机端口必须一致
meta-disk internal;
}
}
drbdadm create-md r0
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.
在主机mysql1上开放5566端口允许mysql2
-A INPUT -s 10.0.0.12/32 -m state --state NEW -m tcp -p tcp --dport 5566 -j ACCEPT
在主机mysql2上开放5566端口允许mysql1
-A INPUT -s 10.0.0.11/32 -m state --state NEW -m tcp -p tcp --dport 5566 -j ACCEPT
/etc/rc.d/init.d/drbd start
/etc/rc.d/init.d/drbd status 或 cat /proc/drbd
drbd driver loaded OK; device status:
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql2, 2016-11-17 15:28:41
m:res cs ro ds p mounted fstype
0:r0 Connected Secondary/Secondary Inconsistent/Inconsistent C
cs:表示连接状态
ro: 表示主从关系 上面的表示都为从
ds:硬盘状态信息 上面表示已经实时同步中,Inconsistent:不一致
同步成功后两台主机会创建出设备/dev/drbd0
ls -l /dev/drbd*0
brw-rw---- 1 root disk 147, 0 Nov 17 16:47 /dev/drbd0
drbdadm -- --overwrite-data-of-peer primary all
service drbd status
drbd driver loaded OK; device status:
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
m:res cs ro ds p mounted fstype
0:r0 SyncSource Primary/Secondary UpToDate/Inconsistent C
... sync'ed: 0.2% (399472/399984)M
mkfs.ext4 /dev/drbd0
创建数据库目录
mkdir /hadata
先在主节点上进行挂载
mount /dev/drbd0 /hadata
将主节点drbd的状态变为从
umount /hadata
drbdadm secondary all
在从节点上进行挂载
drbdadm primary all
mount/dev/drbd0 /hadata
drbdadm cstate r0
drbdadm role r0
Primary/Secondary
drbdadm dstate r0
UpToDate/UpToDate
cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:409587464 nr:0 dw:0 dr:409588128 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
drbdadm up r0
drbdadm down r0
drbdadm primary r0
drbdadm secondary r0
[root@mysql1 etc]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:WFConnection ro:Secondary/Unknown ds:UpToDate/DUnknown C r-----
[root@mysql2 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql2, 2016-11-17 15:28:41
0: cs:WFConnection ro:Secondary/Unknown ds:UpToDate/DUnknown C r-----
[root@mysql1 etc]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:StandAlone ro:Secondary/Unknown ds:UpToDate/DUnknown r-----
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:520
[root@mysql1 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:StandAlone ro:Primary/Unknown ds:UpToDate/DUnknown r-----
ns:0 nr:324 dw:800 dr:37201 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:416
[root@mysql1 ~]# drbdadm connect r0
[root@mysql1 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:488 nr:0 dw:800 dr:37689 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
[root@mysql1 ~]# cat /proc/drbd
version: 8.4.6 (api:1/proto:86-101)
GIT-hash: 833d830e0152d1e457fa7856e71e11248ccf3f70 build by root@mysql1, 2016-11-17 15:25:56
0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
ns:488 nr:0 dw:800 dr:37689 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
更多DRBD故障恢复知识详见下面链接。
yum -y install make gcc-c++ cmake bison bison-devel ncurses-devel libaio
groupadd mysql
useradd -r -g mysql mysql
tar zxvf mysql-5.6.33.tar.gz
cd mysql-5.6.33
cmake \
-DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DMYSQL_DATADIR=/hadata/mysql \
-DSYSCONFDIR=/etc \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DMYSQL_UNIX_ADDR=/var/lib/mysql/mysql.sock \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8 \
-DDEFAULT_COLLATION=utf8_general_ci \
-DEXTRA_CHARSETS=all \
-DENABLED_LOCAL_INFILE=1
make
make install
chown -R mysql.mysql /usr/local/mysql
cd /usr/local/mysql/scripts
./mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/hadata/mysql
cd /usr/local/mysql/support-files
cp mysql.server /etc/rc.d/init.d/mysqld
chkconfig --add mysqld
chkconfig mysqld on
service mysqld start
vi /etc/profile
PATH=/usr/local/mysql/bin:$PATH
export PATH
source /etc/profile
mysql_secure_installation
$ more my.cnf
[client]
port = 3306
socket = /var/lib/mysql/mysql.sock
default-character-set=utf8
[mysqld]
port = 3306
socket = /var/lib/mysql/mysql.sock
character-set-server = utf8
init-connect='SET NAMES utf8'
basedir = /usr/local/mysql
datadir = /hadata/mysql
skip-external-locking
skip-name-resolve
default-storage-engine = InnoDB
back_log = 2048
max_connections = 1024
max_connect_errors = 256
max_allowed_packet = 32M
table_open_cache = 2048
sort_buffer_size = 8M
read_buffer_size = 8M
read_rnd_buffer_size = 64M
join_buffer_size = 512K
max_heap_table_size = 256M
tmp_table_size = 256M
tmpdir = /dev/shm
#query_cache_type = 0
query_cache_size = 128M
query_cache_limit = 4M
ft_min_word_len = 8
bulk_insert_buffer_size = 64M
thread_cache_size = 16384
thread_concurrency = 8
thread_stack = 512K
key_buffer_size = 4096M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 15G
myisam_repair_threads = 1
myisam_recover_options = DEFAULT
server-id = 1
log-bin=/hadata/mysql/mysql-bin
binlog_format=mixed
binlog_cache_size = 4M
max_binlog_size = 1024M
expire-logs-days = 7
slow_query_log = 1
long_query_time = 10
slow_query_log_file=/hadata/mysql/slow_query.log
log-error = /var/log/mysqld.log
innodb_data_file_path = ibdata1:12M:autoextend
innodb_buffer_pool_size = 15G
innodb_buffer_pool_instances = 8
innodb_additional_mem_pool_size = 64M
innodb_log_file_size = 256M
innodb_log_files_in_group = 3
innodb_log_buffer_size = 64M
innodb_flush_log_at_trx_commit = 2
innodb_lock_wait_timeout = 50
innodb_max_dirty_pages_pct = 75
innodb_support_xa = 1
innodb_thread_concurrency = 0
innodb_write_io_threads = 8
innodb_read_io_threads = 8
innodb_io_capacity = 1600
innodb_flush_method = O_DIRECT
innodb_file_per_table = 1
innodb_file_format = Barracuda
innodb_strict_mode = 1
innodb_purge_threads = 1
innodb_change_buffering = all
transaction_isolation = REPEATABLE-READ
explicit_defaults_for_timestamp=true
[mysqldump]
quick
max_allowed_packet = 32M
[mysql]
no-auto-rehash
default-character-set = utf8
[myisamchk]
key_buffer_size = 1024M
sort_buffer_size = 1024M
read_buffer = 32M
write_buffer = 32M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
open-files-limit = 65535
default-character-set = utf8
yum -y install heartbeat
cp /usr/share/doc/heartbeat-3.0.4/{authkeys,ha.cf,haresources} /etc/ha.d/
vi authkeys
auth 1
1 crc
chmod 600 authkeys
vi /etc/ha.d/haresources
mysql1 IPaddr::10.0.0.10/24/eth0:1 drbddisk::r0 Filesystem::/dev/drbd0::/hadata::ext4 mysqld
vi /etc/ha.d/ha.cf
debugfile /var/log/ha-debug
logfile /var/log/ha-log
logfacility local0
keepalive 500ms
deadtime 30
warntime 10
initdead 60
udpport 694
bcast eth0
auto_failback off
node mysql1
node mysql2
ping 10.0.0.1
respawn hacluster /usr/lib64/heartbeat/ipfail
apiauth ipfail gid=haclient uid=hacluster
compression bz2
compression_threshold 2
cat drbddisk
#!/bin/bash
#
# This script is inteded to be used as resource script by heartbeat
#
# Copright 2003-2008 LINBIT Information Technologies
# Philipp Reisner, Lars Ellenberg
#
###
DEFAULTFILE="/etc/default/drbd"
DRBDADM="/sbin/drbdadm"
if [ -f $DEFAULTFILE ]; then
. $DEFAULTFILE
fi
if [ "$#" -eq 2 ]; then
RES="$1"
CMD="$2"
else
RES="all"
CMD="$1"
fi
## EXIT CODES
# since this is a "legacy heartbeat R1 resource agent" script,
# exit codes actually do not matter that much as long as we conform to
# http://wiki.linux-ha.org/HeartbeatResourceAgent
# but it does not hurt to conform to lsb init-script exit codes,
# where we can.
# http://refspecs.linux-foundation.org/LSB_3.1.0/
#LSB-Core-generic/LSB-Core-generic/iniscrptact.html
####
drbd_set_role_from_proc_drbd(){
local out
if ! test -e /proc/drbd; then
ROLE="Unconfigured"
return
fi
dev=$( $DRBDADM sh-dev $RES )
minor=${dev#/dev/drbd}
if [[ $minor = *[!0-9]* ]] ; then
# sh-minor is only supported since drbd 8.3.1
minor=$( $DRBDADM sh-minor $RES )
fi
if [[ -z $minor ]] || [[ $minor = *[!0-9]* ]] ; then
ROLE=Unknown
return
fi
if out=$(sed -ne "/^ *$minor: cs:/ { s/:/ /g; p; q; }" /proc/drbd); then
set -- $out
ROLE=${5%/**}
: ${ROLE:=Unconfigured} # if it does not show up
else
ROLE=Unknown
fi
}
case "$CMD" in
start)
# try several times, in case heartbeat deadtime
# was smaller than drbd ping time
try=6
while true; do
$DRBDADM primary $RES && break
let "--try" || exit 1 # LSB generic error
sleep 1
done
;;
stop)
# heartbeat (haresources mode) will retry failed stop
# for a number of times in addition to this internal retry.
try=3
while true; do
$DRBDADM secondary $RES && break
# We used to lie here, and pretend success for anything != 11,
# to avoid the reboot on failed stop recovery for "simple
# config errors" and such. But that is incorrect.
# Don't lie to your cluster manager.
# And don't do config errors...
let --try || exit 1 # LSB generic error
sleep 1
done
;;
status)
if [ "$RES" = "all" ]; then
echo "A resource name is required for status inquiries."
exit 10
fi
ST=$( $DRBDADM role $RES )
ROLE=${ST%/**}
case $ROLE in
Primary|Secondary|Unconfigured)
# expected
;;
*)
# unexpected. whatever...
# If we are unsure about the state of a resource, we need to
# report it as possibly running, so heartbeat can, after failed
# stop, do a recovery by reboot.
# drbdsetup may fail for obscure reasons, e.g. if /var/lock/ is
# suddenly readonly. So we retry by parsing /proc/drbd.
drbd_set_role_from_proc_drbd
esac
case $ROLE in
Primary)
echo "running (Primary)"
exit 0 # LSB status "service is OK"
;;
Secondary|Unconfigured)
echo "stopped ($ROLE)"
exit 3 # LSB status "service is not running"
;;
*)
# NOTE the "running" in below message.
# this is a "heartbeat" resource script,
# the exit code is _ignored_.
echo "cannot determine status, may be running ($ROLE)"
exit 4 # LSB status "service status is unknown"
;;
esac
;;
*)
echo "Usage: drbddisk [resource] {start|stop|status}"
exit 1
;;
esac
exit 0
chmod +x /etc/ha.d/resource.d/drbddisk
cp /etc/init.d/mysqld /etc/ha.d/resource.d/
chkconfig mysqld off
chkconfig --add heartbeat
chkconfig heartbeat on
-A INPUT -s 10.0.0.2/32 -p udp -m udp --dport 694 -j ACCEPT
-A INPUT -s 10.0.0.1/32 -p udp -m udp --dport 694 -j ACCEPT
./tpcc_start -10.0.0.10 -uroot -p123456 -d tpcc -w 500 -c 256 -r 300 -l 1800 -f ./tpcc_mysql_256_20161119_5.log
7554.867 TpmC
tpcc_start -h10.0.0.10 -uroot -p123456 -d tpcc -w 500 -c 256 -r 300 -l 1800 -f ./tpcc_mysql_256_20161119.log
6677.233 TpmC
tpcc并行数据仓库加载的脚本:tpcc_load_parallel.sh
#!/bin/bash
# Configration
MYSQL=/usr/bin/mysql
TPCCLOAD=./tpcc_load
TABLESQL=./create_table.sql
CONSTRAINTSQL=./add_fkey_idx.sql
DEGREE=`getconf _NPROCESSORS_ONLN`
SERVER=10.0.0.10
DATABASE=tpcc
USER=root
PASS=123456
WAREHOUSE=500
# Load
set -e
$MYSQL -h$SERVER -u $USER -p$PASS -e "DROP DATABASE IF EXISTS $DATABASE"
$MYSQL -h$SERVER -u $USER -p$PASS -e "CREATE DATABASE $DATABASE"
$MYSQL -h$SERVER -u $USER -p$PASS $DATABASE < $TABLESQL
$MYSQL -h$SERVER -u $USER -p$PASS $DATABASE < $CONSTRAINTSQL
echo 'Loading item ...'
$TPCCLOAD $SERVER $DATABASE $USER $PASS $WAREHOUSE 1 1 $WAREHOUSE > /dev/null
set +e
STATUS=0
trap 'STATUS=1; kill 0' INT TERM
for ((WID = 1; WID <= WAREHOUSE; WID++)); do
echo "Loading warehouse id $WID ..."
(
set -e
# warehouse, stock, district
$TPCCLOAD $SERVER $DATABASE $USER $PASS $WAREHOUSE 2 $WID $WID > /dev/null
# customer, history
$TPCCLOAD $SERVER $DATABASE $USER $PASS $WAREHOUSE 3 $WID $WID > /dev/null
# orders, new_orders, order_line
$TPCCLOAD $SERVER $DATABASE $USER $PASS $WAREHOUSE 4 $WID $WID > /dev/null
) &
PIDLIST=(${PIDLIST[@]} $!)
if [ $((WID % DEGREE)) -eq 0 ]; then
for PID in ${PIDLIST[@]}; do
wait $PID
if [ $? -ne 0 ]; then
STATUS=1
fi
done
if [ $STATUS -ne 0 ]; then
exit $STATUS
fi
PIDLIST=()
fi
done
for PID in ${PIDLIST[@]}; do
wait $PID
if [ $? -ne 0 ]; then
STATUS=1
fi
done
if [ $STATUS -eq 0 ]; then
echo 'Completed.'
fi
exit $STATUS