মাইএসকিউএলে লক অপেক্ষার সময়সীমা অতিক্রম করে কীভাবে?


269

আমার উত্পাদন ত্রুটির লগগুলিতে আমি মাঝে মধ্যে দেখতে পাই:

এসকিউএলস্টেট [এইচওয়াই 1000]: সাধারণ ত্রুটি: 1205 লক অপেক্ষার সময়সীমা অতিক্রম করেছে; লেনদেন পুনরায় চালু করার চেষ্টা করুন

আমি জানি যে কোয়েরিটি সেই মুহুর্তে ডাটাবেসটি অ্যাক্সেস করার চেষ্টা করছে তবে সেই প্রশ্নের সাথে কোন কোয়েরিটি সেই মুহুর্তে তালাবন্ধ ছিল?


1
আমি সবাইকে ভারীভাবে
এরিকের

উত্তর:


261

এটি যা দেয় তা হ'ল শব্দ লেনদেন । উক্তিটি দিয়ে স্পষ্ট যে কোয়েরিটি এক বা একাধিক InnoDB টেবিলগুলিতে কমপক্ষে একটি সারি পরিবর্তন করার চেষ্টা করেছিল।

যেহেতু আপনি কোয়েরিটি জানেন, সমস্ত টেবিল অ্যাক্সেস করা হচ্ছে তা অপরাধী হওয়ার প্রার্থী।

সেখান থেকে আপনার চালানো উচিত should SHOW ENGINE INNODB STATUS\G

আপনি প্রভাবিত টেবিল দেখতে সক্ষম হবেন

আপনি সমস্ত ধরণের অতিরিক্ত লকিং এবং মুটেক্স তথ্য পান।

আমার ক্লায়েন্টের একটির নমুনা এখানে:

mysql> show engine innodb status\G
*************************** 1. row ***************************
  Type: InnoDB
  Name:
Status:
=====================================
110514 19:44:14 INNODB MONITOR OUTPUT
=====================================
Per second averages calculated from the last 4 seconds
----------
SEMAPHORES
----------
OS WAIT ARRAY INFO: reservation count 9014315, signal count 7805377
Mutex spin waits 0, rounds 11487096053, OS waits 7756855
RW-shared spins 722142, OS waits 211221; RW-excl spins 787046, OS waits 39353
------------------------
LATEST FOREIGN KEY ERROR
------------------------
110507 21:41:35 Transaction:
TRANSACTION 0 606162814, ACTIVE 0 sec, process no 29956, OS thread id 1223895360 updating or deleting, thread declared inside InnoDB 499
mysql tables in use 1, locked 1
14 lock struct(s), heap size 3024, 8 row lock(s), undo log entries 1
MySQL thread id 3686635, query id 124164167 10.64.89.145 viget updating
DELETE FROM file WHERE file_id in ('6dbafa39-7f00-0001-51f2-412a450be5cc' )
Foreign key constraint fails for table `backoffice`.`attachment`:
,
  CONSTRAINT `attachment_ibfk_2` FOREIGN KEY (`file_id`) REFERENCES `file` (`file_id`)
Trying to delete or update in parent table, in index `PRIMARY` tuple:
DATA TUPLE: 17 fields;
 0: len 36; hex 36646261666133392d376630302d303030312d353166322d343132613435306265356363; asc 6dbafa39-7f00-0001-51f2-412a450be5cc;; 1: len 6; hex 000024214f7e; asc   $!O~;; 2: len 7; hex 000000400217bc; asc    @   ;; 3: len 2; hex 03e9; asc   ;; 4: len 2; hex 03e8; asc   ;; 5: len 36; hex 65666635323863622d376630302d303030312d336632662d353239626433653361333032; asc eff528cb-7f00-0001-3f2f-529bd3e3a302;; 6: len 40; hex 36646234376337652d376630302d303030312d353166322d3431326132346664656366352e6d7033; asc 6db47c7e-7f00-0001-51f2-412a24fdecf5.mp3;; 7: len 21; hex 416e67656c73204e6f7720436f6e666572656e6365; asc Angels Now Conference;; 8: len 34; hex 416e67656c73204e6f7720436f6e666572656e6365204a756c7920392c2032303131; asc Angels Now Conference July 9, 2011;; 9: len 1; hex 80; asc  ;; 10: len 8; hex 8000124a5262bdf4; asc    JRb  ;; 11: len 8; hex 8000124a57669dc3; asc    JWf  ;; 12: SQL NULL; 13: len 5; hex 8000012200; asc    " ;; 14: len 1; hex 80; asc  ;; 15: len 2; hex 83e8; asc   ;; 16: len 4; hex 8000000a; asc     ;;

