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 / 106014
Accepted
Evan Appleby
Evan Appleby
Asked: 2015-07-06 17:26:05 +0800 CST2015-07-06 17:26:05 +0800 CST 2015-07-06 17:26:05 +0800 CST

Como particionar a tabela existente no postgres?

  • 772

Gostaria de particionar uma tabela com mais de 1 milhão de linhas por intervalo de datas. Como isso é feito normalmente sem exigir muito tempo de inatividade ou correr o risco de perder dados? Aqui estão as estratégias que estou considerando, mas aberto a sugestões:

  1. A tabela existente é o mestre e os filhos herdam dela. Com o tempo, mova os dados do mestre para o filho, mas haverá um período de tempo em que alguns dos dados estarão na tabela mestra e outros nos filhos.

  2. Crie uma nova tabela mestre e filhas. Crie uma cópia dos dados na tabela existente nas tabelas filhas (para que os dados residam em dois locais). Depois que as tabelas filhas tiverem os dados mais recentes, altere todas as inserções para apontar para a nova tabela mestre e exclua a tabela existente.

postgresql optimization
  • 2 2 respostas
  • 68731 Views

2 respostas

  • Voted
  1. Best Answer
    Evan Appleby
    2015-07-08T06:07:39+08:002015-07-08T06:07:39+08:00

    Como o nº 1 requer a cópia de dados do mestre para o filho enquanto ele está em um ambiente de produção ativo, eu pessoalmente fui com o nº 2 (criar um novo mestre). Isso evita interrupções na tabela original enquanto ela estiver em uso ativo e, se houver algum problema, posso excluir facilmente o novo mestre sem problemas e continuar usando a tabela original. Aqui estão os passos para fazê-lo:

    1. Crie uma nova tabela mestra.

      CREATE TABLE new_master (
          id          serial,
          counter     integer,
          dt_created  DATE DEFAULT CURRENT_DATE NOT NULL
      );
      
    2. Crie filhos que herdam do mestre.

      CREATE TABLE child_2014 (
          CONSTRAINT pk_2014 PRIMARY KEY (id),
          CONSTRAINT ck_2014 CHECK ( dt_created < DATE '2015-01-01' )
      ) INHERITS (new_master);
      CREATE INDEX idx_2014 ON child_2014 (dt_created);
      
      CREATE TABLE child_2015 (
          CONSTRAINT pk_2015 PRIMARY KEY (id),
          CONSTRAINT ck_2015 CHECK ( dt_created >= DATE '2015-01-01' AND dt_created < DATE '2016-01-01' )
      ) INHERITS (new_master);
      CREATE INDEX idx_2015 ON child_2015 (dt_created);
      
      ...
      
    3. Copie todos os dados históricos para a nova tabela mestra

      INSERT INTO child_2014 (id,counter,dt_created)
      SELECT id,counter,dt_created
      from old_master
      where dt_created < '01/01/2015'::date;
      
    4. Pausar temporariamente novas inserções/atualizações no banco de dados de produção

    5. Copie os dados mais recentes para a nova tabela mestra

      INSERT INTO child_2015 (id,counter,dt_created)
      SELECT id,counter,dt_created
      from old_master
      where dt_created >= '01/01/2015'::date AND dt_created < '01/01/2016'::date;
      
    6. Renomeie as tabelas para que new_master se torne o banco de dados de produção.

      ALTER TABLE old_master RENAME TO old_master_backup;
      ALTER TABLE new_master RENAME TO old_master;
      
    7. Adicione função para instruções INSERT em old_master para que os dados sejam passados ​​para a partição correta.

      CREATE OR REPLACE FUNCTION fn_insert() RETURNS TRIGGER AS $$
      BEGIN
          IF ( NEW.dt_created >= DATE '2015-01-01' AND
               NEW.dt_created < DATE '2016-01-01' ) THEN
              INSERT INTO child_2015 VALUES (NEW.*);
          ELSIF ( NEW.dt_created < DATE '2015-01-01' ) THEN
              INSERT INTO child_2014 VALUES (NEW.*);
          ELSE
              RAISE EXCEPTION 'Date out of range';
          END IF;
          RETURN NULL;
      END;
      $$
      LANGUAGE plpgsql;
      
    8. Adicionar gatilho para que a função seja chamada em INSERTS

      CREATE TRIGGER tr_insert BEFORE INSERT ON old_master
      FOR EACH ROW EXECUTE PROCEDURE fn_insert();
      
    9. Definir exclusão de restrição como ATIVADO

      SET constraint_exclusion = on;
      
    10. Reative UPDATES e INSERTS no banco de dados de produção

    11. Configure o gatilho ou cron para que novas partições sejam criadas e a função seja atualizada para atribuir novos dados à partição correta. Consulte este artigo para exemplos de código

    12. Excluir old_master_backup

    • 37
  2. kakoni
    2016-05-11T12:00:07+08:002016-05-11T12:00:07+08:00

    Existe uma nova ferramenta chamada pg_pathman ( https://github.com/postgrespro/pg_pathman ) que faria isso para você automaticamente.

    Então, algo como o seguinte faria isso.

    SELECT create_range_partitions('master', 'dt_created', 
       '2015-01-01'::date, '1 day'::interval);
    
    • 7

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