Happy birthday... / Feliz anivers�rio

This article is written in English and Portuguese
Este artigo est� escrito em Ingl�s e Portugu�s

English version:

I'm really not very good with dates. I keep forgetting them. Today I was reviewing some of the blog links and structure, and one date poped up: September 26 of 2006. Around four years ago I made the first post in this blog. During these four years I believe I've made some interesting posts here (apologies for the lack od modesty), and judging by some feedback I have received some of this posts were important for my readers. That's the best reward I could get.
On that first post I explained some of the reasons why I was creating a blog. And these were:

  1. The only blog I've found about Informix seems empty
  2. I've been involved with Informix technology for several years and I think the Informix community although enthusiastic is a bit invisible
  3. I have some subjects about which I'd like to write a bit...
It's with great pleasure that I see that 1) and 2) aren't valid anymore. As you can see from the lists of links on the right side, we have a healthy blog community. We also have a strong international user group, and new user groups are appearing around the world (China, Adria, Brazil...)

One thing has not changed: I still have some subjects about which I'd like to write a bit. History is a funny thing and tends to repeat itself. Around 2006 we were preparing Cheetah which was released in 2007. Then came Cheetah 2 (2008). We're now waiting for Panther.

So I hope you enjoy the links/blogs revision and stay tuned for upcoming articles. Let's hope I have the time for everything I want to publish

Vers�o Portuguesa:

N�o sou nada bom com datas. � habitual esquecer-me dos anivers�rios dos amigos (e at� mesmo do meu!). Hoje estava a rever a lista de links e blogs e uma data saltou-me � vista: 26 de Setembro de 2006. H� cerca de quatro anos atr�s eu coloquei o primeiro artigo neste blog. Durante estes quatro anos escrevi alguns artigos interessantes (mod�stia � parte) e a julgar por algumas reac��es que recebi, alguns desses artigos foram importantes para os meus leitores. Essa � a melhor recompensa que poderia ter.

Nesse primeiro artigo eu indiquei as raz�es porque estava a criar um blog. E estas eram:

  1. O �nico blog que encontrei sobre Informix parecia vazio
  2. Estava envolvido com a tecnologia Informix h� j� v�rios anos e parecia-me que a comunidade Informix, apesar de entusiasta, parecia invis�vel.
  3. Tinha v�rios assuntos sobre os quais queria escrever...
� com grande prazer que vejo que 1) e 2) j� n�o s�o v�lidos. Como se pode ver pela lista de � direita, temos uma comunidade de blogs bastante saud�vel. Tamb�m temos um grupo internacional de utilizadores forte, e novos grupos locais t�m aparecido (China, Adria, Brasil...)

Algo que n�o mudou: Ainda tenho v�rios assuntos sobre os quais desejo escrever. A hist�ria costuma repetir-se. Por volta de 2006 est�vamos a preparar a vers�o Cheetah que foi lan�ada em 2007. Depois veio a Cheetah 2 (2008). Agora estamos � espera do Panther.

Assim, espero que aprecie a revis�o dos links/blogs e mantenha-se alerta aos pr�ximos artigos. Espero que tenha tempo suficiente para tudo o que pretendo publicar.

Have you met ROI and TCO? / J� conhece o ROI e o TCO?

This article is written in English and Portuguese
Este artigo est� escrito em Ingl�s e Portugu�s

English Version:

ROI and TCO are two well known IT buzzwords. They mean Return On Investment and Total Cost of Ownership (check the links for more technical descriptions). The first one tries to measure how much you earn or lose by investing on something (software product or solution in IT world). The second one tries to be a measure of the sum of costs you have when you decide to buy and use a software product or solution. For the technical staff these two measures are not the most important aspects. Usually we just like or dislike a product period!
But the decisions and choices usually aren't done by technical staff. Today the decisions are taken by people who have tight budgets and that need to show to corporate management that they are using the company's money properly. In other words, people who do and must care about TCO and ROI.
And many times we hear that Informix is nice technically (easy to work with, robust, scalable etc.), but that it's hard to convince higher management to use it (there are still ghosts from the past and FUD spread by competition).

Well, now we have two consulting firms studies precisely about these two topics.

The first comes from Forrester Consulting and analyses the costs, benefits and ROI of implementing Informix. Needless to say it concludes that you actually can save money while investing in Informix, and it explains why. The study was based on a real company.

The second come from ITG group and compares the TCO of Informix vs Microsoft SQL Server for mid sized companies. It's based on a survey with ten's of participants and the conclusions are, as you might expect, favorable to Informix (important to note that MS SQL Server has a reputation of being "economic", so we could let us think that it would be even better for other competitors)

The studies can be freely obtained from IBM website, and as usual you need to fill some data. I know, I know.... this is always annoying and we could arguably consider that this should be only a link to allow quick access to that, but honestly it will take one minute to fill the form, and you have the usual option to request that you won't be bothered (no emails, phone calls etc.)
Don't let it discourage you. The studies are well worth the effort. Their URLs are:

Finally, take notice that these studies used Informix 11.50. And we're getting closer to Panther which has lot's of improvements and some of them will certainly have impact on the running costs (less burden for the DBAs)


Vers�o Portuguesa:

ROI e TCO s�o duas palavras muito em voga no mundo das TI. Qurem dizer Return On Investment (Retorno do investimento) e Total Cost of Ownership (Custo total da posse) (verifique os links para explica��es mais t�cnicas - e ainda mais detalhadas na vers�o Inglesa). O primeiro tenta medir quanto se ganha ou perde ao investir em algo (produto ou solu��o de software no mundo das TI). O segundo tenta ser uma medida da soma de custos que teremos quando decidimos usar um produto ou solu��o de software. Para o pessoal t�cnico estas medidas n�o s�o os aspectos mais importantes. Normalmente n�s apenas gostamos ou n�o e ponto final!
Mas as decis�es e escolhas normalmente n�o s�o feitas pelo pessoal t�cnico. Hoje em dia as decis�es s�o tomadas por pessoas que t�m or�amentos apertados e que sentem a necessidade de mostrar � administra��o das empresas que est�o a usar o dinheiro da companhia criteriosamente. Por outras palavras, pessoas que se preocupam e devem preocupar com o TCO e ROI.
E muitas vezes ouvimos dizer que o Informix � muito bom tecnicamente (simples, f�cil de usar, fi�vel etc.), mas que � dif�cil convencer a gest�o a us�-lo (ainda existem fantasmas do passado e FUD espalhado pela concorr�ncia)-


Bom, mas agora temos dois estudos de duas empresas de consultoria precisamente sobre estes t�picos.

O primeiro vem da Forrester Consulting e analisa os custos, benef�cios e ROI de implementar Informix. Escusado ser� dizer que conclu� que na realidade estamos a poupar dinheiro ao investir em Informix, e explica porqu�. O estudo foi baseado num caso real.

O segundo vem da ITG Group e compara o TCO do Informix vs Microsoft SQL Server para m�dias empresas. � baseado num inqu�rito com dezenas de participantes e as conclus�es s�o, como seria de esperar, favor�veis ao Informix (� importante notar que o MS SQL Server tem a reputa��o de ser "econ�mico", por isso poder�amos deixar-nos pensar que seria ainda mais favor�vel comparando com outros concorrentes)

Os estudos podem ser obtidos gratuitamente no website da IBM, e como � habitual necessitamos de preencher alguns dados. Sim, eu sei, eu sei.... Isto � sempre irritante e � discut�vel de n�o deveria ser apenas uma quest�o de clicar num link para aceder aos estudos, mas honestamente n�o demora mais de um minuto a preencher o formul�rio e tem as op��es habituais para que n�o sejamos incomodados (nada de emails ou chamadas telef�nicas etc.)
N�o deixe que isso o desencorage. Os estudos merecem bem este pequeno esfor�o. Os seus endere�os s�o:

Finalmente, note-se que estes estudos incidiram no Informix 11.50. E estamos a aproximarmo-nos da vers�o Panther que trar� muitas melhorias e algumas delas ter�o certamente impacto nos custos de utiliza��o (menos carga para os DBAs)

Let's optimize / Vamos optimizar

This article is written in English and Portuguese
Este artigo est� escrito em Ingl�s e Portugu�s

English version.

In this article I'll show you a curious situation related to the Informix query optimizer. There are several reasons to do this. First, this is a curious behavior which by itself deserves a few lines. Another reason is that I truly admire the people who write this stuff... I did and I still do some programming, but my previous experience was related to business applications and currently it's mostly scripts, small utilities, stored procedures etc. I don't mean to offend anyone, but I honestly believe these two programming worlds are on completely different leagues. All this to say that a query optimizer is something admirable given the complexity of the issues it has to solve.

I also have an empiric view or impression regarding several query optimizers in the database market. This impression comes from my personal experience, my contact with professionals who work with other technologies and some readings... Basically I think one of our biggest competitors has an optimizer with inconstant behavior, difficult to understand and not very trustworthy. One of the other IBM relational databases, in this case DB2, has probably the most "intelligent" optimizer, but I have nearly no experience with it. As for Informix, I consider it not the most sophisticated (lot of improvements in V10 and V11, and more to come in Panther), but I really love it for being robust. Typically it just needs statistics. I think I only used or recommended directives two times since I work with Informix. And I believe I never personally hit an optimizer bug (and if you check the fix lists in each fixpack you'll see some of them there...)
To end the introduction I'd like to add that one of my usual tasks is query optimizing... So I did catch a few interesting situations. As I wrote above, typically an UPDATE statistics solves the problem. A few times I saw situations where I noticed optimizer limitations (things could work better if it could solve the query another way), or even engine limitations (the query plan is good, but the execution takes unnecessary time to complete). The following situation was brought to my attention by a customer who was looking around queries using a specific table which had a reasonable number of sequential scans.... Let's see the table schema first:

create table example_table
(
et_id serial not null ,
et_ts datetime year to second,
et_col1 smallint,
et_col2 integer,
et_var1 varchar(50),
et_var2 varchar(50),
et_var3 varchar(50),
et_var4 varchar(50),
et_var5 varchar(50),
primary key (et_id)
)
lock mode row;

create index ids_example_table_1 on example_table (et_timestamp) using btree in dbs1


And then two query plans they manage to obtain:


QUERY: (OPTIMIZATION TIMESTAMP: 08-25-2010 12:31:56)
------
SELECT et_ts, et_col2
FROM example_table WHERE et_var2='LessCommonValue'
AND et_col1 = 1 ORDER BY et_ts DESC


Estimated Cost: 5439
Estimated # of Rows Returned: 684
Temporary Files Required For: Order By

1) informix.example_table: SEQUENTIAL SCAN