But in child table `backoffice`.`attachment`, in index `PRIMARY`, there is a record:
PHYSICAL RECORD: n_fields 6; compact format; info bits 0
 0: len 30; hex 36646261666133392d376630302d303030312d353166322d343132613435; asc 6dbafa39-7f00-0001-51f2-412a45;...(truncated); 1: len 30; hex 38666164663561652d376630302d303030312d326436612d636164326361; asc 8fadf5ae-7f00-0001-2d6a-cad2ca;...(truncated); 2: len 6; hex 00002297b3ff; asc   "   ;; 3: len 7; hex 80000040070110; asc    @   ;; 4: len 2; hex 0000; asc   ;; 5: len 30; hex 416e67656c73204e6f7720436f6e666572656e636520446f63756d656e74; asc Angels Now Conference Document;;

------------
TRANSACTIONS
------------
Trx id counter 0 620783814
Purge done for trx's n:o < 0 620783800 undo n:o < 0 0
History list length 35
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 0 0, not started, process no 29956, OS thread id 1192212800
MySQL thread id 5341758, query id 189708501 127.0.0.1 lwdba
show innodb status
---TRANSACTION 0 620783788, not started, process no 29956, OS thread id 1196472640
MySQL thread id 5341773, query id 189708353 10.64.89.143 viget
---TRANSACTION 0 0, not started, process no 29956, OS thread id 1223895360
MySQL thread id 5341667, query id 189706152 10.64.89.145 viget
---TRANSACTION 0 0, not started, process no 29956, OS thread id 1227888960
MySQL thread id 5341556, query id 189699857 172.16.135.63 lwdba
---TRANSACTION 0 620781112, not started, process no 29956, OS thread id 1222297920
MySQL thread id 5341511, query id 189696265 10.64.89.143 viget
---TRANSACTION 0 620783736, not started, process no 29956, OS thread id 1229752640
MySQL thread id 5339005, query id 189707998 10.64.89.144 viget
---TRANSACTION 0 620783785, not started, process no 29956, OS thread id 1198602560
MySQL thread id 5337583, query id 189708349 10.64.89.145 viget
---TRANSACTION 0 620783469, not started, process no 29956, OS thread id 1224161600
MySQL thread id 5333500, query id 189708478 10.64.89.144 viget
---TRANSACTION 0 620781240, not started, process no 29956, OS thread id 1198336320
MySQL thread id 5324256, query id 189708493 10.64.89.145 viget
---TRANSACTION 0 617458223, not started, process no 29956, OS thread id 1195141440
MySQL thread id 736, query id 175038790 Has read all relay log; waiting for the slave I/O thread to update it
--------
FILE I/O
--------
I/O thread 0 state: waiting for i/o request (insert buffer thread)
I/O thread 1 state: waiting for i/o request (log thread)
I/O thread 2 state: waiting for i/o request (read thread)
I/O thread 3 state: waiting for i/o request (write thread)
Pending normal aio reads: 0, aio writes: 0,
 ibuf aio reads: 0, log i/o's: 0, sync i/o's: 0
