"লক অপেক্ষার সময়সীমা অতিক্রম করা; যদিও আমি কোনও লেনদেন ব্যবহার করছি না, যদিও লেনদেন পুনরায় চালু করার চেষ্টা করুন


266

আমি নিম্নলিখিত মাইএসকিউএল UPDATEবিবৃতি চালাচ্ছি :

mysql> update customer set account_import_id = 1;
ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction

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

সারণীতে 406,733 সারি রয়েছে।

উত্তর:


211

আপনি একটি লেনদেন ব্যবহার করছেন; স্বতঃসিদ্ধকরণ লেনদেন অক্ষম করে না, এটি কেবল বিবৃতি শেষে স্বয়ংক্রিয়ভাবে প্রতিশ্রুতিবদ্ধ করে তোলে।

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

আপনি একটি জারি করে ইভেন্টের আরও বিশদ দেখতে পারবেন

SHOW ENGINE INNODB STATUS

ইভেন্টের পরে ( sqlসম্পাদকে) আদর্শভাবে একটি শান্ত পরীক্ষা-মেশিনে এটি করুন।


1
কোনও ফাইলে আউটপুট সংরক্ষণ করার উপায় আছে কি? আমি ইঞ্জিন INNODB পরিস্থিতি </>> ইনোডাব_স্ট্যাট.টিএক্সটি দেখানোর চেষ্টা করেছি কিন্তু কাজ করে না।
ইয়ানতাক

14
কমান্ড লাইন থেকে: MySQL [সন্নিবেশ পরিচয়পত্র] -e "দেখান ইঞ্জিন InnoDB স্থিতি \ জি"> innodb_stat.txt
VenerableAgents

যদি অনেকগুলি mysql থ্রেড (বা প্রক্রিয়া) ব্যস্ত থাকে, উদাহরণস্বরূপ কিছু প্রশ্নের জন্য খুব দীর্ঘ সময় প্রয়োজন, তাই আপনাকে কিছুটা processনিষ্ক্রিয় হওয়ার জন্য অপেক্ষা করতে হবে। যদি তাই হয় তবে আপনি এই ত্রুটিটি পেতে পারেন। আমি কি সঠিক?
zhuguowei

6
একক লেনদেনের সময় একই সারিতে একাধিক (2+) আপডেটের ক্যোয়ারি চালানোও এই ত্রুটির কারণ হতে পারে।
ওকলনোপার

যারা পাইথন মাইএসকিউএল সংযোগকারী ব্যবহার করেন connection.commit()তাদের প্রতিশ্রুতিবদ্ধ করতে ব্যবহার করুন INSERTবা UPDATEআপনি সবেমাত্র গুলি করেছেন।
এআরই

334

মাইএসকিউএল-এ তালাবদ্ধ টেবিলগুলির জন্য কীভাবে আনলক করা যায়:

এটির মতো লকগুলি ভাঙ্গার ফলে ডাটাবেসের মধ্যে পারমাণবিকতা বজায় রাখা স্কোল স্টেটমেন্টে কার্যকর করা নাও হতে পারে।

এটি হ্যাকিশ, এবং সঠিক সমাধানটি হ'ল আপনার অ্যাপ্লিকেশনটি ঠিক করা যা লকগুলি ঘটায়। যাইহোক, ডলার যখন লাইনে থাকে, তখন একটি সুইফ্ট কিক জিনিসগুলি আবার চলতে পারে।

1) মাইএসকিউএল প্রবেশ করুন

mysql -u your_user -p

2) আসুন লক করা টেবিলগুলির তালিকাটি দেখুন

mysql> show open tables where in_use>0;

3) চলুন বর্তমান প্রক্রিয়াগুলির তালিকাটি দেখুন, এর মধ্যে একটির আপনার টেবিল (গুলি) লক করছে

mysql> show processlist;

4) এই প্রক্রিয়া এক হত্যা

mysql> kill <put_process_id_here>;

