PostgreSQL 18, 25 Eylül 2025'te yayımlanan ana sürümdür. Sürüm notlarının öne çıkardığı yenilikler şunlardır: sıralı tarama, bitmap heap scan ve vacuum gibi işlemleri hızlandırabilen asenkron I/O altyapısı, pg_upgrade'in planlayıcı istatistiklerini koruması, çok sütunlu B-tree indekslerde skip scan, zamana göre sıralanabilen UUID üreten uuidv7(), varsayılan hâle gelen virtual generated column, OAuth kimlik doğrulaması, RETURNING içinde OLD ve NEW, ve aralıklar üzerinde çalışan zamansal (temporal) birincil anahtar, benzersizlik ve yabancı anahtar kısıtları.

Bu yazı yalnızca resmî release-18 notlarına ve 18.1 ile 18.6 arasındaki ara sürüm notlarına dayanır; her başlıkta konunun ayrıntılı anlatıldığı kardeş yazıya bağlantı var. Örnekler PostgreSQL 18.1 üzerinde çalıştırıldı. Yükseltme adımları için pg_upgrade ile sürüm yükseltme, serinin tamamı için PostgreSQL öğrenme rehberi yazısına bakın.

Asenkron I/O (AIO)

Sürümün en büyük altyapı değişikliği asenkron I/O alt sistemidir. Notlara göre bu altyapı, sunucu süreçlerinin birden fazla okuma isteğini kuyruğa almasına izin verir ve böylece sıralı taramaları, bitmap heap scan'leri ve vacuum'ları daha verimli yapabilir. Davranışı io_method parametresi seçer; kılavuza göre geçerli değerler worker (I/O işçi süreçleri), io_uring (--with-liburing ile derlenmiş sürümlerde) ve sync'tir, varsayılan worker'dır ve parametre yalnızca sunucu başlarken ayarlanabilir. İşçi sayısını io_workers belirler (varsayılan 3). Yeni pg_aios görünümü asenkron I/O için kullanılan dosya tanıtıcılarını gösterir. Test kümemizde:

sql
SHOW io_method;   -- sonuç: worker

Aynı başlık altında effective_io_concurrency ve maintenance_io_concurrency parametrelerinin varsayılan değerleri 16'ya çıkarıldı; notlar bunun modern donanımı daha doğru yansıttığını söyler. Ayrıca fadvise() desteği olmayan sistemlerde de bu iki parametrenin sıfırdan büyük değer alabilmesi sağlandı. Değerlerin nasıl ayarlanacağı postgresql.conf ve ALTER SYSTEM yazısında; hangi değerin seçileceği ise genel ayar konusu olarak PostgreSQL performans optimizasyonu yazısında ele alınıyor.

Sorgu ve SQL yenilikleri

Sorgu ve SQL yenilikleri: RETURNING içinde OLD ve NEW, Virtual generated column varsayılan oldu, uuidv7() ve uuidv4(), Zamansal kısıtlar: WITHOUT OVERLAPS ve PERIOD

RETURNING içinde OLD ve NEW

Önceden RETURNING, INSERT ve UPDATE için yeni, DELETE için eski değeri döndürürdü. PostgreSQL 18 ile INSERT, UPDATE, DELETE ve MERGE komutlarında old ve new takma adlarıyla iki değeri de açıkça isteyebilirsiniz:

sql
CREATE TABLE urun (
  id     integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  ad     text NOT NULL,
  fiyat  numeric(10,2) NOT NULL,
  kdvli  numeric(10,2) GENERATED ALWAYS AS (fiyat * 1.20)
);
INSERT INTO urun (ad, fiyat) VALUES ('Klavye', 500), ('Fare', 250);

UPDATE urun SET fiyat = fiyat * 1.10 WHERE ad = 'Klavye'
RETURNING old.fiyat AS eski_fiyat, new.fiyat AS yeni_fiyat, new.kdvli;
text
 eski_fiyat | yeni_fiyat | kdvli  
