Chinaunix首页 | 论坛 | 博客
  • 博客访问: 139324
  • 博文数量: 19
  • 博客积分: 1416
  • 博客等级: 上尉
  • 技术积分: 273
  • 用 户 组: 普通用户
  • 注册时间: 2008-12-22 00:49
文章分类

全部博文(19)

文章存档

2010年(4)

2009年(15)

我的朋友

分类: LINUX

2009-08-06 14:29:23

    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。
阅读(2984) | 评论(0) | 转发(0) |
0

上一篇:ndo入mysql的一些优化

下一篇:武汉-长江

给主人留下些什么吧!~~