Charla general sobre MySQL (4)

 4. Mecanismo de bloqueo de MySQL

1- Descripción general de la teoría de bloqueo de base de datos

Un bloqueo es un mecanismo por el cual una computadora coordina el acceso simultáneo a un recurso por parte de múltiples procesos o subprocesos.

En la base de datos, además de la contención de los recursos informáticos tradicionales (como CPU, RAM, E/S, etc.), los datos también son un recurso compartido por muchos usuarios. Cómo garantizar la coherencia y la validez del acceso simultáneo a los datos es un problema que todas las bases de datos deben resolver, y los conflictos de bloqueo también son un factor importante que afecta el rendimiento del acceso simultáneo a las bases de datos. Desde esta perspectiva, los bloqueos son particularmente importantes y más complejos para las bases de datos.

Analogía: compras en línea

Por ejemplo, vamos a Taobao a comprar un producto y solo hay un producto en stock. Si otra persona lo compra en este momento, ¿cómo resolver el problema de si lo compró usted u otra persona lo compró?

Las transacciones deben usarse aquí. Primero sacamos la cantidad del artículo de la tabla de inventario, luego insertamos el pedido, insertamos la información de la tabla de pago después del pago y luego actualizamos la cantidad del artículo. En este proceso, el uso de bloqueos puede proteger recursos limitados y resolver la contradicción entre aislamiento y concurrencia.

Clasificación de cerraduras

Del tipo de operación de datos (lectura\escritura)

  • Bloqueo de lectura (bloqueo compartido): para el mismo dato, se pueden realizar múltiples operaciones de lectura simultáneamente sin afectarse entre sí.
  • Bloqueo de escritura (bloqueo exclusivo): antes de que se complete la operación de escritura actual, bloqueará otros bloqueos de escritura y bloqueos de lectura.

De la granularidad de las operaciones de datos

  • bloqueo de mesa
  • bloqueo de fila

2- Leer la explicación de la caja de la cerradura

El motor MyISAM de bloqueo de tabla (lectura parcial) se utiliza a continuación.

Características: Favorece el motor de almacenamiento MyISAM, con sobrecarga baja y bloqueo rápido, sin puntos muertos, gran granularidad de bloqueo, la mayor probabilidad de conflictos de bloqueo y la menor concurrencia.

Crear tabla SQL

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql"><span style="color:#0000ff">create</span> <span style="color:#0000ff">table</span> mylock (
    id <span style="color:#a31515">int</span> <span style="color:#0000ff">not</span> <span style="color:#0000ff">null</span> <span style="color:#0000ff">primary</span> key auto_increment,
    name <span style="color:#a31515">varchar</span>(<span style="color:#880000">20</span>) <span style="color:#0000ff">default</span> <span style="color:#a31515">''</span>
) engine myisam; #注意这里使用了MyISAM引擎

<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'a'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'b'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'c'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'d'</span>);
<span style="color:#0000ff">insert</span> <span style="color:#0000ff">into</span> mylock(name) <span style="color:#0000ff">values</span>(<span style="color:#a31515">'e'</span>);

<span style="color:#0000ff">select</span> <span style="color:#ab5656">*</span> <span style="color:#0000ff">from</span> mylock;
</code></span></span>

resultado de la operación

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">select</span> <span style="color:#ab5656">*</span> <span style="color:#0000ff">from</span> mylock;
<span style="color:#ab5656">+</span><span style="color:#008000">----+------+</span>
<span style="color:#ab5656">|</span> id <span style="color:#ab5656">|</span> name <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">----+------+</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">1</span> <span style="color:#ab5656">|</span> a    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">2</span> <span style="color:#ab5656">|</span> b    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">3</span> <span style="color:#ab5656">|</span> c    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">4</span> <span style="color:#ab5656">|</span> d    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>  <span style="color:#880000">5</span> <span style="color:#ab5656">|</span> e    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">----+------+</span>
<span style="color:#880000">5</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.00</span> sec)
</code></span></span>

①Agregar bloqueo de mesa manualmente

