Notas de MySQL de alto rendimiento: conceptos básicos de MySQL (1)

1. Historia y arquitectura de MySQL

Consulte las notas escritas por MySQL de alto rendimiento

1.1 Arquitectura lógica de MySQL

Inserte la descripción de la imagen aquí

El arquitecto de segundo nivel es la parte central de MySQL. La mayoría de las funciones centrales de MySQL se encuentran en esta capa, incluidas las consultas, el análisis, la optimización, el almacenamiento en caché y todas las funciones integradas (fecha, hora, número y funciones de cifrado), todas a través del almacenamiento Las funciones del motor se implementan en esta capa: procedimientos almacenados, vistas, disparadores, etc.

El motor de almacenamiento no analizará nuestro SQL y los diferentes motores de almacenamiento no se comunicarán entre sí, sino que simplemente responderán a las solicitudes del servidor superior.

InnoDB es una excepción , analizará las definiciones de claves externas, porque el servidor MySQL en sí no implementa esta función

1.1.1 Gestión y seguridad de la conexión

Cada cliente tendrá un subproceso en el servidor, y la consulta de esta conexión solo se ejecutará en este único subproceso, y el subproceso solo se puede ejecutar en un determinado núcleo de CPU o CPU a su vez. El servidor será responsable de almacenar en caché los subprocesos, por lo que no es necesario crear o destruir subprocesos para cada nueva conexión.

Las versiones posteriores a MySQL5.5 proporcionan una API para admitir el complemento Thread-Pooling, que puede usar una pequeña cantidad de subprocesos en el grupo para dar servicio a una gran cantidad de conexiones.

1.1.2 Optimización y ejecución

MySQL analizará la consulta, creará una estructura de datos interna (árbol de análisis) y luego realizará varias optimizaciones en ella, incluida la optimización de reescritura, determinar el orden de lectura de la tabla, seleccionar el índice apropiado, etc.

Al optimizador no le importa qué motor de almacenamiento utiliza la tabla, pero el motor de almacenamiento tiene un impacto en la optimización de las consultas.

Para la instrucción SELECT, antes de analizar la consulta, el servidor primero verificará la caché de consultas (Query Cache) . Si la consulta correspondiente se puede encontrar en ella, el servidor no realizará todo el proceso de análisis, optimización y ejecución de consultas, pero volver directamente a la caché de consultas. Conjunto de resultados en

1.2 Control de concurrencia

1.2.1 Bloqueo de lectura y escritura

También se llama bloqueo compartido y bloqueo exclusivo

1.2.2 Bloquear granularidad

Una forma de mejorar la simultaneidad de los recursos compartidos es hacer que los objetos bloqueados sean más selectivos e intentar bloquear solo una parte de los datos que deben modificarse en lugar de todos los recursos.

El problema es que varias operaciones de bloqueo, como bloquear y leer bloqueos, también consumen recursos.

La llamada estrategia de bloqueo consiste en buscar un equilibrio entre la sobrecarga del bloqueo y la seguridad de los datos, por supuesto, este equilibrio también afectará a nuestro rendimiento.

MySQL proporciona una variedad de opciones, cada motor de almacenamiento puede implementar su propia estrategia de bloqueo y granularidad de bloqueo

Bloqueo de mesa

Toda la tabla está bloqueada.Cuando los usuarios modifican, agregan, eliminan, etc., primero necesitan obtener un bloqueo de escritura, que bloqueará todas las operaciones de lectura y escritura en la tabla por parte de otros usuarios. Los bloqueos de lectura no se bloquean entre sí.

Los bloqueos de escritura también tienen una prioridad más alta que los bloqueos de lectura, por lo que las solicitudes de bloqueo de escritura se pueden insertar en la cola. Por el contrario, los bloqueos de lectura no se pueden insertar en la cola de bloqueo de escritura.

Bloqueo de fila

Como sugiere el nombre, es para bloquear una fila de datos, el nivel del bloqueo de la tabla es exacto al nivel de la fila.

1.3 Asuntos

Una transacción es un conjunto de consultas SQL atómicas o una unidad independiente. Se ejecutan todas las declaraciones de la transacción o falla toda la ejecución.

ÁCIDO

Significa: atomicidad, consistencia, aislamiento, durabilidad.

Atomicidad:

Una cosa debe ser considerada como una unidad mínima indivisible de trabajo, es decir, o bien todo entregado con éxito, o todo fallado en revertir, es imposible realizar solo una parte de la operación.

consistencia:

La base de datos siempre pasa de un estado de coherencia a otro estado de coherencia.

