[firebase-br] Monitoramento de queries no FB2.1
Marcelo Carvalho
mc em arquivo.com.br
Qui Nov 8 04:41:04 -03 2007
Olá,
Estava testando o monitoramento de queries em execução do FB 2.1. É muito
legal, e permite ver as queries de cada conexão no BD (independente da
aplicação), apenas monitorando a tabela MON$STATEMENTS e o campo
MON$SQL_TEXT.
Mas durante o teste percebi que o campo MON$STATE , que indica o estado
da query em execução, permanece em 1 enquanto o cursor da tabela não chega
ao fim, ou seja, enquanto todos os dados do Select não foram obtidos,
independente daquela query estar requerendo processamento ou não. A query
(statement) só é considerada concluída quando todos os dados são lidos.
Isso pode ser útil se quisermos saber quem está com tabelas abertas,
navegando nos registros, pois esses usuários podem consumir recursos. Mas
impede que possamos monitorar quem está realmente consumindo processamento
em um dado momento, e possivelmente "travando" o servidor.
Por exemplo: Um usuário ao efetuar um select consome alguns recursos
durante a busca. A tabela MON$STATEMENTS marca essa query como ativa
(MON$STATE) e registra o momento em que começou seu processamento
(MON$TIMESTAMP). Quando os dados são obtidos e exibidos (em um Grid, por
exemplo), esse usuário pára de consumir recursos do processador do
servidor - mas fica ainda como ativo em MON$STATEMENTS - até ele chegar ao
fim do result set, ou fechar a tabela ou a transação. Se nesse meio tempo
nós fizermos um monitoramento, vai parecer que esse usuário está gerando
processamento, e consumindo recursos, enquanto na verdade sua query pode ter
se comportado muito bem. Se ele deixar a tabela aberta e sair para almoçar,
por exemplo, vai ficar parecendo que sua query está sendo processada há um
tempão (pois MON$TIMESTAMP se mantém indicando o momento em que ele iniciou
a query), ainda que ele não esteja consumindo absolutamente nada do
processador.
Desta forma não temos como saber realmente QUEM está consumindo recursos
de processamento - apenas quem tem statements abertos (ainda que parados). E
o que eu vejo como um dos grandes objetivos do monitoramento é justamente
saber quem está "travando o servidor"!
Então pergunto: tem como sabermos que queries estão realmente sendo
processadas em um dado momento? Há algum parâmetro nas tabelas de
monitoramento que possa indicar ou se uma query (em MON$STATEMENTS) está
sendo processada (e há quanto tempo), ou se está apenas em "stand-by"?
O ideal seria que houvesse um campo como MON$STATE que indicasse quem
está realmente em processamento, e que houvesse um outro MON$TIMESTAMP que
indicasse quando esse processamento começou - assim saberíamos realmente se
há em um dado momento alguma tarefa no servidor que está consumindo
processamento, há quanto tempo, e quem é...
Ou seja, que se pudesse identificar o processamento efetivo da query, o
tempo de inatividade (tabela aberta, ponteiro parado) e processamento gerado
por fetch de dados (pesquisa concluída, mas cursor em movimento trazendo
dados). [além de identificarmos queries demoradas, também seria bom poder
monitorar se há gargalos por aplicações que retornam dados demais ainda que
com queries rápidas - o cara que faz um select * sem where e clica em "last"
e traz a base toda...]
Falando nisso, não consegui "derrubar" uma consulta. Em uma das palestras
da Conferência Internacional um dos slides sugeria que isso poderia ser
feito usando Delete na tabela MON$STATEMENTS. Tentei derrubar pelo
MON$STATEMENT_ID, e até pelo MON$ATTACHMENT_ID, mas nada aconteceu - é como
se a tabela fosse read-only. Também tentei "deletar" uma transação
(MON$TRANSACTIONS) e também uma conexão (MON$ATTACHMENTS), e não funcionou.
Apenas neste último caso houve uma exceção "operation not supported" - nos
outros testes foi como se o "delete" tivesse sido ignorado.
Há outro procedimento para derrubar uma conexão, transação ou query? Será
que isso ainda vai ser implementado até o FB 2.1 final?
--
[][][][]
Marcelo Carvalho.
PS: Uma coisa legal que "descobri": apesar da tabela MON$ATTACHMENTS já dar
o IP e o aplicativo que está conectado, você pode obter mais dados do
usuário pela query, para identificá-lo ao monitorar a base de dados. Basta
colocar esses dados (ex: nome do usuário logado, departamento, computador,
hora de acesso, rotina sendo executada, etc) em um /*comentário*/ dentro da
query!
Mais detalhes sobre a lista de discussão lista