Pending flushes (fsync) log: 0; buffer pool: 0
519878 OS file reads, 18962880 OS file writes, 13349046 OS fsyncs
0.00 reads/s, 0 avg bytes/read, 6.25 writes/s, 4.50 fsyncs/s
-------------------------------------
INSERT BUFFER AND ADAPTIVE HASH INDEX
-------------------------------------
Ibuf: size 1, free list len 1190, seg size 1192,
174800 inserts, 174800 merged recs, 54439 merges
Hash table size 35401603, node heap has 35160 buffer(s)
0.50 hash searches/s, 11.75 non-hash searches/s
---
LOG
---
Log sequence number 28 1235093534
Log flushed up to   28 1235093534
Last checkpoint at  28 1235091275
0 pending log writes, 0 pending chkp writes
12262564 log i/o's done, 3.25 log i/o's/second
----------------------
BUFFER POOL AND MEMORY
----------------------
Total memory allocated 18909316674; in additional pool allocated 1048576
Dictionary memory allocated 2019632
Buffer pool size   1048576
Free buffers       175763
Database pages     837653
Modified db pages  6
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages read 770138, created 108485, written 7795318
0.00 reads/s, 0.00 creates/s, 4.25 writes/s
Buffer pool hit rate 1000 / 1000
--------------
ROW OPERATIONS
--------------
0 queries inside InnoDB, 0 queries in queue
1 read views open inside InnoDB
Main thread process no. 29956, id 1185823040, state: sleeping
Number of rows inserted 6453767, updated 4602534, deleted 3638793, read 388349505551
0.25 inserts/s, 1.25 updates/s, 0.00 deletes/s, 2.75 reads/s
----------------------------
END OF INNODB MONITOR OUTPUT
============================

1 row in set, 1 warning (0.00 sec)

আপনি ইনডোডিবি_লক_উইট_টাইমআউট সেট করে ইনোডিবি- র জন্য লক ওয়েট টাইমআউট মান বাড়ানো বিবেচনা করা উচিত , ডিফল্ট 50 সেকেন্ড

mysql> show variables like 'innodb_lock_wait_timeout';
+--------------------------+-------+
| Variable_name            | Value |
+--------------------------+-------+
| innodb_lock_wait_timeout | 50    |
+--------------------------+-------+
1 row in set (0.01 sec)

আপনি /etc/my.cnfএই লাইনের সাথে স্থায়ীভাবে এটিকে উচ্চতর মানতে সেট করতে পারেন

[mysqld]
innodb_lock_wait_timeout=120

এবং mysql পুনরায় আরম্ভ করুন। আপনি যদি এই সময়টি মাইএসকিএল পুনরায় চালু করতে না পারেন তবে এটি চালান:

SET GLOBAL innodb_lock_wait_timeout = 120; 

আপনি আপনার সেশনের সময়কালের জন্য এটি ঠিক সেট করতে পারেন

SET innodb_lock_wait_timeout = 120; 

আপনার জিজ্ঞাসা অনুসারে


5
অন্তর্নির্মিত InnoDB এর জন্য, innodb_lock_wait_timeoutভেরিয়েবলটি কেবল সার্ভার স্টার্টআপে সেট করা যায়। InnoDB প্লাগইন-এর জন্য এটি শুরুতে সেট করা যেতে পারে বা রানটাইমের সময় পরিবর্তিত হতে পারে এবং এর উভয় বৈশ্বিক এবং সেশন মান রয়েছে।
টিমো হুভিনেন

1
: হাই @rolandomysqldba, আপনি পরামর্শ আমাকে দিতে দয়া করে করতে পারেন আমার এই পোস্টে stackoverflow.com/questions/18267565/...
মনীশ Sapkal

2
প্রথম ক্যোয়ারী চালানোর চেষ্টা করার সময় আমি এই ত্রুটিটি SQL Error (1064): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '\G' at line 1
পেয়েছি