tabla de bloqueo nombre de tabla lectura (escritura), nombre de tabla 2 lectura (escritura), otros;

  • leer (escribir) significa: si agregar un bloqueo de lectura o un bloqueo de escritura a esta tabla;
<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> lock <span style="color:#0000ff">table</span> mylock read;Query OK, <span style="color:#880000">0</span> <span style="color:#0000ff">rows</span> affected (<span style="color:#880000">0.00</span> sec)
</code></span></span>

Ver los candados agregados a la tabla

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> <span style="color:#0000ff">open</span> tables;
<span style="color:#ab5656">+</span><span style="color:#008000">--------------------+------------------------------------------------------+--------+-------------+</span>
<span style="color:#ab5656">|</span> Database           <span style="color:#ab5656">|</span> <span style="color:#0000ff">Table</span>                                                <span style="color:#ab5656">|</span> In_use <span style="color:#ab5656">|</span> Name_locked <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">--------------------+------------------------------------------------------+--------+-------------+</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> events_waits_summary_by_user_by_event_name           <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> events_waits_summary_global_by_event_name            <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> events_transactions_summary_global_by_event_name     <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> performance_schema <span style="color:#ab5656">|</span> replication_connection_status                        <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> mysql              <span style="color:#ab5656">|</span> time_zone_leap_second                                <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> mysql              <span style="color:#ab5656">|</span> columns_priv                                         <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> my                 <span style="color:#ab5656">|</span> test03                                               <span style="color:#ab5656">|</span>      <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> bigdata            <span style="color:#ab5656">|</span> mylock                                               <span style="color:#ab5656">|</span>      <span style="color:#880000">1</span> <span style="color:#ab5656">|</span>           <span style="color:#880000">0</span> <span style="color:#ab5656">|</span>
...
</code></span></span>

In_use siendo 1 significa que la tabla mylock de esta biblioteca ha sido bloqueada.

Liberar el candado

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> unlock tables;
Query OK, <span style="color:#880000">0</span> <span style="color:#0000ff">rows</span> affected (<span style="color:#880000">0.00</span> sec)
</code></span></span>

Agregar bloqueo de lectura: agregue bloqueo de lectura a la tabla mylock (ejemplo de escritura de bloque de lectura)

Varias sesiones pueden simular una situación distribuida: cuando la sesión 1 bloquea la tabla A, las demás sesiones solo pueden leer la tabla y se bloquearán las actualizaciones y las inserciones.

3- Leer la explicación de la caja de la cerradura 2

Agregue un bloqueo de escritura a la tabla mylock (un ejemplo de lectura de bloqueo de escritura del motor de almacenamiento MylSAM)

Después de que session1 agregue un bloqueo de escritura ( puedes jugar como quieras ), ¡otras sesiones no pueden leerlo!

Conclusión del caso

Antes de ejecutar la declaración de consulta (SELECT), MyISAM agregará automáticamente bloqueos de lectura a todas las tablas involucradas, y antes de realizar operaciones de adición, eliminación y modificación, agregará automáticamente bloqueos de escritura a las tablas involucradas.

Los bloqueos de nivel de tabla de MySQL tienen dos modos:

  • Bloqueo de lectura compartida de tabla (Bloqueo de lectura de tabla)

  • Bloqueo de escritura exclusivo de tabla (Bloqueo de escritura de tabla)

Tipo de bloqueo Compatibilidad leer bloqueo bloqueo de escritura
leer bloqueo No
bloqueo de escritura No No

En combinación con la tabla anterior, la operación en la tabla MyISAM tendrá las siguientes situaciones:

  1. La operación de lectura ( bloqueo de lectura ) en la tabla MyISAM no bloqueará las solicitudes de lectura de otros procesos a la misma tabla , pero bloqueará las solicitudes de escritura a la misma tabla . Solo cuando se libera el bloqueo de lectura, se realizará la operación de escritura de otros procesos.

  2. La operación de escritura ( agregar un bloqueo de escritura ) a la tabla MyISAM bloqueará las operaciones de lectura y escritura de otros procesos en la misma tabla . Solo después de liberar el bloqueo de escritura, se realizarán las operaciones de lectura y escritura de otros procesos.

