¿El registro de SQL Server registra operaciones no confirmadas?


12

A menudo veo declaraciones como el registro del servidor SQL registra cada transición y operación.

Pero estoy confundido acerca de lo que sucede cuando una transacción es finalmente rodó hacia atrás .

Por ejemplo una transacción explícita tiene 3 estados: statement A, statement B, statement C, y finalmente una rollback statement D.

Ahora diga cuando la ejecución no haya alcanzado el rollback statement D, ¿ statements A through Cse registrarán las modificaciones resultantes del registro del servidor SQL?

Comprensión 1 :

Las declaraciones de la A a la D se graban. SQL Server registra todo, pase lo que pase.

Comprensión 2 : las modificaciones solo se almacenan en algún lugar de la memoria y solo se registran para iniciar sesión cuando SQL Server ve una commitdeclaración. Si resulta ser una rollbackdeclaración, SQL Server simplemente ignora la transacción, no se realiza ninguna escritura en el registro porque no sirve para nada. En otras palabras, SQL Server se registra cuando hay un resultado neto antes y después de las transacciones.

Ambas me parecen lógicas, al menos para mí, pero ambas no pueden estar en lo cierto. Gracias por cualquier ayuda.


Hola, intente [ systoolsgroup.com/sql-log-analyzer.html] (SQL Log Analyzer) para analizar qué sucede en el archivo de registro. Puede probar la versión gratuita de SysTools SQL Log Analyzer para obtener solo una vista previa de los datos de registro de SQL. Espero que esto funcione para usted.
Rylan08

Respuestas:


13

Entender 1 es correcto. SQL Server registra cada operación que cambia los datos al registro de transacciones. Una reversión es un cambio en los datos, por lo que también se registra en el registro de transacciones. Como ejecución de la declaración A, escribirá datos en el registro de transacciones y también reservará datos en el registro de transacciones en caso de que la declaración A deba revertirse. Lo mismo es cierto para B y C. Cuando revierta la transacción, se escribirá más información en el registro.

Hay muchas maneras de ver esto en acción, así que a continuación se muestra una demostración rápida. Aquí está la consulta que usaré para ver lo que se escribió en el registro:

SELECT 
  COUNT(*) transaction_count
, SUM(database_transaction_log_bytes_used) used_bytes
, SUM(database_transaction_log_bytes_reserved) reserved_bytes
FROM sys.dm_tran_database_transactions
where database_id = 10;

Mi mesa:

create table TLOGDEMO (FLUFF VARCHAR(1000));

BEGIN TRANSACTION

La consulta A usa un registro mínimo:

INSERT INTO TLOGDEMO WITH (TABLOCK)
SELECT REPLICATE('A', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Después de:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1    24006640       175429451 
╚═══════════════════╩════════════╩════════════════╝

La consulta B no usa un registro mínimo:

INSERT INTO TLOGDEMO
SELECT REPLICATE('B', 1000)
FROM master..spt_values t1
CROSS JOIN master..spt_values t2;

Después de B:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7352935708      1613986255 
╚═══════════════════╩════════════╩════════════════╝

La consulta C cambia menos datos:

INSERT INTO TLOGDEMO
SELECT REPLICATE('C', 1000)
FROM master..spt_values c;

Después de C:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
                 1  7355821748      1614545331 
╚═══════════════════╩════════════╩════════════════╝

Ahora emitiré ROLLBACKy consultaré el DMV mientras ocurre la reversión. A continuación se muestra una tabla de algunas instantáneas:

╔═══════════════════╦════════════╦════════════════╗
 transaction_count  used_bytes  reserved_bytes 
╠═══════════════════╬════════════╬════════════════╣
 1                  7393305528  1573797677     
 1                  7458767420  1502635737     
 1                  7682482356  1259440979     
 1                  7803881368  1127471233     
 ...                ...         ...            
╚═══════════════════╩════════════╩════════════════╝

Durante el ROLLBACK, los bytes utilizados aumentan y el número reservado de bytes disminuye. Esto se debe a que SQL Server está utilizando el espacio que reservaba antes para deshacer la transacción. Para deshacer la transacción, debe cambiar los datos para que escriba más datos en el registro.


8

Las modificaciones en las tablas de la base de datos se escriben primero en el archivo de registro, luego en las tablas mismas, primero en la memoria y luego, con un proceso asíncrono llamado CHECKPOINT, en el disco. Este mecanismo se conoce como WAL (Registro de escritura anticipada) y es común a todas las bases de datos relacionales.

El registro en sí se escribe primero en la memoria (en el búfer de registro, precisamente) y luego en el disco, pero no se toca nada en las tablas de la base de datos hasta que el registro se haya escrito en el disco.

Este mecanismo permite tanto el avance de las transacciones confirmadas como el retroceso de las transacciones no confirmadas durante el proceso de recuperación. Con respecto a su ejemplo, si algo malo sucedió después statement Cy tuvo un en commitlugar de un rollback(no puede saber esto de antemano), sin guardar todos y cada uno de los pasos en la transacción, el RDBMS no tendría forma de recuperar la base de datos de manera consistente manera y la transacción no cumpliría con la D(durabilidad) en ACID.

Cuando algunas operaciones se revierten, es el archivo de datos el que recibe los cambios netos (vía CHECKPOINT), no el archivo de registro.


5

Entender 1 es correcto, y spaghettidba y Joe tienen buenas explicaciones.

Si está interesado en probar usted mismo (en una instancia de prueba, por favor), puede usar el siguiente script:

--create a database and table for testing
USE master
GO
CREATE DATABASE tranlogtest
GO
USE tranlogtest
GO
CREATE TABLE t1
(junk char(1))

CHECKPOINT
GO

BEGIN TRAN
INSERT t1 VALUES ('a')
INSERT t1 VALUES ('b')
INSERT t1 VALUES ('c')

ROLLBACK
INSERT t1 VALUES ('d')

SELECT *
FROM fn_dblog(NULL,NULL)

Verá que SQL Server registra todo, incluso los pasos dados para deshacer las operaciones.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.