PK atingiu valor máximo, e agora?

Esses dias aconteceu algo que jamais pensei que aconteceria: A PK auto incrementável de uma tabela atingiu o valor máximo pelo tipo de dado. Quando trabalhamos com coisas legadas, é praticamente inevitável passar por alguns percalços, e o melhor é que quando acontece alguma coisa na maioria das vezes é tratada de maneira reativa e não preventiva principalmente quando o legado é um "monstro", ou seja, a passagem dele para algo monitorado, auditado e validado é demorada.

O que aconteceu foi o seguinte, a PK foi configurada como SMALLINT, o que permite até 2 bytes ou 2^16 quando UNSIGNED (só valores positivos), em outras palavras até 65.535 registros (o zero entra no jogo também). Após o aviso de que uma determinada feature não funcionava, o TSHOOT inicial não deixou dúvidas, não era possível inserir mais registros pois a PK tinha atingido o valor máximo.

Existem alguns jeitos de resolver e um deles é criar uma tabela com todo o conteúdo da problemática e configurá-la corretamente, porém para funcionar da maneira mais simples possível existe um requisito fundamental que é não existir FK da PK problemática em outra tabela, adivinha... Esse dia a sorte estava generosa!

Estratégia adotada com tipo de dado INT:

-- 1 - Criar/copiar tabela problemática:
CREATE TABLE TABELA_NOVA SELECT * FROM TABELA_PRODUCAO;
-- 2 - Obter último valor da PK, nosso caso 65535
SELECT PK_ABUDEGA FROM TABELA_PRODUCAO ORDER BY PK_ABUDEGA DESC;
-- 3 - Adicionar constraints necessárias e obviamente da PK também
ALTER TABLE TABELA_NOVA ADD PRIMARY KEY (PK_ABUDEGA);
ALTER TABLE TABELA_NOVA CHANGE PK_ABUDEGA PK_AJUSTADA INT(11) UNSIGNED NOT NULL AUTO_INCREMENT;
ALTER TABLE TABELA_NOVA ADD FOREIGN KEY (TABELA_RELACIONADA_ID) REFERENCES TABELA_RELACIONADA(ID);
-- 4 - O valor do passo 3 mais 1
ALTER TABLE TABELA_NOVA AUTO_INCREMENT = 65536;
-- 5 - Renomear tabela problemática para qualquer outra coisa
RENAME TABLE TABELA_PRODUCAO TO TABELA_PRODUCAO_OLD;
RENAME TABLE TABELA_NOVA TO TABELA_PRODUCAO;
Calma que isso só resolve o lado do banco de dados, e se de repente no lado da aplicação a classe mapeada tiver o atributo da PK com short em vez de integer? Nada é tão ruim que não possa ficar pior. Dia de aventuras, novos conhecimentos, desafios nefastos e lições aprendidas.

Ao som de Joe Satriani - Made of Tears.

Comentários