14
এটি বিপজ্জনক এবং হ্যাকিশ। আপনার অ্যাপ্লিকেশন ঠিক করা একটি যথাযথ সমাধান।
জেনেক্সার

71
বাজে কথা, এটি আপনাকে কোনও মেসআপটি পূর্বাবস্থায় ফেরাতে এবং তারপরে অ্যাপ্লিকেশনটি ঠিক করতে দেয়। আমি যদি এই ব্যক্তিকে এই সমস্যার জন্য 100 টি ভোট দিতে পারি যা আমাকে এখনই ঠিক করতে হয়েছিল।
Lizardx

7
আমি লিজার্ডেক্সের সাথে একমত এই অবস্থায় খুব দরকারী সমাধান ছিল যে আমি বিশেষাধিকার অবস্থা প্রদর্শন করে Name ইঞ্জিন InnoDB কল করতে হয়নি
ট্রাভিস Schneeberger

8
কীভাবে দীর্ঘমেয়াদী জিজ্ঞাসাটি হত্যা করা বিপজ্জনক ? ক্লায়েন্ট কলিং একটি ত্রুটি পাবেন।
শিওনক্রস

7
আমি তোমার পয়েন্ট পেতে @EricLeschinski, কিন্তু আমি জিজ্ঞাসা করতে কেন বিশ্বের তোমার মত পঙ্কিল ডাটাবেসের ব্যবহার করেন আছে মাইএসকিউএল একটি উপর লাইফ-সমালোচনামূলক ব্যবস্থা?
শিওনক্রস

96
mysql> set innodb_lock_wait_timeout=100

Query OK, 0 rows affected (0.02 sec)

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 100   |
+--------------------------+-------+

এবার আবার লকটি ট্রিগার করুন। আপনার কাছে SHOW ENGINE INNODB STATUS\Gডাটাবেসে একটি ইস্যু করার জন্য 100 সেকেন্ড সময় রয়েছে এবং কোন অন্যান্য লেনদেন আপনাকে লক করছে তা দেখুন।


8
এই উত্তরটি কেন ব্যাখ্যাকারীকে তাদের ত্রুটি পাচ্ছে তা ব্যাখ্যা করে না। শুধু উত্তর দেওয়ার পাশাপাশি কেন আপনি বিশদটি বলতে পারেন?
স্লেড

5
+1 যদিও এটি সরাসরি প্রশ্নের উত্তর দেয় না, তবে আমার কাছে এটি এই সমস্যার সমাধানের জন্য একটি ভাল রেফারেন্স।
জোসেফ হারুশ

1
@ আর্টবি ডেভ.মাইসকিএল.ডোক / নিন্ডব/ ১১/ ২০১৮/ ২ মূলত ওপি ত্রুটিটি পাচ্ছে কারণ টেবিলের উপরে একটি লক ডেকে আনা হয়েছিল এবং লেনদেন শেষ হওয়ার আগে lock_wait_timeout
সময়টি ব্যয়

70

আপনার ডাটাবেসটি ঠিক আছে কিনা তা একবার দেখুন। বিশেষ করে লেনদেনের বিচ্ছিন্নতা। ইনোডাব_লোক_উইট_টাইমআউট ভেরিয়েবলটি বাড়ানো ভাল ধারণা নয়।

Mysql ক্লায় আপনার ডাটাবেস লেনদেনের বিচ্ছিন্নতা স্তরটি পরীক্ষা করে দেখুন:

mysql> SELECT @@GLOBAL.transaction_isolation, @@transaction_isolation, @@session.transaction_isolation;
+-----------------------+-----------------+------------------------+
| @@GLOBAL.tx_isolation | @@tx_isolation  | @@session.tx_isolation |
+-----------------------+-----------------+------------------------+
| REPEATABLE-READ       | REPEATABLE-READ | REPEATABLE-READ        |
+-----------------------+-----------------+------------------------+
1 row in set (0.00 sec)

