Tabla de contenido
- 1. La necesidad de revertir las transacciones
- 2. Identificación de la transacción
- 3. Formato del registro de deshacer
- 4. Estructura general de la lista enlazada
- Cinco, página FIL_PAGE_UNDO_LOG
- Seis, Deshacer lista enlazada de página
- 7. El proceso de escritura específico del registro de deshacer
- 8. Reutilice la página Deshacer
- Nueve, segmento de reversión
-
- 9.1 El concepto de segmento rollback
- 9.2 Solicitar la lista enlazada de la página Deshacer desde el segmento de reversión
- 9.3 Múltiples segmentos de reversión
- 9.4 Clasificación de los segmentos de retroceso
- 9.5 Proceso detallado de asignación de la lista enlazada de la página Deshacer para la transacción
- 9.6 Configuración relacionada con el segmento de reversión
1. La necesidad de revertir las transacciones
Cuando aprendimos sobre los asuntos antes, dijimos que los asuntos deben estar garantizados 原子性
, es decir 事务中的操作要么全做,要么全不做
. Pero a veces habrá algunas situaciones en la transacción, tales como:
情况一:
Se pueden encontrar varios errores durante la ejecución de la transacción, como errores en el propio servidor, errores del sistema operativo o incluso errores causados por cortes repentinos de energía.- Caso 2: los programadores pueden ingresar declaraciones manualmente durante la ejecución de la transacción
ROLLBACK
para finalizar la ejecución de la transacción actual
Las dos situaciones anteriores harán que la transacción finalice a la mitad de la ejecución, pero es posible que se hayan modificado muchas cosas durante el proceso de ejecución de la transacción. Para garantizar la transacción, debemos volver a cambiar las cosas al estado original. Este proceso se 原子性
llama 回滚
(nombre en inglés: rollback
), esto puede crear una falsa impresión: esta transacción no parece hacer nada, por lo que cumple con los requisitos de atomicidad.
Es como jugar a las cartas con nuestros amigos cuando éramos jóvenes. La carta de arrepentimiento es una operación de retroceso muy típica, por ejemplo, si juegas dos cartas de tres, la operación correspondiente a la carta de arrepentimiento es sacar las dos cartas de tres. La reversión en la base de datos es similar a la tarjeta de arrepentimiento, inserta un registro y la operación de reversión corresponde a la eliminación de este registro, actualiza un registro y la operación de reversión corresponde a la actualización del registro al valor anterior, si un registro se elimina, la operación de reversión corresponde a insertar el registro nuevamente. parece tan simple
A partir de la descripción anterior, ya podemos sentir vagamente que siempre que queramos realizar cambios en un registro (los cambios aquí pueden referirse a INSERT
, DELETE
, UPDATE
), debemos anotar a mano todo lo necesario para la reversión. Por ejemplo:
- Cuando inserta un registro, debe al menos escribir el valor de la clave principal de este registro, y luego, cuando revierte, solo necesita eliminar el registro correspondiente al valor de la clave principal.
- Elimina un registro, al menos anota el contenido de este registro, de modo que cuando retroceda más tarde, pueda insertar los registros compuestos por estos contenidos en la tabla
- Si modifica un registro, debe registrar al menos el valor anterior antes de modificar este registro, de modo que pueda actualizar este registro al valor anterior cuando retroceda más tarde.
Estas cosas registradas por la base de datos para la reversión se denominan registros de deshacer, y el nombre en inglés undo log
se llama undo日志
. Una cosa a tener en cuenta aquí es que dado que la operación de consulta (SELECCIONAR) no modifica ningún registro de usuario, no es necesario registrar el registro correspondiente cuando se ejecuta la operación de consulta undo
. En realidad InnoDB
, undo
el registro no es tan simple como lo dijimos anteriormente, y el formato del registro generado por diferentes tipos de operaciones undo
también es diferente, pero pongamos estos detalles que son fáciles de confundir por un tiempo. cuál es la identificación de la transacción
2. Identificación de la transacción
2.1 Cuándo asignar un id a una transacción
Como dijimos anteriormente cuando aprendimos sobre la introducción a las transacciones, una transacción puede ser una 只读事务
o una 读写事务
:
- Podemos
START TRANSACTION READ ONLY
abrir uno a través de una declaración只读事务
En una transacción de solo lectura, no podemos agregar, eliminar o modificar tablas ordinarias (tablas a las que también pueden acceder otras transacciones), pero podemos agregar, eliminar y modificar tablas temporales. - Podemos
START TRANSACTION READ WRITE
iniciar una transacción a través de una declaración读写事务
, o usar una declaración para abrir una transacción por defecto.En la transacción de lectura y escritura, podemos realizar operaciones de adición, eliminación, modificación y consulta en la tablaBEGIN
.START TRANSACTION
读写事务
增
Si las operaciones , 删
, y se realizan en una tabla durante la ejecución de una transacción 改
, InnoDB
el motor de almacenamiento le asignará una única 事务id
, de la siguiente manera:
-
Para
只读事务
la transacción, solo cuando realiza operaciones de agregar, eliminar y modificar en una tabla temporal creada por un usuario por primera vez, asignará una identificación de transacción a esta transacción; de lo contrario, no asignará una identificación de transacción小提示:
Como dijimos anteriormente,EXPLAIN
al ejecutar y analizar un plan de consulta para una declaración de consulta determinada, a veces verá un indicador de uso temporal en la columna Extra, lo que indica que se usará una tabla temporal interna al ejecutar la declaración de consulta.CREATE TEMPORARY TABLE
Esta supuesta tabla temporal interna no es la misma que la tabla temporal del usuario que creamos manualmente. Cuando se revierte la transacción, no es necesario revertir la tabla temporal interna utilizada en la ejecución de la declaración SELECT . -
Por
读写事务
ejemplo, se asignará una identificación de transacción a una transacción solo cuando realice operaciones de agregar, eliminar o modificar en una tabla (incluidas las tablas temporales creadas por los usuarios) por primera vez; de lo contrario, no asignará una identificación de transacción.
A veces, aunque hemos habilitado uno 读写事务
, la transacción está llena de declaraciones de consulta y no se ejecutan declaraciones de adición, eliminación o modificación, lo que significa que a esta transacción no se le asignará una identificación de transacción.
Después de hablar durante mucho tiempo, ¿cuál es el uso de la identificación de transacción? Esto se mantendrá en secreto por ahora, y hablaré en detalle paso a paso más adelante. Ahora solo sepa que a una transacción se le asignará una identificación de transacción única solo cuando la transacción realice cambios en los registros de la tabla.
2.2 Cómo se genera la identificación de la transacción
Esto 事务id
es esencialmente un número, y su estrategia de asignación es row_id
aproximadamente la misma que la estrategia de asignación para columnas ocultas (columnas que InnoDB crea automáticamente cuando el usuario no crea una clave principal y una clave ÚNICA para la tabla) que mencionamos anteriormente. es como sigue:
- El servidor mantendrá una variable global en la memoria. Siempre que sea necesario asignar una transacción
事务id
, el valor de la variable se asignará a la transacción como la identificación de la transacción, y la variable se incrementará en 1 - Siempre que el valor de esta variable
256
sea un múltiplo de , el valor de esta variable se actualizará a unMax Trx ID
atributo llamado en la página número 5 del espacio de tabla del sistema. El占用8个字节
espacio de almacenamiento de este atributo - Cuando el sistema se reinicie la próxima vez, cargará
Max Trx ID
los atributos mencionados anteriormente en la memoria, agregará 256 al valor y lo asignará a la variable global que mencionamos anteriormente (porque el valor de la
variable ser mayor queMax Trx ID
el valor del atributo)
Esto asegura que el valor de identificación de la transacción asignado en todo el sistema sea un número creciente. La transacción a la que se le asigna una identificación primero obtiene una identificación de transacción más pequeña, y la transacción a la que se le asigna una identificación luego obtiene una identificación de transacción más grande.
2.3 columna oculta trx_id
Cuando aprendimos InnoDB
el formato de fila de registro, enfatizamos que además de guardar los datos completos del usuario, los registros del índice agrupado agregarán automáticamente una columna oculta llamada , trx_id
si roll_pointer
el usuario es un usuario 没有在表中定义主键以及UNIQUE键
, una row_id
columna oculta llamada Lista. Entonces, la estructura real de un registro en una página se ve así:
Las columnas que contiene trx_id
son bastante fáciles de entender y se encuentran justo donde se encuentra una declaración que realiza cambios en el registro del índice agrupado 事务对应的事务id
(los cambios aquí pueden ser INSERT
, DELETE
u UPDATE
operaciones). En cuanto a roll_pointer
las columnas ocultas, las analizaremos más adelante~
3. Formato del registro de deshacer
Para darse cuenta de la atomicidad de la transacción, el motor de almacenamiento necesita escribir primero el registro correspondiente InnoDB
cuando realmente realiza 增
, 删
o un registro. Generalmente cada vez que se realiza un cambio en un registro corresponde a un log, pero en algunas operaciones de actualización de registros también puede corresponder a 2 logs, de los cuales hablaremos más adelante. Durante la ejecución de una transacción, pueden existir varios registros, es decir, se deben registrar muchos registros correspondientes, y estos registros se numerarán desde el principio, es decir, se denominan No. 0 undo log, No. 1 undo log según el orden de generación No. 1 undo log, ..., No. n undo log, etc., este número también se llama .改
undo
undo
undo
新增
删除
更新
undo
undo
0
undo no
Estos registros de deshacer se registran en páginas de tipo FIL_PAGE_UNDO_LOG
(el número hexadecimal correspondiente es 0x0002
, los estudiantes que hayan olvidado cuál es el tipo de página, deben volver atrás y mirar los capítulos anteriores). Estas páginas se pueden asignar desde el espacio de tabla del sistema o desde un espacio de tabla dedicado a almacenar registros de deshacer, que es la denominada undo tablespace
asignación interna. Sin embargo, hablaremos sobre cómo asignar undo
páginas para almacenar registros más adelante. Ahora echemos un vistazo a qué tipo de undo
registros se generarán mediante diferentes operaciones ~ Para el desarrollo fluido de la historia, primero creemos una demo18
tabla llamada:
mysql> CREATE TABLE demo18 (
id INT NOT NULL,
key1 VARCHAR(100),
col VARCHAR(100),
PRIMARY KEY (id),
KEY idx_key1 (key1)
)Engine=InnoDB CHARSET=utf8;
Query OK, 0 rows affected, 1 warning (0.06 sec)
Hay 3 columnas en esta tabla, entre las cuales id
la columna es la clave principal, hemos key1
creado una para la columna 二级索引
y la columna col es una columna ordinaria. Como mencionamos en el diccionario de datos que presentamos anteriormente InnoDB
, a cada tabla se le asignará una única table id
, podemos verificar a qué corresponde una determinada tabla a través de las tablas information_schema
en la base de datos del sistema , ahora veamos a cuánto corresponde :innodb_tables
table id
demo18
table id
mysql> SELECT * FROM information_schema.innodb_tables WHERE name = 'testdb/demo18';
+----------+---------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
| TABLE_ID | NAME | FLAG | N_COLS | SPACE | ROW_FORMAT | ZIP_PAGE_SIZE | SPACE_TYPE | INSTANT_COLS | TOTAL_ROW_VERSIONS |
+----------+---------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
| 1128 | testdb/demo18 | 33 | 6 | 66 | Dynamic | 0 | Single | 0 | 0 |
+----------+---------------+------+--------+-------+------------+---------------+------------+--------------+--------------------+
1 row in set (0.00 sec)
Como se puede ver en los resultados de la consulta, demo18
la tabla corresponde table id
a 1128
, primero recuerde este valor, lo usaremos más adelante
3.1 El registro de deshacer correspondiente a la operación INSERTAR
Como dijimos antes, cuando insertamos un registro en la tabla, habrá una distinción entre 乐观插入
y 悲观插入
, pero no importa cómo lo insertes, el resultado final es que este registro se coloca en una página de datos. Si desea revertir la operación de inserción, simplemente elimine este registro, es decir, al escribir el undo
registro correspondiente, registre principalmente la información de la clave principal de este registro. Por lo tanto, InnoDB
se diseña un registro TRX_UNDO_INSERT_REC
de tipo undo
, y su estructura completa se muestra en la siguiente figura:
Según el diagrama, destacamos algunos puntos:
-
undo no
Sí en una transacción从0开始递增
, es decir, mientras la transacción no esté comprometida, cada vez que se genere un registro de deshacer, el no deshacer del registro aumentará en 1. -
Si la clave principal en el registro contiene solo una columna, solo necesita registrar la suma ocupada por la columna en el tipo
TRX_UNDO_INSERT_REC
de registro, y si la clave principal en el registro contiene , entonces todos los ocupados deben registrarse (en el figura representa la columna ocupada El tamaño del espacio de almacenamiento representa el valor real de la columna).undo
存储空间大小
真实值
多个列
每个列
存储空间大小和对应的真实值
len
value
小提示:
Cuando insertamos un registro en una tabla, en realidad necesitamos insertar un registro en el índice agrupado y en todos los índices secundarios. Sin embargo, al grabar registros de deshacer, solo debemos considerar la situación al insertar registros en el índice agrupado porque, de hecho, los registros del índice agrupado y los registros del índice secundario tienen una correspondencia uno a uno. operación, solo necesitamos conocer la información de la clave principal de este registro
, y luego realizar la operación de eliminación correspondiente de acuerdo con la información de la clave principal. Cuando se realiza la operación de eliminación, los registros correspondientes en todos los índices secundarios también se eliminarán. Los registros de deshacer correspondientes a la operación ELIMINAR y la operación ACTUALIZAR que se mencionan más adelante también son para los registros del índice agrupado y no lo enfatizaremos más adelante.
Ahora insertamos dos registros en demo18:
mysql> BEGIN; # 显式开启一个事务,假设该事务的id为100
Query OK, 0 rows affected (0.00 sec)
mysql> # 插入两条记录
mysql> INSERT INTO demo18(id, key1, col) VALUES (1, 'AWM', '狙击枪'), (2, 'M416', '步枪');
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
Debido a que la clave primaria del registro contiene solo una columna, solo necesitamos registrar la longitud ( ) y el espacio de almacenamiento que ocupa la columna para insertarla en el registro id
en el registro correspondiente . En este ejemplo, se insertan dos registros, por lo que se generarán dos registros de tipo :undo
id
id列的类型为INT,INT类型占用的存储空间长度为4个字节
真实值
TRX_UNDO_INSERT_REC
undo
- El primer
undo
registroundo no
es0
, la longitud del espacio de almacenamiento ocupado por la clave principal del registro es4
, y el valor real es1
. Dibuja un esquema como este:
- En el segundo
undo
registro , la longitud del espacio de almacenamiento ocupado por la clave principal del registro es y el valor real es . Dibuja un esquema como este:undo no
1
4
2
En comparación con el primer artículo undo日志
, undo no
hay 主键各列信息
una diferencia.
El significado de la columna oculta roll_pointer
Es hora de develar roll_pointer
el verdadero velo. Este 7
campo que ocupa 3 bytes en realidad no tiene ningún misterio. Es esencialmente un puntero al registro correspondiente undo日志的一个指针
. demo18
Por ejemplo, insertamos un registro en la tabla de arriba 2
, y cada registro tiene su correspondiente undo日志
. Los registros se almacenan en FIL_PAGE_INDEX
páginas de tipo (es decir, las páginas de datos de las que hemos estado hablando antes) y undo
los registros se almacenan en FIL_PAGE_UNDO_LOG
páginas de tipo . El efecto se muestra en la figura:
También se puede ver de manera más intuitiva a partir de la figura que roll_pointer
la esencia es un puntero al registro correspondiente al registro undo
. roll_pointer
Sin embargo, el significado específico de cada byte de estos 7 bytes undo
se explicará en detalle después de que hablemos sobre cómo asignar páginas para almacenar registros ~
3.2 Undo log correspondiente a la operación DELETE
Sabemos que los registros insertados en la página formarán next_record
una lista enlazada unidireccional de acuerdo con los atributos en la información del encabezado del registro. A esta lista enlazada la llamamos lista enlazada de registros normales, como dijimos antes cuando hablábamos de la estructura de la página de datos. , registros eliminados De hecho, también se formará una lista vinculada de acuerdo con los atributos en la información del encabezado del registro next_record
, pero en esta lista vinculada 记录占用的存储空间可以被重新利用
, por lo que esta lista vinculada también se llama 垃圾链表
. PageHeader
La sección tiene un PAGE_FREE
atributo llamado , que apunta al nodo principal en la lista de elementos no utilizados que consta de registros eliminados. Para el buen desarrollo de la historia, primero dibujemos una imagen, suponiendo que la distribución de registros en una determinada página en este momento es así (este no es un demo18
registro en la tabla, sino solo un ejemplo que citamos al azar):
Para resaltar el tema, en esta versión simplificada del diagrama esquemático, solo mostramos delete_mask
las banderas de los registros. En la figura se puede ver que 正常记录链表中包含了3条正常记录
, la lista enlazada basura contiene 2条已删除记录
, y el espacio de almacenamiento ocupado por estos registros en la lista enlazada basura se puede reutilizar. Page Header
El valor de la propiedad de la parte de la página PAGE_FREE
representa un puntero al nodo principal de la lista de elementos no utilizados. Suponiendo que vamos a utilizar DELETE
la declaración 正常记录链表
para eliminar el último registro en , de hecho, el proceso de eliminación debe pasar por dos etapas:
-
Fase 1: Solo
delete_mask
poner el bit de identificación del registro a1
, y no modificar los demás (de hecho, se modificarán los valores de estas columnas ocultas del registrotrx_id
)roll_pointer
. InnoDB llama a esta etapadelete mar
k. Así es como se dibuja el proceso:Se puede ver que el último registro en la lista enlazada de registros normales
delete_mask值被设置为1
no se agrega垃圾链表
. Es decir, el registro está en un estado en este momento中间状态
, y el registro eliminado ha estado en este supuesto estado hasta que se confirma la transacción en la que se confirma la declaración de eliminación中间状态
.小提示:
¿Por qué existe un estado intermedio tan extraño? De hecho, es principalmente para realizar una función llamada MVCC, jaja, la presentaré más adelante. -
Fase 2:
当该删除语句所在的事务提交之后
, habrá专门的线程
un borrado real del registro más adelante. La llamada eliminación real consiste en eliminar el正常记录链表
registro y垃圾链表
agregarlo, y luego ajustar alguna otra información de la página, como la cantidad de registros de usuario en la páginaPAGE_N_RECS
, la posición del último registro insertadoPAGE_LAST_INSERT
, el puntero del nodo principal de la lista de elementos no utilizadosPAGE_FREE
, la cantidad de bytes que se pueden reutilizar en la páginaPAGE_GARBAGE
y alguna información sobre el directorio de la página, etc. InnoDB llama a esta fasepurge
.Una vez
阶段二
completada la ejecución, el registro se elimina realmente. El espacio de almacenamiento ocupado por este registro eliminado también se puede reutilizar. Así es como se dibuja: comparando con la imagen, también debemos prestar atención a un punto, al agregar el registro eliminado a la lista de basura, en realidad modificará el valor del atributo
cuando se agregue .链表的头节点处
PAGE_FREE
小提示:
La parte del encabezado de página de la página tiene un atributo PAGE_GARBAGE, que registra el número total de bytes ocupados por el espacio de almacenamiento reutilizable en la página actual. Siempre que se agregue un registro eliminado a la lista de basura, el valor del atributo PAGE_GARBAGE se agregará al espacio de almacenamiento ocupado por el registro eliminado. PAGE_FREE apunta al nodo principal de la lista de elementos no utilizados, y luego cada vez que se inserta un nuevo registro, primero juzgue si el espacio de almacenamiento ocupado por el registro eliminado representado por el nodo principal al que apunta PAGE_FREE es suficiente para acomodar el registro recién insertado, si no, solicite directamente un nuevo espacio en la página para almacenar este registro (sí, leyó bien, no intentará atravesar toda la lista de basura para encontrar un nodo que pueda acomodar el nuevo registro). Si se puede acomodar, reutilice directamente el espacio de almacenamiento de este registro eliminado y señale PAGE_FREE al siguiente registro eliminado en la lista de elementos no utilizados. Pero aquí hay un problema: si el espacio de almacenamiento ocupado por el registro recién insertado es más pequeño que el espacio de almacenamiento ocupado por el nodo principal de la lista basura, significa que parte del espacio de almacenamiento ocupado por el registro correspondiente al nodo principal no se utiliza Esta parte del espacio se llama el espacio de escombros. ¿No se utilizarían para siempre estos espacios fragmentados? De hecho, no lo es. El tamaño del espacio de almacenamiento ocupado por estos espacios fragmentados se contará en el atributo PAGE_GARBAGE. Estos espacios fragmentados no se reutilizarán hasta que toda la página esté casi agotada. Sin embargo, cuando la página esté casi llena , si inserta otro registro, en este momento, el espacio para un registro completo no se puede asignar en la página. En este momento, primero verificaremos si el espacio combinado de PAGE_GARBAGE y el espacio disponible restante pueden acomodar este registro. Si es posible , InnoDB intentará reorganizar El proceso de reorganización de los registros en la página es abrir primero una página temporal, insertar los registros en la página uno por uno, porque no se generarán fragmentos al insertar en secuencia, y luego copiar el contenido de la página temporal a esta página, para que pueda liberar esos espacios fragmentados (obviamente, reorganizar los registros en la página consume más rendimiento).
De la descripción anterior, también podemos ver que antes de la transacción en la que se confirma la declaración de eliminación, solo pasará por la fase uno, es decir, la delete mark
fase (no necesitamos retroceder después de confirmar, por lo que solo debemos considerar realizando la fase uno de la operación de eliminación afectada por la reversión). InnoDB
Para ello se diseña un TRX_UNDO_DEL_MARK_REC
tipo de bitácora undo
, cuya estructura completa se muestra en la siguiente figura:
Dios mío, hay demasiados atributos en esto ~ (De hecho, el significado de la mayoría de los atributos se ha presentado anteriormente) Sí, de hecho hay muchos, pero no preste atención, si no puede recordar a Don No te fuerces, los estoy enumerando todos aquí para que todos se familiaricen. Me gustaría molestar a todos para que primero superen el trastorno de pánico intensivo y luego busquen los atributos en el registro de este tipo anterior, prestando especial atención a estos puntos TRX_UNDO_DEL_MARK_REC
:undo
-
Antes de operar en un registro
delete mark
, los valores de columna antiguostrx_id
yroll_pointer
ocultos del registro deben registrarse en el registro correspondiente , que es el atributo de sumaundo
que se muestra en nuestra figura . Esto tiene la ventaja de que el registro correspondiente al registro antes de la modificación se puede encontrar a través del registro . Por ejemplo, en una transacción, primero insertamos un registro y luego realizamos una operación de eliminación en el registro. El diagrama esquemático de este proceso es el siguiente:oldtrx_id
old roll_pointer
undo
old roll_pointer
undo
-
Puede verse en la figura que
delete mark
después de ejecutar la operación, suundo
registro correspondiente y el registroINSERT
correspondienteundo
de la operación forman una lista enlazada. Esto es muy interesante. Esta lista enlazada se llama版本链
. Ahora parece que no podemos ver el uso de esta cadena de versiones. Echemos un vistazo más adelante. Después de hablar sobre el registroUPDATE
correspondienteundo
de la operación, esta supuesta cadena de versiones mostrarse lentamente fuera de su lugar contundente. -
A diferencia del log de tipo
TRX_UNDO_INSERT_REC
,undo
el log de tipoTRX_UNDO_DEL_MARK_REC
tieneundo
un索引列各列信息
contenido más, es decir, si una columna está incluida en un índice, su información relacionada debe registrarse en esta索引列各列信息
parte, la llamada información relacionada que incluye la posición de la columna en el registro (indicadopos
por ), el espacio de almacenamiento ocupado por la columna (indicadolen
por ) y el valor real de la columna (indicado porvalue
). Entonces,索引列各列信息
el contenido almacenado es esencialmente<pos, len, value>
una lista de archivos . Esta parte de la información se usa principalmente en中间状态记录
la segunda etapa de la eliminación real después de que se confirma la transacción, es decir, sepurge
usa en la etapa. Cómo usarla puede ignorarse ahora ~
Hemos terminado la introducción, ahora continuamos eliminando un registro en la transacción anterior id
para la transacción, por ejemplo, eliminamos el registro para :100
id
1
mysql> DELETE FROM demo18 WHERE id = 1;
Query OK, 1 row affected (0.01 sec)
delete mark
La estructura del log correspondiente a esta operación undo
es la siguiente:
según esta figura, debemos prestar atención a los siguientes puntos:
-
Porque este registro de deshacer se genera en la transacción con id 100
第3条undo日志,所以它对应的undo no就是2
. -
Al operar sobre el registro
delete mark
,trx_id
el valor de la columna oculta del registro es100
(es decir, la última modificación del registro ocurrida en esta transacción), por lo tanto, complete100
elold trx_id
atributo. Luego, saqueroll_pointer
el valor de la columna oculta del registro y relléneloold roll_pointer
en el atributo, de modo que el registroold roll_pointer
generado cuando se modificó el registro por última vez se pueda encontrar a través del valor del atributo .undo
-
Dado que hay 2 índices en la tabla demo18:
一个是聚簇索引
, uno es二级索引idx_key1
.pos
Siempre que sea una columna incluida en el índice, la posición ( ), el espacio de almacenamiento ocupado (len
) y el valor real ( ) de esta columna en el registrovalue
deben almacenarse en el registro de deshacer.-
Para la clave principal, solo hay una
id
columna y la información relevante almacenada en el registro de deshacer es:-
pos
:id
La columna es la clave primaria, es decir, se registra第一个列
, y su valor pos correspondiente es 0. pos toma 1 byte para almacenar. -
len
: El tipo de la columna id es INT, ocupando 4 bytes, por lo que el valor de len es 4. len ocupa 1 byte para almacenar. -
value
: El valor de la columna id en el registro eliminado es 1, es decir, el valor del valor es 1. el valor tarda 4 bytes en almacenarse. -
Haz un dibujo para demostrarlo así:
-
Entonces, para
id
la columna, el resultado de almacenamiento final es <0, 4, 1
>, y el espacio de almacenamiento ocupado al almacenar esta información es1 + 1 + 4 = 6个字节
.
-
-
Para
idx_key1
, solo hay unakey1
columna, yundo
la información relevante almacenada en el registro es:-
pos
: La columna key1 se organiza después de la columna id, la columna trx_id y la columna roll_pointer, y su valor pos correspondiente3
. pos toma 1 byte para almacenar. -
len
: El tipo de la columna key1 es VARCHAR(100), y se utiliza el conjunto de caracteres utf8. El contenido de almacenamiento real del registro eliminado es AWM, por lo que ocupa un total de 3 bytes, es decir, el valor de len es 3 . len ocupa 1 byte para almacenar. -
value
: El valor de la columna clave1 en el registro eliminado es AWM, es decir, el valor del valor es AWM. el valor tarda 3 bytes en almacenarse. -
Haz un dibujo para demostrarlo así:
-
Entonces, para
key1
la columna, el resultado de almacenamiento final es <3, 3, 'AWM'
>, y el espacio de almacenamiento ocupado al almacenar esta información es1 + 1 + 3 = 5
bytes.
-
Como puede verse en la descripción anterior,
<0, 4, 1>
y<3, 3, 'AWM'>
ocupan11
un total de bytes. Luegoindex_col_info len
ocupa2
un byte, por lo que ocupa un total de13
bytes, y el número 13 se completaindex_col_info len
en el atributo. -
3.3 Undo log correspondiente a la operación UPDATE
Al ejecutar UPDATE
una declaración, InnoDB maneja 更新主键
estos 不更新主键
dos casos de manera completamente diferente.
3.3.1 El caso en que la clave principal no se actualiza
En el caso de no actualizar la clave primaria, se puede subdividir en el caso en que el espacio de almacenamiento que ocupa la columna actualizada no cambia o cambia.
Actualización en el lugar (actualización en el lugar)
Al actualizar un registro, para cada columna que se actualizará, si el espacio de almacenamiento ocupado por la columna actualizada y la columna anterior a la actualización son iguales, entonces se puede realizar una actualización en el lugar, es decir, la columna correspondiente se puede actualizar directamente. modificado sobre la base del registro original El valor de la columna. Nuevamente, el espacio de almacenamiento ocupado por cada columna es el mismo antes y después de la actualización.Cualquier columna actualizada ocupa un espacio de almacenamiento mayor que el que ocupa después de la actualización, o el espacio de almacenamiento que ocupa antes de la actualización es menor que el que ocupa después de la actualización. lugar. Por ejemplo, hay un registro con un valor de id de 2 en la tabla demo18, y el tamaño de sus columnas se muestra en la figura (debido a que se usa el juego de caracteres utf8, los dos caracteres 'rifle' ocupan 6 bytes):
Supongamos que tenemos una declaración como esta UPDATE
:
UPDATE demo18 SET key1 = 'P92', col = '手枪' WHERE id = 2;
En esta declaración UPDATE, la columna col se actualiza de un rifle a una pistola, ocupando 6 bytes antes y después, es decir, el espacio de almacenamiento ocupado no ha cambiado; la columna key1 se actualiza de M416 a P92, es decir, es cambió de 4
bytes La actualización es de 3 bytes, lo que no cumple con las condiciones requeridas para la actualización en el lugar, por lo que no se puede realizar la actualización en el lugar. Pero si la instrucción UPDATE se ve así:
UPDATE demo18 SET key1 = 'M249', col = '机枪' WHERE id = 2;
Dado que el espacio de almacenamiento ocupado por cada columna actualizada es el mismo antes y después de la actualización, dicha declaración puede realizar una actualización en el lugar.
Elimine los registros antiguos primero, luego inserte los nuevos
En el caso de no actualizar la clave principal, si el espacio de almacenamiento ocupado por cualquiera de las columnas actualizadas es inconsistente antes y después de la actualización, primero debe eliminar este registro antiguo de la página de índice agrupado y luego de acuerdo con el valor de la columna actualizada crea un nuevo registro y lo inserta en la página.
Tenga en cuenta que la eliminación de la que estamos hablando aquí no es delete mark
una operación, sino una eliminación real, es decir, eliminar este registro de la lista de registros normales y agregarlo a la lista de basura, y modificar la información estadística correspondiente en la página (Para ejemplo PAGE_FREE
, PAGE_GARBAGE
espere esta información). Sin embargo, el subproceso que realiza la operación de eliminación real aquí no es otro subproceso especial que se usa cuando se realiza la operación en la declaración persistente, sino que la operación de eliminación real se realiza de forma sincrónica por el subproceso del usuario.Después de la eliminación real, debe actualizarse de acuerdo con cada DELETE
columnapurge
Aquí, si el espacio de almacenamiento ocupado por el registro recién creado no excede el espacio ocupado por el registro anterior, puede reutilizar directamente el espacio de almacenamiento ocupado por el registro anterior agregado a la lista de elementos no utilizados; de lo contrario, debe solicitar uno nuevo. sección de espacio en la página para Se usa el nuevo registro, si no hay espacio disponible en esta página, entonces se requiere la operación de división de página y luego se inserta un nuevo registro.
Para la situación en la que UPDATE no actualiza la clave principal (incluida la actualización en el lugar mencionada anteriormente y primero elimina el registro anterior y luego inserta el nuevo registro), InnoDB diseñó un tipo de registro de deshacer, su estructura completa es la siguiente TRX_UNDO_UPD_EXIST_REC
:
TRX_UNDO_DEL_MARK_REC
De hecho, la mayoría de las propiedades son similares a los tipos de registros de deshacer que hemos introducido , pero aún debemos prestar atención a los siguientes puntos:
n_updated
El atributo indica que varias columnas se actualizarán después de la ejecución de esta instrucción UPDATE, y las siguientes<pos, old_len, old_value>
indican respectivamente la posición de la columna actualizada en el registro, el espacio de almacenamiento ocupado por la columna antes de la actualización y el valor real de la columna antes de la actualización.- Si
UPDATE
la columna actualizada en el extracto incluye una columna de índice, también se agregará la información de la columna de índice, de lo contrario, esta parte no se agregará.
Ahora continúe actualizando un registro en la transacción anterior id
para la transacción, por ejemplo, actualicemos el registro para :100
id
2
BEGIN; # 显式开启一个事务,假设该事务的id为100
# 插入两条记录
INSERT INTO demo18(id, key1, col) VALUES (1, 'AWM', '狙击枪'), (2, 'M416', '步枪');
# 删除一条记录
DELETE FROM demo18 WHERE id = 1;
# 更新一条记录
UPDATE demo18 SET key1 = 'M249', col = '机枪' WHERE id = 2;
UPDATE
El tamaño de la columna actualizada por esta declaración no ha cambiado, por lo que 采用就地更新
se puede ejecutar de la siguiente manera: al cambiar el registro de la página, TRX_UNDO_UPD_EXIST_REC
primero se registrará un registro de deshacer, que se ve así:
Con esta imagen, prestemos atención a estos lugares como:
- Debido a que este
undo
registro es el primer registro generado en la transacciónid
, corresponde a .100
4
undo
undo no
3
- El registro
roll_pointer
que apuntaundo no
a 1 de este registro es2
el registro generado cuando se inserta el registro con el valor de clave principalundo
, es decir, el registro generado cuando se cambió el registro por última vezundo
. - Dado que el valor de
UPDATE
la columna de índice se actualiza en esta declaraciónkey1
, es necesario registrar la información de cada columna de la columna de índice, es decir, completarkey1
la información de la clave principal y la columna antes de actualizar.
3.3.2 El caso de actualización de la clave primaria
En el índice agrupado, los registros están conectados en una lista unidireccional según el tamaño del valor de la clave principal. Si actualizamos el valor de la clave principal de un registro, significa que la posición de este registro en el índice agrupado cambiará. cambio Cambie, por ejemplo, si registrará 主键值从1更新为10000
, si hay muchos registros cuyos valores de clave principal se distribuyen entre 1 y 10000, entonces estos dos registros pueden estar muy separados en el índice agrupado, o incluso separados en el medio Tantas páginas. En UPDATE
el caso de que el valor de la clave principal del registro se actualice en la declaración, InnoDB
el índice agrupado se procesa en dos pasos:
-
Operación de borrar marca en registros antiguos
高能注意:
¡Aquí está la operación de borrar marca! Es decir,UPDATE
antes de que se confirme la transacción de la declaración, solodelete mark
se realiza una operación en el registro anterior, y después de que se confirme la transacción, un subproceso especial realizapurge
la operación y la agrega a la lista de elementos no utilizados. Esto debe distinguirse de lo que dijimos anteriormente de que cuando el valor de la clave principal del registro no se actualiza, el registro anterior se elimina primero y luego se inserta el nuevo registro.小提示:
La razón por la que la operación de eliminar marca solo se realiza en el registro anterior es que otras transacciones también pueden acceder a este registro al mismo tiempo. Si realmente se elimina y se agrega a la lista de basura, otras transacciones no podrán acceder a él. Esta función es la llamada MVCC, y hablaremos de lo que es un MVCC en detalle en los siguientes capítulos. -
Cree un nuevo registro basado en los valores actualizados de cada columna e insértelo en el índice agrupado (es necesario cambiar la posición de la posición insertada).
Dado que el valor de la clave principal del registro actualizado ha cambiado, es necesario reubicar la ubicación de este registro desde el índice agrupado y luego insertarlo.
Para UPDATE
el caso en que la instrucción actualice el valor de la clave primaria del registro, antes de operar sobre el registro delete mark
, se registrará un registro de tipo deshacer TRX_UNDO_DEL_MARK_REC
; cuando posteriormente se inserte un nuevo registro, se registrará un registro de tipo TRX_UNDO_INSERT_REC
, undo
es decir, uno registro para cada par Cuando se cambia el valor de la clave principal, se registrarán dos registros de deshacer. Hemos hablado sobre el formato de estos registros anteriormente, por lo que no entraré en detalles.
4. Estructura general de la lista enlazada
En 写入undo日志
el proceso se utilizarán múltiples listas vinculadas, y muchas listas vinculadas tienen la misma estructura de nodos, como se muestra en la figura:
En un determinado espacio de tabla, podemos ubicar de manera única la posición de un nodo a través del número de página de una página y el desplazamiento dentro de la página.Estas dos piezas de información son equivalentes a un puntero que apunta a este nodo. entonces:
Pre Node Page Number
La combinación de yPre Node Offset
es un puntero al nodo anterior.Next Node Page Number
La combinación de yNext Node Offset
es un puntero al siguiente nodo.
El conjunto List Node
ocupa 12 bytes de espacio de almacenamiento. Para administrar mejor la lista enlazada, InnoDB propone uno 基节点的结构
, que almacena esto 链表的头节点
, 尾节点
y 链表长度信息
el diagrama de estructura del nodo base es el siguiente:
en:
List Length
Indica cuántos nodos hay en la lista enlazada.First Node Page Number和First Node Offset
La combinación es un puntero al nodo principal de la lista enlazada.Last Node Page Number和Last Node Offset
La combinación es un puntero al nodo final de la lista enlazada.
El conjunto List Base Node
ocupa 16
bytes de espacio de almacenamiento. Entonces, el diagrama esquemático del uso List Base Node
de la List Node
lista enlazada compuesta por estas dos estructuras es así:
Cinco, página FIL_PAGE_UNDO_LOG
Cuando hablábamos antes sobre el espacio de tablas, dijimos que el espacio de tablas en realidad está compuesto por muchas 页面构成
páginas 默认大小为16KB
. Hay diferentes tipos de estas páginas. Por ejemplo, FIL_PAGE_INDEX
las páginas de tipo se usan para almacenar índices agrupados e índices secundarios, FIL_PAGE_TYPE_FSP_HDR
las páginas de tipo se usan para almacenar información de encabezado de espacio de tabla y varios otros tipos de páginas, uno de los cuales se llama Este FIL_PAGE_UNDO_LOG
tipo de página se usa especialmente 存储undo日志
, y la estructura general de este tipo de página se muestra en la siguiente figura (tome el tamaño predeterminado de 16 KB como ejemplo):
Una página de tipo FIL_PAGE_UNDO_LOG
se denomina simplemente Undo
página. File Header
Los y en la imagen de arriba File Trailer
son las estructuras comunes de varias páginas. Hemos aprendido muchas veces antes, así que no entraré en detalles aquí. Undo Page Header
es Undo页面
único, echemos un vistazo a su estructura:
El significado de cada atributo es el siguiente:
-
TRX_UNDO_PAGE_TYPE
: Qué tipo de registros de deshacer se almacenarán en esta página.
Anteriormente introdujimos varios tipos de registros de deshacer, que se pueden dividir en dos categorías:-
TRX_UNDO_INSERT
(Denotado por el decimal 1): elTRX_UNDO_INSERT_REC
registro de deshacer de tipo pertenece a esta categoría y generalmente seINSERT
genera mediante una declaración, o este tipo de registroUPDATE
también se generará cuando la clave principal se actualice en la declaración .undo
-
TRX_UNDO_UPDATE
(Denotado por el decimal 2), a excepción de los registros de tipoTRX_UNDO_INSERT_REC
,undo
todos los demás tipos de registros pertenecen a esta categoría, como el , etc.undo
que mencionamos anteriormente , y los registros generados por la declaración generalmente pertenecen a esta categoría.TRX_UNDO_DEL_MARK_REC
TRX_UNDO_UPD_EXIST_REC
DELETE
UPDATE
undo
Los valores opcionales de este
TRX_UNDO_PAGE_TYPE
atributo son los dos anteriores, que se utilizan para marcar qué categoría de registros se utiliza para almacenar esta páginaundo
. Los registros de diferentes categoríasundo
no se pueden almacenar juntos. Por ejemplo , si una página tiene valor de atributo deUndo
un registros y no se pueden colocar otros tipos de registros de deshacer en esta página.TRX_UNDO_PAGE_TYPE
TRX_UNDO_INSERT
TRX_UNDO_INSERT_REC
undo
小提示:
La razón por la que los registros de deshacer se dividen en dos categorías es que los registros de deshacer de tipo TRX_UNDO_INSERT_REC se pueden eliminar directamente después de que se confirme la transacción, mientras que otros tipos de registros de deshacer también deben servir al llamado MVCC y no se pueden eliminar directamente. El procesamiento debe ser tratado de manera diferente. Por supuesto, si está confundido después de leer este pasaje, no necesita volver a leerlo. Ahora solo necesita saber que los registros de deshacer se dividen en dos categorías. Explicaremos más detalles más adelante. -
-
TRX_UNDO_PAGE_START
: indica dóndeundo
se almacena el registro en la página actual o el desplazamiento inicial del primerundo
registro en esta página. -
TRX_UNDO_PAGE_FREE
: En correspondencia con lo anterior , indica el desplazamiento al final delTRX_UNDO_PAGE_START
último registro almacenado en la página actual , o a partir de esta posición, puede continuar escribiendo nuevos registros de deshacer.undo
Suponiendo que ahora se escriben 3 registros de deshacer en la página, el diagrama esquemático de
TRX_UNDO_PAGE_START
yTRX_UNDO_PAGE_FREE
es así:
Por supuesto, cuando no se escribe ningún registro de deshacer al principio, el valor deTRX_UNDO_PAGE_START
yTRX_UNDO_PAGE_FREE
es el mismo. -
TRX_UNDO_PAGE_NODE: Representa una estructura de Nodo de Lista (nodo ordinario de la lista enlazada, que acabamos de mencionar arriba), este atributo se usará inmediatamente debajo, así que no se impaciente.
Seis, Deshacer lista enlazada de página
6.1 Deshacer lista enlazada de página en una sola transacción
Debido a que una transacción puede contener múltiples declaraciones, y una declaración puede cambiar varios registros, y cada registro debe registrarse antes de cambiar, por lo que durante la 1条或2条的undo日志
ejecución de una transacción 产生很多undo日志
, estos registros pueden no caber en una página, debe colocarse en múltiples páginas, y estas páginas están TRX_UNDO_PAGE_NODE
conectadas en una lista enlazada a través de los atributos que introdujimos anteriormente :
Puede echar un vistazo a la imagen de arriba y, al mismo tiempo, llamar a la primera página Deshacer en la lista vinculada como Deshacer first undo page
, porque además first undo page
de los registros Undo Page Header
, también registrará otra información de gestión. El resto de las páginas Deshacer lo llaman normal undo page
.
Durante la ejecución de una transacción, las declaraciones INSERT, DELETE
y UPDATE
pueden ejecutarse de forma mixta, lo que significa que se generarán diferentes tipos de registros de deshacer. Pero como dijimos antes, la misma Undo
página almacena solo TRX_UNDO_INSERT
grandes categorías de registros de deshacer, o solo almacena TRX_UNDO_UPDATE
grandes categorías de registros de deshacer. De todos modos, no se pueden mezclar, por lo que es posible que se necesiten dos listas enlazadas de páginas de deshacer durante la ejecución de un transacción. , una se llama insert undo
lista enlazada y la otra se llama update undo
lista enlazada. Dibuje un diagrama esquemático como este:
Además, los logs InnoDB
que se generan cuando se modifican los registros de las tablas ordinarias y las tablas temporales undo
deben registrarse por separado (se explica más adelante), de modo que haya como máximo 4 Undo
listas enlazadas compuestas por páginas como nodos en una transacción:
por supuesto, no al principio de la transacción Estas 4 listas vinculadas se asignarán para esta transacción, pero se asignarán a pedido. La estrategia de asignación específica es la siguiente:
- Cuando la transacción acaba de comenzar, tampoco se asigna una lista enlazada de página Deshacer.
- Cuando se inserta un registro en una tabla ordinaria o se realiza una operación de actualización de la clave primaria de un registro durante la ejecución de la transacción, se
insert undo
le asignará una lista enlazada de una tabla ordinaria. - Cuando los registros de la tabla ordinaria se eliminen o actualicen durante la ejecución de la transacción, se
update undo
le asignará una lista enlazada de la tabla ordinaria. - Cuando se inserta un registro en la tabla temporal o se realiza la operación de actualización de la clave primaria del registro durante la ejecución de la transacción, se le asignará una lista enlazada de la tabla temporal
insert undo
. - Cuando los registros de la tabla temporal se eliminen o actualicen durante la ejecución de la transacción, se
update undo
le asignará una lista enlazada de la tabla temporal.
Para resumir es:什么时候需要啥时候再分配,不需要就不分配
.
6.2 Deshacer lista enlazada de página en transacciones múltiples
Para mejorar la eficiencia de escritura del registro de deshacer tanto como sea posible, 不同事务执行过程中产生的undo日志需要被写入到不同的Undo页面链表中
. Por ejemplo, ahora hay dos transacciones con ID de transacción 1 y 2 respectivamente, las llamamos trx 1
sum respectivamente trx 2
, asumiendo que durante la ejecución de estas dos transacciones:
trx 1
La operación se realiza en la mesa ordinaria y la operaciónDELETE
se realiza en la mesa temporal . Se asignará una lista enlazada , que son:INSERT
UPDATE
InnoDB
trx 1
3
update undo
Lista enlazada para tabla normalinsert undo
Lista enlazada para tabla temporal- Una lista enlazada contra una tabla temporal
update undo
.
- trx 2 realizó operaciones de INSERCIÓN, ACTUALIZACIÓN y ELIMINACIÓN en tablas ordinarias, pero no realizó cambios en las tablas temporales.
InnoDB
Setrx 2
asignará una lista enlazada2
, que son:- Insertar lista enlazada de deshacer para tabla ordinaria
- Actualice la lista enlazada de deshacer para la tabla común.
En resumen, en el proceso trx 1
y trx 2
la ejecución, se deben asignar InnoDB
un total de listas enlazadas de 5 páginas para estas dos transacciones. Así es como se dibuja una imagen:Undo
Si hay más transacciones, significa que se pueden generar más listas vinculadas a la página Deshacer.
7. El proceso de escritura específico del registro de deshacer
7.1 El concepto de segmento (Segment)
Si ha leído detenidamente el capítulo sobre espacio de tablas, debería quedar impresionado por el concepto de este segmento.Pasamos mucho espacio hablando de este concepto. En pocas palabras, este segmento es un concepto lógico, esencialmente compuesto por varias páginas dispersas y varias áreas completas. Por ejemplo, un índice de árbol B+ se divide en dos segmentos, un segmento de nodo de hoja y un segmento de nodo de no hoja, de modo que los nodos de hoja se puedan almacenar juntos tanto como sea posible, y los nodos de no hoja se puedan almacenar juntos tanto como sea posible. posible. Cada segmento corresponde a una estructura de Entrada INODE.Esta estructura de Entrada INODE describe diversa información de este segmento, como el ID del segmento, varios nodos base de lista enlazada en el segmento, y los números de página de las páginas dispersas, etc. en esta estructura Puede revisar el significado de cada atributo en el capítulo sobre espacio de tablas). También dijimos antes que para ubicar una Entrada INODE, InnoDB diseñó una Segment Header
estructura:
El conjunto Segment Header
ocupa 10 bytes de tamaño, y el significado de cada atributo es el siguiente:
-
ID de espacio de la entrada INODE: ID del espacio de tabla donde se encuentra la estructura de entrada INODE.
-
Número de página de la entrada de INODE: el número de página de la estructura de entrada de INODE.
-
Compensación de bytes de INODE Ent: la compensación de la estructura de entrada de INODE en esta página
Conociendo el ID del espacio de la tabla, el número de página y el desplazamiento dentro de la página, ¿puede ubicar de manera única la dirección de una entrada de INODE?
小提士:
Los diversos conceptos de segmentos en esta parte se explican en detalle en el capítulo sobre el espacio de la tabla. Lo mencionaré aquí solo para despertar su memoria dormida. Si tiene algún punto que no esté claro, puede volver al espacio de la tabla nuevamente. Lea cuidadosamente
7.2 Deshacer encabezado de segmento de registro
InnoDB
Según la normativa, cada lista enlazada de página Deshacer corresponde a un segmento, denominado Undo Log Segment
. Es decir, todas las páginas de la lista enlazada se solicitan desde esta sección, por lo que diseñaron first undo page
una Undo Log Segment Header
parte llamada primera página de la lista enlazada de página Deshacer, que es la mencionada anteriormente, esta parte contiene la información de la segmento correspondiente a la lista vinculada segment header
y otra información sobre este segmento, por lo que Undo页
la primera página de la lista vinculada en realidad se ve así:
Puedes ver que Undo链表
la primera página de esta página es más que la página normal Undo Log Segment Header
, echemos un vistazo a su estructura:
El significado de cada atributo es el siguiente:
-
TRX_UNDO_STATE
: ¿En qué estado se encuentra la lista vinculada de la página Deshacer? UnUndo Log Segment
posible estado incluye lo siguiente:-
TRX_UNDO_ACTIVE
: Estado activo, es decir, una transacción activa está escribiendo registros de deshacer en este segmento. -
TRX_UNDO_CACHED
: El estado almacenado en caché. La lista enlazada de la página Deshacer en este estado está a la espera de ser reutilizada por otras transacciones. -
TRX_UNDO_TO_FREE
: Para la lista enlazada de deshacer de inserción, si la lista enlazada no se puede reutilizar después de que se confirme su transacción correspondiente, estará en este estado. -
TRX_UNDO_TO_PURGE
: Para la actualización de la lista enlazada de deshacer, si la lista enlazada no se puede reutilizar después de que se confirme su transacción correspondiente, estará en este estado. -
TRX_UNDO_PREPARED
: Contiene registros de deshacer generados por transacciones en la fase PREPARAR
小提士:
Cuándo y cómo se reutilizará la lista vinculada de la página Deshacer se discutirá en detalle más adelante. La etapa PREPARAR de la transacción solo aparece en la llamada transacción distribuida.Este libro no introducirá más sobre las transacciones distribuidas, por lo que puede ignorar este estado por ahora. -
-
TRX_UNDO_LAST_LOG
: La última posición en la lista enlazada de la página DeshacerUndo Log Header
. -
TRX_UNDO_FSEG_HEADER
Undo
: La información del segmento correspondiente a la lista enlazada de esta páginaSegment Header
(es decir, la estructura de 10 bytes que introdujimos en el apartado anterior, a través de la cual puedes encontrar el segmento correspondienteINODE Entry
) -
TRX_UNDO_PAGE_LIST
: El nodo base de la lista de páginas Deshacer.Dijimos anteriormente que la parte del encabezado de la página Deshacer de la página Deshacer tiene un
TRX_UNDO_PAGE_NODE
atributo de 12 bytes, que representa unaList Node
estructura. CadaUndo
página contieneUndo Page Header
una estructura y estas páginas se pueden vincular en una lista vinculada a través de esta propiedad. EsteTRX_UNDO_PAGE_LIST
atributo representa el nodo base de esta lista enlazada, por supuesto, este nodo base solo existe en laUndo
primera página de la lista enlazada de páginas, es decir,first undo page
en.
Deshacer encabezado de registro
La forma en que una transacción Undo
escribe undo
un registro en una página es muy simple y violenta, es decir, escribe directamente en ella y escribe otro inmediatamente después de escribir uno, y cada undo
registro es íntimo. Después de escribir una página Deshacer, solicite una nueva página del segmento, luego inserte esta página en la lista vinculada de la página Deshacer y continúe escribiendo en la página recién aplicada. InnoDB considera los registros de deshacer escritos en una lista vinculada de página Deshacer por la misma transacción como un grupo. Por ejemplo, el trx 1 que presentamos anteriormente asignará 3 listas vinculadas de página Deshacer, por lo que también escribirá 3 grupos de registros de deshacer; Dado que trx 2 asignará 2 listas enlazadas de páginas de deshacer, también escribirá 2 grupos de registros de deshacer. Cada vez que se escribe un grupo de registros de deshacer, algunos atributos sobre este grupo se registrarán antes de este grupo de registros de deshacer.InnoDB llama al lugar donde se almacenan estos atributos Undo Log Header
. Por lo tanto, antes de que la primera página de la lista de páginas Deshacer se escriba en el registro de deshacer, en realidad se llenará con U ndo Page Header
, estas tres partes, como se muestra en la figura:Undo Log Segment Header
Undo Log Header
La Undo Log Header
estructura específica es la siguiente:
Hay muchos atributos nuevamente, echemos un vistazo a lo que significan:
-
TRX_UNDO_TRX_ID
: Genere la identificación de transacción de este grupo de registros de deshacer -
TRX_UNDO_TRX_NO
: Se genera un número de secuencia después de que se confirma la transacción, y este número de secuencia se utiliza para marcar el orden de confirmación de la transacción (el número de secuencia enviado primero es pequeño y el número de secuencia enviado después es grande). -
TRX_UNDO_DEL_MARKS
: Marque si este grupoundo
de registros contieneDelete mark
registros de deshacer generados debido a operaciones. -
TRX_UNDO_LOG_START
: Indica el desplazamiento de página del primer registro de deshacer en este grupo de registros de deshacer. -
TRX_UNDO_XID_EXISTS
: si este grupo de registros de deshacer contiene información XID. -
TRX_UNDO_DICT_TRANS
: marque si este grupo de registros de deshacer es generado por sentencias DDL. -
TRX_UNDO_TABLE_ID
: si TRX_UNDO_DICT_TRANS es verdadero, este atributo indica la identificación de la tabla operada por la instrucción DDL. -
TRX_UNDO_NEXT_LOG
: El desplazamiento en la página donde comienza el siguiente conjunto de registros de deshacer. -
TRX_UNDO_PREV_LOG
: El desplazamiento en la página donde comienzan los registros de deshacer del grupo anterior.小提士:
En términos generales, una lista enlazada de página de deshacer solo almacena un conjunto de registros de deshacer generados durante la ejecución de una transacción, pero en algunos casos, después de confirmar una transacción, la siguiente transacción abierta puede reutilizar esta lista enlazada de página de deshacer, de modo que como Como resultado, se pueden almacenar varios conjuntos de registros de deshacer en una página de deshacer. TRX_UNDO_NEXT_LOG y TRX_UNDO_PREV_LOG se utilizan para marcar las compensaciones del siguiente conjunto y el conjunto anterior de registros de deshacer en la página. Con respecto a cuándo reutilizar la lista vinculada de la página Deshacer y cómo reutilizar esta lista vinculada, lo explicaremos en detalle más adelante. Por ahora, solo comprenda el significado de los dos atributos TRX_UNDO_NEXT_LOG y TRX_UNDO_PREV_LOG. -
TRX_UNDO_HISTORY_NODE
: una estructura de nodo de lista de 12 bytes que representa un nodo denominado lista vinculada de historial.
resumen
Para la lista de páginas vinculadas que no se ha reutilizado , se completará Undo
la primera página de la lista vinculada, es decir, antes de first undo page
que se escriba en el registro, y luego se escribirá oficialmente en el registro de deshacer. Para otras páginas, es decir, antes de escribir en el registro, solo se llenará . El almacenamiento de la lista enlazada , la información se almacena en la parte de cada página , así que dibuje un diagrama esquemático de la lista enlazada de la página como este:undo
Undo Page Header、Undo Log Segment Header、Undo Log Header这3个部分
normal undo page
undo
Undo Page Header
List Base Node
first undo page的Undo Log Segment Header部分
List Node
Undo
undo Page Header
Undo
8. Reutilice la página Deshacer
Dijimos anteriormente que para mejorar el rendimiento de múltiples transacciones simultáneas escritas en undo
el registro, InnoDB
decidimos asignar una Undo
lista vinculada de página correspondiente para cada transacción (se pueden asignar hasta 4 listas vinculadas por separado). Pero esto también causó algunos problemas. Por ejemplo, de hecho, solo uno o unos pocos registros pueden modificarse durante la ejecución de la mayoría de las transacciones. Para una determinada lista vinculada a la página Deshacer, solo se generan muy pocos registros de deshacer, y estos registros de deshacer pueden solo ocupan un poco Para el espacio de almacenamiento, Undo
¿no sería demasiado derrochador crear ? De hecho, es bastante derrochador, por lo que InnoDB decidió reutilizar la lista de páginas de la transacción en algunos casos después de que se confirme la transacción Undo
. Las condiciones para si una Undo
lista enlazada de páginas se puede reutilizar son simples:
-
La lista vinculada contiene solo una
Undo
página.
Si se genera una transacción durante la ejecución非常多的undo日志
, es posible que se agreguen muchas páginas a la lista vinculada de la página Deshacer. Después de enviar la transacción, si se reutilizan las páginas de toda la lista vinculada, significa que incluso si la nueva transacción noUndo
escribe muchosundo
registros en la lista vinculada de páginas, se deben mantener muchas páginas en la lista vinculada. no están disponibles no pueden ser utilizados por otras empresas, lo que crea otro tipo de desperdicio. Por lo tantoInnoDB
, soloUndo
cuando la lista de páginas Deshacer contiene solo una página, la siguiente transacción puede reutilizar la lista. -
El espacio ya utilizado por la página Deshacer
小于整个页面空间的3/4
Como dijimos anteriormente, la lista enlazada de la página Deshacer se puede dividir eninsert undo
lista enlazada yupdate undo
lista enlazada de acuerdo con las categorías de los registros de deshacer almacenados.Estas dos listas enlazadas tienen diferentes estrategias cuando se reutilizan. respectivamente echar un vistazo-
insertar lista de deshacer
insert undo
TRX_UNDO_INSERT_REC
Solo los registros de tipo se almacenan en la lista enlazadaundo
Este tipo de registro de deshacer es inútil después de que la transacción se confirma y se puede borrar. Entonces, después de confirmar una transacción, al reutilizar la lista enlazada de inserción y deshacer de esta transacción (solo hay una página en esta lista enlazada), puede sobrescribir directamente un conjunto de registros de deshacer escritos por la transacción anterior y escribir un conjunto de deshacer registros para la nueva transacción desde cero, como se muestra en la siguiente figura:
Como se muestra en la figura, supongamos que hay una lista vinculada utilizada por una transaccióninsert undo
. Cuando se confirma la transacción, solo se insertan 3 registros de deshacer en la lista vinculada de inserción de deshacer. Esta lista vinculada de inserción de deshacer solo se aplica a una página Deshacer. Suponiendo que en este momento该页面已使用的空间小于整个页面大小的3/4
, la próxima transacción pueda reutilizar estainsert undo
lista vinculada (solo hay una página en la lista vinculada). Suponiendo que una nueva transacción reutilice lainsert undo
lista vinculada en este momento, el antiguo conjunto de registros de deshacer se puede sobrescribir directamente y seundo
puede escribir un nuevo conjunto de registros. -
actualizar deshacer lista vinculada
Después de confirmar una transacción, los registrosupdate undo
en su lista vinculadaundo
no se pueden eliminar inmediatamente (estos registros se usan para MVCC, de lo que hablaremos más adelante). Por lo tanto, si las transacciones posteriores desean reutilizarupdate undo
la lista vinculada, no pueden sobrescribir los registros escritos por transacciones anterioresundo
.Undo
Esto es equivalente a escribir varios grupos de registros en la misma páginaundo
, y el efecto se ve así
-
Nueve, segmento de reversión
9.1 El concepto de segmento rollback
Ahora sabemos que una transacción puede asignar hasta 4 listas vinculadas de páginas durante la ejecución Undo
, y diferentes transacciones tienen diferentes Undo
listas vinculadas de páginas al mismo tiempo, por lo que en realidad puede haber muchas listas vinculadas de páginas de deshacer en el sistema al mismo tiempo. Para administrar mejor estas listas enlazadas , InnoDB
una página llamada . Podemos entender que cada lista enlazada de página es equivalente a una clase, y esta lista enlazada es equivalente al monitor de esta clase. Si encuentra el monitor de esta clase, puede encontrar otros estudiantes en la clase (otros estudiantes son equivalentes ) . A veces la escuela necesita transmitir el espíritu a estas clases, y necesita llamar a todos los monitores a la sala de conferencias, que es el equivalente a una sala de conferencias.Rollback Segment Header
Undo
frist undo page
undo slot
Undo
first undo page
normal undo page
Rollback Segment Header
Echemos un vistazo a Rollback Segment Header
cómo se ve esta supuesta página (tome los 16 KB predeterminados como ejemplo):
InnoDB
Está estipulado que cada Rollback Segment Header
página corresponde a un segmento, y este segmento se llama Rollback Segment
, es decir 回滚段
. A diferencia de las diversas secciones que presentamos anteriormente, Rollback Segment
en realidad solo hay una página en esta (esto puede deberse InnoDB
a que piensan que si quieren asignar páginas para un propósito determinado, primero deben solicitar una sección, o piensan que aunque la versión actual MySQL
en realidad Rollback Segment
solo tiene una página, pero es posible agregar páginas en versiones posteriores).
Después de entender Rollback Segment
el significado de , echemos un vistazo al Rollback Segment Header
significado de cada parte de esta supuesta página:
-
TRX_RSEG_MAX_SIZE
: El valor máximo de la suma del número de páginas enRollback Segment
todas las listas enlazadas de páginas administradas en este libro . En otras palabras, Ben .Undo
Undo
Rollback Segment中所有Undo页面链表中的Undo页面数量之和不能超过TRX_RSEG_MAX_SIZE代表的值
El valor de esta propiedad es infinito por defecto, es decir, podemos escribir tantas páginas Undo como queramos.
小提士:
Infinity es en realidad solo una exageración. El número más grande que se puede representar con 4 bytes es 0xFFFFFFFF, pero veremos más adelante que el número 0xFFFFFFFF tiene un propósito especial, por lo que el valor real de TRX_RSEG_MAX_SIZE es 0xFFFFFFFE. -
TRX_RSEG_HISTORY_SIZE
:History
El número de páginas ocupadas por la lista enlazada. -
TRX_RSEG_HISTORY
:History
El nodo base de la lista enlazada. -
TRX_RSEG_FSEG_HEADER
: Esta es unaRollback Segment
estructura de 10 bytes correspondiente a estaSegment Header
sección, a través de la cual puede encontrar la sección correspondienteINODE Entry
.
TRX_RSEG_UNDO_SLOTS
: La colección de números de página de cada Undo
lista enlazada de páginas , es decir, la colección.first undo page
undo slot
Un número de página ocupa 4
bytes. Para 16KB
una página de este tamaño, esta TRX_RSEG_UNDO_SLOTS
parte almacena un total de 1024
bytes undo slot
, por lo que un total de 1024 × 4 = 4096个字节
9.2 Solicitar la lista enlazada de la página Deshacer desde el segmento de reversión
Inicialmente, dado que no Undo
se asigna ninguna lista vinculada a páginas a ninguna transacción, Rollback Segment Header
cada una de ellas undo slot
se establece en un valor especial para una página: FIL_NULL
(el valor hexadecimal correspondiente es 0xFFFFFFFF), lo que indica que undo slot
no apunta a ninguna página.
A medida que pasa el tiempo, hay transacciones que necesitan asignar Undo
listas vinculadas a la página, así que comience desde la primera del segmento de reversión undo slot
para ver si undo slot
el valor es FIL_NULL
:
-
Si es así
FIL_NULL
, cree un nuevo segmento (es decir), en el espacio de tablaUndo Log Segment
y luego solicite una página del segmento como unaUndo
lista de enlaces de páginafirst undo page
, y luego establezcaundo slot
el valor de esto en el número de página de la página que acaba de aplicar. , lo que significa Estoundo slot
se asigna a esta transacción. -
Si no
FIL_NULL
, significa que estaundo slot
ya apuntó a unaundo
lista enlazada, es decir, estaundo slot
ha sido ocupada por otras transacciones, entonces salte a la siguienteundo slot
, juzgueundo slot
si el valor de esta es correctoFIL_NULL
, y repita los pasos anteriores.
Rollback Segment Header
Incluido en una página 1024个undo slot
, 1024
si undo slot
el valor de esta es none FIL_NULL
, significa que 1024
esta undo slot
ya ha sido nombrada (asignada a una determinada transacción). En este momento, debido a que la nueva transacción ya no puede obtener una nueva Undo
lista de páginas, se activará. devuelve la transacción e informa un error al usuario:
Too many active concurrent transactions
Cuando el usuario ve este error, puede optar por volver a ejecutar la transacción (tal vez se confirmen otras transacciones durante la reejecución y se le puede asignar una Undo
lista de páginas a la transacción).
Cuando se compromete una transacción, lo que ocupa undo slot
tiene dos destinos:
-
Si la lista enlazada de
undo slot
páginasUndo
a la que apunta cumple la condición de ser reutilizada (es decir, la lista enlazada de páginas Deshacer que mencionamos anteriormente solo ocupa una página y el espacio utilizado es menos de 3/4 de la página completa).Está
undo slot
en el estado de almacenamiento en caché, yInnoDB
se estipula que el atributoUndo
de la lista de páginas enlazadasTRX_UNDO_STATE
(la parte rfirst undo page
del atributoUndo Log Segment Heade
) se establecerá enTRX_UNDO_CACHED
.Los almacenados en caché se agregarán a una lista vinculada y se agregarán a diferentes listas vinculadas
undo slot
según el tipo de lista vinculada de la página correspondiente :Undo
-
Si la
Undo
lista vinculada de la página correspondiente esinsert undo
una lista vinculada, seundo slot
agregará ainsert undo cached
la lista vinculada. -
Si la
Undo
lista vinculada de la página correspondiente esupdate undo
una lista vinculada, seundo slot
agregará aupdate undo cached
la lista vinculada.
Un segmento de reversión corresponde a las dos
cached
listas vinculadas anteriores. Si hay una nueva transacción para asignar , primero se encuentra en la lista vinculadaundo slot
correspondiente .cached
Si no está en cachéundo slot
, irá a la的Rollback Segment Header
página del segmento de reversión para encontrarlo nuevamente. -
-
Si la lista de enlaces de páginas
undo slot
señaladaUndo
no cumple la condición de ser reutilizada, entonces la lista de enlaces de páginasundo slot
correspondienteUndo
se manejará de manera diferente según el tipo: -
Si la
Undo
lista vinculada de la página correspondiente esinsert undo
una lista vinculada, el atributoUndo
de la lista vinculada de la páginaTRX_UNDO_STATE
se establecerá en , y luego se liberaráTRX_UNDO_TO_FREE
el segmento correspondiente a la lista vinculada de la página (lo que significa que las páginas del segmento se pueden utilizar para otros fines).Undo
), y luego elundo slot
valor se establece enFIL_NULL
. -
Si la
Undo
lista vinculada de la página correspondiente esupdate undo
una lista vinculada, la propiedadUndo
de la lista vinculada de la páginaTRX_UNDO_STATE
se establecerá enTRX_UNDO_TO_PRUGE
, yundo slot
el valor se establecerá en , y luego se colocaráFIL_NULL
un conjunto de registros escritos por esta transacción en la denominada lista vinculada. lista (tenga en cuenta que el segmento correspondiente a la lista enlazada de la página Deshacer no se publicará aquí, porque estos registros siguen siendo útiles ~)undo
History
undo
9.3 Múltiples segmentos de reversión
Decimos que la mayoría se asigna durante la ejecución de una transacción 4个Undo页面链表
, pero solo en un segmento de retroceso 1024个undo slot
, obviamente undo slot
el número es un poco pequeño. Incluso si asumimos que solo se asigna una lista vinculada a 1
una página durante la ejecución de una transacción de lectura y escritura, eso solo puede admitir la ejecución simultánea de dos transacciones de lectura y escritura, y fallará si hay más. Esto es equivalente al hecho de que la sala de conferencias solo puede acomodar un monitor para realizar una reunión al mismo tiempo. Si miles de personas vienen a la sala de conferencias para una reunión al mismo tiempo, los monitores posteriores no tendrán lugar para sentarse. , y solo puede esperar a que las personas de enfrente terminen la reunión antes de entrar.Undo
1024
undo slot
1024
1024
Se dice que, InnoDB
de hecho, solo hay un segmento de reversión en la etapa inicial de desarrollo, pero InnoDB
luego se dio cuenta de este problema, ¿cómo resolverlo? No hay suficientes salas de conferencias, por lo que necesitamos construir algunas salas de conferencias más. Por lo tanto InnoDB
, definir 128
un segmento de reversión de una vez es equivalente a tener uno 128 × 1024 = 131072个undo slot
. Suponiendo que solo se asigna una lista vinculada a 1
una página durante la ejecución de una transacción de lectura y escritura Undo
, entonces 131072
se puede admitir la ejecución simultánea de múltiples transacciones de lectura y escritura al mismo tiempo (nunca había visto tantas transacciones ejecutadas simultáneamente en una máquina ~)
Cada segmento de retroceso corresponde a una Rollback Segment Header
página. Si hay 128
un segmento de retroceso, debe haber 128
una Rollback Segment Header
página. ¡Las direcciones de estas páginas deben almacenarse en algún lugar! Por lo tanto, un área determinada de InnoDB
la página No. del espacio de tablas del sistema 5
contiene 128 cuadrículas de 8 bytes:
Cada cuadrícula de 8 bytes se construye así:
Como se muestra, cada cuadrícula de 8 bytes en realidad consta de dos partes:
-
4 bytes de tamaño
Space ID
, que representa el ID de un tablespace. -
4 bytes de tamaño
Page number
, que representa un número de página.
Es decir, cada tamaño de 8 bytes 格子
es equivalente a un puntero, que apunta a una determinada página en un determinado espacio de tablas, y estas páginas son Rollback Segment Header
. Una cosa a tener en cuenta aquí es que para ubicar un encabezado de segmento de reversión, debe conocer el ID del espacio de tabla correspondiente, lo que significa que diferentes segmentos de reversión pueden distribuirse en diferentes espacios de tabla.
Entonces, a través de la descripción anterior, podemos entender aproximadamente que hay dos direcciones de página 5
almacenadas en la página No. del espacio de tabla del sistema, cada una de las cuales es equivalente a un segmento de reversión. En la página, también contiene , cada uno correspondiente a una lista de páginas enlazadas. Dibujemos un diagrama:128
Rollback Segment Header
Rollback Segment Header
Rollback Segment Header
1024个undo slot
undo slot
Undo
Es mucho más refrescante una vez que se dibuja la imagen.
9.4 Clasificación de los segmentos de retroceso
Vamos a numerar los segmentos de retroceso 128. El segmento de retroceso inicial se llama segmento de retroceso No. 0, y luego se incrementa sucesivamente. El último segmento de retroceso se llama segmento de retroceso No. 127. Los 128 segmentos de retroceso se pueden dividir en dos categorías:
-
第0号、第33~127号回滚段属于一类
. Entre ellos, el segmento de reversión n.° 0 debe estar en el espacio de tabla del sistema (es decir, la página de encabezado de segmento de reversión correspondiente al segmento de reversión n.° 0 debe estar en el espacio de tabla del sistema), y los segmentos de reversión n.° 33 a 127 se pueden en el espacio de tabla del sistema En, o en el espacio de tabla de deshacer configurado por usted mismo, hablaremos sobre cómo configurarlo más adelante.Si una transacción necesita asignar una lista enlazada de página de deshacer debido a cambios en los registros de la tabla ordinaria durante la ejecución, se debe asignar el espacio de deshacer correspondiente desde este tipo de segmento.
-
第1~32号回滚段属于一类
. Estos segmentos de reversión deben estar en el tablespace temporal (correspondiente al archivo ibtmp1 en el directorio de datos).Si una transacción necesita asignar una lista enlazada de página Deshacer debido a cambios en los registros de la tabla temporal durante la ejecución, debe asignarse desde este tipo de segmento
undo slot
.
Es decir, si una transacción cambia tanto los registros de la tabla ordinaria como los registros de la tabla temporal durante la ejecución, es necesario asignar 2 segmentos de rollback para este registro, y luego pasar a los dos segmentos de rollback correspondientes a la asignación en el segmento undo slot
.
No sé si tienes alguna duda, ¿por qué deberíamos dividir diferentes tipos de segmentos de rollback para tablas ordinarias y tablas temporales? Esto tiene que Undo
empezar con la página en sí, decimos que Undo
una página es en realidad FIL_PAGE_UNDO_LOG
la abreviatura de una página de tipo , después de todo, también es una página ordinaria. Como dijimos antes, debe redo
escribir el registro correspondiente antes de modificar la página, para que cuando el sistema se bloquee y reinicie, pueda restaurarse al estado antes del bloqueo. Undo
Escribir logs en la página undo
en sí es también un proceso de escritura de páginas, por eso InnoDB
se diseñan muchos redo
tipos de logs , como MLOG_UNDO_HDR_CREATE
, MLOG_UNDO_INSERT
, , MLOG_UNDO_INIT
etc., es decir, cualquier cambio que hagamos Undo
en la página registrará el correspondiente tipo de redo
registro. Pero para las tablas temporales, undo
los registros generados al modificar las tablas temporales solo necesitan ser válidos durante la operación del sistema. Si el sistema falla, no es necesario restaurar las undo
páginas donde se encuentran estos registros al reiniciar, por lo que al escribir para las tablas temporales Undo
hay no es necesario grabar el registro correspondiente para la página redo
. Resuma las razones para dividir diferentes tipos de segmentos de reversión para tablas ordinarias y tablas temporales: al modificar las Undo
páginas en los segmentos de reversión para tablas ordinarias, debe registrar los registros correspondientes y modificar las páginas redo
en los segmentos de reversión para tablas temporales registro correspondiente.Undo
redo
小提士:
Si solo realizamos cambios en los registros de la tabla ordinaria, solo se asignará a la transacción el segmento de reversión de la tabla ordinaria y no se asignará el segmento de reversión de la tabla temporal. Pero si solo hacemos cambios en los registros de la tabla temporal, entonces a la transacción se le asignará tanto el segmento de reversión para la tabla ordinaria como el segmento de reversión para la tabla temporal (pero la asignación del segmento de reversión no asignará inmediatamente el segmento de deshacer ranura, y solo asigne la ranura de deshacer en el segmento de reversión cuando la lista vinculada de la página Deshacer sea realmente necesaria).
9.5 Proceso detallado de asignación de la lista enlazada de la página Deshacer para la transacción
Undo页面
Hay muchos conceptos mencionados anteriormente, y todos deberían sentirse un poco mareados. A continuación, tomemos el ejemplo de una transacción que cambia los registros de una tabla común para resolver el proceso completo de asignación de una lista vinculada durante la ejecución de la transacción.
-
Antes de realizar cualquier cambio en los registros de las tablas ordinarias por primera vez durante la ejecución de una transacción, primero asignará un segmento de reversión a la página 5 del espacio de tabla del sistema (de hecho, es para obtener la dirección de una página)
Rollback Segment Header
. Una vez que se asigna un determinado segmento de reversión a esta transacción, cuando los registros de la tabla ordinaria se cambien en la transacción más adelante, no se asignará repetidamente.Utilice el método legendario
round-robin
(reciclado) para asignar segmentos de reversión. Por ejemplo, si la transacción actual asigna el segmento de reversión n.° 0, la siguiente transacción asignará el segmento de reversión n.° 33 y la siguiente transacción asignará el segmento de reversión n.° 34. En pocas palabras, estos segmentos de reversión se asignan Asignación a diferentes asuntos a su vez (es tan simple y grosero, no hay nada que decir). -
Después de asignar el segmento de reversión, primero verifique
cached
si las dos listas vinculadas del segmento de reversión se han almacenado en cachéundo slot
. Por ejemplo, si la transacción esINSERT
una operación, vaya a la lista vinculada i correspondiente al segmento de reversiónnsert undo cached
para ver si hay algún cachéundo slot
; Si la transacción esDELETE
una operación, vaya a la lista enlazada correspondiente al segmento de reversiónupdate undo cached
para ver si hay algún cachéundo slot
. Si hay un cachéundo slot
, entoncesundo slot
asigne este caché a la transacción. -
Si no hay caché
undo slot
disponible para la asignación, entonces es necesarioRollback Segment Header
encontrar unaundo slot
asignación disponible en la página para la transacción actual.Rollback Segment Header
La forma de asignar las páginas disponibles de la páginaundo slot
también se menciona anteriormente, es decir, a partir de la 0undo slot
, si elundo slot
valor de este valorFIL_NULL
significa queundo slot
está libre, entoncesundo slot
asígnelo a la transacción actual, de lo contrario, verifique si la primeraundo slot
es condición satisfecha, y así sucesivamente, hasta la últimaundo slot
. Si ninguna de las 1024 ranuras para deshacer tiene un valorFIL_NULL
, solo informe un error (generalmente esto no sucederá) ~ -
Después de encontrar el disponible
undo slot
, si seundo slot
obtiene decached
la lista enlazada, entoncesUndo Log Segment
se ha asignado el correspondiente; de lo contrario, debe reasignarseUndo Log Segment
, y luegoUndo Log Segment
solicitar una página comoUndo
la lista enlazada de páginasfirst undo page
. -
¡ Entonces la transacción puede
undo
escribir el registro en la aplicación anteriorUndo页面链表了
!
Los pasos para modificar los registros de la tabla temporal son los mismos que los descritos anteriormente, por lo que no los repetiré aquí. Sin embargo, debe enfatizarse nuevamente que si una transacción cambia tanto los registros de la tabla ordinaria como los registros de la tabla temporal durante la ejecución, entonces es necesario asignar 2 segmentos de reversión para este registro. De hecho, a diferentes transacciones ejecutadas simultáneamente también se les puede asignar el mismo segmento de reversión, siempre que se les asignen diferentes undo slot
.
9.6 Configuración relacionada con el segmento de reversión
9.6.1 Configurar el número de segmentos de reversión
Dijimos anteriormente que hay un total de segmentos de reversión en el sistema 128
. De hecho, este es solo el valor predeterminado. Podemos configurar la cantidad de segmentos de reversión a través de los parámetros de inicio innodb_rollback_segments
. El rango configurable es 1~128
. Pero este parámetro no afectará la cantidad de segmentos de reversión para tablas temporales, la cantidad de segmentos de reversión para tablas temporales siempre es 32
, es decir:
-
Si
innodb_rollback_segments
establecemos el valor en1
, solo habrá1
un segmento de reversión disponible para las tablas normales, pero aún habrá32
uno disponible para las tablas temporales. -
Si
innodb_rollback_segments
establecemos el valor en un número entre , el efecto es el mismo2~33
que establecerlo en .1
-
Si establecemos el número
innodb_rollback_segments
en大于33
, entonces el número de segmentos de reversión disponibles para las tablas ordinarias es该值减去32
.
9.6.2 Configurar el tablespace de deshacer
De forma predeterminada, los segmentos de reversión (segmentos numéricos 0
y 33~127
de reversión) configurados para tablas ordinarias se asignan al espacio de tablas del sistema. El 0
segmento de reversión n.º 1 siempre está en el espacio de tabla del sistema, pero el segmento de reversión n.º 1 33~127
se puede colocar en un undo
espacio de tabla personalizado a través de la configuración. Pero esta configuración solo se puede usar cuando se inicializa el sistema (al crear el directorio de datos), una vez que se completa la inicialización, no se puede volver a cambiar. Echemos un vistazo a los parámetros de inicio relevantes:
-
Al
innodb_undo_directory
especificarundo
el directorio donde se encuentra el espacio de tabla, si no se especifica este parámetro, el directorio predeterminadoundo
donde se encuentra el espacio de tabla es el directorio de datos. -
Definiendo el número de tablespaces
innodb_undo_tablespaces
.undo
El valor predeterminado de este parámetro es0
, lo que indica que noundo
se crea ningún espacio de tablas.Los segmentos de reversión n.º 33~127 se pueden distribuir uniformemente en diferentes espacios de tablas de deshacer.
小提士:
Si especificamos crear el tablespace de deshacer cuando se inicializa el sistema, entonces el segmento de reversión No. 0 en el tablespace del sistema no estará disponible.
Por ejemplo, cuando inicializamos el sistema, especificamos como innodb_rollback_segments
, de modo que los segmentos No. y No. rollback se distribuirán a un espacio de tabla respectivamente .35
innodb_undo_tablespaces
2
33
34
undo
undo表空间
Uno de los beneficios de la configuración es que cuando el undo
archivo en el espacio de la tabla es lo suficientemente grande, se puede convertir automáticamente en un archivo pequeño. El tamaño del espacio de la tabla del sistema solo se puede aumentar continuamente, pero no se puede truncar.undo表空间截断
truncate