पंक्ति की दृश्यता कितनी सटीक है?


10

सरलतम स्थिति में, जब हम एक नई पंक्ति को एक तालिका में डालते हैं (और लेन-देन शुरू होता है), तो यह सभी बाद के लेनदेन के लिए दिखाई देगा। xmaxइस उदाहरण में 0 देखें :

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

जब हम इसे अपडेट करते हैं (क्योंकि झंडा FALSEदुर्घटना से सेट हो गया था), यह थोड़ा बदलता है:

UPDATE vis SET is_active = TRUE;

SELECT ctid, xmin, xmax, * FROM vis;

 ctid  xmin  xmax  id  is_active 
──────┼──────┼──────┼────┼───────────
(0,2)  2700     0   1  t

MVCC मॉडल PostgreSQL उपयोगों के अनुसार , एक नई भौतिक पंक्ति लिखी गई थी और पुरानी को अमान्य कर दिया गया था (इसे इससे देखा जा सकता है ctid)। नया अभी भी सभी बाद के लेनदेन के लिए दिखाई दे रहा है।

अब जब हम वापस रोल करते हैं तो एक दिलचस्प बात होती है 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

पंक्ति संस्करण समान रहता है, लेकिन अब xmaxकुछ पर सेट है। इसके बावजूद, बाद के लेनदेन इसे (अन्यथा अपरिवर्तित) पंक्ति देख सकते हैं।

इस बारे में थोड़ा पढ़ने के बाद, आप पंक्ति दृश्यता के बारे में कुछ बातें जान सकते हैं। नहीं है दृश्यता मानचित्र , लेकिन यह केवल पता चलता है कि एक पूरे पेज दिखाई दे रहा है - यह निश्चित रूप से पंक्ति (टपल) स्तर पर काम नहीं करता। फिर कमिट लॉग (उर्फ clog) है - लेकिन पोस्टग्रेज यह पता लगाने के लिए कि यह कैसे जाना है?

मैंने यह देखने के लिए कि वास्तव में कैसे दृश्यता काम करती है, यह जानने के लिए infomask बिट्स पर एक नज़र डालने का फैसला किया । उन्हें देखने के लिए, सबसे आसान तरीका पेजिन्सपेक्ट एक्सटेंशन का उपयोग करना है । यह जानने के लिए कि कौन से बिट सेट हैं, मैंने उन्हें स्टोर करने के लिए एक टेबल बनाया:

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));

फिर जाँच की कि मेरी visमेज के अंदर क्या है - ध्यान दें कि pageinspectढेर की भौतिक सामग्री को दिखाता है, इसलिए न केवल दिखाई देने वाली पंक्तियाँ वापस आ जाती हैं:

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

जो मैं ऊपर से समझता हूं वह यह है कि पहला संस्करण 2699 के लेन-देन के साथ जीवन में आया, फिर 2700 पर नए संस्करण द्वारा सफलतापूर्वक प्रतिस्थापित किया गया।
फिर अगले एक, जो 2700 से जीवित था, UPDATE2702 में लुढ़का हुआ वापस प्रयास किया गया था, जिसे देखा गया था । HEAP_XMAX_INVALID
अंतिम वाला वास्तव में कभी पैदा नहीं हुआ था, जैसा कि दिखाया गया है HEAP_XMIN_INVALID

इसलिए, ऊपर से अनुमान लगाने पर, पहला और आखिरी मामला स्पष्ट है - वे 2703 या उच्चतर लेनदेन करने के लिए अब दिखाई नहीं दे रहे हैं।
दूसरे को कहीं और देखना पड़ता है - मुझे लगता है कि यह कमिट लॉग है, उर्फ clog

आगे के मुद्दों को जटिल बनाने के लिए, UPDATEनिम्नलिखित में परिणाम:

 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

यहां मुझे पहले से ही दो उम्मीदवार दिखाई दे रहे हैं जो दिखाई दे सकते हैं। तो, अंत में, यहाँ मेरे सवाल हैं:

  • क्या मेरी धारणा है कि clogइन मामलों में दृश्यता निर्धारित करने के लिए देखने के लिए जगह है?
  • कौन से झंडे (या झंडे का संयोजन) सिस्टम को यात्रा करने के लिए कहते हैं clog?
  • क्या यह जांचने का कोई तरीका है कि अंदर क्या है clog? clogPostgres के पुराने संस्करणों में भ्रष्टाचार के बारे में उल्लेख है और एक संकेत है कि कोई मैन्युअल रूप से एक नकली फ़ाइल बना सकता है। जानकारी का यह टुकड़ा इसके साथ बहुत मदद करेगा।