Aislamiento:

En términos generales , una modificación de las cosas realizadas antes del envío final de la transacción no es visible para los demás.

Resistencia:

Una vez confirmada la transacción, los cambios realizados se guardarán permanentemente en la base de datos.

1.3.1 Nivel de aislamiento

SQL proporciona cuatro niveles de aislamiento, cada uno de los cuales especifica las modificaciones realizadas en una transacción, que son visibles dentro y entre transacciones y que son invisibles. Los niveles de aislamiento más bajos generalmente pueden realizar una mayor concurrencia, y la sobrecarga del sistema también es menor

El nivel de aislamiento implementado por cada motor de almacenamiento no es el mismo

READ UNCOMMITTED lectura no confirmada

En este nivel, la modificación de una transacción, incluso si no está comprometida, es visible para otras transacciones.

Las transacciones pueden leer datos no confirmados, lo que también se denomina lectura sucia , y existen ciertos problemas de seguridad

El rendimiento no es mucho mejor que en otros niveles, pero carece de la seguridad de otros niveles, por lo que generalmente rara vez se usa.

LEER COMPROMETIDOS

El nivel de aislamiento predeterminado de la mayoría de los sistemas de bases de datos es READ COMMITTED, pero MySQL no. READ COMMITTED satisface la definición simple de aislamiento que mencionamos anteriormente:

Al comienzo de una transacción, solo puede "ver" los cambios realizados por la transacción confirmada. Es decir, desde el inicio de una transacción hasta que se compromete, los cambios realizados son invisibles para otras transacciones.

Este nivel también se denomina lectura no repetible, porque dos ejecuciones de la misma consulta pueden obtener resultados diferentes.

LECTURA REPETIBLE repetibilidad

LECTURA REPETIBLE resuelve el problema de las lecturas sucias. Este nivel asegura que los resultados de leer el mismo registro varias veces en la misma transacción sean consistentes.

Pero teóricamente, el nivel de aislamiento de lectura repetible aún no puede resolver otro
problema de lectura fantasma. La llamada lectura fantasma se refiere a cuando una transacción está leyendo un registro en un cierto rango, otra transacción inserta un nuevo registro en el rango, y cuando la transacción anterior vuelve a leer el registro en el rango, se genera una Fila fantasma. Los motores de almacenamiento InnoDB y XtraDB resuelven el problema de la lectura fantasma mediante el control de concurrencia de múltiples versiones (MVCC, Multiversion Concurrency Control). Discutiremos esto más adelante en este capítulo.
La lectura repetible es el nivel de aislamiento de transacciones predeterminado de MySQL.

SERIALIZABLE se puede serializar

SERIALIZABLE es el nivel de aislamiento más alto . Evita el problema de la lectura fantasma mencionado anteriormente obligando a que las transacciones se ejecuten en serie. En pocas palabras, SERIALIZABLE bloqueará cada fila de datos leídos, por lo que puede causar mucho tiempo de espera y bloquear problemas de contención. Este nivel de aislamiento rara vez se utiliza en aplicaciones prácticas, solo se considera adoptar este nivel cuando es necesario para garantizar la coherencia de los datos y es aceptable que no haya concurrencia.

Nivel de aislamiento Posibilidad de lectura sucia Posibilidad de lectura no repetible Posibilidad de lectura fantasma Bloquear lectura
LEER SIN COMPROMISO No
LEER COMPROMETIDOS No No
LECTURA REPETIBLE No No No
SERIALIZABLE No No No

1.3.2 Interbloqueo

El punto muerto se refiere al fenómeno de dos o más transacciones que se ocupan entre sí en el mismo recurso y solicitan bloquear los recursos que ocupan entre sí, lo que conduce a un círculo vicioso. Cuando varias transacciones intentan bloquear recursos en diferentes órdenes, pueden producirse interbloqueos. Cuando varias transacciones bloquean el mismo recurso al mismo tiempo, también se producirá un punto muerto.

Por ejemplo, imagine que las siguientes dos transacciones procesan la tabla de estudiantes al mismo tiempo

START TRANSACTION
UPDATE Student SET class=5 WHERE student_id = 3 AND DATE="2021-02-12";
UPDATE Student SET class=6 WHERE student_id = 4 AND DATE="2021-02-13";
COMMIT;

START TRANSACTION
UPDATE Student SET student_name="yyyy" WHERE student_id = 4 AND DATE="2021-02-13";
UPDATE Student SET student_name="ssss" WHERE student_id = 3 AND DATE="2021-02-12";
COMMIT;

