You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1635 satır
51KB

  1. #!/bin/sh
  2. # vim: ts=8
  3. #########################################################################
  4. # #
  5. # MySQL performance tuning primer script #
  6. # Writen by: Matthew Montgomery #
  7. # Report bugs to: https://bugs.launchpad.net/mysql-tuning-primer #
  8. # Inspired by: MySQLARd (http://gert.sos.be/demo/mysqlar/) #
  9. # Version: 1.6-r1 Released: 2011-08-06 #
  10. # Licenced under GPLv2 #
  11. # #
  12. #########################################################################
  13. #########################################################################
  14. # #
  15. # Usage: ./tuning-primer.sh [ mode ] #
  16. # #
  17. # Available Modes: #
  18. # all : perform all checks (default) #
  19. # prompt : prompt for login credintials and socket #
  20. # and execution mode #
  21. # mem, memory : run checks for tunable options which #
  22. # effect memory usage #
  23. # disk, file : run checks for options which effect #
  24. # i/o performance or file handle limits #
  25. # innodb : run InnoDB checks /* to be improved */ #
  26. # misc : run checks for that don't categorise #
  27. # well Slow Queries, Binary logs, #
  28. # Used Connections and Worker Threads #
  29. #########################################################################
  30. # #
  31. # Set this socket variable ONLY if you have multiple instances running #
  32. # or we are unable to find your socket, and you don't want to to be #
  33. # prompted for input each time you run this script. #
  34. # #
  35. #########################################################################
  36. socket=
  37. export black='\033[0m'
  38. export boldblack='\033[1;0m'
  39. export red='\033[31m'
  40. export boldred='\033[1;31m'
  41. export green='\033[32m'
  42. export boldgreen='\033[1;32m'
  43. export yellow='\033[33m'
  44. export boldyellow='\033[1;33m'
  45. export blue='\033[34m'
  46. export boldblue='\033[1;34m'
  47. export magenta='\033[35m'
  48. export boldmagenta='\033[1;35m'
  49. export cyan='\033[36m'
  50. export boldcyan='\033[1;36m'
  51. export white='\033[37m'
  52. export boldwhite='\033[1;37m'
  53. cecho ()
  54. ## -- Function to easliy print colored text -- ##
  55. # Color-echo.
  56. # Argument $1 = message
  57. # Argument $2 = color
  58. {
  59. local default_msg="No message passed."
  60. message=${1:-$default_msg} # Defaults to default message.
  61. #change it for fun
  62. #We use pure names
  63. color=${2:-black} # Defaults to black, if not specified.
  64. case $color in
  65. black)
  66. printf "$black" ;;
  67. boldblack)
  68. printf "$boldblack" ;;
  69. red)
  70. printf "$red" ;;
  71. boldred)
  72. printf "$boldred" ;;
  73. green)
  74. printf "$green" ;;
  75. boldgreen)
  76. printf "$boldgreen" ;;
  77. yellow)
  78. printf "$yellow" ;;
  79. boldyellow)
  80. printf "$boldyellow" ;;
  81. blue)
  82. printf "$blue" ;;
  83. boldblue)
  84. printf "$boldblue" ;;
  85. magenta)
  86. printf "$magenta" ;;
  87. boldmagenta)
  88. printf "$boldmagenta" ;;
  89. cyan)
  90. printf "$cyan" ;;
  91. boldcyan)
  92. printf "$boldcyan" ;;
  93. white)
  94. printf "$white" ;;
  95. boldwhite)
  96. printf "$boldwhite" ;;
  97. esac
  98. printf "%s\n" "$message"
  99. tput sgr0 # Reset to normal.
  100. printf "$black"
  101. return
  102. }
  103. cechon ()
  104. ## -- Function to easliy print colored text -- ##
  105. # Color-echo.
  106. # Argument $1 = message
  107. # Argument $2 = color
  108. {
  109. local default_msg="No message passed."
  110. # Doesn't really need to be a local variable.
  111. message=${1:-$default_msg} # Defaults to default message.
  112. #change it for fun
  113. #We use pure names
  114. color=${2:-black} # Defaults to black, if not specified.
  115. case $color in
  116. black)
  117. printf "$black" ;;
  118. boldblack)
  119. printf "$boldblack" ;;
  120. red)
  121. printf "$red" ;;
  122. boldred)
  123. printf "$boldred" ;;
  124. green)
  125. printf "$green" ;;
  126. boldgreen)
  127. printf "$boldgreen" ;;
  128. yellow)
  129. printf "$yellow" ;;
  130. boldyellow)
  131. printf "$boldyellow" ;;
  132. blue)
  133. printf "$blue" ;;
  134. boldblue)
  135. printf "$boldblue" ;;
  136. magenta)
  137. printf "$magenta" ;;
  138. boldmagenta)
  139. printf "$boldmagenta" ;;
  140. cyan)
  141. printf "$cyan" ;;
  142. boldcyan)
  143. printf "$boldcyan" ;;
  144. white)
  145. printf "$white" ;;
  146. boldwhite)
  147. printf "$boldwhite" ;;
  148. esac
  149. printf "%s" "$message"
  150. tput sgr0 # Reset to normal.
  151. printf "$black"
  152. return
  153. }
  154. print_banner () {
  155. ## -- Banner -- ##
  156. cecho " -- MYSQL PERFORMANCE TUNING PRIMER --" boldblue
  157. cecho " - By: Matthew Montgomery -" black
  158. }
  159. ## -- Find the location of the mysql.sock file -- ##
  160. check_for_socket () {
  161. if [ -z "$socket" ] ; then
  162. # Use ~/my.cnf version
  163. if [ -f ~/.my.cnf ] ; then
  164. cnf_socket=$(grep ^socket ~/.my.cnf | awk -F \= '{ print $2 }' | head -1)
  165. fi
  166. if [ -S "$cnf_socket" ] ; then
  167. socket=$cnf_socket
  168. elif [ -S /var/lib/mysql/mysql.sock ] ; then
  169. socket=/var/lib/mysql/mysql.sock
  170. elif [ -S /var/run/mysqld/mysqld.sock ] ; then
  171. socket=/var/run/mysqld/mysqld.sock
  172. elif [ -S /tmp/mysql.sock ] ; then
  173. socket=/tmp/mysql.sock
  174. else
  175. if [ -S "$ps_socket" ] ; then
  176. socket=$ps_socket
  177. fi
  178. fi
  179. fi
  180. if [ -S "$socket" ] ; then
  181. echo UP > /dev/null
  182. else
  183. cecho "No valid socket file \"$socket\" found!" boldred
  184. cecho "The mysqld process is not running or it is installed in a custom location." red
  185. cecho "If you are sure mysqld is running, execute script in \"prompt\" mode or set " red
  186. cecho "the socket= variable at the top of this script" red
  187. exit 1
  188. fi
  189. }
  190. check_for_plesk_passwords () {
  191. ## -- Check for the existance of plesk and login using it's credentials -- ##
  192. if [ -f /etc/psa/.psa.shadow ] ; then
  193. mysql="mysql -S $socket -u admin -p$(cat /etc/psa/.psa.shadow)"
  194. mysqladmin="mysqladmin -S $socket -u admin -p$(cat /etc/psa/.psa.shadow)"
  195. else
  196. mysql="mysql"
  197. mysqladmin="mysqladmin"
  198. # mysql="mysql -S $socket"
  199. # mysqladmin="mysqladmin -S $socket"
  200. fi
  201. }
  202. check_mysql_login () {
  203. ## -- Test for running mysql -- ##
  204. is_up=$($mysqladmin ping 2>&1)
  205. if [ "$is_up" = "mysqld is alive" ] ; then
  206. echo UP > /dev/null
  207. # echo $is_up
  208. elif [ "$is_up" != "mysqld is alive" ] ; then
  209. printf "\n"
  210. cecho "Using login values from ~/.my.cnf"
  211. cecho "- INITIAL LOGIN ATTEMPT FAILED -" boldred
  212. if [ -z $prompted ] ; then
  213. find_webmin_passwords
  214. else
  215. return 1
  216. fi
  217. else
  218. cecho "Unknow exit status" red
  219. exit -1
  220. fi
  221. }
  222. final_login_attempt () {
  223. is_up=$($mysqladmin ping 2>&1)
  224. if [ "$is_up" = "mysqld is alive" ] ; then
  225. echo UP > /dev/null
  226. elif [ "$is_up" != "mysqld is alive" ] ; then
  227. cecho "- FINAL LOGIN ATTEMPT FAILED -" boldred
  228. cecho "Unable to log into socket: $socket" boldred
  229. exit 1
  230. fi
  231. }
  232. second_login_failed () {
  233. ## -- create a ~/.my.cnf and exit when all else fails -- ##
  234. cecho "Could not auto detect login info!"
  235. cecho "Found potential sockets: $found_socks"
  236. cecho "Using: $socket" red
  237. read -p "Would you like to provide a different socket?: [y/N] " REPLY
  238. case $REPLY in
  239. yes | y | Y | YES)
  240. read -p "Socket: " socket
  241. ;;
  242. esac
  243. read -p "Do you have your login handy ? [y/N] : " REPLY
  244. case $REPLY in
  245. yes | y | Y | YES)
  246. answer1='yes'
  247. read -p "User: " user
  248. read -rp "Password: " pass
  249. if [ -z $pass ] ; then
  250. export mysql="$mysql -S$socket -u$user"
  251. export mysqladmin="$mysqladmin -S$socket -u$user"
  252. else
  253. export mysql="$mysql -S$socket -u$user -p$pass"
  254. export mysqladmin="$mysqladmin -S$socket -u$user -p$pass"
  255. fi
  256. ;;
  257. *)
  258. cecho "Please create a valid login to MySQL"
  259. cecho "Or, set correct values for 'user=' and 'password=' in ~/.my.cnf"
  260. ;;
  261. esac
  262. cecho " "
  263. read -p "Would you like me to create a ~/.my.cnf file for you? [y/N] : " REPLY
  264. case $REPLY in
  265. yes | y | Y | YES)
  266. answer2='yes'
  267. if [ ! -f ~/.my.cnf ] ; then
  268. umask 077
  269. printf "[client]\nuser=$user\npassword=$pass\nsocket=$socket" > ~/.my.cnf
  270. if [ "$answer1" != 'yes' ] ; then
  271. exit 1
  272. else
  273. final_login_attempt
  274. return 0
  275. fi
  276. else
  277. printf "\n"
  278. cecho "~/.my.cnf already exists!" boldred
  279. printf "\n"
  280. read -p "Replace ? [y/N] : " REPLY
  281. if [ "$REPLY" = 'y' ] || [ "$REPLY" = 'Y' ] ; then
  282. printf "[client]\nuser=$user\npassword=$pass\socket=$socket" > ~/.my.cnf
  283. if [ "$answer1" != 'yes' ] ; then
  284. exit 1
  285. else
  286. final_login_attempt
  287. return 0
  288. fi
  289. else
  290. cecho "Please set the 'user=' and 'password=' and 'socket=' values in ~/.my.cnf"
  291. exit 1
  292. fi
  293. fi
  294. ;;
  295. *)
  296. if [ "$answer1" != 'yes' ] ; then
  297. exit 1
  298. else
  299. final_login_attempt
  300. return 0
  301. fi
  302. ;;
  303. esac
  304. }
  305. find_webmin_passwords () {
  306. ## -- populate the .my.cnf file using values harvested from Webmin -- ##
  307. cecho "Testing for stored webmin passwords:"
  308. if [ -f /etc/webmin/mysql/config ] ; then
  309. user=$(grep ^login= /etc/webmin/mysql/config | cut -d "=" -f 2)
  310. pass=$(grep ^pass= /etc/webmin/mysql/config | cut -d "=" -f 2)
  311. if [ $user ] && [ $pass ] && [ ! -f ~/.my.cnf ] ; then
  312. cecho "Setting login info as User: $user Password: $pass"
  313. touch ~/.my.cnf
  314. chmod 600 ~/.my.cnf
  315. printf "[client]\nuser=$user\npassword=$pass" > ~/.my.cnf
  316. cecho "Retrying login"
  317. is_up=$($mysqladmin ping 2>&1)
  318. if [ "$is_up" = "mysqld is alive" ] ; then
  319. echo UP > /dev/null
  320. else
  321. second_login_failed
  322. fi
  323. echo
  324. else
  325. second_login_failed
  326. echo
  327. fi
  328. else
  329. cecho " None Found" boldred
  330. second_login_failed
  331. fi
  332. }
  333. #########################################################################
  334. # #
  335. # Function to pull MySQL status variable #
  336. # #
  337. # Call using : #
  338. # mysql_status \'Mysql_status_variable\' bash_dest_variable #
  339. # #
  340. #########################################################################
  341. mysql_status () {
  342. local status=$($mysql -Bse "show /*!50000 global */ status like $1" | awk '{ print $2 }')
  343. export "$2"=$status
  344. }
  345. #########################################################################
  346. # #
  347. # Function to pull MySQL server runtime variable #
  348. # #
  349. # Call using : #
  350. # mysql_variable \'Mysql_server_variable\' bash_dest_variable #
  351. # - OR - #
  352. # mysql_variableTSV \'Mysql_server_variable\' bash_dest_variable #
  353. # #
  354. #########################################################################
  355. mysql_variable () {
  356. local variable=$($mysql -Bse "show /*!50000 global */ variables like $1" | awk '{ print $2 }')
  357. export "$2"=$variable
  358. }
  359. mysql_variableTSV () {
  360. local variable=$($mysql -Bse "show /*!50000 global */ variables like $1" | awk -F \t '{ print $2 }')
  361. export "$2"=$variable
  362. }
  363. float2int () {
  364. local variable=$(echo "$1 / 1" | bc -l)
  365. export "$2"=$variable
  366. }
  367. divide () {
  368. # -- Divide two intigers -- #
  369. usage="$0 dividend divisor '$variable' scale"
  370. if [ $1 -ge 1 ] ; then
  371. dividend=$1
  372. else
  373. cecho "Invalid Dividend" red
  374. echo $usage
  375. exit 1
  376. fi
  377. if [ $2 -ge 1 ] ; then
  378. divisor=$2
  379. else
  380. cecho "Invalid Divisor" red
  381. echo $usage
  382. exit 1
  383. fi
  384. if [ ! -n $3 ] ; then
  385. cecho "Invalid variable name" red
  386. echo $usage
  387. exit 1
  388. fi
  389. if [ -z $4 ] ; then
  390. scale=2
  391. elif [ $4 -ge 0 ] ; then
  392. scale=$4
  393. else
  394. cecho "Invalid scale" red
  395. echo $usage
  396. exit 1
  397. fi
  398. export $3=$(echo "scale=$scale; $dividend / $divisor" | bc -l)
  399. }
  400. human_readable () {
  401. #########################################################################
  402. # #
  403. # Convert a value in to human readable size and populate a variable #
  404. # with the result. #
  405. # #
  406. # Call using: #
  407. # human_readable $value 'variable name' [ places of precision] #
  408. # #
  409. #########################################################################
  410. ## value=$1
  411. ## variable=$2
  412. scale=$3
  413. if [ $1 -ge 1073741824 ] ; then
  414. if [ -z $3 ] ; then
  415. scale=2
  416. fi
  417. divide $1 1073741824 "$2" $scale
  418. unit="G"
  419. elif [ $1 -ge 1048576 ] ; then
  420. if [ -z $3 ] ; then
  421. scale=0
  422. fi
  423. divide $1 1048576 "$2" $scale
  424. unit="M"
  425. elif [ $1 -ge 1024 ] ; then
  426. if [ -z $3 ] ; then
  427. scale=0
  428. fi
  429. divide $1 1024 "$2" $scale
  430. unit="K"
  431. else
  432. export "$2"=$1
  433. unit="bytes"
  434. fi
  435. # let "$2"=$HR
  436. }
  437. human_readable_time () {
  438. ########################################################################
  439. # #
  440. # Function to produce human readable time #
  441. # #
  442. ########################################################################
  443. usage="$0 seconds 'variable'"
  444. if [ -z $1 ] || [ -z $2 ] ; then
  445. cecho $usage red
  446. exit 1
  447. fi
  448. days=$(echo "scale=0 ; $1 / 86400" | bc -l)
  449. remainder=$(echo "scale=0 ; $1 % 86400" | bc -l)
  450. hours=$(echo "scale=0 ; $remainder / 3600" | bc -l)
  451. remainder=$(echo "scale=0 ; $remainder % 3600" | bc -l)
  452. minutes=$(echo "scale=0 ; $remainder / 60" | bc -l)
  453. seconds=$(echo "scale=0 ; $remainder % 60" | bc -l)
  454. export $2="$days days $hours hrs $minutes min $seconds sec"
  455. }
  456. check_mysql_version () {
  457. ## -- Print Version Info -- ##
  458. mysql_variable \'version\' mysql_version
  459. mysql_variable \'version_compile_machine\' mysql_version_compile_machine
  460. if [ "$mysql_version_num" -lt 050000 ]; then
  461. cecho "MySQL Version $mysql_version $mysql_version_compile_machine is EOL please upgrade to MySQL 4.1 or later" boldred
  462. else
  463. cecho "MySQL Version $mysql_version $mysql_version_compile_machine"
  464. fi
  465. }
  466. post_uptime_warning () {
  467. #########################################################################
  468. # #
  469. # Present a reminder that mysql must run for a couple of days to #
  470. # build up good numbers in server status variables before these tuning #
  471. # suggestions should be used. #
  472. # #
  473. #########################################################################
  474. mysql_status \'Uptime\' uptime
  475. mysql_status \'Threads_connected\' threads
  476. queries_per_sec=$(($questions/$uptime))
  477. human_readable_time $uptime uptimeHR
  478. cecho "Uptime = $uptimeHR"
  479. cecho "Avg. qps = $queries_per_sec"
  480. cecho "Total Questions = $questions"
  481. cecho "Threads Connected = $threads"
  482. echo
  483. if [ $uptime -gt 172800 ] ; then
  484. cecho "Server has been running for over 48hrs."
  485. cecho "It should be safe to follow these recommendations"
  486. else
  487. cechon "Warning: " boldred
  488. cecho "Server has not been running for at least 48hrs." boldred
  489. cecho "It may not be safe to use these recommendations" boldred
  490. fi
  491. echo ""
  492. cecho "To find out more information on how each of these" red
  493. cecho "runtime variables effects performance visit:" red
  494. if [ "$major_version" = '3.23' ] || [ "$major_version" = '4.0' ] || [ "$major_version" = '4.1' ] ; then
  495. cecho "http://dev.mysql.com/doc/refman/4.1/en/server-system-variables.html" boldblue
  496. elif [ "$major_version" = '5.0' ] || [ "$mysql_version_num" -gt '050100' ]; then
  497. cecho "http://dev.mysql.com/doc/refman/$major_version/en/server-system-variables.html" boldblue
  498. else
  499. cecho "UNSUPPORTED MYSQL VERSION" boldred
  500. exit 1
  501. fi
  502. cecho "Visit http://www.mysql.com/products/enterprise/advisors.html" boldblue
  503. cecho "for info about MySQL's Enterprise Monitoring and Advisory Service" boldblue
  504. }
  505. check_slow_queries () {
  506. ## -- Slow Queries -- ##
  507. cecho "SLOW QUERIES" boldblue
  508. mysql_status \'Slow_queries\' slow_queries
  509. mysql_variable \'long_query_time\' long_query_time
  510. mysql_variable \'log%queries\' log_slow_queries
  511. prefered_query_time=5
  512. if [ -e /etc/my.cnf ] ; then
  513. if [ -z $log_slow_queries ] ; then
  514. log_slow_queries=$(grep log-slow-queries /etc/my.cnf)
  515. fi
  516. fi
  517. if [ "$log_slow_queries" = 'ON' ] ; then
  518. cecho "The slow query log is enabled."
  519. elif [ "$log_slow_queries" = 'OFF' ] ; then
  520. cechon "The slow query log is "
  521. cechon "NOT" boldred
  522. cecho " enabled."
  523. elif [ -z $log_slow_queries ] ; then
  524. cechon "The slow query log is "
  525. cechon "NOT" boldred
  526. cecho " enabled."
  527. else
  528. cecho "Error: $log_slow_queries" boldred
  529. fi
  530. cecho "Current long_query_time = $long_query_time sec."
  531. cechon "You have "
  532. cechon "$slow_queries" boldred
  533. cechon " out of "
  534. cechon "$questions" boldred
  535. cecho " that take longer than $long_query_time sec. to complete"
  536. float2int long_query_time long_query_timeInt
  537. if [ $long_query_timeInt -gt $prefered_query_time ] ; then
  538. cecho "Your long_query_time may be too high, I typically set this under $prefered_query_time sec." red
  539. else
  540. cecho "Your long_query_time seems to be fine" green
  541. fi
  542. }
  543. check_binary_log () {
  544. ## -- Binary Log -- ##
  545. cecho "BINARY UPDATE LOG" boldblue
  546. mysql_variable \'log_bin\' log_bin
  547. mysql_variable \'max_binlog_size\' max_binlog_size
  548. mysql_variable \'expire_logs_days\' expire_logs_days
  549. mysql_variable \'sync_binlog\' sync_binlog
  550. # mysql_variable \'max_binlog_cache_size\' max_binlog_cache_size
  551. if [ "$log_bin" = 'ON' ] ; then
  552. cecho "The binary update log is enabled"
  553. if [ -z "$max_binlog_size" ] ; then
  554. cecho "The max_binlog_size is not set. The binary log will rotate when it reaches 1GB." red
  555. fi
  556. if [ "$expire_logs_days" -eq 0 ] ; then
  557. cecho "The expire_logs_days is not set." boldred
  558. cechon "The mysqld will retain the entire binary log until " red
  559. cecho "RESET MASTER or PURGE MASTER LOGS commands are run manually" red
  560. cecho "Setting expire_logs_days will allow you to remove old binary logs automatically" yellow
  561. cecho "See http://dev.mysql.com/doc/refman/$major_version/en/purge-master-logs.html" yellow
  562. fi
  563. if [ "$sync_binlog" = 0 ] ; then
  564. cecho "Binlog sync is not enabled, you could loose binlog records during a server crash" red
  565. fi
  566. else
  567. cechon "The binary update log is "
  568. cechon "NOT " boldred
  569. cecho "enabled."
  570. cecho "You will not be able to do point in time recovery" red
  571. cecho "See http://dev.mysql.com/doc/refman/$major_version/en/point-in-time-recovery.html" yellow
  572. fi
  573. }
  574. check_used_connections () {
  575. ## -- Used Connections -- ##
  576. mysql_variable \'max_connections\' max_connections
  577. mysql_status \'Max_used_connections\' max_used_connections
  578. mysql_status \'Threads_connected\' threads_connected
  579. connections_ratio=$(($max_used_connections*100/$max_connections))
  580. cecho "MAX CONNECTIONS" boldblue
  581. cecho "Current max_connections = $max_connections"
  582. cecho "Current threads_connected = $threads_connected"
  583. cecho "Historic max_used_connections = $max_used_connections"
  584. cechon "The number of used connections is "
  585. if [ $connections_ratio -ge 85 ] ; then
  586. txt_color=red
  587. error=1
  588. elif [ $connections_ratio -le 10 ] ; then
  589. txt_color=red
  590. error=2
  591. else
  592. txt_color=green
  593. error=0
  594. fi
  595. # cechon "$max_used_connections " $txt_color
  596. # cechon "which is "
  597. cechon "$connections_ratio% " $txt_color
  598. cecho "of the configured maximum."
  599. if [ $error -eq 1 ] ; then
  600. cecho "You should raise max_connections" $txt_color
  601. elif [ $error -eq 2 ] ; then
  602. cecho "You are using less than 10% of your configured max_connections." $txt_color
  603. cecho "Lowering max_connections could help to avoid an over-allocation of memory" $txt_color
  604. cecho "See \"MEMORY USAGE\" section to make sure you are not over-allocating" $txt_color
  605. else
  606. cecho "Your max_connections variable seems to be fine." $txt_color
  607. fi
  608. unset txt_color
  609. }
  610. check_threads() {
  611. ## -- Worker Threads -- ##
  612. cecho "WORKER THREADS" boldblue
  613. mysql_status \'Threads_created\' threads_created1
  614. sleep 1
  615. mysql_status \'Threads_created\' threads_created2
  616. mysql_status \'Threads_cached\' threads_cached
  617. mysql_status \'Uptime\' uptime
  618. mysql_variable \'thread_cache_size\' thread_cache_size
  619. historic_threads_per_sec=$(($threads_created1/$uptime))
  620. current_threads_per_sec=$(($threads_created2-$threads_created1))
  621. cecho "Current thread_cache_size = $thread_cache_size"
  622. cecho "Current threads_cached = $threads_cached"
  623. cecho "Current threads_per_sec = $current_threads_per_sec"
  624. cecho "Historic threads_per_sec = $historic_threads_per_sec"
  625. if [ $historic_threads_per_sec -ge 2 ] && [ $threads_cached -le 1 ] ; then
  626. cecho "Threads created per/sec are overrunning threads cached" red
  627. cecho "You should raise thread_cache_size" red
  628. elif [ $current_threads_per_sec -ge 2 ] ; then
  629. cecho "Threads created per/sec are overrunning threads cached" red
  630. cecho "You should raise thread_cache_size" red
  631. else
  632. cecho "Your thread_cache_size is fine" green
  633. fi
  634. }
  635. check_key_buffer_size () {
  636. ## -- Key buffer Size -- ##
  637. cecho "KEY BUFFER" boldblue
  638. mysql_status \'Key_read_requests\' key_read_requests
  639. mysql_status \'Key_reads\' key_reads
  640. mysql_status \'Key_blocks_used\' key_blocks_used
  641. mysql_status \'Key_blocks_unused\' key_blocks_unused
  642. mysql_variable \'key_cache_block_size\' key_cache_block_size
  643. mysql_variable \'key_buffer_size\' key_buffer_size
  644. mysql_variable \'datadir\' datadir
  645. mysql_variable \'version_compile_machine\' mysql_version_compile_machine
  646. myisam_indexes=$($mysql -Bse "/*!50000 SELECT IFNULL(SUM(INDEX_LENGTH),0) from information_schema.TABLES where ENGINE='MyISAM' */")
  647. if [ -z $myisam_indexes ] ; then
  648. myisam_indexes=$(find $datadir -name '*.MYI' -exec du $duflags '{}' \; 2>&1 | awk '{ s += $1 } END { printf("%.0f\n", s )}')
  649. fi
  650. if [ $key_reads -eq 0 ] ; then
  651. cecho "No key reads?!" boldred
  652. cecho "Seriously look into using some indexes" red
  653. key_cache_miss_rate=0
  654. key_buffer_free=$(echo "$key_blocks_unused * $key_cache_block_size / $key_buffer_size * 100" | bc -l )
  655. key_buffer_freeRND=$(echo "scale=0; $key_buffer_free / 1" | bc -l)
  656. else
  657. key_cache_miss_rate=$(($key_read_requests/$key_reads))
  658. if [ ! -z $key_blocks_unused ] ; then
  659. key_buffer_free=$(echo "$key_blocks_unused * $key_cache_block_size / $key_buffer_size * 100" | bc -l )
  660. key_buffer_freeRND=$(echo "scale=0; $key_buffer_free / 1" | bc -l)
  661. else
  662. key_buffer_free='Unknown'
  663. key_buffer_freeRND=75
  664. fi
  665. fi
  666. human_readable $myisam_indexes myisam_indexesHR
  667. cecho "Current MyISAM index space = $myisam_indexesHR $unit"
  668. human_readable $key_buffer_size key_buffer_sizeHR
  669. cecho "Current key_buffer_size = $key_buffer_sizeHR $unit"
  670. cecho "Key cache miss rate is 1 : $key_cache_miss_rate"
  671. cecho "Key buffer free ratio = $key_buffer_freeRND %"
  672. if [ "$major_version" = '5.1' ] && [ $mysql_version_num -lt 050123 ] ; then
  673. if [ $key_buffer_size -ge 4294967296 ] && ( echo "x86_64 ppc64 ia64 sparc64 i686" | grep -q $mysql_version_compile_machine ) ; then
  674. cecho "Using key_buffer_size > 4GB will cause instability in versions prior to 5.1.23 " boldred
  675. cecho "See Bug#5731, Bug#29419, Bug#29446" boldred
  676. fi
  677. fi
  678. if [ "$major_version" = '5.0' ] && [ $mysql_version_num -lt 050052 ] ; then
  679. if [ $key_buffer_size -ge 4294967296 ] && ( echo "x86_64 ppc64 ia64 sparc64 i686" | grep -q $mysql_version_compile_machine ) ; then
  680. cecho "Using key_buffer_size > 4GB will cause instability in versions prior to 5.0.52 " boldred
  681. cecho "See Bug#5731, Bug#29419, Bug#29446" boldred
  682. fi
  683. fi
  684. if [ "$major_version" = '4.1' -o "$major_version" = '4.0' ] && [ $key_buffer_size -ge 4294967296 ] && ( echo "x86_64 ppc64 ia64 sparc64 i686" | grep -q $mysql_version_compile_machine ) ; then
  685. cecho "Using key_buffer_size > 4GB will cause instability in versions prior to 5.0.52 " boldred
  686. cecho "Reduce key_buffer_size to a safe value" boldred
  687. cecho "See Bug#5731, Bug#29419, Bug#29446" boldred
  688. fi
  689. if [ $key_cache_miss_rate -le 100 ] && [ $key_cache_miss_rate -gt 0 ] && [ $key_buffer_freeRND -le 20 ]; then
  690. cecho "You could increase key_buffer_size" boldred
  691. cecho "It is safe to raise this up to 1/4 of total system memory;"
  692. cecho "assuming this is a dedicated database server."
  693. elif [ $key_buffer_freeRND -le 20 ] && [ $key_buffer_size -le $myisam_indexes ] ; then
  694. cecho "You could increase key_buffer_size" boldred
  695. cecho "It is safe to raise this up to 1/4 of total system memory;"
  696. cecho "assuming this is a dedicated database server."
  697. elif [ $key_cache_miss_rate -ge 10000 ] || [ $key_buffer_freeRND -le 50 ] ; then
  698. cecho "Your key_buffer_size seems to be too high." red
  699. cecho "Perhaps you can use these resources elsewhere" red
  700. else
  701. cecho "Your key_buffer_size seems to be fine" green
  702. fi
  703. }
  704. check_query_cache () {
  705. ## -- Query Cache -- ##
  706. cecho "QUERY CACHE" boldblue
  707. mysql_variable \'version\' mysql_version
  708. mysql_variable \'query_cache_size\' query_cache_size
  709. mysql_variable \'query_cache_limit\' query_cache_limit
  710. mysql_variable \'query_cache_min_res_unit\' query_cache_min_res_unit
  711. mysql_status \'Qcache_free_memory\' qcache_free_memory
  712. mysql_status \'Qcache_total_blocks\' qcache_total_blocks
  713. mysql_status \'Qcache_free_blocks\' qcache_free_blocks
  714. mysql_status \'Qcache_lowmem_prunes\' qcache_lowmem_prunes
  715. if [ -z $query_cache_size ] ; then
  716. cecho "You are using MySQL $mysql_version, no query cache is supported." red
  717. cecho "I recommend an upgrade to MySQL 4.1 or better" red
  718. elif [ $query_cache_size -eq 0 ] ; then
  719. cecho "Query cache is supported but not enabled" red
  720. cecho "Perhaps you should set the query_cache_size" red
  721. else
  722. qcache_used_memory=$(($query_cache_size-$qcache_free_memory))
  723. qcache_mem_fill_ratio=$(echo "scale=2; $qcache_used_memory * 100 / $query_cache_size" | bc -l)
  724. qcache_mem_fill_ratioHR=$(echo "scale=0; $qcache_mem_fill_ratio / 1" | bc -l)
  725. cecho "Query cache is enabled" green
  726. human_readable $query_cache_size query_cache_sizeHR
  727. cecho "Current query_cache_size = $query_cache_sizeHR $unit"
  728. human_readable $qcache_used_memory qcache_used_memoryHR
  729. cecho "Current query_cache_used = $qcache_used_memoryHR $unit"
  730. human_readable $query_cache_limit query_cache_limitHR
  731. cecho "Current query_cache_limit = $query_cache_limitHR $unit"
  732. cecho "Current Query cache Memory fill ratio = $qcache_mem_fill_ratio %"
  733. if [ -z $query_cache_min_res_unit ] ; then
  734. cecho "No query_cache_min_res_unit is defined. Using MySQL < 4.1 cache fragmentation can be inpredictable" %yellow
  735. else
  736. human_readable $query_cache_min_res_unit query_cache_min_res_unitHR
  737. cecho "Current query_cache_min_res_unit = $query_cache_min_res_unitHR $unit"
  738. fi
  739. if [ $qcache_free_blocks -gt 2 ] && [ $qcache_total_blocks -gt 0 ] ; then
  740. qcache_percent_fragmented=$(echo "scale=2; $qcache_free_blocks * 100 / $qcache_total_blocks" | bc -l)
  741. qcache_percent_fragmentedHR=$(echo "scale=0; $qcache_percent_fragmented / 1" | bc -l)
  742. if [ $qcache_percent_fragmentedHR -gt 20 ] ; then
  743. cecho "Query Cache is $qcache_percent_fragmentedHR % fragmented" red
  744. cecho "Run \"FLUSH QUERY CACHE\" periodically to defragment the query cache memory" red
  745. cecho "If you have many small queries lower 'query_cache_min_res_unit' to reduce fragmentation." red
  746. fi
  747. fi
  748. if [ $qcache_mem_fill_ratioHR -le 25 ] ; then
  749. cecho "Your query_cache_size seems to be too high." red
  750. cecho "Perhaps you can use these resources elsewhere" red
  751. fi
  752. if [ $qcache_lowmem_prunes -ge 50 ] && [ $qcache_mem_fill_ratioHR -ge 80 ]; then
  753. cechon "However, "
  754. cechon "$qcache_lowmem_prunes " boldred
  755. cecho "queries have been removed from the query cache due to lack of memory"
  756. cecho "Perhaps you should raise query_cache_size" boldred
  757. fi
  758. cecho "MySQL won't cache query results that are larger than query_cache_limit in size" yellow
  759. fi
  760. }
  761. check_sort_operations () {
  762. ## -- Sort Operations -- ##
  763. cecho "SORT OPERATIONS" boldblue
  764. mysql_status \'Sort_merge_passes\' sort_merge_passes
  765. mysql_status \'Sort_scan\' sort_scan
  766. mysql_status \'Sort_range\' sort_range
  767. mysql_variable \'sort_buffer%\' sort_buffer_size
  768. mysql_variable \'read_rnd_buffer_size\' read_rnd_buffer_size
  769. total_sorts=$(($sort_scan+$sort_range))
  770. if [ -z $read_rnd_buffer_size ] ; then
  771. mysql_variable \'record_buffer\' read_rnd_buffer_size
  772. fi
  773. ## Correct for rounding error in mysqld where 512K != 524288 ##
  774. sort_buffer_size=$(($sort_buffer_size+8))
  775. read_rnd_buffer_size=$(($read_rnd_buffer_size+8))
  776. human_readable $sort_buffer_size sort_buffer_sizeHR
  777. cecho "Current sort_buffer_size = $sort_buffer_sizeHR $unit"
  778. human_readable $read_rnd_buffer_size read_rnd_buffer_sizeHR
  779. cechon "Current "
  780. if [ "$major_version" = '3.23' ] ; then
  781. cechon "record_rnd_buffer "
  782. else
  783. cechon "read_rnd_buffer_size "
  784. fi
  785. cecho "= $read_rnd_buffer_sizeHR $unit"
  786. if [ $total_sorts -eq 0 ] ; then
  787. cecho "No sort operations have been performed"
  788. passes_per_sort=0
  789. fi
  790. if [ $sort_merge_passes -ne 0 ] ; then
  791. passes_per_sort=$(($sort_merge_passes/$total_sorts))
  792. else
  793. passes_per_sort=0
  794. fi
  795. if [ $passes_per_sort -ge 2 ] ; then
  796. cechon "On average "
  797. cechon "$passes_per_sort " boldred
  798. cecho "sort merge passes are made per sort operation"
  799. cecho "You should raise your sort_buffer_size"
  800. cechon "You should also raise your "
  801. if [ "$major_version" = '3.23' ] ; then
  802. cecho "record_rnd_buffer_size"
  803. else
  804. cecho "read_rnd_buffer_size"
  805. fi
  806. else
  807. cecho "Sort buffer seems to be fine" green
  808. fi
  809. }
  810. check_join_operations () {
  811. ## -- Joins -- ##
  812. cecho "JOINS" boldblue
  813. mysql_status \'Select_full_join\' select_full_join
  814. mysql_status \'Select_range_check\' select_range_check
  815. mysql_variable \'join_buffer%\' join_buffer_size
  816. ## Some 4K is dropped from join_buffer_size adding it back to make sane ##
  817. ## handling of human-readable conversion ##
  818. join_buffer_size=$(($join_buffer_size+4096))
  819. human_readable $join_buffer_size join_buffer_sizeHR 2
  820. cecho "Current join_buffer_size = $join_buffer_sizeHR $unit"
  821. cecho "You have had $select_full_join queries where a join could not use an index properly"
  822. if [ $select_range_check -eq 0 ] && [ $select_full_join -eq 0 ] ; then
  823. cecho "Your joins seem to be using indexes properly" green
  824. fi
  825. if [ $select_full_join -gt 0 ] ; then
  826. print_error='true'
  827. raise_buffer='true'
  828. fi
  829. if [ $select_range_check -gt 0 ] ; then
  830. cecho "You have had $select_range_check joins without keys that check for key usage after each row" red
  831. print_error='true'
  832. raise_buffer='true'
  833. fi
  834. ## For Debuging ##
  835. # print_error='true'
  836. if [ $join_buffer_size -ge 4194304 ] ; then
  837. cecho "join_buffer_size >= 4 M" boldred
  838. cecho "This is not advised" boldred
  839. raise_buffer=
  840. fi
  841. if [ $print_error ] ; then
  842. if [ "$major_version" = '3.23' ] || [ "$major_version" = '4.0' ] ; then
  843. cecho "You should enable \"log-long-format\" "
  844. elif [ "$mysql_version_num" -gt 040100 ]; then
  845. cecho "You should enable \"log-queries-not-using-indexes\""
  846. fi
  847. cecho "Then look for non indexed joins in the slow query log."
  848. if [ $raise_buffer ] ; then
  849. cecho "If you are unable to optimize your queries you may want to increase your"
  850. cecho "join_buffer_size to accommodate larger joins in one pass."
  851. printf "\n"
  852. cecho "Note! This script will still suggest raising the join_buffer_size when" boldred
  853. cecho "ANY joins not using indexes are found." boldred
  854. fi
  855. fi
  856. # XXX Add better tests for join_buffer_size pending mysql bug #15088 XXX #
  857. }
  858. check_tmp_tables () {
  859. ## -- Temp Tables -- ##
  860. cecho "TEMP TABLES" boldblue
  861. mysql_status \'Created_tmp_tables\' created_tmp_tables
  862. mysql_status \'Created_tmp_disk_tables\' created_tmp_disk_tables
  863. mysql_variable \'tmp_table_size\' tmp_table_size
  864. mysql_variable \'max_heap_table_size\' max_heap_table_size
  865. if [ $created_tmp_tables -eq 0 ] ; then
  866. tmp_disk_tables=0
  867. else
  868. tmp_disk_tables=$((created_tmp_disk_tables*100/(created_tmp_tables+created_tmp_disk_tables)))
  869. fi
  870. human_readable $max_heap_table_size max_heap_table_sizeHR
  871. cecho "Current max_heap_table_size = $max_heap_table_sizeHR $unit"
  872. human_readable $tmp_table_size tmp_table_sizeHR
  873. cecho "Current tmp_table_size = $tmp_table_sizeHR $unit"
  874. cecho "Of $created_tmp_tables temp tables, $tmp_disk_tables% were created on disk"
  875. if [ $tmp_table_size -gt $max_heap_table_size ] ; then
  876. cecho "Effective in-memory tmp_table_size is limited to max_heap_table_size." yellow
  877. fi
  878. if [ $tmp_disk_tables -ge 25 ] ; then
  879. cecho "Perhaps you should increase your tmp_table_size and/or max_heap_table_size" boldred
  880. cecho "to reduce the number of disk-based temporary tables" boldred
  881. cecho "Note! BLOB and TEXT columns are not allow in memory tables." yellow
  882. cecho "If you are using these columns raising these values might not impact your " yellow
  883. cecho "ratio of on disk temp tables." yellow
  884. else
  885. cecho "Created disk tmp tables ratio seems fine" green
  886. fi
  887. }
  888. check_open_files () {
  889. ## -- Open Files Limit -- ##
  890. cecho "OPEN FILES LIMIT" boldblue
  891. mysql_variable \'open_files_limit\' open_files_limit
  892. mysql_status \'Open_files\' open_files
  893. if [ -z $open_files_limit ] || [ $open_files_limit -eq 0 ] ; then
  894. open_files_limit=$(ulimit -n)
  895. cant_override=1
  896. else
  897. cant_override=0
  898. fi
  899. cecho "Current open_files_limit = $open_files_limit files"
  900. open_files_ratio=$(($open_files*100/$open_files_limit))
  901. cecho "The open_files_limit should typically be set to at least 2x-3x" yellow
  902. cecho "that of table_cache if you have heavy MyISAM usage." yellow
  903. if [ $open_files_ratio -ge 75 ] ; then
  904. cecho "You currently have open more than 75% of your open_files_limit" boldred
  905. if [ $cant_override -eq 1 ] ; then
  906. cecho "You should set a higer value for ulimit -u in the mysql startup script then restart mysqld" boldred
  907. cecho "MySQL 3.23 users : This is just a guess based upon the current shell's ulimit -u value" yellow
  908. elif [ $cant_override -eq 0 ] ; then
  909. cecho "You should set a higher value for open_files_limit in my.cnf" boldred
  910. else
  911. cecho "ERROR can't determine if mysqld override of ulimit is allowed" boldred
  912. exit 1
  913. fi
  914. else
  915. cecho "Your open_files_limit value seems to be fine" green
  916. fi
  917. }
  918. check_table_cache () {
  919. ## -- Table Cache -- ##
  920. cecho "TABLE CACHE" boldblue
  921. mysql_variable \'datadir\' datadir
  922. mysql_variable \'table_cache\' table_cache
  923. ## /* MySQL +5.1 version of table_cache */ ##
  924. mysql_variable \'table_open_cache\' table_open_cache
  925. mysql_variable \'table_definition_cache\' table_definition_cache
  926. mysql_status \'Open_tables\' open_tables
  927. mysql_status \'Opened_tables\' opened_tables
  928. mysql_status \'Open_table_definitions\' open_table_definitions
  929. table_count=$($mysql -Bse "/*!50000 SELECT COUNT(*) FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE='BASE TABLE' */")
  930. if [ -z "$table_count" ] ; then
  931. if [ "$UID" != "$socket_owner" ] && [ "$UID" != "0" ] ; then
  932. cecho "You are not '$socket_owner' or 'root'" red
  933. cecho "I am unable to determine the table_count!" red
  934. else
  935. table_count=$(find $datadir 2>&1 | grep -c .frm$)
  936. fi
  937. fi
  938. if [ $table_open_cache ] ; then
  939. table_cache=$table_open_cache
  940. fi
  941. if [ $opened_tables -ne 0 ] && [ $table_cache -ne 0 ] ; then
  942. table_cache_hit_rate=$(($open_tables*100/$opened_tables))
  943. table_cache_fill=$(($open_tables*100/$table_cache))
  944. elif [ $opened_tables -eq 0 ] && [ $table_cache -ne 0 ] ; then
  945. table_cache_hit_rate=100
  946. table_cache_fill=$(($open_tables*100/$table_cache))
  947. else
  948. cecho "ERROR no table_cache ?!" boldred
  949. exit 1
  950. fi
  951. if [ $table_cache ] && [ ! $table_open_cache ] ; then
  952. cecho "Current table_cache value = $table_cache tables"
  953. fi
  954. if [ $table_open_cache ] ; then
  955. cecho "Current table_open_cache = $table_open_cache tables"
  956. cecho "Current table_definition_cache = $table_definition_cache tables"
  957. fi
  958. if [ $table_count ] ; then
  959. cecho "You have a total of $table_count tables"
  960. fi
  961. if [ $table_cache_fill -lt 95 ] ; then
  962. cechon "You have "
  963. cechon "$open_tables " green
  964. cecho "open tables."
  965. cecho "The table_cache value seems to be fine" green
  966. elif [ $table_cache_hit_rate -le 85 -o $table_cache_fill -ge 95 ]; then
  967. cechon "You have "
  968. cechon "$open_tables " boldred
  969. cecho "open tables."
  970. cechon "Current table_cache hit rate is "
  971. cecho "$table_cache_hit_rate%" boldred
  972. cechon ", while "
  973. cechon "$table_cache_fill% " boldred
  974. cecho "of your table cache is in use"
  975. cecho "You should probably increase your table_cache" red
  976. else
  977. cechon "Current table_cache hit rate is "
  978. cechon "$table_cache_hit_rate%" green
  979. cechon ", while "
  980. cechon "$table_cache_fill% " green
  981. cecho "of your table cache is in use"
  982. cecho "The table cache value seems to be fine" green
  983. fi
  984. if [ $table_definition_cache ] && [ $table_definition_cache -le $table_count ] && [ $table_count -ge 100 ] ; then
  985. cecho "You should probably increase your table_definition_cache value." red
  986. fi
  987. }
  988. check_table_locking () {
  989. ## -- Table Locking -- ##
  990. cecho "TABLE LOCKING" boldblue
  991. mysql_status \'Table_locks_waited\' table_locks_waited
  992. mysql_status \'Table_locks_immediate\' table_locks_immediate
  993. mysql_variable \'concurrent_insert\' concurrent_insert
  994. mysql_variable \'low_priority_updates\' low_priority_updates
  995. if [ "$concurrent_insert" = 'ON' ]; then
  996. concurrent_insert=1
  997. elif [ "$concurrent_insert" = 'OFF' ]; then
  998. concurrent_insert=0
  999. fi
  1000. cechon "Current Lock Wait ratio = "
  1001. if [ $table_locks_waited -gt 0 ]; then
  1002. immediate_locks_miss_rate=$(($table_locks_immediate/$table_locks_waited))
  1003. cecho "1 : $immediate_locks_miss_rate" red
  1004. else
  1005. immediate_locks_miss_rate=99999 # perfect
  1006. cecho "0 : $questions"
  1007. fi
  1008. if [ $immediate_locks_miss_rate -lt 5000 ] ; then
  1009. cecho "You may benefit from selective use of InnoDB."
  1010. if [ "$low_priority_updates" = 'OFF' ] ; then
  1011. cecho "If you have long running SELECT's against MyISAM tables and perform"
  1012. cecho "frequent updates consider setting 'low_priority_updates=1'"
  1013. fi
  1014. if [ "$mysql_version_num" -gt 050000 ] && [ "$mysql_version_num" -lt 050500 ]; then
  1015. if [ $concurrent_insert -le 1 ] ; then
  1016. cecho "If you have a high concurrency of inserts on Dynamic row-length tables"
  1017. cecho "consider setting 'concurrent_insert=2'."
  1018. fi
  1019. elif [ "$mysql_version_num" -gt 050500 ] ; then
  1020. if [ "$concurrent_insert" = 'AUTO' ] || [ "$concurrent_insert" = 'NEVER' ] ; then
  1021. cecho "If you have a high concurrency of inserts on Dynamic row-length tables"
  1022. cecho "consider setting 'concurrent_insert=ALWAYS'."
  1023. fi
  1024. fi
  1025. else
  1026. cecho "Your table locking seems to be fine" green
  1027. fi
  1028. }
  1029. check_table_scans () {
  1030. ## -- Table Scans -- ##
  1031. cecho "TABLE SCANS" boldblue
  1032. mysql_status \'Com_select\' com_select
  1033. mysql_status \'Handler_read_rnd_next\' read_rnd_next
  1034. mysql_variable \'read_buffer_size\' read_buffer_size
  1035. if [ -z $read_buffer_size ] ; then
  1036. mysql_variable \'record_buffer\' read_buffer_size
  1037. fi
  1038. human_readable $read_buffer_size read_buffer_sizeHR
  1039. cecho "Current read_buffer_size = $read_buffer_sizeHR $unit"
  1040. if [ $com_select -gt 0 ] ; then
  1041. full_table_scans=$(($read_rnd_next/$com_select))
  1042. cecho "Current table scan ratio = $full_table_scans : 1"
  1043. if [ $full_table_scans -ge 4000 ] && [ $read_buffer_size -le 2097152 ] ; then
  1044. cecho "You have a high ratio of sequential access requests to SELECTs" red
  1045. cechon "You may benefit from raising " red
  1046. if [ "$major_version" = '3.23' ] ; then
  1047. cechon "record_buffer " red
  1048. else
  1049. cechon "read_buffer_size " red
  1050. fi
  1051. cecho "and/or improving your use of indexes." red
  1052. elif [ $read_buffer_size -gt 8388608 ] ; then
  1053. cechon "read_buffer_size is over 8 MB " red
  1054. cecho "there is probably no need for such a large read_buffer" red
  1055. else
  1056. cecho "read_buffer_size seems to be fine" green
  1057. fi
  1058. else
  1059. cecho "read_buffer_size seems to be fine" green
  1060. fi
  1061. }
  1062. check_innodb_status () {
  1063. ## -- InnoDB -- ##
  1064. ## See http://bugs.mysql.com/59393
  1065. if [ "$mysql_version_num" -lt 050603 ] ; then
  1066. mysql_variable \'have_innodb\' have_innodb
  1067. fi
  1068. if [ "$mysql_version_num" -lt 050500 ] && [ "$have_innodb" = "YES" ] ; then
  1069. innodb_enabled=1
  1070. fi
  1071. if [ "$mysql_version_num" -ge 050500 ] && [ "$mysql_version_num" -lt 050512 ] ; then
  1072. mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb
  1073. if [ "$ignore_builtin_innodb" = "ON" ] || [ $have_innodb = "NO" ] ; then
  1074. innodb_enabled=0
  1075. else
  1076. innodb_enabled=1
  1077. fi
  1078. elif [ "$major_version" = '5.5' ] && [ "$mysql_version_num" -ge 050512 ] ; then
  1079. mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb
  1080. if [ "$ignore_builtin_innodb" = "ON" ] ; then
  1081. innodb_enabled=0
  1082. else
  1083. innodb_enabled=1
  1084. fi
  1085. elif [ "$mysql_version_num" -ge 050600 ] && [ "$mysql_version_num" -lt 050603 ] ; then
  1086. mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb
  1087. if [ "$ignore_builtin_innodb" = "ON" ] || [ $have_innodb = "NO" ] ; then
  1088. innodb_enabled=0
  1089. else
  1090. innodb_enabled=1
  1091. fi
  1092. elif [ "$major_version" = '5.6' ] && [ "$mysql_version_num" -ge 050603 ] ; then
  1093. mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb
  1094. if [ "$ignore_builtin_innodb" = "ON" ] ; then
  1095. innodb_enabled=0
  1096. else
  1097. innodb_enabled=1
  1098. fi
  1099. fi
  1100. if [ "$innodb_enabled" = 1 ] ; then
  1101. mysql_variable \'innodb_buffer_pool_size\' innodb_buffer_pool_size
  1102. mysql_variable \'innodb_additional_mem_pool_size\' innodb_additional_mem_pool_size
  1103. mysql_variable \'innodb_fast_shutdown\' innodb_fast_shutdown
  1104. mysql_variable \'innodb_flush_log_at_trx_commit\' innodb_flush_log_at_trx_commit
  1105. mysql_variable \'innodb_locks_unsafe_for_binlog\' innodb_locks_unsafe_for_binlog
  1106. mysql_variable \'innodb_log_buffer_size\' innodb_log_buffer_size
  1107. mysql_variable \'innodb_log_file_size\' innodb_log_file_size
  1108. mysql_variable \'innodb_log_files_in_group\' innodb_log_files_in_group
  1109. mysql_variable \'innodb_safe_binlog\' innodb_safe_binlog
  1110. mysql_variable \'innodb_thread_concurrency\' innodb_thread_concurrency
  1111. cecho "INNODB STATUS" boldblue
  1112. innodb_indexes=$($mysql -Bse "/*!50000 SELECT IFNULL(SUM(INDEX_LENGTH),0) from information_schema.TABLES where ENGINE='InnoDB' */")
  1113. innodb_data=$($mysql -Bse "/*!50000 SELECT IFNULL(SUM(DATA_LENGTH),0) from information_schema.TABLES where ENGINE='InnoDB' */")
  1114. if [ ! -z "$innodb_indexes" ] ; then
  1115. mysql_status \'Innodb_buffer_pool_pages_data\' innodb_buffer_pool_pages_data
  1116. mysql_status \'Innodb_buffer_pool_pages_misc\' innodb_buffer_pool_pages_misc
  1117. mysql_status \'Innodb_buffer_pool_pages_free\' innodb_buffer_pool_pages_free
  1118. mysql_status \'Innodb_buffer_pool_pages_total\' innodb_buffer_pool_pages_total
  1119. mysql_status \'Innodb_buffer_pool_read_ahead_seq\' innodb_buffer_pool_read_ahead_seq
  1120. mysql_status \'Innodb_buffer_pool_read_requests\' innodb_buffer_pool_read_requests
  1121. mysql_status \'Innodb_os_log_pending_fsyncs\' innodb_os_log_pending_fsyncs
  1122. mysql_status \'Innodb_os_log_pending_writes\' innodb_os_log_pending_writes
  1123. mysql_status \'Innodb_log_waits\' innodb_log_waits
  1124. mysql_status \'Innodb_row_lock_time\' innodb_row_lock_time
  1125. mysql_status \'Innodb_row_lock_waits\' innodb_row_lock_waits
  1126. human_readable $innodb_indexes innodb_indexesHR
  1127. cecho "Current InnoDB index space = $innodb_indexesHR $unit"
  1128. human_readable $innodb_data innodb_dataHR
  1129. cecho "Current InnoDB data space = $innodb_dataHR $unit"
  1130. percent_innodb_buffer_pool_free=$(($innodb_buffer_pool_pages_free*100/$innodb_buffer_pool_pages_total))
  1131. cecho "Current InnoDB buffer pool free = "$percent_innodb_buffer_pool_free" %"
  1132. else
  1133. cecho "Cannot parse InnoDB stats prior to 5.0.x" red
  1134. $mysql -s -e "SHOW /*!50000 ENGINE */ INNODB STATUS\G"
  1135. fi
  1136. human_readable $innodb_buffer_pool_size innodb_buffer_pool_sizeHR
  1137. cecho "Current innodb_buffer_pool_size = $innodb_buffer_pool_sizeHR $unit"
  1138. cecho "Depending on how much space your innodb indexes take up it may be safe"
  1139. cecho "to increase this value to up to 2 / 3 of total system memory"
  1140. else
  1141. cecho "No InnoDB Support Enabled!" boldred
  1142. fi
  1143. }
  1144. total_memory_used () {
  1145. ## -- Total Memory Usage -- ##
  1146. cecho "MEMORY USAGE" boldblue
  1147. mysql_variable \'read_buffer_size\' read_buffer_size
  1148. mysql_variable \'read_rnd_buffer_size\' read_rnd_buffer_size
  1149. mysql_variable \'sort_buffer_size\' sort_buffer_size
  1150. mysql_variable \'thread_stack\' thread_stack
  1151. mysql_variable \'max_connections\' max_connections
  1152. mysql_variable \'join_buffer_size\' join_buffer_size
  1153. mysql_variable \'tmp_table_size\' tmp_table_size
  1154. mysql_variable \'max_heap_table_size\' max_heap_table_size
  1155. mysql_variable \'log_bin\' log_bin
  1156. mysql_status \'Max_used_connections\' max_used_connections
  1157. if [ "$major_version" = "3.23" ] ; then
  1158. mysql_variable \'record_buffer\' read_buffer_size
  1159. mysql_variable \'record_rnd_buffer\' read_rnd_buffer_size
  1160. mysql_variable \'sort_buffer\' sort_buffer_size
  1161. fi
  1162. if [ "$log_bin" = "ON" ] ; then
  1163. mysql_variable \'binlog_cache_size\' binlog_cache_size
  1164. else
  1165. binlog_cache_size=0
  1166. fi
  1167. if [ $max_heap_table_size -le $tmp_table_size ] ; then
  1168. effective_tmp_table_size=$max_heap_table_size
  1169. else
  1170. effective_tmp_table_size=$tmp_table_size
  1171. fi
  1172. per_thread_buffers=$(echo "($read_buffer_size+$read_rnd_buffer_size+$sort_buffer_size+$thread_stack+$join_buffer_size+$binlog_cache_size)*$max_connections" | bc -l)
  1173. per_thread_max_buffers=$(echo "($read_buffer_size+$read_rnd_buffer_size+$sort_buffer_size+$thread_stack+$join_buffer_size+$binlog_cache_size)*$max_used_connections" | bc -l)
  1174. mysql_variable \'innodb_buffer_pool_size\' innodb_buffer_pool_size
  1175. if [ -z $innodb_buffer_pool_size ] ; then
  1176. innodb_buffer_pool_size=0
  1177. fi
  1178. mysql_variable \'innodb_additional_mem_pool_size\' innodb_additional_mem_pool_size
  1179. if [ -z $innodb_additional_mem_pool_size ] ; then
  1180. innodb_additional_mem_pool_size=0
  1181. fi
  1182. mysql_variable \'innodb_log_buffer_size\' innodb_log_buffer_size
  1183. if [ -z $innodb_log_buffer_size ] ; then
  1184. innodb_log_buffer_size=0
  1185. fi
  1186. mysql_variable \'key_buffer_size\' key_buffer_size
  1187. mysql_variable \'query_cache_size\' query_cache_size
  1188. if [ -z $query_cache_size ] ; then
  1189. query_cache_size=0
  1190. fi
  1191. global_buffers=$(echo "$innodb_buffer_pool_size+$innodb_additional_mem_pool_size+$innodb_log_buffer_size+$key_buffer_size+$query_cache_size" | bc -l)
  1192. max_memory=$(echo "$global_buffers+$per_thread_max_buffers" | bc -l)
  1193. total_memory=$(echo "$global_buffers+$per_thread_buffers" | bc -l)
  1194. pct_of_sys_mem=$(echo "scale=0; $total_memory*100/$physical_memory" | bc -l)
  1195. if [ $pct_of_sys_mem -gt 90 ] ; then
  1196. txt_color=boldred
  1197. error=1
  1198. else
  1199. txt_color=
  1200. error=0
  1201. fi
  1202. human_readable $max_memory max_memoryHR
  1203. cecho "Max Memory Ever Allocated : $max_memoryHR $unit" $txt_color
  1204. human_readable $per_thread_buffers per_thread_buffersHR
  1205. cecho "Configured Max Per-thread Buffers : $per_thread_buffersHR $unit" $txt_color
  1206. human_readable $global_buffers global_buffersHR
  1207. cecho "Configured Max Global Buffers : $global_buffersHR $unit" $txt_color
  1208. human_readable $total_memory total_memoryHR
  1209. cecho "Configured Max Memory Limit : $total_memoryHR $unit" $txt_color
  1210. # human_readable $effective_tmp_table_size effective_tmp_table_sizeHR
  1211. # cecho "Plus $effective_tmp_table_sizeHR $unit per temporary table created"
  1212. human_readable $physical_memory physical_memoryHR
  1213. cecho "Physical Memory : $physical_memoryHR $unit" $txt_color
  1214. if [ $error -eq 1 ] ; then
  1215. printf "\n"
  1216. cecho "Max memory limit exceeds 90% of physical memory" $txt_color
  1217. else
  1218. cecho "Max memory limit seem to be within acceptable norms" green
  1219. fi
  1220. unset txt_color
  1221. }
  1222. ## Required Functions ##
  1223. login_validation () {
  1224. check_for_socket # determine the socket location -- 1st login
  1225. check_for_plesk_passwords # determine the login method -- 2nd login
  1226. check_mysql_login # determine if mysql is accepting login -- 3rd login
  1227. export major_version=$($mysql -Bse "SELECT SUBSTRING_INDEX(VERSION(), '.', +2)")
  1228. # export mysql_version_num=$($mysql -Bse "SELECT LEFT(REPLACE(SUBSTRING_INDEX(VERSION(), '-', +1), '.', ''),4)" )
  1229. export mysql_version_num=$($mysql -Bse "SELECT VERSION()" |
  1230. awk -F \. '{ printf "%02d", $1; printf "%02d", $2; printf "%02d", $3 }')
  1231. }
  1232. shared_info () {
  1233. export major_version=$($mysql -Bse "SELECT SUBSTRING_INDEX(VERSION(), '.', +2)")
  1234. # export mysql_version_num=$($mysql -Bse "SELECT LEFT(REPLACE(SUBSTRING_INDEX(VERSION(), '-', +1), '.', ''),4)" )
  1235. export mysql_version_num=$($mysql -Bse "SELECT VERSION()" |
  1236. awk -F \. '{ printf "%02d", $1; printf "%02d", $2; printf "%02d", $3 }')
  1237. mysql_status \'Questions\' questions
  1238. # socket_owner=$(find -L $socket -printf '%u\n')
  1239. socket_owner=$(ls -nH $socket | awk '{ print $3 }')
  1240. }
  1241. get_system_info () {
  1242. export OS=$(uname)
  1243. # Get information for various UNIXes
  1244. if [ "$OS" = 'Darwin' ]; then
  1245. ps_socket=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }' | head -1)
  1246. found_socks=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }')
  1247. export physical_memory=$(sysctl -n hw.memsize)
  1248. export duflags=''
  1249. elif [ "$OS" = 'FreeBSD' ] || [ "$OS" = 'OpenBSD' ]; then
  1250. ## On FreeBSD must be root to locate sockets.
  1251. ps_socket=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }' | head -1)
  1252. found_socks=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }')
  1253. export physical_memory=$(sysctl -n hw.realmem)
  1254. export duflags=''
  1255. elif [ "$OS" = 'Linux' ] ; then
  1256. ## Includes SWAP
  1257. ## export physical_memory=$(free -b | grep -v buffers | awk '{ s += $2 } END { printf("%.0f\n", s ) }')
  1258. ps_socket=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }' | head -1)
  1259. found_socks=$(netstat -ln | awk '/mysql(.*)?\.sock/ { print $9 }')
  1260. export physical_memory=$(awk '/^MemTotal/ { printf("%.0f", $2*1024 ) }' < /proc/meminfo)
  1261. export duflags='-b'
  1262. elif [ "$OS" = 'SunOS' ] ; then
  1263. ps_socket=$(netstat -an | awk '/mysql(.*)?.sock/ { print $5 }' | head -1)
  1264. found_socks=$(netstat -an | awk '/mysql(.*)?.sock/ { print $5 }')
  1265. export physical_memory=$(prtconf | awk '/^Memory\ size:/ { print $3*1048576 }')
  1266. fi
  1267. if [ -z $(which bc) ] ; then
  1268. echo "Error: Command line calculator 'bc' not found!"
  1269. exit
  1270. fi
  1271. }
  1272. ## Optional Components Groups ##
  1273. banner_info () {
  1274. shared_info
  1275. print_banner ; echo
  1276. check_mysql_version ; echo
  1277. post_uptime_warning ; echo
  1278. }
  1279. misc () {
  1280. shared_info
  1281. check_slow_queries ; echo
  1282. check_binary_log ; echo
  1283. check_threads ; echo
  1284. check_used_connections ; echo
  1285. check_innodb_status ; echo
  1286. }
  1287. memory () {
  1288. shared_info
  1289. total_memory_used ; echo
  1290. check_key_buffer_size ; echo
  1291. check_query_cache ; echo
  1292. check_sort_operations ; echo
  1293. check_join_operations ; echo
  1294. }
  1295. file () {
  1296. shared_info
  1297. check_open_files ; echo
  1298. check_table_cache ; echo
  1299. check_tmp_tables ; echo
  1300. check_table_scans ; echo
  1301. check_table_locking ; echo
  1302. }
  1303. all () {
  1304. banner_info
  1305. misc
  1306. memory
  1307. file
  1308. }
  1309. prompt () {
  1310. prompted='true'
  1311. read -p "Username [anonymous] : " user
  1312. read -rp "Password [<none>] : " pass
  1313. cecho " "
  1314. read -p "Socket [ /var/lib/mysql/mysql.sock ] : " socket
  1315. if [ -z $socket ] ; then
  1316. export socket='/var/lib/mysql/mysql.sock'
  1317. fi
  1318. if [ -z $pass ] ; then
  1319. export mysql="mysql -S $socket -u$user"
  1320. export mysqladmin="mysqladmin -S $socket -u$user"
  1321. else
  1322. export mysql="mysql -S $socket -u$user -p$pass"
  1323. export mysqladmin="mysqladmin -S $socket -u$user -p$pass"
  1324. fi
  1325. check_for_socket
  1326. check_mysql_login
  1327. if [ $? = 1 ] ; then
  1328. exit 1
  1329. fi
  1330. read -p "Mode to test - banner, file, misc, mem, innodb, [all] : " REPLY
  1331. if [ -z $REPLY ] ; then
  1332. REPLY='all'
  1333. fi
  1334. case $REPLY in
  1335. banner | BANNER | header | HEADER | head | HEAD)
  1336. banner_info
  1337. ;;
  1338. misc | MISC | miscelaneous )
  1339. misc
  1340. ;;
  1341. mem | memory | MEM | MEMORY )
  1342. memory
  1343. ;;
  1344. file | FILE | disk | DISK )
  1345. file
  1346. ;;
  1347. innodb | INNODB )
  1348. innodb
  1349. ;;
  1350. all | ALL )
  1351. cecho " "
  1352. all
  1353. ;;
  1354. * )
  1355. cecho "Invalid Mode! Valid options are 'banner', 'misc', 'memory', 'file', 'innodb' or 'all'" boldred
  1356. exit 1
  1357. ;;
  1358. esac
  1359. }
  1360. ## Address environmental differences ##
  1361. get_system_info
  1362. # echo $ps_socket
  1363. if [ -z "$1" ] ; then
  1364. login_validation
  1365. mode='ALL'
  1366. elif [ "$1" = "prompt" ] || [ "$1" = "PROMPT" ] ; then
  1367. mode=$1
  1368. elif [ "$1" != "prompt" ] || [ "$1" != "PROMPT" ] ; then
  1369. login_validation
  1370. mode=$1
  1371. fi
  1372. case $mode in
  1373. all | ALL )
  1374. cecho " "
  1375. all
  1376. ;;
  1377. mem | memory | MEM | MEMORY )
  1378. cecho " "
  1379. memory
  1380. ;;
  1381. file | FILE | disk | DISK )
  1382. cecho " "
  1383. file
  1384. ;;
  1385. banner | BANNER | header | HEADER | head | HEAD )
  1386. banner_info
  1387. ;;
  1388. misc | MISC | miscelaneous )
  1389. cecho " "
  1390. misc
  1391. ;;
  1392. innodb | INNODB )
  1393. banner_info
  1394. check_innodb_status ; echo
  1395. ;;
  1396. prompt | PROMPT )
  1397. prompt
  1398. ;;
  1399. *)
  1400. cecho "usage: $0 [ all | banner | file | innodb | memory | misc | prompt ]" boldred
  1401. exit 1
  1402. ;;
  1403. esac