MySQL Slow Query Log
Thu 25 April 2013တစ်ခါတစ်ရံမှာ သုံးနေရင်းနဲ့ MySQL ဟာ Response အရမ်းကြာတာတွေဖြစ်လာတယ် တတ်နိုင်ရင်တော့ Query ကိုရှင်းရှင်းလင်းလင်း ရေးလေ့ရှိပေမယ့်လည်း မလွှဲသာရင်တော့ ရှုပ်ရှုပ်ထွေးထွေး Aggregation တွေလည်းရေးရတော့တယ်။ အဲဒီလို Query တွေများများလာရင် ဘယ် Query ကြောင့်နှေးမှန်းကို မသိတော့တဲ့အခြေအနေလည်း ရောက်လာတတ်တယ်။
general_log_file = /var/log/mysql/mysql.log
general_log = 1
အဲလိုအခြေအနေရောက်ရင် ပထမဆုံးတစ်နည်းက General Query Log ကို Enable လုပ်ပြီးတော့ ဝင်လာသမျှ Query တွေကို Log File ထဲကိုရေးခိုင်းလိုက်လို့ရတယ်။ ဝင်လာသမျှ Query တွေကိုကြည့်လို့ရတော့ အကောင်းဆုံးလို့ပြောလို့ရပေမယ့် Query တိုင်းကို မှတ်ထားတဲ့အတွက် တစ်နေကုန်သာ Log လုပ်ထားရင် Log File ဟာအတော်ကိုကြီးပါလိမ့်မယ် အဆက်မပြတ်သုံးနေတဲ့ Database ဖြစ်ခဲ့ရင်တော့ Gigabye အရွယ်အစားဖိုင်ကြီးကို Analyze လုပ်ရပါလိမ့်မယ်။ အဲဒီတော့ General Query Log ဟာ မတတ်သာမှပဲ လုပ်လို့အဆင်ပြေပါတယ်။
slow_query_log
min_examined_row_limit
long_query_time
တကယ်တော့ Query တွေအကုန်လုံးလည်း သိစရာတော့မလိုဘူး တကယ်သိချင်တာက နှေးတဲ့ Query တွေကိုသိရင် ဘာဆက်လုပ်ရမလဲ ဆုံးဖြတ်လို့ရတယ် MySQL မှာတစ်ခုအဆင်ပြေတာက Log ကိုအားလုံးမလုပ်ပဲ နှေးတဲ့ Query တွေကိုပဲ Log လုပ်တဲ့ Slow Query Log ရှိတယ်။ ဒီနေရာမှာနှေးတယ်ဆိုတာ ဘယ်လိုသတ်မှတ်သလဲ ဆုံးဖြတ်ပေးလို့ရတယ် အချိန်နဲ့ဆိုရင် long_query_time မှာ သတ်မှတ်ထားပေးရင် အဲဒီ့အချိန်ထက်ပိုတဲ့ Query တွေဟာ Slow လို့သတ်မှတ်တယ် အချိန်နဲ့မဟုတ်ဘူး Scan လုပ်ခဲ့တဲ့ Row အရေအတွက်နဲ့ တိုင်းချင်ရင်လည်း min_examined_row_limit သတ်မှတ်ပေးပြီး အဲဒီအရေအတွက်ထက်ပိုရင် Slow Query လို့သတ်မှတ်လို့ရတယ်။
log_queries_not_using_indexes
Log လုပ်ထားတဲ့ Query တွေကို Anlyze လုပ်တဲ့ပထမဆုံးအဆင့်က Slow Query ကိုရှာတယ် အဲဒီတော့ Slow Query Log ဆိုရင်ပဲ ပထမတစ်ဆင့် အဆင်ပြေပါတယ်။ နောက်တစ်ဆင့်အနေနဲ့ Slow Query တွေကို Optimize လုပ်မယ်ဆိုရင် လိုအပ်တဲ့ Index မရှိလို့နှေးနေတာက အဖြစ်အများဆုံးဆိုတော့ Join တွေ Condition တွေမှာ သုံးထားတဲ့ Column တွေမှာ သင့်လျော်တဲ့ Index ရှိမရှိကြည့်ရတယ်။ Index မသုံးပဲ Table Scan လုပ်နေတဲ့ Query တွေကို Log လုပ်ခိုင်းထားနိုင်ရင် ပိုအဆင်ပြေတယ်။ log_queries_not_using_indexes ကို Enable လုပ်ထားရင် အလွယ်တကူပဲ Log ထဲမှာခွဲလို့ရတယ်။
# Time: 130425 4:13:47
# User@Host: myhost[myhost] @ myhost []
# Query_time: 0.000984 Lock_time: 0.000443 Rows_sent: 0 Rows_examined: 4
SET timestamp=1366863227;
select count(*) into @discard from `information_schema`.`PARAMETERS`;
# Time: 130425 4:18:36
# User@Host: myhost[myhost] @ myhost []
# Query_time: 0.001904 Lock_time: 0.000091 Rows_sent: 386 Rows_examined: 439
use myambook;
SET timestamp=1366863516;
SELECT option_name, option_value FROM wp_options WHERE autoload = 'yes';
Index တွေသင့်သလို ထည့်ပေးလို့မှ မပြေလည်သေးရင်တော့ အသေးစိတ်စပြီးတော့ Analyze လုပ်ဖို့လိုပါပြီ ဒီနေရာမှာတော့ DBA ကို Tools အစားထိုးလို့မရတော့ဘူး။ Log ထဲမှာ Time, timestamp, Query_time, Lock_time, Rows_sent, Rows_examined, Query အဲဒါတွေကို အသေအချာယှဉ်ကြည့်ရတော့တယ်။ Manual ယှဉ်ကြည့်ရင်တော့ များတာနဲ့အမျှ မျက်စေ့လည်ပြီးတော့ ဘယ်နားကဖြစ်မှန်း မသိဆုံးဖြတ်ရခက်တော့ Log File တွေကို Analyze လုပ်တဲ့ Tools တွေသုံးရတော့တယ်။ MySQL အတွက် Percona Toolkit ဟာအသုံးများပါတယ်။
$ pt-query-digest mysql-slow.log
Percona ရဲ့ pt-query-digest နဲ့ Slow Query Log တွေကို အလွယ်တကူ Summarize လုပ်လို့ရတယ်။ Overview အနေနဲ့ Exec time, Lock time, Rows sent, Rows examine, Query size တွေကြည့်လို့ရတာဟာ ဘယ်နေရာမှာအဓိကကြာနေသလဲ ဆုံးဖြတ်တဲ့နေရာမှာ အထောက်အကူပြုတယ်။ Exec time ပိုကြာရင်တော့ Index လိုနေသလား ပိုနေသလားကြည့်ရင် အများအားဖြင့်အဆင်ပြေတယ်။ Lock time များနေရင်တော့ Query တွေရဲ့ အချိန်တွေကိုကြည့်ပြီး Parallel ဖြစ်နေတဲ့ Query တွေကိုရှာ အဲဒီကတစ်ဆင့် Dead Lock ဖြစ်နိုင်တဲ့ Query တွေရှာရမယ် အဲဒါတွေတော့ Manual Process ဖြစ်တော့ပြောရခက်တယ် တစ်ခါတစ်ရံလည်း အလွယ်တကူပြဿနာကိုရှာတွေ့တယ် အခုတော့ဘယ်လိုမှ ရှာမတွေ့သေးတော့ ရုံးရောက်လိုက် Log File ဖွင့်လိုက်နဲ့ လည်နေတယ်။ ရှာတွေ့ရင်တော့ Example တစ်ခုနဲ့ ရေးစရာတစ်ခုတော့ရမယ်ထင်ပါတယ် အခုတော့ ခေါင်းလည်းကိုက် အိပ်ရေးလည်းပျက်ပြီ နှေးလည်းသည်းခံစောင့်ကြလိမ့်မယ် အိမ်ပြန်အိပ်တာပဲကောင်းတယ်။
# 220ms user time, 40ms system time, 19.50M rss, 68.16M vsz
# Current date: Thu Apr 25 05:55:47 2013
# Hostname: myhost
# Files: mysql-slow.log
# Overall: 26 total, 20 unique, 0.05 QPS, 0.05x concurrency ______________
# Time range: 2013-04-25 04:13:47 to 04:22:27
# Attribute total min max avg 95% stddev median
# ============ ======= ======= ======= ======= ======= ======= =======
# Exec time 24s 137us 10s 929ms 3s 3s 1ms
# Lock time 5ms 41us 443us 187us 384us 123us 148us
# Rows sent 1.21k 0 387 47.50 258.32 111.08 0.99
# Rows examine 6.54M 0 2.86M 257.66k 830.38k 756.98k 84.10
# Query size 3.92k 63 503 154.42 381.65 133.14 69.19