Si sucede, ambas transacciones ejecutaron la primera instrucción UPDATE, actualizaron una fila de datos y también bloquearon la fila de datos, y luego cada transacción intentó ejecutar la segunda instrucción UPDATE, pero descubrió que la fila había sido bloqueada por la otra parte. , Y luego ambas transacciones están esperando que la otra libere el bloqueo y, al mismo tiempo, manteniendo el bloqueo que la otra necesita, caerá en un bucle sin fin. A menos que intervengan factores externos, es posible eliminar el punto muerto.

Para resolver este problema, el sistema de base de datos implementa varios mecanismos de detección de interbloqueo y tiempo de espera de interbloqueo. Cuanto más complejo sea el sistema, como el motor de almacenamiento InnoDB, más podrá detectar la dependencia circular del interbloqueo y devolver un error de inmediato. Esta solución es muy eficaz; de lo contrario, el punto muerto conducirá a consultas muy lentas. Otra solución es renunciar a la solicitud de bloqueo cuando el tiempo de consulta alcanza la configuración de tiempo de espera de bloqueo.Este método generalmente no es bueno.

El método actual de InnoDB para lidiar con los interbloqueos es revertir la transacción que contiene la menor cantidad de bloqueos exclusivos a nivel de fila (este es un algoritmo de reversión de interbloqueo relativamente simple).

El comportamiento y la secuencia del bloqueo están relacionados con el motor de almacenamiento. Ejecute las declaraciones en el mismo orden, algunos motores de almacenamiento se bloquearán, otros no. Hay dos razones para los interbloqueos: algunos se deben a conflictos de datos reales, que suelen ser difíciles de evitar, pero otros se deben exclusivamente a la implementación del motor de almacenamiento.

Una vez que se produce el interbloqueo, solo una reversión parcial o completa de una de las transacciones puede romper el interbloqueo. Para los sistemas transaccionales, esto es inevitable, por lo que las aplicaciones deben considerar cómo lidiar con los puntos muertos al diseñar. En la mayoría de los casos, solo necesita volver a ejecutar la transacción que se revirtió debido a un punto muerto .

1.3.3 Registro de transacciones

El registro de transacciones puede ayudar a mejorar la eficiencia de las transacciones.

Usando el registro de transacciones, el motor de almacenamiento solo necesita modificar su copia de memoria cuando modifica los datos de la tabla , y luego registrar el comportamiento de modificación en el registro de transacciones persistido en el disco duro, en lugar de conservar los datos modificados en el disco cada tiempo . El registro de transacciones utiliza un método de adición , por lo que la operación de escribir el registro es E / S secuencial en un área pequeña del disco, a diferencia de la E / S aleatoria que requiere mover la cabeza en varios lugares del disco, por lo que el
registro de transacciones es utilizado El camino es relativamente más rápido.

Una vez que el registro de transacciones es duradero, los datos modificados en la memoria se pueden vaciar lentamente de nuevo al disco en segundo plano.

En la actualidad, la mayoría de los motores de almacenamiento se implementan de esta manera. Por lo general, lo llamamos Registro de escritura anticipada. La modificación de datos requiere escribir dos veces en el disco.
Si la modificación de datos se registró en el registro de transacciones y persistió, pero los datos en sí no se volvieron a escribir en el disco, el sistema falla en este momento y el motor de almacenamiento puede restaurar automáticamente esta parte de los datos modificados cuando se reinicia . El método de recuperación específico depende del motor de almacenamiento.

1.3.4 Transacciones en MySQL

MySQL proporciona dos motores de almacenamiento transaccional: InnoDB y NDB Cluster. Además, algunos motores de almacenamiento de terceros también admiten transacciones. Los más conocidos incluyen XtraDB y PBXT. Algunas de sus características respectivas se discutirán en detalle más adelante. (MyISAM también está entre ellos)

Envío automático (AUTOCOMMIT)

MySQL usa el modo AUTOCOMMIT por defecto.

En otras palabras, si no inicia explícitamente una transacción, cada consulta se trata como una transacción para realizar la operación de confirmación. En la conexión actual, puede habilitar o deshabilitar el modo de confirmación automática configurando la variable AUTOCOMIT:

查看本地默认的提交模式
SHOW VARIABLES LIKE 'AUTOCOMMIT';

Inserte la descripción de la imagen aquí

Mi ON aquí significa habilitar nuestro envío automático, si queremos modificar el valor predeterminado

SET AUTOCOMMIT = 0;

