মাইএসকিউএল / ইনোডিবিতে লেনদেনের জন্য একটি সময়সীমা নির্ধারণ করা


11

এটি এই সম্পর্কিত প্রশ্ন থেকে উদ্ভূত হয়েছে , যেখানে আমি জানতে চেয়েছিলাম যে কীভাবে একটি তুচ্ছ ঘটনাতে ক্রমশ দুটি সংযোগ স্থাপন করতে বাধ্য করা যায় (যেখানে উভয়ই কেবল একটি একক সারিতে কাজ করে)। আমি একটি উত্তর পেয়েছি - SELECT ... FOR UPDATEউভয় লেনদেনের প্রথম লাইন হিসাবে ব্যবহার। তবে এটি একটি সমস্যার দিকে নিয়ে যায়: যদি প্রথম লেনদেনটি কখনই প্রতিশ্রুতিবদ্ধ বা ঘূর্ণিত না হয়, তবে দ্বিতীয় লেনদেনটি অনির্দিষ্টকালের জন্য অবরুদ্ধ করা হবে। innodb_lock_wait_timeoutপরিবর্তনশীল সেকেন্ড পরে যা ক্লায়েন্ট দ্বিতীয় লেনদেন করতে চেষ্টা বলা করা হবে "দুঃখিত, আবার চেষ্টা করুন" ... কিন্তু যতদূর আমি বলতে পারেন, তারা পরবর্তী সার্ভার রিবুট পর্যন্ত আবার চেষ্টা করতে চাই সংখ্যা সেট করে। তাই:

  1. অবশ্যই ROLLBACKকোনও লেনদেন চিরদিনের জন্য নিলে বাধ্য করার উপায় আছে ? আমি কি এই জাতীয় লেনদেনের জন্য ডেমন ব্যবহার করা উচিত এবং যদি তা হয় তবে এই জাতীয় ডেমন কেমন হবে?
  2. যদি কোনও সংযোগ মেরে ফেলা হয় wait_timeoutবা interactive_timeoutমধ্য-লেনদেন হয়, তবে কি লেনদেনটি আবার ঘুরিয়ে দেওয়া হবে? কনসোল থেকে এটি পরীক্ষা করার কোনও উপায় আছে কি?

স্পেসিফিকেশন : ছাড়innodb_lock_wait_timeout দেওয়ার আগে লক প্রকাশের জন্য লেনদেনের জন্য অপেক্ষা করা কয়েক সেকেন্ডের সংখ্যা নির্ধারণ করে; আমি যা চাই তা হ'ল লকটি মুক্তি দিতে বাধ্য করা way

আপডেট 1 : এখানে একটি সহজ উদাহরণ যা দেখায় innodb_lock_wait_timeoutযে দ্বিতীয় লেনদেনটি প্রথম দ্বারা অবরুদ্ধ নয় তা নিশ্চিত করার জন্য কেন পর্যাপ্ত নয়:

START TRANSACTION;
SELECT SLEEP(55);
COMMIT;

এর ডিফল্ট সেটিং সহ innodb_lock_wait_timeout = 50, এই লেনদেনটি 55 সেকেন্ড পরে ত্রুটি ছাড়াই সম্পূর্ণ করে। এবং যদি আপনি লাইনের UPDATEআগে একটি যুক্ত করেন SLEEP, তবে SELECT ... FOR UPDATEএকই ক্লায়ার চেষ্টা করে এমন অন্য ক্লায়েন্টের কাছ থেকে দ্বিতীয় লেনদেন শুরু করুন , এটি দ্বিতীয় লেনদেনের সময় বেরিয়ে আসে, ঘুমিয়ে পড়ে না এমন নয়।

আমি যা খুঁজছি তা হ'ল এই লেনদেনের বিশ্রামহীন ঘুমের জোর বন্ধ করার উপায়।

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

START TRANSACTION
SELECT ... FOR UPDATE

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


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

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

