Consulta:
SELECT COUNT(online.account_id) cnt from online;
Pero la tabla en línea también se modifica por un evento, por lo que con frecuencia puedo ver el bloqueo ejecutando show processlist
.
¿Hay alguna gramática en MySQL que pueda hacer que la instrucción select no cause bloqueos?
Y he olvidado mencionar anteriormente que está en una base de datos esclava MySQL.
Después de agregar en my.cnf:transaction-isolation = READ-UNCOMMITTED
el esclavo se encontrará con un error:
Error 'El registro binario no es posible. Mensaje: El nivel de transacción 'READ-UNCOMMITTED' en InnoDB no es seguro para el modo binlog 'STATEMENT' 'en la consulta
Entonces, ¿hay una manera compatible de hacer esto?
Respuestas:
Encontré un artículo titulado "MYSQL WITH NOLOCK"
https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx
en MS SQL Server haría lo siguiente:
y el equivalente MYSQL es
EDITAR
Michael Mior sugirió lo siguiente (de los comentarios)
fuente
SESSION
y, por lo tanto, que el nivel de transacción se aplique solo a la próxima transacción. Luego, simplemente reemplace la tercera declaración anterior conCOMMIT
. Esto será un noop en este caso, pero tendrá el efecto secundario de finalizar la transacción y restablecer el nivel de aislamiento predeterminado.SET TRANSACTION
declaración de estado: "Esta declaración establece el nivel de aislamiento, que se utiliza para las operaciones en las tablas InnoDB".Si la tabla es InnoDB, consulte http://dev.mysql.com/doc/refman/5.1/en/innodb-consistent-read.html : utiliza la lectura consistente (modo sin bloqueo) para los SELECT "que hacen no especifique FOR UPDATE o LOCK IN SHARE MODE si la opción innodb_locks_unsafe_for_binlog está establecida y el nivel de aislamiento de la transacción no está establecido en SERIALIZABLE. Por lo tanto, no se establecen bloqueos en las filas leídas de la tabla seleccionada ".
fuente
Utilizar
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.
Versión 5.0 Los documentos están aquí .
Versión 5.1 Los documentos están aquí .
fuente
Es posible que desee leer esta página del manual de MySQL. La forma en que se bloquea una tabla depende del tipo de tabla que sea.
MyISAM usa bloqueos de tabla para lograr una velocidad de lectura muy alta, pero si tiene una instrucción UPDATE esperando, los futuros SELECTS se pondrán en cola detrás de UPDATE.
Las tablas de InnoDB usan bloqueo de nivel de fila, y no tendrá toda la tabla bloqueada detrás de una ACTUALIZACIÓN. Hay otro tipo de problemas de bloqueo asociados con InnoDB, pero es posible que se ajuste a sus necesidades.
fuente
Según el tipo de tabla, el bloqueo se realizará de manera diferente, pero también lo hará un recuento SELECT. Para las tablas MyISAM, una simple cuenta SELECT (*) FROM no debe bloquear la tabla ya que accede a los metadatos para extraer la cuenta del registro. Innodb tomará más tiempo ya que tiene que tomar la tabla en una instantánea para contar los registros, pero no debería causar el bloqueo.
Al menos debe tener concurrent_insert establecido en 1 (predeterminado). Luego, si no hay "huecos" en el archivo de datos para que se llene la tabla, se agregarán inserciones al archivo y SELECT e INSERT pueden ocurrir simultáneamente con las tablas MyISAM. Tenga en cuenta que la eliminación de un registro pone un "vacío" en el archivo de datos que intentará rellenarse con futuras inserciones y actualizaciones.
Si rara vez elimina registros, puede establecer concurrent_insert igual a 2, y las inserciones siempre se agregarán al final del archivo de datos. Luego, las selecciones e inserciones pueden suceder simultáneamente, pero su archivo de datos nunca será más pequeño, sin importar cuántos registros elimine (excepto todos los registros).
En pocas palabras, si tiene muchas actualizaciones, inserciones y selecciones en una tabla, debe convertirla en InnoDB. Sin embargo, puede mezclar libremente tipos de tablas en un sistema.
fuente
Otra forma de habilitar la lectura sucia en mysql es agregar una pista: BLOQUEO EN MODO COMPARTIR
fuente
De esta referencia:
fuente
Los SELECT normalmente no realizan ningún bloqueo que le interese en las tablas de InnoDB. El nivel de aislamiento de transacción predeterminado significa que las selecciones no bloquean cosas.
Por supuesto, la contienda todavía sucede.
fuente
show processlist
para ver realmente las cerraduras. Por lo tanto, es seguro asumir que, de hecho, se están bloqueando.