En resumen, los bloqueos de lectura bloquearán la escritura, pero no bloquearán la lectura. El bloqueo de escritura bloqueará tanto la lectura como la escritura.

4- Análisis de bloqueo de tablas

Si hay un comando, háganos saber qué mesas están bloqueadas y cuánto tiempo están bloqueadas

  • Ver qué mesas están bloqueadas
<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> <span style="color:#0000ff">open</span> tables;
</code></span></span>
  • Cómo analizar bloqueos de tablas

Los bloqueos de tablas en su sistema se pueden analizar examinando las variables de estado table_locks_waited y table_locks_immediate.

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span>  <span style="color:#0000ff">show</span> status <span style="color:#0000ff">like</span> <span style="color:#a31515">'table_locks%'</span>;
<span style="color:#ab5656">+</span><span style="color:#008000">-----------------------+-------+</span>
<span style="color:#ab5656">|</span> Variable_name         <span style="color:#ab5656">|</span> <span style="color:#0000ff">Value</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">-----------------------+-------+</span>
<span style="color:#ab5656">|</span> Table_locks_immediate <span style="color:#ab5656">|</span> <span style="color:#880000">170</span>   <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Table_locks_waited    <span style="color:#ab5656">|</span> <span style="color:#880000">0</span>     <span style="color:#ab5656">|</span>  #越高锁门锁竞争的越激烈
<span style="color:#ab5656">+</span><span style="color:#008000">-----------------------+-------+</span>
<span style="color:#880000">2</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.00</span> sec)
</code></span></span>

Aquí hay dos variables de estado para registrar la situación del bloqueo interno de nivel de tabla de MySQL.Las dos variables se describen a continuación:

  • Table_locks_immediate: el número de bloqueos de nivel de tabla generados, que indica el número de consultas que pueden adquirir bloqueos inmediatamente, y el valor de cada bloqueo inmediato aumenta en 1;
  • Table_locks_waited: el número de esperas causadas por la contención de bloqueo a nivel de tabla (el número de veces que el bloqueo no se puede adquirir inmediatamente y el valor del bloqueo aumenta en 1 cada vez que se espera el bloqueo). Un valor alto indica que hay un problema grave. contención de bloqueo a nivel de tabla ;

Además, la programación de bloqueo de lectura y escritura de MyISAM es escribir primero, por lo que MyISAM no es adecuado para escribir como motor de tabla principal . Porque después de escribir el bloqueo, otros subprocesos no pueden realizar ninguna operación, y una gran cantidad de actualizaciones dificultarán que la consulta obtenga el bloqueo, lo que provocará un bloqueo permanente.

Teoría de bloqueo de 5 filas

Se prefiere el motor de almacenamiento InnoDB, con sobrecarga elevada y bloqueo lento; pueden producirse interbloqueos; la granularidad de bloqueo es la más pequeña, la probabilidad de conflictos de bloqueo es la más baja y la concurrencia es la más alta.

Hay dos grandes diferencias entre InnoDB y MyISAM: una es admitir transacciones (TRANSACCIÓN); la otra es usar bloqueos de nivel de fila .

Dado que los bloqueos de fila admiten transacciones, revise el conocimiento antiguo

  • Transaction (Transacción) y sus propiedades ACID
  • Problemas causados ​​por el procesamiento de transacciones concurrentes
  • nivel de aislamiento de transacciones

