¿Es cierto que los sistemas RDBMS están optimizados para COMMIT
operaciones? ¿Cuánto más lento / rápido son las ROLLBACK
operaciones y por qué?
¿Es cierto que los sistemas RDBMS están optimizados para COMMIT
operaciones? ¿Cuánto más lento / rápido son las ROLLBACK
operaciones y por qué?
Para SQL Server, podría argumentar que una operación de confirmación no es más que escribir LOP_COMMIT_XACT en el archivo de registro y liberar bloqueos, que por supuesto será más rápido que el ROLLBACK de cada acción que realizó su transacción desde BEGIN TRAN.
Si está considerando cada acción de una transacción, no solo la confirmación, todavía argumentaría que su declaración no es cierta. Excluyendo factores externos, la velocidad del disco de registro en comparación con la velocidad del disco de datos, por ejemplo, es probable que la reversión de cualquier trabajo realizado por una transacción sea más rápida que hacer el trabajo en primer lugar.
Una reversión es leer un archivo secuencial de cambios y aplicarlos a páginas de datos en memoria. El "trabajo" original tenía que generar un plan de ejecución, adquirir páginas, unir filas, etc.
Editar: El depende poco ...
@JackDouglas señaló este artículo que describe una de las situaciones en las que la reversión puede llevar mucho más tiempo que la operación original. El ejemplo es una transacción de 14 horas, inevitablemente usando paralelismo, que demora más de 48 horas en revertirse porque la reversión es principalmente de un solo subproceso. Lo más probable es que también esté agitando el grupo de búferes repetidamente, por lo que ya no está invirtiendo los cambios en las páginas en memoria.
Entonces, una versión revisada de mi respuesta anterior. ¿Cuánto más lento es el retroceso? Todas las demás cosas consideradas, para una transacción OLTP típica, no lo es. Fuera de los límites de lo típico, puede llevar más tiempo "deshacer" que "hacer" pero (¿es esto un posible trabalenguas?) ¿Por qué dependerá de cómo se hizo el "hacer".
Edit2: a continuación de la discusión en los comentarios, aquí hay un ejemplo muy artificial para demostrar que el trabajo realizado es el factor principal para determinar el gasto relativo de commit vs rollback como operaciones.
Cree dos tablas y empaquéelas de manera ineficiente (espacio desperdiciado por página):
SET STATISTICS IO OFF;
SET STATISTICS TIME OFF;
SET NOCOUNT ON;
GO
CREATE TABLE dbo.Foo
(
col1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, col2 CHAR(4000) NOT NULL DEFAULT REPLICATE('A', 4000)
)
CREATE TABLE dbo.Bar
(
col1 INT IDENTITY(1,1) PRIMARY KEY CLUSTERED
, col2 CHAR(4000) NOT NULL DEFAULT REPLICATE('A', 4000)
)
GO
INSERT dbo.Foo DEFAULT VALUES
GO 100000
INSERT dbo.Bar DEFAULT VALUES
GO 100000
Ejecute una consulta de actualización "incorrecta", midiendo el tiempo necesario para realizar el trabajo y el tiempo necesario para emitir la confirmación.
DECLARE
@StartTime DATETIME2
, @Rows INT
SET @Rows = 1
CHECKPOINT
DBCC DROPCLEANBUFFERS
BEGIN TRANSACTION
SET @StartTime = SYSDATETIME()
UPDATE
dbo.bar
SET
col2 = REPLICATE('B', 4000)
FROM
dbo.bar b
INNER JOIN
(
SELECT TOP(@Rows)
col1
FROM
dbo.foo
ORDER BY
NEWID()
) f
ON f.col1 = b.col1
OPTION (MAXDOP 1)
SELECT 'Find and update row', DATEDIFF(ms, @StartTime, SYSDATETIME())
SET @StartTime = SYSDATETIME()
COMMIT TRANSACTION
SELECT 'Commit', DATEDIFF(ms, @StartTime, SYSDATETIME())
GO
Haga lo mismo nuevamente pero emita y mida la reversión.
DECLARE
@StartTime DATETIME2
, @Rows INT
SET @Rows = 1
CHECKPOINT
DBCC DROPCLEANBUFFERS
BEGIN TRANSACTION
SET @StartTime = SYSDATETIME()
UPDATE
dbo.bar
SET
col2 = REPLICATE('B', 4000)
FROM
dbo.bar b
INNER JOIN
(
SELECT TOP(@Rows)
col1
FROM
dbo.foo
ORDER BY
NEWID()
) f
ON f.col1 = b.col1
OPTION (MAXDOP 1)
SELECT 'Find and update row', DATEDIFF(ms, @StartTime, SYSDATETIME())
SET @StartTime = SYSDATETIME()
ROLLBACK TRANSACTION
SELECT 'Rollback', DATEDIFF(ms, @StartTime, SYSDATETIME())
GO
Con @ Rows = 1 obtengo un razonablemente consistente:
Con @ filas = 100:
Con @ Filas = 1000:
De vuelta a la pregunta original. Si está midiendo el tiempo necesario para hacer el trabajo más el compromiso, la reversión está ganando sin duda porque la mayor parte de ese trabajo se dedica a encontrar la fila para actualizar, en lugar de modificar los datos. Si observa la operación de confirmación de forma aislada, debe quedar claro que la confirmación hace muy poco "trabajo" como tal. Comprometerse es "Ya terminé".
begin tran
solo aumenta el contador de transacciones. Si te entendí, ¿rdbms está haciendo todas las tareas (une filas, genera planes de ejecución ...) en COMMIT?Para Oracle, la reversión puede llevar muchas veces más tiempo que el tiempo que llevó realizar los cambios que están retrocediendo. Esto a menudo no importa porque
Para SQL Server, no estoy seguro de si la situación es la misma, pero alguien más dirá si no es así ...
En cuanto a "por qué", diría que
rollback
debería ser raro , generalmente solo si algo salió mal, y por supuestocommit
es probable que sea mucho más común, por lo que tiene sentido optimizarlo paracommit
fuente
La reversión no es solo "oh, no importa", en muchos casos realmente tiene que deshacer lo que ya había hecho. No existe una regla que establezca que la operación de reversión siempre será más lenta o más rápida que la operación original, aunque incluso si la transacción original se ejecutó en paralelo, la reversión es de un solo subproceso. Si está esperando, sugiero que es más seguro seguir esperando.
Todo esto cambia con SQL Server 2019, por supuesto, y la Recuperación acelerada de la base de datos (que, con una penalización que también es variable, permite la reversión instantánea independientemente del tamaño de los datos).
fuente
No todas las transacciones tendrán una actividad de compromiso mucho mejor que su reversión. Uno de estos casos es la operación de eliminación en SQL. Cuando una transacción elimina filas, estas filas se marcan como registros fantasma. Una vez que se emite una confirmación y se inicia una tarea de limpieza de registros fantasma, solo se eliminan estos registros.
Si se emitió una reversión, solo elimina las marcas fantasma de estos registros, y no las instrucciones de inserción intensiva.
fuente
No todos lo son. PostgreSQL no necesita más tiempo para retroceder que para comprometerse, ya que las dos operaciones son efectivamente idénticas en términos de E / S de disco. En realidad, no creo que se trate de optimizar tanto para el compromiso como de las otras consultas para las que se está optimizando.
La pregunta básica es cómo aborda el diseño en el disco y cómo esto afecta la confirmación frente a la reversión. Las principales bases de datos que retroceden más lentamente que el compromiso tienden a mover datos, particularmente de tablas agrupadas, fuera de las estructuras de datos principales y colocarlos en un segmento de reversión cuando se actualizan datos. Esto significa que para comprometerse simplemente descarte el segmento de reversión, pero para retroceder debe copiar todos los datos.
Para PostgreSQL, todas las tablas son tablas de montón y los índices están separados. Esto significa que al retroceder o confirmar, no es necesario reorganizar los datos. Esto hace que commit y rollback sean rápidos.
Sin embargo, hace que otras cosas sean un poco más lentas. Una búsqueda de clave principal, por ejemplo, tiene que atravesar un archivo de índice y luego debe golpear la tabla de montón (suponiendo que no sean aplicables los índices de cobertura). Esto no es un gran problema, pero agrega una búsqueda de página adicional o tal vez incluso algunas búsquedas de página aleatorias (si se han producido muchas actualizaciones en esa fila) para buscar otra información y visibilidad.
Sin embargo, la velocidad aquí no es una cuestión de optimización en PostgreSQL para operaciones de escritura frente a operaciones de lectura. Es una falta de voluntad para privilegiar algunas operaciones de lectura sobre otras. En consecuencia, PostgreSQL funciona en promedio aproximadamente tan bien como los otros db's. Es solo ciertas operaciones que pueden ser más rápidas o más lentas.
Entonces, creo que la respuesta real es que los db están optimizados para ciertas cargas de trabajo en el lado de lectura y esto lleva a desafíos en el lado de escritura. Por lo general, cuando hay una pregunta, los commits suelen ser, aunque no siempre, favorecidos sobre los retrocesos. Sin embargo, esto depende de las implicaciones de hacer cualquiera de las dos (las actualizaciones son diferentes a las eliminaciones).
fuente