@ ট্রেভর: আপনার ফ্রেসিং পুরোপুরি পরিষ্কার ছিল। সম্পূর্ণ ভিন্ন জিনিস জিজ্ঞাসা করার জন্য আপনি কেবল নিজের প্রশ্ন আপডেট করেছেন, যা অত্যন্ত খারাপ রূপ।
হোবডেভ

প্রশ্নটি সর্বদা একই ছিল: প্রথম লেনদেনটি কখনই প্রতিশ্রুতিবদ্ধ বা ঘুরিয়ে না দেওয়া হয় এমন দ্বিতীয় সমস্যাটি অনির্দিষ্টকালের জন্য অবরুদ্ধ হয়ে যায় It's ROLLBACKএটি nসেকেন্ডের চেয়ে বেশি সময় নিলে আমি প্রথম লেনদেনের উপর জোর করতে চাই । এটি করার কোনও উপায় আছে?
ট্রেভর বার্নহ্যাম

1
@ ট্রেভরবার্নহ্যাম আমিও অবাক হয়েছি কেন MYSQLএই পরিস্থিতি রোধ করার জন্য কোনও কনফিগারেশন নেই? কারণ ক্লায়েন্টদের দায়িত্বজ্ঞানের কারণে সার্ভার হ্যাং গ্রহণযোগ্য নয়। আপনার প্রশ্নটি বুঝতে আমি কোনও অসুবিধা পাইনি এটি এটিও প্রাসঙ্গিক।
দিনোপ পলোলি

উত্তর:


10

অর্ধেকেরও বেশি এই থ্রেডটি সার্ভারফল্টে কীভাবে প্রশ্ন জিজ্ঞাসা করবেন সে সম্পর্কে মনে হয়। আমি মনে করি যে প্রশ্নটি বোঝায় এবং এটি বেশ সহজ: আপনি কীভাবে কোনও স্থগিত লেনদেনটিকে স্বয়ংক্রিয়ভাবে ফিরিয়ে আনবেন?

একটি সমাধান, আপনি যদি পুরো সংযোগটি হত্যা করতে ইচ্ছুক হন, তা হল ওয়েটটাইমআউট / ইন্টারেক্টিভ_টাইমআউট সেট করা। Https://stackoverflow.com/questions/9936699/mysql-rolback-on-transaction-with-lost-disconnected- সংযোগ দেখুন ।


3

যেহেতু আপনার প্রশ্নটি এখানে সার্ভারফল্টে জিজ্ঞাসা করা হয়েছে এটি ধরে নেওয়া যুক্তিযুক্ত যে আপনি একটি মাইএসকিউএল সমস্যাটির একটি মাইএসকিউএল সমাধান খুঁজছেন, বিশেষত জ্ঞানের ক্ষেত্রের মধ্যে যে কোনও সিস্টেম অ্যাডমিনিস্ট্রেটর এবং / অথবা ডিবিএতে দক্ষতা রয়েছে such বিভাগ আপনার প্রশ্নগুলির ঠিকানা:

যদি প্রথম লেনদেনটি কখনও প্রতিশ্রুতিবদ্ধ বা ঘূর্ণিত না হয়, তবে দ্বিতীয় লেনদেনটি অনির্দিষ্টকালের জন্য অবরুদ্ধ করা হবে

না, তা হবে না। আমি তোমাদের বুঝতে করছি না মনে innodb_lock_wait_timeout। এটি আপনার যা প্রয়োজন ঠিক তা করে।

এটি ম্যানুয়ালটিতে বর্ণিত একটি ত্রুটি সহ ফিরে আসবে:

ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
  • সংজ্ঞা অনুসারে, এটি অনির্দিষ্ট নয় । যদি আপনার অ্যাপ্লিকেশনটি পুনরায় সংযোগ স্থাপন করে এবং বারবার অবরুদ্ধ করে চলেছে তবে আপনার অ্যাপ্লিকেশনটি "অনির্দিষ্টকালের জন্য অবরুদ্ধ করা" হবে, লেনদেন নয়। দ্বিতীয় লেনদেনটি innodb_lock_wait_timeoutসেকেন্ডের জন্য খুব অবশ্যই অবরুদ্ধ।

