INSERT DELAYED ...
A opção DELAYED
para a instrução
INSERT
é um opção específica do MySQL
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 MySQL para fazer log
e você também execute periodicamente instruções
SELECT
e UPDATE
que
levem muito tempo para completar. DELAYED
foi intriduzido no MySQL versão 3.22.15. Ela é uma extensão
do MySQL 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
. See
Secção 7.1, “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ções
DELAYED
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 trava DELAYED
pode ser obtida mesmo se outras threads tiver uma trava de
LEITURA
ou ESCRITA
na tabela. De qualquer forma, o handler irá esperar por
todas as travas ALTER TABLE
ou
FLUSH 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 o
INSERT
retorna antes da operação de
inserção ser completada. Se você utiliza a API C, a
função mysql_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ção
SELECT
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 de
delayed_insert_timeout
segundos, o
handler termina.
Se mais que delayed_queue_size
estão
pendentes em uma fila handler específica, a thread
requisitando INSERT DELAYED
espera até
que haja espaçõ na fila. Isto é feito para assegurar
que o servidor mysqld
não utilize toda
a memória área de memória de atraso.
A thread handler irá aparecer na lista de processos do
MySQL process list com delayed_insert
na coluna Command
. Ela será finalizada
se você executar um comando FLUSH
TABLES
ou matá-la com KILL
thread_id
. No entanto, primeiro ela armazenará
todas as linhas enfileiradas na tabela antes de sair.
Durante este tempo ela não aceitará nenhum comando
INSERT
novo da outra thread. Se você
executar um comando INSERT 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 comando INSERT
normal se já houver
um handler INSERT DELAYED
em
execução! Outro comando de atualização terá que
esperar até que a fila INSERT DELAYED
esteja vazia, alguém finalize a thread handler (com
KILL thread_id
), ou alguém execute
FLUSH 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 comando
mysqladmin 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!
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.