Una transacción es una unidad de procesamiento lógico compuesta por un conjunto de sentencias SQL Una transacción tiene los siguientes cuatro atributos, que generalmente se denominan atributos ACID de una transacción:

  • Atomicidad: una transacción es una unidad de operación atómica, y su modificación a los datos se ejecuta por completo o no se ejecuta en absoluto.
  • Coherencia: los datos deben permanecer en un estado coherente cuando comienza y finaliza una transacción. Esto significa que se deben aplicar todas las reglas de datos relevantes a la modificación de la transacción para mantener la integridad de los datos; al final de la transacción, todas las estructuras de datos internas (como índices de árbol B o listas doblemente enlazadas) también deben ser correctas.
  • Aislamiento: el sistema de base de datos proporciona cierto mecanismo de aislamiento para garantizar que las transacciones se ejecuten en un entorno "independiente" que no se vea afectado por operaciones concurrentes externas. Esto significa que el estado intermedio durante el proceso de transacción no es visible para el mundo exterior y viceversa.
  • Persistencia (Durable): Una vez completada la transacción, su modificación de los datos es permanente y se puede mantener incluso si ocurre una falla en el sistema.

Problemas causados ​​por el procesamiento de transacciones concurrentes

  • Actualización perdida
  • Lecturas sucias
  • Lecturas no repetibles (Lecturas no repetibles)
  • Lecturas fantasma

Actualización perdida

El problema de actualización perdida ocurre cuando dos o más transacciones seleccionan la misma fila y luego actualizan esa fila según el valor seleccionado originalmente, ya que cada transacción desconoce la existencia de las otras transacciones; la última actualización sobrescribe el valor creado por la otra. transacción Actualizaciones realizadas por la firma.

Por ejemplo, dos programadores modifican el mismo archivo java. Cada programador cambia independientemente su copia y luego guarda la copia modificada, sobrescribiendo así el documento original. El último editor en guardar una copia de sus cambios sobrescribe los cambios realizados por el programador anterior.

Este problema se puede evitar si otro programador no puede acceder al mismo archivo hasta que otro programador complete y confirme la transacción.

Lecturas sucias

Una transacción está modificando un registro. Antes de que la transacción se complete y envíe, los datos de este registro se encuentran en un estado inconsistente; en este momento, otra transacción también lee el mismo registro. Si no se controla, la segunda transacción Después de leer estos datos "sucios" y procesamiento posterior basado en ellos, se generarán dependencias de datos no comprometidos. Este fenómeno se llama vívidamente "lectura sucia".

En una palabra: la transacción A ha leído los datos modificados pero no enviados por la transacción B y ha realizado operaciones sobre la base de estos datos. En este punto, si se revierte la transacción B, los datos leídos por A no son válidos y no cumplen los requisitos de coherencia. (Tal vez cometí un error y obtuviste los datos incorrectos para trabajar)

Lecturas no repetibles (Lecturas no repetibles)

Un cierto tiempo después de leer algunos datos, una transacción vuelve a leer los datos leídos anteriormente, ¡solo para descubrir que los datos leídos han cambiado o que se han eliminado algunos registros! Este fenómeno se denomina "lectura no repetible".

En una palabra: la transacción A lee los datos modificados enviados por la transacción B, que no cumple con los requisitos de aislamiento.

Lecturas fantasma

Una transacción vuelve a leer los datos recuperados previamente de acuerdo con las mismas condiciones de consulta, pero descubre que otras transacciones han insertado nuevos datos que cumplen con sus condiciones de consulta. Este fenómeno se denomina "lectura fantasma".

En una palabra: la transacción A lee los nuevos datos enviados por la transacción B, que no cumple con los requisitos de aislamiento.

Una palabra más: la lectura fantasma es algo similar a la lectura sucia.

La lectura sucia es la modificación de datos en la transacción B.

La lectura fantasma son datos nuevos en la transacción B.

nivel de aislamiento de transacciones

Las "lecturas sucias", las "lecturas no repetibles" y las "lecturas fantasma" son en realidad problemas de coherencia de lectura de la base de datos, que deben ser resueltos por la base de datos proporcionando un determinado mecanismo de aislamiento de transacciones.

Leer datos: coherencia y efectos secundarios de concurrencia permitidos (nivel de aislamiento) leer consistencia de datos lectura sucia lectura no repetible lectura fantasma
Lectura no confirmada (Lectura no confirmada) El nivel más bajo, que solo puede garantizar que no se leerán los datos dañados físicamente
Comprometido a leer (Leer comprometido) nivel de declaración No
Lectura repetible (Lectura repetible) nivel de transacción No No
serializable nivel más alto, nivel de transacción No No No

