পোস্টগ্র্রেএসকিউএলে সমবর্তী ডিলিট / ইনসার্টের সাথে সমস্যাটি লক করা


35

এটি বেশ সহজ, তবে আমি পিজি কী করে (v9.0) দ্বারা বিস্মিত। আমরা একটি সাধারণ টেবিল দিয়ে শুরু:

CREATE TABLE test (id INT PRIMARY KEY);

এবং কয়েকটি সারি:

INSERT INTO TEST VALUES (1);
INSERT INTO TEST VALUES (2);

আমার প্রিয় জেডিবিসি ক্যোয়ারী সরঞ্জাম (এক্সিকিউটকিউরি) ব্যবহার করে, আমি এই টেবিলটি যেখানে বাস করি সেখানে ডিবিতে দুটি সেশন উইন্ডো সংযুক্ত করি। উভয়ই লেনদেনের (যেমন, স্বতঃ-প্রতিশ্রুতি = মিথ্যা)। আসুন তাদের এস 1 এবং এস 2 কল করুন।

প্রত্যেকের জন্য একই বিট কোড:

1:DELETE FROM test WHERE id=1;
2:INSERT INTO test VALUES (1);
3:COMMIT;

এখন, উইন্ডোতে একবারে একটিকে কার্যকর করে ধীর গতিতে এটি চালান।

S1-1 runs (1 row deleted)
S2-1 runs (but is blocked since S1 has a write lock)
S1-2 runs (1 row inserted)
S1-3 runs, releasing the write lock
S2-1 runs, now that it can get the lock. But reports 0 rows deleted. HUH???
S2-2 runs, reports a unique key constraint violation

এখন, এটি এসকিউএল সার্ভারে কাজ করে works এস 2 মুছে ফেললে, এটি 1 টি সারি মুছে ফেলা হয়েছে বলে প্রতিবেদন করে। এবং তারপরে এস 2 এর সন্নিবেশ সূক্ষ্মভাবে কাজ করে।

আমি সন্দেহ করি যে পোস্টগ্রেএসকিউএল সারণিটি সারণীতে তালিকার তালিকায় লক করছে যেখানে এসকিউএল সার্ভার প্রকৃত মূল্যের মানটি লক করে।

আমি কি সঠিক? এটি কি কাজ করা যায়?

উত্তর:


39

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

এখানে গুরুত্বপূর্ণ বিষয়টি হ'ল এসকিউএল স্ট্যান্ডার্ডের অধীনে READ COMMITTEDলেনদেনের বিচ্ছিন্নতা স্তরে চলমান লেনদেনের মধ্যে সীমাবদ্ধতা হ'ল অনির্ধারিত লেনদেনের কাজটি দৃশ্যমান হবে না। যখন অঙ্গীকারবদ্ধ লেনদেনের কাজ দৃশ্যমান হয় বাস্তবায়ন-নির্ভরশীল। আপনি কী দেখিয়ে দিচ্ছেন তা কীভাবে দুটি পণ্য এটি কার্যকর করতে বেছে নিয়েছে তার মধ্যে একটি পার্থক্য। উভয়ই বাস্তবায়ন মানের প্রয়োজনীয়তা লঙ্ঘন করছে না।

পোস্টগ্র্রেএসকিউএল-এর মধ্যে যা ঘটে তা এখানে বিশদে রয়েছে:

এস 1-1 রান (1 সারি মুছে ফেলা হয়েছে)

পুরাতন সারিটি জায়গায় রেখে দেওয়া হয়েছে, কারণ এস 1 এখনও পিছনে ফিরে আসতে পারে তবে এস 1 এখন সারিটিতে একটি লক ধরে রেখেছে যাতে সারিটি সংশোধন করার চেষ্টা করা অন্য কোনও অধিবেশন এস 1 কমিয়ে দেয় বা ফিরে যায় কিনা তা দেখার জন্য অপেক্ষা করবে। সারণীর যে কোনও পাঠ্য এখনও পুরানো সারিটি দেখতে পাবে, যদি না তারা এটিকে SELECT FOR UPDATEবা দিয়ে লক করার চেষ্টা করে SELECT FOR SHARE

এস 2-1 চালায় (তবে এস 1 এর লেখার লক থাকায় এটি অবরুদ্ধ রয়েছে)

