INSERT DELAYED ...
La opción DELAYED para el comando
INSERT es una extensión de MySQL del
estándar SQL muy útil si tiene clientes que no pueden
esperar a que se complete el INSERT . Este
es un problema común cuando usa MySQL para loguear y
periódicamente ejecuta comandos SELECT y
UPDATE que tardan mucho tiempo en
completarse.
Cuando un cliente usa INSERT DELAYED,
obtiene un ok del servidor una vez, y el registro se encola
para insertarse cuando la tabla no está en uso por otro
flujo.
Otro beneficio de usar INSERT DELAYED es
que las inserciones desde varios clientes se tratan juntas y
se escriben en un bloque. Esto es mucho más rápido que
realizar inserciones separadas.
Hay algunas restricciones al uso de
DELAYED:
En MySQL 5.0, INSERT DELAYED funciona
sólo con tablas MyISAM y
MEMORY . Para tablas
MyISAM , si no hay bloques libres en
medio del fichero de datos, se soportan comandos
SELECT y INSERT
concurrentes. Bajo estas circunstáncias, muy raramente
necesitará usar INSERT DELAYED con
MyISAM. Consulte
Sección 14.1, “El motor de almacenamiento MyISAM” y
Sección 14.3, “El motor de almacenamiento MEMORY
(HEAP)”.
En MySQL 5.0, INSERT DELAYED debe
usarse sólo para comandos INSERT que
especifiquen una lista de valores. El servidor ignora
DELAYED para comandos INSERT
DELAYED ... SELECT .
El servidor ignora DELAYED para
comandos INSERT DELAYED ... ON DUPLICATE
UPDATE.
Debido a que el comando retorna inmediatamente antes que
los registros se inserten, no puede usar
LAST_INSERT_ID() para obtener el valor
AUTO_INCREMENT que el comando genera.
Los registros DELAYED no son visibles
por los comandos SELECT hasta que se
hayan insertado realmente.
DELAYED se ignora en la replicación de
esclavos porque puede causar que el esclavo tenga
distintos datos que el maestro.
Tenga en cuenta que los registros encolados se tratan sólo en
memoria hasta que se insertan en la tabla. Esto significa que
si termina mysqld forzadamente (por
ejemplo, con kill -9) o si
mysqld muere inesperadamente, cualquier
registro encolado que no se escriba en disco se pierde.
A continuación se describe en detalle qué ocurre cuando usa
la opción DELAYED con
INSERT o REPLACE. En
esta descriión, el “flujo” es el flujo que
recibe un comando INSERT DELAYED y
“handler” es el flujo que trata todos los
comandos INSERT DELAYED para una tabla
particular.
Cuando un flujo ejecuta un comando
DELAYED para una tabla, un flujo
handler se crea para procesar todos los comandos
DELAYED para la tabla, si tal handler
no existía préviamente.
El flujo chequea si el handler ha adquirido préviamente
un bloqueo DELAYED ; si no, le dice al
flujo handler que lo haga. El bloqueo
DELAYED puede obtenerse incluso si
otros flujos tienen el bloqueo READ o
WRITE en la tabla. Sin embargo, el
handler espera a todos los bloqueos ALTER
TABLE o FLUSH TABLES para
asegurar que la estructura de tabla está actualizada.
El flujo ejecuta el comando INSERT,
pero en lugar de escribir el registro en la tabla, pone
una copia del registro final en una cola administrada por
el flujo handler. Cualquier error de sintaxis es detectado
por el flujo y se reporta al programa cliente.
El cliente no puede obtener del servidor el número de
registros duplicados o el valor
AUTO_INCREMENT del registro resultante,
ya que INSERT retorna antes que se
complete la operación de inserción. (Si usa la API C, la
función mysql_info() no retorna nada
inteligible por la misma razón.)
El log binario se actualiza por parte del flujo handler cuando el registro se inserta en la tabla. En caso de inserciones de múltiples registros, el log binario se actualiza cuando el primer registro se inserta.
Tras cada delayed_insert_limit los
registros se escriben, el handler chequea si algún
comando SELECT todavía está
pendiente. Si es así, les permite ejecutarse antes de
continuar.
Cuando el handler no tiene más registros en su cola, la
tabla se desbloquea. Si no se reciben nuevos comandos
INSERT DELAYED en
delayed_insert_timeout segundos, el
handler termina.
Si más de delayed_queue_size registros
están pendientes en una cola de handler específica, el
flujo que pida el INSERT DELAYED espera
hasta que haya espacio en la cola. Esto se hace para
asegurar que mysqld no usa toda la
memoria para la cola de memoria retrasada.
El flujo handler se muestra en l lista de procesos MySQL
con delayed_insert en la columna
Command . Si muere si ejecuta un
comando FLUSH TABLES o puede matarlo
con KILL thread_id. Sin embargo, antes
de salir, primero almacena todos los registros encolados
en la tabla. Durante esta operación no acepta ningún
nuevo comando INSERT de otros flujos.
Si ejecuta un comando INSERT DELAYED a
continuación, se crea un nuevo flujo handler.
Tenga en cuenta que esto significa que comandos
INSERT DELAYED tienen mayor prioridad
que comandos INSERT normales si hay un
handler INSERT DELAYED en ejecución.
Otros comandos de actualización tienen que esperar hast
que la cola INSERT DELAYED está
vacía, alguien termine el flujo handler (con
KILL thread_id), o alguien ejecute un
FLUSH TABLES.
Las siguientes variables de estado proporcionan
información acerca de comandos INSERT
DELAYED :
| Variable de estado | Significado |
Delayed_insert_threads |
Número de flujos handler |
Delayed_writes |
Número de registros escritos con INSERT DELAYED
|
Not_flushed_delayed_rows |
Número de registros esperando a ser escritos |
Puede ver estas variables ejecutando un comando
SHOW STATUS o mysqladmin
extended-status.
Tenga en cuenta que INSERT DELAYED es más
lento que un INSERT normal si la tabla no
está en uso. También hay una sobrecarga adicional para el
servidor debido a que tiene que tratar un flujo separado para
cada tabla en que haya registros retardados. Esto significa
que debe usar INSERT DELAYED sólo cuando
esté realmente seguro que lo necesita.
Ésta es una traducción del manual de referencia de MySQL, que puede encontrarse en dev.mysql.com. El manual de referencia original de MySQL está escrito en inglés, y esta traducción no necesariamente está tan actualizada como la versión original. Para cualquier sugerencia sobre la traducción y para señalar errores de cualquier tipo, no dude en dirigirse a mysql-es@vespito.com.
