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 xmax
Bu ö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 FALSE
yanlış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 vis
edin - pageinspect
yığı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 UPDATE
aş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:
clog
Bu 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
?clog
Postgres'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.