এস 2 এর ফলাফল দেখতে এখন এস 2 অপেক্ষা করতে হবে। যদি এস 1 কমিট করার পরিবর্তে পিছনে ফিরে আসে, এস 2 সারিটি মুছবে। দ্রষ্টব্য যে S1 যদি পিছনে ঘূর্ণায়মানের আগে একটি নতুন সংস্করণ sertedোকায়, নতুন সংস্করণটি অন্য কোনও লেনদেনের দৃষ্টিকোণ থেকে কখনও হত না, বা অন্য কোনও লেনদেনের দৃষ্টিকোণ থেকে পুরানো সংস্করণটি মুছে ফেলা হত না।

এস 1-2 রান (1 সারি sertedোকানো)

এই সারিটি পুরানোটির চেয়ে স্বতন্ত্র। যদি আইডি = 1 দিয়ে সারিটির আপডেট থাকে তবে পুরানো এবং নতুন সংস্করণ সম্পর্কিত হবে এবং এস -2 সারণীর আপডেট হওয়া সংস্করণটি আনব্লকড হয়ে গেলে মুছতে পারে। একটি নতুন সারি অতীতে বিদ্যমান এমন কিছু সারির সমান মানগুলির সাথে ঘটে যা এ সারির আপডেট হওয়া সংস্করণের মতো হয় না।

এস 1-৩ চালায়, লেখার লকটি প্রকাশ করে

সুতরাং এস 1 এর পরিবর্তনগুলি বহাল রয়েছে। এক সারি চলে গেছে। একটি সারি যুক্ত করা হয়েছে।

এস 2-1 চালায়, এখন এটি লকটি পেতে পারে। তবে রিপোর্ট 0 টি সারি মুছে ফেলা হয়েছে। ওহো ???

অভ্যন্তরীণভাবে কী হয়, তা হ'ল এটির আপডেট করা থাকলে একটি সারির একটি সংস্করণ থেকে একই সারির পরবর্তী সংস্করণে একটি পয়েন্টার রয়েছে। যদি সারিটি মোছা হয়, তবে পরবর্তী কোনও সংস্করণ নেই। READ COMMITTEDলেখার বিরোধে কোনও ব্লক থেকে কোনও লেনদেন জাগ্রত হয়, এটি শেষ পর্যন্ত সেই আপডেট চেইন অনুসরণ করে; যদি সারিটি মোছা না করা হয়েছে এবং যদি এটি এখনও কোয়েরির নির্বাচনের মানদণ্ড পূরণ করে তবে এটি প্রক্রিয়া করা হবে। এই সারিটি মুছে ফেলা হয়েছে, সুতরাং এস 2 এর ক্যোয়ারী এগিয়ে চলেছে।

টেবিলটি স্ক্যান করার সময় এস 2 নতুন সারিতে উঠতে পারে বা নাও পারে। এটি যদি হয় তবে এটি দেখতে পাবে যে এস-এর DELETEবক্তব্য শুরুর পরে নতুন সারিটি তৈরি করা হয়েছিল এবং এটি সারিগুলির সেটটির অংশ নয়।

পোস্টগ্র্রেএসকিউএল যদি কোনও নতুন স্ন্যাপশট দিয়ে শুরু থেকে এস 2 এর সম্পূর্ণ ডিলিট স্টেটমেন্টটি পুনরায় চালু করতে থাকে তবে এটি এসকিউএল সার্ভারের মতোই আচরণ করবে। পোস্টগ্রিসএসকিউএল সম্প্রদায় পারফরম্যান্সের কারণে এটি করতে বেছে নেয় নি। এই সাধারণ ক্ষেত্রে আপনি পারফরম্যান্সের পার্থক্যটি কখনই লক্ষ্য করতে পারবেন না, তবে আপনি যখন আটকা পড়েছিলেন তখন যদি আপনি দশ মিলিয়ন সারি হয়ে থাকেন তবে DELETEআপনি অবশ্যই তা করতে পারেন। এখানে বাণিজ্য বন্ধ রয়েছে যেখানে পোস্টগ্র্যাস এসকিউএল কার্য সম্পাদনকে বেছে নিয়েছে, যেহেতু দ্রুত সংস্করণ এখনও স্ট্যান্ডার্ডের প্রয়োজনীয়তা মেনে চলে।

এস 2-2 চালায়, একটি অনন্য কী বাধা লঙ্ঘনের রিপোর্ট করেছে

