কীভাবে স্বয়ংক্রিয়ভাবে এন সেকেন্ডের পরে ধীর মাইএসকিউএল কোয়েরিগুলিকে মেরে ফেলা যায়?


16

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


আপনি মাইএসকিউএল এর কোন সংস্করণটি চালাচ্ছেন ???
RolandoMySQLDBA

উত্তর:


21

পারকোনা টুলকিট থেকে পিটি-কিল কমান্ডটি পরীক্ষা করে দেখুন ।

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


পরামর্শ সম্পর্কে ধন্যবাদ, কিন্তু সত্যিই একটি "ওয়ান-অফ" স্ক্রিপ্ট সন্ধান করুন।
আলফিশ

5
পিটি-কিল খুব ভাল পরীক্ষিত এবং আপনার সঠিক সমস্যা সমাধান করে। কমান্ড লাইন প্যারামিটারগুলি বের করে এটি চালিয়ে যেতে 10 মিনিটের মতো সময় লাগে। আপনি আরো কি করতে চান?
হারুন ব্রাউন

12

যদি আপনার মাইএসকিউএল 5.1 থাকে যেখানে প্রক্রিয়া তালিকা INFORMATION_SCHEMA এ রয়েছে, আপনি 20 মিনিট (1200 সেকেন্ড) এর চেয়ে বেশি সময় ধরে চলমান প্রশ্নের জন্য মাইএসকিএল ক্লায়েন্টের মধ্যে থেকে কিল কমান্ড কমান্ড তৈরি করতে এটি করতে পারেন:

SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery
FROM information_schema.processlist WHERE user<>'system user'
AND time >= 1200\G

নির্দিষ্ট ক্যোয়ারী অনুসন্ধানের জন্য আপনি INFO ক্ষেত্রের বিপরীতে যেখানে বিধিগুলি করতে পারেন, দীর্ঘ চলমান ক্যোয়ারির বিরুদ্ধে TIME ক্ষেত্র, বা একটি নির্দিষ্ট ডাটাবেসের বিরুদ্ধে ডিবি ক্ষেত্র।

আপনি যদি রুট @ লোকালহোস্ট হন তবে নীচের মত এটি চালানোর জন্য আপনার সম্পূর্ণ অধিকার থাকা উচিত

SECONDS_TOO_LONG=1200
KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"
mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword

আপনি নিম্নলিখিত হিসাবে এটি crontab করতে পারেন:

SECONDS_TOO_LONG=1200
QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"`
if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ]
then
    KILLPROC_SQLSTMT="SELECT GROUP_CONCAT(CONCAT('KILL QUERY ',id,';') SEPARATOR ' ') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"
    mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" | mysql -uroot -ppassword
fi

এখানে আরও একটি প্রকরণ রয়েছে:

SECONDS_TOO_LONG=1200
QUERIES_RUNNING_TOO_LONG=`mysql -uroot -ppassword -ANe"SELECT COUNT(1) FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"`
if [ ${QUERIES_RUNNING_TOO_LONG} -gt 0 ]
then
    KILLPROC_SQLSTMT="SELECT CONCAT('KILL QUERY ',id,';') KillQuery FROM information_schema.processlist WHERE user<>'system user' AND time >= ${SECONDS_TOO_LONG}"
    mysql -uroot -ppassword -ANe"${KILLPROC_SQLSTMT}" > /tmp/kill_log_queries.sql
    mysql -uroot -ppassword < /tmp/kill_log_queries.sql
fi

বিটিডব্লিউ আপনার কাছে কোনও মাইডিবি নির্দিষ্ট নেই কারণ আমি পুরোপুরি যোগ্যতাসম্পন্ন টেবিলের নাম হিসাবে তথ্য_সেমি.প্রসেসলিস্ট থেকে স্পষ্টভাবে পড়েছি।

আপনার যা দেখতে হবে তা এখানে একটি প্রদর্শন। এই উদাহরণস্বরূপ, আমি সমস্ত প্রসেসের কিল কমান্ড প্রতিধ্বনিত করব যার সময়> 20000 সেকেন্ড:

[root@***** ~]# mysql `lwdba_connect` -ANe"SELECT GROUP_CONCAT('KILL ',id,'; ' SEPARATOR ' ') FROM information_schema.processlist WHERE time > 25000 AND user<>'system user';"
+----------------------------------------------------+
| KILL 180186;  KILL 180141;  KILL 176419;  KILL 3;  |
+----------------------------------------------------+
[root@***** ~]#

আমি এই কৌশলটি গত 5 বছর ধরে করে আসছি। আসলে, আমি এই উত্তরটি গত বছর ডিবিএ স্ট্যাকএক্সচেঞ্জে জমা দিয়েছিলাম এবং এটি গৃহীত হয়েছিল