Cuanto más estricto sea el aislamiento de transacciones de la base de datos, menores serán los efectos secundarios de la concurrencia, pero mayor será el precio pagado, porque el aislamiento de transacciones esencialmente hace que las transacciones se "serialicen" hasta cierto punto, lo que obviamente es contradictorio con la "concurrencia". Al mismo tiempo, diferentes aplicaciones tienen diferentes requisitos para la coherencia de lectura y el aislamiento de transacciones. Por ejemplo, muchas aplicaciones no son sensibles a las "lecturas no repetibles" y las "lecturas fantasma", y pueden estar más preocupadas por la capacidad de acceder a los datos simultáneamente. .

A menudo, vea el nivel de aislamiento de transacciones de la base de datos actual: muestre variables como 'tx_isolation';

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> variables <span style="color:#0000ff">like</span> <span style="color:#a31515">'tx_isolation'</span>;
<span style="color:#ab5656">+</span><span style="color:#008000">---------------+-----------------+</span>
<span style="color:#ab5656">|</span> Variable_name <span style="color:#ab5656">|</span> <span style="color:#0000ff">Value</span>           <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">---------------+-----------------+</span>
<span style="color:#ab5656">|</span> tx_isolation  <span style="color:#ab5656">|</span> REPEATABLE<span style="color:#ab5656">-</span>READ <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">---------------+-----------------+</span>
<span style="color:#880000">1</span> <span style="color:#a31515">row</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span>, <span style="color:#880000">1</span> warning (<span style="color:#880000">0.00</span> sec)
</code></span></span>

MySQL tiene por defecto el nivel de transacción y puede ocurrir una lectura fantasma.

Explicación de la caja de bloqueo de 6 filas

SQL nuevo

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">#使用INNODB引擎
<span style="color:#0000ff">CREATE</span> <span style="color:#0000ff">TABLE</span> test_innodb_lock (a <span style="color:#a31515">INT</span>(<span style="color:#880000">11</span>),b <span style="color:#a31515">VARCHAR</span>(<span style="color:#880000">16</span>))ENGINE<span style="color:#ab5656">=</span>INNODB;

<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">1</span>,<span style="color:#a31515">'b2'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">3</span>,<span style="color:#a31515">'3'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">4</span>, <span style="color:#a31515">'4000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">5</span>,<span style="color:#a31515">'5000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">6</span>, <span style="color:#a31515">'6000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">7</span>,<span style="color:#a31515">'7000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">8</span>, <span style="color:#a31515">'8000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">9</span>,<span style="color:#a31515">'9000'</span>);
<span style="color:#0000ff">INSERT</span> <span style="color:#0000ff">INTO</span> test_innodb_lock <span style="color:#0000ff">VALUES</span>(<span style="color:#880000">1</span>,<span style="color:#a31515">'b1'</span>);

<span style="color:#0000ff">CREATE</span> INDEX test_innodb_a_ind <span style="color:#0000ff">ON</span> test_innodb_lock(a);
<span style="color:#0000ff">CREATE</span> INDEX test_innodb_lock_b_ind <span style="color:#0000ff">ON</span> test_innodb_lock(b);
</code></span></span>

resultado de la operación

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">select</span> <span style="color:#ab5656">*</span> <span style="color:#0000ff">from</span> test_innodb_lock;
<span style="color:#ab5656">+</span><span style="color:#008000">------+------+</span>
<span style="color:#ab5656">|</span> a    <span style="color:#ab5656">|</span> b    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">------+------+</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">1</span> <span style="color:#ab5656">|</span> b2   <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">3</span> <span style="color:#ab5656">|</span> <span style="color:#880000">3</span>    <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">4</span> <span style="color:#ab5656">|</span> <span style="color:#880000">4000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">5</span> <span style="color:#ab5656">|</span> <span style="color:#880000">5000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">6</span> <span style="color:#ab5656">|</span> <span style="color:#880000">6000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">7</span> <span style="color:#ab5656">|</span> <span style="color:#880000">7000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">8</span> <span style="color:#ab5656">|</span> <span style="color:#880000">8000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">9</span> <span style="color:#ab5656">|</span> <span style="color:#880000">9000</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span>    <span style="color:#880000">1</span> <span style="color:#ab5656">|</span> b1   <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">------+------+</span>
<span style="color:#880000">9</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.00</span> sec)

