সারি লক কনটেন্টেশনের সন্ধান, ডিবাগিং এবং ফিক্স করা হচ্ছে


12

দেরিতে বন্ধ হয়েছি, আমি প্রচুর সারি লক বিবাদের মুখোমুখি হয়েছি। বিতর্ক টেবিলটি একটি বিশেষ টেবিল বলে মনে হচ্ছে।

এটি সাধারণত যা হয় -

  • বিকাশকারী 1 ওরাকল ফর্মস সামনের শেষ স্ক্রিন থেকে একটি লেনদেন শুরু করে
  • বিকাশকারী 2 একই স্ক্রিনটি ব্যবহার করে একটি আলাদা সেশন থেকে আরেকটি লেনদেন শুরু করে

~ 5 মিনিটে, সামনের প্রান্তটি প্রতিক্রিয়াহীন বলে মনে হচ্ছে। সেশনগুলি পরীক্ষা করা সারি লক যুক্তি দেখায়। প্রত্যেকে যে "সমাধান" প্রায়শই ছুড়ে ফেলে তা হ'ল সেশনগুলি মেরে ফেলা: /

ডাটাবেস বিকাশকারী হিসাবে As

  • সারি লক বিতর্ক দূর করতে কী করা যেতে পারে?
  • কোনও সঞ্চিত পদ্ধতির কোন লাইনটি এই সারি লক যুক্তি ঘটিয়েছে তা খুঁজে পাওয়া সম্ভব?
  • কোন কোডিং এরকম সমস্যা হ্রাস / এড়াতে / মুছে ফেলার সাধারণ গাইডলাইন কী হবে?

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


প্রশ্নের মধ্যে থাকা সারণীটি প্রচুর সন্নিবেশ এবং আপডেটের অধীনে রয়েছে, আমি বলব এটি সর্বাধিক ব্যস্ত ছকগুলির মধ্যে একটি। এসপি মোটামুটি জটিল - এটি সহজ করার জন্য - এটি বিভিন্ন টেবিল থেকে ডেটা এনে দেয়, এটি কাজের টেবিলগুলিতে পপুলেট করে, কাজের টেবিলে প্রচুর পাটিগণিতের ক্রিয়াকলাপ ঘটে এবং কাজের টেবিলের ফলাফল প্রশ্নের সারণিতে /োকানো / আপডেট করা হয়।


ডাটাবেস সংস্করণটি হল ওরাকল ডেটাবেস 10 জি এন্টারপ্রাইজ সংস্করণ প্রকাশ 10.2.0.1.0 - 64 বিট। উভয় সেশনে যুক্তির প্রবাহ একই ক্রমে কার্যকর করা হয়, লেনদেন খুব বেশি সময়ের জন্য উন্মুক্ত রাখা হয় না (বা কমপক্ষে আমার মনে হয় ), এবং লকগুলি লেনদেনের সক্রিয় প্রয়োগের সময় ঘটে।


আপডেট: সারণী সারি গণনাটি আমার প্রত্যাশার চেয়ে প্রায় 3.1 মিলিয়ন সারিতে বড়। এছাড়াও, একটি সেশনের ট্রেস করার পরে আমি দেখতে পেলাম যে এই টেবিলের আপডেটের দুটি বিবৃতি সূচকটি ব্যবহার করছে না। কেন এমন - আমি নিশ্চিত নই। কলামটি যেখানে অনুচ্ছেদে সূচিযুক্ত তা উল্লেখ করা হয়েছে। আমি বর্তমানে সূচকটি পুনর্নির্মাণ করছি।


1
@ সাথ্যা - আপনি কি সঞ্চিত পদ্ধতির জটিলতাটি বিস্তারিতভাবে বর্ণনা করতে পারেন? সন্দেহযুক্ত টেবিলটি কঠোর আপডেটের অধীনে বা sertোকানো হচ্ছে?
কোডারহক

