Sintaxe INSERT DELAYED
A opção DELAYED
para a instrução INSERT
é um opção específica do MariaDB que é muito útil se você tiver clientes que não possam esperar que o INSERT
se complete. Este é um problema comum quando você utiliza o MariaDB para fazer log e você também execute periodicamente instruções SELECT
e UPDATE
que levem muito tempo para completar. DELAYED
foi intriduzido no MariaDB versão 3.22.15. Ela é uma extensão do MariaDB ao SQL-92.
INSERT DELAYED
só funciona com tabelas ISAM
e MyISAM
. Note que como tabelas MyISAM
suportam SELECT
e INSERT
concorrentes, se não houver blocos livres no meio do arquivo de dados, você raramente precisará utilizar INSERT DELAYED
com MyISAM
. Leia "Tabelas MyISAM
".
Quando você utiliza INSERT DELAYED
, o cliente irá obter um OK de uma vez e a linha será inserida quando a tabela não estiver sendo usada por outra thread.
Outro grande benefício do uso de INSERT DELAYED
e que inserções de muitos clientes são empacotados juntos e escritos em um bloco. Isto é muito mais rápido que se fazer muitas inserções seperadas.
Note que atualmente as linhas enfileirdas só são armazenadas em memória até que elas sejam inseridas na tabela. Isto significa que se você matar o mysqld
com kill -9
ou se o mysqld
finalizar inesperadamente, as linhas enfileiradas que não forma escritas em disco são perdidas.
A seguir temos uma descrição em detalhes do que acontece quando você utiliza a opção DELAYED
com INSERT
ou REPLACE
. Nesta descrição, a thread
e a thread que recebe um comando INSERT DELAYED
e handler
é a thread que trata todas as instruções INSERT DELAYED
de uma tabela particular.
- Quando uma thread executa uma instrução
DELAYED
em uma tabela, uma thread handler é criada para processar todas as instruçõesDELAYED
para a tabela, se tal handler ainda não existir. - A thread verifica se o handler já adquiriu uma trava
DELAYED
; se não, ele diz a thread handler para fazê-lo. A travaDELAYED
pode ser obtida mesmo se outras threads tiver uma trava deLEITURA
ouESCRITA
na tabela. De qualquer forma, o handler irá esperar por todas as travasALTER TABLE
ouFLUSH TABLES
para se assegurar que a estrutura da tabela está atualizada. - A thread executa a instrução
INSERT
, mas em vez de escrever a linha na tabela, ela põe uma cópia da linha final na fila que é gerenciada pela thread handler. Quaisquer erros de sintaxe são notificados pela thread e relatadas ao programa cliente. - O cliente não pode relatar o número de duplicatas ou o valor
AUTO_INCREMENT
para a linha resultante; ele não pode obtê-los do servidor, pois oINSERT
retorna antes da operação de inserção ser completada. Se você utiliza a API C, a funçãomysql_info()
não irá retornar nada significante, pela mesma razão. - O log binário é atualizado pela thread handler quando a linha é inserida na tabela. No caso de inserção de múltiplas linhas, o log binário é atualizado quando a primeira linha é inserida.
- Depois que todas as linhas
delayed_insert_limit
são escrita, o handle verifica se alguma instruçãoSELECT
está pendente. Se estiver, ele permite que ela seja executada antes de continuar. - Quando o handler não tiver mais linhas na fila, a tabela é destravada. Se nunhum comando
INSERT DELAYED
novo é recebido dentro dedelayed_insert_timeout
segundos, o handler termina. - Se mais que
delayed_queue_size
estão pendentes em uma fila handler específica, a thread requisitandoINSERT DELAYED
espera até que haja espaçõ na fila. Isto é feito para assegurar que o servidormysqld
não utilize toda a memória área de memória de atraso. - A thread handler irá aparecer na lista de processos do MariaDB process list com
delayed_insert
na colunaCommand
. Ela será finalizada se você executar um comandoFLUSH TABLES
ou matá-la comKILL thread_id
. No entanto, primeiro ela armazenará todas as linhas enfileiradas na tabela antes de sair. Durante este tempo ela não aceitará nenhum comandoINSERT
novo da outra thread. Se você executar um comandoINSERT DELAYED
depois disto, uma nova thread handler será criada.Note que o mostrado acima significa que o comando
INSERT DELAYED
tem prioridade maior que um comandoINSERT
normal se já houver um handlerINSERT DELAYED
em execução! Outro comando de atualização terá que esperar até que a filaINSERT DELAYED
esteja vazia, alguém finalize a thread handler (comKILL thread_id
), ou alguém executeFLUSH TABLES
. - As seguintes variáveis de estado fornecem informção sobre comandos
INSERT DELAYED
:Variável Significado Delayed_insert_threads
Número de threads handler Delayed_writes
Números de linhas escrita com INSERT DELAYED
Not_flushed_delayed_rows
Número de linhas esperando para serem escritas Você pode visualizar estas variáveis com a instrução
SHOW STATUS
ou executando um comandomysqladmin extended-status
.
Note que INSERT DELAYED
é mais lento que um INSERT normal se a tabela não estiver em uso. Também há uma sobrecarga adicional para o servidor tratar um thread separada para cada tabela na qual você utiliza INSERT DELAYED
. Isto significa que você só deve usar INSERT DELAYED
quando você estiver certo de necessita dele!