মাইএসকিউএল লক না করেই নির্বাচন করার কোনও উপায়?


126

প্রশ্ন:

SELECT COUNT(online.account_id) cnt from online;

তবে অনলাইন টেবিলটিও একটি ইভেন্টের মাধ্যমে সংশোধন করা হয়, তাই প্রায়শই আমি চালিয়ে তালা দেখতে পাই show processlist

মাইএসকিউএলে এমন কোনও ব্যাকরণ রয়েছে যা নির্বাচনী বিবৃতিটি লক না ঘটায়?

এবং আমি উপরে উল্লেখ করতে ভুলে গেছি যে এটি একটি মাইএসকিউএল স্লেভ ডাটাবেসে রয়েছে।

আমি my.cnf:transaction-isolation = READ-UNCOMMITTED দাসে যোগ করার পরে ত্রুটির সাথে দেখা হবে:

ত্রুটি 'বাইনারি লগিং সম্ভব নয়। বার্তা: InnoDB- এ লেনদেনের স্তর 'READ-UNCOMMITTED' ক্যোয়ারিতে বিনলগ মোড 'STATEMENT' 'র জন্য নিরাপদ নয়

সুতরাং, এটি করার একটি সুসংগত উপায় আছে?


3
অন্যদের ক্ষেত্রে যারা এই প্রশ্নটির মুখোমুখি হন এবং তাদের টেবিলে থাকা লকগুলি নিয়ে খুব কঠিন সময় কাটাচ্ছেন: মাইএসকিউএল কীভাবে অভ্যন্তরীণভাবে লক ব্যবহার করে তা স্টোরেজ ইঞ্জিনের উপর নির্ভর করে। নীচে @ জম্বাটে উত্তরটি পড়ুন।
সাইমন ফারসবার্গ

উত্তর:


169

"নলকের সাথে MYSQL" শীর্ষক একটি নিবন্ধ পেয়েছে

https://web.archive.org/web/20100814144042/http://sqldba.org/articles/22-mysql-with-nolock.aspx

এমএস এসকিউএল সার্ভারে আপনি নিম্নলিখিতগুলি করবেন:

SELECT * FROM TABLE_NAME WITH (nolock)

এবং MYSQL সমতুল্য

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ;

সম্পাদনা

মাইকেল মায়ার নীচের পরামর্শ দিয়েছেন (মন্তব্যগুলি থেকে)

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;
SELECT * FROM TABLE_NAME ;
COMMIT ;

54
ভবিষ্যতের পাঠকদের জন্য কেবলমাত্র একটি নোট যা আপনি মুছে ফেলতে চাইতে পারেন SESSIONএবং এইভাবে লেনদেনের স্তরটি কেবলমাত্র পরবর্তী লেনদেনে প্রয়োগ করা যেতে পারে। তারপরে, উপরের তৃতীয় বিবৃতিটি কেবল এর সাথে প্রতিস্থাপন করুন COMMIT। এটি এক্ষেত্রে অগ্রণী হবে তবে লেনদেন শেষ করে এবং ডিফল্ট বিচ্ছিন্নতার স্তরে পুনরায় সেট করার একটি পার্শ্ব-প্রতিক্রিয়া রয়েছে।
মাইকেল মায়ার