বিদেশী কীগুলি এখানে কোনও ভূমিকা পালন করে? (কখনও কখনও এটির জন্য একটি সূচকের প্রয়োজন হয়) ডাটাবেসের কোন সংস্করণ রয়েছে? যুক্তির প্রবাহটি কি দুটি সেশনে একই ক্রমে কার্যকর করা হয়? লেনদেনটি কি দীর্ঘ সময়ের জন্য 'খোলা' রাখা হয়? ব্যবহারকারীদের সময় বা লেনদেনের সক্রিয় কার্যকারিতার সময় লকটি ঘটে?
ik_zelf

@ স্যান্ডি আমি প্রশ্নটি আপডেট করেছি
সত্যজিৎ ভাট

@ আমি_জেলফ আমি প্রশ্নটি আপডেট করেছি
সত্যাজিৎ ভাট

1
কেন এটি সমস্যা তা আমার কাছে স্পষ্ট নয় - ওরাকল যা করার কথা বলেছিল ঠিক সেভাবেই করছে, যা একক সারিতে অ্যাক্সেসকে সিরিয়ালাইজ করছে। কারও কাছে যদি এই সারি থাকে তবে আপনি এর পূর্ববর্তী সংস্করণটি পড়তে পারেন তবে লিখতে আপনাকে তাদের লকটি প্রকাশের জন্য অপেক্ষা করতে হবে। এর একমাত্র "ফিক্স" হ'ল হয় ক) মূর্খ না হওয়া এবং COMMITবা ROLLBACKযুক্তিসঙ্গত সময়ে বা খ) এমন ব্যবস্থা করুন যে একই সময়ে একই লোকেরা সর্বদা একই সারিতে চায় না।
গাইউস

উত্তর:


10

কোনও সঞ্চিত পদ্ধতির কোন লাইন এই সারি লক বিতর্ক সৃষ্টি করছে তা খুঁজে পাওয়া সম্ভব?

ঠিক নয় তবে আপনি এসকিউএল স্টেটমেন্টটি লকটির কারণ হয়ে উঠতে পারেন এবং পরিবর্তে পদ্ধতিতে সম্পর্কিত লাইনগুলি সনাক্ত করতে পারেন।

SELECT sid, sql_text
FROM v$session s
LEFT JOIN v$sql q ON q.sql_id=s.sql_id
WHERE state = 'WAITING' AND wait_class != 'Idle'
AND event = 'enq: TX - row lock contention';

কোডিংয়ের মাধ্যমে এ জাতীয় সমস্যাগুলি হ্রাস / এড়ানো / নির্মূল করার জন্য সাধারণ নির্দেশিকা কী হবে?

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

  • COMMITবারবার. প্রতিটি COMMITরিলিজ লক করে থাকে, তাই আপনি যদি ব্যাচে আপডেট করতে পারেন তবে একই সারিটির প্রয়োজন মতো অন্য সেশনের সম্ভাবনা হ্রাস পাবে।
  • নিশ্চিত করুন যে আপনি কোনও সারিগুলির মান পরিবর্তন না করে আপডেট করছেন না। উদাহরণস্বরূপ, UPDATE t1 SET f1=DECODE(f2,’a’,f1+1,f1);আরও নির্বাচনী (কম লক পড়ুন) হিসাবে আবার লিখতে হবে UPDATE t1 SET f1=f1+1 WHERE f2=’a’;। অবশ্যই যদি বিবৃতি পরিবর্তন করে এখনও সারণীর বেশিরভাগ সারি লক করে রাখে তবে পরিবর্তনের ফলে কেবল পঠনযোগ্যতার সুবিধা হবে।
  • সর্বাধিক বর্তমান মানটিতে একটি যোগ করতে কোনও সারণি লক না করে আপনি সিকোয়েন্স ব্যবহার করছেন তা নিশ্চিত করুন।
  • নিশ্চিত করুন যে আপনি কোনও ফাংশন ব্যবহার করছেন না যা কোনও সূচককে ব্যবহার না করার কারণ করছে। যদি ফাংশনটি প্রয়োজন হয় তবে এটিকে একটি ফাংশন ভিত্তিক সূচক হিসাবে বিবেচনা করুন।
  • সেটে চিন্তা করুন। পিএল / এসকিউএল ব্লকগুলি চালনা করে একটি লুপ আপডেট করে যা একটি একক আপডেটের বিবৃতি হিসাবে আবারও লেখা যায় কিনা তা বিবেচনা করুন। তা না হলে সম্ভবত বাল্ক প্রসেসিং ব্যবহার করা যেতে পারে BULK COLLECT ... FORALL
  • প্রথম UPDATEএবং দ্বিতীয়টির মধ্যে যে কাজটি হয় তা হ্রাস করুন COMMIT। উদাহরণস্বরূপ, যদি কোডটি প্রতিটি আপডেটের পরে ইমেল প্রেরণ করে তবে ইমেলগুলি সারিবদ্ধ করা এবং আপডেটগুলি প্রতিশ্রুতি দেওয়ার পরে সেগুলি প্রেরণ বিবেচনা করুন।
  • একটি SELECT ... FOR UPDATE NOWAITবা দ্বারা অপেক্ষা করে পরিচালনা করার জন্য অ্যাপ্লিকেশনটি ডিজাইন করুন WAIT 2। তারপরে আপনি সারিটি লক করতে অক্ষমতাটি ধরতে এবং ব্যবহারকারীকে জানাতে পারেন যে অন্য সেশন একই ডেটা পরিবর্তন করছে।