Filters: (informix.example_table.et_var2 = 'LessCommonValue' AND informix.example_table.et_col1 = 1 )


So this was the query responsible for their sequential scans. Nothing special. The conditions are on non indexed fields. So no index is used. It includes an ORDER BY clause, so a temporary file to sort is needed (actually it can be done in memory, but the plan means that a sort operation has to be done).
So, nothing noticeable here... But let's check another query plan on the same table. In fact, the query is almost the same:


QUERY: (OPTIMIZATION TIMESTAMP: 08-25-2010 12:28:32)
------
SELECT et_ts, et_col2
FROM example_table WHERE et_var2='MoreCommonValue'
AND et_col1 = 1 ORDER BY et_ts DESC


Estimated Cost: 5915
Estimated # of Rows Returned: 2384

1) informix.example_table: INDEX PATH

Filters: (informix.example_table.et_var2 = 'MoreCommonValue' AND informix.example_table.et_col1 = 1 )

(1) Index Name: informix.ids_example_table_1
Index Keys: et_ts (Serial, fragments: ALL)


Ok... It's almost the same query, but this time we have an INDEX path.... Wait... Didn't I wrote that the conditions where not on indexed column(s)? Yes. Another difference: It does not need a temporary file for sort (meaning that it's not doing a sort operation). Also note that there are no filter applied on the index. So, in this case it's doing a completely different thing than on the previous situation. It reads the index (the whole index), accesses the rows (so it gets them already ordered) and then applies the filters discarding the rows that do not match. It does that because it wants to avoid the sort operation. But why does it change the behavior? You might have noticed that I already included a clue about this. To protect data privacy, I changed the table name, table fields and the query values. And in the first query I used "LessCommonValue" and on the second I used "MoreCommonValue". So as you might expect, the value on the second query is more frequent in the table than the value of the first query. How do we know that? First, by looking at the number of estimated rows returned (684 versus 2384). How does it predict this values? Because the table has statistics, and in particular column distribution. Here are them for the et_var2 column (taken with dbschema -hd):


Distribution for informix.example_table.et_var2

Constructed on 2010-08-25 12:19:04.31216

Medium Mode, 2.500000 Resolution, 0.950000 Confidence


--- DISTRIBUTION ---

( AnotherValue )


--- OVERFLOW ---

1: ( 4347, Value_1 )
2: ( 4231, Value_2 )
3: ( 3129, MoreCommonValue )
4: ( 2840, Value_4 )
5: ( 2405, Value_5 )
6: ( 3854, Value_6 )
7: ( 3941, Value_7 )
8: ( 2086, Value_8 )
9: ( 4086, Value_9 )
10: ( 4144, Value_10 )
11: ( 4086, Value_11 )
12: ( 2666, Value_12 )
13: ( 2869, Value_13 )
14: ( 3245, Value_14 )
15: ( 2811, Value_15 )
16: ( 3419, Value_16 )
17: ( 2637, Value_17 )
18: ( 3187, Value_18 )
19: ( 4347, Value_19 )
20: ( 898, LessCommonValue )
21: ( 4144, Value_20 )
22: ( 2260, Value_21 )
23: ( 3999, Value_22 )
24: ( 1797, Value_23 )
25: ( 2115, Value_24 )
26: ( 2173, Value_25 )
27: ( 4144, Value_26 )


If you're not used to look at this output I'll describe it. The distributions are showed as a list of "bins". Each bin, except the first one, contains 3 columns: The number of record it represents, the number of unique values within that bin, and the highest value within that bin. The above is not a good example because the "normal" bin values has only one (AnotherValue) and given it's the first one it means it's the "lowest" value in the column. Let's see an example from the dbschema description in the migration guide:


( 5)
1: ( 16, 7, 11)
2: ( 16, 6, 17)
3: ( 16, 8, 25)
4: ( 16, 8, 38)
5: ( 16, 7, 52)
6: ( 16, 8, 73)
7: ( 16, 12, 95)
8: ( 16, 12, 139)
9: ( 16, 11, 182)
10: ( 10, 5, 200)


Ok. So, looking at this we could see that the lowest value is 5, and that between 5 and 11 we have 16 values, 7 of them are unique. Between 11 and 17 we have 6 unique values etc.

Going back to our example we see an "OVERFLOW" section. This is created when there are highly repeated values that would skew the distributions. In these cases the repeated values are showed along the number of times they appear.

So, in our case, the values we're interested are "LessCommonValue" (898 times) and "MoreCommonValue" (3129 times). So with these evidences we can understand the decision to choose the INDEX PATH. When the engine gets to the end of the result set it's already ordered. And in this situation (more than 3000 rows) the order by would be much more expensive than for the other value (around 800 rows).

It's very arguable if the choice is effectively correct. But my point is that it cares... Meaning it goes deep in it's analysis, and that it takes into account many aspects, and is able to decide to use a query plan that it's not obvious (and choose it for good reasons).


Vers�o portuguesa:

Neste artigo vou mostrar uma situa��o curiosa relacionada com o optimizador de queries do Informix. H� v�rias raz�es para fazer isto. Primeiro porque � um comportamento interessante que por si s� merece umas linhas. Outra raz�o � que eu admiro verdadeiramente as pessoas que escrevem este componente.... Eu fiz e ainda fa�o alguma programa��o, mas a minha experi�ncia anterior estava relacionada com aplica��es de neg�cio e actualmente � essencialmente scripts, pequenos utilit�rios, stored procedures etc. N�o querendo ofender ningu�m, mas honestamente acredito que estes dois mundos de programa��o est�o em campeonatos completamente diferentes. Tudo isto para dizer que o optimizador � algo admir�vel dada a complexidade dos problemas que ele tem de resolver.

Tamb�m tenho uma vis�o emp�rica ou apenas uma impress�o relativamente a alguns optimizadores no mercado de bases de dados. Esta impress�o deriva da minha experi�ncia pessoal, do meu contacto com profissionais que trabalham com outras tecnologias e de alguma leitura... Basicamente penso que o nosso maior competidor tem um optimizador com um comportamento insconstante, dif�cil de entender e pouco confi�vel. Uma das outras bases de dados relacionais da IBM, DB2 neste caso, tem provavelmente o optimizador mais "inteligente", mas n�o tenho practicamente nenhuma experi�ncia com ele. No caso do Informix, considero que n�o � o mais sofisticado (muitas melhorias na vers�o 10 e 11, e mais no Panther), mas realmente adoro a sua robustez. Tipicamente apenas precisa de estat�sticas. Julgo que s� utilizei ou recomendei optimizer directives duas vezes desde que trabalho com Informix. E que me lembre nunca bati pessoalmente num bug do optimizador (embora baste consultar a lista de correc��es de cada fixpack para sabermos que eles existem).
Para terminar esta introdu��o gostaria de referir que uma das minhas tarefas habituais � a optimiza��o de queries. Por isso j� encontrei algumas situa��es interessantes. Como escrevi acima, tipicamente um UPDATE STATISTICS resolve o problema. Algumas vezes encontrei limita��es do optimizador (as coisas poderiam correr melhor se ele pudesse resolver as queries de outra maneira) e at� limita��es do motor (o plano de execu��o gerado � bom, mas a execu��o leva tempo desnecess�rio a correr). A situa��o que se segue chegou-me � aten��o atrav�s de um cliente que estava a analisar queries sobre uma tabela que estava a sofrer muitos sequential scans.... Vejamos a defini��o da tabela primeiro:
create table example_table
(
et_id serial not null ,
et_ts datetime year to second,
et_col1 smallint,
et_col2 integer,
et_var1 varchar(50),
et_var2 varchar(50),
et_var3 varchar(50),
et_var4 varchar(50),
et_var5 varchar(50),
primary key (et_id)
)
lock mode row;

create index ids_example_table_1 on example_table (et_timestamp) using btree in dbs1


E agora dois planos de execu��o que obtiveram:


QUERY: (OPTIMIZATION TIMESTAMP: 08-25-2010 12:31:56)
------
SELECT et_ts, et_col2
FROM example_table WHERE et_var2='ValorMenosComum'
AND et_col1 = 1 ORDER BY et_ts DESC


Estimated Cost: 5439
Estimated # of Rows Returned: 684
Temporary Files Required For: Order By

1) informix.example_table: SEQUENTIAL SCAN

Filters: (informix.example_table.et_var2 = 'ValorMenosComum' AND informix.example_table.et_col1 = 1 )


Esta era uma das queries respons�vel pelos sequential scans. Nada de especial. As condi��es da query incidem em colunas n�o indexadas. Portanto n�o utiliza nenhum ind�ce. Inclui uma cl�usula ORDER BY, por isso um necessita de "ficheiros" tempor�rios para ordena��o. (na verdade pode ser feito em mem�ria, mas o plano quer dizer que precisa de fazer uma opera��o de ordena��o).
Portanto nada a salientar aqui.... Mas vejamos o outro plano sobre a mesma tabela. Na verdade a query � muito semelhante:


QUERY: (OPTIMIZATION TIMESTAMP: 08-25-2010 12:28:32)
------
SELECT et_ts, et_col2
FROM example_table WHERE et_var2='ValorMaisComum'
AND et_col1 = 1 ORDER BY et_ts DESC


Estimated Cost: 5915
Estimated # of Rows Returned: 2384

1) informix.example_table: INDEX PATH

Filters: (informix.example_table.et_var2 = 'ValorMaisComum' AND informix.example_table.et_col1 = 1 )

(1) Index Name: informix.ids_example_table_1
Index Keys: et_ts (Serial, fragments: ALL)