------------+------------+--------
     500.00 |     550.00 | 660.00
(1 row)

DELETE içinde new değerleri NULL gelir: DELETE FROM urun WHERE ad = 'Fare' RETURNING old.ad, new.ad IS NULL sorgusu Fare | t döndürdü. Ayrıntılı örnekler INSERT, UPDATE, DELETE ve RETURNING ile UPSERT ve MERGE yazılarında. 18.6 notları bu özellikle ilgili iki düzeltme içerir: parantezli OLD/NEW ifadelerinin ayrıştırılması ve BEFORE UPDATE trigger'ı olan tabloda RETURNING OLD kullanan UPDATE'te kaçırılabilen eşzamanlı güncelleme.

Virtual generated column varsayılan oldu

Generated column artık varsayılan olarak virtual'dır: değer yazılırken saklanmaz, okunurken hesaplanır. Saklamak istiyorsanız STORED yazmanız gerekir. Yukarıdaki tabloda kdvli sütununa bir şey eklemedik; katalog bunu virtual olarak kaydetti:

sql
SELECT attname, attgenerated FROM pg_attribute
WHERE attrelid = 'urun'::regclass AND attname = 'kdvli';
text
 attname | attgenerated 
---------+--------------
 kdvli   | v
(1 row)

Notlara göre generated column'ların virtual olabilmesi 18 ile geldi; önceki sürümlerden gelen sütunlar zaten stored'dır. Fark, yeni yazılan tanımlarda tür belirtilmediğinde ortaya çıkar. Örneğin full text search için GIN indeksi kurulacak bir tsvector sütununu kılavuz stored generated column ile gösterir; full text search yazısındaki örnekte STORED açıkça yazıldı. Konu CREATE TABLE ve ALTER TABLE yazısında ayrıntılı.

uuidv7() ve uuidv4()

uuidv7() zamana göre sıralanabilen sürüm 7 UUID üretir; sürüm 4 UUID'leri açıkça üretmek için uuidv4() takma adı da eklendi. Sürüm numarasını uuid_extract_version ile doğrulayabilirsiniz:

sql
SELECT uuid_extract_version(uuidv7()) AS surum, uuid_extract_version(uuidv4()) AS surum4;
text
 surum | surum4 
-------+--------
     7 |      4
(1 row)

UUID tipinin kullanımı PostgreSQL veri tipleri yazısında, kimlik sütunu seçenekleri identity, serial ve sequence yazısında.

Zamansal kısıtlar: WITHOUT OVERLAPS ve PERIOD

PRIMARY KEY ve UNIQUE kısıtlarının son sütununa WITHOUT OVERLAPS, yabancı anahtarlara PERIOD yazılabiliyor. CREATE TABLE sayfasına göre böyle bir kısıt aslında bir EXCLUDE kısıtıyla uygulanır, son sütun aralık (range) veya çoklu aralık tipinde olmalıdır ve diğer sütunlar için skaler tiplerin kullanılması beklenen yol olarak btree_gist eklentisi gerekir. Aynı odanın çakışan iki rezervasyonu reddedildi:

sql
CREATE EXTENSION btree_gist;
CREATE TABLE oda_rezervasyon (
  oda_no  integer,
  donem   daterange,
  PRIMARY KEY (oda_no, donem WITHOUT OVERLAPS)
);
INSERT INTO oda_rezervasyon VALUES (101, '[2026-11-01,2026-11-05)');
INSERT INTO oda_rezervasyon VALUES (101, '[2026-11-04,2026-11-08)');
text
ERROR:  conflicting key value violates exclusion constraint "oda_rezervasyon_pkey"
DETAIL:  Key (oda_no, donem)=(101, [2026-11-04,2026-11-08)) conflicts with existing key (oda_no, donem)=(101, [2026-11-01,2026-11-05)).