আপনি ডি আইসোলেশন স্তর পরিবর্তন করে উন্নতি পেতে পারেন, READ COMMITTED এর পরিবর্তে READATABLE READ (InnoDB Defaults) এর মতো ওরাকলটি ব্যবহার করতে পারেন

mysql> SET tx_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> SET GLOBAL tx_isolation = 'READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> 

এছাড়াও প্রযোজ্য প্রয়োজনে কেবল নির্বাচন করার জন্য নির্বাচন করুন চেষ্টা করুন।


1
এটি লকিংয়ের সমস্যার জন্য দুর্দান্ত সমাধান।
স্মৃতিভারাতুর

3
আমার জন্য দুর্দান্ত কাজ করে, মাই সিএনএফ সংস্করণটি হ'ল [মাইকিকিএলডি] লেনদেন-বিচ্ছিন্নতা = পড়ুন-সমালোচনা
বেনোইট গৌথিয়ার

কেবল একটি নোট: মাইএসকিউএল 8 এর পরিবর্তনশীলটির নাম tx_isolationপরিবর্তন করেছে transaction_isolation
xonya

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

27

প্রস্তাবিত সমাধানগুলির কোনওোটাই আমার পক্ষে কাজ করেনি তবে এটি করেছিল।

কিছু ক্যোয়ারির সম্পাদনটিকে অবরুদ্ধ করছে। সম্ভবত আপনার কোয়েরির একটি সারণী থেকে অন্যটি কোয়েরি আপডেট করা, সন্নিবেশ করানো বা মুছতে হবে। এটি কী তা আপনাকে খুঁজে বের করতে হবে:

SHOW PROCESSLIST;

একবার আপনি ব্লকিংয়ের প্রক্রিয়াটি সনাক্ত করার পরে এটিটি খুঁজে বের করুন id:

KILL {id};

আপনার প্রাথমিক ক্যোয়ারী পুনরায় রান করুন।


আমি ঘটনাক্রমে শো প্রসেসলিস্টের সাথে তালিকাবদ্ধ সমস্ত প্রক্রিয়া মেরে ফেললাম; এখন আমি পিপিপিএমএডমিনে 500 ত্রুটি পাচ্ছি। যে 500 টি ত্রুটি এই প্রক্রিয়াগুলি হত্যার সাথে সম্পর্কিত? যদি হ্যাঁ, আমি কীভাবে এটি পুনরায় চালু করতে পারি।
দশরথ

আপনি কী বর্ণনা করছেন তা আমি দেখতে পাচ্ছি, তবে হত্যার প্রক্রিয়াটি কার্যকর হয় না। প্রক্রিয়াটির কমান্ডটি "হত্যা" হয় তবে এটি প্রক্রিয়া তালিকায় থাকে।
টর্স্টেন

12

মার্কআর যা বলেছে তার সাথে 100%। স্বতঃপাদন প্রতিটি বিবৃতিতে একটি করে বিবৃতি লেনদেন করে।

SHOW ENGINE INNODB STATUSঅচলাবস্থার কারণ হিসাবে আপনাকে কিছু সংকেত দেওয়া উচিত। টেবিলটি কী কী জিজ্ঞাসা করছে তা দেখার জন্য আপনার ধীর ক্যোয়ারী লগটিতে খুব ভাল নজর দিন এবং একটি পূর্ণ টেবিল স্ক্যান করে যা কিছু মুছে ফেলার চেষ্টা করুন। সারি স্তরের লকিং ভাল কাজ করে কিন্তু যখন আপনি সমস্ত সারি লক করার চেষ্টা করছেন না!


5

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


3
হয়তো innodb_lock_wait_timeoutmy.cnf
oblig

1
আমি my.cnf এ সেট করেছি: <br/> ইনোডবি_লক_উইট_টাইমআউট = 120 <br/> মাইএসকিএল 5.5 এর জন্য ডিফল্ট 50 হয়। এই পরিবর্তনের পরে আমি আমার ইউনিট পরীক্ষায় এই সমস্যাটি দেখতে পাচ্ছিলাম না! প্রক্সুল থেকে টমক্যাট জেডিবিসি পুলে স্যুইচ করার পরে এটি ঘটেছিল। টমক্যাট পুলের সাথে আরও বেশি লেনদেনের কারণে সম্ভবত ?!
চ্যাম্প

