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
DELAYEDem uma tabela, uma thread handler é criada para processar todas as instruçõesDELAYEDpara 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 travaDELAYEDpode ser obtida mesmo se outras threads tiver uma trava deLEITURAouESCRITAna tabela. De qualquer forma, o handler irá esperar por todas as travasALTER TABLEouFLUSH TABLESpara 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_INCREMENTpara a linha resultante; ele não pode obtê-los do servidor, pois oINSERTretorna 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_limitsão escrita, o handle verifica se alguma instruçãoSELECTestá 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 DELAYEDnovo é recebido dentro dedelayed_insert_timeoutsegundos, o handler termina. - Se mais que
delayed_queue_sizeestão pendentes em uma fila handler específica, a thread requisitandoINSERT DELAYEDespera até que haja espaçõ na fila. Isto é feito para assegurar que o servidormysqldnã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_insertna colunaCommand. Ela será finalizada se você executar um comandoFLUSH TABLESou 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 comandoINSERTnovo da outra thread. Se você executar um comandoINSERT DELAYEDdepois disto, uma nova thread handler será criada.Note que o mostrado acima significa que o comando
INSERT DELAYEDtem prioridade maior que um comandoINSERTnormal se já houver um handlerINSERT DELAYEDem execução! Outro comando de atualização terá que esperar até que a filaINSERT DELAYEDesteja 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_threadsNúmero de threads handler Delayed_writesNúmeros de linhas escrita com INSERT DELAYEDNot_flushed_delayed_rowsNúmero de linhas esperando para serem escritas Você pode visualizar estas variáveis com a instrução
SHOW STATUSou 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!