使用 Shell 备份远程服务器上的 MySQL 数据库到本机

操作流程:

  1. 先登录服务器,备份数据库;
  2. 将备份文件拉取到本机。

主要涉及知识点:expectmysqldumpscp

1. 源码

新建 Shell 文件:mysqlDumpRemote2Local.sh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#!/bin/bash
################################################
# TODO: 登录远程服务器,备份指定数据库并下载到本地
# 示例:
# ./mysqlDumpRemote2Local.sh
#
# File: https://github.com/whorusq/linux-learning/blob/master/shell/mysqlDumpRemote2Local.sh
# Author: whoru.S.Q <whoru@sqiang.net>
# Version: 1.0
################################################


# 待操作待服务器列表
# 格式:"描述,数据库名,数据库用户名,数据库密码,数据库端口号,SSH登录用户名,SSH服务器IP,SSH登录密码,SSH端口号"
HOSTS=(
"test,db_demo,root,pwd123456,3306,root,192.168.1.127,pwd3333,22"
)
HOSTS_LEN=`echo ${#HOSTS[*]}`
HOST_KEY=

# 服务器上备份文件的存放目录
DB_BACKUP_PATH=/opt/backup

# 当前脚本所处目录
BASE_PATH=$(cd "$(dirname "$0")";pwd)

# 入口
function main {
#检查基础设置
if [ "$HOST_LEN" == "0" ]; then
echo "您还没有配置待操作的服务器参数"
exit 1
fi

# 显示菜单
MENU="\n"
INDEX=1
for host in ${HOSTS[*]}
do
local host_name=`echo $host | awk -F ',' '{ print $1" ===> "$2}'`
MENU=$MENU"\t"$INDEX". "$host_name"\n"
INDEX=`expr $INDEX + 1`
done
echo -en $MENU"\n"

# 检查选择
checkChoice

# 开始导出操作
doDump
}

function checkChoice {
read -p "请输入序号选择待备份的数据库:" HOST_NUM
len=`echo "$HOST_NUM"|sed 's/[1-9]//g'`
if [ -n "$len" ]; then
ifGoon "输入有误,只支持1-9的数字,是否重新输入[y/n]:"
else
KEY=`expr $HOST_NUM - 1`
if [ $KEY -le $HOSTS_LEN ]; then
HOST_KEY=$KEY
else
ifGoon "未知的序号,是否重新输入[y/n]:"
fi
fi
}

function ifGoon {
echo -en "\033[32m==>\033[0m "
read -p $1 GOON
if [ "$GOON" == "y" ]; then
checkChoice
else
exit 0
fi
}

function doDump {
if [ -n "$SERVER_KEY" ]; then
echo "未知的序号"
exit 0
fi

# 从对应的配置中解析数据库和 SSH 参数
HOST=${HOSTS[$HOST_KEY]}
HOST_NAME=`echo $HOST | awk -F ',' '{ print $1 }'`
DB_NAME=`echo $HOST | awk -F ',' '{ print $2 }'`
DB_USER=`echo $HOST | awk -F ',' '{ print $3 }'`
DB_PWD=`echo $HOST | awk -F ',' '{ print $4 }'`
DB_PORT=`echo $HOST | awk -F ',' '{ print $5 }'`
SSH_USER=`echo $HOST | awk -F ',' '{ print $6 }'`
SSH_IP=`echo $HOST | awk -F ',' '{ print $7 }'`
SSH_PWD=`echo $HOST | awk -F ',' '{ print $8 }'`
SSH_PORT=`echo $HOST | awk -F ',' '{ print $9 }'`

# 备份文件名
DUMP_FILENAME=$HOST_NAME"_"`date +%Y%m%d%H%M%S`

echo -e "\n\033[32m==>\033[0m 操作开始 "
sleep 1

echo -e "\n\033[32m==>\033[0m 登录 ${HOST_NAME} 正式服务器,备份数据库"
sleep 1
expect -c "
spawn ssh ${SSH_USER}@${SSH_IP} -p ${SSH_PORT}
expect {
\"yes/no\" {send \"yes\n\"; exp_continue;}
\"*assword\" { send \"${SSH_PWD}\r\n\"; exp_continue ; sleep 3; }
\"Last*\" { send_user \"\n 登录成功 \n\";}
}
expect \"*]#\"
send \"ls ${DB_BACKUP_PATH} &>/dev/null && cd ${DB_BACKUP_PATH} || mkdir -p ${DB_BACKUP_PATH} && cd ${DB_BACKUP_PATH} \r\"
send \"mysqldump -u${DB_USER} -p${DB_PWD} -P ${DB_PORT} ${DB_NAME} > ${DUMP_FILENAME}.sql \r\"
send \"tar -zcvf ${DUMP_FILENAME}.tar.gz ${DUMP_FILENAME}.sql \r\"
send \"exit \r\"
interact
"

echo -e "\n\033[32m==>\033[0m 退出 ${HOST_NAME} 正式服务器 \n"
sleep 1

echo -e "\n\033[32m==>\033[0m 将备份文件拉取到本机 \n"
sleep 1
expect -c "
spawn scp -P $SSH_PORT $SSH_USER@$SSH_IP:$DB_BACKUP_PATH/$DUMP_FILENAME.tar.gz $BASE_PATH
expect {
\"*assword\" { send \"${SSH_PWD}\r\n\"; exp_continue ; }
}
"

echo -e "\n\033[32m==>\033[0m 操作结束,文件位置:"$BASE_PATH/$DUMP_FILENAME.tar.gz" \n"
}

# 运行
main

2. 使用示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
➜  ./mysqlDumpRemote2Local.sh

1. test ===> db_demo

请输入序号选择待备份的数据库:1

==> 操作开始

==> 登录 test 正式服务器,备份数据库
spawn ssh root@192.168.1.127 -p 22
root@192.168.1.127's password:
Last login: Tue Nov 13 13:43:53 2018 from xxxxxxxxx

登录成功
[root@ test ~]# ls /opt/backup &>/dev/null && cd /opt/backup || mkdir -p /opt/backup && cd /opt/backup
[root@ test backup]# mysqldump -uroot -ppwd123456 -P 3306 db_demo > test_20181113135359.sql
Warning: Using a password on the command line interface can be insecure.
[root@dbhs backup]# tar -zcvf test_20181113135359.tar.gz test_20181113135359.sql
test_20181113135359.sql
[root@dbhs backup]# exit
logout
Connection to 192.168.1.127 closed.

==> 退出 test 正式服务器

==> 将备份文件拉取到本机

spawn scp -P 22 root@192.168.1.127:/opt/backup/test_20181113135359.tar.gz /Users/xxxxx/mydev/linux-learning/shell
root@218.29.103.28's password:
test_20181113135359.tar.gz 100% 66KB 941.5KB/s 00:00

==> 操作结束,文件位置:/Users/xxxxx/mydev/linux-learning/shell/test_20181113135359.tar.gz