Kısıtlarla ilgili diğer yenilikler: CHECK ve yabancı anahtar kısıtları NOT ENFORCED olarak tanımlanabiliyor (katalogda yeni pg_constraint.conenforced sütunu; test kümemizde f döndü), NOT NULL tanımları artık pg_constraint içinde saklanıyor ve adlandırılabiliyor, bölümlenmiş tablolarda NOT VALID yabancı anahtar mümkün. Ayrıntı primary key, foreign key ve kısıtlar yazısında.

Fonksiyonlar ve veri tipleri

Notlardaki yeni fonksiyonlardan bazıları: büyük/küçük harf duyarsız eşleşme için casefold(), dizinin ilk boyutunu sıralayan array_sort() ve ters çeviren array_reverse(), crc32() ve crc32c(), gamma() ve lgamma(), EXTRACT() için WEEK seçeneği, to_number() için Roma rakamı (RN) desteği, diziler ve bileşik tipler üzerinde MIN()/MAX(). Unicode verisi 16.0.0'a güncellendi, tam büyük/küçük harf eşlemesi iyileştirildi, jsonb null değerleri skaler tiplere NULL olarak dönüştürülebiliyor ve Estonca için full text search kök bulma desteği geldi.

sql
SELECT array_sort(ARRAY[3,1,2]) AS sirali, array_reverse(ARRAY[1,2,3]) AS ters;
text
 sirali  |  ters   
---------+---------
 {1,2,3} | {3,2,1}
(1 row)

Collation tarafında builtin sağlayıcıya PG_UNICODE_FAST eklendi ve LIKE artık nondeterministic collation ile çalışıyor; Türkçe açısından anlamı collation ve Türkçe sıralama yazısında. Dizi fonksiyonları için array veri tipi, JSON için JSONB kullanımı yazısına bakın.

Planlayıcı, indeks ve EXPLAIN

B-tree indeksler için skip scan geldi: notlara göre çok sütunlu bir B-tree indeksi, ilk sütunlarda koşul olmadığında (ya da eşitlik dışı koşul olduğunda) ve sonraki sütunlarda işe yarar koşullar bulunduğunda da kullanılabiliyor. Kılavuzun çok sütunlu indeks sayfası örneği (x, y) indeksi ve WHERE y = 7700 koşuludur. GIN indeksleri paralel oluşturulabiliyor. Planlayıcı bazı gereksiz self join'leri kendiliğinden kaldırıyor, bazı OR koşullarını dizilere çevirerek indeks işlemeyi hızlandırıyor ve diğer sütunlara fonksiyonel bağımlı GROUP BY sütunlarını yok sayıyor. İndeks seçimi için indeks türleri yazısına bakın.

EXPLAIN ANALYZE artık BUFFERS bilgisini kendiliğinden içeriyor, indeks tarama düğümü başına indeks arama sayısını raporluyor, satır sayılarını kesirli gösteriyor ve devre dışı bırakılmış düğümleri işaretliyor. Aynı sorguda bunların üçü birden görünüyor:

sql
EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM urun WHERE id = 1;
text
                          QUERY PLAN                           
---------------------------------------------------------------
 Index Scan using urun_pkey on urun (actual rows=1.00 loops=1)
   Index Cond: (id = 1)
   Index Searches: 1
   Buffers: shared hit=2
 Planning:
   Buffers: shared hit=5
(6 rows)

BUFFERS yazmadığımız hâlde Buffers: satırları geldi, Index Searches satırı yeni, rows=1.00 ise kesirli satır sayısı biçimidir. Planı okumayı EXPLAIN ANALYZE plan okuma yazısında bulabilirsiniz.

Yönetim, güvenlik ve bağlantı

