En basit durumda, bir tabloya yeni bir satır eklediğimizde (ve işlem gerçekleştiğinde), sonraki tüm işlemler tarafından görülebilir. Bkz xmaxBu örnekte, 0 olan:
CREATE TABLE vis (
id serial,
is_active boolean
);
INSERT INTO vis (is_active) VALUES (FALSE);
SELECT ctid, xmin, xmax, * FROM vis;
ctid │xmin │ xmax │ id │ is_active
───────┼─────┼──────┼────┼───────────
(0,1) │2699 │ 0 │ 1 │ f
Güncellediğimizde (bayrak FALSEyanlışlıkla ayarlandığından ), biraz değişir:
UPDATE vis SET is_active = TRUE;
SELECT ctid, xmin, xmax, * FROM vis;
ctid │ xmin │ xmax │ id │ is_active
──────┼──────┼──────┼────┼───────────
(0,2) │ 2700 │ 0 │ 1 │ t
PostgreSQL'in kullandığı MVCC modeline göre , yeni bir fiziksel satır yazıldı ve eskisi geçersiz kılındı (bu, 'den görülebilir ctid). Yeni işlem, sonraki tüm işlemlerde görünmeye devam eder.
Şimdi geri döndüğümüzde ilginç bir şey var UPDATE:
BEGIN;
UPDATE vis SET is_active = TRUE;
ROLLBACK;
SELECT ctid, xmin, xmax, * FROM vis;
ctid │ xmin │ xmax │ id │ is_active
───────┼──────┼──────┼────┼───────────
(0,2) │ 2700 │ 2702 │ 1 │ t
Satır sürümü aynı kalır, ancak şimdi bir xmaxşeye ayarlanmıştır. Buna rağmen, sonraki işlemler bu (aksi takdirde değişmemiş) satırı görebilir.
Bu konuda biraz okuduktan sonra, satır görünürlüğü hakkında birkaç şey öğrenebilirsiniz. Orada görünürlük haritası , ancak yalnızca bir bütün sayfa görünür ise söyler - kesinlikle satır (lü) düzeyinde çalışmaz. Sonra kayıt günlüğü var (aka clog) - ama Postgres onu ziyaret etmek zorunda olup olmadığını nasıl anlar?
Görünürlüğün gerçekten nasıl çalıştığını anlamak için bilgi bitlerine bakmaya karar verdim . Bunları görmenin en kolay yolu pageinspect uzantısını kullanmaktır . Hangi bitlerin ayarlandığını bulmak için bunları saklamak için bir tablo oluşturdum:
CREATE TABLE infomask (
i_flag text,
i_bits bit(16)
);
INSERT INTO infomask
VALUES
('HEAP_HASNULL', x'0001'::bit(16)),
('HEAP_HASVARWIDTH', x'0002'::bit(16)),
('HEAP_HASEXTERNAL', x'0004'::bit(16)),
('HEAP_HASOID', x'0008'::bit(16)),
('HEAP_XMAX_KEYSHR_LOCK', x'0010'::bit(16)),
('HEAP_COMBOCID', x'0020'::bit(16)),
('HEAP_XMAX_EXCL_LOCK', x'0040'::bit(16)),
('HEAP_XMAX_LOCK_ONLY', x'0080'::bit(16)),
('HEAP_XMIN_COMMITTED', x'0100'::bit(16)),
('HEAP_XMIN_INVALID', x'0200'::bit(16)),
('HEAP_XMAX_COMMITTED', x'0400'::bit(16)),
('HEAP_XMAX_INVALID', x'0800'::bit(16)),
('HEAP_XMAX_IS_MULTI', x'1000'::bit(16)),
('HEAP_UPDATED', x'2000'::bit(16)),
('HEAP_MOVED_OFF', x'4000'::bit(16)),
('HEAP_MOVED_IN', x'8000'::bit(16)),
('HEAP_XACT_MASK', x'FFF0'::bit(16));
Daha sonra masamın içinde ne olduğunu kontrol visedin - pageinspectyığının fiziksel içeriğini gösteren not , böylece sadece görünür satırlar döndürülmez:
SELECT t_xmin, t_xmax, string_agg(i_flag, ', ') FILTER (WHERE (t_infomask::bit(16) & i_bits)::integer::boolean)
FROM heap_page_items(get_raw_page('vis', 0)),
infomask
GROUP BY t_xmin, t_xmax;
t_xmin │ t_xmax │ string_agg
────────┼────────┼──────────────────────────────────────────────────────
2699 │ 2700 │ HEAP_XMIN_COMMITTED, HEAP_XMAX_COMMITTED
2700 │ 2702 │ HEAP_XMIN_COMMITTED, HEAP_XMAX_INVALID, HEAP_UPDATED
2702 │ 0 │ HEAP_XMIN_INVALID, HEAP_XMAX_INVALID, HEAP_UPDATED
Yukarıda anladığım şey, ilk sürümün 2699 işlemiyle hayata geçirilmiş, daha sonra başarıyla 2700'de yeni sürümle değiştirilmiş olmasıdır.
Daha sonra 2700'den beri hayatta olan bir sonraki sürüm 2702'de geri çekilmiş bir girişime sahipti UPDATE. HEAP_XMAX_INVALID.
Sonuncusu asla gösterildiği gibi gerçekten doğmadı HEAP_XMIN_INVALID.
Yani, yukarıdan tahmin etmek, ilk ve son durum açıktır - 2703 veya daha yüksek işlemlerde artık görünmezler.
İkincisi bir yere bakmalı - sanırım bu işlem kayıt günlüğü, aka clog.
Sorunları daha da karmaşıklaştırmak için, daha sonra UPDATEaşağıdakilerle sonuçlanır:
t_xmin │ t_xmax │ string_agg
────────┼────────┼────────────────────────────────────────────────────
2699 │ 2700 │ HEAP_XMIN_COMMITTED, HEAP_XMAX_COMMITTED
2702 │ 0 │ HEAP_XMIN_INVALID, HEAP_XMAX_INVALID, HEAP_UPDATED
2703 │ 0 │ HEAP_XMAX_INVALID, HEAP_UPDATED
2700 │ 2703 │ HEAP_XMIN_COMMITTED, HEAP_UPDATED
Burada zaten görülebilecek iki aday görüyorum. Son olarak, işte sorularım:
clogBu durumlarda görünürlüğü belirlemek için bakılacak yer olduğu varsayımım mı ?- Hangi bayraklar (veya bayrak kombinasyonları) sisteme
clog? - İçinde ne olduğunu incelemenin bir yolu var mı
clog?clogPostgres'in önceki sürümlerinde yolsuzluktan bahsediliyor ve sahte bir dosyayı manuel olarak oluşturabileceğinize dair bir ipucu var. Bu bilgi bu konuda çok yardımcı olacaktır.