PostgreSQL "duplicate key value violates unique constraint" — Sequence Neden Geride Kalır?
Restore veya toplu içe aktarma sonrası "duplicate key value violates unique constraint" hatasının nedeni, tek komutla düzeltme ve tüm sequence'ları tarayan DO bloğu.
Operasyonel Doğrulama & Güvenilirlik Standardı
Hata mesajı semptomdur, kök neden değildir. Sunucuyu yeniden başlatmadan veya rastgele ayar değiştirmeden önce aşağıdaki "Nedeni ayırt eden tek sorgu"yu çalıştırarak gerçek senaryoyu netleştirin.
▸Belirti
ERROR: duplicate key value violates unique constraint "kullanicilar_pkey"
DETAIL: Key (id)=(1043) already exists.Bu hatanın ayırt edici işareti şudur: tabloda `id = 1043` olan bir kayıt zaten var, ama `INSERT` bu değeri üretmeye çalışıyor. Genellikle şu üç durumdan sonra ortaya çıkar:
- •Veritabanı geri yüklendi (
pg_restore,psql < dump) - •Veriler başka bir sistemden, açık
iddeğerleriyle içe aktarıldı - •Tablo yeniden oluşturuldu ve veriler kopyalandı
pg_dump sequence durumunu dump anındaki haliyle yazar. Sonradan açık id ile eklenen satırlar sequence'ı ilerletmez.
▸Doğrulama
SELECT max(id) AS tablodaki_en_buyuk FROM kullanicilar;
SELECT last_value, is_called FROM kullanicilar_id_seq;tablodaki_en_buyuk > last_value ise tanı kesindir.
▸Çözüm
1. Tek tablo için hızlı onarım:
SELECT setval(
pg_get_serial_sequence('public.kullanicilar', 'id'),
(SELECT max(id) FROM public.kullanicilar)
);2. Tüm şemayı tarayan otomatik DO bloğu: Restore sonrası tek tek uğraşmak yerine:
DO $$
DECLARE
r record;
m bigint;
BEGIN
FOR r IN
SELECT n.nspname AS sch,
c.relname AS tab,
a.attname AS col,
pg_get_serial_sequence(
quote_ident(n.nspname) || '.' || quote_ident(c.relname),
a.attname
) AS seq
FROM pg_class c
JOIN pg_namespace n ON n.oid = c.relnamespace
JOIN pg_attribute a ON a.attrelid = c.oid AND a.attnum > 0
WHERE c.relkind = 'r'
AND n.nspname NOT IN ('pg_catalog', 'information_schema')
LOOP
CONTINUE WHEN r.seq IS NULL;
EXECUTE format('SELECT max(%I) FROM %I.%I', r.col, r.sch, r.tab) INTO m;
IF m IS NOT NULL THEN
PERFORM setval(r.seq, m);
RAISE NOTICE '% => %', r.seq, m;
END IF;
END LOOP;
END $$;▸İlgili Mühendislik Rehberleri ve İç Linkler
- •PostgreSQL İlk Restore Tatbikatı Runbook'u
- •PostgreSQL Backup & Restore CheatSheet
- •Test edilen sürümler: PostgreSQL 14 / 15 / 16 / 17
Diğer Veritabanı Hata Teşhisleri
Kriz anında başvurabileceğiniz diğer doğrulanmış hata rehberleri.
PostgreSQL too many clients already Hatası: 6 Adımda Çözüm
FATAL: sorry, too many clients already hatasının üç nedeni, nedeni ayırt eden tek sorgu ve max_connections ile PgBouncer üzerinden kalıcı çözümü.
PostgreSQL password authentication failed Hatası: Neden ve Çözüm
psql password authentication failed hatasının dört nedeni: yanlış şifre, md5/SCRAM uyuşmazlığı, pg_hba.conf sırası ve yanlış cluster. Adım adım teşhis.
PostgreSQL connection refused: 8 Adımda Kesin Teşhis
Connection refused, timeout ve "no pg_hba.conf entry" arasındaki fark; listen_addresses, port, firewall ve Docker port yayınlama kontrolleri.