Cuando AUTOCOMMIT = 0, todas las consultas están en una transacción, hasta que se realice la confirmación COMMIT o la reversión ROLLBACK de forma explícita, la transacción finaliza y se inicia otra nueva transacción al mismo tiempo.

La modificación de AUTOCOMMIT no tiene
ningún efecto en tablas no transaccionales, como MyISAM o tablas de memoria . Para este tipo de tabla, no existe el concepto COMMIT o ROLLBACK, y también se puede decir que es equivalente a haber estado en modo AUTOCOMMIT habilitado.

También hay algunos comandos que obligarán a COMMIT a confirmar la transacción activa actual antes de la ejecución . Un ejemplo típico, en el lenguaje de definición de datos (DDL), si es una operación que hará que una gran cantidad de datos cambie, como ALTER TABLE, este es el caso . Además, otras declaraciones como LOCK TABLES pueden producir el mismo resultado. Si es necesario, consulte la documentación oficial de la versión correspondiente para confirmar la lista de todas las declaraciones que pueden causar el envío automático.
MySQL puede establecer el nivel de aislamiento ejecutando el comando SET TRANSACTION ISOLATION LEVEL . El nuevo nivel de aislamiento entrará en vigor cuando comience la siguiente transacción. El nivel de aislamiento de toda la base de datos se puede establecer en el archivo de configuración, o solo se puede cambiar el nivel de aislamiento de la sesión actual:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITED;

MySQL puede reconocer los cuatro niveles de aislamiento ANSI y el motor InnoDB también admite todos los niveles de aislamiento.

Mezclar motores de almacenamiento en transacciones

La capa del servidor MySQL no administra transacciones, y las transacciones son implementadas por el motor de almacenamiento subyacente. Por lo tanto, no es confiable utilizar varios motores de almacenamiento en la misma transacción.
Si mezcla tablas transaccionales y no transaccionales (como tablas InnoDB y MyISAM) en una transacción, no habrá problemas en la confirmación normal.
Pero si es necesario revertir la transacción, los cambios en la tabla no transaccional no se pueden deshacer, lo que provocará que la base de datos se encuentre en un estado incoherente. Esta situación es difícil de reparar y el resultado final de la transacción será incierto. Por lo tanto, es muy importante elegir el motor de almacenamiento adecuado para cada mesa.
Al realizar operaciones relacionadas con transacciones en una tabla no transaccional, MySQL generalmente no emite un recordatorio ni informa un error. A veces, se emite una advertencia solo cuando se revierte: "Los cambios en determinadas tablas no transaccionales no se pueden revertir". Pero en la mayoría de los casos, no habrá solicitudes para operaciones en tablas no transaccionales.

Bloqueo implícito y explícito

  1. Bloqueo implícito

    InnoDB utiliza un protocolo de bloqueo de dos fases. Durante la ejecución de la transacción, el bloqueo se puede realizar en cualquier momento. El bloqueo se libera solo cuando se ejecuta COMMIT o ROLLBACK, y todos los bloqueos se liberan al mismo tiempo. Los bloqueos descritos anteriormente son todos bloqueos implícitos, e InnoDB se bloqueará automáticamente cuando sea necesario de acuerdo con el nivel de aislamiento.

  2. Bloqueo de pantalla

    Además, InnoDB también admite el bloqueo explícito a través de declaraciones específicas, que no forman parte de la especificación SQL:

    SELECT ... LOCK IN SHARE MODE
    SELECT ... FOR UPDATE
    

    MySQL también admite declaraciones LOCK TABLES y UNL0CK TABLES , que se implementan en la capa del servidor y no tienen nada que ver con el motor de almacenamiento. Tienen sus propios usos, pero no sustituyen el procesamiento de transacciones. Si la aplicación necesita usar transacciones, aún debe elegir un motor de almacenamiento transaccional.

A menudo se puede encontrar que la aplicación ha convertido la tabla de MyISAM a InnoDB, pero aún usa explícitamente la instrucción LOCK TABLES . Esto no solo es innecesario, sino que también afecta gravemente al rendimiento.De hecho, los bloqueos de nivel de fila de InnoDB funcionan mejor.
Si L0CK TABLES y las transacciones se afectan entre sí, la situación se volverá muy complicada, e incluso se producirán resultados impredecibles en algunas versiones de MySQL. Por lo tanto, este libro recomienda que, excepto que AUTOCOMIT esté deshabilitado en la transacción y se pueda usar LOCK TABLES , no ejecute explícitamente LOCK TABLES en ningún momento, sin importar qué motor de almacenamiento se use.