1
@ পেসারিয়ার প্রতিবার মাইএসকিএলটি পুনরায় চালু হওয়ার পরে আপনাকে SET GLOBAL innodb_lock_wait_timeout = 120;আবার চালাতে হবে । যদি /etc/my.cnfবিকল্প থাকে তবে innodb_lock_wait_timeoutআপনার জন্য সেট করা আছে। প্রত্যেকের জন্যই এটি বিশ্বব্যাপী পরিবর্তনের জন্য সর্বোচ্চ সুযোগ নেই ( dev.mysql.com/doc/refman/5.6/en/… )
RolandoMySQLDBA

3
@ ইলিয়ানঅনোফ্রেই \ জি অক্ষরটি মাইএসকিউএল কমান্ড লাইনের একটি বিশেষ বৈশিষ্ট্য এবং আউটপুট প্রদর্শিত হওয়ার পদ্ধতি পরিবর্তন করে। অন্যান্য মাইএসকিউএল ক্লায়েন্টদের পরিবর্তে কেবল নিয়মিত সেমিকোলন ব্যবহার করুন।
তারপরে ডায়াল

83

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

মন্তব্যকারী অনুরূপ কিছু বলেছিলেন "" কখনও কখনও একটি মাইএসকিউএল থ্রেড একটি টেবিলটি লক করে, তারপরে ঘুমিয়ে থাকে যখন এটি মাইএসকিউএল সম্পর্কিত কিছু না হওয়ার জন্য অপেক্ষা করে। "

show engine innodb statusলগটি পুনরায় পর্যালোচনা করার পরে (একবার আমি লকটির জন্য দায়ী ক্লায়েন্টকে ট্র্যাক করে নিলাম), আমি লক্ষ্য করেছি যে প্রশ্নে থাকা আটকে থাকা থ্রেডটি লেনদেনের তালিকার একেবারে নীচে তালিকাভুক্ত ছিল, ত্রুটিযুক্ত হওয়া সক্রিয় প্রশ্নের নীচে হিমায়িত লকের কারণে বাইরে:

------------------
---TRANSACTION 2744943820, ACTIVE 1154 sec(!!)
2 lock struct(s), heap size 376, 2 row lock(s), undo log entries 1
MySQL thread id 276558, OS thread handle 0x7f93762e7710, query id 59264109 [ip] [database] cleaning up
Trx read view will not see trx with id >= 2744943821, sees < 2744943821

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

গল্পটির নৈতিকতা হ'ল থ্রেডটি ঘুমিয়ে থাকা সত্ত্বেও কোনও লেনদেন সক্রিয় হতে পারে ।


2
আমি বলতে পারি না আপনি আমার জীবন বাঁচিয়েছিলেন, তবে আপনি অবশ্যই আমার মন শান্তিতে স্থির করেছেন। আপনার উত্তরটি পড়ে, আমি একটি চতুর থ্রেড পেয়েছি যা 3260 সেকেন্ডের জন্য সক্রিয় ছিল এবং কোথাও প্রদর্শিত হচ্ছে না। এটি হত্যার পরে, আমার সমস্ত সমস্যার সমাধান হয়ে গেল!
kommradHomer

এটা আমার সমস্যা ছিল। 20,000 সেকেন্ডের সময় সহ একটি নিদ্রার লেনদেন যা একটি রিয়েল অ্যাপ্লিকেশনটিতে বিলম্বিত জবকে সঠিকভাবে চলতে বাধা দিচ্ছিল। ধন্যবাদ @ ইরিক
বিগটেক্স 777

কোনও ধারণা কেন একটি ঘুমের লেনদেন যাইহোক বন্ধ হয় না? পছন্দ করুন, কোনও সময়সীমা কি সেট করতে পারেন যে কোনও লেনদেনের মধ্যেই শেষ করা উচিত?
প্যাট্রিকদাভী