जवाबों:


6

इसलिए, ऊपर से अनुमान लगाने पर, पहला और आखिरी मामला स्पष्ट है - वे 2703 या उच्चतर लेनदेन करने के लिए अब दिखाई नहीं दे रहे हैं। दूसरे को कहीं और देखना पड़ता है - मुझे लगता है कि यह कमिट लॉग है, उर्फ ​​क्लॉग।

दूसरा एक है HEAP_XMAX_INVALID। इसका मतलब है कि इसे क्लॉग से परामर्श करने की आवश्यकता नहीं है, क्योंकि किसी ने पहले से ही ऐसा किया है, यह देखा है कि xmaxगर्भपात हो गया है, और एक "संकेत बिट" सेट करें ताकि भविष्य की प्रक्रियाओं को उस पंक्ति के लिए फिर से क्लॉग पर जाने की आवश्यकता न हो।

कौन से झंडे (या झंडे का संयोजन) सिस्टम को क्लॉग पर जाने के लिए कहते हैं?

यदि कोई नहीं है heap_xmin_committedया heap_xmin_invalid, तो आपको यह देखने के लिए क्लॉग पर जाना होगा कि एक्समिन का स्वभाव क्या था। यदि लेन-देन अभी भी जारी है, तो पंक्ति आपको दिखाई नहीं दे रही है और आप किसी भी झंडे को सेट नहीं कर सकते हैं। यदि लेन-देन प्रतिबद्ध या लुढ़का हुआ है, तो आप heap_xmin_committedया उसके heap_xmin_invalidअनुसार सेट करते हैं (यदि ऐसा करना सुविधाजनक है - यह अनिवार्य नहीं है) तो भविष्य के लोगों को इसे देखने की आवश्यकता नहीं है।

यदि xminवैध और प्रतिबद्ध है, और यदि xmaxशून्य नहीं है, और कोई भी heap_max_committedया नहीं है heap_max_invalid, तो आपको यह देखने के लिए क्लॉग पर जाना होगा कि उस लेनदेन का स्वभाव क्या था।

क्या यह जांचने का एक तरीका है कि क्लॉग के अंदर क्या है? Postgres के पुराने संस्करणों में भ्रष्टाचार के बारे में उल्लेख है और एक संकेत है कि कोई मैन्युअल रूप से एक नकली फ़ाइल बना सकता है। जानकारी का यह टुकड़ा इसके साथ बहुत मदद करेगा।

मैं ऐसा करने के एक उपयोगकर्ता के अनुकूल तरीके से अवगत नहीं हूँ। आप "ओग" का उपयोग कर सकते हैं ताकि वे कागज़ की फाइलों को उनके निरीक्षण के लिए उपयुक्त तरीके से डंप कर सकें, और यह पता लगा सकें कि मैक्रोज़ द्वारा परिभाषित मैक्रो का उपयोग करके कहाँ निरीक्षण किया जाए।src/backend/access/transam/clog.c

मुझे आश्चर्य है कि PGXN पर कोई एक्सटेंशन नहीं है जो आपके लिए काम करता है, लेकिन मुझे एक नहीं मिला। लेकिन मुझे लगता है कि यह सब उपयोगी नहीं होगा, क्योंकि आपके सर्वर के नहीं चलने पर आपको वास्तव में ऐसा करने में सक्षम होना चाहिए।


4

HeapTupleSatisfiesMVCC () कार्यान्वयन पर एक नज़र डालें : वास्तविक clogजाँच TransactionIdDidCommit () में होती है , लेकिन इसे केवल तभी कहा जाता है जब लेनदेन की स्थिति को इन्फोमस बिट्स ( HeapTupleHeaderXminCommitted) (मैक्रो और दोस्तों) से पता नहीं लगाया जा सकता है ।

मैंने pg_clogफ़ंक्शंस की पहुंच का पता लगाया है TransactionDidCommit()और TransactionDidAbort()फिर, मैंने देखा है कि ये कहाँ कहे जाते हैं और आपके प्रश्न से संबंधित कोड में एकमात्र स्थान है HeapTupleSatisfiesMVCC()। इस फ़ंक्शन के कोड से आप देख सकते हैं कि वास्तविक क्लॉग लुकअप केवल तभी हो सकता है जब टुपल में संबंधित infomask बिट्स सेट न हों: कोड की शुरुआत HeapTupleHeaderXminCommitted()एट अल के साथ बिट्स की जाँच से होती है । और clog लुकअप केवल तभी होता है जब बिट (s) सेट नहीं होते हैं।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.