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 / 273213
Accepted
Gandolf989
Gandolf989
Asked: 2020-08-05 11:23:33 +0800 CST2020-08-05 11:23:33 +0800 CST 2020-08-05 11:23:33 +0800 CST

Eu preciso fazer commits periódicos na minha função de purga

  • 772

Eu escrevi uma função de limpeza que roda no Postgres 9.6. A função passa por todas as tabelas em nosso aplicativo, começando da tabela filho inferior e terminando com a tabela pai superior e limpa com base na data ou no cliente. Quando executamos isso em produção e beta, há outros processos acontecendo ao mesmo tempo e o banco de dados está obtendo bloqueios de bloqueio com base em minhas exclusões não confirmadas. Uma solução possível seria fazer um commit a cada mil ou mais linhas. Mas sou novo no Postgres e não consigo fazer com que o Postgres 9.6 faça commits dentro de um loop. É possível que o Postgres 9.6 não faça isso e talvez o Postgres 12 o faça. Estamos migrando para o Postgres 12.

Existe alguma maneira de fazer os commits funcionarem no Postgres 9.6? Incluí um código de teste para que você possa testar os commits por conta própria. Meu código real é muito mais complicado.

Obrigado

\timing

DROP TABLE IF EXISTS _tmp_test_transactions_table;
CREATE TABLE _tmp_test_transactions_table ( pkey INTEGER );

create or replace function _tmp_test_transactions ( p_number_of_rows INTEGER )
returns int language plpgsql
as
$fun$
DECLARE
   v_counter     INTEGER := 0;
   v_final_count INTEGER := 0;
BEGIN
   START TRANSACTION ISOLATION LEVEL READ COMMITTED;

   LOOP
      v_counter := v_counter + 1;
      EXIT WHEN v_counter > p_number_of_rows;
      
      IF MOD( v_counter, 10 ) = 0
      THEN
         COMMIT;
         START TRANSACTION ISOLATION LEVEL READ COMMITTED;
      END IF;
   END LOOP;

   SELECT COUNT(*) 
     INTO v_final_count
     FROM _tmp_test_transactions_table;

   RAISE NOTICE 'Inserted % rows in the _tmp_test_transactions_table table', v_final_count;
   COMMIT;
END
$fun$;

SELECT _tmp_test_transactions( 100 );
psql:bbyrd_test_transactions.sql:36: ERROR:  unsupported transaction command in PL/pgSQL
CONTEXT:  PL/pgSQL function _tmp_test_transactions(integer) line 6 at SQL statement
Time: 0.473 ms
postgresql transaction
  • 2 2 respostas
  • 3250 Views

2 respostas

  • Voted
  1. Best Answer
    Daniel Vérité
    2020-08-06T10:32:20+08:002020-08-06T10:32:20+08:00

    O controle de transações (commit, rollback) não é permitido dentro das funções do PostgreSQL.

    A partir do PostgreSQL 11, é possível em procedimentos (veja CREATE PROCEDURE na documentação). Na verdade, essa é a principal diferença entre funções e procedimentos.

    Antes do PostgreSQL 11, a capacidade de confirmar dentro de um loop vinha da programação além do SQL do lado do cliente. É claro que a psqlCLI pode emitir commit e rollback, mas não possui algumas das construções básicas encontradas em linguagens de programação, como loops.

    • 1
  2. Gandolf989
    2020-08-07T05:53:32+08:002020-08-07T05:53:32+08:00

    Fiz um teste para confirmar usando um procedimento e funciona bem.

    Obrigado

    \timing
    Timing is on.
    DROP TABLE IF EXISTS _tmp_test_transactions_table;
    DROP TABLE
    Time: 38.583 ms
    CREATE TABLE _tmp_test_transactions_table ( pkey INTEGER );
    CREATE TABLE
    Time: 17.007 ms
    create or replace procedure _tmp_test_transactions ( p_number_of_rows INTEGER )
    language plpgsql
    as
    $fun$
    DECLARE
       v_counter     INTEGER := 0;
       v_final_count INTEGER := 0;
       v_dummy       INTEGER;
    BEGIN
       TRUNCATE TABLE _tmp_test_transactions_table;
       LOOP
          v_counter := v_counter + 1;
          EXIT WHEN v_counter > p_number_of_rows;
    
          INSERT INTO _tmp_test_transactions_table VALUES ( v_counter );
          COMMIT;
       END LOOP;
    
       SELECT COUNT(*)
         INTO v_final_count
         FROM _tmp_test_transactions_table;
    
       RAISE NOTICE 'Inserted % rows in the _tmp_test_transactions_table table', v_final_count;
    
       RAISE EXCEPTION 'This is an error, roll back';
    END
    $fun$;
    CREATE PROCEDURE
    Time: 5.104 ms
    CALL _tmp_test_transactions( 100 );
    psql:run_commit_test.sql:34: NOTICE:  Inserted 100 rows in the _tmp_test_transactions_table table
    psql:run_commit_test.sql:34: ERROR:  This is an error, roll back
    CONTEXT:  PL/pgSQL function _tmp_test_transactions(integer) line 22 at RAISE
    Time: 116.180 ms
    SELECT COUNT(*) FROM _tmp_test_transactions_table;
     count
    -------
       100
    (1 row)
    
    • 0

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