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.
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.
MySQL ERROR 1045 Access denied: root Şifresi Sıfırlama Rehberi
MySQL 1045 hatasının dört nedeni, "using password: YES/NO" ayrımının anlamı ve kilitli kalınca --init-file ile güvenli şifre sıfırlama.