导入数据
导出的数据文件为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/[email protected]/shhis"
oracleparallel=3
tables=(`$psqlconn -c "$selectsql"`)
# oracle count
for t in ${tables[@]}
do
# oracle count
o_cnt=`sqlplus -S /nolog <
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亿多用户提供在线服务,具备高性能、弹性扩展、高可靠等产品特性,峰值每秒可处理百万笔电信核心交易,保障系统持续稳定运行近十年,并在通信、金融、交通、能源、物联网等行业成功商用落地。