Yönetim, güvenlik ve bağlantı: OAuth, MD5 kullanımdan kaldırılıyor, TLSv1.3 şifre takımları için ssl_tls13_ciphers eklendi, ssl_ecdh_curve parametresi ssl_groups adını aldı...
  • OAuth: pg_hba.conf için yeni oauth yöntemi, libpq OAuth seçenekleri ve doğrulama kitaplıklarını yükleyen oauth_validator_libraries parametresi eklendi; derlemede --with-libcurl gerekir. Bağlam için pg_hba.conf ve uzak bağlantı.
  • MD5 kullanımdan kaldırılıyor: MD5 parola desteği gelecekteki bir ana sürümde kaldırılacak. CREATE ROLE ve ALTER ROLE MD5 parola ayarlanırken uyarı veriyor; uyarı md5_password_warnings = off ile kapatılabilir. Rol yönetimi için kullanıcı ve rol yönetimi.
  • TLS: TLSv1.3 şifre takımları için ssl_tls13_ciphers eklendi, ssl_ecdh_curve parametresi ssl_groups adını aldı (eski ad çalışmaya devam ediyor) ve varsayılanı X25519'u içeriyor. Bkz. SSL/TLS şifreli bağlantı.
  • Kayıt ve izleme: log_connections artık yalnızca açık/kapalı değil, bağlantı aşamalarının sürelerini de raporlayabiliyor; log_line_prefix için istemci IP adresini yazan %L geldi; kilit alma başarısızlıklarını kaydeden log_lock_failures eklendi; pg_stat_all_tables VACUUM ve ANALYZE için harcanan süreyi, pg_stat_io bayt cinsinden I/O ve WAL etkinliğini gösteriyor. Bkz. pg_stat_activity ve pg_stat_statements.
  • Vacuum: normal vacuum bazı tümüyle görünür sayfaları da dondurabiliyor; autovacuum_vacuum_max_threshold ile autovacuum'u tetikleyen ölü satır sayısına sabit üst sınır verilebiliyor; autovacuum_worker_slots sayesinde autovacuum_max_workers yeniden başlatmadan değiştirilebiliyor. Bkz. VACUUM ve autovacuum.
  • Replikasyon: generated column değerleri logical replication ile aktarılabiliyor (publish_generated_columns), CREATE SUBSCRIPTION için streaming varsayılanı off yerine parallel oldu, uygulama sırasındaki çakışmalar kaydediliyor; boşta kalan slotlar idle_replication_slot_timeout ile otomatik geçersiz kılınabiliyor. Bkz. logical replication ve streaming replication.
  • COPY: ON_ERROR = 'ignore' ile birlikte REJECT_LIMIT ve LOG_VERBOSITY silent geldi; dolu materialized view'lar COPY TO ile aktarılabiliyor. Bkz. COPY ile CSV aktarımı.
  • psql: \parse, \bind_named, \close_prepared, pipeline komutları (\startpipeline ve diğerleri), liste komutlarında genişletilmiş görünüm için x soneki, tablo biçiminde \conninfo ve WATCH_INTERVAL değişkeni. Bkz. psql komutları.
  • Yedek araçları: pg_dump, pg_dumpall ve pg_restore için --statistics-only, --no-statistics, --no-data, --no-schema ve --no-policies; pg_combinebackup için --link; pg_verifybackup tar biçimini doğrulayabiliyor. Bkz. pg_dump ve pg_restore ile WAL arşivleme ve PITR.

Uyumsuzluklar: yükseltmeden önce okuyun

Notların "Migration to Version 18" bölümü önceki sürümlerle uyumu bozabilecek değişiklikleri listeler. Bunların her biri uygulamanızda davranış değişikliği yaratabilir:

