Question

Est-il vrai que les systèmes SGBDR sont optimisés pour les opérations de COMMIT? Combien sont plus lents / plus rapide des opérations de ROLLBACK et pourquoi?

Était-ce utile?

La solution

Pour SQL Server, vous pouvez faire valoir qu'une opération de validation est rien de plus que l'écriture LOP_COMMIT_XACT dans le fichier journal et de libérer les verrous, ce qui est d'aller bien sûr être plus rapide que le ROLLBACK de toute action transaction effectuée depuis BEGIN TRAN.

Si vous envisagez de toutes les actions d'une transaction, non seulement la commettras, je voudrais encore faire valoir votre déclaration n'est pas vrai. En excluant les facteurs externes, la vitesse du disque journal par rapport à des données vitesse du disque par exemple, il est probable que l'annulation de tout travail effectué par une transaction sera plus rapide que de faire le travail en premier lieu.

Un rollback est en train de lire un fichier séquentiel de modifications et de les appliquer aux pages de données en mémoire. L'original "travail" devait générer un plan d'exécution, pages Acquire, joignez-vous des lignes etc.

Edit: Le tout dépend peu ...

@JackDouglas a cet article qui décrit l'une des situations où rollback peut prendre beaucoup plus longtemps que l'opération initiale. L'exemple étant une opération de 14 heures, inévitablement en utilisant le parallélisme, qui prend 48+ heures pour rollback, car la plupart du temps rollback est un seul thread. Vous très probablement barattage aussi la piscine tampon à plusieurs reprises, donc plus vous inversez les modifications des pages en mémoire.

Ainsi, une version révisée de ma réponse précédente. Comment est beaucoup plus lent rollback? Toutes choses considérées, pour une transaction OLTP typique est pas. En dehors des limites de la typique, il peut prendre plus de temps à « undo » que « faire », mais (est-ce une langue potentielle Twister?) Pourquoi dépendra de la façon dont le « faire » a été fait.

Edit2: À la suite de la discussion dans les commentaires, voici un très artificiel par exemple pour démontrer que le travail accompli est le principal facteur pour déterminer la charge relative de commettre vs rollback que les opérations.

Créer deux tables et les emballer inefficacement (espace perdu par page):

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

Exécutez une requête de mise à jour « mauvaise », la mesure du temps pris pour faire le travail et le temps de délivrer le commettras.

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

Faites la même chose à nouveau, mais rollback d'émission et mesure.

    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

Avec @ lignes = 1 je reçois une assez cohérente:

  • 5500ms pour la recherche / mise à jour
  • 3ms commettre
  • 1ms rollback

Avec @ lignes = 100:

  • 8500ms trouver / mise à jour
  • 15ms commettre
  • 15ms rollback

Avec @ lignes = 1000:

  • 15000ms trouver / mise à jour
  • 10ms commettre
  • 500ms rollback

Retour à la question initiale. Si vous le temps de mesure prises pour faire du travail ainsi que la validation, la restauration gagne haut la main parce que la majorité de ce travail est consacré à la recherche de la ligne mise à jour, de ne pas modifier réellement les données. Si vous cherchez à l'opération de validation dans l'isolement, il devrait être clair que commettent fait très peu « travail » en tant que tel. Commit est "Je suis fait".

Autres conseils

Pour Oracle, la restauration peut prendre plusieurs fois plus longtemps que le temps qu'il a fallu pour faire les changements qui roulent en arrière. Cela ne souvent pas d'importance parce que

  1. Pas de verrou ont lieu pendant que la transaction fait reculer
  2. Il est géré par un processus d'arrière-plan de faible priorité

Pour SQL Server Je ne sais pas si la situation est la même, mais quelqu'un d'autre dira si ce n'est pas ...

En ce qui concerne « pourquoi », je dirais que le rollback devrait être rare , le plus souvent que si quelque chose a mal tourné, et bien sûr commit est susceptible d'être beaucoup plus fréquent - il est donc logique pour optimiser pour commit

Rollback est non seulement « oh, never mind » - dans beaucoup de cas, il n'a vraiment de défaire ce qu'il avait déjà fait. Il n'y a pas de règle que l'opération de restauration sera toujours plus lent ou toujours être plus rapide que l'opération initiale, bien que même si la RAN de la transaction initiale en parallèle, la restauration système mono-thread. Si vous attendez que je suggère qu'il est plus sûr de garder à attendre.

toutes les modifications avec SQL Server 2019, bien sûr, et Récupération accélérée Base de données (qui, à une pénalité qui est également variable, permet de rollback instantanée quelle que soit la taille-de-données).

Pas toutes les transactions auront leur activité commettre de bien meilleurs résultats que leur rollback. Un tel cas est l'opération de suppression dans SQL. Lorsqu'une transaction supprime des lignes, ces lignes sont marquées comme des enregistrements fantômes. Une fois Commit est émis et une tâche nettoyage d'enregistrement fantôme commence, alors que sont ces enregistrements « supprimés ».

Si un rollback a été délivrée à la place, il enlève juste les marques fantômes de ces dossiers, et non les instructions d'insertion intensive.

Pas tous. PostgreSQL ne prend pas plus de temps pour faire reculer que de commettre les deux opérations sont effectivement identiques en termes de E / S disque. Je ne pense pas que ce fait est une question d'être optimisé pour commettre tant qu'il est question de ce que d'autres requêtes un OPTIMISE pour.

La question fondamentale est de savoir comment vous adresse la mise en page sur disque et comment cela affecte commettez vs rollback. Les principaux de db qui diminueront plus lentement que de commettre ont tendance à déplacer les données, en particulier des tables en cluster, sur les principales structures de données et le mettre dans un segment de restauration lors de la mise à jour des données. Cela signifie que pour vous engage tout le segment tomber rollback mais rouleau arrière, vous devez copier tout le dos de données.

Pour PostgreSQL, toutes les tables sont des tables et index tas sont séparés. Cela signifie que lors de l'annulation ou de commettre, aucune donnée ne doit être réarrangée. Cela rend validation et d'annulation à la fois rapide.

Cependant, il fait d'autres choses un peu plus lent. Une recherche clé primaire, par exemple, doit parcourir un fichier d'index, puis il doit frapper la table de tas (en supposant qu'aucun couvrant les index qui sont applicables). Ce n'est pas une affaire énorme mais il ajoute une recherche de page supplémentaire ou peut-être même quelques recherches page au hasard (si beaucoup de mises à jour ont eu lieu sur cette ligne) pour vérifier d'autres informations et de visibilité.

La vitesse ici est cependant pas une question d'optimisation dans PostgreSQL pour les opérations d'écriture contre les lire. Il est un manque de volonté de privilégier certaines des opérations de lecture ci-dessus les autres. En conséquence PostgreSQL est en moyenne à peu près aussi bien que de l'autre db. Il est juste certaines opérations qui peuvent être plus ou moins rapide.

Je pense donc que la réponse réelle est que la DB sont optimisés pour certaines charges de travail du côté de la lecture, ce qui conduit à des problèmes du côté écriture. En général, où il y a une question, commits sont généralement, mais pas toujours, va être favorisée par rapport rollbacks. Cela dépend toutefois des implications découlant de l'un (mises à jour sont différentes de suppressions).

Licencié sous: CC-BY-SA avec attribution
Non affilié à dba.stackexchange
scroll top