7

আমি বিকাশকারী দৃষ্টিকোণ থেকে একটি উত্তর সরবরাহ করব।

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

একটি হারানো আপডেট ঘটে যখন:

অধিবেশন 1: টমের কর্মচারী রেকর্ড পড়ুন

সেশন 2: টমের কর্মচারী রেকর্ড পড়ুন

সেশন 1: টমের কর্মচারী রেকর্ড আপডেট করুন

সেশন 2: টমের কর্মচারী রেকর্ড আপডেট করুন

সেশন 2 সেশন 1 এর পরিবর্তনগুলি কখনও না দেখে লিখিত থাকবে - ফলস্বরূপ আপডেটটি হারিয়েছে lost

আপনি হারানো আপডেটের একটি বাজে পার্শ্ব-প্রতিক্রিয়াটির অভিজ্ঞতা পেয়েছেন: অধিবেশন 2 অবরুদ্ধ করা যেতে পারে কারণ সেশন 1 এখনও কমিট করেনি। তবে প্রধান সমস্যাটি হ'ল সেশন 2 অন্ধভাবে রেকর্ডটি আপডেট করে। মনে করুন যে উভয় অধিবেশন বিবৃতি জারি করে:

UPDATE table SET col1=:col1, ..., coln=:coln WHERE id = :pk

উভয় বক্তব্যের পরে, সেশন 1 এর পরিবর্তনগুলি ওভাররাইট করা হয়েছে, সেশনের 2 ছাড়াই সেশন 1 দ্বারা সারিটি পরিবর্তন করা হয়েছে তা অবহিত করা হয়নি।


হারানো আপডেট (এবং বিতর্ক পার্শ্ব প্রতিক্রিয়া) কখনই ঘটবে না, সেগুলি 100% এড়ানো যায়। দুটি প্রধান পদ্ধতির সাথে তাদের প্রতিরোধ করার জন্য আপনার লকিং ব্যবহার করা উচিত: আশাবাদী এবং নিরাশাবাদী লকিং

1) হতাশাবাদী লকিং

