Criação concorrente de índices no Firebird 5
Atualmente, quando um índice é construído, qualquer modificação nos dados da tabela não é permitida. Isso é necessário para criar um índice correto, sem perder novas chaves inseridas durante a construção.
O algoritmo de construção de índice concorrente permite reduzir significativamente o tempo em que esse bloqueio de leitura é necessário. Embora não elimine totalmente a necessidade de bloquear modificações concorrentes nos dados da tabela, o tempo desse bloqueio é muito menor em comparação com o algoritmo tradicional não concorrente. Isso é especialmente útil em ambientes de produção, onde bloquear a atividade dos usuários por longos períodos é impraticável ou impossível.
Devido à carga concorrente e à complexidade adicional, a criação de índice concorrente pode levar mais tempo do que a abordagem tradicional.
Sintaxe
A nova palavra-chave opcional não reservada CONCURRENTLY é usada para especificar a criação de índice concorrente.
Criar novo índice
CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]] INDEX indexname ON tablename {(col [, col ...]) | COMPUTED BY ()} [WHERE ] [CONCURRENTLY]
Ativar índice existente
ALTER INDEX indexname {ACTIVE | INACTIVE} [CONCURRENTLY]
Observe que CONCURRENTLY pode ser usado apenas com ACTIVE.
Validação de unicidade
É difícil ou impossível verificar a unicidade do índice enquanto ele é construído de forma concorrente. Portanto, quando um índice único é criado (ou ativado) de forma concorrente, ele é imediatamente marcado como NOT VALIDATED no catálogo do sistema. A unicidade do índice é validada após a conclusão da construção do índice, quando o índice contém chaves para todos os registros da tabela.
Se a verificação de unicidade for bem-sucedida, a marca NOT VALIDATED é removida.
Se a verificação de unicidade falhar, o índice permanece ativo e marcado como NOT VALIDATED. Posteriormente, o usuário pode encontrar e corrigir duplicatas e validar a unicidade novamente, ou descartar o índice, se apropriado.
Observe que um índice único NOT VALIDATED ainda não permite a inserção de duplicatas na tabela.
Para validar um índice único, execute
ALTER INDEX indexname VALIDATE UNIQUE
Esta instrução realiza uma varredura no índice para encontrar chaves duplicadas e verificar os registros correspondentes. Se nenhuma duplicata for encontrada, a marca NOT VALIDATED é removida e o índice é considerado validado. Caso contrário, a marca NOT VALIDATED permanece e o índice pode ser validado novamente mais tarde.
O comando SHOW INDEX do isql agora exibe a marca NOT VALIDATED, se presente.
Restrições de tabela
A criação concorrente de índices para restrições de tabela, como PRIMARY|UNIQUE|FOREIGN KEY, ainda não é suportada. É possível suportar PRIMARY|UNIQUE KEY no futuro, mas é improvável para FOREIGN KEY.
Exemplos
Prepare uma tabela com alguns dados
create table tab ( id int not null, f1 varchar(64));
insert into tab values (1, '1');
insert into tab values (1, '2');commit;
crie um índice usando a cláusula CONCURRENTLY
create index idx_tab_f1 on tab(f1) concurrently;
crie um índice único em uma coluna com duplicatas
create unique index idx_tab_id on tab(id);
isso gera um erro:
Statement failed, SQLSTATE = 23000
attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
crie o mesmo índice único usando CONCURRENTLY
create unique index idx_tab_id on tab(id) concurrently;
isso gera um aviso:
Validation of unique index "IDX_TAB_ID" failed.
-attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
verifique se o índice existe:
show index idx_tab_id;
IDX_TAB_ID UNIQUE NOT VALIDATED INDEX ON (ID)
observe a marca NOT VALIDATED.
Valide o índice:
alter index idx_tab_id validate unique;
Statement failed, SQLSTATE = 23000
unsuccessful metadata update-Validation of unique index "IDX_TAB_ID" failed.
-attempt to store duplicate value (visible to active transactions) in unique index "IDX_TAB_ID"
-Problematic key value is ("ID" = 1)
Corrija o registro duplicado e valide novamente
update tab set id = 2 where f1 = '2';
commit;
alter index idx_tab_id validate unique;
sem erros.
Verifique o estado do índice:
show index idx_tab_id;
IDX_TAB_ID UNIQUE INDEX ON (ID)
Baixe o HQbird e experimente agora: /br/download-hqbird