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 / 29043
Accepted
Craig Efrein
Craig Efrein
Asked: 2012-11-22 02:27:30 +0800 CST2012-11-22 02:27:30 +0800 CST 2012-11-22 02:27:30 +0800 CST

A chave duplicada do PostgreSQL viola o erro de restrição exclusiva

  • 772

CentOS 6.2 Servidor PostgreSQL 8.4.9 de 64 bits instalado via yum

Estou vendo erros de tempos em tempos nos logs do PostgreSQL sobre uma tabela chamada eventos. A tabela de eventos é usada para armazenar informações geradas por triggers no Zabbix sempre que um evento específico ocorre em um servidor que está sendo monitorado.

O Zabbix é o único aplicativo que usa o servidor de banco de dados.

Aqui está o erro:

INSTRUCTION :  insert into events (eventid,source,object,objectid,clock,ns,value,value_changed) values (6393428,2,3,38,1353354000,0,1,0)
ERROR:  duplicate key violates unique constraint « events_pkey »

Não há sequência associada aos eventos da tabela

Aqui está a estrutura da tabela para eventos

                               Table « public.events »
    Colonne    |  Type   |          Modificateurs           | Stockage | Description 
---------------+---------+----------------------------------+----------+-------------
 eventid       | bigint  | non NULL                         | plain    | 
 source        | integer | non NULL Par défaut, 0           | plain    | 
 object        | integer | non NULL Par défaut, 0           | plain    | 
 objectid      | bigint  | non NULL Par défaut, (0)::bigint | plain    | 
 clock         | integer | non NULL Par défaut, 0           | plain    | 
 value         | integer | non NULL Par défaut, 0           | plain    | 
 acknowledged  | integer | non NULL Par défaut, 0           | plain    | 
 ns            | integer | non NULL Par défaut, 0           | plain    | 
 value_changed | integer | non NULL Par défaut, 0           | plain    | 
Index :
    "events_pkey" PRIMARY KEY, btree (eventid)
    "events_1" btree (object, objectid, eventid)
    "events_2" btree (clock)
Référencé par :
    TABLE "acknowledges" CONSTRAINT "c_acknowledges_2" FOREIGN KEY (eventid) REFERENCES events(eventid) ON DELETE CASCADE
    TABLE "alerts" CONSTRAINT "c_alerts_2" FOREIGN KEY (eventid) REFERENCES events(eventid) ON DELETE CASCADE

Pergunta

Que passos posso tomar para resolver este erro?

obrigada

Atualizado em 26/11

Tentei executar a instrução ALTER TABLE ALTER COLUMN que o dezso me enviou, mas recebo um erro sobre o tipo bigserial.

zabbix=# ALTER TABLE events ALTER COLUMN eventid TYPE bigserial;
ERREUR:  le type « bigserial » n'existe pas

No entanto, posso criar uma nova tabela com esse tipo de dados

zabbix=# \connect postgres
psql (8.4.13)
Vous êtes maintenant connecté à la base de données « postgres ».
postgres=# CREATE TABLE test(x bigserial);
NOTICE:  CREATE TABLE créera des séquences implicites « test_x_seq » pour la colonne serial « test.x »
CREATE TABLE
postgres=# \ds
              Liste des relations
 Schéma |    Nom     |   Type   | Propriétaire 
--------+------------+----------+--------------
 public | test_x_seq | séquence | postgres
(1 ligne)

Como devo proceder para alterar eventid para bigserial?

Atualização 27/11

Eu tentei outro método para adicionar a sequência à coluna eventid

create sequence eventid_seq;
alter table events alter column eventid set default nextval('eventid_seq');
select (max(eventid) +1) as nexteventid from events;
SELECT setval('eventid_seq', 6645754);

Isso funcionou, mas quando liguei o Zabbix novamente, o valor do eventid continuou a aumentar, mas a sequência não. O que estou fazendo de errado?

postgresql unique-constraint
  • 1 1 respostas
  • 25548 Views

1 respostas

  • Voted
  1. Best Answer
    dezso
    2012-11-25T02:25:36+08:002012-11-25T02:25:36+08:00

    (Eu tento compilar uma resposta dos comentários.)

    Parece que há um problema no processo com o qual seu aplicativo gera o valor para a chave primária. Geralmente é mais sensato deixar isso para o SGBD: defina uma sequência e deixe-a preencher os valores de PK. Se você tem uma sequência, você tem pelo menos duas opções: ou defina o valor como

    $eventid = exec(SELECT nextval('your_sequence')) // pseudocode!
    

    e use isso na INSERTdeclaração, ou deixe completamente para o PostgreSQL omitindo PK do INSERT:

    INSERT INTO events (source, object, [...]) 
    VALUES (2, 3, [...]);  
    

    (Pessoalmente, costumo optar pela segunda solução.)

    Você pode alterar esse comportamento definindo o tipo de dados da sua coluna PK para bigserial(no caso de um integer, seria apenas serial):

    ALTER TABLE events ALTER COLUMN eventid TYPE bigserial;
    

    Isso irá gerar um aviso que informa que uma sequência chamada (provavelmente) events_eventid_seqé gerada. Você pode usá-lo como descrito acima.

    EDITAR (2012-11-27)

    Você pode definir a sequência por uma consulta como

    SELECT setval('events_eventid_seq', (SELECT max(eventid) FROM events));
    

    Para permitir que a sequência produza o próximo valor para eventid, você não deve definir um valor explicitamente em seu arquivo INSERT. Se você fizer isso, ele pegará o valor fornecido manualmente e não avançará a sequência. Isso causará o mesmo erro de violação exclusivo mais tarde.

    Em relação ao ALTER TABLE: como você pode ver, há alguma discrepância entre ALTER TABLE- o tipo não existe e o CREATE TABLE. Tem certeza de que tentou isso no mesmo banco de dados? Não me lembro das versões mais antigas, mas já a 8.3 tinha a bigserialabreviação (não é um tipo real). (Pensando melhor, é bem possível que você não possa usá-lo em ALTER TABLE, já que é uma abreviação...) Você pode resolver o problema seguindo o manual :

    CREATE SEQUENCE events_eventid_seq;
    
    ALTER TABLE events 
    ALTER COLUMN eventid TYPE bigint;
    
    ALTER SEQUENCE events_eventid_seq OWNED BY events.eventid;
    
    SELECT setval('events_eventid_seq', (SELECT max(eventid) FROM events));
    
    • 3

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