导出导入数据
导入数据
导出的数据文件为copy命令的sql文件,可以直接使用psql -f参数执行。但是在文件数量比较多的时候,建议采用脚本封装的方式,可控的进行数据导入。
编写导入脚本
该脚本通过命令行参数来控制是通过表名查找文件导入还是按照文件大小排序后取一定的文件数来进行导入。用法如下:
sh psqlcopy.sh -u party -d /adbdata/ora2pg/data/party -l /adbdata/ora2pg/log -s 11
复制
按照文件大小正序排序后取前11个文件
sh psqlcopy.sh -u party -d /adbdata/ora2pg/data/party -l /adbdata/ora2pg/log -S 11
复制
按照文件大小正序倒序后取前11个文件
sh psqlcopy.sh -u party -d /adbdata/ora2pg/data/party -l /adbdata/ora2pg/log -t INS_DES_ACCREL
复制
导入以INS_DES_ACCREL开头的表文件
vi psqlcopy.sh #!/bin/bash source /home/postgres/.bashrc function check_dir { if [ ! -d "$2" ]; then echo "the $1 direcory $2 does not exist!" exit 0 fi } function usage { echo "Usage: " echo " `basename $0` -u username -d datadir -t tablename -l logdir" echo " `basename $0` -u username -d datadir -s|S filecnt -l logdir" exit 0 } function psql_copy_file { $psqlconn -f ${datadir}/$file"_importing" > ${logdir}/"psqlcopy_"$file.log 2>&1 errcnt=`grep -E "ERROR|FATAL" ${logdir}/"psqlcopy_"$file.log | wc -l` if [ "$errcnt" -gt 0 ];then echo `date "+%Y-%m-%d %H:%M:%S" `": file ${datadir}/$file"_importing" copy failed,please check log ${logdir}/"psqlcopy_"$file.log!" >> ${logdir}/"psqlcopy_error".log elif [ "$errcnt" -eq 0 ]; then mv ${datadir}/$file"_importing" ${datadir}/import_done/$file"_done" fi } function exe_psql_copy { if [ "x$tablelike" != "x" ]; then files=`ls -rt $datadir |grep -E '*sql$' |grep -v tmp | grep -v done |grep -v import |grep $tablelike` elif [ $filecnt -gt 0 ]; then if [ $file_sort -eq 0 ]; then lsopt="ls -rS" elif [ $file_sort -eq 1 ]; then lsopt="ls -S" fi files=`$lsopt $datadir |grep -E '*sql$' |grep -v tmp | grep -v done |grep -v import |head -$filecnt` fi # rename file to filename_importing for file in ${files[@]} do mv ${datadir}/$file ${datadir}/$file"_importing" done # execute copy, after move file to done dir for file in ${files[@]} do echo `date "+%Y-%m-%d %H:%M:%S"` " execute file: $file ,file size :`du -sh ${datadir}/$file"_importing" |awk '{print $1}'`" #echo `date "+%Y-%m-%d %H:%M:%S"` " execute file: $file ,file size :`du -sh ${datadir}/$file |awk '{print $1}'`" # sh /data/ora2pg/scripts/psqlcopyfile.sh $dbname $tableowner $file_dir $file >> ${logdir}/"psqlcopy".log 2>&1 & psql_copy_file & done } function check_adb_conn { result==`$psqlconn -q -t -c "select 1"` if [ "x$result" = "x" ];then echo "connect to adb is invalid,please check!" exit 1 } function dir_stat { exporting_cnt=`ls -rt $datadir |grep 'exporting' |grep -v done |wc -l` importing_cnt=`ls -rt $datadir |grep 'importing' |grep -v done |wc -l` noimport_cnt=`ls -rt $datadir |grep -E '*sql$' |grep -v tmp | grep -v done |grep -v import |wc -l` done_cnt=`ls -rt $datadir/import_done |grep "done" |wc -l` echo `date "+%Y-%m-%d %H:%M:%S"` "data directory $datadir stat: exporting:$exporting_cnt,noimport:$noimport_cnt,importing:$importing_cnt,import_done:$done_cnt" } while getopts 'u:d:t:s:S:l:' OPT; do case $OPT in u) username="$OPTARG";; d) datadir="$OPTARG";; t) tablelike="$OPTARG";; s) file_sort=0 filecnt="$OPTARG";; S) file_sort=1 filecnt="$OPTARG";; l) logdir="$OPTARG";; ?) usage esac done check_dir "data" $datadir check_dir "log" $logdir # should use -t or -s|S option. if [ "x$tablelike" != "x" -a "x$filecnt" != "x" ]; then echo "you should use -t or -s|S option." usage fi dbname='shcrm1' hostname='10.10.152.77' port="5432" psqlconn="psql -h $hostname -p $port -d $dbname -U $username " echo "username:$username,datadir:$datadir,tablelike:$tablelike,file_sort:$file_sort,filecnt:$filecnt,logdir:$logdir" check_adb_conn exe_psql_copy dir_stat
复制
查找文件
提供一个脚本,根据文件名查找文件是否存在:
vi findfile.sh echo "-------------------------------------`date`" dir=$1 find $dir -maxdepth 2 -name "*$2*" -exec ls -lhr {} \;
复制
因为导出文件是以表名命名的,所以,根据表名(大写)查找出来的文件,通过标识(exporting,done等)可以知道表的状态(导出中、导出完成、导入中、导入完成)。
查看日志
日志文件在指定的日志目录中存放,命名方式为:
psqlcopy_filename.log
在日志目录中,会有一个总的记录导入失败的文件的日志:psqlcopy_error.log,记录导入失败的文件,并提供对应的日志文件全路径。
数据稽核
两边数据库计算count(*)
同样,表少的情况下,可以直接使用select count(*) 在两边数据库查询。
表多的时候,依然建议将查询结果存表。
Oracle侧查询
oracle侧查询脚本,默认在Oracle起三个并行进行查询,通过配置表取表名,然后更新配置表的o_cnt字段:
vi o_cnt.sh #/bin/bash # sh o.sh so1 ins_des_user_ext_210 > o_cnt.log 2>&1 & dbname="shhis" owner=$1 tablename=$2 psqlconn="psql -d $dbname -U adb -q -t" selectsql="select tablename from t_ora2adb_tableinfo_cnt where dbname='$dbname' and owner='$owner' and upper(tablename) like '$tablename%' --and o_cnt is null or o_cnt=0 " usertns="username/password@10.10.10.10/shhis" oracleparallel=3 tables=(`$psqlconn -c "$selectsql"`) # oracle count for t in ${tables[@]} do # oracle count o_cnt=`sqlplus -S /nolog <<EOF set heading off feedback off pagesize 0 verify off echo off conn $usertns select /*+ parallel($oracleparallel)*/ count(*) from $owner.$t; exit EOF` # oracle size o_size_m=`sqlplus -S /nolog <<EOF set heading off feedback off pagesize 0 verify off echo off conn $usertns select round(sum(bytes)/1024/1024,2) from dba_segments --from user_segments where 1=1 and owner=upper('$owner') and segment_name=upper('$t'); exit EOF` echo `date "+%Y-%m-%d %H:%M:%S"` "table_cnt on oracle: $owner:$t:$o_cnt:$o_size_m MB" $psqlconn << EOF update t_ora2adb_tableinfo_cnt set o_cnt=$o_cnt,o_size_m=$o_size_m,o_cnt_time=now() where 1=1 and owner='$owner' and tablename like '$t' ; EOF done
复制
ADB侧查询
同样通过配置表取表名,然后更新配置表的a_cnt字段:
vi a_cnt.sh #!/bin/bash # sh a.sh so1 ins_des_user_ext_210 > o_cnt.log 2>&1 & source /home/adb/.bashrc # init parameter dbnname="shhis" owner=$1 tablename=$2 # oracle connect info # adb connect info updatepsqlconn="psql -d $dbnname -U adb -q -t" cntpsqlconn="psql -d $dbnname -U $owner -q -t" selectsql="select tablename from t_ora2adb_tableinfo_cnt where dbname='$dbnname' and owner='$owner' and upper(tablename) like '$tablename%' --and o_cnt>0 --and (a_cnt is null or a_cnt=0 or o_minus_a <> 0) " tables=(`$updatepsqlconn -c "$selectsql"`) # oracle count for t in ${tables[@]} do a_cnt=`$cntpsqlconn << EOF select count(*) from $owner.$t; EOF` a_size_m=`$cntpsqlconn << EOF select pg_relation_size('$owner.$t')/1024/1024; EOF` echo `date "+%Y-%m-%d %H:%M:%S"` "table_cnt on adb: $owner:$t:$a_cnt:$a_size_m MB" $updatepsqlconn << EOF update t_ora2adb_tableinfo_cnt set a_cnt=$a_cnt,a_size_m=$a_size_m,a_cnt_time=now() where 1=1 and owner='$owner' and tablename like '$t' ; EOF done $updatepsqlconn -c "update t_ora2adb_tableinfo_cnt set o_minus_a=o_cnt-a_cnt;"
复制
两个脚本中获取表名的sql为selectsql,可以根据实际情况进行修改。
AntDB数据库始于2008年,在运营商的核心系统上,为全国24个省份的10亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔电信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。