zoukankan      html  css  js  c++  java
  • 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
    !
    
  • 相关阅读:
    java语法基础
    HashMap中的put()和get()的实现原理
    理解:o(1), o(n), o(logn), o(nlogn) 时间复杂度
    mongodb去重分页查询支持排序
    elk日志分析系统搭建(window )亲自搭建
    IDEA更改主题插件——Material Theme UI
    css实现图片的瀑布流且右上角有计数
    C# string "yyMMdd" 转DataTime
    Vue.js系列(一):Vue项目创建详解
    VS2017常用快捷键
  • 原文地址:https://www.cnblogs.com/wanli002/p/10629766.html
Copyright © 2011-2022 走看看