1
লকিং লেনদেনের জন্য আপনার অনুসন্ধানে সহায়ক হতে পারে এমন অন্যান্য কমান্ড: show processlist;বর্তমানে সম্পাদিত প্রক্রিয়াগুলির একটি সম্পূর্ণ তালিকা প্রদর্শন করতে, যা দুর্দান্ত এটি কারণ এটি একটি ঘনীভূত সংস্করণ show engine innodb status\g। এছাড়াও, যদি আপনার ডিবি অ্যামাজন আরডিএসে থাকে তবে আপনি CALL mysql.rds_kill(<thread_id>);থ্রেডগুলি মারতে ব্যবহার করতে পারেন । আমার মনে হয় এর উচ্চতর অনুমতি রয়েছে, কারণ এটি আমাকে kill <thread_id>;
প্লেইনের

1
যে কারও কাছে এর জন্য উত্স আছে - সম্ভবত কোনও ডকুমেন্টেশন পৃষ্ঠাতে লকগুলি উল্লেখ করা হচ্ছে কমিটের পর্বের আগে স্থাপন করা হয়েছে? এই সঠিক সমস্যাটি দেখার পরেও আমি কিছুই খুঁজে পেলাম না এবং তালার ঝুলিতে থাকা ঘুমের থ্রেডটি মেরে এটি পরিষ্কার হয়ে গেল।
এরিন শুনোভার

42

মাইএসকিউএল-এর জনপ্রিয়তার কারণে লকের অপেক্ষার সময়সীমা অতিক্রম করার কোনও অবাক লাগে না ; পুনরায় চালু করার চেষ্টা করুন লেনদেনের ব্যতিক্রম এসও তেমন মনোযোগ পায়।

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

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

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

পুনঃপঠনযোগ্য পড়ুন লেনদেনের সময় অর্জিত প্রতিটি লক লেনদেনের সময়কালের জন্য রাখা হয়।

রিড কমিটিতে স্ক্যানের সাথে মেলে না এমন লকগুলি STATEMENT শেষ হওয়ার পরে ছেড়ে দেওয়া হয়।

...

এর অর্থ হ'ল রিড কমিটিতে অন্যান্য লেনদেনগুলি সারিগুলি আপডেট করার জন্য নিখরচায় যে তারা আপডেটের বিবরণীটি শেষ হওয়ার পরে (পুনঃপঠনযোগ্য রিডে) আপডেট করতে সক্ষম হত না।

অতএব: বিচ্ছিন্নতা স্তর যত বেশি সীমাবদ্ধ ( REPEATABLE_READ, SERIALIZABLE) অচলাবস্থার সম্ভাবনা তত বেশি। এটি "প্রতি সে" ইস্যু নয়, এটি বাণিজ্য-বন্ধ।

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


4
লক ওয়েট টাইমআউট ডেডলকের চেয়ে আলাদা না? উদাহরণস্বরূপ, যদি কোনও থ্রেড বৈধ কারণে 60 সেকেন্ডের জন্য একটি লক ধরে থাকে তবে লকের অপেক্ষার সময়সীমা শেষ হতে পারে। এটি সত্য নয় যে সত্যই যদি কোনও অচলাবস্থা থাকে তবে মাইএসকিউএল এটি সনাক্ত করে এবং তাত্ক্ষণিকভাবে একটি লেনদেনকে হত্যা করবে এবং এটি লক অপেক্ষার সময়সীমাটির সাথে সম্পর্কিত নয়?
কলিনম

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

19

রেকর্ডের জন্য, যখন কোনও অচলাবস্থা থাকে এবং মাইএসকিউএল এটি সনাক্ত করতে পারে না, তখন লক ওয়েট টাইমআউট ব্যতিক্রম ঘটে। অন্য কারণ হতে পারে একটি দীর্ঘ দীর্ঘ চলমান ক্যোয়ারী, যা সমাধান / মেরামত করা সহজ, তবে, এবং আমি এখানে এই কেসটি বর্ণনা করব না।

