ndo的表有很多,对我们有意义的表没多少,抛开我不太清楚的notification,我把我所了解的大概的东西讲一下,每张表的描述大概分三段,第一
段是表的功能描述,第二段是我觉得我们查询时候比较重要的列,第三段是已有的索引。有些索引并不是自己带的,而是我后来建的,有些是为了优化ndo2db
的delete,有些是为了优化centreon的查询,对于自建查询来说,还是有点用处的。
nagios_objects:
ndo
里最重要的对象表,里面有nagios所有的对象,每一个对象,包括contact,hostgroup,service,host等等,在ndo的库里
都有一个唯一的标志,就是object_id,这个id就是在这张表里定义的。在其他所有的表中出现的所有的对象,几乎都是object_id,所以几乎
每次查询都要过这张表。
表里有两个名字列,name1,name2,这在ndo里面也是很重要的一个标识,这个是我们认为判断这
个对象的唯一的标识。对于大部分对象来说,name2都是空的,比如host,name1是host的名字,name2为NULL;对于
service,name1是这个service所属的host的名字,name2是service的名字。
这个表做了两个索引:
1、主键,object_id。
2、object_type_id,这个索引的定义是:KEY `objecttype_id` (`objecttype_id`,`name1`,`name2`)。
nagios_hosts:
ndo里存储host对象信息的表,查询的时候用到可能不是很多,因为host的信息,大多数情况下是查的nagios_hoststatus表。
nagios_services:
ndo
里存储service对象信息的表,在得知主机的object_id,然后查询这个主机上的service相关信息的时候需要用到,因为ndo里只有这张
表存储了host_object_id和service_object_id的对应。查询的时候,也就是对这两列进行查询。
我们查询的时候,一般只用到两个列,host_object_id和service_object_id。
这个表有4个索引,两个是自带的,两个是后来加的,但是我觉得我们平时用到的是后两个:
1、service_object_id,这个索引的定义是:KEY `service_object_id` (`service_object_id`)。
2、htob_svob_index,这个索引的定义是:KEY `htob_svob_index` (`host_object_id`,`service_object_id`)。
nagios_hostgroups:
ndo
里存储hostgroup对象信息的表,也是很重要的表,在做hostgroup相关查询的时候一定会用到它,因为它也保存了一个唯一的对应关系,就是
hostgroup_id到hostgroup_object_id的对应关系,这个hostgroup_id是完全没有必要出现的一个东西,但是另外一
张表里,nagios_hostgroup_members表里只有hostgroup_id,没有hostgroup_object_id,所以我们如
果知道hostgroup_object_id,然后想知道它所包含的host的时候,就必须通过这张表来做一次转换,然后再到
nagios_hostgroup_members里查找了。
最重要的列有三个,hostgroup_id,hostgroup_object_id,还有一个alias,有些时候我们只用alias就可以定位到hostgroup,而用不着非得去nagios_objects里面去查。
这个表有三个索引:
1、主键,hostgroup_id,用处不大。
2、
唯一键,instance_id,索引的定义是:UNIQUE KEY `instance_id`。
(`instance_id`,`hostgroup_object_id`),如果知道hostgroup_object_id来查的时候可能有点用,
不过一般也不用这么查。
3、idx_hg_ins_ali,索引定义是:KEY `idx_hg_ins_ali` (`instance_id`,`alias`),一般用这个的比较多,主要是用来查alias的。
nagios_hostgroup_members:
ndo里存储hostgroup和host对应关系的表,也是挺重要的一个表,设计到hostgroup的,大多也要查它。
重要的列有两个,hostgroup_id,host_object_id,它居然没用hostgroup_object_id,所以比较恶心,让我查的时
候还要到nagios_hostgroups表里绕一圈。查询的时候也都是,得知hostgroup_id查成员,得知成员object_id查找主机
组。
这个表有两个索引,主键没用,只有一个用的比较多:UNIQUE KEY `instance_id` (`hostgroup_id`,`host_object_id`)。
nagios_hoststatus:
ndo里存储host状态的表,查询host状态的话,这里应该是最后返回结果的一张表了。
重要的列太多了,报警有没有关,现在状态如何,是否自动检测等等,都在这里取到的,一般是用host_object_id来取。
这个表有两个索引,主键没用,只要一个host_object_id的索引就够了。
nagios_servicestatus:
ndo里存储service状态的表,查询service一般最终也是这张表返回的。
重要的列也很多,不过遗憾的是没有host_object_id,所以如果查询一个host的所有service状态,要走nagios_services表
索引有三个:
1、主键,servicestatus_id,没用的东西。
2、唯一键,object_id,是service_object_id,用到比较多。
3、c_state,索引定义为:KEY `c_state` (`current_state`,`service_object_id`),这个是给centreon查询做的索引。
nagios_hostchecks:
ndo
里存储host的历史查询结果的表,是整个ndo里第二大的表,现在保留一周的数据,是个merge的表。查询的时候也可以按周查询,直接找星期数对应的
那张表,比如周一的查nagios_hostchecks_1。存储的是检查的结果,一般的查询都是限定host_object_id,限定时间段来查询
的。
重要的列主要是host_object_id,start_time(检查时间),return_code(返回值,代表是否正常),output(输出),perfdata(性能数据,绘图用)
索引有三个:
1、主键,没用。
2、唯一键,定义为:UNIQUE KEY `instance_id` (`instance_id`,`host_object_id`,`start_time`,`start_time_usec`),一般的查询都用的这个。
3、
idx_hostche__ins_start,索引定义为:KEY `idx_hostche__ins_start`
(`instance_id`,`start_time`),原先是做了给ndo2db删数据用的,现在不删了,基本上也没用了,可以考虑删掉这个索引,
节省空间和更新时间。
nagios_servicechecks:
ndo里存储service历史查询结果的表,是最大的表了,merge引擎。总体上和hostchecks表类似。
nagios_instances:
保存nagios主机信息的,只有5条记录,简洁明了,一看就明白。instance_id在查询的时候用的还是挺多的,虽然觉得有点多余,但是大部分的索引都是以它开头的,所以不加也得加…………
我们现在可以写一些脚本来查询ndo的库了,毕竟入库就是为了查询,否则干嘛花那么大力气来搞ndo呢?
至于sql语句,我觉得主要有以下几点需要注意:
1、在把sql写进脚本里以前,一定要在mysql里测试一下,select语句的话最好先explain一下,看大概要扫描多少条记录,是不是走到了索引上,特别是这个语句跑出来需要多长时间,如果真的太慢了,而且查询时间很长,那大家可以讨论下如何优化。
2、
如果在测试的时候卡住了(这个是很有可能的,有些select语句一年都跑不出来),不要光是ctrl+c退出来就好了,特别是两张myisam的
表,myisam是表级别的锁定,select锁了表,所有的插入就都挂住了,搞不好nagios会被拖挂掉,所以一定要再进去show
processlist一下,然后把select的线程kill掉。
3、写where语句的约束条件的时候,一定要记得走索引,特别是查
询里面有大表的时候。mysql每次查询每张表只能用一个索引,而且必须按照顺序来,ndo里面的话,我们的索引第一个条件基本上都是
instance_id,那么在写约束的时候一定也要加上instance_id,只要第一个列没合上,那它就不会用这个索引了。这个通过explain
语句是可以看出来的。
4、查一个表,一般是出不来结果的,所以我们的查询估计是好几张表一起查,我写一个查询语句吧,参照一下:
select no.name1, no.name2, sc.state, sc.start_time, sc.return_code, sc.output
from nagios_objects no, nagios_servicechecks_2 sc, nagios_hostgroups hg, nagios_hostgroup_members hm, nagios_services ns
where no.object_id = ns.service_object_id
and hm.hostgroup_id = hg.hostgroup_id
and hg.instance_id = '4'
and hg.alias = 'tmp_hostgroup'
and hm.host_object_id = ns.host_object_id
and sc.instance_id = '4'
and sc.service_object_id = no.object_id
and sc.start_time between '2009-06-02 07:00:00' and '2009-06-02 08:00:00'
这个sql是取6月2日,7点到8点之间tmp_hostgroup这组机器的service的检查结果。
explain之后,结果如下:
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: hg
type: ref
possible_keys: PRIMARY,instance_id,idx_hg_ins_ali
key: idx_hg_ins_ali
key_len: 514
ref: const,const
rows: 1
Extra: Using where; Using index
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: sc
type: range
possible_keys: instance_id,idx_serche_ins_start
key: idx_serche_ins_start
key_len: 10
ref: NULL
rows: 30740
Extra: Using where; Using join buffer
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: ns
type: ref
possible_keys: service_object_id,htob_svob_index
key: service_object_id
key_len: 4
ref: nagios.sc.service_object_id
rows: 1
Extra:
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: hm
type: eq_ref
possible_keys: instance_id
key: instance_id
key_len: 8
ref: nagios.hg.hostgroup_id,nagios.ns.host_object_id
rows: 1
Extra: Using index
*************************** 5. row ***************************
id: 1
select_type: SIMPLE
table: no
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: nagios.ns.service_object_id
rows: 1
Extra: Using where
可以看到,查的5个表里,有4个表可以通过索引直接定位,扫描的行数只有1,只有servicechecks的表索引建的不好,要扫3w行左右的数据,查询以后,耗时0.53s,还是挺快的。
但是如果写的时候少加了instance_id,那就不一样了,如果变成下面的sql
select no.name1, no.name2, sc.state, sc.start_time, sc.return_code, sc.output
from nagios_objects no, nagios_servicechecks_2 sc, nagios_hostgroups hg, nagios_hostgroup_members hm, nagios_services ns
where no.object_id = ns.service_object_id
and hm.hostgroup_id = hg.hostgroup_id
and hg.alias = 'tmp_hostgroup'
and hm.host_object_id = ns.host_object_id
and sc.service_object_id = no.object_id
and sc.start_time between '2009-06-02 07:00:00' and '2009-06-02 08:00:00'
explain之后是这个样子,功能和上面的sql语句是一样的,select出来的结果也一样,但是……
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: sc
type: ALL
possible_keys: NULL
key: NULL
key_len: NULL
ref: NULL
rows: 4268324
Extra: Using where
*************************** 2. row ***************************
id: 1
select_type: SIMPLE
table: ns
type: ref
possible_keys: service_object_id,htob_svob_index
key: service_object_id
key_len: 4
ref: nagios.sc.service_object_id
rows: 1
Extra:
*************************** 3. row ***************************
id: 1
select_type: SIMPLE
table: hg
type: index
possible_keys: PRIMARY
key: idx_hg_ins_ali
key_len: 514
ref: NULL
rows: 421
Extra: Using where; Using index; Using join buffer
*************************** 4. row ***************************
id: 1
select_type: SIMPLE
table: no
type: eq_ref
possible_keys: PRIMARY
key: PRIMARY
key_len: 4
ref: nagios.ns.service_object_id
rows: 1
Extra: Using where
*************************** 5. row ***************************
id: 1
select_type: SIMPLE
table: hm
type: eq_ref
possible_keys: instance_id
key: instance_id
key_len: 8
ref: nagios.hg.hostgroup_id,nagios.ns.host_object_id
rows: 1
Extra: Using index
少了两个约束条件,结果一个表就直接全表扫描了,另外一个表也从刚刚的直接定位换到扫描421行,执行时间不知道要多多少倍,所以加instance_id这个条件还是很重要的。
还有就是,查询的结果集不要太大,如果查询大量的结果,最好加limit。
阅读(3099) | 评论(0) | 转发(0) |