文章目录
- 1. 数据挖掘:/etc/rc.local,sudo su
- 2.HTTP协议:优先wget
- 3.非结构化数据存储:blob,pzhrain24file
- 4.数据管理子系统:数据字典表
- 5.监控告警子系统:tmpfs,top,/proc/stat,/proc/meminfo,mount ,processes
- 5.1 du,df,fdisk,lsblk:磁盘=硬盘
- 5.2 文件:建表入表,传输
1. 数据挖掘:/etc/rc.local,sudo su
数据挖掘dmining和数据交换exptables差不多(exptables自己设计数据表有keyid字段,从其他地方拿数据未必有keyid字段需要指定,也就是数据是增量的,但不提供增量提取方式即没有keyid字段),将数据从数据库中取出导入文件(执行一个sql拿出数据)。vi /etc/rc.local(随操作系统自启动)。
vi /htidc/gz…sh上面如下,如下要写的其实就是< selectsql >字段里内容。比如取近一小时数据,每次取到都有重复,但在入库时(获取到的数据生成xml再入自己库)处理重复就行。
#include "_public.h"
#include "_ooci.h"
struct st_arg
{char connstr
[101];char charset
[51];char tname
[51];char cols
[1001];char fieldname
[1001];char fieldlen
[501];int exptype
;char andstr
[501];char bname
[51];char ename
[51];char idfieldname
[51];char idfilename
[301];char exppath
[301];int timetvl
;
} starg
;
CLogFile logfile
;
connection conn
;
bool
_dmintables();
void EXIT(int sig
);
vector
<string
> vfieldname
;
vector
<int> vfieldlen
;
int maxfieldlen
;
void SplitFields();
void _help(char *argv
[]);
long maxkeyid
;
bool
LoadMaxKeyid();
bool
UptMaxKeyid();
bool
_xmltoarg(char *strxmlbuffer
);int main(int argc
,char *argv
[])
{if (argc
!=3) { _help(argv
); return -1; }CloseIOAndSignal();signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[1],"a+")==false
){printf("打开日志文件失败(%s)。\n",argv
[1]); return -1;} if (_xmltoarg(argv
[2])==false
) return -1; while (true
){if (conn
.connecttodb(starg
.connstr
,starg
.charset
) != 0){logfile
.Write("connect database %s failed.\n",starg
.connstr
); sleep(starg
.timetvl
); continue;}if (_dmintables() == false
) logfile
.Write("export tables failed.\n");conn
.disconnect(); sleep(starg
.timetvl
);}return 0;
}
void EXIT(int sig
)
{logfile
.Write("程序退出,sig=%d\n\n",sig
);exit(0);
}
void _help(char *argv
[])
{printf("\n");printf("Using:/htidc/public/bin/dminoracle logfilename xmlbuffer\n\n");printf("增量挖掘示例:\n");printf("Sample:/htidc/public/bin/dminoracle /log/shqx/dminoracle_surfdata_from_qx.log \"<connstr>shqx/pwdidc@snorcl11g_198</connstr><charset>Simplified Chinese_China.ZHS16GBK</charset><tname>T_SURFDATA</tname><cols>obtid,to_char(ddatetime,'yyyymmddhh24miss'),t,p,u,wd,wf,r,vis</cols><fieldname>obtid,ddatetime,t,p,u,wd,wf,r,vis</fieldname><fieldlen>5,14,8,8,8,8,8,8,8</fieldlen><exptype>1</exptype><andstr> and obtid in ('59293','50745')</andstr><bname>SURFDATA_</bname><ename>_from_qx</ename><idfilename>/data/dmin/SURFDATA_from_qx.txt</idfilename><idfieldname>keyid</idfieldname><exppath>/data/shqx/sdata/fromqx</exppath><timetvl>30</timetvl>\"\n\n");printf("全量挖掘示例:\n");printf("Sample:/htidc/public/bin/dminoracle /log/shqx/dminoracle_obtcode_from_qx.log \"<connstr>shqx/pwdidc@snorcl11g_198</connstr><charset>Simplified Chinese_China.ZHS16GBK</charset><tname>T_OBTCODE</tname><cols>obtid,obtname,provname,lat,lon,height</cols><fieldname>obtid,obtname,provname,lat,lon,height</fieldname><fieldlen>5,30,30,8,8,8</fieldlen><exptype>2</exptype><andstr> and rsts=1 and obtid in ('59293','50745')</andstr><bname>OBTCODE_</bname><ename>_from_qx</ename><exppath>/data/shqx/sdata/fromqx</exppath><timetvl>300</timetvl>\"\n\n");printf("本程序是数据中心的公共功能模块,从其它业务系统的数据库中挖掘数据,用于入库到数据中心。\n");printf("logfilename是本程序运行的日志文件。\n");printf("xmlbuffer为文件传输的参数,如下:\n");printf("数据库的连接参数 <connstr>shqx/pwdidc@snorcl11g_198</connstr>\n");printf("数据库的字符集 <charset>Simplified Chinese_China.ZHS16GBK</charset> 这个参数要与数据源数据库保持>一致,否则会出现中文乱码的情况。\n");printf("待挖掘数据的表名 <tname>T_SURFDATA</tname>\n");printf("需要挖掘字段的列表 <cols>obtid,to_char(ddatetime,'yyyymmddhh24miss'),t,p,u,wd,wf,r,vis</cols> 可以采用函数。\n");printf("挖掘字段的别名列表 <fieldname>obtid,ddatetime,t,p,u,wd,wf,r,vis</fieldname> 必须与cols一一对应。\n");printf("挖掘字段的长度列表 <fieldlen>5,14,8,8,8,8,8,8,8</fieldlen> 必须与cols一一对应。\n");printf("挖掘数据的方式 <exptype>1</exptype> 1-增量挖掘;2-全量挖掘,如果是增量挖掘,要求表一定要有表达记录序号的id字段。\n");printf("挖掘数据的附加条件 <andstr> and obtid in ('59293','50745')</andstr> 注意,关键字and不能少。\n");printf("数据文件的命名的前部分 <bname>SURFDATA_</bname>\n");printf("数据文件的命名的后部分 <ename>_from_qx</ename>\n");printf("挖掘数据表记录号字段名 <idfieldname>keyid</idfieldname> 当exptype=1时该参数有效。\n");printf("已挖掘数据id保存的文件名 <idfilename>/data/dmin/SURFDATA_from_qx.txt</idfilename> 当exptype=1时该参数有效。\n");printf("挖掘文件存放的目录 <exppath>/data/shqx/sdata/fromqx</exppath>\n");printf("挖掘数据的时间间隔 <timetvl>30</timetvl> 单位:秒,建议大于10。\n");printf("以上参数,除了idfieldname、idfilename和andstr,其它字段都不允许为空。\n\n\n");
}
bool
_xmltoarg(char *strxmlbuffer
)
{memset(&starg
,0,sizeof(struct st_arg));GetXMLBuffer(strxmlbuffer
,"connstr",starg
.connstr
);if (strlen(starg
.connstr
)==0) { logfile
.Write("connstr is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"charset",starg
.charset
);if (strlen(starg
.charset
)==0) { logfile
.Write("charset is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"tname",starg
.tname
);if (strlen(starg
.tname
)==0) { logfile
.Write("tname is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"cols",starg
.cols
);if (strlen(starg
.cols
)==0) { logfile
.Write("cols is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"fieldname",starg
.fieldname
);if (strlen(starg
.fieldname
)==0) { logfile
.Write("fieldname is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"fieldlen",starg
.fieldlen
);if (strlen(starg
.fieldlen
)==0) { logfile
.Write("fieldlen is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"exptype",&starg
.exptype
);if ( (starg
.exptype
!=1) && (starg
.exptype
!=2) ) { logfile
.Write("exptype is not in (1,2).\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"andstr",starg
.andstr
);if (strlen(starg
.andstr
)==0) { logfile
.Write("andstr is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"bname",starg
.bname
);if (strlen(starg
.bname
)==0) { logfile
.Write("bname is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"ename",starg
.ename
);if (strlen(starg
.ename
)==0) { logfile
.Write("ename is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"idfieldname",starg
.idfieldname
);if ( (starg
.exptype
==1) && (strlen(starg
.idfieldname
)==0) ) { logfile
.Write("idfieldname is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"idfilename",starg
.idfilename
);if ( (starg
.exptype
==1) && (strlen(starg
.idfilename
)==0) ) { logfile
.Write("idfilename is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"exppath",starg
.exppath
);if (strlen(starg
.exppath
)==0) { logfile
.Write("exppath is null.\n"); return false
; }GetXMLBuffer(strxmlbuffer
,"timetvl",&starg
.timetvl
);if (starg
.timetvl
==0) { logfile
.Write("timetvl is null.\n"); return false
; }SplitFields();if (vfieldname
.size() != vfieldlen
.size() ) { logfile
.Write("fieldname和fieldlen的元素个数不同。.\n"); return false
; }return true
;
}
bool
_dmintables()
{if (LoadMaxKeyid()==false
) { logfile
.Write("LoadMaxKeyid() failed.\n"); return false
; }char strsql
[4096]; char fieldvalue
[vfieldname
.size()][maxfieldlen
+1]; memset(strsql
,0,sizeof(strsql
));if (starg
.exptype
==1)sprintf(strsql
,"select %s,%s from %s where 1=1 and %s>%ld %s order by %s",starg
.cols
,starg
.idfieldname
,starg
.tname
,starg
.idfieldname
,maxkeyid
,starg
.andstr
,starg
.idfieldname
);elsesprintf(strsql
,"select %s from %s where 1=1 %s",starg
.cols
,starg
.tname
,starg
.andstr
);sqlstatement
stmt(&conn
);stmt
.prepare(strsql
);for (int ii
=0;ii
<vfieldname
.size();ii
++){stmt
.bindout(ii
+1,fieldvalue
[ii
],vfieldlen
[ii
]);} if (starg
.exptype
==1) stmt
.bindout(vfieldname
.size()+1,&maxkeyid
); if (stmt
.execute() != 0) {logfile
.Write("select %s failed.\n%s\n%s\n",starg
.tname
,stmt
.m_cda
.message
,stmt
.m_sql
); return false
;}int iFileSeq
=1; char strFileName
[301],strLocalTime
[21];CFile File
;while (true
){memset(fieldvalue
,0,sizeof(fieldvalue
)); if (stmt
.next() !=0) break; if (File
.IsOpened()==false
) {memset(strLocalTime
,0,sizeof(strLocalTime
));LocalTime(strLocalTime
,"yyyymmddhh24miss");memset(strFileName
,0,sizeof(strFileName
));sprintf(strFileName
,"%s/%s%s%s_%d.xml",starg
.exppath
,starg
.bname
,strLocalTime
,starg
.ename
,iFileSeq
++);if (File
.OpenForRename(strFileName
,"w")==false
){logfile
.Write("File.OpenForRename(%s) failed.\n",strFileName
); return false
;}File
.Fprintf("<data>\n");}for (int ii
=0;ii
<vfieldname
.size();ii
++){File
.Fprintf("<%s>%s</%s>",vfieldname
[ii
].c_str(),fieldvalue
[ii
],vfieldname
[ii
].c_str());}File
.Fprintf("<endl/>\n");if (stmt
.m_cda
.rpc
%1000==0) {File
.Fprintf("</data>\n");if (File
.CloseAndRename()==false
){logfile
.Write("File.CloseAndRename(%s) failed.\n",strFileName
); return false
;}if (UptMaxKeyid()==false
) { logfile
.Write("UptMaxKeyid() failed.\n"); return false
; }logfile
.Write("create file %s ok.\n",strFileName
);}}if (File
.IsOpened()==true
){File
.Fprintf("</data>\n");if (File
.CloseAndRename()==false
){logfile
.Write("File.CloseAndRename(%s) failed.\n",strFileName
); return false
;}if (UptMaxKeyid()==false
) { logfile
.Write("UptMaxKeyid() failed.\n"); return false
; }logfile
.Write("create file %s ok.\n",strFileName
);}if (stmt
.m_cda
.rpc
>0) logfile
.Write("本次挖掘了%d条记录。\n",stmt
.m_cda
.rpc
);return true
;
}
void SplitFields()
{vfieldname
.clear(); vfieldlen
.clear(); maxfieldlen
=0; CCmdStr CmdStr
;CmdStr
.SplitToCmd(starg
.fieldname
,",");vfieldname
.swap(CmdStr
.m_vCmdStr
);int ifieldlen
=0;CmdStr
.SplitToCmd(starg
.fieldlen
,",");for (int ii
=0;ii
<CmdStr
.CmdCount();ii
++){ CmdStr
.GetValue(ii
,&ifieldlen
);if (ifieldlen
>maxfieldlen
) maxfieldlen
=ifieldlen
; vfieldlen
.push_back(ifieldlen
);}
}
bool
LoadMaxKeyid()
{if (starg
.exptype
!=1) return true
;CFile File
;if (File
.Open(starg
.idfilename
,"r")==false
) {logfile
.Write("注意,%s文件不存在,程序将从新开始挖掘数据。\n",starg
.idfilename
); return true
;}char strBuf
[21];memset(strBuf
,0,sizeof(strBuf
));File
.Fread(strBuf
,20);maxkeyid
=atol(strBuf
);logfile
.Write("maxkeyid=%d\n",maxkeyid
);return true
;
}
bool
UptMaxKeyid()
{if (starg
.exptype
!=1) return true
;CFile File
;if (File
.Open(starg
.idfilename
,"w")==false
) {logfile
.Write("File.Open(%s) failed.\n",starg
.idfilename
); return false
;}File
.Fprintf("%ld",maxkeyid
);return true
;
}
2.HTTP协议:优先wget
数据共享平台也有一个web系统(服务端)用java做的,vi /etc/rc.local如下。
如下http客户端访问不了,startup后可访问。
按照http格式向网站发报文也会得到回应,如下http客户端。
wgetclient是用wget命令下载,httpclient下载的内容有时候会有断行,wget下载不会。优先wget,wget下载不了的用http。wget支持http,https,ftp,sftp等协议。linux下同步文件rsync,curl,wget,ftp,sftp。
如上调用接口,如下还可以右击网页上图片复制图片地址。
程序在后台跑,有新图就拿下来,wgetclient将网页内容全弄下来,搞清图片命名规律进行解析。
#include "_public.h"
void EXIT(int sig
);
CLogFile logfile
;
int main(int argc
, char *argv
[])
{if(argc
!=6){printf("Usage:%s weburl tmpfilename outputfilename logfilename charset\n",argv
[0]); printf("本程序用于获取WEB网页的内容。\n");printf("weburl 网页WEB的地址。\n");printf("tmpfilename 获取到的网页的内容存放的全路径的临时文件名,该文件可能是utf-8或其它编码。\n");printf("outputfilename 最终的输出文件全路径文件名,该文件是gb18030编码,注意tmpfilename被转换为outputfilename后,tmpfilename文件被自动删除。\n");printf("logfilename 本程序的运行产生的日志文件名。\n");printf("charset 网页的字符集,如utf-8\n\n");exit(1);}CloseIOAndSignal(); signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[4],"a+") == false
){printf("logfile.Open(%s) failed.\n",argv
[4]); return -1;}MKDIR(argv
[2],true
); MKDIR(argv
[3],true
);char strweburl
[3001];memset(strweburl
,0,sizeof(strweburl
));strncpy(strweburl
,argv
[1],3000);char strcmd
[3024];memset(strcmd
,0,sizeof(strcmd
));snprintf(strcmd
,3000,"/usr/bin/wget -c -q -O %s \"%s\" 1>>/dev/null 2>>/dev/null",argv
[2],strweburl
);system(strcmd
);logfile
.Write("%s\n",strcmd
);char strfilenametmp
[301];memset(strfilenametmp
,0,sizeof(strfilenametmp
));snprintf(strfilenametmp
,300,"%s.tmp",argv
[3]);memset(strcmd
,0,sizeof(strcmd
));snprintf(strcmd
,256,"iconv -c -f %s -t gb18030 %s -o %s",argv
[5],argv
[2],strfilenametmp
);system(strcmd
);logfile
.Write("%s\n",strcmd
);REMOVE(argv
[2]); RENAME(strfilenametmp
,argv
[3]);return 0;
}void EXIT(int sig
)
{if (sig
> 0) signal(sig
,SIG_IGN
);logfile
.Write("catching the signal(%d).\n",sig
);logfile
.Write("wgetclient exit.\n");exit(0);
}
#include "_public.h"
void EXIT(int sig
);
CLogFile logfile
;
bool
GetURL(char *strBuffer
,char *strURL
,char *strFileName
);
int main(int argc
, char *argv
[])
{if(argc
!=4){printf("Usage:%s logfilename tmpfilename outputfilename\n",argv
[0]); printf("Sample:./wgetrain24 /log/shqx/wgetrain24.log /data/wgettmp /data/wfile/zhrain24\n\n");printf("本程序用于从中国天气网获取逐小时降雨量实况图。\n");printf("中国天气网的url是http://products.weather.com.cn/product/Index/index/procode/JC_JSL_ZH.shtml\n");printf("如果中国天气网的url改变,程序也在做改动。\n");printf("logfilename 本程序的运行产生的日志文件名。\n");printf("tmpfilename 本程序运行产生的临时文件存放的目录。\n");printf("获取逐小时降雨量实况图存放的目录。\n\n");exit(1);}CloseIOAndSignal(); signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[1],"a+") == false
){printf("logfile.Open(%s) failed.\n",argv
[1]); return -1;}MKDIR(argv
[2],false
); MKDIR(argv
[3],false
);while (true
){ char strwgetclient
[2001]; memset(strwgetclient
,0,sizeof(strwgetclient
));snprintf(strwgetclient
,2000,"/htidc/public/bin/wgetclient \"http://products.weather.com.cn/product/Index/index/procode/JC_JSL_ZH.shtml\" %s/wgetclient_%d.tmp %s/wgetclient_%d.html %s/wgetclient.log utf-8",argv
[2],getpid(),argv
[2],getpid(),argv
[2]);system(strwgetclient
);char stroutputfile
[301];memset(stroutputfile
,0,sizeof(stroutputfile
));snprintf(stroutputfile
,300,"%s/wgetclient_%d.html",argv
[2],getpid());CFile File
;if (File
.Open(stroutputfile
,"r")==false
){logfile
.Write("File.Open(%s) failed.\n",stroutputfile
); sleep(60); continue;} char strBuffer
[1001],strURL
[501],strFullFileName
[301],strFileName
[101]; while (true
){memset(strBuffer
,0,sizeof(strBuffer
));memset(strURL
,0,sizeof(strURL
));memset(strFullFileName
,0,sizeof(strFullFileName
));memset(strFileName
,0,sizeof(strFileName
)); if (File
.Fgets(strBuffer
,1000)==false
) break; if (MatchFileName(strBuffer
,"*PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20*.JPG*")==false
) continue; if (GetURL(strBuffer
,strURL
,strFileName
)==false
) continue; snprintf(strFullFileName
,300,"%s/%s",argv
[3],strFileName
); if (access(strFullFileName
,F_OK
)==0) continue; logfile
.Write("download %s ",strFileName
); memset(strwgetclient
,0,sizeof(strwgetclient
));snprintf(strwgetclient
,500,"wget \"%s\" -o %s/wgetrain24.log -O %s",strURL
,argv
[2],strFullFileName
);system(strwgetclient
); if (access(strFullFileName
,F_OK
)==0) logfile
.WriteEx("ok.\n");else logfile
.WriteEx("failed.\n");} File
.CloseAndRemove();sleep(60);}return 0;
}bool
GetURL(char *strBuffer
,char *strURL
,char *strFileName
)
{char *start
,*end
;start
=end
=0;if ((start
=strstr(strBuffer
,"http"))==0) return false
;if ((end
=strstr(start
,"\""))==0) return false
; strncpy(strURL
,start
,end
-start
);strcpy(strFileName
,strstr(strURL
,"PWCP"));return true
;
}
void EXIT(int sig
)
{if (sig
> 0) signal(sig
,SIG_IGN
);logfile
.Write("catching the signal(%d).\n",sig
);logfile
.Write("wgetclient exit.\n");exit(0);
}
3.非结构化数据存储:blob,pzhrain24file
#include "_ooci.h"
int main(int argc
,char *argv
[])
{connection conn
; if (conn
.connecttodb("scott/tiger@snorcl11g_198","Simplified Chinese_China.ZHS16GBK") != 0){printf("connect database %s failed.\n%s\n","scott/tiger@orcl",conn
.m_cda
.message
); return -1;} sqlstatement
stmt(&conn
); stmt
.prepare("\BEGIN\delete from goods;\insert into goods(id,name,pic) values(1,'商品名称',empty_blob());\END;"); if (stmt
.execute() != 0){printf("stmt.execute() failed.\n%s\n%s\n",stmt
.m_sql
,stmt
.m_cda
.message
); return -1;}stmt
.prepare("select pic from goods where id=1 for update");stmt
.bindblob();if (stmt
.execute() != 0){printf("stmt.execute() failed.\n%s\n%s\n",stmt
.m_sql
,stmt
.m_cda
.message
); return -1;}if (stmt
.next() != 0) return 0; if (stmt
.filetolob((char *)"pic_in.jpg") != 0){printf("stmt.filetolob() failed.\n%s\n",stmt
.m_cda
.message
); return -1;} conn
.commit(); return 0;
}
#include "_public.h"
#include "_ooci.h"
#include "_shqx.h"
CLogFile logfile
;
CDir Dir
;
bool
_pzhrain24file(char *strargv2
,char *strargv4
,char *strargv5
);
connection conn
;
void EXIT(int sig
);int main(int argc
,char *argv
[])
{if (argc
!=7){printf("\n本程序用于处理全国逐小时雨量实况图片文件。\n\n");printf("/htidc/shqx/bin/pzhrain24file logfilename connstr srcpathname dstpathname tname timetvl\n");printf("例如:/htidc/shqx/bin/pzhrain24file /log/shqx/pzhrain24file.log shqx/pwdidc@snorcl11g_198 /data/wfile/zhrain24 /qxfile/zhrain24 T_ZHRAIN24 30\n");printf("logfilename 本程序运行的日志文件名。\n");printf("connstr 数据库的连接参数。\n");printf("srcpathname 原始文件存放的目录,文件命名如PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20191101070000000.JPG。\n");printf("dstpathname 目标文件存放的目录,文件按yyyy/mm/dd组织目录,重命名为zhrain24_yyyymmddhh24miss.jpg。\n");printf("tname 数据存放的表名。\n");printf("timetvl 本程序运行的时间间隔,单位:秒。\n");return -1;}CloseIOAndSignal();signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[1],"a+")==false
){printf("打开日志文件失败(%s)。\n",argv
[1]); return -1;}logfile
.Write("程序启动。\n");while (true
){if (Dir
.OpenDir(argv
[3],"PWCP_TWC_WEAP_SFER_ER1_TWC_L88_P9_20*.JPG",1000,true
,true
)==false
){logfile
.Write("Dir.OpenDir(%s) failed.\n",argv
[3]); sleep(atoi(argv
[6])); continue;} while (true
) {if (Dir
.ReadDir()==false
) break;if (_pzhrain24file(argv
[2],argv
[4],argv
[5])==false
) {logfile
.WriteEx("失败。\n"); continue;}}if (conn
.m_state
==1) conn
.disconnect(); sleep(atoi(argv
[6]));}return 0;
}
void EXIT(int sig
)
{logfile
.Write("程序退出,sig=%d\n\n",sig
);exit(0);
}
bool
_pzhrain24file(char *strargv2
,char *strargv4
,char *strargv5
)
{char strddatetime
[21]; memset(strddatetime
,0,sizeof(strddatetime
));strncpy(strddatetime
,strstr(Dir
.m_FileName
,"20"),14);char strdstfilename
[301]; memset(strdstfilename
,0,sizeof(strdstfilename
));snprintf(strdstfilename
,300,"zhrain24_%s.jpg",strddatetime
);char strdstfilepath
[301]; memset(strdstfilepath
,0,sizeof(strdstfilepath
));snprintf(strdstfilepath
,300,"%s/",strargv4
);strncat(strdstfilepath
,strddatetime
,4); strcat(strdstfilepath
,"/"); strncat(strdstfilepath
,strddatetime
+4,2); strcat(strdstfilepath
,"/"); strncat(strdstfilepath
,strddatetime
+6,2); strcat(strdstfilepath
,"/"); char strfulldstfilename
[301]; memset(strfulldstfilename
,0,sizeof(strfulldstfilename
));snprintf(strfulldstfilename
,300,"%s%s",strdstfilepath
,strdstfilename
);if (access(strfulldstfilename
,F_OK
) == 0) return true
;if (conn
.m_state
==0){if (conn
.connecttodb(strargv2
,"Simplified Chinese_China.ZHS16GBK")!=0){logfile
.Write("connect database(%s) failed.\n%s\n",strargv2
,conn
.m_cda
.message
); return false
;}}if (COPY(Dir
.m_FullFileName
,strfulldstfilename
)==false
) {logfile
.Write("复制文件COPY(%s,%s)...failed.\n",Dir
.m_FullFileName
,strfulldstfilename
); return false
;}if (FileToTable(&conn
,&logfile
,strargv5
,strfulldstfilename
,strddatetime
)!=0){logfile
.Write("把文件%s存入%s...failed.\n",strfulldstfilename
,strargv5
); return false
;}logfile
.Write("把文件%s存入%s...ok.\n",strfulldstfilename
,strargv5
); return true
;
}
4.数据管理子系统:数据字典表
Oracle数据字典:是一组表和视图的结构(就像仓库里有什么,每种有多少,哪些空间可用等日记)。自己创建的表,oracle会将这表的信息自动写入系统表,系统表上再创建一视图供客户查看。数据字典中的表是不能被访问修改(自己用的),但是可以访问数据字典的视图就可以知道自己创建的表的详细信息。
tab也是视图,tab里面表,视图,同义词都可以查到。若是select * from dba_tables;必须是dba用户才可以查,三类user_,all_,dba_
数据量大了会出现性能和数据管理,迁移,备份问题。假如有1亿数据量,不能用exp导出,一个文件有几百G导出要一天。索引设计要合理,不然table scan跑不动。一亿以下的数据单表存放,一亿以上的数据考虑分表,十亿虽然比一亿容量大十倍,但性能不会下降十倍,因为索引(比如按首字母找名字)。
如下并行数据库分布式查询可解决多表性能低的问题。
写一些程序实现数据管理,数据删除(deletables.cpp)或放历史表等等。三种表数据结构一样,迁移数据可写成一个通用功能模块程序。若是不同表,只知道表名去查询数据字典得到数据结构。如下hsmtable.cpp(和deletetable.cpp像):数据源表就是要把数据从哪个表迁移出来,列名从数据字典取出,把列拼成一个字符串,获取列名后把数据rowid从源表查出来,生成插入目的表sql,删除源表sql。
#include "_public.h"
#include "_ooci.h"
char logfilename
[301];
char connstr
[101];
char srctname
[51];
char dsttname
[51];
char where
[1024];
char hourstr
[101];
char localhour
[21];
int maxcount
=1;
connection conn
;
CLogFile logfile
;
void EXIT(int sig
);
char strColumnStr
[2048];
bool
GetColumnStr();
void _help(char *argv
[]);
bool
_hsmtables();int main(int argc
,char *argv
[])
{if (argc
!= 2) { _help(argv
); return -1; }memset(logfilename
,0,sizeof(logfilename
));memset(connstr
,0,sizeof(connstr
));memset(srctname
,0,sizeof(srctname
));memset(dsttname
,0,sizeof(dsttname
));memset(where
,0,sizeof(where
));memset(hourstr
,0,sizeof(hourstr
));GetXMLBuffer(argv
[1],"logfilename",logfilename
,300);GetXMLBuffer(argv
[1],"connstr",connstr
,100);GetXMLBuffer(argv
[1],"srctname",srctname
,50);GetXMLBuffer(argv
[1],"dsttname",dsttname
,50);GetXMLBuffer(argv
[1],"where",where
,1000);GetXMLBuffer(argv
[1],"maxcount",&maxcount
);GetXMLBuffer(argv
[1],"hourstr",hourstr
,2000);if (strlen(logfilename
) == 0) { printf("logfilename is null.\n"); return -1; }if (strlen(connstr
) == 0) { printf("connstr is null.\n"); return -1; }if (strlen(srctname
) == 0) { printf("srctname is null.\n"); return -1; }if (strlen(dsttname
) == 0) { printf("dsttname is null.\n"); return -1; }if (strlen(where
) == 0) { printf("where is null.\n"); return -1; }if ( (maxcount
<1) || (maxcount
>1000) ) { printf("maxcount %d is invalid,should in 1-1000.\n",maxcount
); return -1; }if (strlen(hourstr
) == 0) { printf("hourstr is null.\n"); return -1; }CloseIOAndSignal();signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(logfilename
,"a+") == false
){printf("logfile.Open(%s) failed.\n",logfilename
); return -1;}while (true
){ memset(localhour
,0,sizeof(localhour
)); LocalTime(localhour
,"hh24");if (strstr(hourstr
,localhour
)==0) { sleep(60); continue; }if (conn
.connecttodb(connstr
,"Simplified Chinese_China.ZHS16GBK") != 0){logfile
.Write("connect database %s failed.\n",connstr
); sleep(60); continue; }logfile
.Write("from table %s to %s.\n",srctname
,dsttname
);if (_hsmtables() == false
) logfile
.Write("_hsmtables failed.\n"); conn
.disconnect();sleep(60); }return 0;
}
void EXIT(int sig
)
{printf("程序退出,sig=%d\n\n",sig
);exit(0);
}
void _help(char *argv
[])
{printf("\nUsing:/htidc/public/bin/hsmtables \"<logfilename>/log/shqx/hsmtables_SURFDATA.log</logfilename><connstr>shqx/pwdidc@snorcl11g_198</connstr><srctname>T_SURFDATA</srctname><dsttname>T_SURFDATA_HIS</dsttname><where>where ddatetime<sysdate-10</where><maxcount>500</maxcount><hourstr>23,01,02,03,04,05,06</hourstr>\"\n\n");printf("这是一个工具程序,用于清理表中的数据。\n");printf("<logfilename>/log/shqx/hsmtables_SURFDATA.log</logfilename> 本程序运行日志文件名。\n");printf("<connstr>szidc/pwdidc@SZQX_10.153.97.251</connstr> 目的数据库的连接参数。\n");printf("<srctname>T_SURFDATA</srctname> 数据源表名。\n");printf("<dsttname>T_SURFDATA_HIS</dsttname> 目的数据表名。\n");printf("<where>where ddatetime<sysdate-10</where> 待迁移数据的条件。\n");printf("<maxcount>500</maxcount> 单次执行数据迁移的记录数,取值在1-1000之间。\n");printf("<hourstr>23,01,02,03,04,05,06</hourstr> 本程序启动的时次,小时,时次之间用半角的逗号分隔开。\n\n");return;
}
bool
_hsmtables()
{ if (GetColumnStr() == false
) return false
; int ccount
=0;char strrowid
[51],strrowidn
[maxcount
][51];sqlstatement
selstmt(&conn
); selstmt
.prepare("select rowid from %s %s",srctname
,where
);selstmt
.bindout(1, strrowid
,50);if (selstmt
.execute() != 0){logfile
.Write("%s failed.\n%s\n",selstmt
.m_sql
,selstmt
.m_cda
.message
); return false
;}int ii
=0; char strInsertSQL
[10241],strDeleteSQL
[10241];memset(strInsertSQL
,0,sizeof(strInsertSQL
));memset(strDeleteSQL
,0,sizeof(strDeleteSQL
));sprintf(strInsertSQL
,"insert into %s(%s) select %s from %s where rowid in (",dsttname
,strColumnStr
,strColumnStr
,srctname
);sprintf(strDeleteSQL
,"delete from %s where rowid in (",srctname
);char strtemp
[11];for (ii
=0; ii
<maxcount
; ii
++){memset(strtemp
,0,sizeof(strtemp
));if (ii
==0) sprintf(strtemp
,":%d",ii
+1);if (ii
>0) sprintf(strtemp
,",:%d",ii
+1);strcat(strInsertSQL
,strtemp
);strcat(strDeleteSQL
,strtemp
);}strcat(strInsertSQL
,")");strcat(strDeleteSQL
,")");sqlstatement
insstmt(&conn
);insstmt
.prepare(strInsertSQL
);sqlstatement
delstmt(&conn
);delstmt
.prepare(strDeleteSQL
);for (ii
=0; ii
<maxcount
; ii
++){insstmt
.bindin(ii
+1,strrowidn
[ii
],50);delstmt
.bindin(ii
+1,strrowidn
[ii
],50);}while (true
) {memset(strrowid
,0,sizeof(strrowid
));if (selstmt
.next() != 0) break;strcpy(strrowidn
[ccount
],strrowid
);ccount
++;if (ccount
== maxcount
){if (insstmt
.execute() != 0){if (insstmt
.m_cda
.rc
!= 1){logfile
.Write("_hsmtables insert %s failed.\n%s\n",dsttname
,insstmt
.m_cda
.message
); return false
;}}if (delstmt
.execute() != 0){logfile
.Write("_hsmtables delete %s failed.\n%s\n",dsttname
,insstmt
.m_cda
.message
); return false
;}conn
.commit();memset(strrowidn
,0,sizeof(strrowidn
));ccount
=0;}if (fmod(selstmt
.m_cda
.rpc
,10000) < 1){logfile
.Write("%s to %s ok(%d).\n",srctname
,dsttname
,selstmt
.m_cda
.rpc
); memset(localhour
,0,sizeof(localhour
)); LocalTime(localhour
,"hh24");if (strstr(hourstr
,localhour
)==0) return true
;}}for (ii
=0; ii
<ccount
; ii
++){insstmt
.prepare("\BEGIN\insert into %s(%s) select %s from %s where rowid=:1;\delete from %s where rowid=:2;\END;",dsttname
,strColumnStr
,strColumnStr
,srctname
,srctname
);insstmt
.bindin(1,strrowidn
[ii
],50);insstmt
.bindin(2,strrowidn
[ii
],50);if (insstmt
.execute() != 0){if (insstmt
.m_cda
.rc
!= 1){logfile
.Write("_hsmtables insert %s or delete %s failed.\n%s\n",dsttname
,srctname
,insstmt
.m_cda
.message
); return false
;}}}conn
.commit(); logfile
.Write("%s to %s finish(%d).\n",srctname
,dsttname
,selstmt
.m_cda
.rpc
);return true
;
}
bool
GetColumnStr()
{memset(strColumnStr
,0,sizeof(strColumnStr
)); char column_name
[51];sqlstatement
stmt(&conn
);stmt
.prepare("select lower(column_name) from USER_TAB_COLUMNS where table_name=upper('%s') order by column_id",dsttname
);stmt
.bindout(1,column_name
,50);if (stmt
.execute() != 0){logfile
.Write("%s failed.\n%s\n",stmt
.m_sql
,stmt
.m_cda
.message
); return false
;}while(true
){memset(column_name
,0,sizeof(column_name
));if (stmt
.next()!=0) break;if (stmt
.m_cda
.rpc
>1) strcat(strColumnStr
,",");strcat(strColumnStr
,column_name
);}if (stmt
.m_cda
.rpc
==0) { logfile
.Write("表%s不存在。\n",dsttname
); return false
; }return true
;
}
$sqlplus shqx/pwdidc,如下数据都是一小时前生成,需要将后台生成数据脚本启动。
如下是数据迁移程序如何兼容其他数据库,oracle有rowid,mysql和pg都没有rowid但有keyid。
不管id字段是数字还是字符或字符串,我们都可用字符绑定。
如下不同数据库查数据字典得到全部列。
5.监控告警子系统:tmpfs,top,/proc/stat,/proc/meminfo,mount ,processes
我们处理后台数据也会有一个web系统用来管理参数,展示数据,查询数据等界面(不能让用户去登录plsqldeveloper查询)。如下是数据的监控,数据少于某数量显示红色。
如下日志等等都在sda(raid1,2个300G)中。
5.1 du,df,fdisk,lsblk:磁盘=硬盘
du:Disk Usage。-a:不仅统计目录还包括文件大小。-h:显示K/M/G等字节信息。-s:总的占用空间大小(-a是每个都统计)。一般文件夹大小4096b即4k(不包含里面文件大小)。
df:Disk Free。如果你想知道某个文件夹或文件大小用du,磁盘相关使用情况用df。
5.2 文件:建表入表,传输
以下是收集磁盘空间信息,现在插入一个U盘,fdisk -l可以看到U盘。
每个服务器上运行一个收集磁盘空间的小程序,收集到磁盘空间后生成xml文件存放在本地目录,通过文件传输系统或ftp将文件传给数据处理服务器(因为有的服务器不安装oracle客户端,只可安装文件传输客户端),统一保存到数据库。
#include "_public.h"
void EXIT(int sig
);
CLogFile logfile
;int main(int argc
,char *argv
[])
{if (argc
!= 4){printf("\n");printf("Using:./diskinfo hostname logfilename outputpath\n");printf("Example:/htidc/public/bin/diskinfo 118.89.50.198 /tmp/htidc/log/diskinfo.log /tmp/htidc/monclient\n\n");printf("此程序调用df命名,把本服务器的磁盘使用率信息写入xml文件。\n");printf("hostname是本服务器的主机名,为了方便识别,也可以用IP。\n");printf("logfilename是本程序的日志文件名。\n");printf("outputpath是输出的xml文件存放的目录。\n");printf("此程序运行在需要监控的服务器上(本程序只适用Linux系统),采集后的xml文件由文件传输程序发送给数据处理服务程序入库。\n\n\n");return -1;}CloseIOAndSignal(); signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[2],"a+") == false
){printf("logfile.Open(%s) failed.\n",argv
[2]); return -1;}FILE
*fp
=0;if ( (fp
=popen("df -k --block-size=1M","r")) == NULL ){logfile
.Write("popen(df -k --block-size=1M) failed.\n"); return false
;}char strXMLFileName
[301],strLocalTime
[21];memset(strXMLFileName
,0,sizeof(strXMLFileName
));memset(strLocalTime
,0,sizeof(strLocalTime
));LocalTime(strLocalTime
,"yyyymmddhh24miss");snprintf(strXMLFileName
,300,"%s/diskinfo_%s_%s.xml",argv
[3],strLocalTime
,argv
[1]);CFile XMLFile
;if (XMLFile
.OpenForRename(strXMLFileName
,"w+") == false
){logfile
.Write("XMLFile.OpenForRename(%s) failed.\n",strXMLFileName
); pclose(fp
); return -1;}XMLFile
.Fprintf("<data>\n");CCmdStr CmdStr
;char strBuffer
[1024],strLine
[500];while (true
){memset(strBuffer
,0,sizeof(strBuffer
));if (FGETS(fp
,strBuffer
,500) == false
) break;if (strstr(strBuffer
,"%") == 0){memset(strLine
,0,sizeof(strLine
));if (FGETS(fp
,strLine
,500) == false
) break;strcat(strBuffer
," "); strcat(strBuffer
,strLine
);}DeleteLRChar(strBuffer
,' '); DeleteLRChar(strBuffer
,'\n');UpdateStr(strBuffer
," "," ");ToLower(strBuffer
);if (strncmp(strBuffer
,"/dev",4) != 0) continue;CmdStr
.SplitToCmd(strBuffer
," ");if (CmdStr
.CmdCount() != 6) continue;char strusep
[21];memset(strusep
,0,sizeof(strusep
));strcpy(strusep
,CmdStr
.m_vCmdStr
[4].c_str());UpdateStr(strusep
,"%","");char strLocalTime
[21];memset(strLocalTime
,0,sizeof(strLocalTime
));LocalTime(strLocalTime
,"yyyymmddhh24miss");XMLFile
.Fprintf(\
"<nodip>%s</nodip>"\
"<crttime>%s</crttime>"\
"<filesystem>%s</filesystem>"\
"<total>%0.02f</total>"\
"<used>%0.02f</used>"\
"<available>%0.02f</available>"\
"<usep>%0.02f</usep>"\
"<mount>%s</mount><endl/>\n",argv
[1],strLocalTime
,CmdStr
.m_vCmdStr
[0].c_str(),atof(CmdStr
.m_vCmdStr
[1].c_str())/1024.0,atof(CmdStr
.m_vCmdStr
[2].c_str())/1024.0,atof(CmdStr
.m_vCmdStr
[3].c_str())/1024.0,(atof(CmdStr
.m_vCmdStr
[2].c_str())/atof(CmdStr
.m_vCmdStr
[1].c_str()))*100.0,CmdStr
.m_vCmdStr
[5].c_str());}XMLFile
.Fprintf("</data>\n");pclose(fp
);XMLFile
.CloseAndRename();logfile
.Write("create %s ok.\n",strXMLFileName
);exit(0);
}void EXIT(int sig
)
{if (sig
> 0) signal(sig
,SIG_IGN
);logfile
.Write("catching the signal(%d).\n",sig
);logfile
.Write("diskinfo exit.\n");exit(0);
}
以下为收集CPU和内存信息,top命令显示如下,zombie表示僵尸,q退出,cpu用到20%算忙了。
ps -ef |grep htidc,cpuinfo.cpp思路是定义三个结构体变量,加载cpu信息到结构体里,睡60s,再继续加载cpu信息到结构体里,再将两结构体成员相减,就可以知道一分钟内cpu情况,采用的是一分钟信息。vi /proc/stat如下。
#include "_public.h"
void EXIT(int sig
);
CLogFile logfile
;
struct st_cpuinfo
{double user
;double sys
;double wait
;double nice
;double idle
;double irq
;double softirq
;double total
;
};
struct st_cpuinfo stcpuinfo1
,stcpuinfo2
,stcpuinfo3
;
bool
LoadCPUInfo(struct st_cpuinfo &stcpuinfo
);int main(int argc
,char *argv
[])
{if (argc
!= 4){printf("\n");printf("Using:./cpuinfo hostname logfilename outputpath\n");printf("Example:/htidc/public/bin/cpuinfo 118.89.50.198 /tmp/htidc/log/cpuinfo.log /tmp/htidc/monclient\n\n");printf("此程序读取/proc/stat文件,把本服务器的CPU使用率信息写入xml文件。\n");printf("hostname是本服务器的主机名,为了方便识别,也可以用IP。\n");printf("logfilename是本程序的日志文件名。\n");printf("outputpath是输出的xml文件存放的目录。\n");printf("此程序运行在需要监控的服务器上(本程序只适用Linux系统),采集后的xml文件由文件传输程序发送给数据处理服务程序入库。\n\n\n");return -1;}CloseIOAndSignal(); signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[2],"a+") == false
){printf("logfile.Open(%s) failed.\n",argv
[2]); return -1;}memset(&stcpuinfo1
,0,sizeof(struct st_cpuinfo));memset(&stcpuinfo2
,0,sizeof(struct st_cpuinfo));memset(&stcpuinfo3
,0,sizeof(struct st_cpuinfo));if (LoadCPUInfo(stcpuinfo1
) ==false
) return -1; sleep(60);if (LoadCPUInfo(stcpuinfo2
) ==false
) return -1;stcpuinfo3
.user
=stcpuinfo2
.user
-stcpuinfo1
.user
;stcpuinfo3
.sys
=stcpuinfo2
.sys
-stcpuinfo1
.sys
;stcpuinfo3
.wait
=stcpuinfo2
.wait
-stcpuinfo1
.wait
;stcpuinfo3
.nice
=stcpuinfo2
.nice
-stcpuinfo1
.nice
;stcpuinfo3
.idle
=stcpuinfo2
.idle
-stcpuinfo1
.idle
;stcpuinfo3
.irq
=stcpuinfo2
.irq
-stcpuinfo1
.irq
;stcpuinfo3
.softirq
=stcpuinfo2
.softirq
-stcpuinfo1
.softirq
;stcpuinfo3
.total
=stcpuinfo3
.user
+stcpuinfo3
.sys
+stcpuinfo3
.wait
+stcpuinfo3
.nice
+stcpuinfo3
.idle
+stcpuinfo3
.irq
+stcpuinfo3
.softirq
;char strLocalTime
[21];memset(strLocalTime
,0,sizeof(strLocalTime
));LocalTime(strLocalTime
,"yyyymmddhh24miss");char strXMLFileName
[301];memset(strXMLFileName
,0,sizeof(strXMLFileName
));snprintf(strXMLFileName
,300,"%s/cpuinfo_%s_%s.xml",argv
[3],strLocalTime
,argv
[1]);CFile XMLFile
;if (XMLFile
.OpenForRename(strXMLFileName
,"w+") == false
){logfile
.Write("XMLFile.OpenForRename(%s) failed.\n",strXMLFileName
); return -1;}XMLFile
.Fprintf("<data>\n");XMLFile
.Fprintf("<nodip>%s</nodip><crttime>%s</crttime><user>%0.02f</user><sys>%0.02f</sys><wait>%0.02f</wait><nice>%0.02f</nice><idle>%0.02f</idle><usep>%0.02f</usep><endl/>\n",argv
[1],strLocalTime
,stcpuinfo3
.user
/stcpuinfo3
.total
*100.0,stcpuinfo3
.sys
/stcpuinfo3
.total
*100.0,stcpuinfo3
.wait
/stcpuinfo3
.total
*100.0,stcpuinfo3
.nice
/stcpuinfo3
.total
*100.0,stcpuinfo3
.idle
/stcpuinfo3
.total
*100.0,100.0-stcpuinfo3
.nice
/stcpuinfo3
.total
*100.0);XMLFile
.Fprintf("</data>\n");XMLFile
.CloseAndRename();logfile
.Write("create %s ok.\n",strXMLFileName
);exit(0);
}
void EXIT(int sig
)
{if (sig
> 0) signal(sig
,SIG_IGN
);logfile
.Write("catching the signal(%d).\n",sig
);logfile
.Write("cpuinfo exit.\n");exit(0);
}bool
LoadCPUInfo(struct st_cpuinfo &stcpuinfo
)
{CFile CPUFile
;if (CPUFile
.Open("/proc/stat","r") == false
){logfile
.Write("CPUFile.OpenForRead(/proc/stat) failed.\n"); return false
;}CCmdStr CmdStr
;char strBuffer
[1024];while (true
){memset(strBuffer
,0,sizeof(strBuffer
));if (CPUFile
.FFGETS(strBuffer
,500) == false
) break;DeleteLRChar(strBuffer
,' ');UpdateStr(strBuffer
," "," ");ToLower(strBuffer
);CmdStr
.SplitToCmd(strBuffer
," ");if (strcmp(CmdStr
.m_vCmdStr
[0].c_str(),"cpu")==0) {stcpuinfo
.user
=atof(CmdStr
.m_vCmdStr
[1].c_str());stcpuinfo
.sys
=atof(CmdStr
.m_vCmdStr
[2].c_str());stcpuinfo
.wait
=atof(CmdStr
.m_vCmdStr
[3].c_str());stcpuinfo
.nice
=atof(CmdStr
.m_vCmdStr
[4].c_str());stcpuinfo
.idle
=atof(CmdStr
.m_vCmdStr
[5].c_str());stcpuinfo
.irq
=atof(CmdStr
.m_vCmdStr
[6].c_str());stcpuinfo
.softirq
=atof(CmdStr
.m_vCmdStr
[7].c_str());return true
;}}logfile
.Write("Read /proc/stat failed.\n"); return false
;
}
vi /tmp/htdic/monclient/cpu*,如下是收集到的信息。
收集内存信息#free -m,和top命令查看的内存是一样的,也在系统文件vi /proc/meminfo。
以下是收集Oracle表空间信息,表空间就像磁盘空间一样,表空间的信息收集要去读取oracle的数据字典,如下sql是查询oracle表空间使用率,取出后写入xml文件里,vi tbspaceinfo.cpp,要dba权限。
select * from (
Select a
.tablespace_name
,
to_char
(a
.bytes
/1024/1024,'99,999.999') total_bytes
,
to_char
(b
.bytes
/1024/1024,'99,999.999') free_bytes
,
to_char
(a
.bytes
/1024/1024 - b
.bytes
/1024/1024,'99,999.999') use_bytes
,
to_char
((1 - b
.bytes
/a
.bytes
)*100,'99.99') || '%' use
from (select tablespace_name
,
sum(bytes
) bytes
from dba_data_files
group by tablespace_name
) a
,
(select tablespace_name
,
sum(bytes
) bytes
from dba_free_space
group by tablespace_name
) b
where a
.tablespace_name
= b
.tablespace_name
union all
select c
.tablespace_name
,
to_char
(c
.bytes
/1024/1024,'99,999.999') total_bytes
,
to_char
( (c
.bytes
-d
.bytes_used
)/1024/1024,'99,999.999') free_bytes
,
to_char
(d
.bytes_used
/1024/1024,'99,999.999') use_bytes
,
to_char
(d
.bytes_used
*100/c
.bytes
,'99.99') || '%' use
from
(select tablespace_name
,sum(bytes
) bytes
from dba_temp_files
group by tablespace_name
) c
,
(select tablespace_name
,sum(bytes_cached
) bytes_used
from v$temp_extent_pool
group by tablespace_name
) d
where c
.tablespace_name
= d
.tablespace_name
)
#include "_public.h"
#include "_ooci.h"
void EXIT(int sig
);
struct st_TBSPACEINFO
{long taskid
;char nodip
[31];char tablespace
[101];double total
;double used
;double available
;double usep
;double alarmvalue
;int alarmsts
;char crttime
[21];int rsts
;
};
struct st_TBSPACEINFO stTBSPACEINFO
;
CLogFile logfile
;
connection conn
;
int main(int argc
,char *argv
[])
{if (argc
!= 5){printf("\n");printf("Using:./tbspaceinfo hostname logfilename outputpath username/password@tnsnames\n");printf("Example:/htidc/public/bin/tbspaceinfo 10.153.98.13 /tmp/htidc/log/tbspaceinfo_10.153.98.13.log /tmp/htidc/monclient shqx/pwdidc@SZQX_10.153.98.13\n\n");printf("此程序连接远程数据库,把远程数据库表空间使用率信息写入xml文件。\n");printf("hostname是本服务器的主机名,为了方便识别,也可以用IP。\n");printf("logfilename是本程序的日志文件名。\n");printf("outputpath是输出的xml文件存放的目录。\n");printf("username/password@tnsnames为待监控的远程数据库的用户名/密码@连接名。\n");printf("此程序运行在数据中心应用程序的服务器上。\n\n\n");return -1;}CloseIOAndSignal(); signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[2],"a+") == false
){printf("logfile.Open(%s) failed.\n",argv
[2]); return -1;}if (conn
.connecttodb(argv
[4],"Simplified Chinese_China.ZHS16GBK") != 0){logfile
.Write("conn.connecttodb(%s) failed.\n",argv
[4]); return -1;}sqlstatement stmt
;stmt
.connect(&conn
);stmt
.prepare("\select f.tablespace_name,a.total,u.used,f.free,(u.used/a.total)*100 from\(select tablespace_name,sum(bytes/(1024*1024*1024)) total from DBA_DATA_FILES\group by tablespace_name) a,\(select tablespace_name,round(sum(bytes/(1024*1024*1024))) used from DBA_EXTENTS\group by tablespace_name) u,\(select tablespace_name,round(sum(bytes/(1024*1024*1024))) free from DBA_FREE_SPACE\group by tablespace_name) f\where a.tablespace_name = f.tablespace_name\and a.tablespace_name = u.tablespace_name\and f.tablespace_name in (select tablespace_name from DBA_TABLESPACES where contents='PERMANENT')");stmt
.bindout(1,stTBSPACEINFO
.tablespace
,100);stmt
.bindout(2,&stTBSPACEINFO
.total
);stmt
.bindout(3,&stTBSPACEINFO
.used
);stmt
.bindout(4,&stTBSPACEINFO
.available
);stmt
.bindout(5,&stTBSPACEINFO
.usep
);if (stmt
.execute() != 0){logfile
.Write("select DBA_DATA_FILES,DBA_EXTENTS,DBA_FREE_SPACE failed.\n%s\n",stmt
.m_cda
.message
); return -1;}char strLocalTime
[21];memset(strLocalTime
,0,sizeof(strLocalTime
));LocalTime(strLocalTime
,"yyyymmddhh24miss");char strXMLFileName
[301];memset(strXMLFileName
,0,sizeof(strXMLFileName
));snprintf(strXMLFileName
,300,"%s/tbspaceinfo_%s_%s.xml",argv
[3],strLocalTime
,argv
[1]);CFile XMLFile
;if (XMLFile
.OpenForRename(strXMLFileName
,"w+") == false
){logfile
.Write("XMLFile.OpenForRename(%s) failed.\n",strXMLFileName
); return -1;}XMLFile
.Fprintf("<data>\n");while (true
){memset(&stTBSPACEINFO
,0,sizeof(stTBSPACEINFO
));if (stmt
.next() != 0) break;XMLFile
.Fprintf(\
"<nodip>%s</nodip>"\
"<crttime>%s</crttime>"\
"<tablespace>%s</tablespace>"\
"<total>%0.02f</total>"\
"<used>%0.02f</used>"\
"<available>%0.02f</available>"\
"<usep>%0.02f</usep><endl/>\n",argv
[1],strLocalTime
,stTBSPACEINFO
.tablespace
,stTBSPACEINFO
.total
,stTBSPACEINFO
.used
,stTBSPACEINFO
.available
,stTBSPACEINFO
.usep
);}XMLFile
.Fprintf("</data>\n");XMLFile
.CloseAndRename();logfile
.Write("生成文件%s.\n",strXMLFileName
);exit(0);
}
void EXIT(int sig
)
{if (sig
> 0) signal(sig
,SIG_IGN
);logfile
.Write("catching the signal(%d).\n",sig
);logfile
.Write("tbspaceinfo exit.\n");exit(0);
}
以下是收集Oracle会话信息,我们用客户端通oracle的监听连上oracle数据库,oracle数据库会启动一个进程向会话提供服务,是多进程的服务端,每增加一连接(进程),需要消耗系统资源(内存,socket连接)。如下一共有6个客户端连上,SQL>exit退出一个就剩下5个。ps -ef |grep oracle可查看oracle数据库系统进程。
如下两个sql是查询数据字典查到进程和上面一样,第一个sql是查全部包括系统进程。如下表有一个OSUSER表示连上来的客户端操作系统名字,还可以通过SQL_ID查到连上来的客户端sql语句操作。还可以指定oracle用户的会话数。
#include "qxmon.h"
void EXIT(int sig
);
struct st_DBSESSIONINFO stDBSESSIONINFO
;
CLogFile logfile
;
connection conndst
;
CProgramActive ProgramActive
;int main(int argc
,char *argv
[])
{if (argc
!= 5){printf("\n");printf("Using:./dbsessioninfo hostname logfilename outputpath username/password@tnsnames\n");printf("Example:/htidc/htidc/bin/procctl 300 /htidc/qxmon/bin/dbsessioninfo 10.153.98.13 /log/qxmon/dbsessioninfo_10.153.98.13.log /qxdata/qxmon/qxmonclient szidc/pwdidc@SZQX_10.153.98.13\n\n");printf("此程序连接远程数据库,把远程数据库会话信息写入XML文件。\n");printf("hostname是本服务器的主机名,为了方便识别,也可以用IP。\n");printf("logfilename是本程序的日志文件名。\n");printf("outputpath是输出的XML文件存放的目录。\n");printf("username/password@tnsnames为待监控的远程数据库的用户名/密码@连接名。\n");printf("此程序运行在监控平台的服务器上。\n\n\n");return -1;}CloseIOAndSignal(); signal(SIGINT
,EXIT
); signal(SIGTERM
,EXIT
);if (logfile
.Open(argv
[2],"a+") == FALSE
){printf("logfile.Open(%s) failed.\n",argv
[2]); return -1;}ProgramActive
.SetProgramInfo(&logfile
,"alarmserver",300);if (conndst
.connecttodb(argv
[4])!=0){logfile
.Write("connmon.connecttodb(%s) failed.\n",argv
[4]); EXIT(-1);}sqlstatement stmt
;stmt
.connect(&conndst
);stmt
.prepare("select count(*) from V$SESSION where type!='BACKGROUND' and status!='KILLED'"); stmt
.bindout(1,&stDBSESSIONINFO
.total
);if (stmt
.execute() != 0){logfile
.Write("select V$SESSION failed.\n%s\n",stmt
.cda
.message
); EXIT(-1);}char strLocalTime
[21];memset(strLocalTime
,0,sizeof(strLocalTime
));LocalTime(strLocalTime
,"yyyymmddhh24miss");char strXMLFileName
[301];memset(strXMLFileName
,0,sizeof(strXMLFileName
));snprintf(strXMLFileName
,300,"%s/dbsessioninfo_%s_%s.xml",argv
[3],strLocalTime
,argv
[1]);CFile XMLFile
;if (XMLFile
.OpenForRename(strXMLFileName
,"w+") == FALSE
){logfile
.Write("XMLFile.OpenForRename(%s) failed.\n",strXMLFileName
); EXIT(-1);}XMLFile
.Fprintf("<data>\n");while (TRUE
){memset(&stDBSESSIONINFO
,0,sizeof(stDBSESSIONINFO
));if (stmt
.next() != 0) break;XMLFile
.Fprintf(\
"<nodip>%s</nodip>"\
"<crttime>%s</crttime>"\
"<total>%d</total><endl/>\n",argv
[1],strLocalTime
,stDBSESSIONINFO
.total
);}XMLFile
.Fprintf("</data>\n");XMLFile
.CloseAndRename();logfile
.Write("生成文件%s.\n",strXMLFileName
);exit(0);
}void EXIT(int sig
)
{if (sig
> 0) signal(sig
,SIG_IGN
);logfile
.Write("catching the signal(%d).\n",sig
);logfile
.Write("dbsessioninfo exit.\n");exit(0);
}
oracle里有一个系统参数processes(最大允许的会话总数)。_ooci.h中connection类连接上一个后进程及processes+1,sqlstatement类实例化并指定数据库连接也会消耗一种资源即open_cursors参数。oracle有缓存机制存sql,下次用到则不进行语法分析,所以oracle需大内存,存的越多,缓存命中率越高。
总结
以上是生活随笔为你收集整理的【C/C++13】天气APP:数据挖掘/HTTP协议/非结构化数据存储(filetoblob.cpp),数据管理/监控告警(hsmtable.cpp,tbspaceinfo.cpp)的全部内容,希望文章能够帮你解决所遇到的问题。
如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。