mysql<span style="color:#ab5656">></span> <span style="color:#0000ff">show</span> index <span style="color:#0000ff">from</span> test_innodb_lock;
</code></span></span>

imagen-20210515162559758

Demostración básica del bloqueo de filas (dos clientes actualizan el mismo registro de filas)

Lea lo que escribí , porque los datos en la sesión 1 no se enviaron, por lo que los datos más recientes no se pueden leer en la sesión 2; se pueden comparar: publicar en Momentos, definitivamente puedo verlo por primera vez, pero otros El usuario no puede garantizar que la actualización llegará a la primera y debe retrasarse unos segundos (sistema distribuido), lo que no puede satisfacer una consistencia sólida;

Cuando dos sesiones modifican la misma fila de datos, las posteriores se bloquearán; cuando la modificación no sea la misma fila de datos, no se interferirán entre sí (el camino va hacia el cielo en cada lado ).

Suplemento de preguntas y respuestas de demostración de bloqueo de 7 filas

Session2 también necesita volver a confirmar para actualizar los datos más recientes: la razón es que la confirmación de session2 también se establece en 0. Si la confirmación predeterminada de MySQL = 1, los datos más recientes se pueden obtener durante la lectura.

La falla del índice 8 hace que el bloqueo de fila se bloquee en la tabla

Actualizar bloqueos de fila no indexados a bloqueos de tabla

9- Peligro de bloqueo de espacio

¿Qué es un bloqueo de espacio?

Cuando usamos condiciones de rango en lugar de condiciones de igualdad para recuperar datos y solicitar bloqueos compartidos o exclusivos, InnoDB bloqueará los elementos de índice de los registros de datos existentes que cumplan las condiciones Para los registros cuyos valores clave están dentro del rango de condición pero no no existe , llamado "Brecha (GAP)".

InnoDB también bloqueará esta "brecha". Este mecanismo de bloqueo es el llamado bloqueo de brecha (Next-Key lock). En el caso anterior, no hay registro de a=2, pero MySQL aún bloquea este registro. .

【dañar】

Porque si la consulta pasa por la búsqueda de rango durante la ejecución, bloqueará todos los valores de clave de índice en todo el rango, incluso si el valor de clave no existe.

Gap lock tiene una debilidad relativamente fatal, es decir, después de bloquear un rango de valores clave, incluso algunos valores clave inexistentes se bloquearán inocentemente, lo que resultará en la incapacidad de insertar cualquier dato dentro del rango de valores clave bloqueado durante el bloqueo. En algunos escenarios, esto puede ser muy perjudicial para el rendimiento.

10-Pregunta de la entrevista: Cómo bloquear una fila

Entrevista: ¿Cómo bloquear una fila? empezar... comprometerse

Espero que estos datos no puedan ser modificados por otros subprocesos cuando operen estos datos.

11- Resumen de bloqueos de fila y bloqueos de página

Debido a que el motor de almacenamiento Innodb implementa el bloqueo a nivel de fila, aunque la pérdida de rendimiento causada por la implementación del mecanismo de bloqueo puede ser mayor que la del bloqueo a nivel de tabla, es muy superior al nivel de tabla de MyISAM en términos de capacidades generales de procesamiento concurrente. .cerrado Cuando la concurrencia del sistema es alta, el rendimiento general de Innodb tendrá ventajas obvias en comparación con MylISAM.