3

সারিগুলির সংখ্যা বিশাল নয় ... অ্যাকাউন্ট_ইম্পোর্ট_আইডিতে প্রাথমিক কী না হলে একটি সূচক তৈরি করুন।

CREATE INDEX idx_customer_account_import_id ON customer (account_import_id);

ওএমজি ... এটি আমাকে বাঁচিয়েছে। আমি রয়্যালি একটি সূচক ফেলে দিয়ে একটি প্রোডাকশন ডিবি স্ক্রু করেছি এবং এটি এটি ঠিক করে দিয়েছে। তোমাকে ধন্যবাদ.
নিক গটচ

2

আপনি যদি সবেমাত্র একটি বড় ক্যোয়ারী মেরে ফেলেছেন তবে এতে সময় লাগবে rollback। যদি আপনি নিহত ক্যোয়ারীটি ঘূর্ণায়মান হয়ে যাওয়ার আগে অন্য কোনও ক্যোয়ারী ইস্যু করেন তবে আপনি একটি লক টাইমআউট ত্রুটি পেতে পারেন। আমার ক্ষেত্রেও তাই হয়েছিল। সমাধানটি ছিল কেবল কিছুটা অপেক্ষা করার জন্য।

বিবরণ:

প্রায় 1 মিলিয়ন সারিগুলির মধ্যে প্রায় 900,000 সরাতে আমি একটি মোছা ক্যোয়ারী জারি করেছি।

আমি ভুল করে এটি চালিয়েছি (সারিগুলির কেবল 10% সরিয়ে ফেলে): DELETE FROM table WHERE MOD(id,10) = 0

এর পরিবর্তে (90% সারি সরিয়ে দেয়): DELETE FROM table WHERE MOD(id,10) != 0

আমি 10% নয়, 90% সারি মুছে ফেলতে চেয়েছিলাম। সুতরাং আমি মাইএসকিউএল কমান্ড লাইনে প্রক্রিয়াটি মেরেছিলাম, এটা জেনে যে এটি এখন পর্যন্ত মুছে ফেলা সমস্ত সারি আবার ফিরিয়ে আনবে।

তারপরে আমি তত্ক্ষণাত সঠিক কমান্ডটি চালিয়েছি এবং এরপরেই একটি lock timeout exceededত্রুটি পেয়েছি । আমি বুঝতে পেরেছিলাম যে লকটি সম্ভবত rollbackপটভূমিতে ঘটে যাওয়া নিহত ক্যোয়ারির মধ্যে হতে পারে । তাই আমি কয়েক সেকেন্ড অপেক্ষা করে আবারো ক্যোয়ারী চালিয়েছি।


1

ডাটাবেস সারণিগুলি InnoDB স্টোরেজ ইঞ্জিন এবং READ-COMMITTED লেনদেনের বিচ্ছিন্নতা স্তর ব্যবহার করছে তা নিশ্চিত করুন।

আপনি এটি নির্বাচন করুন @ GLOBAL.tx_isolation, @@ tx_isolation দ্বারা পরীক্ষা করতে পারেন; mysql কনসোল এ।

যদি এটি পড়ুন-সেট করা না হয়ে থাকে তবে আপনাকে এটি সেট করতে হবে। এটি নির্ধারণের আগে নিশ্চিত হয়ে নিন যে আপনার মাইএসকিএল-এ সুপের সুবিধা রয়েছে।

আপনি http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html থেকে সহায়তা নিতে পারেন ।

এটি সেট করার মাধ্যমে আমি মনে করি আপনার সমস্যার সমাধান হবে।


