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 / 12374
Accepted
Bhavik Ambani
Bhavik Ambani
Asked: 2012-02-08 02:45:35 +0800 CST2012-02-08 02:45:35 +0800 CST 2012-02-08 02:45:35 +0800 CST

Tabelas acessadas durante o último período

  • 772

Desejo verificar quais tabelas foram atualizadas em um determinado período, por exemplo, em ordem decrescente de tempo de acesso por tabela.

Como posso obter isso para o PostgreSQL?

postgresql trigger
  • 2 2 respostas
  • 1319 Views

2 respostas

  • Voted
  1. Best Answer
    Jack Douglas
    2012-02-08T05:44:56+08:002012-02-08T05:44:56+08:00

    Você pode obter algumas informações sobre a última alteração em uma tabela com xmin, por exemplo:

    select max(xmin::text::bigint) from t;
    

    Mas você precisa estar ciente de muitas advertências , incluindo modulo, wraparound e frozen xids .

    banco de ensaio:

    set role dba;
    create role stack;
    grant stack to dba;
    create schema authorization stack;
    set role stack;
    --
    create or replace function f(p_schema in text, p_table in text) 
                      returns integer language plpgsql immutable as $$
    declare
      n integer;
    begin
      execute 'select max(xmin::text::bigint) from '||p_schema||'.'||p_table into n;
      return n;
    end;$$;
    --
    create table foo as select generate_series(1, 100) as id;
    create table bar as select generate_series(1, 100) as id;
    create table baz as select generate_series(1, 100) as id;
    --
    

    método:

    select table_name, f(table_schema, table_name)
    from information_schema.tables
    where table_schema='stack'
    order by 2 desc;
    /*
     table_name |   f
    ------------+--------
     baz        | 784657
     bar        | 784656
     foo        | 784655
    */
    --
    update foo set id=id+1 where id=100;
    --
    select table_name, f(table_schema, table_name)
    from information_schema.tables
    where table_schema='stack'
    order by 2 desc;
    /*
     table_name |   f
    ------------+--------
     foo        | 784658
     baz        | 784657
     bar        | 784656
    */
    

    limpar:

    drop schema stack cascade;
    set role dba;
    drop role stack;
    
    • 4
  2. Erwin Brandstetter
    2012-02-08T03:33:19+08:002012-02-08T03:33:19+08:00

    Uma instalação básica do PostgreSQL não registra o acesso às tabelas.

    Se você precisar disso, terá que implementá-lo sozinho. Eu usaria gatilhos para isso. Eu uso uma configuração como esta para muitas das minhas tabelas. Eu adiciono uma coluna nomeada log_upàs tabelas para as quais desejo rastrear atualizações:

    log_up timestamptz DEFAULT current_timestamp;
    

    Use timestamptz( timestamp with time zone) que funciona em fusos horários:

    • Ignorando totalmente os fusos horários no Rails e no PostgreSQL

    Função de gatilho:

    CREATE OR REPLACE FUNCTION trg_log_up()
      RETURNS trigger AS
    $func$
    BEGIN
       NEW.log_up := current_timestamp;
       RETURN NEW;
    END;
    $func$
      LANGUAGE plpgsql VOLATILE;
    

    Acionar:

    CREATE TRIGGER log_up
    BEFORE UPDATE ON tbl
    FOR EACH ROW EXECUTE PROCEDURE trg_log_up();
    

    Existem alguns parâmetros de registro relacionados nos quais você pode estar interessado adicionalmente. Gostar log_connectionsou log_statement.

    Atualização: Considere também "commit timestamps" adicionados no Postgres 9.5 :

    • Use a comparação de carimbo de data/hora do sistema na consulta SELECT

    Adicionar gatilho a todas as tabelas

    Você pode criar um script para todas as tabelas existentes consultando o catálogo do banco de dados. Por exemplo, para gerar as instruções DDL para todas as tabelas no esquema public:

    SELECT string_agg(format('CREATE TRIGGER log_up BEFORE UPDATE ON %s '
                             'FOR EACH ROW EXECUTE PROCEDURE trg_log_up();'
                            , c.oid::regclass), E'\n')
    FROM   pg_namespace n
    JOIN   pg_class     c ON c.relnamespace = n.oid
    WHERE  n.nspname = 'public';
    -- AND c.relname ~~* '%tbl%' -- to filter tables by name
    

    Retorna:

    CREATE TRIGGER log_up BEFORE UPDATE ON tbl1 FOR EACH ROW EXECUTE PROCEDURE trg_log_up();
    CREATE TRIGGER log_up BEFORE UPDATE ON tbl2 FOR EACH ROW EXECUTE PROCEDURE trg_log_up();
    CREATE TRIGGER log_up BEFORE UPDATE ON tbl3 FOR EACH ROW EXECUTE PROCEDURE trg_log_up();
    ...
    

    Claro, todos eles precisam ter uma coluna log_updo tipo timestamptzprimeiro. Você pode criar um script DDL para adicionar a coluna a todas as tabelas de maneira semelhante.


    Log apenas por último UPDATEpor tabela

    Se você estiver interessado apenas no último UPDATEpor tabela, uma solução mais simples servirá. Aqui está uma demonstração de como acompanhar em uma tabela centralizada:

    CREATE TABLE lastup (
      schema_name text
    , tbl_name text
    , ts timestamptz
    , PRIMARY KEY (schema_name, tbl_name)
    );
    

    Acionar. Consulte o manual sobre as variáveis ​​especiais que utilizo:

    CREATE OR REPLACE FUNCTION trg_lastup()
      RETURNS trigger AS
    $func$
    BEGIN
       UPDATE lastup
       SET    ts = current_timestamp
       WHERE  schema_name = TG_TABLE_SCHEMA
       AND    tbl_name    = TG_TABLE_NAME;
    
       RETURN NULL;   -- For AFTER trigger irrelevant
    END
    $func$  LANGUAGE plpgsql;
    

    Tabela fictícia para testes:

    CREATE TABLE dummy (id int);
    INSERT INTO dummy VALUES (1), (2), (3);
    

    Digite a linha para a tabela na tabela de log:

    INSERT INTO lastup(schema_name, tbl_name) VALUES ('public', 'dummy');
    

    Acionar. Observe que eu uso um AFTERgatilho FOR EACH STATEMENT(mais barato). Mais no manual aqui.

    CREATE TRIGGER log_up
    AFTER UPDATE ON dummy
    FOR EACH STATEMENT EXECUTE PROCEDURE trg_lastup();
    

    Teste:

    UPDATE dummy
    SET    id = id + 5
    WHERE  id < 3;
    

    Voilá:

    SELECT * FROM lastup;
    

    Ou , se você deseja excluir atualizações vazias (nada alterado), mas a um custo mais alto porque várias linhas atualizadas acionam várias atualizações de log:

    CREATE OR REPLACE FUNCTION trg_lastup()
      RETURNS trigger AS
    $func$
    BEGIN
       IF OLD IS DISTINCT FROM NEW THEN  -- check for changes
          UPDATE lastup
          SET    ts = current_timestamp
          WHERE  schema_name = TG_TABLE_SCHEMA
          AND    tbl_name    = TG_TABLE_NAME;
       END IF;
    
       RETURN NULL;  -- For AFTER trigger!
    END;
    $func$  LANGUAGE plpgsql;
    
    CREATE TRIGGER log_up
    AFTER UPDATE ON dummy
    FOR EACH ROW EXECUTE PROCEDURE trg_lastup();  -- per ROW instead of STATEMENT
    

    Para criar gatilhos para todas as tabelas que você deseja incluir neste regime, use um script de criação de DDL semelhante ao acima.

    • 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

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 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

    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

    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
    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
    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
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +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