3
কেবল একটি নোট, সেই লিঙ্কটি মারা গেছে ... :(
দীর্ঘদা

5
দুঃখিত, তবে এখানে ইনোডিবি এবং মাইআইএসএএম-এর মধ্যে খুব গুরুত্বপূর্ণ পার্থক্য উল্লেখ না করার জন্য আমাকে এই উত্তরটি হ্রাস করতে হবে। উপরের @ এমজি দ্বারা উল্লিখিত হিসাবে, এটি InnoDB এর জন্য কাজ করবে তবে মাইআইএসএএম টেবিলগুলির জন্য নয়।
সাইমন ফারসবার্গ

4
@Craig এটা অবশ্যই বেঠিক যে MyISAM নির্বাচন প্রশ্নের সময় পড়ুন কেশ জারি না - সেখানে আছে যারা কেশ হয় InnoDB করার কেশ এবং প্রতিবাদী টেবিল কেশ, সমস্ত অনুরোধ করা লিখুন কেশ ব্লক এবং সম্পাদনের সময় সব পরবর্তী প্রশ্নের। মূল প্রশ্ন InnoDB সম্পর্কে করা যদিও বিচ্ছিন্নতা মাত্রা খুব MyISAM জন্য নেই বললেই চলে প্রদর্শিত - এর জন্য দস্তাবেজ SET TRANSACTIONবিবৃতি রাজ্য: "। এই বিবৃতি লেনদেন বিচ্ছিন্নতা স্তর, InnoDB টেবিলের উপর অপারেশন জন্য ব্যবহৃত সেট করে"
syneticon-dj

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

24

যদি টেবিলটি InnoDB হয় তবে দেখুন http://dev.mysql.com/doc/refman/5.1/en/innodb-cons Contin-read.html - এটি SELECTs "এর জন্য ধারাবাহিক-পঠন (কোনও লকিং মোড) ব্যবহার করে" যা করে আপডেটের জন্য বা শেয়ার মোডে লক ইন লন্ডন নির্দিষ্ট করবেন না যদি ইনোনোডবি_লকস_অ্যানস্যাফ_ফর্ম_বিনলগ বিকল্পটি সেট করা থাকে এবং লেনদেনের বিচ্ছিন্নতা স্তরটি সিরিয়ালিজেবল সেট করা না হয়। সুতরাং, নির্বাচিত টেবিল থেকে পঠিত সারিগুলিতে কোনও লক সেট করা নেই "।


16

ব্যবহার

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED.

সংস্করণ 5.0 ডক্স এখানে রয়েছে

সংস্করণ 5.1 ডক্স এখানে রয়েছে


2
আপনাকে ধন্যবাদ, আমি মনে করি এটি নিকটে, তবে এই বিবৃতিটি কতক্ষণ প্রভাব ফেলবে? আমি এই বিবৃতিটি পিএইচপি প্রোগ্রামে ব্যবহার করতে যাচ্ছি, এবং একবারে কোয়েরি শেষ হয়ে গেলে স্বয়ংক্রিয়ভাবে ট্রান্সঅ্যাকশন আইসোলেশন লেভেলটি পুনরায় সেট করা উচিত
ওমগ

14

আপনি মাইএসকিউএল ম্যানুয়ালটির এই পৃষ্ঠাটি পড়তে চাইতে পারেন । কোনও টেবিলটি কীভাবে লক হয়ে যায় তা নির্ভর করে এটি কোন ধরণের টেবিলের উপর নির্ভর করে।

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

InnoDB টেবিলগুলি সারি-স্তরের লকিং ব্যবহার করে এবং কোনও আপডেটের পরে পুরো টেবিলটি আপনার লক আপ করতে পারে না। InnoDB এর সাথে যুক্ত অন্যান্য ধরণের লকিংয়ের সমস্যা রয়েছে তবে আপনি এটি আপনার প্রয়োজনের সাথে মানিয়ে নিতে পারেন।


1
মাইসাম টেবিলগুলির জন্য "সেট ট্রান্সএকশন আইসোলেশন লেভেল রিড আনকমিটেড" কাজ করবে?
ওএমজি

5
মাইআইএসএএম টেবিলগুলি কোনও রূপে লেনদেনকে সমর্থন করে না। একটি লেনদেনমূলক ক্যোয়ারী একটি মাইআইএসএএম টেবিলে চলবে, সুতরাং আপনার উপরে উল্লিখিত ক্যোয়ারী কার্যকর হবে তবে এর কোনও প্রভাব নেই।
জুমব্যাট

1
তারপরে মাইআইএসএএম-এর ক্ষেত্রে SELECTS সারিবদ্ধভাবে এড়াতে আমি কী করতে পারি?
ওএমজি

6
মাইআইএসএএম-র ক্ষেত্রে সারিবদ্ধভাবে সারিবদ্ধভাবে এড়ানোর জন্য আমি কী করতে পারি? ইনোডাব এ স্যুইচ করুন। মাইআইএসএএম প্রতিটি প্রশ্নের জন্য টেবিল স্তরের লক ব্যবহার করে। এটাই বড় ত্রুটি।
ফ্রাঙ্ক ফার্মার

2

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

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

যদি আপনি খুব কমই রেকর্ড মুছে ফেলেন তবে আপনি 2 এর সমান সমকালীন_সিন্ট সেট করতে পারেন এবং ডেটা ফাইলের শেষে সন্নিবেশগুলি সর্বদা যুক্ত করা হবে। তারপরে বাছাই এবং সন্নিবেশগুলি একই সাথে ঘটতে পারে তবে আপনি যতগুলি রেকর্ড মুছুন না কেন (সমস্ত রেকর্ড বাদে) আপনার ডেটা ফাইলটি কখনই ছোট হবে না।

নীচের লাইনটি, যদি আপনার কোনও টেবিলে প্রচুর আপডেট থাকে, সন্নিবেশ করান এবং নির্বাচন করেন তবে আপনার এটি ইনোডিবি করা উচিত। আপনি কোনও সিস্টেমে অবিচ্ছিন্নভাবে টেবিলের প্রকারগুলি মিশ্রিত করতে পারেন।


1

মাইএসকিএল-তে নোংরা পঠন সক্ষম করার আরেকটি উপায় হ'ল সংযুক্তি: শেয়ার মোডে লক করুন

SELECT * FROM TABLE_NAME LOCK IN SHARE MODE; 

"যদি স্ব-স্বীকৃতিটি 1 তে সেট করা থাকে তবে লক ইন শেয়ার মোড এবং ফোর আপডেটের শর্তগুলির কোনও প্রভাব নেই" " ... এবং অটোকোমিট = 1 ডিফল্ট
মার্টিন জাভেরাক

0

এই রেফারেন্স থেকে :

আপনি যদি লক টেবিলগুলির সাথে স্পষ্টভাবে কোনও টেবিল লকটি অর্জন করেন তবে আপনি টেবিলটি লক থাকা অবস্থায় অন্যান্য সেশনগুলি সমবর্তী সন্নিবেশ সম্পাদন করতে সক্ষম করতে একটি পুনরায় লকের পরিবর্তে একটি পুনরায় পড়ুন স্থানীয় লকটির জন্য অনুরোধ করতে পারেন।


0

নির্বাচনগুলি InnoDB টেবিলগুলিতে আপনার যত্ন নেওয়া সাধারণত কোনও লকিং করে না। ডিফল্ট লেনদেনের বিচ্ছিন্নকরণ স্তরটির অর্থ নির্বাচনগুলি লক করে না।

অবশ্যই বিতর্ক এখনও ঘটে।


1
আমি জানি এই পোস্টটি পুরানো, তবে এই উত্তরটি খুব সাধারণ, এবং কখনও কখনও সত্য হয়। Dev.mysql.com/doc/refman/5.0/en/innodb-locks-set.html দেখুন । লক্স অবশ্যই হয় অর্জিত সার্চ জন্য, বিচ্ছিন্নতা স্তরের উপর নির্ভর করে। বিশেষত, এই ক্ষেত্রে, পোস্টারটি প্রতিলিপিযুক্ত ডেটাবেসগুলির সাথে লেনদেন করছে এবং স্পষ্টভাবে বলেছে যে সে show processlistআসলে লকগুলি দেখতে ব্যবহার করতে পারে । সুতরাং এটি ধরে নেওয়া নিরাপদ যে বাস্তবে লকগুলি নেওয়া হচ্ছে।
ক্রেগ

1
উত্তর সর্বদা সত্য is অবশ্যই, কিছু লকিং রয়েছে - ইনানোডাবের অভ্যন্তরে কিছু অভ্যন্তরীণ মিউটেক্স যা ব্যবহার করা হয় (উদাহরণস্বরূপ ইনডোডাব বাফার পুল মুটেক্স)। বেশিরভাগ ব্যবহারকারী এই লকগুলি সম্পর্কে যত্নবান হন না বা লক্ষ্য করেন না এবং এগুলি সাধারণত ডিডিএল অপারেশনের সময় বিতর্কিত হয় (যেমন যদি আপনার 16 জি বাফার পুল থাকে এবং অন্য থ্রেডে "ড্রপ টেবিল" করেন)। তবে এটি ডিফল্টরূপে কোনও সারি-লক নেয় না। যে আমি বোঝানো কি. উত্তর যদিও বেশ অস্পষ্ট ছিল।
MarkR

1
সর্বদা সবসময়? যদি লেনদেনের বিচ্ছিন্নতা স্তরটি সিরিয়ালাইজযোগ্যতে সেট করা হয় বা নির্বাচিত বিবৃতিটি লক ইন শেয়ার মোড ব্যবহার করে এবং স্বতঃসীমা অক্ষম করা থাকে তবে কী হবে? আমি অনেকগুলি (সবচেয়ে / সমস্ত?) ডাটাবেস সার্ভারগুলি এখন সত্য সিরিয়ালাইজেশনের পরিবর্তে ডিফল্টরূপে স্ন্যাপশট বিচ্ছিন্নতা ব্যবহার করে জানি, তবে এখনও সিরিয়ালাইজযোগ্য পাঠগুলি বাধ্য করার জন্য মাঝে মাঝে ন্যায়সঙ্গততা নেই? তবে মনে হচ্ছে আপনি বলছেন যে সমস্ত দূরবর্তী স্বাভাবিক ক্ষেত্রে মাইএসকিউএল-এ ডিফল্ট শর্তগুলি অন্যান্য থ্রেডগুলিকে প্রভাবিত করে পড়ার লক তৈরি করে না, তাই আপনার যে সমস্যা নেই তা নিয়ে চিন্তা করবেন না? আমি আমার ডাউনটি, বিটিডাব্লু পূর্বাবস্থায় ফেলার চেষ্টা করেছি। দুঃখিত ...
ক্রেগ

3
আমি বললাম "সাধারণত করবেন না"। আমি বোঝাতে চাইছি যদি আপনি একটি সাধারণ নির্বাচন করেন (আপডেট না করে বা শেয়ার মোডে লক না করে) এবং ডিফল্ট লেনদেনের বিচ্ছিন্নতা স্তরটি ব্যবহার করেন। বিচ্ছিন্নতা স্তর পরিবর্তন করার জন্য কিছু বৈধ মামলা আছে, তবে আমি কেবলমাত্র প্রতি সেশনের ভিত্তিতে এটি করতাম কখনই ডিফল্ট হয় না।
মার্কআর
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.