আপনি একবারে দুটি প্রক্রিয়াতে এটি আপডেট করার চেষ্টা করছেন না তাও আপনি দেখতে চাইতে পারেন। ব্যবহারকারীরা (@ টালা) এই প্রসঙ্গে একই জাতীয় ত্রুটি বার্তির মুখোমুখি হয়েছেন, সম্ভবত এটি ডাবল-চেক করুন ...


1

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

আমি অক্ষম করেছিলাম autocommitএবং এরপরে এটি COMMITএসকিউএল বাক্যটির শেষে যোগ করার কাজ করে । আমি যতদূর বুঝতে পেরেছি কমান্ডের শেষে অপেক্ষা না করে কিছুটা হলেও বাফারটিকে কিছুটা মুক্তি দেয়।

ওপিটির উদাহরণ ধরে রাখার জন্য এটি কাজ করা উচিত ছিল:

mysql> set autocommit=0;

mysql> update customer set account_import_id = 1; commit;

আপনি autocommitযদি আগের মতো মাইএসকিউএল কনফিগারেশনটি ছেড়ে যেতে চান তবে পুনরায় সক্রিয় করতে ভুলবেন না ।

mysql> set autocommit=1;


0

পার্টিতে দেরিতে (যথারীতি) তবে আমার ইস্যুটি হ'ল যে আমি কিছু খারাপ এসকিউএল লিখেছি (একজন নবাগত হওয়া) এবং বেশ কয়েকটি প্রক্রিয়ার রেকর্ডে একটি লক ছিল (গুলি) - যথাযথ অক্ষমতা নিশ্চিত নয়। আমি ঠিক করতে পেরেছি: SHOW PROCESSLISTএবং তারপরে আইডি ব্যবহার করে হত্যা করবKILL <id>


0

আমি যখন পিএইচপি ল্যাঙ্গুয়েজ কনস্ট্রাক্ট প্রস্থান ব্যবহার করছিলাম তখন এই জাতীয় জিনিসটি আমার সাথে ঘটেছিল; লেনদেনের মাঝখানে তারপরে এই লেনদেনটি "স্তব্ধ হয়ে যায়" এবং আপনাকে মাইএসকিএল প্রক্রিয়াটি হরণ করতে হবে (প্রসেসলিস্টের সাথে উপরে বর্ণিত;)


0

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

LOCK TABLES `customer` WRITE;
update customer set account_import_id = 1;
UNLOCK TABLES;

এটি সম্ভবত সাধারণ ব্যবহারের জন্য ভাল ধারণা নয়।

আরও তথ্যের জন্য দেখুন: মাইএসকিউএল 8.0 রেফারেন্স ম্যানুয়াল


0

আমি এটিতে 2 টি মতবাদ ডিবিএল সংযোগ নিয়ে ছুটে এসেছি, যার মধ্যে একটি অ-লেনদেনের হিসাবে গুরুত্বপূর্ণ (গুরুত্বপূর্ণ লগগুলির জন্য), তারা একে অপরের উপর নির্ভর করে না সমান্তরাল চালানোর উদ্দেশ্যে।

CodeExecution(
    TransactionConnectionQuery()
    TransactionlessConnectionQuery()
)

আমার একীকরণ পরীক্ষাগুলি খুব পরীক্ষার পরে ডেটা রোলব্যাকের জন্য লেনদেনের মধ্যে আবৃত ছিল।

beginTransaction()
CodeExecution(
    TransactionConnectionQuery()
    TransactionlessConnectionQuery() // CONFLICT
)
rollBack()

আমার সমাধানটি ছিল সেই পরীক্ষাগুলিতে মোড়ানোর লেনদেনটি অক্ষম করা এবং ডিবি ডেটা অন্য উপায়ে পুনরায় সেট করা।


-4

এই একই ত্রুটিটি ছিল, যদিও আমি কেবল একটি এন্ট্রি সহ কেবল একটি টেবিল আপডেট করছি, তবে মাইএসকিএল পুনরায় চালু করার পরে এটি সমাধান হয়ে গেছে।

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