shell脚本实现数据库表增量同步

需求:

  每天定时将 源数据库 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 {}

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
要使用shell脚本查询数据库,你可以通过以下步骤来实现: 1. 使用mysql命令连接到数据库。你可以使用以下命令来连接到数据库: ``` mysql -h 主机名 -u 用户名 -p 密码 数据库名 ``` 其中,主机名是数据库所在的主机地址,用户名和密码是用于登录数据库的凭据,数据库名是你要查询的数据库的名称。 2. 编SQL查询语句。在连接到数据库后,你可以编SQL查询语句来查询中的数据。例如,要查询名为"名"的中的所有数据,你可以使用以下语句: ``` SELECT * FROM 名; ``` 通过修改"名"为你要查询的的名称,你可以查询该中的所有数据。 3. 将查询结果保存到变量中。使用shell脚本的变量来保存查询结果。你可以使用以下命令将查询结果保存到变量中: ``` result=$(mysql -h 主机名 -u 用户名 -p 密码 -D 数据库名 -s -N -e "SELECT * FROM 名;") ``` 在这个命令中,通过将查询语句放在双引号中,你可以将查询结果保存到名为"result"的变量中。 4. 处理查询结果。你可以使用shell脚本的字符串处理函数来处理查询结果。例如,你可以使用"cut"命令来提取特定列的数据,使用"grep"命令来过滤特定条件的数据等等。根据你的需求,使用适当的命令来处理查询结果。 通过以上步骤,你可以使用shell脚本查询数据库并对查询结果进行处理。请根据你的具体需求和情况进行相应的调整。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [shell脚本进行数据库查询(分库分)](https://blog.csdn.net/jiange_zh/article/details/78154119)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [【shell脚本批量查询数据库数据】](https://blog.csdn.net/qq_42065917/article/details/125488510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值