সারি দৃশ্যমানতা ঠিক কীভাবে নির্ধারণ করা হয়?


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 মডেল পোস্টগ্রি ব্যবহারসমূহ, একটি নতুন শারীরিক সারি লেখা হয়েছিল এবং পুরানো এক invalidated (এই থেকে দেখা যায় 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) আছে - তবে পোস্টগ্রিজ যদি এটি দেখতে হয় তবে কীভাবে তা নির্ধারণ করবে?

আমি দৃশ্যমানতা কীভাবে কাজ করে তা নির্ধারণের জন্য তথ্যমাস্ক বিটগুলিতে একবার তাকানোর সিদ্ধান্ত নিয়েছি । তাদের দেখতে, সবচেয়ে সহজ উপায় হচ্ছে পেইনস্পেক্ট এক্সটেনশনটি ব্যবহার করা । কোন বিট সেট করা আছে তা জানতে, আমি সেগুলি সংরক্ষণের জন্য একটি টেবিল তৈরি করেছি:

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? clogপোস্টগ্রিসের পূর্ববর্তী সংস্করণগুলিতে দুর্নীতি সম্পর্কে উল্লেখ রয়েছে এবং একটি ইঙ্গিত রয়েছে যে কেউ ম্যানুয়ালি একটি নকল ফাইল তৈরি করতে পারে। এই টুকরো টুকরো তথ্য এতে অনেক সাহায্য করবে।

উত্তর:


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, তবে সেই লেনদেনের স্বভাবটি কী ছিল তা দেখতে আপনাকে ক্লোজে যেতে হবে।

এই ঝাঁকুনির ভিতরে কী আছে তা পরীক্ষা করার কোনও উপায় আছে? পোস্টগ্রিসের পূর্ববর্তী সংস্করণগুলিতে ক্লোজ দুর্নীতির বিষয়ে উল্লেখ রয়েছে এবং একটি ইঙ্গিত রয়েছে যে কেউ ম্যানুয়ালি একটি নকল ফাইল তৈরি করতে পারে। এই টুকরো টুকরো তথ্য এতে অনেক সাহায্য করবে।

আমি এটি ব্যবহারকারীর পক্ষে বন্ধুত্বপূর্ণ পদ্ধতি সম্পর্কে অবগত নই। ক্লগ ফাইলগুলিকে পরিদর্শন করার জন্য একটি উপযুক্ত উপায়ে ডাম্প করতে আপনি "ওড" ব্যবহার করতে পারেন এবং ম্যাক্রোগুলি সংজ্ঞায়িত করে কোথায় পরিদর্শন করবেন তা নির্ধারণ করতে পারেনsrc/backend/access/transam/clog.c

আমি অবাক হয়েছি পিজিএক্সএন-তে কোনও এক্সটেনশন নেই যা আপনার পক্ষে কাজ করে তবে আমি এটি খুঁজে পাইনি। তবে আমি মনে করি এটি এতটা কার্যকর হবে না, কারণ আপনার সার্ভারটি চলমান না থাকাকালীন আপনার সত্যিই এটি করতে সক্ষম হওয়া দরকার।


4

কটাক্ষপাত আছে HeapTupleSatisfiesMVCC () বাস্তবায়ন: প্রকৃত clogচেক ঘটে TransactionIdDidCommit () , কিন্তু এটি শুধুমাত্র বলা হয় লেনদেন অবস্থা infomask বিট (থেকে অনুমিত করা যাবে না যদি HeapTupleHeaderXminCommitted () ম্যাক্রো এবং বন্ধুদের)।

আমি pg_clogফাংশনগুলিতে অ্যাক্সেস ফিরে পেয়েছি TransactionDidCommit()এবং TransactionDidAbort()তারপরে আমি অনুসন্ধান করেছি যেখানে এগুলি বলা হয় এবং আপনার প্রশ্নের সাথে সম্পর্কিত কোডের একমাত্র জায়গাটি মনে হয় HeapTupleSatisfiesMVCC()। এই ফাংশনটির কোড থেকে আপনি দেখতে পাবেন যে টিপলটিতে সম্পর্কিত তথ্যমাস্ক বিটস সেট না থাকলেই প্রকৃত ক্লগ লুকআপটি ঘটতে পারে: কোডটি HeapTupleHeaderXminCommitted()এট আল দিয়ে বিটগুলি পরীক্ষা করে শুরু হয় । বিট (গুলি) সেট না করা থাকলে এবং ক্লোগ লুকআপ কেবল তখনই ঘটে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.