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 / 278736
Accepted
Anentropic
Anentropic
Asked: 2020-10-28 04:15:58 +0800 CST2020-10-28 04:15:58 +0800 CST 2020-10-28 04:15:58 +0800 CST

Qual é o comportamento de bloqueio do Postgres quando a cláusula UPDATE WHERE faz uma varredura de tabela?

  • 772

Digamos que você tenha uma grande tabela com dezenas de milhões de linhas.

Você deseja UPDATE large_table SET col=value WHERE col=other_value... mas colnão está indexado e EXPLAINmostra que essa consulta fará uma varredura seq em toda a tabela.

Qual é o comportamento de bloqueio aqui? De acordo com a maioria das contas, o Postgres bloqueia apenas as linhas afetadas de uma consulta UPDATE e não possui escalonamento de bloqueio. Então, ele procura as linhas para atualizar primeiro e depois bloqueia apenas as linhas encontradas? Parece que potencialmente haveria problemas de outras consultas atualizando linhas simultaneamente nesse caso. Ele bloqueia cada linha "como as encontra", ou seja, bloqueia as linhas progressivamente à medida que passa pela varredura seq?

Portanto, acho que o melhor caso aqui é bloquear as linhas à medida que as encontra, e as linhas afetadas (somente) serão bloqueadas pelo tempo que a consulta UPDATE levar para ser concluída.

Mas estou preocupado que essa consulta possa acabar bloqueando todas as gravações na tabela até que seja concluída.

Eu li isso: https://habr.com/en/company/postgrespro/blog/503008/ e acho que o pior caso não vai acontecer, mas aqui https://blog.heroku.com/curious-case-table -locking-update-query é uma representação possivelmente imprecisa de informações semelhantes que me dão algumas dúvidas.

O aplicativo usa apenas SELECT, SELECT FOR UPDATEe UPDATEconsultas (ou seja, nenhum outro bloqueio explícito separado desses). A tabela possui chaves estrangeiras para outras tabelas e outras tabelas possuem chaves estrangeiras para esta tabela.

Estamos no Postgres 11.

postgresql lock-escalation
  • 1 1 respostas
  • 2903 Views

1 respostas

  • Voted
  1. Best Answer
    Laurenz Albe
    2020-10-28T05:54:59+08:002020-10-28T05:54:59+08:00

    Para a discussão, vamos supor que seu plano de execução se parece com

            QUERY PLAN        
    --------------------------
     Update on mytab
       ->  Seq Scan on mytab
             Filter: (id = 1)
    

    Também presumo que você esteja usando o READ COMMITTEDnível de isolamento padrão.

    Então o PostgreSQL lerá sequencialmente a tabela.

    Sempre que encontrar uma linha que corresponda ao filtro, essa linha será bloqueada e atualizada.

    Se o bloqueio de uma linha for bloqueado por uma consulta simultânea, o PostgreSQL espera até que o bloqueio desapareça. Em seguida, ele reavalia a condição do filtro e avança (se a condição não se aplicar mais devido a uma modificação simultânea) ou bloqueia e atualiza a linha modificada.

    Veja a documentação :

    UPDATE, DELETE, SELECT FOR UPDATEe SELECT FOR SHAREcomandos se comportam da mesma forma queSELECTem termos de busca de linhas de destino: eles só encontrarão linhas de destino que foram confirmadas na hora de início do comando. No entanto, essa linha de destino pode já ter sido atualizada (ou excluída ou bloqueada) por outra transação simultânea no momento em que for encontrada. Nesse caso, o suposto atualizador aguardará que a primeira transação de atualização seja confirmada ou revertida (se ainda estiver em andamento). Se o primeiro atualizador reverter, seus efeitos serão negados e o segundo atualizador poderá prosseguir com a atualização da linha originalmente encontrada. Se o primeiro atualizador confirmar, o segundo atualizador ignorará a linha se o primeiro atualizador a excluiu, caso contrário, ele tentará aplicar sua operação à versão atualizada da linha. A condição de pesquisa do comando (oWHEREcláusula) é reavaliada para ver se a versão atualizada da linha ainda corresponde à condição de pesquisa. Em caso afirmativo, o segundo atualizador prossegue com sua operação usando a versão atualizada da linha.

    Em particular, é possível que duas UPDATEinstruções, cada uma modificando várias linhas, entrem em deadlock, uma vez que adquirem bloqueios à medida que prosseguem e os bloqueios são sempre mantidos até o final da transação.

    • 5

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

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

    conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host

    • 12 respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

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

    • 4 respostas
  • Marko Smith

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

    • 10 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
  • Martin Hope
    Jin conectar ao servidor PostgreSQL: FATAL: nenhuma entrada pg_hba.conf para o host 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +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

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