1.4 Control de concurrencia de múltiples versiones

La mayoría de los motores de almacenamiento transaccional de MySQL no implementan bloqueos simples de nivel de fila.

Sobre la base de la consideración de mejorar el rendimiento de la concurrencia, generalmente implementan el control de concurrencia de múltiples versiones (MVCC) al mismo tiempo. No solo MySQL, sino también otros sistemas de bases de datos como Oracle y PostgreSQL también han implementado MVCC, pero sus mecanismos de implementación no son los mismos, porque MVCC no tiene un estándar de implementación unificado.

Se puede considerar que MVCC es una variante del bloqueo a nivel de fila, pero evita las operaciones de bloqueo en muchos casos, por lo que la sobrecarga es menor. Aunque los mecanismos de implementación son diferentes, la mayoría implementa operaciones de lectura sin bloqueo y las operaciones de escritura solo bloquean las filas necesarias.

La realización de MVCC se logra guardando una instantánea de los datos en un momento determinado . En otras palabras, no importa cuánto tiempo tarde en ejecutarse, los datos que ve cada transacción son consistentes.

De acuerdo con el momento en que comienza la transacción, los datos que ve cada transacción en la misma mesa al mismo tiempo pueden ser diferentes. Si no existe tal concepto antes, esta oración suena un poco confusa. Una vez que se haya familiarizado con ella, encontrará que esta oración es realmente muy fácil de entender.
Como se mencionó anteriormente, la implementación de MVCC para diferentes motores de almacenamiento es diferente, los típicos son el control de concurrencia optimista y el control de concurrencia pesimista. A continuación, usamos la versión simplificada del comportamiento de InnoDB para ilustrar cómo funciona MVCC.

El MVCC de InnoDB se implementa almacenando dos columnas ocultas detrás de cada fila de registros . De estas dos columnas, una contiene el tiempo de creación de la fila y la otra el tiempo de vencimiento (o tiempo de eliminación) de la fila .

Por supuesto, lo que se almacena no es el valor de tiempo real, sino el número de versión del sistema. Cada vez que inicia una nueva transacción, el número de versión del sistema se incrementa automáticamente.

El número de versión del sistema al comienzo de la transacción se utilizará como el número de versión de la transacción que
se comparará con el número de versión de cada fila de la consulta . Echemos un vistazo a cómo funciona MVCC bajo el nivel de aislamiento REPEATABLE READ .

SELECT
	InnoDB会根据以下两个条件检查每行记录:
	a. InnoDB只查找版本早于当前事务版本的数据行(也就是,行的系统版本号小于或等于事务的系统版本号),这样可以确保事务读取的行,要么是在事务开
始前已经存在的,要么是事务自身插人或者修改过的。
	b.行的删除版本要么未定义,要么大于当前事务版本号。这可以确保事务读取到的行,在事务开始之前未被删除。只有符合上述两个条件的记录,才能返回作为查询结果。

El significado de lo anterior es simple: solo se pueden encontrar los datos modificados por la transacción anterior, y se pueden encontrar los datos antes del inicio de la transacción

INSERT
	InnoDB为新插入的每一行保存当前系统版本号作为行版本号。
DELETE
	InnoDB为删除的每一行保存当前系统版本号作为行删除标识。
UPDATE
	InnoDB为插入一行新记录,保存当前系统版本号作为行版本号,同时保存当前系统版本号到原来的行作为行删除标识。

Guarde estos dos números de versión del sistema adicionales, de modo que se puedan desbloquear la mayoría de las operaciones de lectura. Este diseño hace que la operación de lectura de datos sea muy simple, el rendimiento es muy bueno y también puede garantizar que solo se leerán las filas que cumplan con los estándares.

La desventaja es que cada fila de registros requiere espacio de almacenamiento adicional, más trabajo de inspección de filas y algún trabajo de mantenimiento adicional.
MVCC sólo funciona en dos niveles de aislamiento: REPEATABLE READ y READ COMMITTED . Los otros dos niveles de aislamiento no son compatibles con MVCC (MVCC no tiene una especificación formal, por lo que la implementación de cada motor de almacenamiento y sistema de base de datos es diferente, nadie puede decir que otras implementaciones sean incorrectas)

Porque READ UNCOMMITTED siempre lee la última fila de datos, no la fila de datos que se ajusta a la versión actual de la transacción. Y SERIALIZABLE bloqueará todas las filas leídas.

Supongo que te gusta

Origin blog.csdn.net/qq_22155255/article/details/109908057
Recomendado
Clasificación