Ok... � quase a mesma query, mas desta vez temos um INDEX PATH... Um momento!.... N�o escrevi que as condi��es n�o indiciam sobre colunas indexadas? Sim. Outra diferen�a: Neste caso n�o necessita de "temporary files" (o que significa que n�o est� a fazer ordena��o). Note-se ainda que n�o existe nenhum filtro aplicado ao ind�ce. Portanto, neste caso est� a fazer algo completamente diferente da situa��o anterior. L� o ind�ce (todo o ind�ce), acede �s linhas (assim obt�m-nas j� ordenadas) e depois aplica os filtros descartando as linhas que n�o verificam as condi��es. Faz isto porque pretende evitar a opera��o de ordena��o. Mas porque � que muda o comportamento? Poder� ter reparado que j� inclui uma pista sobre isto. Para proteger a privacidade dos dados mudei o nome da tabela, dos campos e dos valores das queries. E no primeiro caso utilizei "ValorMenosComum" e no segundo usei "ValorMaisComum". Portanto como se pode esperar, o valor da segunda query � mais frequente na tabela que o valor usado na primeira query. Como sabemos isso? Primeiro olhando para o valor estimado de n�mero de linhas retornadas pela query (684 vs 2384). Como � que o optimizador prev� estes valores? Atrav�s das estat�sticas da tabela, em particular as distribui��es de cada coluna. Aqui est�o as mesmas para a coluna et_var2 (obtidas com dbschema -hd):

Distribution for informix.example_table.et_var2

Constructed on 2010-08-25 12:19:04.31216

Medium Mode, 2.500000 Resolution, 0.950000 Confidence


--- DISTRIBUTION ---

( OutroValor )


--- OVERFLOW ---

1: ( 4347, Value_1 )
2: ( 4231, Value_2 )
3: ( 3129, ValorMaisComum )
4: ( 2840, Value_4 )
5: ( 2405, Value_5 )
6: ( 3854, Value_6 )
7: ( 3941, Value_7 )
8: ( 2086, Value_8 )
9: ( 4086, Value_9 )
10: ( 4144, Value_10 )
11: ( 4086, Value_11 )
12: ( 2666, Value_12 )
13: ( 2869, Value_13 )
14: ( 3245, Value_14 )
15: ( 2811, Value_15 )
16: ( 3419, Value_16 )
17: ( 2637, Value_17 )
18: ( 3187, Value_18 )
19: ( 4347, Value_19 )
20: ( 898, ValorMenosComum )
21: ( 4144, Value_20 )
22: ( 2260, Value_21 )
23: ( 3999, Value_22 )
24: ( 1797, Value_23 )
25: ( 2115, Value_24 )
26: ( 2173, Value_25 )
27: ( 4144, Value_26 )


Para o caso de n�o estar habituado a analisar esta informa��o vou fazer uma pequena descri��o da mesma. As distribui��es s�o mostradas como uma lista de "cestos". Cada cesto, excepto o primeiro, cont�m 3 colunas: O n�mero de registo que representa, o n�mero de valores �nicos nesse cesto e o valor mais "alto" nesse cesto. O que est� acima n�o � um bom exemplo porque a sec��o de "cestos" normal s� tem um valor (OutroValor), e dado que � o primeiro apenas tem o valor, o que significa que � o valor mais "baixo" da coluna. Vejamos um exemplo retirado da descri�ao do utilit�rio dbschema no manual de migra��o:


( 5)
1: ( 16, 7, 11)
2: ( 16, 6, 17)
3: ( 16, 8, 25)
4: ( 16, 8, 38)
5: ( 16, 7, 52)
6: ( 16, 8, 73)
7: ( 16, 12, 95)
8: ( 16, 12, 139)
9: ( 16, 11, 182)
10: ( 10, 5, 200)


Portanto olhando para isto podemos ver que o valor mais baixo � 5, que entre 5 e 11 temos 16 valores, 7 dos quais s�o �nicos. Entre 11 e 17 temos 6 valores �nicos etc.

Voltando � nossa situa��o concreta vemos uma sec��o de "OVERFLOW". Esta sec��o � criada quando h� valores altamente repetidos que iriam deturpar ou desequilibrar as distribui��es. Nestes casos os valores repetidos s�o mostrados lado a lado com o n�mero de vezes que aparecem.

Assim, no nosso caso, estamos interessados nos valores "ValorMenosComum" (898 vezes) e "ValorMaisComum" (3129 vezes). Portanto, com estas evid�ncias podemos perceber a decis�o de escolher o INDEX PATH. Quando o motor chega ao final do conjunto de resultados o mesmo j� est� ordenado. E nesta situa��o (mais de 3000 linhas) a ordena��o consumiria mais recursos qeu para a outra situa��o em an�lise (cerca de 800 linhas).


Pode ser muito discutivel se a decis�o � efectivamente correcta. Mas o que quero salientar � que o optimizador se preocupa.... Ou seja, a an�lise que faz das condi��es e op��es � profunda e � capaz de escolher um plano de execu��o que n�o � �bvio (e escolh�-lo por boas raz�es).

Briug / Briug :)

Este artigo est� escrito em Ing�s e Portugu�s.
This article is written in English and Portuguese.

Vers�o Portuguesa

