Bölümlenmiş Tablolarda RETURNING ID Sorunu

Veritabanımda bir log tablomun giderek hızla büyümesi sebebiyle sıkıntı yaşamaya başlamadan bölümledim ve sorgular oldukça rahatladı. Kullandığımız Django 1.4 versiyonu itibariyle bir veriyi kaydettikten sonra bu veriye sequence’den atanan id’nin döndürmesini istiyor.

Normalde aşağıdaki gibi bir trigger fonksiyonu kullanıyorum fakat bu şekilde INSERT yapıldıktan sonra hiç bir şey döndürmüyor.

CREATE OR REPLACE FUNCTION log_insert_trigger() RETURNS TRIGGER  
AS $$  
BEGIN  
        ........... 
        ........... 
    ELSE 
        INSERT INTO log_xxx VALUES (NEW.*); 
    END IF; 
RETURN NULL;  
END;  
$$ LANGUAGE plpgsql;

RETURN NULL yerine RETURN NEW diyerek geriye son eklenen id’yi döndürmesini sağladığımı zannettim(!)

CREATE OR REPLACE FUNCTION log_insert_trigger() RETURNS TRIGGER  
AS $$  
BEGIN  
        ........... 
        ........... 
    ELSE 
        INSERT INTO log_xxx VALUES (NEW.*); 
    END IF; 
RETURN NEW;  
END; $$ LANGUAGE plpgsql;  

ANCAK! Bu değişiklik hüsranla sonuçlandı.
Geriye id döndürüyordu ama INSERT işlemini hem partitionlanmış ilgili alt tabloya hem de ana tabloya yazması gibi bir sorunla karşılaştım. Sonrasında, çift girilmiş 167bin veriyi temizlemek durumunda kaldım.

Fonksiyonun return tipi TRIGGER olarak yazmak mecburiyetinde olduğumuz için fonksiyon sonunda integer ya da başka bir değer döndüremiyoruz. Döndürdüğümüz değer, kayıt (record) ya da NULL olmak zorunda.

Bu sebeple partitioning yaptığımız tablolarda “returning id” bir hayal oluyor.
IRC’den sorduğumda, depesz’in bu konudaki cevabı “do not use returning id in partitioned tables” oldu.

Erkin Çakar

PostgreSQL DBA & Software developer