GaussDB(DWS)记录数据表操纵日志--系统日志提取方案
一、 背景概述
客户要求获取数据库表数据操纵的实时日志信息,包括对数据表的增删改操作,并且保留SQL语句中的参数值,对于该需求我们考虑了以下两个方案,一个使用逻辑解码,通过反解xlog的方式生成逻辑日志;另一种方案通过参数调整系统日志记录内容,使其记录表数据操作信息,再将这客户所需部分信息提取出来另行保存。因逻辑解码属于poc特性,不建议现网使用,选择满足客户需求且风险更小的系统日志提取方案。
二、 系统日志概述
集群运行时CN、DN、GTM、CM以及集群安装部署时产生的日志统称为系统日志。如果集群在运行时发生故障,可以通过这些系统日志即使定位故障发生的原因,根据日志内容指定恢复集群的方法。用户可以根据自己的需要,通过修改实例数据目录下的postgresl.conf文件中特定的参数来控制日志的输出,从而更好的了解数据库的运行状态。
CN、DN日志每一行内容默认格式:
日期+时间+时区+用户名称+数据库名称+会话ID+日志级别+日志内容
log_statement参数说明:
log_statement参数配置日志中记录哪些SQL语句,默认值为none,不记录任何SQL语句,配置为ddl记录数据定义语句,mod记录数据定义语句和数据操作语句,all记录所有语句,针对需求我们需要将此参数设置为all。
三、 实施方案
1. 修改log_statement参数使日志中记录所有语句
gs_guc reload -Z coordinator -N all -I all -c “log_statement=all”
2. 提取表更新信息
使用grep过滤日志中数据操纵语句,参考命令如下
cat postgresql.log | grep -v postgres | grep -E -i ": insert|: update|: delete" | grep -v -i ": select " | grep -v '\$'
cat postgresql.log | grep -v postgres | grep -E -i -A 1 ": insert|: update|: delete" | grep '\$' | grep -v -i ": select "
3. 自动化读取脚本编写策略
CN日志文件到达指定大小会重新生成新的文件,当一份CN日志生成时,从日志文件中获取表数据操作信息,并写入到指定文件中,进行转存处理。
因系统日志文件名中包含时间信息,可以根据系统获取的时间获取对应时间的文件列表,日志文件命名规则postgresql-%Y-%m-%d_%H%M%S.log
#获取当前时间精确到小时(2小时),和日志文件名同格式
date=`date "+%Y-%m-%d_%H"`
date1=`date -d "1 hour ago" "+%Y-%m-%d_%H"`
使用两个参数获取当前两小时内的文件列表
fileList=`ls /var/log/Bigdata/mpp/omm/pg_log/cn_*| grep -E "$date|$date1"`
将文件列表转存为数组,当文件列表更新时,说明上一份日志已经打印完成,使用cat从文件列表的倒数第二份文件中读取日志信息。
cat /var/log/Bigdata/mpp/omm/pg_log/cn_*/${arrylist[$fileNums-2]} | grep -v postgres | grep -E -i ": insert|: update|: delete" | grep -v -i ": select " | grep -v '\$' > /srv/BigData/mppdb/data1/log/${arrylist[$fileNums-2]}.log
cat /var/log/Bigdata/mpp/omm/pg_log/cn_*/${arrylist[$fileNums-2]} | grep -v postgres | grep -E -i -A 1 ": insert|: update|: delete" | grep '\$' | grep -v -i ": select " >> /srv/BigData/mppdb/data1/log/${arrylist[$fileNums-2]}.log
完整实现脚本如下
#log_extraction.sh
#!/bin/bash
#get all filename in specified path
source /opt/huawei/Bigdata/mppdb/.mppdbgs_profile
#获取当前时间精确到小时(2小时),和日志文件名相同
date_tmp=`date "+%Y-%m-%d_%H"`
date1_tmp=`date -d "1 hour ago" "+%Y-%m-%d_%H"`
#获取当前两小时文件数量
countNums=`ls /var/log/Bigdata/mpp/omm/pg_log/cn_* | grep -E "$date_tmp|$date1_tmp" |wc -l`
while true
do
date=`date "+%Y-%m-%d_%H"`
date1=`date -d "1 hour ago" "+%Y-%m-%d_%H"`
#读取两小时文件列表
fileList=`ls /var/log/Bigdata/mpp/omm/pg_log/cn_*| grep -E "$date|$date1"`
fileNums=`ls /var/log/Bigdata/mpp/omm/pg_log/cn_* | grep -E "$date|$date1" |wc -l`
#当文件数新增1时
if [ $((10#$fileNums)) -eq $((10#$countNums+1)) ]
then
#将文件列表转存为数组
set i=0
for file in $fileList
do
arrylist[i]=$file
i=$[$i+1]
done
#根据过滤条件提取刚生成的日志文件
cat /var/log/Bigdata/mpp/omm/pg_log/cn_*/${arrylist[$fileNums-2]} | grep -v postgres | grep -E -i ": insert|: update|: delete" | grep -v -i ": select " | grep -v '\$' > /srv/BigData/mppdb/data1/log/${arrylist[$fileNums-2]}.log
cat /var/log/Bigdata/mpp/omm/pg_log/cn_*/${arrylist[$fileNums-2]} | grep -v postgres | grep -E -i -A 1 ": insert|: update|: delete" | grep '\$' | grep -v -i ": select " >> /srv/BigData/mppdb/data1/log/${arrylist[$fileNums-2]}.log
#将文件按时间排序
sort -k2nr /srv/BigData/mppdb/data1/log/${arrylist[$fileNums-2]}.log > /srv/BigData/mppdb/data1/log/recored_${arrylist[$fileNums-2]}
rm /srv/BigData/mppdb/data1/log/${arrylist[$fileNums-2]}.log
fi
#更新外部参数
countNums=$fileNums
sleep 10
done
- 点赞
- 收藏
- 关注作者
评论(0)