অবশ্যই, সারি ইতিমধ্যে বিদ্যমান। এটি ছবির সবচেয়ে কম অবাক করা অংশ।

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

এখন, ব্যক্তিগতভাবে আমি কোনও পণ্যের বাস্তবায়নে READ COMMITTEDলেনদেনের বিচ্ছিন্নতা স্তরের কোনও বড় অনুরাগী নই । এগুলি সমস্ত দৌড়ের পরিস্থিতি লেনদেনের দিক থেকে অবাক করা আচরণ তৈরি করার অনুমতি দেয়। কেউ একবার একটি পণ্য দ্বারা অনুমোদিত অদ্ভুত আচরণে অভ্যস্ত হয়ে ওঠে, তারা সেই "স্বাভাবিক" এবং অন্য পণ্য দ্বারা নির্বাচিত ট্রেড-অফকে বিবেচ্য বলে বিবেচনা করে। তবে প্রতিটি পণ্যকে যে কোনও মোডের জন্য বাস্তবে রূপায়িত করা হয়নি তার জন্য কিছু প্রকারের বাণিজ্য বন্ধ করতে হবে SERIALIZABLE। পোস্টগ্র্রেএসকিউএল বিকাশকারীরা যেখানে লাইনটি আঁকতে বেছে নিয়েছেন READ COMMITTEDতা হ'ল ব্লকিং হ্রাস করা (রাইটগুলি ব্লক করবেন না এবং লেখেন না ব্লক রিডগুলি পড়ে না) এবং সিরিয়ালাইজেশন ব্যর্থতার সম্ভাবনা হ্রাস করা।

স্ট্যান্ডার্ডটির প্রয়োজন হয় যে SERIALIZABLEলেনদেনগুলি ডিফল্ট হয়, তবে বেশিরভাগ পণ্য তা করে না কারণ এটি আরও বেশি লেনদেনের বিচ্ছিন্নতা স্তরের উপর একটি কার্যকারিতা হিট করে। কিছু পণ্য এমনকি যখন SERIALIZABLEবেছে নেওয়া হয় সত্যিকারের সিরিয়ালাইজযোগ্য লেনদেন সরবরাহ করে না - উল্লেখযোগ্যভাবে ওরাকল এবং ৯.১ এর পূর্বে পোস্টগ্র্যাসকিউএলএর সংস্করণ। তবে সত্যিকারের SERIALIZABLEলেনদেনগুলি ব্যবহার করা জাতির পরিস্থিতি থেকে আশ্চর্যজনক প্রভাব এড়ানোর একমাত্র উপায়, এবং SERIALIZABLEলেনদেনের ক্ষেত্রে সর্বদা হয় প্রতিরোধের পরিস্থিতি এড়াতে অবরুদ্ধ হওয়া উচিত বা বিকাশমান বর্ণের পরিস্থিতি এড়াতে কিছু লেনদেন ব্যাক করতে হবে। SERIALIZABLEলেনদেনের সর্বাধিক সাধারণ বাস্তবায়ন হ'ল স্ট্রিক্ট টু-ফেজ লকিং (এস 2 পিএল) যা ব্লকিং এবং সিরিয়ালাইজেশন ব্যর্থতা উভয়ই (ডেডলক আকারে)।

সম্পূর্ণ প্রকাশ: এমআইটি-র ড্যান পোর্টসের সাথে পোস্টগ্র্রেএসকিউএল সংস্করণ 9.1-এ সিরিয়ালাইজেবল স্ন্যাপশট আইসোলেশন নামে একটি নতুন কৌশল ব্যবহার করে সত্যই সিরিয়ালযোগ্য লেনদেন যুক্ত করতে আমি কাজ করেছি।


আমি ভাবছি যদি এই কাজটি করার সত্যিই সস্তা (চিটসি?) উপায়টি হয় তবে INSERT এর পরে দুটি মুছে ফেলা হবে? আমার সীমিত (২ টি থ্রেড) পরীক্ষায় এটি ঠিক আছে, তবে এটি অনেক থ্রেড ধরে রাখে কিনা তা পরীক্ষা করার জন্য আরও পরীক্ষা করা দরকার।
ডেভিয়েবো

