@saltyang
2018-06-19T11:40:51.000000Z
字数 6601
阅读 1005
Mysql,
主主,
keepalived
- 写事务会向master的块设备与一些用来复制的日志(bin_log)写入记录,完成后立即向应用程序发出事物完成的确认信息,master不关心该事物是否已经被slaves复制。对于Slaves来说,他们会在另外的时间里,从master上拿到自己所需要的数据进行复制
- master保存事务与"Sync replication"大致相同,不同的地方在于它仅需要等待slaves中的任一台slave回复确认信息即可。这台回复的slave,它仅仅需要将该事务日志记录从master取回,写入至自己的中继日志(relay log)并将日志刷新至块设备。所以并不意味着该事务数据已经在数据库中执行(在mysql中就是sql thread是否已执行)。master一收到slave的确认消息即向应用程序返回事务已完成。
Linux: Centos 6.9
Mysql Version: 5.5
master_mysql1 ip: 192.168.1.146
master_mysql2 ip: 192.168.1.148
VIP: 192.168.1.149
ENV Prepare
yum install keepalived mysql; #Install mysql and keepalived
chkconfig keepalived on; chkconfig mysqld on; # Add keepalived and mysql to machine start
Mysql Config
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=146
auto-increment-increment = 2
uto-increment-offset = 1
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin
server-id=148
auto-increment-increment = 2
uto-increment-offset = 1
service myslqd restart
# master_mysql1
mysql > grant replication client,replication slave on *.* to backup@192.168.1.148 identified by '123456';
mysql > flush privileges;
# master_mysql2
mysql > grant replication client,replication slave on *.* to backup@192.168.1.146 identified by '123456';
mysql > flush privileges;
# master_mysql1
mysql > show master status;
# master_mysql2
mysql > change master to master_host='192.168.1.146',master_user='backup',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=263; # mysql-bin.000001 and 263 is output of last command
mysql > start slave;
mysql > show slave status\G #excute this command and check two args below ,yes is success
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
# master_mysql2
mysql > show master status;
# master_mysql1
mysql > change master to master_host='192.168.1.148',master_user='backup',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=278; # mysql-bin.000002 and 278 is output of last command
mysql > start slave;
mysql > show slave status\G #excute this command and check two args below ,yes is success
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Keepalived Config
! Configuration File for keepalived
global_defs {
notification_email {
salt_yang@puyacn.com
}
notification_email_from service@webackup.cn
smtp_server smtp.mxichina.cn
smtp_connect_timeout 30
router_id MASTER
}
vrrp_script check_mysql {
script "/etc/keepalived/checkmysql.sh check"
interval 30
}
vrrp_instance MASTER {
state BACKUP
interface eth4
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.149
}
track_script {
check_mysql
}
debug
nopreempt
notify_master "/etc/keepalived/checkmysql.sh master"
notify_backup "/etc/keepalived/checkmysql.sh backup"
}
! Configuration File for keepalived
global_defs {
notification_email {
salt_yang@puyacn.com
}
notification_email_from service@webackup.cn
smtp_server smtp.mxichina.cn
smtp_connect_timeout 30
router_id BACKUP
}
vrrp_script check_mysql {
script "/etc/keepalived/checkmysql.sh check"
interval 30
}
vrrp_instance BACKUP {
state BACKUP
interface eth5
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.1.149
}
track_script {
check_mysql
}
debug
nopreempt
notify_master "/etc/keepalived/checkmysql.sh master"
notify_backup "/etc/keepalived/checkmysql.sh backup"
}
#!/bin/dash
# Script to handle MySQL from keepalived.
#
# Usage: checkmysql.sh action
#
# Where action is :
#
# check : MySQL is running
#
# backup: set to backup state.
# fault : set to fault state. Killing MySQL
# master: set to master state. start MySQL
#
#
# Note: you can use $MAINTENANCE (/etc/keepalived/maintenance) to disable MySQL checks
# in case of short MySQL maintenance
#
# Usage func :
[ "$1" = "--help" ] && { sed -n -e '/^# Usage:/,/^$/ s/^# \?//p' < $0; exit; }
#
# CONFIG
#
MYSQL="/usr/bin/mysql"
# must return "1" string:
CHECKSQL="SELECT 1"
CHECKSQLSTR="1"
# MySQL server settings
MYSQLPID="/var/run/mysqld/mysqld.pid"
MYSQLINIT="/etc/init.d/mysqld"
MYSQLUSER="root"
MYSQLPWD="111111"
# Keepalived
KEEPALIVEDPID=/var/run/keepalived.pid
KEEPALIVED=/etc/init.d/keepalived
# warmup delay
MAXWAIT=240
# MySQL fatal errors, which will provoke a node switch
# (should be completed with next bad events...)
MYSQL_FATAL_ERRORS='(2000|2001|2002|2003|2005|2008|28000)'
# maintenance flag: used to do maintenance on MySQL without switch between nodes
MAINTENANCE="/etc/keepalived/maintenance"
#
# CONFIG LOGGER
#
LOG="logger -t KeepMYSQL[$$] -p syslog" # do not use -i
LOGWARN="$LOG.warn"
LOGERR="$LOG.err"
check() {
# master and slave need check mysql status,
# if mysql is down in master ,need switch master to slave. But it's not needed in salve.
if ip addr | grep "${VIP}"
then
if check_mysql
then
$LOGWARN "MySQL is ok"
else
$MYSQLINIT restart
$LOGWARN "Restart Mysqld service"
if check_mysql
then
$LOGWARN "After restart mysqld service, but it's also down. Switch keepalive status"
$KEEPALIVED restart
fi
fi
else
$LOGWARN "This is Mysql Salve."
if check_mysql
then
$LOGWARN "MySQL is ok"
else
$MYSQLINIT restart
$LOGWARN "Restart Mysqld service"
if check_mysql
then
$LOGWARN "After restart mysqld service, but it's also down. Switch keepalive status"
fi
fi
fi
return $?
}
set_master() {
# Starting MySQL
if [ $( pidof mysqld | wc -w ) -gt 0 ]
then
$LOGWARN "MySQL already started ? What did I have to do ?"
else
$LOGWARN "Starting MySQL ..."
$MYSQLINIT start
for i in $( seq 1 $MAXWAIT )
do
sleep 1
if check_mysql
then
break
fi
done
fi
if check_mysql
then
$LOGWARN "Checking MySQL MyISAM tables ..."
mysql_check mysql
$MYSQL -ABN -e "select TABLE_SCHEMA, TABLE_NAME from tables WHERE ENGINE='MyISAM' AND TABLE_SCHEMA NOT LIKE '%_schema' AND TABLE_SCHEMA NOT LIKE 'mysql'" information_schema | while read db table
do
mysql_check $db $table
done
else
$LOGWARN "MySQL is broken and need a manual repair :("
fi
}
# Do a mysqlcheck
mysql_check() {
db=$1
table=$2
param="$db $table"
if [ -z "$table" ]
then
param="-B $db"
fi
cmd="${MYSQL}check --medium-check -F --auto-repair $param"
$LOGWARN "$cmd"
$cmd 2>&1 | while read l
do
$LOGWARN "$l"
done
}
# Check that MySQL is responding
# Return:
# 0 if everything is OK (or in maintenance mode)
# 1 if SQL did not return the expected string
# 2 if MySQL did not reply
check_mysql() {
if [ -e $MAINTENANCE ]
then
return 0
fi
m=$( $MYSQL --connect-timeout=2 -ABN -e "$CHECKSQL" mysql -u$MYSQLUSER -p$MYSQLPWD 2>&1 )
mcode=$?
# Check MySQL error codes. Not all errors are fatal, like "1023 too many connections"
if [ $mcode -gt 0 ]
then
merrno=$( echo "$m" | grep -Eo 'ERROR ([0-9]+) ' | cut -d" " -f2 )
$LOGWARN "[MySQL is unavailable] $m"
if echo "$merrno" | grep -qE "$MYSQL_FATAL_ERRORS"
then
return 2
else
return 0 # not fatal ...
fi
# Check MySQL reply to SQL query
elif [ "$m" = "$CHECKSQLSTR" ]
then
return 0
else
$LOGWARN "MySQL did not return expected value: '$CHECKSQLSTR' != '$m'"
return 1
fi
return 1
}
case "$1" in
check)
check
exit $?
;;
backup)
$LOGWARN "=> set to backup state <="
set_master
exit $?
;;
master)
$LOGWARN "=> set to master state <="
set_master
exit $?
;;
esac