Chinaunix首页 | 论坛 | 博客
  • 博客访问: 57304
  • 博文数量: 18
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 200
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-01 13:27
个人简介

学习是一种信仰

文章分类

全部博文(18)

文章存档

2016年(8)

2015年(8)

2013年(2)

我的朋友

分类: Mysql/postgreSQL

2016-05-26 00:18:01

背景:
     在现实环境中,一个数据库会同时为多个应用提供服务,在某些环境下,应用程序是直连数据库的,并没有走HA,SLB,VIP等,也就是说如果master数据库不可用了,即使有standby数据库,想在短时间内完成切换数据库、切换应用、恢复提供服务是很难做到的,这时就需要写一个脚本,完成数据库,应用一键切换。

环境:
     有三台数据库服务器,一主两从,其中一个从库与master是同步关系,另一个从库与master是异步关系。
     master数据库与另一台数据库服务器通过pgq实现数据同步关系,如果考虑数据库切换,一定要考虑pgq的切换

一键切换数据库、应用、DNS:
#!/bin/bash
. ~/.bash_profile

dns_ip=
dns_path=
src_ip=$1

echo "切换开始时间是:`date +%Y%m%d-%H%M%S`"
echo " "
#判断服务器是否可以通过ssh登录
if [ -z $1 ]
then
   echo "WARNING:请输入原主数据库ip来判断原master数据库是否可以通ssh登录。。。"
   echo " "
"
   exit 1
else
ssh -o connecttimeout=10 root@$1 "exit"
if [ $? -eq 0 ]
then
   echo "服务器$1 可以通过ssh登录"
   echo " "
else 
   echo "服务器$1 无法通过ssh登录,请登录控制台。。。"
   echo " "
fi
fi
echo " "

#判断是否输入主库ip和主备库ip,否则提示并退出
if [ -z $1 ] || [ -z $2 ]
then
   echo "WARNING:请按顺序最少输入前2个数据库ip地址:原主数据库ip 主备ip 备库ip"
   echo " "
"
   exit 1
else
   echo "您输入的ip分别是:
原主数据库ip:$1
主备ip:      $2
备库ip:      $3
"
   echo "请确认数据库ip是否正确,如没问题请输入暗号:"
   read sign
if [ $sign = "good" ]
then
  echo "暗号正确,继续执行。。。"
else 
  echo "暗号输入错误,请重新输入。。。"
  exit 1
fi
fi

#判断是否输入主库ip和主备库ip,否则提示并退出
if [ -z $1 ] || [ -z $2 ]
then
   echo "WARNING:请按顺序最少输入前2个数据库ip地址:原主数据库ip 主备ip 备库ip"
   echo " "
   echo "#####################################"
   exit 1
fi

# 判断原主数据库是否已经停止提供服务,如没停止,需要先停止原主数据库
PROCESS=`ssh root@$1 'su - postgres -c "source .bash_profile;ps -ef | grep -v grep | grep "bin/postgres""'| wc -l`
if [ $PROCESS -eq 0 ]
then
    echo "master database $1 postgres is not running"

#如果只传入两个参数,则直接进行数据库切换                
if [ -z $3 ]
then

# 启动备份数据库
ssh root@$2 'su - postgres -c "source ~/.bash_profile;pg_ctl promote"'

# 修改DNS配置文件
ssh root@$dns_ip "
cd $dns_path
cp ${dns_path}/named.yazuoyw.com ${dns_path}/named.yazuoyw.com_`date +%Y%m%d%H%M%S`

sed -n "s/$src_ip/$2/p" $dns_path/named.yazuoyw.com
sed -i "s/$src_ip/$2/" $dns_path/named.yazuoyw.com

# 修改DNS配置文件属组
chown -R named:named /var/named

# 重启DNS
service named reload
"                
#如果传入三个参数(即一主两备),需要对两个备库做判断
else
                
delay1=`/usr/local/pgsql/bin/psql "host=$2 port=5432 user=trace password=readonly dbname=postgres" -x -c "select * from get_rcv_replication_stat;"|grep -i last_apply_delay_ms|awk -F '|' '{print $2}'`
delay2=`/usr/local/pgsql/bin/psql "host=$3 port=5432 user=trace password=readonly dbname=postgres" -x -c "select * from get_rcv_replication_stat;"|grep -i last_apply_delay_ms|awk -F '|' '{print $2}'`

receiver_state1=`/usr/local/pgsql/bin/psql "host=$2 port=5432 user=trace password=readonly dbname=postgres" -x -c "select * from get_rcv_replication_stat;"|grep -i receiver_state|awk -F '|' '{print $2}'`
receiver_state2=`/usr/local/pgsql/bin/psql "host=$3 port=5432 user=trace password=readonly dbname=postgres" -x -c "select * from get_rcv_replication_stat;"|grep -i receiver_state|awk -F '|' '{print $2}'`

echo "主备库:$2的状态是$receiver_state1"
echo "备份库:$3的状态是$receiver_state2"
echo " "
echo "主备库:$2的延时是$delay1"
echo "备份库:$3的延时是$delay2"
echo " "
echo "########################"
if (( $delay1 >= $delay2 )); then
   echo "建议切换到 $2" 
   updb=$2
else 
   echo "建议切换到 $3"
   updb=$3
fi;

# 启动备份数据库
ssh root@$updb 'su - postgres -c "source ~/.bash_profile;pg_ctl promote"'

# 修改DNS配置文件
ssh root@$dns_ip "
cd $dns_path
cp ${dns_path}/named.yazuoyw.com ${dns_path}/named.yazuoyw.com_`date +%Y%m%d%H%M%S`

sed -n "s/$src_ip/$updb/p" $dns_path/named.yazuoyw.com
sed -i "s/$src_ip/$updb/" $dns_path/named.yazuoyw.com

# 修改DNS配置文件属组
chown -R named:named /var/named

# 重启DNS
service named reload
"
fi
                
echo "数据库及应用切换完成,请切换pgq"                
else

#如果原主数据库没有关闭,则关闭原主数据库
echo "master database $1 is already running..."
echo " "
echo "现在关闭原主数据库,当前时间是`date +%Y%m%d-%H%M%S`"
ssh root@$1 'su - postgres -c "source ~/.bash_profile;pg_ctl stop -m fast"'
echo " "
#检查原主数据库是否关闭
PROCESS1=`ssh root@$1 'su - postgres -c "source .bash_profile;ps -ef | grep -v grep | grep "bin/postgres""'| wc -l`
if [ $PROCESS1 -eq 0 ]
then
    echo "原主数据库 $1 已经关闭,请重新执行此脚本"
else
    echo "原主数据库 $1 依然在运行中,请检查。。。"  
fi  
echo " "
fi

  
阅读(636) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~