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:
SHOW io_method; -- sonuç: workerAynı 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

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:
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; 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:
SELECT attname, attgenerated FROM pg_attribute
WHERE attrelid = 'urun'::regclass AND attname = 'kdvli'; 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:
SELECT uuid_extract_version(uuidv7()) AS surum, uuid_extract_version(uuidv4()) AS surum4; 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:
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)');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.
SELECT array_sort(ARRAY[3,1,2]) AS sirali, array_reverse(ARRAY[1,2,3]) AS ters; 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:
EXPLAIN (ANALYZE, COSTS OFF, TIMING OFF, SUMMARY OFF) SELECT * FROM urun WHERE id = 1; 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ı

- OAuth:
pg_hba.confiçin yenioauthyöntemi, libpq OAuth seçenekleri ve doğrulama kitaplıklarını yükleyenoauth_validator_librariesparametresi eklendi; derlemede--with-libcurlgerekir. 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 ROLEveALTER ROLEMD5 parola ayarlanırken uyarı veriyor; uyarımd5_password_warnings = offile kapatılabilir. Rol yönetimi için kullanıcı ve rol yönetimi. - TLS: TLSv1.3 şifre takımları için
ssl_tls13_cipherseklendi,ssl_ecdh_curveparametresissl_groupsadı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_connectionsartık yalnızca açık/kapalı değil, bağlantı aşamalarının sürelerini de raporlayabiliyor;log_line_prefixiçin istemci IP adresini yazan%Lgeldi; kilit alma başarısızlıklarını kaydedenlog_lock_failureseklendi;pg_stat_all_tablesVACUUM ve ANALYZE için harcanan süreyi,pg_stat_iobayt 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_thresholdile autovacuum'u tetikleyen ölü satır sayısına sabit üst sınır verilebiliyor;autovacuum_worker_slotssayesindeautovacuum_max_workersyeniden başlatmadan değiştirilebiliyor. Bkz. VACUUM ve autovacuum. - Replikasyon: generated column değerleri logical replication ile aktarılabiliyor (
publish_generated_columns),CREATE SUBSCRIPTIONiçinstreamingvarsayılanıoffyerineparalleloldu, uygulama sırasındaki çakışmalar kaydediliyor; boşta kalan slotlaridle_replication_slot_timeoutile otomatik geçersiz kılınabiliyor. Bkz. logical replication ve streaming replication. - COPY:
ON_ERROR = 'ignore'ile birlikteREJECT_LIMITveLOG_VERBOSITY silentgeldi; dolu materialized view'larCOPY TOile aktarılabiliyor. Bkz. COPY ile CSV aktarımı. - psql:
\parse,\bind_named,\close_prepared, pipeline komutları (\startpipelineve diğerleri), liste komutlarında genişletilmiş görünüm içinxsoneki, tablo biçiminde\conninfoveWATCH_INTERVALdeğişkeni. Bkz. psql komutları. - Yedek araçları:
pg_dump,pg_dumpallvepg_restoreiçin--statistics-only,--no-statistics,--no-data,--no-schemave--no-policies;pg_combinebackupiçin--link;pg_verifybackuptar 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şiklik | Ne anlama gelir |
|---|---|
| initdb varsayılan olarak data checksums açar | pg_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ıyor | CREATE ROLE ve ALTER ROLE MD5 parolada uyarı verir |
| VACUUM ve ANALYZE kalıtım çocuklarını da işler | Eski davranış için yeni ONLY seçeneği |
| COPY FROM CSV okurken \. dosya sonu sayılmaz | psql STDIN için hâlâ sayar; \. tek başına satırda olmalı; eski psql istemcileri \copy sorunları yaşayabilir |
| Unlogged bölümlenmiş tablo yasak | ALTER TABLE SET [UN]LOGGED önceden hiçbir şey yapmıyordu |
| AFTER trigger'lar olayın kuyruğa alındığı anki rolle çalışır | Rol 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şti | parent sütunu kaldırıldı, level bir tabanlı oldu |
| Full text search varsayılan collation sağlayıcısını kullanır | ICU 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:
SET password_encryption = 'md5';
CREATE ROLE eski_uygulama LOGIN PASSWORD 'Deneme123';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 ROLEBir 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 STATISTICSiçin şemadaCREATEyetkisi 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.
ltreesü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()vejsonb_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_createsubscriberveALTER SUBSCRIPTION ... REFRESH PUBLICATIONiçinde ad tırnaklama sorunları,ts_headline()seçeneklerinin uzunluk denetimi. - 18.6 (13 Ağustos 2026): logical decoding çıktı eklentilerini yeni
output_plugin_librariesparametresindeki listeyle sınırlama (CVE-2026-6471); varsayılan listede yalnızcapgoutputvetest_decodingvardır, başka eklenti kullananlar güncellemeden sonra listeye eklemelidir. Paralel GIN indeks oluşturmanınreltuplesdeğerini bozabildiği hata düzeltildi;btree_gistveltreeindeksleri 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:
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; 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