ডিফল্টরূপে, লেনদেনটি আবার ঘুরিয়ে দেওয়া হবে না। এই ত্রুটিটি কীভাবে পরিচালনা করা উচিত, তা আবার চেষ্টা করা হচ্ছে না, বা পিছন ফিরে হচ্ছে তা ঠিক করার জন্য আপনার অ্যাপ্লিকেশন কোডের দায়িত্ব।

আপনি যদি স্বয়ংক্রিয় রোলব্যাক চান তবে এটি ম্যানুয়ালটিতেও ব্যাখ্যা করা হয়েছে:

বর্তমান লেনদেন পিছনে ঘূর্ণিত হয় না। (পুরো লেনদেনের রোল ফিরে পেতে, --innodb_rollback_on_timeoutবিকল্পটি দিয়ে সার্ভারটি শুরু করুন ।


উত্তর: আপনার অসংখ্য আপডেট এবং মন্তব্য

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

যাইহোক, আমি সেই প্রশ্নের উত্তরও দিতে পারি। মাইএসকিউএল প্রোটোকলের একটি "ক্যোয়ারির সময়সীমা" নেই। এর অর্থ হ'ল আপনি প্রথম অবরুদ্ধ লেনদেনের সময়সীমা শেষ করতে পারবেন না। এটি শেষ না হওয়া পর্যন্ত আপনাকে অপেক্ষা করতে হবে, বা সেশনটি মেরে ফেলতে হবে। সেশনটি মারা গেলে সার্ভারটি স্বয়ংক্রিয়ভাবে লেনদেনটি আবার রোল করবে।

কেবলমাত্র অন্য বিকল্পটি হ'ল এমন কোনও মাইএসকিএল লাইব্রেরি ব্যবহার করা বা লিখতে হবে যা অবরুদ্ধকরণ না করে I / O ব্যবহার করে যা আপনার অ্যাপ্লিকেশনটিকে এন সেকেন্ডের পরে কোয়েরি তৈরি করতে থ্রেড / কাঁটাচামচ মেরে ফেলবে। এই জাতীয় লাইব্রেরির প্রয়োগ ও ব্যবহার সার্ভারফল্টের আওতার বাইরে। এটি স্ট্যাকওভারফ্লোর জন্য উপযুক্ত প্রশ্ন ।

দ্বিতীয়ত, আপনি আপনার মন্তব্যে নিম্নলিখিতটি বলেছেন:

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

এটি আপনার আসল প্রশ্নে মোটেও স্পষ্ট ছিল না এবং এখনও নেই। আপনি মন্তব্যটিতে বরং এটি গুরুত্বপূর্ণ টিডবিটটি ভাগ করে নেওয়ার পরে এটি কেবল তাত্পর্যপূর্ণ হবে।

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


দুঃখিত, তবে যখন লেনদেনটি কোনও লকের জন্য অপেক্ষা করতে থাকে (ঠিকানার নাম এবং দলিল হিসাবে innodb_lock_wait_timeout), তখন আমার পক্ষে যে পরিস্থিতি ঘটেছিল তা তেমন হয় না: যেখানে ক্লায়েন্ট একটি COMMITবা করার পরিবর্তনের আগেই ঝুলে যায় বা ক্র্যাশ হয়ে যায় or ROLLBACK
ট্রেভর বার্নহ্যাম

@ ট্রেভর: আপনি কেবল ভুল এটি আপনার শেষের দিকে পরীক্ষা করা তুচ্ছ। আমি কেবল আমার শেষের দিকে এটি পরীক্ষা করেছি। দয়া করে আপনার ডাউনটোটটি ফিরিয়ে দিন।
হোবডেভ

@ হাবো, ঠিক আপনার অধিকারের অর্থ এই নয় যে সে এটি পছন্দ করবে।
ক্রিস এস

ক্রিস, আপনি ঠিক কীভাবে ব্যাখ্যা করতে পারেন? প্রথম লেনদেনের সমাধানের জন্য যদি কোনও COMMITবা ROLLBACKবার্তা না পাঠানো হয় তবে দ্বিতীয় লেনদেন কীভাবে ঘটবে ? Hobodave, সম্ভবত আপনি যদি আপনার পরীক্ষার কোড উপস্থাপন করেন তবে এটি সহায়ক হবে।
ট্রেভর বার্নহ্যাম

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

1

অনুরূপ পরিস্থিতিতে আমার দলটি পিটি-কিল ( https://www.percona.com/doc/percona-toolkit/2.1/pt-kill.html ) ব্যবহার করার সিদ্ধান্ত নিয়েছে । এটি (অন্যান্য জিনিসগুলির মধ্যে) খুব দীর্ঘ সময়ের জন্য চলছে এমন প্রশ্নের উপর খুন বা হত্যা করতে পারে। এরপরে এটি প্রতি X মিনিটে ক্রোনে চালানো সম্ভব।

সমস্যাটি হ'ল এমন একটি ক্যোয়ারী যা অপ্রত্যাশিতভাবে দীর্ঘ (যেমন অনির্দিষ্ট) মৃত্যুর সময় ছিল এমন একটি ব্যাকআপ পদ্ধতি লক করে যা পঠিত লক দিয়ে টেবিলগুলি ফ্লাশ করার চেষ্টা করেছিল, যা "টেবিলগুলি প্রবাহিত হওয়ার অপেক্ষায় থাকায়" সমস্ত অন্যান্য প্রশ্নকে লক আউট করে যা এর পরে কখনই শেষ হয় নি never কারণ তারা কোনও লকের জন্য অপেক্ষা করছেন না, যার ফলস্বরূপ অ্যাপ্লিকেশনটিতে কোনও ত্রুটি নেই, যা পরিণামে প্রশাসকদের কোনও সতর্কতা এবং অ্যাপ্লিকেশন থামেনি resulted

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


0

একটি সহজ সমাধান হ'ল আপনার প্রয়োজনীয় timeoutসময়ের চেয়ে বেশি সময় নেয় এমন প্রশ্নের সমাধানের জন্য একটি স্টোরেজ পদ্ধতি থাকা এবং innodb_rollback_on_timeoutএটির সাথে অপশনটি ব্যবহার করা।


-2

কিছুক্ষণের জন্য গুগল করার পরে, দেখে মনে হচ্ছে প্রতি লেনদেনের সময়সীমা নির্ধারণের সরাসরি কোনও উপায় নেই । আমি যে সন্ধান করতে পেরেছিলাম তার সেরা সমাধান এখানে:

আদেশ

SHOW PROCESSLIST;

আপনাকে বর্তমানে চালিত সমস্ত কমান্ড এবং সময় শুরু হওয়ার পরে (সেকেন্ডে) সহ একটি সারণী দেয়। যখন কোনও ক্লায়েন্ট কমান্ড দেওয়া বন্ধ করে দেয়, তখন তাদের Sleepকমান্ড দেওয়ার হিসাবে বর্ণনা করা হয়, Timeকলামটি তাদের শেষ কমান্ডটি সেকেন্ড হওয়ার পরে সেকেন্ডের সংখ্যা সহ। সুতরাং আপনি ম্যানুয়ালি প্রবেশ করতে পারেন এবং KILLসমস্ত কিছু যার একটি Timeমান আছে, বলুন, 5 সেকেন্ড যদি আপনি আত্মবিশ্বাসী হন যে আপনার ডাটাবেসে কোনও কোয়েরি 5 সেকেন্ডের বেশি না নেয়। উদাহরণস্বরূপ, যদি আইডি 3 সহ প্রক্রিয়াটির Timeকলামে 12 এর মান থাকে তবে আপনি করতে পারেন

KILL 3;

কেআইএলএল সিনট্যাক্সের ডকুমেন্টেশন থেকে বোঝা যায় যে সেই আইডি দিয়ে থ্রেড দ্বারা পরিচালিত একটি লেনদেন আবার ঘুরিয়ে দেওয়া হবে (যদিও আমি এটি পরীক্ষা করে নিই, সুতরাং সতর্ক থাকি)।

তবে কীভাবে এটি স্বয়ংক্রিয় করবেন এবং প্রতি 5 সেকেন্ডে সমস্ত ওভারটাইম স্ক্রিপ্টগুলিকে হত্যা করবেন? একই পৃষ্ঠায় প্রথম মন্তব্যটি আমাদের একটি ইঙ্গিত দেয়, তবে কোডটি পিএইচপিতে রয়েছে; মনে হয় যে আমরা একটি ব্যবহার করতে পারবেন না SELECTউপর SHOW PROCESSLISTমাইএসকিউএল ক্লায়েন্ট থেকে। তবুও, ধরুন আমাদের একটি পিএইচপি ডেমন রয়েছে যা আমরা প্রতি $MAX_TIMEসেকেন্ডে চালাই , এটি দেখতে এরকম কিছু দেখায়:

$result = mysql_query("SHOW FULL PROCESSLIST");
while ($row=mysql_fetch_array($result)) {
  $process_id=$row["Id"];
    if ($row["Time"] > $MAX_TIME) {
      $sql="KILL $process_id";
      mysql_query($sql);
  }
}

মনে রাখবেন যে এর সাথে সমস্ত অলস ক্লায়েন্ট সংযোগগুলি পুনরায় সংযোগ করতে বাধ্য করার পার্শ্ব প্রতিক্রিয়া হবে , কেবলমাত্র যারা দুর্ব্যবহার করছে।

কারোর যদি এর থেকে আরও ভাল উত্তর থাকে তবে আমি এটি শুনতে পছন্দ করব।

সম্পাদনা করুন:KILL এইভাবে ব্যবহার করার ক্ষেত্রে কমপক্ষে একটি গুরুতর ঝুঁকি রয়েছে । মনে করুন যে আপনি উপরের স্ক্রিপ্টটি KILL10 সেকেন্ডের জন্য নিষ্ক্রিয় প্রতিটি সংযোগে ব্যবহার করেন । কোনও সংযোগটি 10 ​​সেকেন্ডের জন্য নিষ্ক্রিয় হওয়ার পরে, কিন্তু KILLজারি হওয়ার আগে , যার সংযোগটি মারা হচ্ছে সেই ব্যবহারকারী একটি START TRANSACTIONআদেশ জারি করে । তারা তখন KILLএড। তারা UPDATEদু'বার চিন্তা করে একটি প্রেরণ করে এবং এ ROLLBACK। তবে, KILLতাদের আসল লেনদেনটি ফিরিয়ে আনার কারণে আপডেটটি তাত্ক্ষণিকভাবে পেরিয়ে গেছে এবং এটিকে আবার ঘুরিয়ে দেওয়া যাবে না! পরীক্ষার মামলার জন্য এই পোস্টটি দেখুন ।


2
এই মন্তব্যটি এই উত্তরটির ভবিষ্যতের পাঠকদের জন্য। এটি গ্রহণযোগ্য উত্তর হলেও দয়া করে এটি করবেন না।
হোবডেভ

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

6
মন্তব্যটি ফাঁক নয়। আপনার "সমাধান" ব্যবহারে কোনও প্রয়াস না করা ভবিষ্যতের সকল পাঠকদের জন্য এটি একটি সতর্কতা। দীর্ঘমেয়াদি চলমান লেনদেনগুলি স্বয়ংক্রিয়ভাবে হত্যা করা একতরফাভাবে ভয়ঙ্কর ধারণা is এটি কখনই করা উচিত নয় । এটাই ব্যাখ্যা। খুনের সেশনগুলি একটি আদর্শ নয়, ব্যতিক্রম হওয়া উচিত। মূল কারণ আপনার কল্পিত সমস্যার ব্যবহারকারী ত্রুটি। আপনি ডিবিএর জন্য প্রযুক্তিগত সমাধান তৈরি করেন না যারা সারিগুলিকে লক করে এবং তারপরে "চলে যায়"। তুমি তাদের গুলি চালিয়ে দাও।
হোবডেভ

-2

হোবডাভ যেমন একটি মন্তব্যে পরামর্শ দিয়েছে, কোনও কোনও ক্লায়েন্টের ক্ষেত্রে (যদিও দৃশ্যত, mysqlকমান্ড-লাইন ইউটিলিটি নয়) লেনদেনের জন্য সময়সীমা নির্ধারণ করা সম্ভব। এখানে রুবিতে অ্যাক্টিভেকর্ড ব্যবহার করে একটি বিক্ষোভ রয়েছে:

require 'rubygems'
require 'timeout'
require 'active_record'

Timeout::timeout(5) {
  Foo.transaction do
    Foo.create(:name => 'Bar')
    sleep 10
  end
}

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

KILLকমান্ড লাইন থেকে লেনদেনের বিপরীতে অ্যাক্টিভেকর্ডে লেনদেনের ক্ষেত্রে যদি জারি করা হয় তবে সেফ হওয়ার সুবিধাও রয়েছে । Https://dba.stackexchange.com/questions/1561/mysql-client- বিশ্বাসের- theyre- in- a- transaction- gets- killed- wreaks- haococ দেখুন ।

আমি আমার অন্যান্য উত্তরে পোস্ট করা মতো স্ক্রিপ্টের মাধ্যমে সার্ভার সাইডে সর্বাধিক লেনদেনের সময় প্রয়োগ করা সম্ভব বলে মনে হয় না।


আপনি অবহেলা করেছেন যে অ্যাক্টিভেকর্ড সিঙ্ক্রোনাস (ব্লক করে) I / O ব্যবহার করে। স্ক্রিপ্টটি যা করছে তা হ'ল রুবি স্লিপ কমান্ডকে বাধা দিচ্ছে। যদি আপনার Foo.createআদেশটি 5 মিনিটের জন্য অবরুদ্ধ থাকে তবে টাইমআউটটি এটি হত্যা করে না। এটি আপনার প্রশ্নে প্রদত্ত উদাহরণের সাথে সঙ্গতিপূর্ণ নয়। এ SELECT ... FOR UPDATEসহজেই দীর্ঘ সময়ের জন্য অন্য কোনও ক্যোয়ারী হিসাবে ব্লক করতে পারে।
হোবোডাভ

এটি লক্ষ করা উচিত যে প্রায় সমস্ত মাইএসকিএল ক্লায়েন্ট লাইব্রেরিগুলি I / O- কে ব্লক করে ব্যবহার করে, তাই আমার উত্তরে আপনাকে পরামর্শ দিতে হবে যে আপনাকে নিজের বা ব্লক করা আই / ও ব্যবহার করার প্রয়োজন নেই। সময়সীমা অকেজো হয়ে যাওয়ার একটি সহজ বোধ এখানে রয়েছে: gist.github.com/856100
hobodave

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

আমি আপনার দাবি করা ফলাফলগুলি সদৃশ করতে পারি না। আমি গিস্টটি ব্যবহার করতে গিস্টটি আপডেট করেছি ActiveRecord::Base#find_by_sql: gist.github.com/856100 আবার, এটি কারণ এআর ব্লকিং I / O ব্যবহার করে।
হোবডেভ

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