gp数据库运维
最近需要將一份db2導出的歷史數據入庫gp集群,然后把每天的增量數據導出成txt文件和對應的log日志,再ftp傳輸給另外一臺機器。其中陸續碰到一些坑,在此記錄
歷史文件數據清洗
列分隔符的選擇
碰到的第一個問題是db2導出的文件格式。因為之前的db2腳本導出用的是export命令,coldel0x01 nochardel,指定16進制的不可見字符0x01當做列分隔符。而gp的copy命令雖然可以指定列分隔符,但是好像不能使用16進制字符,所以這里的操作時把0x01都sed替換成((開始嘗試使用,|等常見字符,但是后來發現有部分表入庫失敗,grep搜索后發現是數據本身帶有這些字符,破壞了分列格式,最后嘗試之后發現沒有),于是用$當成分隔符)
number類型字段的空值處理
歷史文件里的空值,對用pg字段里的number類型字段,會提示字段類型不匹配入庫失敗。這里才去的是把$$替換成(0),用0來替換空值
特殊轉義字符
經過前2步操作,大部分表已經入庫成功。對于失敗的表,發現清洗過的數據變成了亂碼,猜測是之前的sed操作出了問題。查看對應的原始數據,定位到失敗的具體行數,發現里面有右斜杠,這樣在ascii里面的16進制字符替換會出錯。于是在清洗之前先把轉義的右斜杠替換成空
shell腳本
#config begin
base_path="/data/"
meta_host="*.*.*.*"
mete_user="postgres"
mete_databse="postgres"
mete_password="123456"
meta_port="5432"
dw_host="*.*.*.*"
dw_user="postgres"
dw_database="postgres"
dw_password="123456"
#config end
function insert_file(){
tb_name=$1;
file_name=${base_path}'C3208133000016-'${tb_name}'-20171024.txt'
if [ -f "${file_name}" ]; then
#過濾
sed -i 's/\//g' ${file_name}
#16進制的列分隔0x01符替換成$
sed -i 's/x01/$/g' ${file_name}
#把$$替換成$0$防止numeric類型的是空
for(( i=1;i<4;i++))
do
sed -i 's/$$/$0$/g' ${file_name}
done
#psql入庫
PGPASSWORD=${dw_database} psql -U ${dw_user} -d ${dw_database} -h ${dw_host} -c "copy sjck.${tb_name} from '${file_name}' WITH DELIMITER '$'"
echo $(date +%Y-%m-%d %H:%M:%S)','${tb_name}' end'
fi
}
echo 'trans begin'
count=0
for file in `PGPASSWORD=${mete_password} psql -U ${mete_user} -d ${mete_databse} -h ${meta_host} -p ${meta_port} -c "select distinct tb_name from sjck.table_columns where module='NEWCBRC'"|tail -n +3|head -n -2`
do
tb_name=${file}
((count++))
echo $(date +%Y-%m-%d %H:%M:%S)',num:'${count}',' ${tb_name}
insert_file ${tb_name}
done
echo ${count}
echo 'trans end'
截取部分輸出日志
發現其中最大的一張表大概2000多萬的數據,入庫大概花了15分鐘
trans begin
2019-03-28 11:59:05,num:1? DGKH
COPY 24831
2019-03-28 11:59:11,DGKH end
******
2019-03-28 12:05:32,num:16? JYLS
COPY 21297993
2019-03-28 12:20:07,JYLS end
增量數據每天導出
gp導出文件權限
用gp的COPY命令導出文件時,發現touch創建文件還不夠,會提示權限相關問題,于是改成777權限。
pg命令的環境變量
最后調好腳本在shell執行都是正常的,但是通過ssh連接遠程服務器執行腳本時,發現psql相關命令不能執行,輸出亂碼。開始以為是gbk和utf8的編碼問題,浪費了不少時間,后來是缺少gp的環境變量,將系統的相關的環境變量,在腳本里再寫了一次,可以正常使用psql命令
shell腳本
#!/bin/bash
#config begin
base_path="/data/shell/txt_log/"
meta_host="*.*.*.*"
mete_user="postgres"
mete_databse="postgres"
mete_password="123456"
meta_port="5432"
dw_host="*.*.*.*"
dw_user="gpadmin"
dw_database="postgres"
dw_password="123456"
#config end
#要配置psql相關的環境變量,不然監控平臺調用腳本執行不了psql命令
source /uur/local/greenplum-db/greenplum_path.sh
export MASTER_DATA_DIRECTORY=/data/master/gpseg-1
DATE=`date -d '-'1' day' +%Y%m%d`
bg_dt_zcc=`date -d '-'1' day' +%Y-%m-%d`
echo ${DATE}"-task begin"
function make_file(){
tb_name=$1;
filenm="C3208133000016-"${tb_name}"-"${DATE}
file_name=${filenm}".txt"
log_name=${filenm}".log"
data_path=${base_path}${file_name}
data_temppath=${base_path}${filenm}"_temp.txt"
log_path=${base_path}${log_name}
if [ ! -f "${data_temppath}" ];then
touch "${data_temppath}"
fi
echo ${data_temppath}
chmod 777 ${data_temppath}
PGPASSWORD=${dw_database} psql -U ${dw_user} -d ${dw_database} -h ${dw_host} -c "COPY (select * from tbbak.${tb_name} where bg_dt_zcc='${bg_dt_zcc}') to '${data_temppath}'"
echo "select * from tbbak.${tb_name} where bg_dt_zcc='${bg_dt_zcc}'"
#刪除拉鏈日期字段
awk '{$1="";$2="";print $0}' ${data_temppath} > ${data_path}
#去除行首空格
sed -i 's/^[ ]*//g' ${data_path}
if [ ! -f "${log_path}" ];then
touch "${log_path}"
fi
echo ${log_path}
echo ${file_name} >> ${log_path}
filesize=$(wc -c ${data_path} | awk '{print $1}')
echo $filesize >> ${log_path}
fileday=$(ls --full-time ${data_path} | awk '{print $6}')
filetime=$(ls --full-time ${data_path} | awk '{print $7}')
filetime1=$(echo ${filetime:0:8})
echo ${fileday}" "${filetime1}>>${log_path}
fileline=$(cat ${data_path} |wc -l)
echo 'Y'>> ${log_path}
echo $fileline >> ${log_path}
echo $(date +%Y-%m-%d %H:%M:%S)','${tb_name}" finish"
}
count=0
for file in `PGPASSWORD=${mete_password} psql -U ${mete_user} -d ${mete_databse} -h ${meta_host} -p ${meta_port} -c "select distinct tb_name from sjck.table_columns where module='NEWCBRC'"|tail -n +3|head -n -2`
do
tb_name=${file}
((count++))
echo $(date +%Y-%m-%d %H:%M:%S)',num:'${count}',' ${tb_name}
make_file ${tb_name}
done
make_file 'DGKH'
echo "size is:"${count}
echo ${DATE}"-task end"
生成文件后,ftp傳輸到遠程服務器
ftp -n<<!
open *.*.*.*
user guest 123456
binary
hash
cd /data/remote
lcd /data/local
prompt
mput *
close
bye
!
總結
- 上一篇: 小学生入门激光SLAM<六>
- 下一篇: 怎么创建具有真实纹理的CG场景岩石?