AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 5233
Accepted
garik
garik
Asked: 2011-09-01 00:25:24 +0800 CST2011-09-01 00:25:24 +0800 CST 2011-09-01 00:25:24 +0800 CST

O ROLLBACK é uma operação rápida?

  • 772

É verdade que os sistemas RDBMS são otimizados para COMMIToperações? Quão mais lentas/rápidas são ROLLBACKas operações e por quê?

sql-server-2008 performance
  • 5 5 respostas
  • 7493 Views

5 respostas

  • Voted
  1. Best Answer
    Mark Storey-Smith
    2011-09-01T01:02:56+08:002011-09-01T01:02:56+08:00

    Para o SQL Server, você poderia argumentar que uma operação de commit nada mais é do que escrever LOP_COMMIT_XACT no arquivo de log e liberar bloqueios, o que obviamente será mais rápido do que o ROLLBACK de todas as ações executadas por sua transação desde BEGIN TRAN.

    Se você está considerando cada ação de uma transação, não apenas o commit, eu ainda diria que sua afirmação não é verdadeira. Excluindo fatores externos, velocidade do disco de log em comparação com a velocidade do disco de dados, por exemplo, é provável que a reversão de qualquer trabalho feito por uma transação seja mais rápida do que fazer o trabalho em primeiro lugar.

    Uma reversão está lendo um arquivo sequencial de alterações e aplicando-as às páginas de dados na memória. O "trabalho" original tinha que gerar um plano de execução, adquirir páginas, juntar linhas etc.

    Edit: Depende um pouco...

    @JackDouglas apontou para este artigo que descreve uma das situações em que a reversão pode demorar significativamente mais do que a operação original. O exemplo é uma transação de 14 horas, inevitavelmente usando paralelismo, que leva mais de 48 horas para reverter porque a reversão é principalmente de thread único. Você provavelmente também estaria agitando o pool de buffer repetidamente, portanto, não está mais revertendo as alterações nas páginas na memória.

    Portanto, uma versão revisada da minha resposta anterior. Quão mais lento é o rollback? Todas as outras coisas consideradas, para uma transação OLTP típica, não é. Fora dos limites do típico, pode demorar mais para "desfazer" do que para "fazer", mas (isso é um trava-língua em potencial?) O motivo dependerá de como o "fazer" foi feito.

    Edit2: Na sequência da discussão nos comentários, aqui está um exemplo muito artificial para demonstrar que o trabalho que está sendo feito é o principal fator na determinação da despesa relativa de confirmação versus reversão como operações.

    Crie duas tabelas e empacote-as de forma ineficiente (espaço desperdiçado 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
    

    Execute uma consulta de atualização "ruim", medindo o tempo necessário para fazer o trabalho e o tempo necessário para emitir o commit.

    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
    

    Faça o mesmo novamente, mas emita e meça a reversão.

        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
    

    Com @Rows=1, obtenho uma consistência razoável:

    • 5500ms para localizar/atualizar
    • Compromisso de 3ms
    • reversão de 1 ms

    Com @Linhas=100:

    • 8500ms encontrar/atualizar
    • 15ms de confirmação
    • reversão de 15ms

    Com @Linhas=1000:

    • 15000ms encontrar/atualizar
    • 10ms de confirmação
    • reversão de 500ms

    De volta à pergunta original. Se você está medindo o tempo gasto para fazer o trabalho mais a confirmação, a reversão está ganhando, porque a maior parte desse trabalho é gasta para encontrar a linha a ser atualizada, não modificando os dados. Se você está olhando para a operação de commit isoladamente, deve ficar claro que o commit faz muito pouco "trabalho" como tal. Commit é "terminei".

    • 14
  2. Jack Douglas
    2011-09-01T00:36:59+08:002011-09-01T00:36:59+08:00

    Para Oracle, a reversão pode levar muito mais tempo do que o tempo necessário para fazer as alterações que estão sendo revertidas. Muitas vezes isso não importa porque

    1. Nenhum bloqueio é mantido enquanto a transação está sendo revertida
    2. É tratado por um processo em segundo plano de baixa prioridade

    Para o SQL Server, não tenho certeza se a situação é a mesma, mas alguém dirá se não for ...

    Quanto ao "porquê", eu diria que rollbackdeve ser raro , geralmente apenas se algo der errado e, commité claro, provavelmente será muito mais comum - portanto, faz sentido otimizar paracommit

    • 13
  3. Aaron Bertrand
    2011-09-01T05:27:27+08:002011-09-01T05:27:27+08:00

    A reversão não é apenas "oh, não importa" - em muitos casos, ela realmente precisa desfazer o que já havia feito. Não há regra de que a operação de reversão será sempre mais lenta ou sempre mais rápida que a operação original, embora, mesmo que a transação original seja executada em paralelo, a reversão seja de thread único. Se você está esperando, sugiro que seja mais seguro continuar esperando.

    Tudo isso muda com o SQL Server 2019, é claro, e o Accelerated Database Recovery (que, com uma penalidade também variável, permite a reversão instantânea, independentemente do tamanho dos dados).

    • 9
  4. StanleyJohns
    2011-09-01T05:17:33+08:002011-09-01T05:17:33+08:00

    Nem todas as transações terão sua atividade de confirmação executada muito melhor do que sua reversão. Um desses casos é a operação de exclusão no SQL. Quando uma transação exclui linhas, essas linhas são marcadas como registros fantasmas. Depois que um commit é emitido e uma tarefa de limpeza de registro fantasma é iniciada, somente esses registros são 'excluídos'.

    Se, em vez disso, foi emitida uma reversão, ela apenas remove as marcações fantasmas desses registros, e não as instruções de inserção intensivas.

    • 8
  5. Chris Travers
    2014-03-05T21:47:13+08:002014-03-05T21:47:13+08:00

    Nem todos são. O PostgreSQL não leva mais tempo para reverter do que para confirmar, pois as duas operações são efetivamente idênticas em termos de E/S de disco. Na verdade, não acho que seja uma questão de ser otimizado para confirmação, mas sim para quais outras consultas alguém está otimizando.

    A questão básica é como você aborda o layout em disco e como isso afeta o commit versus o rollback. Os principais bancos de dados que revertem mais lentamente do que o commit tendem a mover os dados, principalmente de tabelas agrupadas, para fora das estruturas de dados principais e colocá-los em um segmento de reversão ao atualizar os dados. Isso significa que, para confirmar, basta descartar o segmento de reversão, mas para reverter, você deve copiar todos os dados de volta.

    Para o PostgreSQL, todas as tabelas são heap e os índices são separados. Isso significa que, ao reverter ou confirmar, nenhum dado precisa ser reorganizado. Isso torna a confirmação e a reversão rápidas.

    No entanto, torna algumas outras coisas um pouco mais lentas. Uma pesquisa de chave primária, por exemplo, precisa percorrer um arquivo de índice e, em seguida, atingir a tabela de heap (supondo que não haja índices de cobertura aplicáveis). Isso não é grande coisa, mas adiciona uma pesquisa de página extra ou talvez até algumas pesquisas de página aleatórias (se muitas atualizações ocorreram nessa linha) para verificar outras informações e visibilidade.

    A velocidade aqui, no entanto, não é uma questão de otimização no PostgreSQL para operações de gravação versus operações de leitura. É uma falta de vontade de privilegiar algumas operações de leitura em detrimento de outras. Conseqüentemente, o PostgreSQL executa, em média, tão bem quanto os outros bancos de dados. São apenas algumas operações que podem ser mais rápidas ou mais lentas.

    Portanto, acho que a resposta real é que os bancos de dados são otimizados para determinadas cargas de trabalho no lado da leitura e isso leva a desafios no lado da gravação. Normalmente, quando há uma dúvida, os commits geralmente, embora nem sempre, serão favorecidos em relação aos rollbacks. No entanto, isso depende das implicações de fazer qualquer um deles (atualizações são diferentes de exclusões).

    • 5

relate perguntas

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

  • Onde posso encontrar o log lento do mysql?

  • Como posso otimizar um mysqldump de um banco de dados grande?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como você mostra o SQL em execução em um banco de dados Oracle?

    • 2 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Posso ver Consultas Históricas executadas em um banco de dados SQL Server?

    • 6 respostas
  • Marko Smith

    Como uso currval() no PostgreSQL para obter o último id inserido?

    • 10 respostas
  • Marko Smith

    Como executar o psql no Mac OS X?

    • 11 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Marko Smith

    Passando parâmetros de array para um procedimento armazenado

    • 12 respostas
  • Martin Hope
    Manuel Leduc Restrição exclusiva de várias colunas do PostgreSQL e valores NULL 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler Quando uma chave primária deve ser declarada sem cluster? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - Qual é melhor como chave primária? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick Como posso otimizar um mysqldump de um banco de dados grande? 2011-01-04 13:13:48 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve