├── LICENSE ├── README.md └── tuning-primer.sh /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | MySQL Tuning Primer 2 | =================== 3 | 4 | Modernized [MySQL performance tuning primer script](https://github.com/RootService/tuning-primer) for MySQL >= 5.5 <= 5.7 5 | 6 | 7 | Based on the [MySQL performance tuning primer script](https://launchpad.net/mysql-tuning-primer) version 1.6-r1 released on 2011-08-06 by Matthew Montgomery and licenced under the GPLv2. 8 | 9 | 10 | 11 | 12 | MySQLTuner.pl 13 | ------------- 14 | 15 | For a much better solution have a look at the 16 | [MySQL Tuner Perl Script](https://github.com/major/MySQLTuner-perl) 17 | -------------------------------------------------------------------------------- /tuning-primer.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 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 | # # 16 | # MySQL performance tuning primer script # 17 | # Rewritten by: Markus Kohlmeyer # 18 | # Download: https://github.com/RootService/tuning-primer # 19 | # Report bugs to: https://github.com/RootService/tuning-primer/issues # 20 | # Changelog: https://github.com/RootService/tuning-primer/commits # 21 | # Version: 2.0.1-r1 Released: 2017-06-07 # 22 | # Licenced under GPLv2 # 23 | # https://github.com/RootService/tuning-primer/blob/master/LICENSE # 24 | # # 25 | ################################################################################ 26 | 27 | ################################################################################ 28 | # # 29 | # Usage: ./tuning-primer.sh [ mode ] # 30 | # # 31 | # Available Modes: # 32 | # all : perform all checks (default) # 33 | # prompt : prompt for login credintials and socket # 34 | # and execution mode # 35 | # mem, memory : run checks for tunable options which # 36 | # effect memory usage # 37 | # disk, file : run checks for options which effect # 38 | # i/o performance or file handle limits # 39 | # innodb : run InnoDB checks /* to be improved */ # 40 | # misc : run checks for that don't categorise # 41 | # well Slow Queries, Binary logs, # 42 | # Used Connections and Worker Threads # 43 | # # 44 | ################################################################################ 45 | # # 46 | # Set this socket variable ONLY if you have multiple instances running # 47 | # or we are unable to find your socket, and you don't want to to be # 48 | # prompted for input each time you run this script. # 49 | # # 50 | ################################################################################ 51 | socket= 52 | 53 | 54 | export black='\033[0m' 55 | export boldblack='\033[1;0m' 56 | export red='\033[31m' 57 | export boldred='\033[1;31m' 58 | export green='\033[32m' 59 | export boldgreen='\033[1;32m' 60 | export yellow='\033[33m' 61 | export boldyellow='\033[1;33m' 62 | export blue='\033[34m' 63 | export boldblue='\033[1;34m' 64 | export magenta='\033[35m' 65 | export boldmagenta='\033[1;35m' 66 | export cyan='\033[36m' 67 | export boldcyan='\033[1;36m' 68 | export white='\033[37m' 69 | export boldwhite='\033[1;37m' 70 | 71 | 72 | for bin in awk bc du find grep head ls mysql mysqladmin netstat sleep sysctl tput uname ; do 73 | which "$bin" > /dev/null 74 | if [ "$?" = "0" ] ; then 75 | bin_path="$(which $bin)" 76 | export bin_$bin="$bin_path" 77 | else 78 | echo "Error: Needed command \"$bin\" not found in PATH!" 79 | exit 1 80 | fi 81 | done 82 | 83 | 84 | cecho () 85 | ## -- Function to easliy print colored text -- ## 86 | { 87 | local var1="$1" # message 88 | local var2="$2" # color 89 | 90 | local default_msg="No message passed." 91 | 92 | message="${var1:-$default_msg}" 93 | color="${var2:-black}" 94 | 95 | case "$color" in 96 | black) 97 | printf "$black" ;; 98 | boldblack) 99 | printf "$boldblack" ;; 100 | red) 101 | printf "$red" ;; 102 | boldred) 103 | printf "$boldred" ;; 104 | green) 105 | printf "$green" ;; 106 | boldgreen) 107 | printf "$boldgreen" ;; 108 | yellow) 109 | printf "$yellow" ;; 110 | boldyellow) 111 | printf "$boldyellow" ;; 112 | blue) 113 | printf "$blue" ;; 114 | boldblue) 115 | printf "$boldblue" ;; 116 | magenta) 117 | printf "$magenta" ;; 118 | boldmagenta) 119 | printf "$boldmagenta" ;; 120 | cyan) 121 | printf "$cyan" ;; 122 | boldcyan) 123 | printf "$boldcyan" ;; 124 | white) 125 | printf "$white" ;; 126 | boldwhite) 127 | printf "$boldwhite" ;; 128 | esac 129 | 130 | printf "%s\n" "$message" 131 | $bin_tput sgr0 132 | printf "$black" 133 | 134 | return 135 | } 136 | 137 | 138 | cechon () 139 | ## -- Function to easliy print colored text -- ## 140 | { 141 | local var1="$1" # message 142 | local var2="$2" # color 143 | 144 | local default_msg="No message passed." 145 | 146 | message="${var1:-$default_msg}" 147 | color="${var2:-black}" 148 | 149 | case "$color" in 150 | black) 151 | printf "$black" ;; 152 | boldblack) 153 | printf "$boldblack" ;; 154 | red) 155 | printf "$red" ;; 156 | boldred) 157 | printf "$boldred" ;; 158 | green) 159 | printf "$green" ;; 160 | boldgreen) 161 | printf "$boldgreen" ;; 162 | yellow) 163 | printf "$yellow" ;; 164 | boldyellow) 165 | printf "$boldyellow" ;; 166 | blue) 167 | printf "$blue" ;; 168 | boldblue) 169 | printf "$boldblue" ;; 170 | magenta) 171 | printf "$magenta" ;; 172 | boldmagenta) 173 | printf "$boldmagenta" ;; 174 | cyan) 175 | printf "$cyan" ;; 176 | boldcyan) 177 | printf "$boldcyan" ;; 178 | white) 179 | printf "$white" ;; 180 | boldwhite) 181 | printf "$boldwhite" ;; 182 | esac 183 | 184 | printf "%s" "$message" 185 | $bin_tput sgr0 186 | printf "$black" 187 | 188 | return 189 | } 190 | 191 | 192 | print_banner () 193 | ## -- Banner -- ## 194 | { 195 | cecho " -- MYSQL PERFORMANCE TUNING PRIMER 2.0.1-r1 --" boldblue 196 | cecho " - By: Matthew Montgomery -" black 197 | cecho " - By: Markus Kohlmeyer -" black 198 | } 199 | 200 | 201 | check_for_socket () 202 | ## -- Find the location of the mysql.sock file -- ## 203 | { 204 | if [ -z "$socket" ] ; then 205 | cnf_socket="$($bin_mysql --print-defaults | $bin_grep -o "socket=[^[:space:]]*" | $bin_awk -F \= '{ print $2 }')" 206 | if [ -S "$cnf_socket" ] ; then 207 | socket="$cnf_socket" 208 | elif [ -S "/var/lib/mysql/mysql.sock" ] ; then 209 | socket="/var/lib/mysql/mysql.sock" 210 | elif [ -S "/var/run/mysqld/mysqld.sock" ] ; then 211 | socket="/var/run/mysqld/mysqld.sock" 212 | elif [ -S "/tmp/mysql.sock" ] ; then 213 | socket="/tmp/mysql.sock" 214 | else 215 | if [ -S "$ps_socket" ] ; then 216 | socket="$ps_socket" 217 | fi 218 | fi 219 | fi 220 | 221 | if [ -S "$socket" ] ; then 222 | echo "UP" > /dev/null 223 | cmd_mysql="$bin_mysql -S$socket" 224 | cmd_mysqladmin="$bin_mysqladmin -S$socket" 225 | else 226 | cecho "No valid socket file \"$socket\" found!" boldred 227 | cecho "The mysqld process is not running or it is installed in a custom location." red 228 | cecho "If you are sure mysqld is running, execute script in \"prompt\" mode or set " red 229 | cecho "the socket= variable at the top of this script" red 230 | exit 1 231 | fi 232 | } 233 | 234 | 235 | check_mysql_login () 236 | ## -- Test for running mysql -- ## 237 | { 238 | is_up="$($cmd_mysqladmin ping 2>&1)" 239 | if [ "$is_up" = "mysqld is alive" ] ; then 240 | echo "UP" > /dev/null 241 | elif [ "$is_up" != "mysqld is alive" ] ; then 242 | cecho " " 243 | cecho "Using login values from ~/.my.cnf" 244 | cecho "- INITIAL LOGIN ATTEMPT FAILED -" boldred 245 | if [ -z "$prompted" ] ; then 246 | second_login_failed 247 | else 248 | return 1 249 | fi 250 | else 251 | cecho "Unknow exit status" red 252 | exit 1 253 | fi 254 | } 255 | 256 | 257 | final_login_attempt () 258 | ## -- -- ## 259 | { 260 | is_up="$($cmd_mysqladmin ping 2>&1)" 261 | if [ "$is_up" = "mysqld is alive" ] ; then 262 | echo "UP" > /dev/null 263 | elif [ "$is_up" != "mysqld is alive" ] ; then 264 | cecho "- FINAL LOGIN ATTEMPT FAILED -" boldred 265 | cecho "Unable to log into socket: $socket" boldred 266 | exit 1 267 | fi 268 | } 269 | 270 | 271 | second_login_failed () 272 | ## -- create a ~/.my.cnf and exit when all else fails -- ## 273 | { 274 | cecho "Could not auto detect login info!" 275 | cecho "Found potential sockets: $found_socks" 276 | cecho "Using: $socket" red 277 | 278 | read -p "Would you like to provide a different socket? [y/N] : " REPLY 279 | case "$REPLY" in 280 | yes | y | Y | YES) 281 | read -p "Socket: " socket 282 | ;; 283 | esac 284 | 285 | read -p "Do you have your login handy? [y/N] : " REPLY 286 | case "$REPLY" in 287 | yes | y | Y | YES) 288 | answer1="yes" 289 | read -p "User: " user 290 | read -rp "Password: " pass 291 | if [ -z "$pass" ] ; then 292 | export cmd_mysql="$bin_mysql -S$socket -u$user" 293 | export cmd_mysqladmin="$bin_mysqladmin -S$socket -u$user" 294 | else 295 | export cmd_mysql="$bin_mysql -S$socket -u$user -p$pass" 296 | export cmd_mysqladmin="$bin_mysqladmin -S$socket -u$user -p$pass" 297 | fi 298 | ;; 299 | *) 300 | cecho "Please create a valid login to MySQL" 301 | cecho "Or, set correct values for 'user=' and 'password=' in ~/.my.cnf" 302 | ;; 303 | esac 304 | cecho " " 305 | 306 | read -p "Would you like me to create a ~/.my.cnf file for you? [y/N] : " REPLY 307 | case "$REPLY" in 308 | yes | y | Y | YES) 309 | answer2="yes" 310 | if [ ! -f "~/.my.cnf" ] ; then 311 | umask 077 312 | printf "[client]\nuser=$user\npassword=$pass\nsocket=$socket" > ~/.my.cnf 313 | if [ "$answer1" != "yes" ] ; then 314 | exit 1 315 | else 316 | final_login_attempt 317 | return 0 318 | fi 319 | else 320 | cecho " " 321 | cecho "~/.my.cnf already exists!" boldred 322 | cecho " " 323 | read -p "Replace? [y/N] : " REPLY 324 | if [ "$REPLY" = "y" ] || [ "$REPLY" = "Y" ] ; then 325 | printf "[client]\nuser=$user\npassword=$pass\socket=$socket" > ~/.my.cnf 326 | if [ "$answer1" != "yes" ] ; then 327 | exit 1 328 | else 329 | final_login_attempt 330 | return 0 331 | fi 332 | else 333 | cecho "Please set the 'user=' and 'password=' and 'socket=' values in ~/.my.cnf" 334 | exit 1 335 | fi 336 | fi 337 | ;; 338 | *) 339 | if [ "$answer1" != "yes" ] ; then 340 | exit 1 341 | else 342 | final_login_attempt 343 | return 0 344 | fi 345 | ;; 346 | esac 347 | } 348 | 349 | 350 | mysql_status () 351 | ## -- Function to pull MySQL status variable -- ## 352 | { 353 | local var1="$1" 354 | local var2="$2" 355 | 356 | local status="$($cmd_mysql -Bse "SHOW /*!50000 GLOBAL */ STATUS LIKE $var1" | $bin_awk '{ print $2 }')" 357 | 358 | export "$var2"="$status" 359 | } 360 | 361 | 362 | mysql_variable () 363 | ## -- Function to pull MySQL server runtime variable -- ## 364 | { 365 | local var1="$1" 366 | local var2="$2" 367 | 368 | local variable="$($cmd_mysql -Bse "SHOW /*!50000 GLOBAL */ VARIABLES LIKE $var1" | $bin_awk '{ print $2 }')" 369 | 370 | export "$var2"="$variable" 371 | } 372 | 373 | 374 | mysql_variableTSV () 375 | ## -- Function to pull MySQL server runtime variable -- ## 376 | { 377 | local var1="$1" 378 | local var2="$2" 379 | 380 | local variable="$($cmd_mysql -Bse "SHOW /*!50000 GLOBAL */ VARIABLES LIKE $var1" | $bin_awk -F \t '{ print $2 }')" 381 | 382 | export "$var2"="$variable" 383 | } 384 | 385 | 386 | float2int () 387 | ## -- Convert floating point to integer -- ## 388 | { 389 | local var1="$1" 390 | local var2="$2" 391 | 392 | local variable="$(echo "scale=0 ; $var1 / 1" | $bin_bc -l)" 393 | 394 | export "$var2"="$variable" 395 | } 396 | 397 | 398 | divide () 399 | ## -- Divide two intigers -- ## 400 | { 401 | local var1="$1" 402 | local var2="$2" 403 | local var3="$3" 404 | local var4="$4" 405 | 406 | usage="$0 dividend divisor '$variable' scale" 407 | 408 | if [ $((var1 >= 1)) -ne 0 ] ; then 409 | dividend="$var1" 410 | else 411 | cecho "Invalid Dividend" red 412 | cecho "$usage" 413 | exit 1 414 | fi 415 | 416 | if [ $((var2 >= 1)) -ne 0 ] ; then 417 | divisor="$var2" 418 | else 419 | cecho "Invalid Divisor" red 420 | cecho "$usage" 421 | exit 1 422 | fi 423 | 424 | if [ ! -n "$var3" ] ; then 425 | cecho "Invalid variable name" red 426 | cecho "$usage" 427 | exit 1 428 | fi 429 | 430 | if [ -z "$var4" ] ; then 431 | scale="2" 432 | elif [ $((var4 >= 0)) -ne 0 ] ; then 433 | scale="$var4" 434 | else 435 | cecho "Invalid scale" red 436 | cecho "$usage" 437 | exit 1 438 | fi 439 | 440 | export "$var3"="$(echo "scale=$scale ; $dividend / $divisor" | $bin_bc -l)" 441 | } 442 | 443 | 444 | human_readable () 445 | ## -- Make sizes human readable -- ## 446 | { 447 | local var1="$1" 448 | local var2="$2" 449 | local var3="$3" 450 | 451 | scale="$var3" 452 | 453 | if [ $((var1 >= 1073741824)) -ne 0 ] ; then 454 | if [ -z "$var3" ] ; then 455 | scale="2" 456 | fi 457 | divide "$var1" "1073741824" "$var2" "$scale" 458 | unit="G" 459 | elif [ $((var1 >= 1048576)) -ne 0 ] ; then 460 | if [ -z "$var3" ] ; then 461 | scale="0" 462 | fi 463 | divide "$var1" "1048576" "$var2" "$scale" 464 | unit="M" 465 | elif [ $((var1 >= 1024)) -ne 0 ] ; then 466 | if [ -z "$var3" ] ; then 467 | scale="0" 468 | fi 469 | divide "$var1" "1024" "$var2" "$scale" 470 | unit="K" 471 | else 472 | export "$var2"="$var1" 473 | unit="bytes" 474 | fi 475 | } 476 | 477 | 478 | human_readable_time () 479 | ## -- Make times human readable -- ## 480 | { 481 | local var1="$1" 482 | local var2="$2" 483 | 484 | usage="$0 seconds 'variable'" 485 | 486 | if [ -z "$var1" ] || [ -z "$var2" ] ; then 487 | cecho "$usage" red 488 | exit 1 489 | fi 490 | 491 | days="$(echo "scale=0 ; $var1 / 86400" | $bin_bc -l)" 492 | remainder="$(echo "scale=0 ; $var1 % 86400" | $bin_bc -l)" 493 | hours="$(echo "scale=0 ; $remainder / 3600" | $bin_bc -l)" 494 | remainder="$(echo "scale=0 ; $remainder % 3600" | $bin_bc -l)" 495 | minutes="$(echo "scale=0 ; $remainder / 60" | $bin_bc -l)" 496 | seconds="$(echo "scale=0 ; $remainder % 60" | $bin_bc -l)" 497 | 498 | export "$var2"="$days days $hours hrs $minutes min $seconds sec" 499 | } 500 | 501 | 502 | check_mysql_version () 503 | ## -- Print Version Info -- ## 504 | { 505 | mysql_variable \'version\' mysql_version 506 | mysql_variable \'version_compile_machine\' mysql_version_compile_machine 507 | 508 | cecho "MySQL Version $mysql_version $mysql_version_compile_machine" 509 | } 510 | 511 | 512 | post_uptime_warning () 513 | ## -- Warn if uptime not long enough -- ## 514 | { 515 | mysql_status \'Uptime\' uptime 516 | mysql_status \'Threads_connected\' threads 517 | 518 | queries_per_sec="$((questions / $uptime))" 519 | human_readable_time "$uptime" uptimeHR 520 | 521 | cecho "Uptime = $uptimeHR" 522 | cecho "Avg. qps = $queries_per_sec" 523 | cecho "Total Questions = $questions" 524 | cecho "Threads Connected = $threads" 525 | cecho " " 526 | 527 | if [ $((uptime > 172800)) -ne 0 ] ; then 528 | cecho "Server has been running for over 48hrs." 529 | cecho "It should be safe to follow these recommendations" 530 | else 531 | cechon "Warning: " boldred 532 | cecho "Server has not been running for at least 48hrs." boldred 533 | cecho "It may not be safe to use these recommendations" boldred 534 | 535 | fi 536 | cecho " " 537 | cecho "To find out more information on how each of these" red 538 | cecho "runtime variables effects performance visit:" red 539 | cecho "http://dev.mysql.com/doc/refman/$major_version/en/server-system-variables.html" boldblue 540 | cecho "Visit http://www.mysql.com/products/enterprise/advisors.html" boldblue 541 | cecho "for info about MySQL's Enterprise Monitoring and Advisory Service" boldblue 542 | } 543 | 544 | 545 | check_slow_queries () 546 | ## -- Slow Queries -- ## 547 | { 548 | cecho "SLOW QUERIES" boldblue 549 | 550 | mysql_status \'Slow_queries\' slow_queries 551 | mysql_variable \'long_query_time\' long_query_time 552 | mysql_variable \'slow_query_log\' log_slow_queries 553 | 554 | prefered_query_time="5" 555 | 556 | if [ "$log_slow_queries" = "ON" ] ; then 557 | cecho "The slow query log is enabled." 558 | elif [ "$log_slow_queries" = "OFF" ] ; then 559 | cechon "The slow query log is " 560 | cechon "NOT" boldred 561 | cecho " enabled." 562 | elif [ -z "$log_slow_queries" ] ; then 563 | cechon "The slow query log is " 564 | cechon "NOT" boldred 565 | cecho " enabled." 566 | else 567 | cecho "Error: $log_slow_queries" boldred 568 | fi 569 | cecho "Current long_query_time = $long_query_time sec." 570 | cechon "You have " 571 | cechon "$slow_queries" boldred 572 | cechon " out of " 573 | cechon "$questions" boldred 574 | cecho " that take longer than $long_query_time sec. to complete" 575 | 576 | float2int "$long_query_time" long_query_timeInt 577 | 578 | if [ $((long_query_timeInt > $prefered_query_time)) -ne 0 ] ; then 579 | cecho "Your long_query_time may be too high, I typically set this under $prefered_query_time sec." red 580 | else 581 | cecho "Your long_query_time seems to be fine" green 582 | fi 583 | } 584 | 585 | 586 | check_binary_log () 587 | ## -- Binary Log -- ## 588 | { 589 | cecho "BINARY UPDATE LOG" boldblue 590 | 591 | mysql_variable \'log_bin\' log_bin 592 | mysql_variable \'max_binlog_size\' max_binlog_size 593 | mysql_variable \'max_binlog_cache_size\' max_binlog_cache_size 594 | mysql_variable \'expire_logs_days\' expire_logs_days 595 | mysql_variable \'sync_binlog\' sync_binlog 596 | 597 | if [ "$log_bin" = "ON" ] ; then 598 | cecho "The binary update log is enabled" 599 | if [ -z "$max_binlog_size" ] ; then 600 | cecho "The max_binlog_size is not set. The binary log will rotate when it reaches 1GB." red 601 | fi 602 | if [ $((expire_logs_days == 0)) -ne 0 ] ; then 603 | cecho "The expire_logs_days is not set." boldred 604 | cechon "The mysqld will retain the entire binary log until " red 605 | cecho "RESET MASTER or PURGE MASTER LOGS commands are run manually" red 606 | cecho "Setting expire_logs_days will allow you to remove old binary logs automatically" yellow 607 | cecho "See http://dev.mysql.com/doc/refman/$major_version/en/purge-master-logs.html" yellow 608 | fi 609 | if [ $((sync_binlog == 0)) -ne 0 ] ; then 610 | cecho "Binlog sync is not enabled, you could loose binlog records during a server crash" red 611 | fi 612 | else 613 | cechon "The binary update log is " 614 | cechon "NOT " boldred 615 | cecho "enabled." 616 | cecho "You will not be able to do point in time recovery" red 617 | cecho "See http://dev.mysql.com/doc/refman/$major_version/en/point-in-time-recovery.html" yellow 618 | fi 619 | } 620 | 621 | 622 | check_used_connections () 623 | ## -- Used Connections -- ## 624 | { 625 | mysql_status \'Max_used_connections\' max_used_connections 626 | mysql_status \'Threads_connected\' threads_connected 627 | mysql_variable \'max_connections\' max_connections 628 | 629 | connections_ratio="$((max_used_connections * 100 / $max_connections))" 630 | 631 | cecho "MAX CONNECTIONS" boldblue 632 | cecho "Current max_connections = $max_connections" 633 | cecho "Current threads_connected = $threads_connected" 634 | cecho "Historic max_used_connections = $max_used_connections" 635 | cechon "The number of used connections is " 636 | if [ $((connections_ratio >= 85)) -ne 0 ] ; then 637 | txt_color="red" 638 | error="1" 639 | elif [ $((connections_ratio <= 10)) -ne 0 ] ; then 640 | txt_color="red" 641 | error="2" 642 | else 643 | txt_color="green" 644 | error="0" 645 | fi 646 | cechon "$connections_ratio% " $txt_color 647 | cecho "of the configured maximum." 648 | 649 | if [ $((error == 1)) -ne 0 ] ; then 650 | cecho "You should raise max_connections" $txt_color 651 | elif [ $((error == 2)) -ne 0 ] ; then 652 | cecho "You are using less than 10% of your configured max_connections." $txt_color 653 | cecho "Lowering max_connections could help to avoid an over-allocation of memory" $txt_color 654 | cecho "See \"MEMORY USAGE\" section to make sure you are not over-allocating" $txt_color 655 | else 656 | cecho "Your max_connections variable seems to be fine." $txt_color 657 | fi 658 | unset txt_color 659 | } 660 | 661 | 662 | check_threads () 663 | ## -- Worker Threads -- ## 664 | { 665 | cecho "WORKER THREADS" boldblue 666 | 667 | mysql_status \'Threads_created\' threads_created1 668 | $bin_sleep 1 669 | mysql_status \'Threads_created\' threads_created2 670 | 671 | mysql_status \'Threads_cached\' threads_cached 672 | mysql_status \'Uptime\' uptime 673 | mysql_variable \'thread_cache_size\' thread_cache_size 674 | 675 | historic_threads_per_sec="$((threads_created1 / $uptime))" 676 | current_threads_per_sec="$((threads_created2 - $threads_created1))" 677 | 678 | cecho "Current thread_cache_size = $thread_cache_size" 679 | cecho "Current threads_cached = $threads_cached" 680 | cecho "Current threads_per_sec = $current_threads_per_sec" 681 | cecho "Historic threads_per_sec = $historic_threads_per_sec" 682 | 683 | if [ $((historic_threads_per_sec >= 2)) -ne 0 ] && [ $((threads_cached <= 1)) -ne 0 ] ; then 684 | cecho "Threads created per/sec are overrunning threads cached" red 685 | cecho "You should raise thread_cache_size" red 686 | elif [ $((current_threads_per_sec >= 2)) -ne 0 ] ; then 687 | cecho "Threads created per/sec are overrunning threads cached" red 688 | cecho "You should raise thread_cache_size" red 689 | else 690 | cecho "Your thread_cache_size is fine" green 691 | fi 692 | } 693 | 694 | 695 | check_key_buffer_size () 696 | ## -- Key buffer Size -- ## 697 | { 698 | cecho "KEY BUFFER" boldblue 699 | 700 | mysql_status \'Key_read_requests\' key_read_requests 701 | mysql_status \'Key_reads\' key_reads 702 | mysql_status \'Key_blocks_used\' key_blocks_used 703 | mysql_status \'Key_blocks_unused\' key_blocks_unused 704 | mysql_variable \'key_cache_block_size\' key_cache_block_size 705 | mysql_variable \'key_buffer_size\' key_buffer_size 706 | mysql_variable \'datadir\' datadir 707 | mysql_variable \'version_compile_machine\' mysql_version_compile_machine 708 | 709 | myisam_indexes="$($cmd_mysql -Bse "/*!50000 SELECT IFNULL(SUM(INDEX_LENGTH),0) FROM information_schema.tables WHERE ENGINE='MyISAM' */")" 710 | 711 | if [ -z "$myisam_indexes" ] ; then 712 | myisam_indexes="$($bin_find $datadir -iname '*.MYI' -exec $bin_du $duflags '{}' \; 2>&1 | $bin_awk '{ s += $1 } END { printf("%.0f\n", s) }')" 713 | fi 714 | 715 | if [ $((key_reads == 0)) -ne 0 ] ; then 716 | cecho "No key reads?!" boldred 717 | cecho "Seriously look into using some indexes" red 718 | key_cache_miss_rate="0" 719 | key_buffer_free="$(echo "$key_blocks_unused * $key_cache_block_size / $key_buffer_size * 100" | $bin_bc -l)" 720 | key_buffer_freeRND="$(echo "scale=0 ; $key_buffer_free / 1" | $bin_bc -l)" 721 | else 722 | key_cache_miss_rate="$((key_read_requests / $key_reads))" 723 | if [ ! -z "$key_blocks_unused" ] ; then 724 | key_buffer_free="$(echo "$key_blocks_unused * $key_cache_block_size / $key_buffer_size * 100" | $bin_bc -l)" 725 | key_buffer_freeRND="$(echo "scale=0 ; $key_buffer_free / 1" | $bin_bc -l)" 726 | else 727 | key_buffer_free="Unknown" 728 | key_buffer_freeRND="75" 729 | fi 730 | fi 731 | 732 | human_readable "$myisam_indexes" myisam_indexesHR 733 | cecho "Current MyISAM index space = $myisam_indexesHR $unit" 734 | 735 | human_readable "$key_buffer_size" key_buffer_sizeHR 736 | cecho "Current key_buffer_size = $key_buffer_sizeHR $unit" 737 | cecho "Key cache miss rate is 1 : $key_cache_miss_rate" 738 | cecho "Key buffer free ratio = $key_buffer_freeRND %" 739 | 740 | if [ $((key_cache_miss_rate <= 100)) -ne 0 ] && [ $((key_cache_miss_rate > 0)) -ne 0 ] && [ $((key_buffer_freeRND <= 20)) -ne 0 ] ; then 741 | cecho "You could increase key_buffer_size" boldred 742 | cecho "It is safe to raise this up to 1/4 of total system memory;" 743 | cecho "assuming this is a dedicated database server." 744 | elif [ $((key_buffer_freeRND <= 20)) -ne 0 ] && [ $((key_buffer_size <= $myisam_indexes)) -ne 0 ] ; then 745 | cecho "You could increase key_buffer_size" boldred 746 | cecho "It is safe to raise this up to 1/4 of total system memory;" 747 | cecho "assuming this is a dedicated database server." 748 | elif [ $((key_cache_miss_rate >= 10000)) -ne 0 ] || [ $((key_buffer_freeRND <= 50)) -ne 0 ] ; then 749 | cecho "Your key_buffer_size seems to be too high." red 750 | cecho "Perhaps you can use these resources elsewhere" red 751 | else 752 | cecho "Your key_buffer_size seems to be fine" green 753 | fi 754 | } 755 | 756 | 757 | check_query_cache () 758 | ## -- Query Cache -- ## 759 | { 760 | cecho "QUERY CACHE" boldblue 761 | 762 | mysql_status \'Qcache_free_memory\' qcache_free_memory 763 | mysql_status \'Qcache_total_blocks\' qcache_total_blocks 764 | mysql_status \'Qcache_free_blocks\' qcache_free_blocks 765 | mysql_status \'Qcache_lowmem_prunes\' qcache_lowmem_prunes 766 | mysql_variable \'version\' mysql_version 767 | mysql_variable \'query_cache_size\' query_cache_size 768 | mysql_variable \'query_cache_limit\' query_cache_limit 769 | mysql_variable \'query_cache_min_res_unit\' query_cache_min_res_unit 770 | 771 | if [ $((query_cache_size == 0)) -ne 0 ] ; then 772 | cecho "Query cache is supported but not enabled" red 773 | cecho "Perhaps you should set the query_cache_size" red 774 | else 775 | qcache_used_memory="$((query_cache_size - $qcache_free_memory))" 776 | qcache_mem_fill_ratio="$(echo "scale=2 ; $qcache_used_memory * 100 / $query_cache_size" | $bin_bc -l)" 777 | qcache_mem_fill_ratioHR="$(echo "scale=0 ; $qcache_mem_fill_ratio / 1" | $bin_bc -l)" 778 | 779 | cecho "Query cache is enabled" green 780 | human_readable "$query_cache_size" query_cache_sizeHR 781 | cecho "Current query_cache_size = $query_cache_sizeHR $unit" 782 | human_readable "$qcache_used_memory" qcache_used_memoryHR 783 | cecho "Current query_cache_used = $qcache_used_memoryHR $unit" 784 | human_readable "$query_cache_limit" query_cache_limitHR 785 | cecho "Current query_cache_limit = $query_cache_limitHR $unit" 786 | cecho "Current Query cache Memory fill ratio = $qcache_mem_fill_ratio %" 787 | human_readable "$query_cache_min_res_unit" query_cache_min_res_unitHR 788 | cecho "Current query_cache_min_res_unit = $query_cache_min_res_unitHR $unit" 789 | if [ $((qcache_free_blocks > 2)) -ne 0 ] && [ $((qcache_total_blocks > 0)) -ne 0 ] ; then 790 | qcache_percent_fragmented="$(echo "scale=2 ; $qcache_free_blocks * 100 / $qcache_total_blocks" | $bin_bc -l)" 791 | qcache_percent_fragmentedHR="$(echo "scale=0 ; $qcache_percent_fragmented / 1" | $bin_bc -l)" 792 | if [ $((qcache_percent_fragmentedHR > 20)) -ne 0 ] ; then 793 | cecho "Query Cache is $qcache_percent_fragmentedHR % fragmented" red 794 | cecho "Run \"FLUSH QUERY CACHE\" periodically to defragment the query cache memory" red 795 | cecho "If you have many small queries lower 'query_cache_min_res_unit' to reduce fragmentation." red 796 | fi 797 | fi 798 | 799 | if [ $((qcache_mem_fill_ratioHR <= 25)) -ne 0 ] ; then 800 | cecho "Your query_cache_size seems to be too high." red 801 | cecho "Perhaps you can use these resources elsewhere" red 802 | fi 803 | if [ $((qcache_lowmem_prunes >= 50)) -ne 0 ] && [ $((qcache_mem_fill_ratioHR >= 80)) -ne 0 ] ; then 804 | cechon "However, " 805 | cechon "$qcache_lowmem_prunes " boldred 806 | cecho "queries have been removed from the query cache due to lack of memory" 807 | cecho "Perhaps you should raise query_cache_size" boldred 808 | fi 809 | cecho "MySQL won't cache query results that are larger than query_cache_limit in size" yellow 810 | fi 811 | } 812 | 813 | 814 | check_sort_operations () 815 | ## -- Sort Operations -- ## 816 | { 817 | cecho "SORT OPERATIONS" boldblue 818 | 819 | mysql_status \'Sort_merge_passes\' sort_merge_passes 820 | mysql_status \'Sort_scan\' sort_scan 821 | mysql_status \'Sort_range\' sort_range 822 | mysql_variable \'sort_buffer_size\' sort_buffer_size 823 | mysql_variable \'read_rnd_buffer_size\' read_rnd_buffer_size 824 | 825 | total_sorts="$((sort_scan + $sort_range))" 826 | 827 | ## Correct for rounding error in mysqld where 512K != 524288 ## 828 | sort_buffer_size="$((sort_buffer_size + 8))" 829 | read_rnd_buffer_size="$((read_rnd_buffer_size + 8))" 830 | 831 | human_readable "$sort_buffer_size" sort_buffer_sizeHR 832 | cecho "Current sort_buffer_size = $sort_buffer_sizeHR $unit" 833 | 834 | human_readable "$read_rnd_buffer_size" read_rnd_buffer_sizeHR 835 | cechon "Current " 836 | cechon "read_rnd_buffer_size " 837 | cecho "= $read_rnd_buffer_sizeHR $unit" 838 | 839 | if [ $((total_sorts == 0)) -ne 0 ] ; then 840 | cecho "No sort operations have been performed" 841 | passes_per_sort="0" 842 | fi 843 | if [ $((sort_merge_passes != 0)) -ne 0 ] ; then 844 | passes_per_sort="$((sort_merge_passes / $total_sorts))" 845 | else 846 | passes_per_sort="0" 847 | fi 848 | 849 | if [ $((passes_per_sort >= 2)) -ne 0 ] ; then 850 | cechon "On average " 851 | cechon "$passes_per_sort " boldred 852 | cecho "sort merge passes are made per sort operation" 853 | cecho "You should raise your sort_buffer_size" 854 | cechon "You should also raise your " 855 | cecho "read_rnd_buffer_size" 856 | else 857 | cecho "Sort buffer seems to be fine" green 858 | fi 859 | } 860 | 861 | 862 | check_join_operations () 863 | ## -- Joins -- ## 864 | { 865 | cecho "JOINS" boldblue 866 | 867 | mysql_status \'Select_full_join\' select_full_join 868 | mysql_status \'Select_range_check\' select_range_check 869 | mysql_variable \'join_buffer_size\' join_buffer_size 870 | 871 | ## Some 4K is dropped from join_buffer_size adding it back to make sane ## 872 | ## handling of human-readable conversion ## 873 | join_buffer_size="$((join_buffer_size + 4096))" 874 | human_readable "$join_buffer_size" join_buffer_sizeHR 2 875 | 876 | cecho "Current join_buffer_size = $join_buffer_sizeHR $unit" 877 | cecho "You have had $select_full_join queries where a join could not use an index properly" 878 | 879 | if [ $((select_range_check == 0)) -ne 0 ] && [ $((select_full_join == 0)) -ne 0 ] ; then 880 | cecho "Your joins seem to be using indexes properly" green 881 | fi 882 | if [ $((select_full_join > 0)) -ne 0 ] ; then 883 | print_error="true" 884 | raise_buffer="true" 885 | fi 886 | if [ $((select_range_check > 0)) -ne 0 ] ; then 887 | cecho "You have had $select_range_check joins without keys that check for key usage after each row" red 888 | print_error="true" 889 | raise_buffer="true" 890 | fi 891 | 892 | if [ $((join_buffer_size >= 4194304)) -ne 0 ] ; then 893 | cecho "join_buffer_size >= 4 M" boldred 894 | cecho "This is not advised" boldred 895 | fi 896 | 897 | if [ "$print_error" = "true" ] ; then 898 | cecho "You should enable \"log-queries-not-using-indexes\"" 899 | cecho "Then look for non indexed joins in the slow query log." 900 | if [ "$raise_buffer" = "yes" ] ; then 901 | cecho "If you are unable to optimize your queries you may want to increase your" 902 | cecho "join_buffer_size to accommodate larger joins in one pass." 903 | cecho " " 904 | cecho "Note! This script will still suggest raising the join_buffer_size when" boldred 905 | cecho "ANY joins not using indexes are found." boldred 906 | fi 907 | fi 908 | 909 | # XXX Add better tests for join_buffer_size pending mysql bug #15088 XXX # 910 | } 911 | 912 | 913 | check_tmp_tables () 914 | ## -- Temp Tables -- ## 915 | { 916 | cecho "TEMP TABLES" boldblue 917 | 918 | mysql_status \'Created_tmp_tables\' created_tmp_tables 919 | mysql_status \'Created_tmp_disk_tables\' created_tmp_disk_tables 920 | mysql_variable \'tmp_table_size\' tmp_table_size 921 | mysql_variable \'max_heap_table_size\' max_heap_table_size 922 | 923 | if [ $((created_tmp_tables == 0)) -ne 0 ] ; then 924 | tmp_disk_tables="0" 925 | else 926 | tmp_disk_tables="$((created_tmp_disk_tables * 100 / (created_tmp_tables + created_tmp_disk_tables)))" 927 | fi 928 | human_readable "$max_heap_table_size" max_heap_table_sizeHR 929 | cecho "Current max_heap_table_size = $max_heap_table_sizeHR $unit" 930 | 931 | human_readable "$tmp_table_size" tmp_table_sizeHR 932 | cecho "Current tmp_table_size = $tmp_table_sizeHR $unit" 933 | 934 | cecho "Of $created_tmp_tables temp tables, $tmp_disk_tables% were created on disk" 935 | if [ $((tmp_table_size > $max_heap_table_size)) -ne 0 ] ; then 936 | cecho "Effective in-memory tmp_table_size is limited to max_heap_table_size." yellow 937 | fi 938 | if [ $((tmp_disk_tables >= 25)) -ne 0 ] ; then 939 | cecho "Perhaps you should increase your tmp_table_size and/or max_heap_table_size" boldred 940 | cecho "to reduce the number of disk-based temporary tables" boldred 941 | cecho "Note! BLOB and TEXT columns are not allow in memory tables." yellow 942 | cecho "If you are using these columns raising these values might not impact your " yellow 943 | cecho "ratio of on disk temp tables." yellow 944 | else 945 | cecho "Created disk tmp tables ratio seems fine" green 946 | fi 947 | } 948 | 949 | 950 | check_open_files () 951 | ## -- Open Files Limit -- ## 952 | { 953 | cecho "OPEN FILES LIMIT" boldblue 954 | 955 | mysql_status \'Open_files\' open_files 956 | mysql_variable \'open_files_limit\' open_files_limit 957 | 958 | if [ -z "$open_files_limit" ] || [ $((open_files_limit == 0)) -ne 0 ] ; then 959 | open_files_limit="$(ulimit -n)" 960 | cant_override="1" 961 | else 962 | cant_override="0" 963 | fi 964 | cecho "Current open_files_limit = $open_files_limit files" 965 | 966 | open_files_ratio="$((open_files * 100 / $open_files_limit))" 967 | 968 | cecho "The open_files_limit should typically be set to at least 2x-3x" yellow 969 | cecho "that of table_open_cache if you have heavy MyISAM usage." yellow 970 | if [ $((open_files_ratio >= 75)) -ne 0 ] ; then 971 | cecho "You currently have open more than 75% of your open_files_limit" boldred 972 | if [ $((cant_override == 1)) -ne 0 ] ; then 973 | cecho "You should set a higer value for ulimit -u in the mysql startup script then restart mysqld" boldred 974 | elif [ $((cant_override == 0)) -ne 0 ] ; then 975 | cecho "You should set a higher value for open_files_limit in my.cnf" boldred 976 | else 977 | cecho "ERROR can't determine if mysqld override of ulimit is allowed" boldred 978 | exit 1 979 | fi 980 | else 981 | cecho "Your open_files_limit value seems to be fine" green 982 | fi 983 | } 984 | 985 | 986 | check_table_cache () 987 | ## -- Table Cache -- ## 988 | { 989 | cecho "TABLE CACHE" boldblue 990 | 991 | mysql_status \'Open_tables\' open_tables 992 | mysql_status \'Opened_tables\' opened_tables 993 | mysql_status \'Open_table_definitions\' open_table_definitions 994 | mysql_variable \'datadir\' datadir 995 | mysql_variable \'table_open_cache\' table_open_cache 996 | mysql_variable \'table_definition_cache\' table_definition_cache 997 | 998 | table_count="$($cmd_mysql -Bse "/*!50000 SELECT COUNT(*) FROM information_schema.tables WHERE TABLE_TYPE='BASE TABLE' */")" 999 | 1000 | if [ -z "$table_count" ] ; then 1001 | if [ "$UID" != "$socket_owner" ] && [ "$UID" != "0" ] ; then 1002 | cecho "You are not '$socket_owner' or 'root'" red 1003 | cecho "I am unable to determine the table_count!" red 1004 | else 1005 | table_count="$($bin_find $datadir 2>&1 | $bin_grep -ic .frm$)" 1006 | fi 1007 | fi 1008 | 1009 | if [ $((opened_tables != 0)) -ne 0 ] && [ $((table_open_cache != 0)) -ne 0 ] ; then 1010 | table_cache_hit_rate="$((open_tables * 100 / $opened_tables))" 1011 | table_cache_fill="$((open_tables * 100 / $table_open_cache))" 1012 | elif [ $((opened_tables == 0)) -ne 0 ] && [ $((table_open_cache != 0)) -ne 0 ] ; then 1013 | table_cache_hit_rate="100" 1014 | table_cache_fill="$((open_tables * 100 / $table_open_cache))" 1015 | else 1016 | cecho "ERROR no table_open_cache?!" boldred 1017 | exit 1 1018 | fi 1019 | cecho "Current table_open_cache = $table_open_cache tables" 1020 | cecho "Current table_definition_cache = $table_definition_cache tables" 1021 | if [ ! -z "$table_count" ] ; then 1022 | cecho "You have a total of $table_count tables" 1023 | fi 1024 | 1025 | if [ $((table_cache_fill < 95)) -ne 0 ] ; then 1026 | cechon "You have " 1027 | cechon "$open_tables " green 1028 | cecho "open tables." 1029 | cecho "The table_open_cache value seems to be fine" green 1030 | elif [ $((table_cache_hit_rate <= 85)) -ne 0 ] || [ $((table_cache_fill >= 95)) -ne 0 ] ; then 1031 | cechon "You have " 1032 | cechon "$open_tables " boldred 1033 | cecho "open tables." 1034 | cechon "Current table_open_cache hit rate is " 1035 | cecho "$table_cache_hit_rate%" boldred 1036 | cechon ", while " 1037 | cechon "$table_cache_fill% " boldred 1038 | cecho "of your table cache is in use" 1039 | cecho "You should probably increase your table_open_cache" red 1040 | else 1041 | cechon "Current table_open_cache hit rate is " 1042 | cechon "$table_cache_hit_rate%" green 1043 | cechon ", while " 1044 | cechon "$table_cache_fill% " green 1045 | cecho "of your table cache is in use" 1046 | cecho "The table cache value seems to be fine" green 1047 | fi 1048 | if [ $((table_definition_cache <= $table_count)) -ne 0 ] && [ $((table_count >= 100)) -ne 0 ] ; then 1049 | cecho "You should probably increase your table_definition_cache value." red 1050 | fi 1051 | } 1052 | 1053 | 1054 | check_table_locking () 1055 | ## -- Table Locking -- ## 1056 | { 1057 | cecho "TABLE LOCKING" boldblue 1058 | 1059 | mysql_status \'Table_locks_waited\' table_locks_waited 1060 | mysql_status \'Table_locks_immediate\' table_locks_immediate 1061 | mysql_variable \'concurrent_insert\' concurrent_insert 1062 | mysql_variable \'low_priority_updates\' low_priority_updates 1063 | 1064 | if [ "$concurrent_insert" = "ON" ] ; then 1065 | concurrent_insert="1" 1066 | elif [ "$concurrent_insert" = "OFF" ] ; then 1067 | concurrent_insert="0" 1068 | fi 1069 | 1070 | cechon "Current Lock Wait ratio = " 1071 | if [ $((table_locks_waited > 0)) -ne 0 ] ; then 1072 | immediate_locks_miss_rate="$((table_locks_immediate / $table_locks_waited))" 1073 | cecho "1 : $immediate_locks_miss_rate" red 1074 | else 1075 | immediate_locks_miss_rate="99999" # perfect 1076 | cecho "0 : $questions" 1077 | fi 1078 | if [ $((immediate_locks_miss_rate < 5000)) -ne 0 ] ; then 1079 | cecho "You may benefit from selective use of InnoDB." 1080 | if [ "$low_priority_updates" = "OFF" ] ; then 1081 | cecho "If you have long running SELECT's against MyISAM tables and perform" 1082 | cecho "frequent updates consider setting 'low_priority_updates=1'" 1083 | fi 1084 | if [ "$concurrent_insert" = "AUTO" ] || [ "$concurrent_insert" = "NEVER" ] ; then 1085 | cecho "If you have a high concurrency of inserts on Dynamic row-length tables" 1086 | cecho "consider setting 'concurrent_insert=ALWAYS'." 1087 | fi 1088 | else 1089 | cecho "Your table locking seems to be fine" green 1090 | fi 1091 | } 1092 | 1093 | 1094 | check_table_scans () 1095 | ## -- Table Scans -- ## 1096 | { 1097 | cecho "TABLE SCANS" boldblue 1098 | 1099 | mysql_status \'Com_select\' com_select 1100 | mysql_status \'Handler_read_rnd_next\' read_rnd_next 1101 | mysql_variable \'read_buffer_size\' read_buffer_size 1102 | 1103 | human_readable "$read_buffer_size" read_buffer_sizeHR 1104 | cecho "Current read_buffer_size = $read_buffer_sizeHR $unit" 1105 | 1106 | if [ $((com_select > 0)) -ne 0 ] ; then 1107 | full_table_scans="$((read_rnd_next / $com_select))" 1108 | cecho "Current table scan ratio = $full_table_scans : 1" 1109 | if [ $((full_table_scans >= 4000)) -ne 0 ] && [ $((read_buffer_size <= 2097152)) -ne 0 ] ; then 1110 | cecho "You have a high ratio of sequential access requests to SELECTs" red 1111 | cechon "You may benefit from raising " red 1112 | cechon "read_buffer_size " red 1113 | cecho "and/or improving your use of indexes." red 1114 | elif [ $((read_buffer_size > 8388608)) -ne 0 ] ; then 1115 | cechon "read_buffer_size is over 8 MB " red 1116 | cecho "there is probably no need for such a large read_buffer" red 1117 | 1118 | else 1119 | cecho "read_buffer_size seems to be fine" green 1120 | fi 1121 | else 1122 | cecho "read_buffer_size seems to be fine" green 1123 | fi 1124 | } 1125 | 1126 | 1127 | check_innodb_status () 1128 | ## -- InnoDB -- ## 1129 | { 1130 | ## See http://bugs.mysql.com/59393 1131 | 1132 | if [ $((mysql_version_num < 050603)) -ne 0 ] ; then 1133 | mysql_variable \'have_innodb\' have_innodb 1134 | fi 1135 | if [ $((mysql_version_num >= 050500)) -ne 0 ] && [ $((mysql_version_num < 050512)) -ne 0 ] ; then 1136 | mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb 1137 | if [ "$ignore_builtin_innodb" = "ON" ] || [ "$have_innodb" = "NO" ] ; then 1138 | innodb_enabled="0" 1139 | else 1140 | innodb_enabled="1" 1141 | fi 1142 | elif [ "$major_version" = "5.5" ] && [ $((mysql_version_num >= 050512)) -ne 0 ] ; then 1143 | mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb 1144 | if [ "$ignore_builtin_innodb" = "ON" ] ; then 1145 | innodb_enabled="0" 1146 | else 1147 | innodb_enabled="1" 1148 | fi 1149 | elif [ $((mysql_version_num >= 050600)) -ne 0 ] && [ $((mysql_version_num < 050603)) -ne 0 ] ; then 1150 | mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb 1151 | if [ "$ignore_builtin_innodb" = "ON" ] || [ "$have_innodb" = "NO" ] ; then 1152 | innodb_enabled="0" 1153 | else 1154 | innodb_enabled="1" 1155 | fi 1156 | elif [ "$major_version" = "5.6" ] && [ $((mysql_version_num >= 050603)) -ne 0 ] ; then 1157 | mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb 1158 | if [ "$ignore_builtin_innodb" = "ON" ] ; then 1159 | innodb_enabled="0" 1160 | else 1161 | innodb_enabled="1" 1162 | fi 1163 | elif [ $((mysql_version_num >= 050700)) -ne 0 ] ; then 1164 | mysql_variable \'ignore_builtin_innodb\' ignore_builtin_innodb 1165 | if [ "$ignore_builtin_innodb" = "ON" ] ; then 1166 | innodb_enabled="0" 1167 | else 1168 | innodb_enabled="1" 1169 | fi 1170 | fi 1171 | if [ $((innodb_enabled == 1)) -ne 0 ] ; then 1172 | cecho "INNODB STATUS" boldblue 1173 | 1174 | mysql_status \'Innodb_buffer_pool_pages_data\' innodb_buffer_pool_pages_data 1175 | mysql_status \'Innodb_buffer_pool_pages_misc\' innodb_buffer_pool_pages_misc 1176 | mysql_status \'Innodb_buffer_pool_pages_free\' innodb_buffer_pool_pages_free 1177 | mysql_status \'Innodb_buffer_pool_pages_total\' innodb_buffer_pool_pages_total 1178 | mysql_status \'Innodb_buffer_pool_read_ahead_seq\' innodb_buffer_pool_read_ahead_seq 1179 | mysql_status \'Innodb_buffer_pool_read_requests\' innodb_buffer_pool_read_requests 1180 | mysql_status \'Innodb_os_log_pending_fsyncs\' innodb_os_log_pending_fsyncs 1181 | mysql_status \'Innodb_os_log_pending_writes\' innodb_os_log_pending_writes 1182 | mysql_status \'Innodb_log_waits\' innodb_log_waits 1183 | mysql_status \'Innodb_row_lock_time\' innodb_row_lock_time 1184 | mysql_status \'Innodb_row_lock_waits\' innodb_row_lock_waits 1185 | mysql_variable \'innodb_buffer_pool_size\' innodb_buffer_pool_size 1186 | mysql_variable \'innodb_additional_mem_pool_size\' innodb_additional_mem_pool_size 1187 | mysql_variable \'innodb_fast_shutdown\' innodb_fast_shutdown 1188 | mysql_variable \'innodb_flush_log_at_trx_commit\' innodb_flush_log_at_trx_commit 1189 | mysql_variable \'innodb_locks_unsafe_for_binlog\' innodb_locks_unsafe_for_binlog 1190 | mysql_variable \'innodb_log_buffer_size\' innodb_log_buffer_size 1191 | mysql_variable \'innodb_log_file_size\' innodb_log_file_size 1192 | mysql_variable \'innodb_log_files_in_group\' innodb_log_files_in_group 1193 | mysql_variable \'innodb_safe_binlog\' innodb_safe_binlog 1194 | mysql_variable \'innodb_thread_concurrency\' innodb_thread_concurrency 1195 | 1196 | innodb_indexes="$($cmd_mysql -Bse "/*!50000 SELECT IFNULL(SUM(INDEX_LENGTH),0) FROM information_schema.tables WHERE ENGINE='InnoDB' */")" 1197 | innodb_data="$($cmd_mysql -Bse "/*!50000 SELECT IFNULL(SUM(DATA_LENGTH),0) FROM information_schema.tables WHERE ENGINE='InnoDB' */")" 1198 | 1199 | human_readable "$innodb_indexes" innodb_indexesHR 1200 | cecho "Current InnoDB index space = $innodb_indexesHR $unit" 1201 | human_readable "$innodb_data" innodb_dataHR 1202 | cecho "Current InnoDB data space = $innodb_dataHR $unit" 1203 | percent_innodb_buffer_pool_free="$((innodb_buffer_pool_pages_free * 100 / $innodb_buffer_pool_pages_total))" 1204 | cecho "Current InnoDB buffer pool free = "$percent_innodb_buffer_pool_free" %" 1205 | human_readable "$innodb_buffer_pool_size" innodb_buffer_pool_sizeHR 1206 | cecho "Current innodb_buffer_pool_size = $innodb_buffer_pool_sizeHR $unit" 1207 | cecho "Depending on how much space your innodb indexes take up it may be safe" 1208 | cecho "to increase this value to up to 2 / 3 of total system memory" 1209 | else 1210 | cecho "No InnoDB Support Enabled!" boldred 1211 | fi 1212 | } 1213 | 1214 | 1215 | total_memory_used () 1216 | ## -- Total Memory Usage -- ## 1217 | { 1218 | cecho "MEMORY USAGE" boldblue 1219 | 1220 | mysql_status \'Max_used_connections\' max_used_connections 1221 | mysql_variable \'read_buffer_size\' read_buffer_size 1222 | mysql_variable \'read_rnd_buffer_size\' read_rnd_buffer_size 1223 | mysql_variable \'sort_buffer_size\' sort_buffer_size 1224 | mysql_variable \'thread_stack\' thread_stack 1225 | mysql_variable \'max_connections\' max_connections 1226 | mysql_variable \'join_buffer_size\' join_buffer_size 1227 | mysql_variable \'tmp_table_size\' tmp_table_size 1228 | mysql_variable \'max_heap_table_size\' max_heap_table_size 1229 | mysql_variable \'log_bin\' log_bin 1230 | 1231 | if [ "$log_bin" = "ON" ] ; then 1232 | mysql_variable \'binlog_cache_size\' binlog_cache_size 1233 | else 1234 | binlog_cache_size="0" 1235 | fi 1236 | 1237 | if [ $((max_heap_table_size <= $tmp_table_size)) -ne 0 ] ; then 1238 | effective_tmp_table_size="$max_heap_table_size" 1239 | else 1240 | effective_tmp_table_size="$tmp_table_size" 1241 | fi 1242 | 1243 | per_thread_buffers="$(echo "($read_buffer_size + $read_rnd_buffer_size + $sort_buffer_size + $thread_stack + $join_buffer_size + $binlog_cache_size) * $max_connections" | $bin_bc -l)" 1244 | 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" | $bin_bc -l)" 1245 | 1246 | mysql_variable \'innodb_buffer_pool_size\' innodb_buffer_pool_size 1247 | if [ -z "$innodb_buffer_pool_size" ] ; then 1248 | innodb_buffer_pool_size="0" 1249 | fi 1250 | 1251 | mysql_variable \'innodb_additional_mem_pool_size\' innodb_additional_mem_pool_size 1252 | if [ -z "$innodb_additional_mem_pool_size" ] ; then 1253 | innodb_additional_mem_pool_size="0" 1254 | fi 1255 | 1256 | mysql_variable \'innodb_log_buffer_size\' innodb_log_buffer_size 1257 | if [ -z "$innodb_log_buffer_size" ] ; then 1258 | innodb_log_buffer_size="0" 1259 | fi 1260 | 1261 | mysql_variable \'key_buffer_size\' key_buffer_size 1262 | if [ -z "$key_buffer_size" ] ; then 1263 | key_buffer_size="0" 1264 | fi 1265 | 1266 | mysql_variable \'query_cache_size\' query_cache_size 1267 | if [ -z "$query_cache_size" ] ; then 1268 | query_cache_size="0" 1269 | fi 1270 | 1271 | global_buffers="$(echo "$innodb_buffer_pool_size + $innodb_additional_mem_pool_size + $innodb_log_buffer_size + $key_buffer_size + $query_cache_size" | $bin_bc -l)" 1272 | 1273 | max_memory="$(echo "$global_buffers + $per_thread_max_buffers" | $bin_bc -l)" 1274 | total_memory="$(echo "$global_buffers + $per_thread_buffers" | $bin_bc -l)" 1275 | 1276 | pct_of_sys_mem="$(echo "scale=0 ; $total_memory * 100 / $physical_memory" | $bin_bc -l)" 1277 | 1278 | if [ $((pct_of_sys_mem > 90)) -ne 0 ] ; then 1279 | txt_color="boldred" 1280 | error="1" 1281 | else 1282 | txt_color= 1283 | error="0" 1284 | fi 1285 | 1286 | human_readable "$max_memory" max_memoryHR 1287 | cecho "Max Memory Ever Allocated : $max_memoryHR $unit" $txt_color 1288 | human_readable "$per_thread_buffers" per_thread_buffersHR 1289 | cecho "Configured Max Per-thread Buffers : $per_thread_buffersHR $unit" $txt_color 1290 | human_readable "$global_buffers" global_buffersHR 1291 | cecho "Configured Max Global Buffers : $global_buffersHR $unit" $txt_color 1292 | human_readable "$total_memory" total_memoryHR 1293 | cecho "Configured Max Memory Limit : $total_memoryHR $unit" $txt_color 1294 | human_readable "$effective_tmp_table_size" effective_tmp_table_sizeHR 1295 | cecho "Plus $effective_tmp_table_sizeHR $unit per temporary table created" 1296 | human_readable "$physical_memory" physical_memoryHR 1297 | cecho "Physical Memory : $physical_memoryHR $unit" $txt_color 1298 | if [ $((error == 1)) -ne 0 ] ; then 1299 | cecho " " 1300 | cecho "Max memory limit exceeds 90% of physical memory" $txt_color 1301 | else 1302 | cecho "Max memory limit seem to be within acceptable norms" green 1303 | fi 1304 | unset txt_color 1305 | } 1306 | 1307 | 1308 | login_validation () 1309 | ## -- -- ## 1310 | { 1311 | check_for_socket 1312 | check_mysql_login 1313 | } 1314 | 1315 | 1316 | shared_info () 1317 | ## -- -- ## 1318 | { 1319 | mysql_status \'Questions\' questions 1320 | socket_owner="$($bin_ls -lnH $socket | $bin_awk '{ print $3 }')" 1321 | export major_version="$($cmd_mysql -Bse "SELECT SUBSTRING_INDEX(VERSION(), '.', +2)")" 1322 | export mysql_version_num="$($cmd_mysql -Bse "SELECT VERSION()" | $bin_awk -F \. '{ printf "%2d", $1; printf "%02d", $2; printf "%02d", $3 }')" 1323 | if [ $((mysql_version_num < 050500)) -ne 0 ] ; then 1324 | cecho "UNSUPPORTED MYSQL VERSION" boldred 1325 | exit 1 1326 | fi 1327 | } 1328 | 1329 | 1330 | get_system_info () 1331 | ## -- -- ## 1332 | { 1333 | export OS="$($bin_uname)" 1334 | 1335 | # Get information for various UNIXes 1336 | if [ "$OS" = "Darwin" ] ; then 1337 | ps_socket="$($bin_netstat -ln | $bin_awk '/mysql(.*)?\.sock/ { print $9 }' | $bin_head -n 1)" 1338 | found_socks="$($bin_netstat -ln | $bin_awk '/mysql(.*)?\.sock/ { print $9 }')" 1339 | export physical_memory="$($bin_sysctl -n hw.memsize)" 1340 | export duflags='' 1341 | elif [ "$OS" = "FreeBSD" ] || [ "$OS" = "OpenBSD" ] ; then 1342 | ## On FreeBSD must be root to locate sockets. 1343 | ps_socket="$($bin_netstat -ln | $bin_awk '/mysql(.*)?\.sock/ { print $9 }' | $bin_head -n 1)" 1344 | found_socks="$($bin_netstat -ln | $bin_awk '/mysql(.*)?\.sock/ { print $9 }')" 1345 | export physical_memory="$($bin_sysctl -n hw.realmem)" 1346 | export duflags="" 1347 | elif [ "$OS" = "Linux" ] ; then 1348 | ps_socket="$($bin_netstat -ln | $bin_awk '/mysql(.*)?\.sock/ { print $9 }' | $bin_head -n 1)" 1349 | found_socks="$($bin_netstat -ln | $bin_awk '/mysql(.*)?\.sock/ { print $9 }')" 1350 | export physical_memory="$($bin_awk '/^MemTotal/ { printf("%.0f", $2*1024) }' < /proc/meminfo)" 1351 | export duflags="-b" 1352 | elif [ "$OS" = "SunOS" ] ; then 1353 | ps_socket="$($bin_netstat -an | $bin_awk '/mysql(.*)?.sock/ { print $5 }' | $bin_head -n 1)" 1354 | found_socks="$($bin_netstat -an | $bin_awk '/mysql(.*)?.sock/ { print $5 }')" 1355 | if [ -z "$(which prtconf)" ] ; then 1356 | cecho "Error: Needed command \"prtconf\" not found in PATH!" 1357 | exit 1 1358 | else 1359 | bin_path="$(which prtconf)" 1360 | export bin_prtconf="$bin_path" 1361 | fi 1362 | export physical_memory="$($bin_prtconf | $bin_awk '/^Memory\ size:/ { print $3*1048576 }')" 1363 | fi 1364 | } 1365 | 1366 | 1367 | banner_info () 1368 | ## -- -- ## 1369 | { 1370 | shared_info 1371 | print_banner ; cecho " " 1372 | check_mysql_version ; cecho " " 1373 | post_uptime_warning ; cecho " " 1374 | } 1375 | 1376 | 1377 | misc () 1378 | ## -- -- ## 1379 | { 1380 | shared_info 1381 | check_slow_queries ; cecho " " 1382 | check_binary_log ; cecho " " 1383 | check_threads ; cecho " " 1384 | check_used_connections ; cecho " " 1385 | check_innodb_status ; cecho " " 1386 | } 1387 | 1388 | 1389 | memory () 1390 | ## -- -- ## 1391 | { 1392 | shared_info 1393 | total_memory_used ; cecho " " 1394 | check_key_buffer_size ; cecho " " 1395 | check_query_cache ; cecho " " 1396 | check_sort_operations ; cecho " " 1397 | check_join_operations ; cecho " " 1398 | } 1399 | 1400 | 1401 | file () 1402 | ## -- -- ## 1403 | { 1404 | shared_info 1405 | check_open_files ; cecho " " 1406 | check_table_cache ; cecho " " 1407 | check_tmp_tables ; cecho " " 1408 | check_table_scans ; cecho " " 1409 | check_table_locking ; cecho " " 1410 | } 1411 | 1412 | 1413 | all () 1414 | ## -- -- ## 1415 | { 1416 | banner_info 1417 | misc 1418 | memory 1419 | file 1420 | } 1421 | 1422 | 1423 | prompt () 1424 | ## -- -- ## 1425 | { 1426 | prompted="true" 1427 | read -p "Username [anonymous] : " user 1428 | read -rp "Password [] : " pass 1429 | cecho " " 1430 | read -p "Socket [/var/lib/mysql/mysql.sock] : " socket 1431 | if [ -z "$socket" ] ; then 1432 | export socket="/var/lib/mysql/mysql.sock" 1433 | fi 1434 | 1435 | if [ -z "$pass" ] ; then 1436 | export cmd_mysql="$bin_mysql -S $socket -u$user" 1437 | export cmd_mysqladmin="$bin_mysqladmin -S $socket -u$user" 1438 | else 1439 | export cmd_mysql="$bin_mysql -S $socket -u$user -p$pass" 1440 | export cmd_mysqladmin="$bin_mysqladmin -S $socket -u$user -p$pass" 1441 | fi 1442 | 1443 | login_validation 1444 | 1445 | if [ "$?" = "1" ] ; then 1446 | exit 1 1447 | fi 1448 | 1449 | read -p "Mode to test - banner, file, misc, mem, innodb, [all] : " REPLY 1450 | if [ -z "$REPLY" ] ; then 1451 | REPLY="all" 1452 | fi 1453 | case "$REPLY" in 1454 | banner | BANNER | header | HEADER | head | HEAD) 1455 | banner_info 1456 | ;; 1457 | misc | MISC | miscelaneous ) 1458 | misc 1459 | ;; 1460 | mem | memory | MEM | MEMORY ) 1461 | memory 1462 | ;; 1463 | file | FILE | disk | DISK ) 1464 | file 1465 | ;; 1466 | innodb | INNODB ) 1467 | innodb 1468 | ;; 1469 | all | ALL ) 1470 | all 1471 | ;; 1472 | * ) 1473 | cecho "Invalid Mode! Valid options are 'banner', 'misc', 'memory', 'file', 'innodb' or 'all'" boldred 1474 | exit 1 1475 | ;; 1476 | esac 1477 | } 1478 | 1479 | 1480 | main () 1481 | ## -- -- ## 1482 | { 1483 | local var1="$1" 1484 | 1485 | get_system_info 1486 | 1487 | if [ -z "$var1" ] ; then 1488 | login_validation 1489 | mode="ALL" 1490 | elif [ "$var1" = "prompt" ] || [ "$var1" = "PROMPT" ] ; then 1491 | mode="$var1" 1492 | elif [ "$var1" != "prompt" ] || [ "$var1" != "PROMPT" ] ; then 1493 | login_validation 1494 | mode="$var1" 1495 | fi 1496 | 1497 | case "$mode" in 1498 | all | ALL ) 1499 | all 1500 | ;; 1501 | mem | memory | MEM | MEMORY ) 1502 | banner_info 1503 | memory 1504 | ;; 1505 | file | FILE | disk | DISK ) 1506 | banner_info 1507 | file 1508 | ;; 1509 | banner | BANNER | header | HEADER | head | HEAD ) 1510 | banner_info 1511 | ;; 1512 | misc | MISC | miscelaneous ) 1513 | banner_info 1514 | misc 1515 | ;; 1516 | innodb | INNODB ) 1517 | banner_info 1518 | check_innodb_status 1519 | ;; 1520 | prompt | PROMPT ) 1521 | prompt 1522 | ;; 1523 | *) 1524 | cecho "usage: $0 [ all | banner | file | innodb | memory | misc | prompt ]" boldred 1525 | exit 1 1526 | ;; 1527 | esac 1528 | } 1529 | 1530 | if [ ! -z "$2" ] ; then 1531 | main usage 1532 | elif [ ! -z "$1" ] ; then 1533 | main "$1" 1534 | else 1535 | main all 1536 | fi 1537 | --------------------------------------------------------------------------------