আপনি একটি সারি আপডেট করতে চান। এই মোডে আপনি অন্যকে এই সারিতে সংশোধন করতে বাধা দেবেন row সারিটিতে একটি লক অনুরোধ করে ( SELECT ... FOR UPDATE NOWAITবিবৃতি)। যদি সারিটি ইতিমধ্যে সংশোধন করা হচ্ছে তবে আপনি একটি ত্রুটি বার্তা পাবেন যা আপনি চূড়ান্তভাবে শেষ ব্যবহারকারীর কাছে অনুবাদ করতে পারেন (এই সারিটি অন্য কোনও ব্যবহারকারী দ্বারা সংশোধিত হচ্ছে)। যদি সারিটি উপলভ্য থাকে তবে আপনার সংশোধনীগুলি (আপডেট করুন) করুন, তারপরে আপনার লেনদেন শেষ হলেই কমিট করুন।

2) আশাবাদী লকিং

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

SELECT <...>
  FROM table
 WHERE id = :id
   AND marker = :marker
   FOR UPDATE NOWAIT

যদি ক্যোয়ারী একটি সারিতে ফিরে আসে, আপনার আপডেট করুন। যদি এটি না হয়, এর অর্থ হ'ল আপনি যখন শেষ বার অনুসন্ধান করেছিলেন তখন থেকেই কেউ সারিটি পরিবর্তন করেছে। আপনাকে প্রক্রিয়াটি শুরু থেকেই পুনরায় চালু করতে হবে।

দ্রষ্টব্য: আপনার ডিবি অ্যাক্সেস করে এমন সমস্ত অ্যাপ্লিকেশনগুলির উপরে যদি আপনার সম্পূর্ণ বিশ্বাস থাকে তবে আপনি আশাবাদী লকিংয়ের জন্য সরাসরি আপডেটের উপর নির্ভর করতে পারেন। আপনি সরাসরি ইস্যু করতে পারেন:

UPDATE table
   SET <...>, 
       marker = marker + 1
 WHERE id = :id;

যদি বিবৃতিটি কোনও সারি আপডেট না করে তবে আপনি জানেন যে কেউ এই সারিটি পরিবর্তন করেছে এবং আপনাকে সর্বদা শুরু করা দরকার।

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

টি এল; ডিআর

  • এর আগে লক না রেখে কোনও সারি আপডেট করা অ্যাপ্লিকেশনটিকে সম্ভাব্য "হিমায়িত" করে দেয়। যদি ডিবি থেকে সমস্ত ডিএমএল আশাবাদী বা নিরাশাবাদী লক প্রয়োগ করে তবে এড়ানো যায়।
  • যাচাই করে নিন যে নির্বাচন বৈদ্যুতিন ফেরতের মানগুলি পূর্ববর্তী কোনও নির্বাচনের সাথে সামঞ্জস্যপূর্ণ (কোনও হারানো আপডেট সমস্যা এড়াতে)

5

এই উত্তরটি সম্ভবত ডেইলি ডাব্লুটিএফ-এ প্রবেশের যোগ্যতা অর্জন করবে।

ঠিক আছে, সেশনগুলি সন্ধান করার পরে এবং অনুসন্ধান করার পরে USER_SOURCE- আমি মূল কারণটি সন্ধান করেছি

  • কারণ, আশ্চর্যজনকভাবে ত্রুটিযুক্ত যুক্তি ছিল
  • সম্প্রতি, এসপিতে একটি আপডেট বিবৃতি যুক্ত করা হয়েছিল। আপডেট বিবৃতিটি মূলত পুরো টেবিলটি আপডেট করবে। স্পষ্টতই প্রশ্নে বিকাশকারী প্রয়োজনীয় বিবৃতি আপডেট করার জন্য যেখানে ক্লজগুলি ডান যুক্ত করার কথা ভুলে গিয়েছিলেন।
  • উপরে উল্লিখিত হিসাবে সারণিটি আপডেট করা হচ্ছে, সর্বাধিক লেনদেন করা সারণীগুলির মধ্যে একটি এবং এতে প্রচুর রেকর্ড রয়েছে। আপডেটটি দীর্ঘ, যন্ত্রণাদায়ক সময় নেবে।
  • ফলাফলটি ছিল যে অন্যান্য সেশনগুলি টেবিলে একটি লক পেতে সক্ষম হয় নি এবং সারি-লক বিতর্কে বসে।
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.