DeğişiklikNe anlama gelir
initdb varsayılan olarak data checksums açarpg_upgrade aynı checksum ayarını ister; eski checksumsız küme için yeni küme initdb --no-data-checksums ile kurulabilir
Saat dilimi kısaltmalarıOturumun saat dilimi kısaltmaları timezone_abbreviations parametresinden önce kontrol edilir
MD5 parola doğrulaması kullanımdan kaldırılıyorCREATE ROLE ve ALTER ROLE MD5 parolada uyarı verir
VACUUM ve ANALYZE kalıtım çocuklarını da işlerEski davranış için yeni ONLY seçeneği
COPY FROM CSV okurken \. dosya sonu sayılmazpsql STDIN için hâlâ sayar; \. tek başına satırda olmalı; eski psql istemcileri \copy sorunları yaşayabilir
Unlogged bölümlenmiş tablo yasakALTER TABLE SET [UN]LOGGED önceden hiçbir şey yapmıyordu
AFTER trigger'lar olayın kuyruğa alındığı anki rolle çalışırRol işlem ortasında değişiyorsa sonuç farklı olabilir
GRANT/REVOKE içindeki işlevsiz RULE yetkisi kaldırıldı8.2'den beri çalışmıyordu
pg_backend_memory_contexts değiştiparent sütunu kaldırıldı, level bir tabanlı oldu
Full text search varsayılan collation sağlayıcısını kullanırICU veya builtin kümelerde FTS ve pg_trgm indeksleri yükseltme sonrası yeniden oluşturulmalı

Checksum değişikliğini test kümemizde de gördük: hiçbir seçenek vermeden initdb ile kurulan kümede SHOW data_checksums sonucu on oldu. MD5 uyarısı da gerçek çıktıdır:

sql
SET password_encryption = 'md5';
CREATE ROLE eski_uygulama LOGIN PASSWORD 'Deneme123';
text
WARNING:  setting an MD5-encrypted password
DETAIL:  MD5 password support is deprecated and will be removed in a future release of PostgreSQL.
HINT:  Refer to the PostgreSQL documentation for details about migrating to another password type.
CREATE ROLE