মাইএসকিউএল সাধারণত দু'টি লেনদেনের মধ্যে "সঠিকভাবে" নির্মিত হলে ডেডলকগুলি মোকাবেলা করতে সক্ষম হয়। মাইএসকিউএল কেবলমাত্র সেই লেনদেনের মালিকানাধীন একটি ট্রানজেকশনকে মেরে ফেলবে / রোলব্যাক করবে (এটি কম সারিগুলিতে প্রভাব ফেলবে বলে কম গুরুত্বপূর্ণ) এবং অন্যটিকে শেষ করতে দেয়।

এখন ধরা যাক, এ এবং বি এবং তিনটি লেনদেন দুটি রয়েছে:

Process A Transaction 1: Locks X
Process B Transaction 2: Locks Y
Process A Transaction 3: Needs Y => Waits for Y
Process B Transaction 2: Needs X => Waits for X
Process A Transaction 1: Waits for Transaction 3 to finish

(see the last two paragraph below to specify the terms in more detail)

=> deadlock 

এটি একটি খুব দুর্ভাগ্যজনক সেটআপ কারণ মাইএসকিউএল দেখতে পাচ্ছে না সেখানে কোনও অচলাবস্থা রয়েছে (3 টি লেনদেনের মধ্যে বিস্তৃত)। সুতরাং মাইএসকিউএল যা করে ... তা কিছুই না! এটি কেবল অপেক্ষা করে, যেহেতু এটি কী করতে হবে তা জানে না। প্রথম অধিগ্রহণকৃত লকটি সময়সীমা অতিক্রম না হওয়া পর্যন্ত এটি অপেক্ষা করে (প্রক্রিয়া এ লেনদেন 1: লক্স এক্স), এরপরে এটি লক এক্সকে অবরোধ মুক্ত করবে, যা লেনদেন 2 আনলক করে etc.

শিল্পটি হ'ল প্রথম কোন লকটি (লক এক্স) কী কারণে (কোন কোয়েরিতে) রয়েছে তা খুঁজে বের করা। আপনি সহজেই দেখতে সক্ষম হবেন ( show engine innodb status) যে লেনদেন 3 টি লেনদেন 2 এর জন্য অপেক্ষা করে তবে আপনি দেখতে পাবেন না লেনদেন 2 কোন লেনদেনের জন্য অপেক্ষা করছে (লেনদেন 1)। মাইএসকিউএল লেনদেনের সাথে সম্পর্কিত কোনও লক বা কোয়েরি মুদ্রণ করবে না। কেবলমাত্র ইঙ্গিতটি show engine innodb statusহ'ল লেনদেন তালিকার একেবারে নীচে ( প্রিন্টআউটটির) আপনি দেখতে পাবেন লেনদেন 1 আপাতদৃষ্টিতে কিছুই করছে না (তবে বাস্তবে লেনদেন 3 থেকে অপেক্ষার জন্য অপেক্ষা করছে) ফিনিস)।

কোন এসকিউএল ক্যোয়ারীর জন্য লক (লক এক্স) প্রদত্ত একটি প্রদত্ত লেনদেনের জন্য মঞ্জুরি দেওয়া হয় তা আবিষ্কার করার কৌশলটি এখানে বর্ণিত হয়েছে Tracking MySQL query history in long running transactions

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

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


14

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

Statement st = con.createStatement();
ResultSet rs =  st.executeQuery("SHOW ENGINE INNODB STATUS");
while(rs.next()){
    log.info(rs.getString(1));
    log.info(rs.getString(2));
    log.info(rs.getString(3));
}

11

pt-deadlock-loggerইউটিলিটির ম্যান পৃষ্ঠাটি একবার দেখুন :

brew install percona-toolkit
pt-deadlock-logger --ask-pass server_name

এটি engine innodb statusউপরে উল্লিখিত থেকে তথ্য আহরণ করে এবং এটি daemonপ্রতি 30 সেকেন্ডে চলে এমন একটি তৈরিতে ব্যবহার করা যেতে পারে ।



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


11

উপরের রোল্যান্ডোর উত্তর থেকে এক্সট্রোপোলেটিং, এগুলিই আপনার ক্যোয়ারীটি ব্লক করছে:

