需求:
每天定时将 源数据库 study_plan 库的 zxxt_class 表
增量同步到 目标数据库 axt_statistics 库的 zxxt_class 表中
前提条件:
两个库中的 zxxt_class 表结构一致
询问开发根据哪个字段作为增量参考,这里开发给的是id字段
流程:
获取 axt_statistics 库的 zxxt_class 表中id字段的最大id值
通过这个id值备份study_plan 库的 zxxt_class 表中大于此id的数据
将数据导入
脚本:
#!/bin/bash
#通用变量
MySql_Comm='/usr/local/mysql/bin/mysql'
MySqldump_Comm='/usr/local/mysql/bin/mysqldump'
DateTime=`date +%Y-%m-%d-%H:%M:%S`
echo -e "\n\n${DateTime} -----脚本开始执行-----" >> /tmp/sourcedb.log
#源数据库信息
Source_MySql_User='root'
Source_MySql_Pass='123456'
Source_MySql_Port='3306'
Source_MySql_DB='study_plan'
Source_MySql_Table='zxxt_class'
Source_Host_IP='192.168.0.100'
#本机数据库信息
Mysql_User='root'
MySql_Pass='12345678'
MySql_Port='3306'
MySql_DB='axt_statistics'
MySql_Table='zxxt_class'
MySql_Bak_Dir="/tmp/`date +%Y-%m-%d-%H-%M`"
#创建备份目录
mkdir ${MySql_Bak_Dir}
#备份本机表
if [ -d ${MySql_Bak_Dir} ];then
${MySqldump_Comm} \
-u${Mysql_User} \
-p${MySql_Pass} \
-h 127.0.0.1 \
-P${MySql_Port} \
${MySql_DB} ${MySql_Table} > ${MySql_Bak_Dir}/${MySql_DB}-${MySql_Table}.sql
else
echo "${DateTime} ERROR: ${MySql_Bak_Dir} 目录不存在" >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
exit 1
fi
#获取本机表最大ID
${MySql_Comm} \
-u${Mysql_User} \
-p${MySql_Pass} \
-h 127.0.0.1 \
-P${MySql_Port} \
--compress ${MySql_DB} -e "select max(id) from ${MySql_Table}" > /tmp/tmp.txt
ID_Num=`tail -1 /tmp/tmp.txt`
echo $ID_Num
#备份源表大于本机获取id的数据
if [[ ${ID_Num} -gt 0 ]];then
if [ -d ${MySql_Bak_Dir} ];then
echo "${DateTime} 开始备份原主机${Source_MySql_DB} ${Source_MySql_Table} ID大于${ID_Num}的数据..." >> /tmp/sourcedb.log
${MySqldump_Comm} -t \
-u${Source_MySql_User} \
-p${Source_MySql_Pass} \
-h${Source_Host_IP} \
-P${Source_MySql_Port} \
--single-transaction --compress ${Source_MySql_DB} ${Source_MySql_Table} --where="id > '`tail -1 /tmp/tmp.txt`'" > ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql
echo "${DateTime} 数据备份完成 ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql" >> /tmp/sourcedb.log
#导入数据
if [ -f ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql ];then
echo "${DateTime} 开始导入数据..." >> /tmp/sourcedb.log
${MySql_Comm} \
-u${Mysql_User} \
-p${MySql_Pass} \
-h 127.0.0.1 \
-P${MySql_Port} \
${MySql_DB} -e "source ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql"
echo "${DateTime} 数据导入完成${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql..." >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
else
echo "${DateTime} ERROR: sql文件${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql不存在!"
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
exit 1
fi
else
echo "${DateTime} ERROR: ${MySql_Bak_Dir} 目录不存在" >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
exit 1
fi
else
echo "${DateTime} ERROR: ID 等于 NULL" >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
exit 1
fi
注意!脚本中需要注意的是,从源库中使用mysqldump时必须加参数 -t ,-t 表示备份插入数据,如果不加 -t ,那么导入到目标库的数据将替换源有数据。
测试:
上面两图可以看到,源表中比目标表多了一个数据
执行脚本后
数据已同步过来
日志:
再看看导入的sql脚本
可以看到只备份并导入了自己新加的那一条数据
下面这个是id不固定的,所以根据创建时间进行增量
#!/bin/bash
#通用变量
MySql_Comm='/usr/local/mysql/bin/mysql'
MySqldump_Comm='/usr/local/mysql/bin/mysqldump'
DateTime=`date +%Y-%m-%d-%H:%M:%S`
echo -e "\n\n${DateTime} -----脚本开始执行-----" >> /tmp/sourcedb.log
#源数据库信息
Source_MySql_User='root'
Source_MySql_Pass='xxxxxxxxx'
Source_MySql_Port='3306'
Source_MySql_DB='db_name'
Source_MySql_Table='tb_name'
Source_Host_IP='172.16.0.100'
#本机数据库信息
Mysql_User='root'
MySql_Pass='xxxxxxxxx'
MySql_Port='3306'
MySql_DB='db_name'
MySql_Table='tb_name'
MySql_Bak_Dir="/data/${MySql_DB}-${MySql_Table}/`date +%Y-%m-%d-%H-%M`"
MySql_Bak_Dir_2="/data/${MySql_DB}-${MySql_Table}"
#创建备份目录
mkdir -p ${MySql_Bak_Dir}
#备份本机表
if [ -d ${MySql_Bak_Dir} ];then
${MySqldump_Comm} \
-u${Mysql_User} \
-p${MySql_Pass} \
-h 127.0.0.1 \
-P${MySql_Port} \
${MySql_DB} ${MySql_Table} > ${MySql_Bak_Dir}/${MySql_DB}-${MySql_Table}.sql
else
echo "${DateTime} ERROR: ${MySql_Bak_Dir} 目录不存在" >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
echo "error" > /etc/zabbix/mysql_source/${Source_MySql_DB}-${Source_MySql_Table}.txt
exit 1
fi
#获取本机表最大创建时间
${MySql_Comm} \
-u${Mysql_User} \
-p${MySql_Pass} \
-h 127.0.0.1 \
-P${MySql_Port} \
--compress ${MySql_DB} -e "select max(kl_create_time) from ${MySql_Table}" > /tmp/tmp.txt
#如果第一次同步前创建了表,而表中没有数据,也就无法根据当前表的数据创建时间来获取增量数据,所以如果结果是空则给一个时间,给个很早期的时间,至少要比源数据最早的时间要早
ID_Num=`tail -1 /tmp/tmp.txt`
if [[ ${ID_Num} -eq NULL ]];then
echo $ID_Num
ID_Num='2000-11-09 17:29:45'
fi
echo $ID_Num
#备份源表大于本机获取创建时间的数据
if [ -d ${MySql_Bak_Dir} ];then
echo "${DateTime} 开始备份原主机${Source_MySql_DB} ${Source_MySql_Table} 数据创建时间大于等于${ID_Num}的数据..." >> /tmp/sourcedb.log
${MySqldump_Comm} -t \
-u${Source_MySql_User} \
-p${Source_MySql_Pass} \
-h${Source_Host_IP} \
-P${Source_MySql_Port} \
--single-transaction --compress ${Source_MySql_DB} ${Source_MySql_Table} --where="kl_create_time >= '${ID_Num}'" > ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql
echo "${DateTime} 数据备份完成 ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql" >> /tmp/sourcedb.log
#导入数据
if [ -f ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql ];then
echo "${DateTime} 开始导入数据..." >> /tmp/sourcedb.log
${MySql_Comm} \
-u${Mysql_User} \
-p${MySql_Pass} \
-h 127.0.0.1 \
-P${MySql_Port} \
${MySql_DB} -e "source ${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql"
echo "${DateTime} 数据导入完成${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql..." >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
echo "ok" > /etc/zabbix/mysql_source/${Source_MySql_DB}-${Source_MySql_Table}.txt
else
echo "${DateTime} ERROR: sql文件${MySql_Bak_Dir}/${Source_MySql_DB}-${Source_MySql_Table}.sql不存在!"
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
echo "error" > /etc/zabbix/mysql_source/${Source_MySql_DB}-${Source_MySql_Table}.txt
exit 1
fi
else
echo "${DateTime} ERROR: ${MySql_Bak_Dir} 目录不存在" >> /tmp/sourcedb.log
echo "${DateTime} -----脚本执行完成!!!-----" >> /tmp/sourcedb.log
echo "error" > /etc/zabbix/mysql_source/${Source_MySql_DB}-${Source_MySql_Table}.txt
exit 1
fi
#清理旧数据
find ${MySql_Bak_Dir_2} -name "20*" -mtime +3 | xargs -t -i rm -rf {}