INSERT DELAYED
INSERT DELAYED ...
La opción DELAYED para la sentencia INSERT es una extensión de MySQL al SQL
estándar que es muy práctica si se tienen clientes que no pueden esperar a que el INSERT
se complete. Este es un problema frecuente cuando se usa MySQL y además se ejecutan periódicamente
sentencias SELECT y UPDATE que necesitan mucho tiempo para completarse.
DELAYED se añadió en MySQL 3.22.15.
Cuando un cliente usa INSERT DELAYED, obtiene una confirmación por parte del servidor de forma
inmediata, y la fila se almacena en una cola para ser insertada cuando la tabla no esté en uso por
ningún otro proceso.
Otra gran ventaja de usar INSERT DELAYED es que las inserciones desde muchos clientes son
ligadas juntas y escritas en un bloque. Esto es mucho más rápido que hacer muchas inserciones
separdas.
Existen algunas limitaciones en el uso de DELAYED:
- INSERT DELAYED funciona sólo con tabls MyISAM y ISAM. Para tablas MyISAM,
si no existen bloques libres en el interior del fichero de datos, se soportan sentencias
SELECT e INSERT concurrentes. Bajo esas circunstancias, raramente será necesario
el uso de INSERT DELAYED con MyISAM.
- INSERT DELAYED debe ser usado sólo con sentecias INSERT que especifiquen listas de
valores. Esto está forzado desde MySQL 4.0.18. El servidor ignora el DELAYED para sentencias
INSERT DELAYED ... SELECT.
- El servidor también ignora el DELAYED para sentencias
INSERT DELAYED ... ON DUPLICATE UPDATE.
- Ya que la sentencia regresa inmediatamente, antes de que las filas sean insertadas, no se puede usar
LAST_INSERT_ID() para obtener el valor AUTO_INCREMENT que la sentencia
generará.
- Las filas DELAYED no son visibles para sentencias SELECT hasta que hayan sido
insertadas.
Hay que tener en cuenta que las filas actualmente en la cola se almacenan sólo en memoria hasta que
sean insertadas en la tabla. Eso significa que si se fuerza la terminación de mysqld (por
ejemplo, con kill -9) o si mysqld termina de forma inesperada, cualquier fila en la cola que
no haya sido escrita en disco se perderá.
A continuación se describe con detalle qué ocurre cuando se usa la opción DELAYED con
INSERT o REPLACE. En esta descripción, el "proceso" es el que recibe una
sentencia INSERT DELAYED y el "manipulador" es el proceso que manipula todas las rentencias
INSERT DELAYED para una tabla concreta.
- Cuando un proceso ejecuta una sentencia DELAYED para una tabla, se crea un proceso manipulador
para procesar todas las sentencias DELAYED para esa tabla, si es que no existe ya tal
manipulador.
- El proceso verifica si el manipulador ha adquirido ya un bloqueo DELAYED; si no lo ha hecho,
le indica al proces manipulador que lo haga. El bloqueo DELAYED puede ser obtenido incluso si
otro proceso tiene un bloque READ o WRITE sobre la tabla. No obstante, el manipulador
esperará a que terminen todos los bloqueos ALTER TABLE y FLUSH TABLES para asegurarse
de que la estructura de la tabla esté lista para usarse.
- El proceso ejecuta la sentencia INSERT, pero en lugar de escribir la fila en la tabla,
coloca una copia de la fila final en una cola que es manejada por el proceso manipulador. Cualquier
error de sintaxis se notifica al proceso y enviado al proceso cliente.
- El cliente no puede obtener el número de registros duplicados desde el servidor o el valor
AUTO_INCREMENT de la fila resultante, porque la sentencia INSERT regresa antes de
que la operación de inserción haya sido completada. (Si se usa el API C, la función
mysql_info() tampoco devuelve nada con significado, por la misma razón.)
- El diario binario se actualiza por el proceso manipulador cuando la fila es insertada en la tabla.
En caso de inserciones de varias filas, el diario binario se acutaliza cuando la primera fila es
insertada.
- Después de cada escritura de every delayed_insert_limit filas, el manipulador comprueba si
hay pendiente alguna sentencia SELECT. Si es así, permite su ejecución antes de
continuar.
- Cuando el manipulador no tiene más filas en su cola, desbloquea la tabla. Si no se reciben nuevas
sentencias INSERT DELAYED en el intervalo de delayed_insert_timeout segundos, el
manipulador termina.
- Si hay más de delayed_queue_size filas pendientes en una cola de manipulador, el proceso que
ha lanzado el INSERT DELAYED espera hasta que haya espacio en la cola. Esto se hace para
asegurarse que el servidor mysqld no use toda la memoria para la cola de inserciones
retrasadas.
- El proceso manipulador aparece en la lista de procesos MySQL con delayed_insert en la columna
'Command'. Puede ser terminado si se ejecuta la sentencia FLUSH TABLES o con
KILL thread_id. Sin embargo, antes de salir, primero almacenará todas las filas en la tabla.
Durante este tiempo no aceptará ninguna nueva sentencia INSERT desde otro proceso. Si
se ejecuta una sentencia INSERT DELAYED después, se creará un nuevo proceso manipulador.
Esto significa que las sentencias INSERT DELAYED tienen mayor prioridad que las sentencias
INSERT normales si existe un manipulador de INSERT DELAYED en ejecución. Otras
sentencias de actualización tendrán que esperar a que la cola de INSERT DELAYED se vacíe,
alguien finalice el proceso manipulador (con KILL thread_id), o alguien ejecute
FLUSH TABLES.
- Las siguientes variables de estado proporcionan información sobre sentencias INSERT DELAYED:
Variable de estado |
Significado |
Delayed_insert_threads |
Número de procesos manipuladores |
Delayed_writes |
Número de filas escritas con INSERT DELAYED |
Not_flushed_delayed_rows |
Número de filas esperando a ser escritas |
- Se pueden ver estas variables mediante una sentencia SHOW STATUS o ejecutando un comando
mysqladmin extended-status.
Hay que tener en cuenta que INSERT DELAYED es más lenta que un INSERT normal si
la tabla no está en uso. Hay algo de trabajo adicional para el servidor al manipular un proceso separado
para cada tabla para la que haya inserciones de filas retrasadas. Esto significa que sólo se debe usar
INSERT DELAYED cuando se esté realmente seguro de que es necesario.
(4.1.1)