যতক্ষণ আপনি READ COMMITTEDলেনদেন ব্যবহার করছেন , আপনার প্রতিযোগিতার শর্ত রয়েছে: যদি অন্য প্রথম লেনদেন প্রথম DELETEশুরু হওয়ার পরে এবং দ্বিতীয়টি DELETEশুরুর আগে একটি নতুন সারি ?োকায় তবে কী হবে ? SERIALIZABLEবর্ণের পরিস্থিতি বন্ধ করার দুটি প্রধান উপায়ের চেয়ে কম কঠোর লেনদেনের সাথে দ্বন্দ্ব প্রচার (তবে সারিটি মুছে ফেলা হচ্ছে যখন তা সাহায্য করে না) এবং একটি সংঘাতের বাস্তবায়নের মাধ্যমে। আপনি "আইডি" সারণী রেখে প্রতিটি সারি মুছে ফেলার জন্য আপডেট করা বা স্পষ্টভাবে টেবিলটি লক করে দ্বন্দ্বকে বাস্তবায়িত করতে পারেন। অথবা ত্রুটিতে পুনরায় চেষ্টা করুন।
কেজিগ্রিটন

এটি আবার চেষ্টা করে। মূল্যবান অন্তর্দৃষ্টি জন্য অনেক ধন্যবাদ!
ডেভিয়েবো

21

আমি বিশ্বাস করি পোস্টগ্র্রেএসকিউএল 9.2 এর জন্য পঠিত প্রতিশ্রুতিবদ্ধ বিচ্ছিন্নতার স্তরের বিবরণ অনুসারে এটি নকশা দ্বারা is

আপডেট, মুছে ফেলুন, আপডেটের জন্য নির্বাচন করুন, এবং ভাগ করুন কমান্ডগুলি লক্ষ্য সারিগুলির অনুসন্ধানের ক্ষেত্রে নির্বাচন হিসাবে একই আচরণ করে: তারা কেবলমাত্র লক্ষ্য সারিগুলি আবিষ্কার করবে যা কমান্ড শুরুর সময় 1 অনুসারে প্রতিশ্রুতিবদ্ধ ছিল । যাইহোক, এই জাতীয় লক্ষ্য সারিটি ইতিমধ্যে অন্য সমবর্তী লেনদেনের দ্বারা এটি খুঁজে পাওয়ার আগেই আপডেট করা হয়েছে (বা মুছে ফেলা বা লক করা হয়েছে)। এই ক্ষেত্রে, আপ-দ্য আপডেটেটরটি প্রথম আপডেট করার লেনদেনটি কমিট বা রোল ব্যাক করতে অপেক্ষা করবে (যদি এটি এখনও প্রগতিতে থাকে)। যদি প্রথম আপডেটেটর পিছনে ঘূর্ণায়মান হয়, তবে এর প্রভাবগুলি উপেক্ষিত হয় এবং দ্বিতীয় আপডেটেটারটি মূলত পাওয়া সারিটি আপডেট করে এগিয়ে যেতে পারে। প্রথম আপডেটার করে, তাহলে দ্বিতীয় আপডেটার যদি প্রথম আপডেটার এটি মোছা সারি উপেক্ষা করা হবে 2অন্যথায় এটি তার অপারেশনটি সারিটির আপডেট হওয়া সংস্করণে প্রয়োগ করার চেষ্টা করবে।

আপনি যে সারিটি সন্নিবেশ করিয়েছেন সেটি শুরু S1হওয়ার পরে এখনও বিদ্যমান ছিল না । সুতরাং এটি উপরের ( 1 ) অনুযায়ী মোছার দ্বারা দেখা যাবে না । মুছে ফেলা একটিকে ( 2 ) এর অনুসারে উপেক্ষা করা হবে ।S2DELETES2S1S2DELETE

সুতরাং S2, মুছুন কিছুই করে না। যখন সন্নিবেশ যদিও বরাবর আসে, যেটা করে দেখতে S1'র সন্নিবেশ:

পড়ুন প্রতিশ্রুতিবদ্ধ মোড প্রতিটি কমান্ডকে একটি নতুন স্ন্যাপশট দিয়ে শুরু করে যার সাথে তাত্ক্ষণিকভাবে প্রতিশ্রুতিবদ্ধ সমস্ত লেনদেন অন্তর্ভুক্ত রয়েছে, একই লেনদেনে পরবর্তী কমান্ডগুলি যে কোনও ক্ষেত্রে প্রতিশ্রুতিবদ্ধ সমবর্তী লেনদেনের প্রভাব দেখতে পাবে । উপরের ইস্যুতে বিষয়টি হ'ল একক কমান্ড ডাটাবেসটির একেবারে সামঞ্জস্যপূর্ণ ভিউ দেখে কিনা।

