Postgres'te büyük veritabanlarıyla çalışıyorsanız bu hikaye tanıdık gelecektir. Postgres veritabanınız büyümeye devam ettikçe performansınız düşmeye başlar ve depolama alanı konusunda, daha doğrusu, bunun için ne kadar ödeyeceğiniz konusunda endişelenmeye başlarsınız. PostgreSQL'i seviyorsunuz ama sahip olmayı dilediğiniz bir şey var: son derece etkili bir veri sıkıştırma mekanizması.
PostgreSQL'in bir çeşit sıkıştırma mekanizması vardır:
Veri kümelerinin boyutunu azaltsa bile TOAST (Büyük Boyutlu Öznitelik Depolama Tekniği), geleneksel veri sıkıştırma mekanizmanız değildir. TOAST'ın ne olduğunu anlamak için konuşarak başlamalıyız.
Postgres'in depolama birimlerine sayfalar denir ve bunların sabit bir boyutu vardır (varsayılan olarak 8 kB). Sabit bir sayfa boyutuna sahip olmak Postgres'e veri yönetimi basitliği, verimliliği ve tutarlılığı gibi birçok avantaj sağlar, ancak bunun bir dezavantajı da vardır: bazı veri değerleri o sayfaya sığmayabilir.
TOAST burada devreye giriyor. TOAST, PostgreSQL'in Postgres'te bir sayfaya sığmayan değerleri verimli bir şekilde depolamak ve yönetmek için kullandığı otomatik mekanizmayı ifade eder. Bu tür değerleri işlemek için Postgres TOAST, varsayılan olarak bunları dahili bir algoritma kullanarak sıkıştırır. Sıkıştırma sonrasında değerler hala çok büyükse, Postgres bunları ayrı bir tabloya (TOAST tablosu adı verilen) taşıyacak ve işaretçileri orijinal tabloda bırakacaktır.
Bu makalenin ilerleyen kısımlarında göreceğimiz gibi, kullanıcı olarak bu stratejiyi, örneğin Postgres'e belirli bir sütundaki verileri sıkıştırmaktan kaçınmasını söyleyerek değiştirebilirsiniz.
TOAST'a tabi tutulabilecek veri türleri, öncelikle standart bir PostgreSQL sayfasının boyut sınırlarını aşma potansiyeline sahip değişken uzunluktaki veri türleridir. Öte yandan, integer
, float
veya timestamp
gibi sabit uzunluktaki veri türleri, bir sayfaya rahatça sığdıkları için TOAST'a tabi değildir.
TOAST'a tabi tutulabilecek veri türlerinin bazı örnekleri şunlardır:
json
ve jsonb
Büyük text
dizeleri
varchar
ve varchar(n)
( varchar(n)
'de belirtilen uzunluk yeterince küçükse, o sütunun değerleri her zaman TOAST eşiğinin altında kalabilir.)
bytea
ikili verileri saklıyor
path
ve polygon
gibi geometrik veriler ve geometry
veya geography
gibi PostGIS türleri
TOAST'ı anlamak yalnızca sayfa boyutu kavramıyla değil aynı zamanda başka bir Postgres depolama konseptiyle de ilgilidir: tuple'lar. Tuple'lar PostgreSQL tablosundaki satırlardır. Tipik olarak TOAST mekanizması, bir demet içindeki tüm alanların toplam boyutu yaklaşık 2 kB'nin üzerindeyse devreye girer.
Eğer dikkat ettiyseniz, "Durun ama sayfa boyutu 8 kB civarında, neden bu ek yük?" diye merak ediyor olabilirsiniz. Bunun nedeni, PostgreSQL'in tek bir sayfada birden fazla tuple depolayabilmesini sağlamayı sevmesidir: eğer demetler çok büyükse, her sayfaya daha az tuple sığar, bu da G/Ç işlemlerinin artmasına ve performansın düşmesine neden olur.
Postgres'in ayrıca ek operasyonel verileri sığdırmak için boş alan tutması gerekir: her sayfa yalnızca demet verilerini değil aynı zamanda öğe tanımlayıcıları, başlıklar ve işlem bilgileri gibi verileri yönetmek için ek bilgileri de depolar.
Bu nedenle, bir demetteki tüm alanların toplam boyutu yaklaşık 2 kB'yi (veya daha sonra göreceğimiz gibi TOAST eşik parametresini) aştığında PostgreSQL, verilerin verimli bir şekilde saklanmasını sağlamak için harekete geçer. TOAST bunu iki temel yolla ele alır:
Sıkıştırma. PostgreSQL, bu makalenin ilerleyen kısımlarında ele alacağımız bir sıkıştırma algoritmasını kullanarak, demet içindeki büyük alan değerlerini sıkıştırarak boyutlarını küçültebilir. Varsayılan olarak, sıkıştırma, demetin toplam boyutunu eşiğin altına getirmeye yeterliyse, veriler sıkıştırılmış formatta da olsa ana tabloda kalacaktır.
Hat dışı depolama. Sıkıştırma tek başına büyük alan değerlerinin boyutunu küçültecek kadar etkili değilse Postgres bunları ayrı bir TOAST tablosuna taşır. Bu işlem "hat dışı" depolama olarak bilinir çünkü ana tablodaki orijinal demet artık büyük alan değerlerini tutmaz. Bunun yerine, TOAST tablosundaki büyük verilerin konumuna ilişkin bir "işaretçi" veya referans içerir.
Bu makale için işleri biraz basitleştiriyoruz—
pglz
TOAST'ın PostgreSQL'de büyük değerleri sıkıştırabildiğinden bahsetmiştik. Peki PostgreSQL hangi sıkıştırma algoritmasını kullanıyor ve ne kadar etkili?
pglz
(PostgreSQL Lempel-Ziv), özellikle TOAST için uyarlanmış PostgreSQL tarafından kullanılan varsayılan dahili sıkıştırma algoritmasıdır.
Çok basit bir ifadeyle şu şekilde çalışır:
pglz
tekrarlanan verilerden kaçınmaya çalışır. Tekrarlanan verileri gördüğünde aynı şeyi tekrar yazmak yerine sadece daha önce yazdığı yere işaret eder. Bu "tekrardan kaçınma" yerden tasarruf etmenize yardımcı olur.
pglz
verileri okurken, gördüğü son verilerin bir kısmını hatırlar. Bu son anıya "kayan pencere" adı veriliyor.
Yeni veriler geldikçe pglz
, bu verileri yakın zamanda (kayan pencerede) görüp görmediğini kontrol eder. Cevabınız evet ise verileri tekrarlamak yerine kısa bir referans yazar.
Veriler yeniyse veya referansı gerçek verilerden daha kısa hale getirecek kadar tekrarlanmadıysa, pglz
onu olduğu gibi yazar.
Sıkıştırılmış verileri okuma zamanı geldiğinde pglz
, orijinal verileri getirmek için referanslarını kullanır. Bu süreç, atıfta bulunulan verileri arayıp ait olduğu yere yerleştirdiği için oldukça doğrudandır.
pglz
belleği için ayrı bir depolamaya ihtiyacı yoktur (kayan pencere); hareket halindeyken sıkıştırırken onu oluşturur ve sıkıştırmayı açarken de aynısını yapar.
Bu uygulama, TOAST mekanizması içindeki sıkıştırma verimliliği ve hız arasında bir denge sağlamak üzere tasarlanmıştır. Sıkıştırma oranı açısından pglz
etkinliği büyük ölçüde verinin doğasına bağlı olacaktır.
Örneğin, yüksek oranda tekrarlanan veriler, yüksek entropili verilerden (rastgele veriler gibi) çok daha iyi sıkıştırılacaktır. Sıkıştırma oranlarının yüzde 25 ila 50 aralığında olduğunu görebilirsiniz, ancak bu çok genel bir tahmindir; sonuçlar, verinin kesin doğasına bağlı olarak büyük ölçüde farklılık gösterecektir.
Varsayılan olarak PostgreSQL, daha önce açıklanan prosedüre göre TOAST mekanizmasından geçecektir (sıkıştırma yeterli değilse önce sıkıştırma ve ardından hat dışı depolama). Yine de bu davranışa sütun başına ince ayar yapmak isteyebileceğiniz senaryolar olabilir. PostgreSQL bunu TOAST stratejilerini PLAIN
, EXTERNAL
, EXTENDED
ve MAIN
kullanarak yapmanıza olanak sağlar.
EXTENDED
: Bu varsayılan stratejidir. Bu, normal bir tablo sayfası için çok büyükse verilerin ayrı bir TOAST tablosunda sıra dışı olarak saklanacağı anlamına gelir. Veriler TOAST tablosuna taşınmadan önce yerden tasarruf sağlamak için sıkıştırılacaktır.
EXTERNAL
: Bu strateji, eğer veriler normal bir tablo sayfasına sığmayacak kadar büyükse, PostgreSQL'e bu sütuna ait verileri satır dışında saklamasını söyler ve biz de PostgreSQL'den verileri sıkıştırmamasını isteriz; değer yalnızca tablo sayfasına taşınacaktır. TOAST masası olduğu gibi.
MAIN
: Bu strateji bir orta yoldur. Sıkıştırma yoluyla verileri ana tabloda aynı hizada tutmaya çalışır; eğer veri kesinlikle çok büyükse, hatayı önlemek için veriyi TOAST tablosuna taşıyacaktır, ancak PostgreSQL sıkıştırılmış veriyi taşımayacaktır. Bunun yerine, değeri TOAST tablosunda orijinal biçiminde saklar.
PLAIN
: Bir sütunda PLAIN
kullanmak, PostgreSQL'e sütunun verilerini her zaman ana tablodaki satırda saklamasını söyler, böylece satır dışı TOAST tablosuna taşınmamasını sağlar. Veriler sayfa boyutunu aşarsa veriler sığmayacağından INSERT
başarısız olacağını göz önünde bulundurun.
Belirli bir tablonun mevcut stratejilerini incelemek istiyorsanız aşağıdakileri çalıştırabilirsiniz:
\d+ your_table_name
Bunun gibi bir çıktı alacaksınız:
=> \d+ example_table Table "public.example_table" Column | Data Type | Modifiers | Storage | Stats target | Description ---------+------------------+-----------+----------+--------------+------------- bar | varchar(100000) | | extended | |
Depolama ayarını değiştirmek isterseniz bunu aşağıdaki komutu kullanarak yapabilirsiniz:
-- Sets EXTENDED as the TOAST strategy for bar_column ALTER TABLE example_blob ALTER COLUMN bar_column SET STORAGE EXTENDED;
Yukarıdaki stratejilerin dışında, bu iki parametre de TOAST davranışını kontrol etmek için önemlidir:
TOAST_TUPLE_THRESHOLD
Bu, büyük boyutlu tuple'lar için TOASTing işlemlerinin (sıkıştırma ve hat dışı depolama) dikkate alındığı durumlar için boyut eşiğini ayarlayan parametredir.
Daha önce de belirttiğimiz gibi, varsayılan olarak TOAST_TUPLE_THRESHOLD
yaklaşık 2 kB'ye ayarlıdır.
TOAST_COMPRESSION_THRESHOLD
Bu, Postgres'in TOAST işlemi sırasında onu sıkıştırmayı düşünmesinden önce bir değerin minimum boyutunu belirten parametredir.
Bir değer bu eşiği aşarsa PostgreSQL onu sıkıştırmaya çalışacaktır. Bununla birlikte, bir değerin sıkıştırma eşiğinin üzerinde olması, otomatik olarak sıkıştırılacağı anlamına gelmez: TOAST stratejileri, PostgreSQL'e, sıkıştırılıp sıkıştırılmadığına ve sonuç boyutuna bağlı olarak verinin nasıl işleneceği konusunda rehberlik edecektir. Bir sonraki bölümde göreceğimiz gibi sayfa sınırları.
TOAST_TUPLE_THRESHOLD
tetikleme noktasıdır. Bir demetin veri alanlarının toplam boyutu bu eşiği aştığında PostgreSQL, sıkıştırma ve hat dışı depolamayı göz önünde bulundurarak sütunları için belirlenmiş TOAST stratejisine dayalı olarak bunun nasıl yönetileceğini değerlendirecektir. Gerçekleştirilen kesin işlemler aynı zamanda sütun verilerinin TOAST_COMPRESSION_THRESHOLD
değerini aşıp aşmadığına da bağlı olacaktır:
EXTENDED
(varsayılan strateji): Bir demetin boyutu TOAST_TUPLE_THRESHOLD
değerini aşarsa, PostgreSQL ilk önce büyük boyutlu sütunları, ayrıca TOAST_COMPRESSION_THRESHOLD
değerini de aşmaları durumunda sıkıştırmayı deneyecektir. Sıkıştırma demet boyutunu eşiğin altına getirirse ana tabloda kalacaktır. Aksi takdirde veriler, hat dışı TOAST tablosuna taşınacak ve ana tablo, bu harici verilere yönelik işaretçiler içerecektir.
MAIN
: Eğer demet boyutu TOAST_TUPLE_THRESHOLD
değerini aşarsa, PostgreSQL büyük boyutlu sütunları sıkıştırmaya çalışacaktır ( TOAST_COMPRESSION_THRESHOLD
değerinin üzerinde olmaları şartıyla). Sıkıştırma, demetin ana tablonun demetinin içine sığmasına izin veriyorsa, orada kalır. Değilse, veriler sıkıştırılmamış haliyle TOAST tablosuna taşınır.
EXTERNAL
: PostgreSQL, TOAST_COMPRESSION_THRESHOLD
değerine bakılmaksızın sıkıştırmayı atlar. Demetin boyutu TOAST_TUPLE_THRESHOLD
değerinin ötesindeyse, büyük boyutlu sütunlar TOAST tablosunda satır dışı olarak depolanacaktır.
PLAIN
: Veriler her zaman ana tabloda saklanır. Bir demetin boyutu sayfa boyutunu aşarsa (sütunların çok büyük olması nedeniyle), bir hata ortaya çıkar.
Strateji | Tuple > TOAST_COMPRESSION_THRESHOLD ise sıkıştır | Tuple > TOAST_TUPLE_THRESHOLD ise hat dışında depolayın | Tanım |
---|---|---|---|
UZATILMIŞ | Evet | Evet | Varsayılan strateji. Önce sıkıştırır, ardından hat dışı depolamanın gerekli olup olmadığını kontrol eder. |
ANA | Evet | Yalnızca sıkıştırılmamış biçimde | İlk önce sıkıştırılır ve eğer hala büyükse, sıkıştırma olmadan TOAST tablosuna taşınır. |
HARİCİ | HAYIR | Evet | Büyük boyutluysa, sıkıştırma olmadan her zaman TOAST'a geçer. |
OVA | HAYIR | HAYIR | Veriler her zaman ana tabloda kalır. Bir demet sayfa boyutunu aşarsa bir hata oluşur. |
Şimdiye kadar muhtemelen TOAST'ın neden PostgreSQL'de olmasını istediğiniz veri sıkıştırma mekanizması olmadığını anlayacaksınız. Modern uygulamalar, her gün büyük miktarda verinin alınmasını gerektirir; bu da veritabanlarının hızla (aşırı) büyümesi anlamına gelir.
Sevgili Postgres'imiz onlarca yıl önce geliştirildiğinde bu tür bir sorun bu kadar belirgin değildi, ancak günümüzün geliştiricileri, veri kümelerinin depolama alanını azaltmak için sıkıştırma çözümlerine ihtiyaç duyuyor.
TOAST, sıkıştırmayı tekniklerinden biri olarak dahil etse de, birincil rolünün geleneksel anlamda bir veritabanı sıkıştırma mekanizması olarak hizmet etmek olmadığını anlamak çok önemlidir. TOAST temel olarak tek bir soruna çözüm sunar: Postgres sayfasının yapısal sınırları içinde büyük değerleri yönetmek.
Bu yaklaşım, belirli büyük değerlerin sıkıştırılması nedeniyle bir miktar depolama alanı tasarrufuna yol açsa da, asıl amacı, depolama alanını genel olarak optimize etmek değildir.
Örneğin, küçük demetlerden oluşan 5 TB'lık bir veritabanınız varsa, TOAST bu 5 TB'yi 1 TB'ye dönüştürmenize yardımcı olmaz. TOAST'ta ayarlanabilen parametreler olsa da bu, TOAST'ı genelleştirilmiş, depolama tasarrufu sağlayan bir çözüme dönüştürmez.
Ayrıca TOAST'ı PostgreSQL'de geleneksel bir sıkıştırma mekanizması olarak kullanmanın doğasında olan başka sorunlar da vardır, örneğin:
TOAST'lanmış verilere erişim, özellikle veriler hat dışında depolandığında ek yük oluşturabilir. Bu, birçok büyük metin veya diğer TOAST özellikli veri türlerine sıklıkla erişildiğinde daha belirgin hale gelir.
TOAST, sıkıştırma politikalarını dikte etmek için üst düzey, kullanıcı dostu bir mekanizmadan yoksundur. Depolama maliyetlerini optimize etmek veya depolama yönetimini kolaylaştırmak için tasarlanmamıştır.
TOAST'ın sıkıştırması özellikle yüksek sıkıştırma oranları sağlayacak şekilde tasarlanmamıştır. Tipik olarak yüzde 25-50 arasında değişen sıkıştırma oranlarına sahip yalnızca bir algoritma ( pglz
) kullanır.
Büyük tablolarınıza sıkıştırma politikası ekleyerek,
Zamana dayalı bir sıkıştırma ilkesi tanımlayarak verilerin ne zaman sıkıştırılması gerektiğini belirtirsiniz. Örneğin yedi (7) günden eski verileri otomatik olarak sıkıştırmayı seçebilirsiniz:
-- Compress data older than 7 days SELECT add_compression_policy('my_hypertable', INTERVAL '7 days');
Bu sıkıştırma politikası aracılığıyla Timescale tabloyu dönüştürecek
Şamandıralar için Goril sıkıştırması
Delta-of-delta +
Birkaç yinelenen değere sahip sütunlar için tam satır sözlük sıkıştırması (üstte + LZ sıkıştırması)
Diğer tüm türler için LZ tabanlı dizi sıkıştırma
Bu sütunlu sıkıştırma tasarımı, PostgreSQL'deki büyük veri kümeleri sorununa etkili ve ölçeklenebilir bir çözüm sunar. Sorgu performansınıza zarar vermeden daha fazla veri depolamak için daha az depolama alanı kullanmanıza olanak tanır (iyileştirir). Ayrıca TimescaleDB'nin en son sürümlerinde, doğrudan sıkıştırılmış veriler üzerinden INSERT
, DELETE
ve UPDATE
işlemlerini de gerçekleştirebilirsiniz.
Bu makalenin, TOAST'ın bir PostgreSQL sayfasındaki büyük değerleri yönetmek için iyi düşünülmüş bir mekanizma olmasına rağmen, modern uygulamalar alanında veritabanı depolama kullanımını optimize etmede etkili olmadığını anlamanıza yardımcı olacağını umuyoruz.
Depolama tasarruflarınızda ilerleme kaydedebilecek etkili veri sıkıştırma arıyorsanız Timescale'i bir deneyin. PostgreSQL'i yeni performans seviyelerine taşıyan, onu daha hızlı ve daha güçlü hale getiren bulut platformumuzu deneyebilirsiniz.
Carlota Soto'nun yazdığı.