Sin embargo, el bloqueo a nivel de fila de Innodb también tiene su lado frágil: cuando lo usamos incorrectamente, el rendimiento general de Innodb puede no solo ser superior al de MyISAM, sino incluso peor. (Uso inadecuado, los bloqueos de fila se convierten en bloqueos de tabla)

①Análisis de bloqueo de fila

Cómo analizar bloqueos de fila

Analice la contención de bloqueo de filas en su sistema examinando la variable de estado lnnoDB_row_lock

<span style="color:#2c2c2c"><span style="background-color:#ffffff"><code class="language-sql">mysql<span style="color:#ab5656">></span>  <span style="color:#0000ff">show</span> status <span style="color:#0000ff">like</span> <span style="color:#a31515">'innodb_row_lock%'</span>;
<span style="color:#ab5656">+</span><span style="color:#008000">-------------------------------+--------+</span>
<span style="color:#ab5656">|</span> Variable_name                 <span style="color:#ab5656">|</span> <span style="color:#0000ff">Value</span>  <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">-------------------------------+--------+</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_current_waits <span style="color:#ab5656">|</span> <span style="color:#880000">0</span>      <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_time          <span style="color:#ab5656">|</span> <span style="color:#880000">128380</span> <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_time_avg      <span style="color:#ab5656">|</span> <span style="color:#880000">32095</span>  <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_time_max      <span style="color:#ab5656">|</span> <span style="color:#880000">50618</span>  <span style="color:#ab5656">|</span>
<span style="color:#ab5656">|</span> Innodb_row_lock_waits         <span style="color:#ab5656">|</span> <span style="color:#880000">4</span>      <span style="color:#ab5656">|</span>
<span style="color:#ab5656">+</span><span style="color:#008000">-------------------------------+--------+</span>
<span style="color:#880000">5</span> <span style="color:#0000ff">rows</span> <span style="color:#0000ff">in</span> <span style="color:#0000ff">set</span> (<span style="color:#880000">0.01</span> sec)
</code></span></span>

La descripción de cada cantidad de estado es la siguiente:

  • Innodb_row_lock_current_waits: el número actualmente en espera de bloqueos;
  • Innodb_row_lock_time: el tiempo total bloqueado desde el inicio del sistema hasta ahora;
  • Innodb_row_lock_time_avg: el tiempo promedio de espera cada vez;
  • Innodb_row_lock_time_max: el tiempo que lleva esperar el tiempo más frecuente desde el inicio del sistema hasta ahora;
  • Innodb_row_lock_waits: el número total de esperas desde que se inició el sistema;

Para estas cinco variables de estado, las más importantes son

  • Innodb_row_lock_time_avg (tiempo medio de espera)
  • lnnodb_row_lock_waits (número total de esperas)
  • lnnodb_row_lock_time (tiempo de espera total) estos tres elementos.

Especialmente cuando el número de esperas es alto y el tiempo de espera no es pequeño cada vez, necesitamos analizar por qué hay tantas esperas en el sistema y luego proceder a especificar un plan de optimización basado en los resultados del análisis (se puede usar showProfile ) .

②Sugerencias de optimización

  • En la medida de lo posible, toda la recuperación de datos se realiza a través del índice para evitar la actualización de bloqueos de fila no indexados a bloqueos de tabla.
  • Índices de diseño razonable para minimizar el alcance de los bloqueos
  • Menos condiciones de búsqueda posibles para evitar bloqueos de espacio
  • Intente controlar el tamaño de la transacción, reduzca la cantidad de recursos bloqueados y el tiempo
  • Aislamiento de transacciones de bajo nivel posible
  • ¡El tipo varchar debe agregarse con comillas simples!

③bloqueo de página

La sobrecarga y el tiempo de bloqueo están entre bloqueos de tabla y bloqueos de fila; habrá interbloqueos; la granularidad de bloqueo está entre bloqueos de tabla y bloqueos de fila, y la simultaneidad es promedio. (Infórmate)

Supongo que te gusta

Origin blog.csdn.net/m0_60961651/article/details/132272847
Recomendado
Clasificación