MySQL (Análisis de InnoDB): --- Bloqueo (crecimiento propio y bloqueo, clave externa y bloqueo)

1. Crecimiento propio y bloqueo

  • El crecimiento personal es un atributo muy común en las bases de datos y también es el método de clave principal preferido por los desarrolladores.

Contador auto-creciente

  • En la estructura de memoria de InnoDB, cada tabla que contiene un valor del crecimiento tiene un contador de autoincremento ( contador de Auto-INCREMENTO ), cuando la tabla que contiene el contador desde el tiempo de crecimiento de la operación de inserción, el contador se inicializa
  • Ejecute la siguiente declaración para obtener el valor del contador
select max(auto_inc_col) from t for update;

Bloqueo AUTO-INC

  • La operación de inserción se asignará a la columna de aumento automático sumando 1 al valor del contador de aumento automático . Esta implementación se llama Bloqueo AUTO-INC.
  • En realidad, este tipo de bloqueo utiliza un mecanismo de bloqueo de tabla especial . Para mejorar el rendimiento de la inserción, el bloqueo no se libera después de que se completa una transacción, sino inmediatamente después de que se completa la instrucción SQL para la inserción de valor auto-creciente.
  • Aunque AUTO-INC Locking mejora la eficiencia de las inserciones simultáneas hasta cierto punto, todavía existen algunos problemas de rendimiento :
    • En primer lugar, el rendimiento de inserciones simultáneas para columnas con valores que aumentan automáticamente es deficiente y la transacción debe esperar a que se complete la inserción anterior (aunque no es necesario esperar a que se complete la transacción)
    • En segundo lugar, la inserción de una gran cantidad de datos para INSERT ... SELECT afectará el rendimiento de la inserción , porque la inserción en otra transacción se bloqueará

parámetro innodb_autoinc_lock_mode

  • A partir de MySQL 5.1.22 , InnoDB proporciona un mecanismo de implementación de incremento automático de mutex ligero , que mejora en gran medida el rendimiento de la inserción de valor de incremento automático
  • Y a partir de esta versión, el motor de almacenamiento InnoDB proporciona este parámetro para controlar el modo de crecimiento propio . El valor predeterminado de este parámetro es 1

  • Antes de introducir la implementación del crecimiento personal , debe clasificar los tipos de inserción de crecimiento personal, como se muestra en la siguiente tabla :

  • Hay 3 valores válidos (0 , 1 , 2) para este parámetro , que se describen a continuación:

La diferencia entre InnoDB y MyIASM

  • Además, debe tenerse en cuenta que la realización del crecimiento personal en InnoDB es diferente de MyIASM. MyIASM es un diseño de bloqueo de tabla , y el crecimiento personal no necesita considerar inserciones simultáneas.

  • Por lo tanto, bajo la arquitectura de replicación de usar el motor de almacenamiento InnoDB en el maestro y el motor de almacenamiento MyIASM en el esclavo, los usuarios deben considerar estas dos situaciones

  • Además, en InnoDB, la columna de crecimiento automático debe ser un índice y debe ser la primera columna del índice . Si no es la primera columna, MySQL generará una excepción, pero el motor de almacenamiento MyIASM no tiene esta restricción . Como se muestra abajo

create table t(
    a int auto_increment,
    b int,
    key(b,a)
)engine=InnoDB;

create table t2(
    a int auto_increment,
    b int,
    key(b,a)
)engine=MyISAM;

Dos, llaves extranjeras y cerraduras

  • Las claves externas se utilizan principalmente para la verificación de restricciones de integridad referencial
  • En InnoDB, para una columna de clave externa, si la columna no está indexada explícitamente, InnoDB le agregará automáticamente un índice, porque esto puede evitar el bloqueo -esto es mejor que la base de datos Oracle, la base de datos Oracle no lo hará automáticamente Para agregar un índice, el el usuario debe agregarlo manualmente, lo que también conduce a un posible punto muerto en Oracle

Cómo funcionan las llaves y cerraduras externas

  • Para la inserción o actualización de valores de clave externa, primero debe consultar los registros en la tabla principal , es decir , la tabla principal SELECT
  • Pero para la operación SELECT de la tabla principal, no se usa el método de lectura consistente sin bloqueo , porque esto causará inconsistencia en los datos. Por lo tanto , el método SELECT ... LOCK IN SHARE MODE se usa en este momento , es decir, activamente agregue uno al candado S de la tabla principal. Si ya hay un bloqueo X en la tabla principal en este momento, la operación en la tabla secundaria se bloqueará

Caso de demostración

  • Cree una tabla principal principal, inserte 3 registros en ella
  • create table parent(
        id int primary key
    );
     
    insert into parent select 1;
    insert into parent select 2;
    insert into parent select 3;
     
    select * from parent;

  • Crea un niño de mesa infantil. El segundo campo de la tabla secundaria es una clave externa, que apunta al campo de identificación de la tabla principal
create table child(
    child_id int primary key,
    parent_id int not null,
    foreign key(parent_id) references parent(id)
);
 
insert into child select 1,1;
 
select * from child;

  • Ahora abra la sesión A, elimine el registro con la identificación 3 en la tabla principal en la sesión A (en este momento agregue un candado X al registro con la identificación 3 ), pero la transacción no está confirmada:
begin;
 
delete from parent where id=3;

  • En este momento, al abrir una sesión B, quiero insertar una declaración (más bloqueo S) en la tabla secundaria en la sesión B , ya que el segundo campo es una clave externa, entonces esta declaración se bloqueará (porque el padre es el Se ha agregado el campo de identificación de bloqueo 3 X), puede ver en la imagen que la declaración de inserción está bloqueada
begin;
 
insert into child select 2,3;

  • Imagínese algo (solo hipotético, no cierto) : si está utilizando una lectura constante sin bloqueo, la sesión B leerá un registro con id = 3 en la tabla principal. Habrá inconsistencias en los datos de las tablas principal y secundaria
  • Ahora consulte la tabla Innodb_locks en la sesión C , verá los siguientes resultados :
select * from information_schema.innodb_locks\G

 

 

  • Después de un tiempo, volvemos a mirar la sesión B , podemos ver que el tiempo de espera para el bloqueo se agotó y la declaración no se pudo insertar.

 

  • Todo el proceso se muestra en la siguiente figura:

 

  • Nota : Después de que se envíe nuestra sesión A, la declaración de inserción de la sesión B también fallará, porque la sesión A ha eliminado el campo con la identificación 3 en la tabla principal, por lo que la inserción de la sesión B fallará, lo que garantiza la relación entre el padre y tablas secundarias Integridad y coherencia de los datos

 

El contenido está tomado de "Mysql Technology Insider --- InnoDB Storage Engine"

 

 

 

 

 

 

Supongo que te gusta

Origin blog.csdn.net/m0_46405589/article/details/113737485
Recomendado
Clasificación