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?
(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
e use isso na
INSERT
declaração, ou deixe completamente para o PostgreSQL omitindo PK doINSERT
:(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 uminteger
, seria apenasserial
):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
Para permitir que a sequência produza o próximo valor para
eventid
, você não deve definir um valor explicitamente em seu arquivoINSERT
. 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 entreALTER TABLE
- o tipo não existe e oCREATE 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 abigserial
abreviação (não é um tipo real). (Pensando melhor, é bem possível que você não possa usá-lo emALTER TABLE
, já que é uma abreviação...) Você pode resolver o problema seguindo o manual :