Bir başka uyarı Migration bölümünün dışında, kısıtlar başlığında yer alır: birincil anahtar/yabancı anahtar ilişkileri artık ya deterministik collation ya da iki tarafta aynı nondeterministic collation kullanmalıdır. Notlar, bu koşul sağlanmazsa pg_dump geri yüklemesinin (ve onu kullanan pg_upgrade'in) başarısız olacağını ve yükseltmeden önce şema değişikliği gerektiğini açıkça yazar.

18.1 ile 18.6 arasındaki önemli düzeltmeler

Ara sürümler yeni özellik getirmez ama güvenlik açıklarını ve hataları kapatır. Hepsinin notu "18.X kullananlar için döküm/geri yükleme gerekmez" der; bazıları ek işlem ister. 18.5 hiç yayımlanmadı; 18.6 notları bunun paketleme sonrası bulunan bir gerilemeden kaynaklandığını belirtir.

  • 18.1 (13 Kasım 2025): CREATE STATISTICS için şemada CREATE yetkisi denetimi (CVE-2025-12817) ve libpq'da bellek ayırma boyutu hesaplarında tamsayı taşması düzeltmesi (CVE-2025-12818).
  • 18.2 (12 Şubat 2026): çok baytlı karakter uzunluklarının yetersiz doğrulanması düzeltildi (CVE-2026-2006); notlara göre bundan sonra uygulamalar veritabanında saklanan geçersiz metinde "invalid byte sequence for encoding" hatası görebilir. ltree sütunlarındaki indeksler için yeniden indeksleme gerekebilir. Yerleşik olmayan seçicilik tahmincisini bir operatöre bağlamak için süper kullanıcı yetkisi istenir hâle geldi.
  • 18.3 (26 Şubat 2026): 18.2'deki kodlama düzeltmesinin fazla katı olduğu ve TOAST'lanmış verilerde substring() için yanlış hata verdiği durum düzeltildi. json_strip_nulls() ve jsonb_strip_nulls() yanlışlıkla stable işaretlenmişti; düzeltme yeni kümelere uygulanır, 18.0 ile 18.2 arasında oluşturulmuş kümeler için notlar elle bir katalog güncellemesi verir.
  • 18.4 (14 Mayıs 2026): başlangıç paketlerinde sınırsız özyineleme (CVE-2026-6479), bellek ayırma hesaplarında tamsayı taşmaları (CVE-2026-6473), pg_createsubscriber ve ALTER SUBSCRIPTION ... REFRESH PUBLICATION içinde ad tırnaklama sorunları, ts_headline() seçeneklerinin uzunluk denetimi.
  • 18.6 (13 Ağustos 2026): logical decoding çıktı eklentilerini yeni output_plugin_libraries parametresindeki listeyle sınırlama (CVE-2026-6471); varsayılan listede yalnızca pgoutput ve test_decoding vardır, başka eklenti kullananlar güncellemeden sonra listeye eklemelidir. Paralel GIN indeks oluşturmanın reltuples değerini bozabildiği hata düzeltildi; btree_gist ve ltree indeksleri için yeniden indeksleme gerekebilir.

18.6 notları GIN indeksli tabloların reltuples değerlerini denetlemek için bir sorgu önerir. Bozuk bir değer autovacuum ve autoanalyze'ın tabloyu hiç işlememesine yol açabilir ve kendiliğinden düzelmez; elle ANALYZE veya yeni bir indeks oluşturmak gerekir. Sorguyu test kümemizdeki GIN indeksli veritabanında çalıştırdık:

sql
SELECT DISTINCT t.oid::regclass, t.reltuples
FROM pg_class t
  JOIN pg_index i ON t.oid = i.indrelid
  JOIN pg_class ic ON i.indexrelid = ic.oid
WHERE t.relhasindex AND ic.relam = 2742;
text
  oid   | reltuples 
--------+-----------
 makale |         4
(1 row)

Değer tablodaki gerçek satır sayısıyla (4) uyumluydu. Infinity, NaN veya gerçek sayıdan çok farklı bir değer görürseniz tabloya ANALYZE çalıştırın. Bu örnekte kullandığımız sunucu 18.1 olduğu için 18.2 sonrası düzeltmeleri içermez; bu da güncel ara sürüme geçmenin neden ertelenmemesi gerektiğini gösterir.

Sık Sorulan Sorular

PostgreSQL 18'e geçmek için döküm almam gerekir mi?

Önceki bir ana sürümden geliyorsanız notlara göre pg_dumpall ile döküm/geri yükleme, pg_upgrade veya logical replication gerekir. 18.x içindeki ara sürüm geçişlerinde döküm gerekmez. Adımlar sürüm yükseltme yazısında.

Asenkron I/O'yu ayrıca açmam gerekir mi?

Kılavuza göre io_method varsayılanı worker'dır; yani asenkron I/O varsayılan olarak işçi süreçleriyle çalışır. Davranışı değiştirmek için parametreyi ayarlayıp sunucuyu yeniden başlatmanız gerekir, çünkü yalnızca başlangıçta okunur.

Mevcut generated column'larım virtual olacak mı?

Değişiklik, yeni bir tanımda STORED veya VIRTUAL yazılmadığında hangisinin seçileceğiyle ilgilidir. Virtual generated column 18 ile geldiği için önceki sürümlerde oluşturulmuş generated column'lar stored'dır. Bir sütunun türünü pg_attribute.attgenerated değerinden (s veya v) kontrol edebilirsiniz.

Hangi 18 ara sürümünü kullanmalıyım?

Kılavuza göre ara sürümler veri biçimini değiştirmez ve aynı ana sürümün diğer ara sürümleriyle uyumludur; yukarıdaki listede görüldüğü gibi her biri güvenlik ve hata düzeltmeleri getirir. Bu nedenle mevcut en yeni ara sürümü izlemek mantıklıdır. Bu yazı yazılırken belgelerdeki en yeni sürüm 18.6 idi.

Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.

İlgili içerikler: PostgreSQL öğrenme rehberi · Sürüm yükseltme · RETURNING ile OLD/NEW · EXPLAIN ANALYZE · Sık hatalar ve SQLSTATE · PostgreSQL nedir