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 / 288937
Accepted
Radu Dumbrăveanu
Radu Dumbrăveanu
Asked: 2021-03-31 00:33:13 +0800 CST2021-03-31 00:33:13 +0800 CST 2021-03-31 00:33:13 +0800 CST

Dúvidas sobre o Mapa de Espaço Livre do PostgreSQL

  • 772

Vamos criar uma tabela temporária (eu escolho uma tabela temporária porque o autovacuum não funciona para esse tipo de tabela):

CREATE TEMP TABLE test (
  id int PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  value int
);
INSERT INTO test (value) SELECT 0 FROM generate_series(0, 250);
SELECT ctid, * FROM test;

Veremos que a tabela consiste em duas páginas:

(0,1)   1   0
(0,2)   2   0
...
(0,226) 226 0
(1,1)   227 0
...
(1,25)  251 0

Agora, se atualizarmos uma linha

UPDATE test SET value = -1 WHERE id = 1;
SELECT ctid, * FROM test WHERE value <> 0;

veremos que a nova versão de linha foi inserida no final da tabela (na segunda página, que tem espaço livre suficiente para esta operação) e este é um comportamento padrão do PostgreSQL (a versão de linha antiga de (0,1) era marcado como morto)

(1,26)  1   -1

Vamos verificar o espaço livre das páginas:

CREATE EXTENSION pg_freespacemap;
SELECT * FROM pg_freespace('test');

Nós temos

0   0
1   0

ou seja, sem espaço livre; documentações dizem que o Free Space Map (FSM) é atualizado após a execução do vácuo. Agora, se atualizarmos outra linha da primeira página:

UPDATE test SET value = -1 WHERE id = 2;
SELECT ctid, * FROM test WHERE value <> 0;

vamos ver

(0,227) 2   -1
(1,26)  1   -1

A nova versão de linha não foi adicionada à 2ª página, mas foi adicionada à página atual, porque criamos espaço livre quando atualizamos o registro com id 1. Mas essa abordagem não corresponde ao meu entendimento de FSM. Aqui estão minhas perguntas:

  1. Como o PostgreSQL soube no segundo UPDATE que havia espaço livre na primeira página se pg_freespace('test')retornasse zero? Eu pensei que esta função lhe dá o FSM que por sua vez é usado no caso de UPDATEs para decidir qual página tem espaço livre suficiente para armazenar a nova versão da linha.
  2. Geralmente eu estava pensando que, mesmo que a primeira linha estivesse marcada como morta, ela ocuparia algum espaço na 1ª página e esse espaço será liberado somente após o vácuo. Assim, eu esperava que o segundo UPDATE também adicionasse a nova versão de linha à 2ª página.
postgresql vacuum
  • 1 1 respostas
  • 212 Views

1 respostas

  • Voted
  1. Best Answer
    Laurenz Albe
    2021-03-31T02:23:51+08:002021-03-31T02:23:51+08:00

    Isso conterá alguns componentes internos do PostgreSQL; desculpe, você pediu.

    O Autovacuum não é executado em tabelas temporárias (porque elas são invisíveis fora da sua sessão) e, de qualquer forma, uma ou duas atualizações não acionarão o autovacuum. Agora é ele VACUUMque cria e mantém o mapa de espaço livre, então não há mapa de espaço livre no seu caso . pg_freespacemapnão dá erro, mas relata isso como 0.

    Na falta de um mapa de espaço livre, o PostgreSQL precisa examinar os blocos individuais para encontrar um bloco com espaço livre. Isso deixa o enigma por que a segunda atualização poderia encontrar espaço para criar uma tupla no bloco 0.

    Para responder ao enigma, vamos discutir suas declarações e seus efeitos. Você pode verificar tudo isso usando a pageinspectextensão.

    • o primeiro UPDATE:

      UPDATE test SET value = -1 WHERE id = 1;
      

      Isso marca a tupla (0,1) como atualizada (configura xmax) e cria a nova tupla (1,26), exatamente como você esperava.

    • a seguinte consulta:

      SELECT ctid, * FROM test WHERE value <> 0;
      

      Essa consulta pode obter um bloqueio de página no bloco 0 e realizar a poda de heap , que é um “micro-vácuo” que libera o espaço ocupado por tuplas mortas. Observe que ele não pode remover (0,1), pois ainda é referenciado em um índice, mas o ponteiro de linha (0,1) torna-se um “stub” marcado LP_DEADque não ocupa nenhum espaço. O espaço ocupado por essa tupla morta é liberado.

      Observe que, se você não executar isso SELECT, o seguinte UPDATEexecutará a remoção de heap no bloco 0, portanto, o efeito será o mesmo.

    • o segundo UPDATE:

      UPDATE test SET value = -1 WHERE id = 2;
      

      Na falta de um mapa de espaço livre, a instrução procura um bloco 0 e percebe que há espaço livre suficiente, então executa uma atualização HOT e coloca a nova tupla no bloco 0.

    • 2

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