Semana passada um colega passou por uma situação interessante: perdeu o controle de uma coluna auto incrementável de suma importância, que culminou com a interrupção de um serviço on-line importante. Ora, faz parte do papel do DBA manter os dados sob rédea curta, sob controle, mesmo que às vezes eles se comportem como um cavalo doido, e, tente se comportar à margem das Leis de Murphy, Moore, dentre tantas outras.

Fazer colunas maiores do que, realmente, elas precisam ser é um grande desperdício de recurso. Principalmente, no MySQL, onde temos uma grande variedade de tipos de dados (data types).

Colunas menores ocupam menos espaço em disco, em memória, e, acima de tudo geram menos I/O. Na verdade, a diminuição de I/O é a nossa maior e legitima preocupação, quando entra em pauta o assunto “data types”.

Todo mundo tem uma coluna “id” para chamar de  “sua“. Pelo menos, se, minimamente, utiliza-se alguma das formas normais. Sem teorizar muito: toda tabela deveria ter uma coluna que identifica-se (id) uma linha de forma indelével (é, não faz parte do meu tradicional repertório, é efeito do filme Amour). Em outras palavras, é uma coluna que garante singularidade máxima a uma linha, candidatíssima a chave primária, de valor único e inconfundível! Uma maneira de o MySQL prover uma chave destas, é através do uso de AUTO INCREMENT e PRIMARY KEY.

Exemplo simples de criação de uma tabela com uma coluna “id” auto incrementável:

CREATE TABLE clientes ( cliente_id smallint not null auto_increment primary key, cliente_nome varchar(30) not null) engine=innodb;

Então, automaticamente, toda vez que criarmos uma nova linha (novo registro) na tabela clientes, o MySQL irá criar um novo número sequencial para este cliente. Para tanto, basta mover NULL para cliente_id, ou, simplesmente, não passar-lhe valor algum no comando INSERT.

O Problema!

Para quem não fugiu da escola :-), sabe que a tabela cliente não terá mais do que 32.767 clientes, pois, este é o valor máximo suportado por uma coluna smallint (signed, ufff, escrevi isso…).

O que acontece quando tentarmos incluir o 32.768? Erro, isto é o que acontece. Estouramos a capacidade (range) máximo daquela coluna. Numa aplicação on-line rodando 24 horas por dia, 7 dias por semana, isto seria fatal. Teríamos uma parada de determinado serviço e/ou aplicação.

Solução à Moda da Casa

Simples, é só fazer a coluna bigint unsigned, assim, esta tabela poderia ter 18.446.744.073.709.551.615!!! Bonzinho, né? Nãooooo! Agora, ao invés de usar uma coluna otimizada de apenas 2 bytes, estaríamos usando uma coluna de 8 bytes, e, para quê? Para evitar que o DBA tenha que conhecer o seu banco de dados, e, gerar um alto I/O?

Esta solução pode atender à maioria das pessoas, mas, não está certo!

Solução Racional

Primeiramente, o que sempre digo: “O sucesso e o fracasso de um aplicação começa a ser determinado no levantamento dos requisitos, determinação das entidades e propriedades, e, passando, necessariamente, pela modelagem da base de dados”. Titio, já disse isso várias vezes!

Controle, Monitore, Gerencie sua base de dados. Crie as colunas o mais racionais possíveis, e, principalmente, no caso das colunas auto incrementáveis, controlem o crescimento das tabelas e, consequente, evolução das mesmas.

Okay, o MySQL não provê algo para fazer isso de forma “pain less”. Voce pede, o titio faz.

Pensando nisso, criei um aplicativo, simples, rápido, mas, eficiente: alemaxai.

O alemaxai vai vasculhar todo uma instância do MySQL, procurar por todas as tabelas que contenham colunas auto incrementáveis, verificar o tipo de dados destas colunas, e, através de uma margem de segurança determinada pelo usuário, irá mostrar na tela (ou enviar email) com as tabelas que tenham colunas auto incrementáveis com valores acima da margem de segurança.

O uso é muito simples:

1. Crie um arquivo de configuração com extensão alemaxai (adicionei um modelo de arquivo para download). Neste arquivo contém: host, porta, usuário, senha para conexão, e, email para enviar as mensagens

2. Execute o alemaxai passando o path do arquivo de configuração

Exemplo de uso:

shell> /opt/mysql/alemaxai jobs            (nota: jobs é o arquivo jobs.alemaxai que está em /opt/mysql)

+——————————————————-+
| alemaxai v1.0 – by Alexandre Almeida (alepilot) |
+——————————————————-+

Browsing for tables with misbehavior…

—————————————————————————————–
Databases Tables Max ID Data Type
—————————————————————————————–
cphulkd ale 125 tinyint
cphulkd ale1 126 tinyint

Visit my blog: http://www.alexandremalmeida.com.br

Simples assim!

Baixe o programa, use sem moderação, controle suas colunas auto incrementáveis. Evite fazer colunas maiores do que elas, realmente, precisam ser, mas, mantenha-as sob controle.