Banco de Dados

12 jun, 2013

Scripts e tabelas de catálogo 02: tabelas e tablespaces no DB2

Publicidade

Continuando o assunto das tabelas de catálogo que tratei no artigo anterior, hoje vou mostrar outro exemplo de uso.

Faz algum tempo que eu estava trabalhando com um banco de dados que cresceu muito rapidamente e passou a apresentar problemas de performance. Eu estava estudando o problema, e a primeira coisa que decidi checar foi quais tablespaces eram usados para cada tabela do banco.

Existe um mau hábito entre os DBAs de DB2 em ambiente UNIX de usar um ou no máximo alguns tablespaces compartilhados entre todas as tabelas do banco. Outro problema é usar um único bufferpool para esses poucos tablespaces.

Eu queria verificar se eram essas as razões do problema de performance e eu precisava de um método fácil e rápido de fazer essa checagem nas centenas de tabelas existentes.

Foi então que tive a ideia de usar as tabelas de catálogo para buscar essas informações. Na realidade, meu problema seria resolvido usando 3 catálogos:

  • SYSCAT.TABLES
  • SYSCAT.TABLESPACES
  • SYSCAT.BUFFERPOOLS

Eu criei duas consultas para buscar os dados que precisava. Eu mostro aqui os resultados executados na base SAMPLE, que é base de exemplo para o DB2.

A primeira consulta informa quantas tabelas de usuário estão vinculadas a cada um dos tablespaces. Essa consulta nos dá uma ideia superficial de possíveis gargalos para acesso a disco (os containers) e memória (os bufferpools).

SELECT  TS.TBSPACE, COUNT(*)

            FROM SYSCAT.TABLES T

               INNER JOIN SYSCAT.TABLESPACES TS  ON  T.TBSPACEID = TS.TBSPACEID

WHERE T.TABSCHEMA NOT LIKE 'SYS%'

GROUP BY TS.TBSPACE ;

TBSPACE                                          NUM_TAB    

---------------------------------------------+-----------------------

IBMDB2SAMPLEREL                             4

IBMDB2SAMPLEXML                            7

USERSPACE1                                       15

3 record(s) selected.

Essa consulta traz uma informação interessante sobre I/O. Os tablespaces do DB2, por default, têm gerenciamento automático da alocação de disco. Essa área alocada é chamada de container e, assim, normalmente temos apenas 1 container por tablespace. Portanto, se tivermos várias tabelas usando um único tablespace, todas elas estarão acessando o mesmo container durante a execução das operações de SELECT, INSERT, UPDATE ou DELETE. E evidentemente isso é um gargalo em matéria de acesso a disco e com certeza pode causar problemas de performance.

Por outro lado, pode haver também gargalos no acesso à memória da máquina. Para estudar esse problema, eu criei outra consulta, que informa quantas tabelas e tablespaces estão associados a cada bufferpool. Essa consulta é mostrada a seguir:

SELECT

     B.BPNAME,

     COUNT(DISTINCT T.TBSPACEID) AS NUM_TS,

     COUNT(T.TABNAME) AS NUM_TAB

FROM SYSCAT.BUFFERPOOLS B

     INNER JOIN SYSCAT.TABLESPACES TS

     ON TS. BUFFERPOOLID = B. BUFFERPOOLID

     INNER JOIN SYSCAT.TABLES T

     ON T.TBSPACEID = TS.TBSPACEID

WHERE T.TABSCHEMA NOT LIKE 'SYS%'

GROUP BY B.BPNAME ;

BPNAME                                           NUM_TS      NUM_TAB    

 ----------------------------------------------------------------------------------------

IBMDEFAULTBP                                     4                   50

1 record(s) selected.

Essa consulta mostra que todas as tabelas de todos os tablespaces desse banco usam exatamente o mesmo bufferpool, ou seja, a mesma alocação de memória. Isso obviamente é um gargalo sério num banco de dados que trabalhe com um volume de dados considerável ou mesmo um que tenha um grande número de acessos concorrentes.

O leitor mais observador perceberá que uma solução mais abrangente para o problema de performance teria que considerar não apenas a quantidade de tabelas que usam o mesmo tablespace e/ou mesmo bufferpool, mas também a quantidade de registros em cada uma dessas tabelas e os tipos de operações mais executados com esses dados.

Os tipos de operações mais comuns estão relacionados ao tipo de sistema envolvido. Um sistema transacional certamente envolverá muitas operações de INSERT e talvez muitos UPDATEs e DELETEs também. Já um sistema analítico (um BI, por exemplo) certamente terá muitas operações de SELECT (sendo que as cargas de dados serão executadas enquanto o banco estiver fora do ar).

A informação sobre número de registros é obtida com a consulta que eu mostrei no artigo anterior. Mas eu deixa a cargo do leitor criar o script combinando as duas consultas.

Não é objetivo deste texto discutir técnicas de avaliação de performance, e sim mostrar o uso das tabelas de sistemas para obter informações importantes da estrutura do banco. Obviamente, este exemplo mais uma vez usa as tabelas de catálogo do DB2, mas naturalmente podemos usar esta abordagem em praticamente qualquer SGBD.

No próximo artigo, mostrarei exemplos usando as tabelas de sistema do SQL SERVER. Até lá!