---TRANSACTION 0 620783788, not started, process no 29956, OS thread id 1196472640
MySQL thread id 5341773, query id 189708353 10.64.89.143 viget

আপনার যদি আপনার জিজ্ঞাসা চালানো দরকার এবং অন্যরা চালিত হওয়ার জন্য অপেক্ষা করতে না পারেন তবে মাইএসকিউএল থ্রেড আইডি ব্যবহার করে তাদের হত্যা করুন:

kill 5341773 <replace with your thread id>

(mysql এর মধ্যে থেকে, শেল নয়, অবশ্যই)

আপনাকে থ্রেড আইডিগুলি খুঁজে পেতে হবে:

show engine innodb status\G

কমান্ড, এবং কোনটি একটি যা ডেটাবেস ব্লক করছে তা খুঁজে বের করুন।


1
তুমি কীভাবে জানলে এটা 5341773? আমি দেখতে পাচ্ছি না যে এটি অন্যদের থেকে কী আলাদা করে।
Wodin

না এটি সম্ভবত থ্রেডআইডি নয়, এটি একটি উদাহরণ ছিল। আপনাকে "শো ইঞ্জিন ইন্নাডব স্ট্যাটাস \ জি" কমান্ড থেকে থ্রেড আইডিগুলি সন্ধান করতে হবে এবং ডাটাবেসটি ব্লক করছে কোনটি সেটিকে খুঁজে বের করতে হবে।
এলার্ট ভ্যান কোপেরেন

1
ধন্যবাদ। সুতরাং অন্য কথায় এটি কোন উপায় নেই তা বলার উপায় নেই যেমন একে একে হত্যা করে?
Wodin

লেনদেনের তালিকায় আপনি দেখতে পাচ্ছেন কোনটি চলছে এবং কত দিন চলছে। সুতরাং একে একে একে হত্যা করার দরকার নেই, এই তালিকাটি সাধারণত আপনাকে যা চলছে তার একটি সুন্দর ধারণা দেয়।
এলার্ট ভ্যান কোপেরেন

10

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

-- Pending InnoDB transactions
SELECT * FROM information_schema.innodb_trx ORDER BY trx_started; 

-- Optionally, log what transaction holds what locks
SELECT * FROM information_schema.innodb_locks;

উপরের সাহায্যে, আমরা সমবর্তী প্রশ্নগুলি চিহ্নিত করতে সক্ষম হয়েছি যেগুলি অচলাবস্থার কারণে সারিগুলিকে লক করে রেখেছে। আমার ক্ষেত্রে, এগুলি বিবৃতি ছিল INSERT ... SELECTযেমন সরল SELECTs অন্তর্নিহিত সারিগুলিকে লক করে। তারপরে আপনি কোডটি পুনর্গঠিত করতে পারেন বা পড়ার মতো বাছাইয়ের মতো আলাদা লেনদেনের বিচ্ছিন্নতা ব্যবহার করতে পারেন।

শুভকামনা!


9

তুমি ব্যবহার করতে পার:

show full processlist

যা মাইএসকিউএল এবং সংযোগের বর্তমান অবস্থার পাশাপাশি কোয়েরি কার্যকর করা হচ্ছে এমন সমস্ত সংযোগের তালিকা তৈরি করবে। একটি সংক্ষিপ্ত রূপ রয়েছে show processlist;যা সংক্ষিপ্ত কোয়েরি পাশাপাশি সংযোগের পরিসংখ্যান প্রদর্শন করে।



-2

মাইএসকিউএল জেনারেল.লগ (ডিস্ক নিবিড়) সক্রিয় করুন এবং দীর্ঘ চলমান লেনদেন নিষ্কাশন করতে mysql_analyse_general_log.pl ব্যবহার করুন , উদাহরণস্বরূপ:

--মিনে-সময়কাল = আপনার ইনডোডব_লোক_উইট_টাইমআউট মান

এর পরে জেনারেল.লগ অক্ষম করুন।

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