Biblioteca

Criação concorrente de índices no Firebird 5

Atualmente, quando um índice está sendo construído, qualquer modificação nos dados da tabela não é permitida. Isso é necessário para criar um índice correto, sem perder chaves inseridas durante a construção.

O algoritmo de construção concorrente de índices permite reduzir significativamente o tempo em que esse bloqueio de leitura é necessário. Embora não elimine completamente 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 concorrente de índices 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 concorrente de índices.

Criar novo índice

CREATE [UNIQUE] [ASC[ENDING] | DESC[ENDING]]  INDEX indexname ON tablename  {(col [, col ...]) | COMPUTED BY (<expression>)}  [WHERE <search_condition>]  [CONCURRENTLY]

Ativar índice existente

ALTER INDEX indexname {ACTIVE | INACTIVE}  [CONCURRENTLY]

Observe que CONCURRENTLY só pode ser usado com ACTIVE.

Validação de unicidade

É difícil, quase impossível, verificar a unicidade do índice enquanto ele é construído de forma concorrente. Por isso, 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 construção do índice ser concluída, quando o índice já contém as chaves de 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 localizar e corrigir as duplicatas e validar a unicidade novamente, ou remover 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

Esse comando 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, quando presente.

Constraints de tabela

A criação concorrente de índices para constraints de tabela, como PRIMARY|UNIQUE|FOREIGN KEY, ainda não é suportada. É possível que o suporte a PRIMARY|UNIQUE KEY seja adicionado 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 o í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)

Download HQbird and try it now: https://ib-aid.com/en/download-hqbird