Skip to content

Commit 14edd05

Browse files
committed
feature: added new invalid indexes metrics
1 parent 2c5fa76 commit 14edd05

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

mamonsu/plugins/pgsql/databases.py

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3+
from distutils.version import LooseVersion
34
from mamonsu.plugins.pgsql.plugin import PgsqlPlugin as Plugin
45
from .pool import Pooler
56
from mamonsu.lib.zbx_template import ZbxTemplate
@@ -16,6 +17,11 @@ class Databases(Plugin):
1617
" datistemplate = false and datname = :'p1';"
1718
query_age = "select age(datfrozenxid) from pg_catalog.pg_database where datistemplate = false " \
1819
"and datname = :'p1';"
20+
query_invalid_indexes = "SELECT count(*) " \
21+
"FROM pg_catalog.pg_class, pg_catalog.pg_index " \
22+
"WHERE pg_catalog.pg_index.indisvalid = false " \
23+
"AND pg_catalog.pg_index.indexrelid = pg_catalog.pg_class.oid " \
24+
"AND substring(pg_catalog.pg_class.relname, '([^_]+$)') ~ '^cc{0}';"
1925

2026
# queries for zabbix agent
2127
query_agent_discovery = "SELECT json_build_object ('data',json_agg(json_build_object('{#DATABASE}',d.datname)))" \
@@ -26,10 +32,14 @@ class Databases(Plugin):
2632
key_db_age = "pgsql.database.max_age{0}"
2733
key_db_bloating_tables = "pgsql.database.bloating_tables{0}"
2834
key_autovacumm = "pgsql.autovacumm.count{0}"
35+
key_invalid_rebuilt_indexes = "pgsql.database.invalid_rebuilt_indexes{0}"
36+
key_invalid_old_indexes = "pgsql.database.invalid_old_indexes{0}"
2937

3038
DEFAULT_CONFIG = {'min_rows': str(50), 'bloat_scale': str(0.2)}
3139

3240
def run(self, zbx):
41+
if Pooler.server_version_greater('12'):
42+
self.query_invalid_indexes = self.query_invalid_indexes[:-1] + " AND pg_catalog.pg_class.oid NOT IN (SELECT index_relid FROM pg_catalog.pg_stat_progress_create_index);"
3343
result = Pooler.query('select \
3444
datname, pg_database_size(datname::text), age(datfrozenxid) \
3545
from pg_catalog.pg_database where datistemplate = false')
@@ -49,6 +59,18 @@ def run(self, zbx):
4959
zbx.send(
5060
'pgsql.database.bloating_tables[{0}]'.format(info[0]),
5161
int(bloat_count))
62+
invalid_rebuilt_indexes_count = Pooler.query(
63+
self.query_invalid_indexes.format('new'),
64+
info[0])[0][0]
65+
invalid_old_indexes_count = Pooler.query(
66+
self.query_invalid_indexes.format('old'),
67+
info[0])[0][0]
68+
zbx.send(
69+
'pgsql.database.invalid_rebuilt_indexes[{0}]'.format(info[0]),
70+
int(invalid_rebuilt_indexes_count))
71+
zbx.send(
72+
'pgsql.database.invalid_old_indexes[{0}]'.format(info[0]),
73+
int(invalid_old_indexes_count))
5274
zbx.send('pgsql.database.discovery[]', zbx.json({'data': dbs}))
5375
del dbs, bloat_count
5476

@@ -100,6 +122,12 @@ def discovery_rules(self, template, dashboard=False):
100122
'delay': self.plugin_config('interval')},
101123
{'key': self.right_type(self.key_db_bloating_tables, var_discovery="{#DATABASE},"),
102124
'name': 'Count of bloating tables in database: {#DATABASE}',
125+
'delay': self.plugin_config('interval')},
126+
{'key': self.right_type(self.key_invalid_rebuilt_indexes, var_discovery="{#DATABASE},"),
127+
'name': 'Count of indexes corrupted during REINDEX in database: {#DATABASE}',
128+
'delay': self.plugin_config('interval')},
129+
{'key': self.right_type(self.key_invalid_old_indexes, var_discovery="{#DATABASE},"),
130+
'name': 'Count of old invalid indexes in database: {#DATABASE}',
103131
'delay': self.plugin_config('interval')}
104132
]
105133
graphs = [
@@ -129,15 +157,30 @@ def discovery_rules(self, template, dashboard=False):
129157
'yaxisside': 1}]
130158
}
131159
]
132-
return template.discovery_rule(rule=rule, conditions=conditions, items=items, graphs=graphs)
160+
triggers = [{
161+
'name': 'PostgreSQL corrupted indexes during REINDEX in database '
162+
'{#DATABASE} (hostname={HOSTNAME} value={ITEM.LASTVALUE})',
163+
'expression': '{#TEMPLATE:pgsql.database.invalid_rebuilt_indexes[{#DATABASE}].last()}>0'},
164+
{
165+
'name': 'PostgreSQL old invalid indexes in database '
166+
'{#DATABASE} (hostname={HOSTNAME} value={ITEM.LASTVALUE})',
167+
'expression': '{#TEMPLATE:pgsql.database.invalid_old_indexes[{#DATABASE}].last()}>0'}
168+
]
169+
return template.discovery_rule(rule=rule, conditions=conditions, items=items, graphs=graphs, triggers=triggers)
133170

134171
def keys_and_queries(self, template_zabbix):
172+
if LooseVersion(self.VersionPG) >= LooseVersion('12'):
173+
self.query_invalid_indexes = self.query_invalid_indexes[:-1] + " AND pg_catalog.pg_class.oid NOT IN (SELECT index_relid FROM pg_catalog.pg_stat_progress_create_index);"
135174
result = ['{0},$2 $1 -c "{1}"'.format(self.key_autovacumm.format("[*]"), Pooler.SQL['count_autovacuum'][0]),
136175
'{0},$2 $1 -c "{1}"'.format(self.key_db_discovery.format("[*]"), self.query_agent_discovery),
137176
'{0},echo "{1}" | $3 $2 -v p1="$1"'.format(self.key_db_size.format("[*]"), self.query_size),
138177
'{0},echo "{1}" | $3 $2 -v p1="$1"'.format(self.key_db_age.format("[*]"), self.query_age),
139178
'{0},$3 $2 -d "$1" -c "{1}"'.format(self.key_db_bloating_tables.format("[*]"),
140179
self.query_bloating_tables.format(
141180
self.plugin_config('bloat_scale'),
142-
self.plugin_config('min_rows')))]
181+
self.plugin_config('min_rows'))),
182+
'{0},$3 $2 -d "$1" -c "{1}"'.format(self.key_invalid_rebuilt_indexes.format("[*]"),
183+
self.query_invalid_indexes.format('new')),
184+
'{0},$3 $2 -d "$1" -c "{1}"'.format(self.key_invalid_old_indexes.format("[*]"),
185+
self.query_invalid_indexes.format('old'))]
143186
return template_zabbix.key_and_query(result)

0 commit comments

Comments
 (0)