Normalmente come�o com a vers�o Inglesa, mas desta vez tinha naturalmente de come�ar com a vers�o Portuguesa. E como j� ter�o reparado o t�tulo do artigo est� igual em ambas as linguas. O que quer dizer BRIUG? Simples, Brazilian Informix Users Group. E pronto, est� o artigo acabado... N�o. Ainda n�o.... Falta dizer que foi criado o grupo Brasileiro de utilizadores de Informix, j� tem um website ( http://www.briug.org/ ) e que quem est� de momento a dar a cara e o trabalho pelo mesmo � o Miguel Carbone, bem conhecido na comunidade, entre outras coisas porque faz parte do board of directors do International Informix Users Group (IIUG) e o C�sar Martins, autor do blog sobre Informix em http://www.imartins.com.br/informix/
Naturalmente o grupo vai contar com o apoio e colabora��o de outras caras conhecidas da comunidade no Brasil e n�o s�. Estou a recordar-me do Vagner Pontes, do Alexandre Marini (muito activo na mailing list do IIUG), do Pedro Henriques.... Temo esquecer-me de algu�m.
Tive o privilegio de conhecer pessoalmente algumas destas pessoas durante a confer�ncia anual do IIUG e o que posso dizer � que estou confiante que o assunto est� bem entregue.

Do lado de c� do Atl�ntico v�o os votos de muito sucesso, e muito contentamento por ver uma organiza��o deste tipo num Pa�s que fala Portugu�s. Espero que apesar da dist�ncia tamb�m n�s em Portugal possamos usufruir de algumas iniciativas que o novo grupo venha a desenvolver. E naturalmente quando for necess�rio uma ma�zinha c� estaremos para o que for poss�vel.

English Version:

I usually start by the English version, but this time I had to change. If you noticed, the article title is the same in English and Portuguese... So what is BRIUG? It means Brazilian Informix Users Group... I probably could end the article here, since it's easy to guess what happened, but I must write a few more words... So the Brazilian Informix Users are starting a new user group, and they already have a website ( http://www.briug.org/ ), and for now the people behind it are Miguel Carbone, a well known guy in the community (member of the International Informix Users Group - IIUG - board of directors) and C�sar Martins, author of the Informix blog at http://www.imartins.com.br/informix/.
Naturally the group counts on the support and colaboration of other well known faces of the Brazilian Informix community like Vagner Pontes, Alexandre Marini (very active in the IIUG mailing list), Pedro Henriques.... I'm afraid I'll forget someone...
I had the pleasure of meeting some of these guys during the IIUG annual meeting and I'm convinced that the matter is in good hands.

From this side of the Atlantic ocean, I send my wishes of great success and I'm very happy to see the birth of an organization like this in a Portuguese speaking country.
I hope that despite the distance we in Portugal can take advantage of some of the initiatives that the new group develop in the future. Ans obviously, when you need an helping hand, we're here to do whatever is possible.

Out of support? Not yet! / Fora de suporte? Ainda n�o

This article is written in English and Portuguese
Este artigo est� escrito em Ingl�s e Portugu�s

English Version:

I hope that you had the chance to listen to the latest Chat with the Labs web conference. The topic was really interesting, specially if you're running Informix 7.31, 9.4 or 10. As you should know all these versions are out of support (v10 will be by the end of September). In this call, IBM announced (or re-announced) three options for support of these versions:

  1. Upgrade Bridge
    • This is just for 7.31
    • Has costs
    • Requires active subscription and support (S&S)
    • Client must have plans for upgrade
    • Can't be sold by partners
    • Doesn't provide R&D access or new fixes development
    • Provides severity 1 critical responses (systems down)
  2. Continuing Support (Pilot)
    • This is for version 9.4 and v10
    • Is included in active subscription and support (S&S)
    • Can be sold by partners, since it's included in S&S
    • Doesn't provide R&D access or new fixes development
    • Provides severity 1 critical responses (systems down)
    • Will end on September 2011 (1 year duration)
  3. Service extension
    • This can be acquired for any unsupported version
    • Has costs
    • Requires active subscription and support (S&S)
    • Can't be sold by partners
    • Provides access to R&D and new fixes development
    • Provides severity 1 critical response (systems down)
So, what does it all mean? Well, it really depends on your current version and your future plans:
  • For 7.31 (bridge) means that if you want to migrate, IBM will support you during the time it takes, and can also help you do the upgrade (separate cost). Note that you need to have upgrade plans.
    If you hit a new bug (one that has no fix for 7.31 or that is unknown), you're stuck with it. If you have a system down situation you will get help.
  • For versions 9.40 and 10, it means that you'll have one more year of support, included in the regular maintenance fee. Note that again, if you hit a new bug (either really new, or one that has no fix in versions 9.40 or 10) you'll have to live with it
    The good news is that you just need active maintenance (S&S)
  • For any version, if you really need access to new fixes (new bugs, or bugs to which there was no fixpack available with the fix), you can request the service extension. Note that this has charges besides the normal S&S cost.
So, the Continuing Support (Pilot) offer means you gained one more year to plan and do an upgrade, while keeping the ability of asking for help in case something goes wrong. Is this good? I believe the answer is yes if you're running one of those versions. But I personally have mixed feelings regarding this. Let's see:

  1. Ending support of a product version is always risky, since you may cause customer dissatisfaction
  2. Ending support of a product version can lead the customer to consider alternatives from competitors (If I have to migrate, why don't I choose another software....?)
  3. Keeping endless support for a product is negative for the software supplier for a number of (good) reasons:
    • It costs money (resources, source code maintenance, some bugs can be fixed in one way in newer versions, but have to be dealt with differently in older versions)
    • It keeps your customers away from new features and improved product uses
    • Increases the chances that customers favor the competition, because many times they compare the old version of a product from X with a newer version of a product from Y
  4. Having old product versions is bad for customers because:
    • Increases exposure to old bugs and security issues
    • Limits the ability to move to more recent platforms (hardware and operating systems)
    • Decreases your team members motivation (typically people like to work with new features, and they feel happy to learn new stuff)
  5. Upgrades are good for software suppliers and partners because:
    • Typically they are drivers for new sales of products and services
    • They are opportunities to get involved with the customers
    • They are opportunities to transfer knowledge and improve customer satisfaction and awareness
    • They can be drivers to new opportunities (cross sell anyone?)
  6. Upgrades are good for customers because:
    • They have the chance to improve product use
    • They are able to use new features
    • They can move to newer, better and cheaper platforms
    • They can gain new knowledge
  7. Upgrades can bin risky because you may face new problems, bugs or human errors
All this are advantages and disadvantages to use current software versions. I tried to be absolutely honest and objective (you can judge that and add or emphasize some of the points above). But in general, I'm in favor of keeping up to date with the current versions. Obviously you need to be careful, and stability has to be a value to preserve. But keeping yourself in software versions that are out of support or that will be out of support in a near future is no way to go. Do your upgrades, and do them well. I honestly suggest to everyone that is using 9.4 or 10 to take this new opportunity, and plan your upgrades in the next year. Each environment is different, but I've been very happy with latests 11.50 fixpacks.

So, please, check the web conference files (slides and audio - when available), if you have questions check the contact details, and then plan, plan, plan, test, test, test and upgrade!
I truly believe you'll be very happy with the improvements that IBM have been putting into IDS (and if you want to learn more about the future, check the Panther beta program)



Vers�o Portuguesa:

Espero que tenha tido oportunidade de assistir � �ltima confer�ncia web da s�rie Chat with the Labs. O t�pico foi verdadeiramente interessante, especialmente de estiver a utilizar o Informix 7.31, 9.40 ou 10. Como deve saber, estas vers�es est�o sem suporte (a vers�o 10 ficar� no final de Setembro pr�ximo).
Nesta apresenta��o a IBM anunciou (ou re-anunciou) tr�s op��es para suporte destas vers�es:
  1. Upgrade Bridge
    • Apenas para a vers�o 7.31
    • Tem custos
    • Necessita de subscri��o e suporte activa (S&S)
    • Cliente tem de possuir plano de upgrade
    • N�o pode ser vendido por parceiros
    • N�o permite acesso ao desenvolvimento nem a novas correc��es
    • Disponibiliza suporte a problemas de severidade 1 (sistemas parados)
  2. Continuing Support (Pilot)
    • Dispon�vel para as vers�es 9.40 e 10
    • Est� incluinda na manuten��o (subscri��o e suporte - S&S)
    • Pode ser vendida por parceiros pois est� inclu�da na manuten��o
    • N�o permite acesso ao desenvolvimento nem a novas correc��es
    • Disponibiliza suporte a problemas de severidade 1 (sistemas parados)
    • Termina em Setembro de 2011 (dura��o de um ano)
  3. Extens�o de servi�o ou suporte extendido
    • Pode ser adquirido para qualquer vers�o j� sem suporte
    • Tem custos
    • Necessita de manuten��o (subscri��o e suporte - S&S)
    • N�o pode ser vendido por parceiros
    • N�o permite acesso ao desenvolvimento nem a novas correc��es
    • Disponibiliza suporte a problemas de severidade 1 (sistemas parados)
Portanto, o que � que tudo isto significa? Bem, depende da sua vers�o actual e dos seus planos para o futuro:

  • Para a 7.31 (bridge) significa que se quiser migrar, a IBM ir� fornecer suporte durante o tempo que demorar, e pode at� ajudar na migra��o (custos separados). Note-se que ter� de ter planos de upgrade
    Se encontrar um novo bug, (um que n�o tenha correc��o na linha 7.31 ou que seja desconhecido) n�o lhe ser� dada solu��o. Se tiver uma situa��o de sistema parado ser-lhe-� prestada ajuda.
  • Para as vers�es 9.40 e 10 (Continuing Support Pilot) significa que ter� mais um ano de suporte, inclu�do na presta��o de manuten��o regular. Note-se novamente que se encontrar um novo bug (seja realmente novo, ou um para o qual n�o exista nenhum fixpack nas vers�es 9.40 ou 10 que incl�a a correc��o) ter� de viver com o mesmo
    A boa (excelente?) not�cia � que s� precisa de ter a manuten��o (S&S) activa
  • Para qualquer vers�o, se quer mesmo ter acesso a todas as possibilidades do suporte (incluindo novos fixes) pode contratar a extens�o de suporte. Note-se que isto tem custos adicionais ao custo normal de manuten��o
Assim, a oferta Continuing Support Pilot significa que ganhou mais um ano para planear e efectuar o upgrade, mantendo entretanto a possibilidade de pedir ajuda caso alguma coisa corra mal. Isto � bom? Penso que a resposta � sim, mas tenho sentimentos contradit�rios e pessoais sobre o assunto:

  1. Terminar o suporte a uma vers�o de um produto � sempre um risco, pois pode causar insatisfa��o dos clientes
  2. Terminar o suporte a uma vers�o de um produto pode levar um cliente a considerar alternativas da concorr�ncia ( se sou obrigado a migrar, porque n�o hei-de escolher outro software?)
  3. Manter o suporte por tempo indeterminado ou muito longo � negativo para o fornecedor de software por v�rias (boas?) raz�es:
    • Custa dinheiro (recursos, manuten��o do c�digo fonte, alguns bugs podem ser corrigidos de uma maneira nas vers�es correntes, mas terem de ser corrigidos de maneira diferente em vers�es mais antigas)
    • Leva os clientes a n�o utilizarem novas funcionalidades e n�o tirarem o melhor partido do que o produto (actual) permite
    • Aumenta as hip�teses de os clientes favorecerem a concorr�ncia, porque muitas vezes compara-se uma vers�o antiga do produto X com uma vers�o actual do produto Y
  4. Manter vers�es antigas de produtos � mau para os clientes porque:
    • Aumenta a exposi��o a bugs antigos e falhas de seguran�a
    • Limita a possibilidade de migra��o para plataformas mais actuais (hardware e sistema operativo)
    • Aumenta a desmotiva��o nas equipas de TI (tipicamente as pessoas gostam de trabalhar com as novas funcionalidades e ficam satisfeitas por adquirir novos e mais actuais conhecimentos
  5. Migra��es de vers�es podem ser boas para os fornecedores de software e seus parceiros porque:
    • Tipicamente s�o pretexto para novas vendas de produtos e servi�os
    • Providenciam oportunidades de criar e manter um maior envolvimento com os clientes
    • S�o oportunidades para haver transfer�ncia de conhecimento e melhorar a satisfa��o e reconhecimento dos clientes
    • Podem ser pretexto para novas oportunidades noutras �reas de neg�cio (cross sell)
  6. Migra��es de vers�es s�o boas para os clientes porque:
    • S�o uma oportunidade de melhorar a utiliza��o e explora��o dos produtos
    • Permitem o uso das novas funcionalidades
    • Permitem migrar para plataformas mais recentes, melhores e mais econ�micas
    • Permitem adquirir novos conhecimentos
  7. Migra��es de vers�es acarretam riscos porque se pode encontrar novos problems, bugs ou erros humanos
Tudo isto s�o vantagens e desvantagens de se manter em vers�es actualizadas do software. Tentei ser absolutamente honesto e objectivo (pode julgar por si, adicionar e relativizar a import�ncia dos v�rios pontos). Mas em geral, sou a favor de nos mantermos em vers�es correntes. Naturalmente temos de ter cuidados, e a estabilidade dos ambientes deve ser um valor a preservar. Mas deixar-se cair em vers�es sem suporte, ou que ir�o ficar sem suporte num futuro pr�ximo, n�o � um caminho correcto. Fa�a os seus upgrades e fa�a-os bem. Honestamente, sugiro a todos os utilizadores que estejam em vers�es 9.40 ou 10 que aproveitem esta oportunidade e planeiem as migra��es durante o pr�ximo ano. Cada ambiente � um caso espec�fico, mas tenho tinho muito boas experi�ncias com os �ltimos fixpacks da vers�o 11.50

Assim, por favor, consulte os ficheiros da confer�ncia web (slides e �udio - quando dispon�vel), se tiver quest�es consulte os contactos inclu�dos, e planeie, planeie, planeie, teste, teste, teste e migre!
Julgo sinceramente que ficar� bastante satisfeito com as melhorias que a IBM tem inclu�do no Informix (e se quiser saber mais sobre o futuro veja o programa beta da vers�o Panther)

New IBM Redbook / Novo Redbook IBM

This article is written in English and Portuguese
Este artigo est� escrito em Ingl�s e Portugu�s

English Version:

A new draft Redbook was announce by IBM through RSS feeds. It's called IBM Informix Developer's Handbook and it covers lots of aspects of Informix application development and several client technologies (ESQL/C, Java, ODBC, OleDB, PHP, .NET, Hibernate, Ruby...).

I took the opportunity to include some direct RSS feed on the right side of the blog. You can check it for new APARs, announcements etc.


Portuguese Version:

Um novo Redbook, ainda em vers�o "rascunho" foi anunciado pela IBM atrav�s dos feeds RSS. O t�tulo � "IBM Informix Developer's Handbook e cobre muitos aspectos do desenvolvimento de aplica��es em Informix, e v�rias tecnologias cliente (ESQL/C, Java, ODBC, OleDB, PHP, .NET, Hibernate, Ruby...).

Aproveitei a oportunidade de inserir alguns feeds RSS no lado direito do blog. Pode utiliz�-los para consultar novos APARs, an�ncios etc.

OAT: monitor dbspace usage / Monitoriza��o de ocupa��o de dbspaces

This article is written in English and Portuguese
Este artigo est� escrito em Ingl�s e Portugu�s

English version:

I keep working with OAT and the database scheduler and It keeps causing me a very good impression. The fact is that we can really get a structured way to deal with typical issues. The example I'll put here in this article is trivial, and every serious DBA has dealt with it. So, in a sense it doesn't bring anything new. Why the trouble? Because it serves as a very nice example on how things can fit together. During this article I'll show you how to take advantage of some components that you probably already use (alarmprogram and OAT) to build a robust, simple, configurable and also important, elegant space usage monitoring.

I'm sure you probably already have a script to monitor your space usage, so you may be thinking how will I convince you to dump it and use this. Let's see what are the usual issues with that kind of scripts:
  1. Typically they're launched by cron. Strangely or not, some customers are restricting the usage of cron. Hopefully this is not your case.
  2. Typically the scripts have the mechanism to send alarms inside them. If you need to change anything (email addresses, phone or page numbers), you may have to change several scripts
  3. Most of the times the scripts don't have "memory". Meaning for example, they'll keep sending alarms forever. In some cases this maybe useless and annoying.
  4. Since the scripts don't have "memory", they will not "clear" the alarm if the problem is solved
  5. The scripts typically will not send info to OAT. And OAT is elegant and easy to use
  6. Typically, different dbspaces in different instances will have acceptable usage thresholds different from each other. This means the scripts need to be more complex to allow customization
I think I could get a few more issues, but the above 6 will be enough. So, my value proposition is to create a mechanism that will solve all the issues above, and that also have some other advantages:
  • You can use is as a skeleton to build other monitoring tasks
  • It's all configurable within the database
As mentioned above we'll need several components:
  1. A fully functional ALARMPROGRAM script
    You should already have this, but some more customization will need to be implemented (a few lines)
  2. Open Admin Tool up and running
  3. Database scheduler active
  4. A procedure to call the ALARMPROGRAM script
    I took a look at a recent article from Andrew Ford about auto-extending dbspaces. He also has an example of a procedure to do this.
So, let's begin:

ALARMPROGRAM script changes


You should create a new class for the event generated by this monitoring task. I noticed Andrew recommends adding two classes (101 and 102 in his example), but I prefer to add just one and leave the decision to send email or paging/sms to the other ALARMPROGRAM parameter, the "severity". In fact I typically use a customized ALARMPROGRAM script where I can define that all events with a certain severity will send a short message and with lower will just send an email, or otherwise define a set of classes that send emails or sms independently of the severity

In any case configure and test your ALARMPROGRAM to receive another class and act accordingly to your needs. The advantage of using an ALARMPROGRAM script is that it becomes the only place where you'll need to change email addresses, pager or SMS numbers etc. Once configured it will work perfectly for you, and be re-usable for any kind of monitoring.

Open Admin Tool up and running

As you'll see, this task will generate alerts in the OAT screen. So you'll have something to show to your management. Typically they like to see some fancy graphics... You'll also be able to change the schedule and configuration of the task (including the thresholds). More on this later, as I have one complain about OAT :)

Database scheduler active

As already mentioned, this monitoring tool is implemented as a task in the database scheduler (introduced in version 11). So this is a requirement.

A procedure to call the ALARMPROGRAM script

As mentioned before, we'll need a procedure to call the ALARMPROGRAM script. This procedure will basically receive the parameters, construct a command and make a SYSTEM() call. The path of the ALARPROGRAM script will be queried from the sysmaster database. So if you ever want to change your script location you don't have to worry about this procedure. It will automatically adapt. The code for this procedure can be found in Listing 1 at the end of the article.
This procedure will be called in several places inside our monitoring task.


The task itself: Description and setup

The free space monitoring task is implemented as a stored procedure. You can find it in Listing 2 below. Let's check it nearly line by line.


  • Lines 1 and 2 are just the DROP/CREATE instructions. Notice that the procedure takes two arguments that are really great and helpful as we'll see later:
    task_id is the id in the ph_task table. It's unique for each task and allows us to cross reference several other tables in sysadmin
    v_id is the execution number of this task. It will change (increment) each time this task is executed
  • The next lines, up to 19, are just variable definitions. I won't explain them since they'll appear in several comments below
  • Lines 20 to 25 refer to debugging instructions. Just uncomment the lines 23 and 24 to get a trace of the task execution in a file created in your /tmp directory (obviously this can be changed)
  • Lines 29 to 31 are very important. The values defined are the last resort used by the task if all the other configuration parameters aren't in place. The defaults defined are:
    default yellow threshold (90): This will represent the percentage of use for each dbspace, above which an alarm of severity 3 will be raised
    default red threshold (95): This will represent the percentage of use for each dbspace, above which an alarm of severity 4 will be raised
    number of alarms (3): This will represent the number of alarms to send. A number of 0 will mean it will keep sending alarms until the situation is solved.

    As we shall see next, these values can be overridden by values configured in the task configuration, and the red/yellow threshold can be configured by dbspace. The above values will only be used if the other more specific configuration items are not setup. And of course, you can change these values in the code, so that they meet your environment.
  • Line 33 is very important since it defines the ALARMPROGRAM class number for lack of space in one dbspace. You should adjust these to the value you added to your ALARMPROGRAM. I use values above 900 for my "personal" extensions so that they won't match classes added to ALARMPROGRAM by IBM in the future (we'll never know how many will be added, but 900 seems a reasonable gap...)
  • Lines 35 to 93. Here we will try to get the defaults that were configured for the above values. These defaults are configuration items for the task. Unfortunately, current OAT versions don't allow us to use the GUI to setup these initial values. We have to create them using SQL. After that they can be changed using OAT's GUI.... I'd like to see the wizard for a new task creation to include the configuration of any task configuration items.... But it isn't there at this moment (version 2.28...). So we need to insert them via SQL. How to do it: These values are kept in the ph_threshold table, which has the following fields:
    name: This is the parameter name. In our case we have the following: DEFAULT NUM ALARMS, DBSPACE YELLOW DEFAULT, DBSPACE RED DEFAULT and then we can insert any in the forms DBSPACE YELLOW dbspace_name and DBSPACE RED dbspace_name. I think the names are self explanatory. The idea is that if you want to create red/yellow thresholds for specific dbspaces you'll have to insert the DBSPACE RED/YELLOW dbspace_name parameters in the ph_thresholds table. If there isn't a specific value for a certain dbspace it will use the value specified in the DBSPACE RED/YELLOW DEFAULT parameter. If these are also not defined, it will use the values defined in lines 29 to 31.
    task_name: the name of the task from the ph_task table. This value needs to match whatever name we give to the task and that's the one we will use to create the entry in the scheduler. For the purpose of this article I'll use IXMon Check Space. You can use whatever you want, as long as you're consistent.
    value: the value of the threshold. This will be the value to be used by the task. In our case, the DBSPACE RED/YELLOW * parameters will use percentage values (1-100)
    value_type: the data type of the threshold (STRING or NUMERIC). In our case we'll use NUMERIC. From some investigation I noticed that we can use NUMERIC(x,y) for non integer values. I didn't test it, but it should work in case it makes sense for you.
    description: a description of what the threshold does. This will be visible in the OAT's GUI if later you want to change the values using the GUI.

    So, to give you some examples, I'll just show the instructions used to create the values that are also specified in the code (number of alarms, red and yellow default thresholds). I'll use the same values:



    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DEFAULT NUM ALARMS', 'IXMon Check Space', '3', 'NUMERIC', 'Number of alarms to send');
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DBSPACE YELLOW DEFAULT', 'IXMon Check Space', '90', 'NUMERIC', 'Generic yellow threshiold. It will be applied to any dbspace lacking a specific threshold');
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DBSPACE RED DEFAULT', 'IXMon Check Space', '95', 'NUMERIC', 'Generic red threshiold. It will be applied to any dbspace lacking a specific threshold');


    And for example, if you have a dbspace called llogs_dbs, dedicated to logical logs which is nearly full and which doesn't make too much sense to monitor you could add:


    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DEFAULT YELLOW llogs_dbs', 'IXMon Check Space', '100', 'NUMERIC', 'Make llogs_dbs pass all tests....');
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DEFAULT RED llogs_dbs', 'IXMon Check Space', '100', 'NUMERIC', 'Make llogs_dbs pass all tests....');


  • Line 97 creates a FOREACH loop. It's based on the query in the next lines which will check the used space in every dbspace in the system
  • Lines 98 to 111. This is the dbspace usage query. Some parts of it might not be necessary, but I took the query from another script... Don't worry, it should work. It gives the number of the pages and the number of free pages in all the dbspace chunks grouped together.
    Notice that the task is based on usage percentage. It could be improved to handle other types of parameters, like allocated GB, or free GB etc. For now I kept it simple....
  • Lines 114 to 153 are used just to try to find specific thresholds for the dbspace we're processing. If they're not found in the ph_threshold table the generic defaults will be used.
  • Lines 154 to 172. Here we calculate the used space percentage and check it against the red and yellow thresholds. If we're beyond any of these values we'll define an alert color and the alert message. If we're below the yellow threshold we leave the color as NULL.
  • Lines 175 to 200. If our current dbspace usage is below the yellow threshold we look for an alert in the ph_alert table for this specific dbspace with state equal to "NEW". If we find one we update it, changing it's state to "ADDRESSED". This can happen if after an alarm was generated someone drops a table for example. In this case I'm not calling the ALARMPROGRAM, but it could make sense to call it with a message like "Previous alarm for dbspace_name is canceled because it's now below the defined thresholds"
  • From 204 till the end, we have exceeded one of the thresholds.... So... First we query ph_alert to see if we have an alarm for this dbspace in the state "NEW". If we don't (223 - 239) we insert it and call the ALARMPROGRAM using the procedure above. If we already have an alarm we check if it's the same color. If it's not (244 - 252), we update two fields:
    alert_task_seq: we do this to reset the alarm counter
    alert_color: we update the color code of the alarm (for usage in OAT's GUI. Note that at this time we may have a RED alert with an YELLOW message text. I choose to do this, to show that there was a change between the current and previous situation. If the alarm has the same color than we check the field alert_task_seq and compare it with our task execution number (given as a parameter to the procedure) and decide, based on the configured number of alarms if we should call ALARMPROGRAM or not

So, finally, how do we schedule the task? Well you can do it by using OAT's GUI or if you want you can insert it directly into the ph_task table:


INSERT INTO ph_task
(
tk_id, tk_name, tk_description, tk_type, tk_dbs,
tk_execute, tk_start_time, tk_frequency,
k_monday, tk_tuesday, tk_wednesday, tk_thursday,
tk_friday, tk_saturday, tk_sunday,
tk_group, tk_enable, tk_priority
)
VALUES
(
0, 'IXMon Check Space', 'Check dbspace free space', 'TASK', 'sysadmin',
'ixmon_check_space', '00:00:00', '0 00:30:00',
't', 't', 't', 't', 't', 't', 't',
'USER','t',0
)



UPDATE [ 20 Aug 2010]:
I missed and IF block wrapping the UPDATE to move the existing alarm to the state ADDRESSED (lines 195-200). Like it was, it would try the update even if we didn't find an alert... This was not very serious, but it you want to call ALARMPROGRAM when the alert conditions clear up, then you need this IF or it will send alarms for every dbspace that is below the thresholds.... Sorry about this mess... So I added the IF on line 194 and the END IF on line 201.

Vers�o Portuguesa:

Conitnuo a trabalhar com o Open Admin Tool (OAT) e o scheduler de tarefas da base de dados e continuo a ficar bem impressionado com ambos. A verdade � que nos permitem uma abordagem estruturada na gest�o de quest�es t�picas. O exemplo que vou deixar neste artigo refere-se a um assunto trivial e qualquer DBA j� se deparou com o mesmo. Neste sentido n�o tr�s nada de novo. Assim, porqu� o trabalho? Porque serve como excelente exemplo de como as coisas se podem encaixar. Ao longo deste artico tentarei mostrar como tirar proveito de alguns componentes que provavelmente j� utiliza nas suas inst�ncias (ALARMPROGRAM e OAT) para construir um mecanismo de monitoriza��o de espa�o utilizado que se pretende robusto, simples, configur�vel e igualmente importante, elegante.

Tenho a certeza que provavelmente j� ter� um script para monitorizar este aspecto, pelo que poder� estar a pensar como � que o vou convencer a desistir do mesmo e utilizar este (ou algo constru�do com base neste). Vejamos quais s�o os problemas habituais destes sripts:

  1. Normalmente s�o lan�ados pelo cron. Estranhamente ou n�o, alguns clientes est�o a restringir a utiliza��o do cron. Com sorte este n�o ser� o seu caso.
  2. Muitas vezes os scripts t�m mecanismos para enviar alarmes dentro deles. Se necessitar de mudar alguma coisa (endere�os de email, n�meros de telefone ou pagers) poder� ter de mudar v�rios scripts.
  3. Na maioria dos casos os scripts n�o t�m "mem�ria". Isto querer� dizer, por exemplo, que continuar�o a enviar alarmes sempre (enquanto o problema se mantiver). Em algumas situa��es isto pode ser in�til e irritante.
  4. Como os scripts n�o t�m "mem�ria" eles n�o ir�o "limpar" um alarme caso se verifique que o problema se resolveu.
  5. Em principio os scripts n�o enviam informa��o ao OAT. E o OAT � elegante e f�cil de utilizar.
  6. Tradicionalmente, diferentes dbspaces em diferentes inst�ncias ter�o valores de ocupa��o aceit�vel diferentes uns dos outros. Isto obriga a maior complexidade dos scripts para permitir a customiza��o.
Provavelmente conseguiria referir mais alguns problemas, mas os 6 acima dever�o ser suficientes. Assim, a minha proposta de valor � criar um mecanismo que resolva todos os problemas acima, mas que traga tamb�m algumas outras vantagens:
  • Possa ser utilizado como esqueleto para outras opera��es de monitoriza��o
  • Seja configur�vel exclusivamente dentro da pr�pria base de dados
Como referi anteriormente iremos necessitar de v�rios componentes:
  1. Um script de ALARPROGRAM completamente funcional
    J� dever� ter isto, mas ser�o necess�rias algumas altera��es (poucas linhas)
  2. Open Admin Tool a funcionar
  3. O scheduler da base de dados activo
  4. Um procedimento ou fun��o para chamar o script ALARMPROGRAM
    Li recentement um artigo do Andre Ford sobre como auto-estender os dbspaces. Nesse mesmo artigo tamb�m h� um exemplo de um procedimento para efectuar isto
Comecemos ent�o:

Altera��es no script ALARMPROGRAM


Dever� criar uma nova classe para o evento gerado por esta tarefa de monitoriza��o. Notei que o Andrew Ford indica a cria��o de duas classes (101 e 102 no exemplo dele), uma para enviar emails e outra para gerar SMS/paging, mas eu prefiro criar s� uma e deixar a decis�o de enviar email ou um pager/SMS baseada no outro par�metro do ALARMPROGRAM, a severidade.
Na verdade, eu habitualmente utilizo uma vers�o alterada do ALARMPROGRAM onde eu posso definir que todos os eventos com uma dada severidade enviam um SMS e abaixo disso apenas enviam um email, ou alternativamente definir um conjunto de classes que enviam sempre ou emails ou SMS conforme a gravidade.

Em qualquer caso, configure e teste o seu script de ALARMPROGRAM para receber uma nova classe e agir em conformidade com as suas necessidades. A vantagem de utilizar o script de ALARMPROGRAM � que isto faz com que este seja o �nico sit�o que ter� de mexer caso necessite de alterar algum email ou endere�o de paging ou n�mero de SMS. Uma vez configurado ir� trabalhar perfeitamente para si e ser� re-utiliz�vel para qualquer tarefa de monitoriza��o.

Open Admin Tool a funcionar

Como se ver� mais adiante esta tarefa ir� gerar alertas na consola do OAT. Assim ter� alguma coisa para mostrar � sua chefia. Habitualmente gostam de ver gr�ficos agrad�veis � vista.... Para al�m disso, e do ponto de vista pr�tico, o OAT facilitar� o agendamento e configura��o da tarefa (incluindo os seus par�metros). Falarei disto mais adiante, at� porque tenho uma queixa relativamente ao OAT :)


O scheduler da base de dados activo

Como j� foi referido, esta ferramenta de monitoriza��o ser� implementada como uma tarefa no scheduler da base de dados (introduzido na vers�o 11). Portanto isto � um requisito directo.

Um procedimento ou fun��o para chamar o script ALARMPROGRAM

Um dos requisitos, se queremos integrar a tarefa com o script de ALARMPROGRAM � ter um procedimento que possa chamar o referido script. Este procedimento ir� basicamente receber par�metros (semelhantes aos do ALARMPROGRAM), e construir um comando de sistema operativo que ser� depois executado com uma chamada � instru��o SYSTEM(). O caminho do ALARMPROGRAM ser� obtido dinamicamente na base de dados sysmaster. Desta forma n�o ter� de alterar o procedimento, caso necessite de alterar a localiza��o do script no sistema de ficheiros. O c�digo para este procedimento pode ser encontrado na Listagem 1) no final deste artigo. Este procedimento ir� ser chamado em v�rios pontos da nossa tarefa


A tarefa propriamente dita: Descri��o e instala��o

A tarefa de monitoriza��o � implementada como um procedimento em linguagem SPL. O c�digo da mesma pode ser obtido na listagem 2 no final deste artigo. Vamos analis�-lo quase linha a linha.


  • Linhas 1 e 2 s�o apenas as instru��es de DROP/CREATE. Repare-se que o procedimento recebe dois argumentos que s�o realmente uma grande ajuda, como veremos mais tarde:
    task_id � o id na tabela ph_task. � �nico para cada tareda e permite-nos referenciar outras tabelas na base de dados sysadmin que sustenta o scheduler e muitas funcionaliades do OAT
    v_id � o n�mero da execu��o desta tarefa. Ir� mudar (incrementalmente) cada vez que a tarefa � executada
  • As linhas seguintes, at� � 19 s�o defini��es de vari�veis. N�o as irei explicar isoladamente pois ser�o referidas nos coment�rios abaixo
  • Linhas 20 a 25 referem-se a instru�oes de debug. Remova os coment�rios das linhas 23 e 24 para obter um trace da execu��o do procedimento, criado em /tmp (a localiza��o pode obviamente ser mudada)
  • As linhas 29 a 31 s�o muito importantes. Os valores nelas definidos s�o o �ltimo recurso utilizado pelo procedimento se todos os outros par�metros de configura��o n�o forem definidos. Os valores aqui definidos por omiss�o s�o:
    default yellow threshold (90): Isto representa a percentagem de utiliza��o de um qualquer dbspace, acima do qual ser� emitido um alerta amarelo (severidade 3 no ALARMPROGRAM)
    default red threshold (95): Isto representa a percentagem de utiliza��o de um qualquer dbspace, acima do qual ser� emitido um alerta vermelho (severidade 4 no ALARMPROGRAM)
    number of alarms (3): Isto representa o n�mero de alarmes a enviar. Um valor de zero sinaliza que devem ser enviados alarmes at� que a situa��o seja resolvida

    Como veremos a seguir, estes valores podem ser sobrepostos por valores atribu�dos a par�metros de configura��o da tarefa, e os limites vermelho e amarelo podem ser definidos por dbspace.
    Os valores acima s� ser�o utilizados se os outros, mais espec�ficos n�o forem definidos. E claro que estes valores podem ser alterados no c�digo do procedimento antes de fazer a instala��o no seu ambiente, de forma a adapt�-los �s suas necessidades e prefer�ncias.
  • Linha 33 � muito importante dado que define a class passada ao ALARMPROGRAM referente a falta de espa�o livre num dbspace. Isto deve ser ajustado ao valor da classe adicionada ao ALARMPROGRAM. Eu utilizo valores na casa dos 900 para as minhas extens�es "pessoais", de forma a que n�o venham a sobrepor-se com classes presentes no ALARMPROGRAM, adicionadas pela IBM no futuro (n�o sabemos quantas poder�o ser adicionadas, mas come�ar nos 900 d� uma margem razo�vel)
  • Linhas 35 a 93. Aqui tentamos ler os valores configurados para os par�metros de funcionamento acima. Estes valores s�o items de configura��o das tarefas. Infelizmente a vers�o actual do OAT n�o permite configur�-los via interface gr�fica, ou melhor, n�o permite cri�-los. Teremos de os inserir usando SQL e depois ent�o podemos manipul�-los via OAT. Gostaria que o processo de cria��o das tarefas no OAT permitisse introduzir estes par�metros. Mas de momento (vers�o 2.28) isto n�o est� dispon�vel e portanto teremos de os inserir via SQL. Como o fazer? Estes valores s�o guardados na tabela ph_threshold que cont�m os seguintes campos:
    name: Este � o nome do par�metro. No nosso caso, temos os seguintes: DEFAULT NUM ALARMS, DBSPACE YELLOW DEFAULT, DBSPACE RED DEFAULT e depois podemos inserir qualquer um na forma DBSPACE YELLOW dbspace_name e DBSPACE RED dbspace_name. Penso que os nomes j� explicam o significado. A ideia � que se quisermos ter limites "amarelos" e "vermelhos" para dbspaces espec�ficos temos de inserir um par�metro com o nome DBSPACE RED/YELLOW dbspace_name na tabela ph_thresholds. Se n�o existir um valor espec�fico para um determinado dbspace o procedimento ir� usar o valor indicado pelo par�metro DBSPACE RED/YELLOW DEFAULT. Se estes tamb�m n�o estiverem definidos, ir� usar os valores definidos nas linhas 29 a 31
    task_name: O nome da tarefa na tabela ph_task. Este valor tem de se igual ao nome que dermos a esta tarefa, e esse ser� o que dermos na cria��o do agendamento para a mesma. Neste artigo usarei "IXMon Check Space". Pode usar o que desejar, desde que mantenha a coerencia
    value: O valor do limite. Este valor ser� usado pela tarefa. No nosso caso, os par�metros DBSPACE RED/YELLOW * ser�o representados em percentagem (1-100).
    value_type: O tipo de dados do limite (STRING ou NUMERIC). No nosso caso usaremos NUMERIC. Investigando um pouco foi poss�vel perceber que podemos usar NUMERIC(x,y) para valores fraccionados. N�o testei, mas dever� funcionar, caso isso fa�a sentido para as suas necessidades.
    description: Uma descri��o do que o limite controla. Isto ser� utilizado pela interface gr�fice do OAT, caso posteriormente queira editar os valores pelo OAT.

    Para dar alguns exemplos apresento de seguida as instru��es para criar os par�metros cuja defini��o tamb�m existe no c�digo (n�mero de alarmes, limites gen�ricos amarelo e vermelho). Usarei os mesmo valores:
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DEFAULT NUM ALARMS', 'IXMon Check Space', '3', 'NUMERIC', 'Numero de alarmes a enviar');
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DBSPACE YELLOW DEFAULT', 'IXMon Check Space', '90', 'NUMERIC', 'Limite amarelo generico. Sera aplicado a qualquer dbspace que nao tenha um parametro especifico');
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DBSPACE RED DEFAULT', 'IXMon Check Space', '95', 'NUMERIC', 'Limite vermelho generico. Sera aplicado a qualquer dbspace que nao tenha um parametro especifico');


    E por exemplo, se tiver um dbspace com o nome
    llogs_dbs, dedicato aos logical logs, que esteja practicamente cheio e que portanto n�o far� sentido monitorizar poderia adicionar:


    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DEFAULT YELLOW llogs_dbs', 'IXMon Check Space', '100', 'NUMERIC', 'Faz com que o llogs_dbs passe todos os teses...');
    INSERT INTO ph_threshold ( name, task_name, value, value_type, description)
    VALUES ( 'DEFAULT RED llogs_dbs', 'IXMon Check Space', '100', 'NUMERIC', 'Faz com que o llogs_dbs passe todos os teses...');


  • Linha 97 cria um ciclo FOREACH. � baseado na query das linhas seguintes a qual verifica o espa�o utilizado em cada dbspace do sistema.
  • Linhas 98 a 111. Esta � a query referida acima. Algumas partes dela podem n�o ser necess�rias para este efeito, mas foi retirada de outro script... N�o se preocupe, deve funcionar. D� o n�mero de p�ginas e o n�mero de p�ginas livres em todos os chunks do dbspace.
    Note que esta tarefa � baseada em percentagem de utiliza��o. Poderia ser melhorada para lidar com outros tipos de par�metros como os GB alocados, os GB livres etc. Por agora mantive-a simples.
  • Linhas 114 a 153 s�o usadas para tentar obter limites espec�ficos para o dbspace que est� a ser processado. Se n�o forem encontrados na tabela ph_threshold os limites gen�ricos ser�o utilizados
  • Linhas 154 a 172. Aqui calculamos a percentagem de espa�o utilizado e verificamos se excede o limite amarelo ou vermelho. Se tal acontecer inicializamos a vari�vel com a cor do alerta e a mensagem de alerta. Se estivermos abaixo do limite amarelo ent�o deixamos a vari�vel da cor a NULL
  • Linhas 175 a 200. Se a utiliza��o actual estiver abaixo do limite inferior (amarelo), procuramos um alerta j� inserido na tabela ph_alert para este dbspace com o state igual a "NEW". Se encontrarmos alteramo-lo, mudando o estado para "ADDRESSED". Isto pode acontecer se depois de um alerta algu�m apagar uma tabela por exemplo. Nesta situa��o n�o estou a chamar o ALARMPROGRAM, mas poderia fazer sentido cham�-lo com uma mensagem do tipo: "O alarme anterior para o dbspace dbspace_name foi cancelado porque estamos agora abaixo do limite definido"
  • Da 204 at� ao final, c�digo que trata as situa��es em que excedemos um dos limites.... Assim... Primeiro pesquisamos na ph_alert para ver se temos um alarme para este dbspace no estado "NEW". Se n�o tivermos (223 - 239) inserimo-lo e chamamos o ALARMPROGRAM usando o procedimento referido acima. Se j� tivermos um alarme verificamos se � da mesma cor. Se n�o for (244 - 252), fazemos um UPDATE a dois campos:
    alert_task_seq: Fazemos isto para reposicionar o contador do alarme.
    alert_color: Alteramos o c�digo de cor do alarm (para utiliza��o na interface do OAT). Note que nesta altura podemos ter um alarme vermelho, com um texto de mensagem referente a um amarelo. Preferi manter assim, para mostrar que houve uma altera��o entre a situa��o original e a actual. No entanto o alarme que � enviado ao ALARMPROGRAM tem a mensagem correspondente ao alarme vermelho. S� no OAT se ver� a diferen�a. Se o alarme tiver a mesma cor, verificamos o campo alert_task_seq e comparamo-lo com o n�sso n�mero de execu��o da tarefa (dado como par�metro na chamada do procedimento) e decidimos, baseado no n�mero de alarmes se devemos ou n�o chamar o ALARMPROGRAM.
Finalmente, como � que agendamos a tarefa? Podemos faz�-lo via interface do OAT. ou se preferir podemos inserir directamente o registo na tabela ph_task:



INSERT INTO ph_task
(
tk_id, tk_name, tk_description, tk_type, tk_dbs,
tk_execute, tk_start_time, tk_frequency,
k_monday, tk_tuesday, tk_wednesday, tk_thursday,
tk_friday, tk_saturday, tk_sunday,
tk_group, tk_enable, tk_priority
)
VALUES
(
0, 'IXMon Check Space', 'Check dbspace free space', 'TASK', 'sysadmin',
'ixmon_check_space', '00:00:00', '0 00:30:00',
't', 't', 't', 't', 't', 't', 't',
'USER','t',0
)



Atualiza��o [ 20 Ago 2010]:

Tinha-me esquecido de um bloco condicional (IF) em volta do UPDATE que altera o estado de um alerta j� existente para 'ADDRESSED' (linhas 195-200)
Como estava, o UPDATE era sempre feito mesmo quando n�o tinhamos encontrado um alerta. Isto n�o seria um erro grave, mas caso tamb�m queira chamar
o ALARMPROGRAM quando as condi��es do alarme s�o reveridas ent�o necessitamos deste ID, ou a tarefa ir� enviar alarme para cada dbspace que esteja dentro dos limites
Pe�o desculpa pela confus�o.... Portanto adicionei o IF da linha 194 e o END IF da linha 201.




Listing 1:



DROP PROCEDURE call_alarmprogram;
CREATE PROCEDURE call_alarmprogram(
v_severity smallint,
v_class smallint,
v_class_msg varchar(255) ,
v_specific varchar(255) ,
v_see_also varchar(255)
)


-- severity: Category of event
-- class-id: Class identifier
-- class-msg: string containing text of message
-- specific-msg: string containing specific information
-- see-also: path to a see-also file

DEFINE v_command CHAR(2000);
DEFINE v_alarmprogram VARCHAR(255);

--SET DEBUG FILE TO '/tmp/call_alarmprogram.dbg' WITH APPEND;
--TRACE ON;

SELECT
cf_effective
INTO
v_alarmprogram
FROM
sysmaster:sysconfig
WHERE
cf_name = "ALARMPROGRAM";

LET v_command = TRIM(v_alarmprogram) || " " || v_severity || " " || v_class || " '" || v_class_msg || "' '" || NVL(v_specific,v_class_msg) || "' '" || NVL(v_see_also,' ') || "'";
SYSTEM v_command;
END PROCEDURE;


Listing 2:



1 DROP FUNCTION ixmon_check_space;
2 CREATE FUNCTION "informix".ixmon_check_space(task_id INTEGER, v_id INTEGER) RETURNING INTEGER
3
4 DEFINE v_default_num_alarms, v_num_alarms SMALLINT;
5 DEFINE v_default_yellow_threshold, v_default_red_threshold SMALLINT;
6 DEFINE v_generic_yellow_threshold, v_generic_red_threshold SMALLINT;
7 DEFINE v_dbs_yellow_threshold, v_dbs_red_threshold SMALLINT;
8 DEFINE v_name LIKE ph_threshold.name;
9 DEFINE v_dbsnum INTEGER;
10 DEFINE v_dbs_name CHAR(128);
11 DEFINE v_pagesize, v_is_blobspace, v_is_sbspace, v_is_temp SMALLINT;
12 DEFINE v_size, v_free BIGINT;
13 DEFINE v_used DECIMAL(4,2);
14 DEFINE v_alert_id LIKE ph_alert.id;
15 DEFINE v_alert_task_seq LIKE ph_alert.alert_task_seq;
16 DEFINE v_alert_color,v_current_alert_color CHAR(6);
17 DEFINE v_message VARCHAR(254,0);
18
19 DEFINE v_severity, v_class SMALLINT;
20 ---------------------------------------------------------------------------
21 -- Uncomment to activate debug
22 ---------------------------------------------------------------------------
23 --SET DEBUG FILE TO '/tmp/ixmon_check_space.dbg' WITH APPEND;
24 --TRACE ON;
25
26 ---------------------------------------------------------------------------
27 -- Default values if nothing is configured in ph_threshold table
28 ---------------------------------------------------------------------------
29 LET v_default_yellow_threshold=90;
30 LET v_default_red_threshold=95;
31 LET v_default_num_alarms=3;
32
33 LET v_class = 908;
34
35 ---------------------------------------------------------------------------
36 -- Get the number of times to call the alarm...
37 ---------------------------------------------------------------------------
38
39 LET v_num_alarms=NULL;
40
41 SELECT
42 value
43 INTO
44 v_num_alarms
45 FROM
46 ph_threshold
47 WHERE
48 task_name = 'IXMon Check Space' AND
49 name = 'DEFAULT NUM ALARMS';
50
51 IF v_num_alarms IS NULL
52 THEN
53 LET v_num_alarms=v_default_num_alarms;
54 END IF;
55
56 ---------------------------------------------------------------------------
57 -- Get the defaults configured in the ph_threshold table
58 ---------------------------------------------------------------------------
59 LET v_generic_yellow_threshold=NULL;
60 LET v_generic_red_threshold=NULL;
61
62 SELECT
63 value
64 INTO
65 v_generic_yellow_threshold
66 FROM
67 ph_threshold
68 WHERE
69 task_name = 'IXMon Check Space' AND
70 name = 'DBSPACE YELLOW DEFAULT';
71
72 IF v_generic_yellow_threshold IS NULL
73 THEN
74 LET v_generic_yellow_threshold=v_default_yellow_threshold;
75 END IF;
76
77
78
79 SELECT
80 value
81 INTO
82 v_generic_red_threshold
83 FROM
84 ph_threshold
85 WHERE
86 task_name = 'IXMon Check Space' AND
87 name = 'DBSPACE RED DEFAULT';
88
89 IF v_generic_red_threshold IS NULL
90 THEN
91 LET v_generic_red_threshold=v_default_red_threshold;
92 END IF;
93
94 ---------------------------------------------------------------------------
95 -- Foreach dbspace....
96 ---------------------------------------------------------------------------
97 FOREACH
98 SELECT
99 d.dbsnum, d.name, d.pagesize, d.is_blobspace, d.is_sbspace, d.is_temp,
100 SUM(c.chksize), SUM(c.nfree)
101 INTO
102 v_dbsnum, v_dbs_name, v_pagesize, v_is_blobspace, v_is_sbspace, v_is_temp,
103 v_size, v_free
104 FROM
105 sysmaster:sysdbspaces d, sysmaster:syschunks c
106 WHERE
107 d.dbsnum = c.dbsnum
108
109
110 GROUP BY 1, 2, 3, 4, 5, 6
111 ORDER BY 1
112
113
114 ---------------------------------------------------------------------------
115 -- Get specific dbspace red threshold if available....
116 ---------------------------------------------------------------------------
117 LET v_name = 'DBSPACE RED ' || TRIM(v_dbs_name);
118
119 SELECT
120 value
121 INTO
122 v_dbs_red_threshold
123 FROM
124 ph_threshold
125 WHERE
126 task_name = 'IXMon Check Space' AND
127 name = v_name;
128
129 IF v_dbs_red_threshold IS NULL
130 THEN
131 LET v_dbs_red_threshold = v_generic_red_threshold;
132 END IF;
133
134 ---------------------------------------------------------------------------
135 -- Get specific dbspace yellow threshold if available....
136 ---------------------------------------------------------------------------
137 LET v_name = 'DBSPACE YELLOW ' || TRIM(v_dbs_name);
138
139 SELECT
140 value
141 INTO
142 v_dbs_yellow_threshold
143 FROM
144 ph_threshold
145 WHERE
146 task_name = 'IXMon Check Space' AND
147 name = v_name;
148
149 IF v_dbs_yellow_threshold IS NULL
150 THEN
151 LET v_dbs_yellow_threshold = v_generic_yellow_threshold;
152 END IF;
153
154 ---------------------------------------------------------------------------
155 -- Calculate used percentage and act accordingly...
156 ---------------------------------------------------------------------------
157 LET v_used = ROUND( ((v_size - v_free) / v_size) * 100,2);
158 IF v_used > v_dbs_red_threshold
159 THEN
160 LET v_alert_color = 'RED';
161 LET v_message ='DBSPACE ' || TRIM(v_dbs_name) || ' exceed the RED threshold (' ||v_dbs_red_threshold||'). Currently using ' || v_used ;
162 LET v_severity = 4;
163 ELSE
164 IF v_used > v_dbs_yellow_threshold
165 THEN
166 LET v_alert_color = 'YELLOW';
167 LET v_message ='DBSPACE ' || TRIM(v_dbs_name) || ' exceed the YELLOW threshold (' ||v_dbs_yellow_threshold||'). Currently using ' || v_used ;
168 LET v_severity = 3;
169 ELSE
170 LET v_alert_color = NULL;
171 END IF
172 END IF
173
174
175 IF v_alert_color IS NULL
176 THEN
177 ---------------------------------------------------------------------------
178 -- The used space is lower than any of the thresholds...
179 -- check to see if there is an already inserted alarm
180 -- If so... clear it...
181 ---------------------------------------------------------------------------
182 LET v_alert_id = NULL;
183
184 SELECT
185 p.id, p.alert_task_seq, p.alert_color
186 INTO
187 v_alert_id, v_alert_task_seq, v_current_alert_color
188 FROM
189 ph_alert p
190 WHERE
191 p.alert_task_id = task_id
192 AND p.alert_object_name = v_dbs_name
193 AND p.alert_state = "NEW";
194 IF v_alert_id IS NOT NULL
195 UPDATE
196 ph_alert
197 SET
198 alert_state = 'ADDRESSED'
199 WHERE
200 ph_alert.id = v_alert_id;
201 END IF;
202 ELSE
203
204 ---------------------------------------------------------------------------
205 -- The used space is bigger than one of the thresholds...
206 -- Check to see if we already have an alert in the ph_alert table in the
207 -- state NEW ...
208 ---------------------------------------------------------------------------
209
210 LET v_alert_id = NULL;
211
212 SELECT
213 p.id, p.alert_task_seq, p.alert_color
214 INTO
215 v_alert_id, v_alert_task_seq, v_current_alert_color
216 FROM
217 ph_alert p
218 WHERE
219 p.alert_task_id = task_id
220 AND p.alert_object_name = v_dbs_name
221 AND p.alert_state = "NEW";
222
223 IF v_alert_id IS NULL
224 THEN
225 ---------------------------------------------------------------------------
226 -- There is no alarm... or the alarm changed from NEW
227 ---------------------------------------------------------------------------
228
229 INSERT INTO
230 ph_alert (id, alert_task_id, alert_task_seq, alert_type, alert_color, alert_time,
231 alert_state, alert_state_changed, alert_object_type, alert_object_name, alert_message,
232 alert_action_dbs)
233 VALUES(
234 0, task_id, v_id, 'WARNING', v_alert_color, CURRENT YEAR TO SECOND,
235 'NEW', CURRENT YEAR TO SECOND,'DBSPACE', v_dbs_name, v_message, 'sysadmin');
236
237 EXECUTE PROCEDURE call_alarmprogram(v_severity, v_class, 'DBSPACE used space too high',v_message,NULL);
238
239 ELSE
240 ---------------------------------------------------------------------------
241 -- There is an alarm...
242 -- Need to check if it's still the same color...
243 ---------------------------------------------------------------------------
244 IF v_current_alert_color != v_alert_color
245 THEN
246 ---------------------------------------------------------------------------
247 -- Change the color... And reset the seq to reactivate the couter...
248 ---------------------------------------------------------------------------
249 UPDATE ph_alert
250 SET (alert_task_seq, alert_color) = (v_id,v_alert_color)
251 WHERE ph_alert.id = v_alert_id;
252 EXECUTE PROCEDURE call_alarmprogram(v_severity, v_class, 'DBSPACE used space too high',v_message,NULL);
253 ELSE
254 IF (v_id < v_alert_task_seq + v_num_alarms) OR v_num_alarms = 0
255 THEN
256 EXECUTE PROCEDURE call_alarmprogram(v_severity, v_class, 'DBSPACE used space too high',v_message,NULL);
257 END IF;
258 END IF;
259 END IF;
260 END IF;
261 END FOREACH
262
263 END FUNCTION;