রোল্যান্ড, আপনি কি দয়া করে এগুলি স্পষ্ট করে বলতে পারেন: এই আদেশটি কি অবিচল, নাকি ঘন ঘন চালানো দরকার? মাইএসকিএল ব্যবহারকারী 'রুট' এবং ডাটাবেসটির নাম মাইডিবি হ'ল ধরে নিয়ে কমান্ডটিতে কী যুক্ত করা উচিত? ধন্যবাদ
আলফিশ

আমি আমার উত্তর আপডেট।
রোল্যান্ডোমাইএসকিউএলডিবিএ

ধন্যবাদ, তবে আপনার শেষ রেসিপিটি ব্যাশ স্ক্রিপ্টে রূপান্তরিত করার পরে, আমি পেয়েছি: লাইন 1 এ ERROR 1064 (42000): আপনার এসকিউএল সিন্টেক্সে আপনার একটি ত্রুটি রয়েছে; 1 ম লাইনে '' এর নিকটবর্তী সঠিক
সংশ্লেষের

কোন এসকিউএল আদেশটি ত্রুটিটি তৈরি করেছিল ???
RolandoMySQLDBA

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

6

আমি এখানে নিম্নলিখিত কোড-স্নিপড পেয়েছি :

আপডেট 2013-01-14: একটি বেনামে ইঙ্গিত ছিল যে এটি সম্ভাব্য বিপজ্জনক এবং অনুলিপি প্রক্রিয়াগুলিও হত্যা করতে পারে। সুতরাং আপনার নিজের ঝুঁকিতে ব্যবহার করুন:

mysql -e 'show processlist\G' |\
egrep -b5 'Time: [0-9]{2,}' |\
grep 'Id:' |\
cut -d':' -f2 |\
sed 's/^ //' |\
while read id
do
  mysql -e "kill $id;"
done

উপরের স্নিপেটে সময় ধ্রুবকটি কী?
আলফিশ

@ আলফিশ আমি লেখক নই - তবে আমি বলব এটি একটি নিয়মিত প্রকাশ যা কমপক্ষে দুটি অঙ্কযুক্ত সর্বকালের মানের সাথে মেলে। সুতরাং এখানে অনুমান যে 10 খুব দীর্ঘ।
নীল

1

মাইএসকিউএল ৫.7 এর পরে আপনি সমস্ত "নির্বাচন" পড়ার প্রশ্নের জন্য স্বয়ংক্রিয়ভাবে এটি সম্পন্ন করতে সর্বোচ্চ_অ্যাকশন_টাইম ভেরিয়েবলটি ব্যবহার করতে পারেন।


0

আপনি আপটাইম পছন্দ হলে আমি বাশ সমাধানগুলি চেষ্টা করব না!

আপনার যদি কোডটিতে অ্যাক্সেস থাকে তবে আপনি এখানে বর্ণিত পদ্ধতিটি ব্যবহার করে সलेक्ट স্টেটমেন্টগুলিতে সর্বাধিক কার্যকর সময় নির্ধারণ করতে পারেন :

SELECT 
MAX_EXECUTION_TIME = 1000 --in milliseconds
* 
FROM table;

অন্যথায়, সার্ভারে:

/programming/415905/how-to-set-a-maximum-execution-time-for-a-mysql-query

পিটি-কিল ইনস্টল করুন:

$ wget percona.com/get/pt-kill

আপনার প্রসেসলিস্টের একটি স্ন্যাপশট নিন:

$ mysql -u root -B -pmyreallyimportantpassword -e "show processlist;" > processlist.txt

স্ন্যাপশটে পিটি-কিল পরীক্ষা করুন:

$ ./pt-kill --test-matching processlist.txt --busy-time 45 --kill-busy-commands 'Execute' --victims all --print
# 2019-02-25T17:34:37 KILL 45710302 (Execute 374 sec) SELECT\n\tCOUNT(DISTINCT(LP.sessionId))\nFROM lp_traffic LP\nINNER JOIN orders O ON O.orderId = LP.order
# 2019-02-25T17:34:37 KILL 45713515 (Execute 67 sec) SELECT \n\tCOUNT(DISTINCT(CASE WHEN T.response = 'SUCCESS' AND T.isVoid = 0 AND (T.txnType IN

ম্যাচের নিয়মগুলি আপনার ক্ষেত্রে উপযুক্ত কিনা তা নিশ্চিত করুন। এগুলি উপরের 45 সেকেন্ডের মধ্যে সমস্ত কার্যকর বিবৃতি মেরে ফেলবে। একবার আপনি নিশ্চিত হয়ে গেলে 10 সেকেন্ডের ব্যবধানে বিবৃতিটি কার্যকর করতে এই কমান্ডটি সংশোধন করুন এবং চালনা করুন:

$ ./pt-kill -u root -p myreallyimportantpassword --busy-time 45 --kill-busy-commands 'Execute' --victims all --interval 10 --kill
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.