সুতরাং প্রবেশের চেষ্টা S2সীমাবদ্ধতা লঙ্ঘনের সাথে ব্যর্থ হয়।

সেই ডকটি পড়া চালিয়ে যাওয়া, পুনরাবৃত্তযোগ্য পড়া বা এমনকি সিরিয়ালাইজযোগ্য ব্যবহার করে আপনার সমস্যা সম্পূর্ণরূপে সমাধান হবে না - দ্বিতীয় সেশনটি মুছে ফেলার ক্ষেত্রে সিরিয়ালাইজেশন ত্রুটির সাথে ব্যর্থ হবে।

এটি আপনাকে যদিও লেনদেনটি আবার চেষ্টা করার অনুমতি দেয়।


ধন্যবাদ মাদুর। যা ঘটছে বলে মনে হচ্ছে, সেখানে যুক্তিটির কোনও ত্রুটি রয়েছে বলে মনে হয়। আমার কাছে মনে হয়, একটি READ_COMMITTED আইসো স্তরে, তবে এই দুটি বিবৃতি অবশ্যই একটি টিএক্সের মধ্যে সফল হতে হবে : পরীক্ষার মধ্য থেকে আইডি = 1 প্রবেশ করান পরীক্ষা ভ্যালু (1) এর অর্থ, যদি আমি সারিটি মুছুন এবং সারিটি সন্নিবেশ করান, তাহলে sertোকানো সফল হবে should এসকিউএল সার্ভার এই অধিকার পায়। যেমনটি হ'ল, আমি এমন একটি পণ্য যা এই উভয় ডাটাবেসের সাথে কাজ করতে হয় এমন পরিস্থিতিতে এই পরিস্থিতিটি মোকাবেলায় খুব কঠিন সময় কাটাচ্ছি।
ডেভ্যোবিজ

11

আমি @ ম্যাট এর দুর্দান্ত উত্তরের সাথে সম্পূর্ণ সম্মত । আমি কেবল অন্য উত্তর লিখি, কারণ এটি কোনও মন্তব্যে মাপসই হয় না।

আপনার মন্তব্যের উত্তরে: DELETEএস 2 ইনটি ইতিমধ্যে একটি নির্দিষ্ট সারি সংস্করণে আবদ্ধ। যেহেতু এদিকে এস 1 দ্বারা এটি হত্যা করা হয়েছে, এস 2 নিজেকে সফল মনে করে। তাত্ক্ষণিকভাবে নজরে না আসার পরেও ঘটনার ধারাবাহিকটি কার্যত এইরকম:

   এস 1 মোছা সফল  
এস 2 মোছা (প্রক্সি দ্বারা সফল - এস 1 থেকে মুছে ফেলা)  
   এস 1 এর মধ্যে পুনরায় INSERTs এর মধ্যে কার্যত মূল্য মুছে ফেলে  
এস 2 INSERT অনন্য কী বাধা লঙ্ঘনের সাথে ব্যর্থ

এটি সব ডিজাইনের মাধ্যমে। SERIALIZABLEআপনার প্রয়োজনের জন্য আপনার সত্যিকারের লেনদেনগুলি ব্যবহার করা উচিত এবং নিশ্চিত হয়ে নিন যে আপনি সিরিয়ালাইজেশন ব্যর্থতায় আবার চেষ্টা করছেন।


1

একটি ডিফলার প্রাথমিক কী ব্যবহার করুন এবং আবার চেষ্টা করুন।


টিপটির জন্য ধন্যবাদ, তবে ডিফারালਬਲ ব্যবহার করে কোনও পার্থক্য হয়নি। ডকটি পড়ার মতো এটি পড়তে পারে তবে তা হয় না।
ডেভিয়েবো

-2

আমরাও এই সমস্যার মুখোমুখি হয়েছি। আমাদের সমাধান select ... for updateআগে যোগ করা হয় delete from ... where। বিচ্ছিন্নতা স্তরটি পড়তে হবে প্রতিশ্রুতিবদ্ধ।

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