Mar 13

We recently came across a problem with Cacti and the MySQL counters. For those of you who don’t know how to integrate MySQL statistics into Cacti have a look at this: http://code.google.com/p/mysql-cacti-templates/. These templates are a great way to gain some insight into how your MySQL database servers perform. The templates are actually PHP pages that query the databases through a variety of commands like SHOW STATUS and SHOW ENGINE INNODB STATUS.

The issue that we encountered was that some statistics like the InnoDB buffer pool activity were not displaying anything for one server. Other servers were displaying it just fine and other statistics for that server were also fine.

Among other things the SHOW ENGINE INNODB STATUS command shows deadlock information pertaining to the last deadlock that the InnoDB engine encountered. In some cases this information will be quite extensive and this causes a problem. The output of this command is one giant text field with a limit of 64KB. If the deadlock information is very large other information will get cut off which means certain statistics are lost. The easy fix for this is to restart the database server but in case this is not an option you can always use the innotop utility to wipe the deadlock information by causing a small deadlock.

Tagged with:
Mar 09

Here’s an interesting one, what if you have a MySQL replication setup and the slave stops replicating with a syntax error? The slave should be executing the exact same commands as the master, right? Well, as it turns out, yes and no. There is a bug in MySQL that has been fixed in 5.0.56 according to the bug report. It’s a long story and it’s worth the read but what happens is that a timeout in the network connection between the master and the slave can cause the master to resend part of packet that it sent before. The slave handled the previous packet correctly so it’s not expecting a resend and as a result it starts writing some garbage to the relay log (which is where it stored the statements it will execute). The SQL command gets mangled in the process and when the slave tries to execute it, voila, a syntax error.

To fix this you can use the CHANGE MASTER command to set the slave to the master bin log file and position that shows up in the SHOW SLAVE STATUS output. Make sure you use the Relay_Master_Log_File and Exec_Master_Log_Pos fields since they indicate what position in the master binlog the slave actually thought it was executing. Keep in mind that corruption and its effects are hard to predict. It will definitely be useful to compare the master and slave afterward using the MaatKit tools.

As some more background, the server log will be probably show and error like this to indicate there was a network error:
[ERROR] Error reading packet from server: Lost connection to MySQL server during query (server_errno=2013)

And finally, if you do read the entire bug thread you will notice that the original developer of MySQL also has an opinion on this.

Tagged with:
Mar 03

If you want to grant remote access privileges to a DB on your server,Please look fllow.

First login trough SSH on your server and get access to you mysql

$mysqladmin -u xxx password  xxx

Note: the db user and db passwd are your database username and database password

GRANT ALL PRIVILEGES ON db_base.* TO db_user @’%’ IDENTIFIED BY ‘db_passwd’;

You can also grant accesss to a specific IP adress

GRANT ALL PRIVILEGES ON failserv_example.* TO failserver@’xx.xx.xx.xx’ IDENTIFIED BY ‘db_passwd’;

(where x is your own remote IP)

Refresh privileges,After that to activate your setting type

FLUSH PRIVILEGES;

And exit your mysql

$mysql>quit

Tagged with:
Dec 17

Description:
Currently the number of fd’s on windows is limited to 2048.
This is bad for performance, for many reasons, mostly windows servers
are stuck with a tiny table_cache or low number of concurrent connections,
compared with linux running on the same hardware.

Error Log:
Could not increase number of max_open_files to more than 2048 (request: 3082)

Othre Error:

ERROR 1135: Can’t create a new thread (errno 11). If you are not out of available memory, you can consult the manual for a possible OS-dependent bug

How to repeat:
Run the server

mysqld-nt.exe –table_cache=1000 –max_connections=500 –open_files-limit=3000 –console

061122 17:04:27 [Warning] Could not increase number of max_open_files to more than 2048
(request: 2510)
061122 17:04:28  InnoDB: Started; log sequence number 0 43655
061122 17:04:28 [Note] mysqld-nt: ready for connections.
Version: ‘5.0.30-enterprise-gpl-nt’  socket: ”  port: 3306  MySQL Enterprise Server
(GPL)

More:http://bugs.mysql.com/bug.php?id=24509

Solution:

1.Update Your Mysql Server to Mysql5.5,It has been fix is released in 5.5.

2.Replacement of the operating system,Linux have not the problem.

Tagged with:
Dec 02

Mysql Full Backup Script, Hope it can help you.

#!/bin/sh
###################################################################
# Name:Mysql_Full_Backup.sh
# PS:MySQL DataBase Full Backup.
# Write by:Jason
# Last Modify:2009-11-20
###################################################################

# Define Variable Please Modify By Fact
# Define Script Directory
scriptsDir=/home/Script

# Define Database Directory
mysqlDir=/srv/mysql

# Define Database User & Name
user=bkuser
userPWD=pwd

# Define Backup Directory
dataBackupDir=/home/mysqlbackup

# Define Email Content
eMailFile=$dataBackupDir/email.txt

# Define Email Address
eMail=xxxx@mail.com

# Define Backup Log File.
logFile=$dataBackupDir/mysqlbackup.log
DATE=`date -I`

echo "" > $eMailFile
echo $(date +"%y-%m-%d %H:%M:%S") >> $eMailFile
cd $dataBackupDir

# Define Backup Filename.
dumpFile=database_$DATE.sql
GZDumpFile=database_$DATE.sql.tar.gz

# Backup Database By mysqldump
$mysqlDir/bin/mysqldump -u$user -p$userPWD \
–opt –default-character-set=gbk –extended-insert=false \
–triggers -R –hex-blob –all-databases \
–flush-logs –delete-master-logs \
–lock-all-tables > $dumpFile

# Compress Backup File

if [[ $? == 0 ]]; then
  tar czf $GZDumpFile $dumpFile >> $eMailFile 2>&1
  echo "BackupFileName:$GZDumpFile" >> $eMailFile
  echo "DataBase Backup Success!" >> $eMailFile

  rm -f $dumpFile

# Delete daily backup files.
#  cd $dataBackupDir/daily
#  rm -f *

# Delete old backup files(mtime>2).
#  $scriptsDir/rmBackup.sh

# Move Backup Files To Backup Server.
$scriptsDir/Rsync_Backup.sh

  if (( !$? )); then
    echo "Move Backup Files To Backup Server Success!" >> $eMailFile
    else
    echo "Move Backup Files To Backup Server Fail!" >> $eMailFile
  fi
else
  echo "DataBase Backup Fail!" >> $emailFile
fi

# Write Log File…
#echo "——————————————————–" >> $logFile

cat $eMailFile >> $logFile

# Notify ADMIN by Email.
#cat $eMailFile | mail -s "MySQL Backup" $eMail

Tagged with:
Aug 06

Of course, the data you put into MySQL can be any language you want, but many people around the world who do not speak English as a first language use MySQL. MySQL AB, the company now responsible for MySQL, is based in Sweden, and most of the primary developers are Scandinavian. So, it comes as no surprise that MySQL distributions come with support for other languages. The following languages are currently supported, and more are likely to be added: Czech, Danish, Dutch, English (the default), Estonian, French, German, Greek, Hungarian, Italian, Korean, Norwegian, Norwegian-ny, Polish, Portuguese, Romanian, Russian, Slovak, Spanish, and Swedish.

Displaying Error Messages in Another Language

Starting MySQL so that it displays error messages in one of these languages is as easy as using
the –language or -L options at startup. To do so in the config file, simply add a line such as the following:

language=french

You can also edit the error messages yourself (perhaps you want your database to have that personal touch) or contribute your own set in another language, and give something back to the MySQL community. To change the error messages, simply edit the errmsg.txt file in the appropriate language directory (usually /share/language_name from the MySQL base directory), run the cmp_error utility, and restart the server. For example:

% cp errmsg.txt errmsg.bak
% vi errmsg.txt

Here I edited the error message that read as follows:

"No Database Selected",

to read as follows instead:

"Haven't you forgotten something - No Database Selected",

and then saved it:

"errmsg.txt" 229 lines, 12060 characters written
% comp_err errmsg.txt errmsg.sys
Found 226 messages in language file errmsg.sys

Then restart the server, and the new error messages will take effect:

% mysqladmin shutdown
% /etc/rc.d/init.d/mysql start
% mysql -uroot -pg00r002b
mysql> SELECT * FROM a;
ERROR 1046: Haven't you forgotten something - No Database Selected

You’ll have to repeat the changes if you upgrade to a newer version of MySQL.

Using a Different Character Set

By default, MySQL uses the Latin1 (ISO-8859-1) character set. The character set determines what characters can be used, as well as the sorting order for queries. You can change the character set by changing the value of the –default-character-set option when you start the server. The available character sets currently include the following:

latin1

dos

estonia

big5

german1

hungarian

czech

hp8

koi8_ukr

euc_kr

koi8_ru

win1251ukr

gb2312

latin2

greek

gbk

swe7

win1250

latin1_de

usa7

croat

sjis

cp1251

cp1257

tis620

danish

latin5

ujis

hebrew

 

dec8

win1251

 

You can see what character sets are available in your distribution by looking at the value of the character_sets variable.

When you change a character set, you’ll need to rebuild your indexes to ensure they sort according to the rules of the new character set.

By default, MySQL is compiled with –with-extra-charsets=complex, which makes the other character sets available if necessary. If you are compiling MySQL yourself, and you know you are never going to need other character sets, you can use the –with-extra-charsets=none option.

Adding Your Own Character Set

You can add your own character set as well. If it is a simple character set and does not need multibyte character support or string collating routines for sorting, adding it is easy. It becomes more complex if these extras are required. To add a character set, perform the following steps:

  1. Add the new character set to the sql/share/charsets/Index file, and give it a unique ID. The path may differ on some distributions, but it’ll always be the Index file. Here, you can call the new character set martian, with an ID of 31:

    # sql/share/charsets/Index
    #
    # This file lists all of the available character sets.
    
    big5               1
    czech              2
    dec8               3
    dos                4
    german1            5
    hp8                6
    koi8_ru            7
    latin1             8
    latin2             9
    swe7              10
    usa7              11
    ujis              12
    sjis              13
    cp1251            14
    danish            15
    hebrew            16
    # The win1251 character set is deprecated.  Please use cp1251 instead.
    win1251           17
    tis620            18
    euc_kr            19
    estonia           20
    hungarian         21
    koi8_ukr          22
    win1251ukr        23
    gb2312            24
    greek             25
    win1250           26
    croat             27
    gbk               28
    cp1257            29
    latin5            30
    martian           31
  2. Create the .conf and place it in the directory, for example, sql/share/charsets/martian.conf. Use one of the existing .conf files as a starting point for this.

    In the .conf file, lines beginning with a # are comments, words are separated by any amount of whitespace, and every word must be in hexadecimal format. There are four arrays. In order, they are ctype (containing 257 elements), to_lower and to_upper (each containing 256 elements), and sort_order (also containing 256 elements). The following is a sample .conf file (this is the standard latin1.conf):

    # Configuration file for the latin1 character set
    
    # ctype array (must have 257 elements)
      00
      20  20  20  20  20  20  20  20  20  28  28  28  28  28  20  20
      20  20  20  20  20  20  20  20  20  20  20  20  20  20  20  20
      48  10  10  10  10  10  10  10  10  10  10  10  10  10  10  10
      84  84  84  84  84  84  84  84  84  84  10  10  10  10  10  10
      10  81  81  81  81  81  81  01  01  01  01  01  01  01  01  01
      01  01  01  01  01  01  01  01  01  01  01  10  10  10  10  10
      10  82  82  82  82  82  82  02  02  02  02  02  02  02  02  02
      02  02  02  02  02  02  02  02  02  02  02  10  10  10  10  20
      00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      00  00  00  00  00  00  00  00  00  00  00  00  00  00  00  00
      48  10  10  10  10  10  10  10  10  10  10  10  10  10  10  10
      10  10  10  10  10  10  10  10  10  10  10  10  10  10  10  10
      01  01  01  01  01  01  01  01  01  01  01  01  01  01  01  01
      01  01  01  01  01  01  01  10  01  01  01  01  01  01  01  02
      02  02  02  02  02  02  02  02  02  02  02  02  02  02  02  02
      02  02  02  02  02  02  02  10  02  02  02  02  02  02  02  02
    
    # to_lower array (must have 256 elements)
      00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F
      10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F
      20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F
      30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F
      40  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F
      70  71  72  73  74  75  76  77  78  79  7A  5B  5C  5D  5E  5F
      60  61  62  63  64  65  66  67  68  69  6A  6B  6C  6D  6E  6F
      70  71  72  73  74  75  76  77  78  79  7A  7B  7C  7D  7E  7F
      80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F
      90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F
      A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF
      B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF
      E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF
      F0  F1  F2  F3  F4  F5  F6  D7  F8  F9  FA  FB  FC  FD  FE  DF
      E0  E1  E2  E3  E4  E5  E6  E7  E8  E9  EA  EB  EC  ED  EE  EF
      F0  F1  F2  F3  F4  F5  F6  F7  F8  F9  FA  FB  FC  FD  FE  FF
    
    # to_upper array (must have 256 elements)
      00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F
      10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F
      20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F
      30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F
      40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F
      50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F
      60  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F
      50  51  52  53  54  55  56  57  58  59  5A  7B  7C  7D  7E  7F
      80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F
      90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F
      A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF
      B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF
      C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF
      D0  D1  D2  D3  D4  D5  D6  D7  D8  D9  DA  DB  DC  DD  DE  DF
      C0  C1  C2  C3  C4  C5  C6  C7  C8  C9  CA  CB  CC  CD  CE  CF
      D0  D1  D2  D3  D4  D5  D6  F7  D8  D9  DA  DB  DC  DD  DE  FF
    
    # sort_order array (must have 256 elements)
      00  01  02  03  04  05  06  07  08  09  0A  0B  0C  0D  0E  0F
      10  11  12  13  14  15  16  17  18  19  1A  1B  1C  1D  1E  1F
      20  21  22  23  24  25  26  27  28  29  2A  2B  2C  2D  2E  2F
      30  31  32  33  34  35  36  37  38  39  3A  3B  3C  3D  3E  3F
      40  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F
      50  51  52  53  54  55  56  57  58  59  5A  5B  5C  5D  5E  5F
      60  41  42  43  44  45  46  47  48  49  4A  4B  4C  4D  4E  4F
      50  51  52  53  54  55  56  57  58  59  5A  7B  7C  7D  7E  7F
      80  81  82  83  84  85  86  87  88  89  8A  8B  8C  8D  8E  8F
      90  91  92  93  94  95  96  97  98  99  9A  9B  9C  9D  9E  9F
      A0  A1  A2  A3  A4  A5  A6  A7  A8  A9  AA  AB  AC  AD  AE  AF
      B0  B1  B2  B3  B4  B5  B6  B7  B8  B9  BA  BB  BC  BD  BE  BF
      41  41  41  41  5C  5B  5C  43  45  45  45  45  49  49  49  49
      44  4E  4F  4F  4F  4F  5D  D7  D8  55  55  55  59  59  DE  DF
      41  41  41  41  5C  5B  5C  43  45  45  45  45  49  49  49  49
      44  4E  4F  4F  4F  4F  5D  F7  D8  55  55  55  59  59  DE  FF

    The ctype array contains bit values, with one element for one character. The to_lower and to_upper arrays simply hold the uppercase and lowercase characters that correspond to each member of the character set. For example, to_lower['A'] contains a, while to_upper['z'] contains Z.

    The sort_order array indicates the order that characters are to be sorted (it usually corresponds to to_upper, in which case the sorting will be case insensitive. All of the arrays are indexed by character value, except ctype, which is indexed by character value + 1 (an old legacy).

  3. Add the new character set (martian.conf) to the CHARSETS_AVAILABLE and COMPILED_CHARSETS lists in the file configure.in.

  4. Reconfigure and recompile MySQL, and test the new character set.

If you’re brave enough to tackle adding a new complex character set, there are a few more steps to this process. See the MySQL documentation for what is required (as well as the documentation in the existing complex character sets: czech, gbk, sjis, and tis160).

Summary

To understand how to get the most out of your database server, it’s important to understand the number of options you have when fine-tuning the server. To see how an existing server has been set up, use the SHOW VARIABLES statement, as well as SHOW STATUS to see how it’s been handling. The output of these two statements can reveal many hidden problems, including queries that are not optimized, poor use of available memory, or simply that it’s time for an upgrade.

MySQL supplies four configuration files that can help to get better performance from the server. Just choose the closest of my-huge.cnf, my-large.cnf, my-medium.cnf or my-small.cnf for your server situation.

Two of the easiest and most important variables to tweak are table_cache (the number of tables MySQL can keep open) and the key_buffer_size (how much of the indexes MySQL can keep in memory, minimizing disk access).

InnoDB databases have their own vagaries and work in a fundamentally different way than MyISAM tables, where each table is related to specific files. InnoDB configuration requires careful planning because disk space is allocated in advance.

Hardware too can be an easy way of improving the performance of a server, with memory, CPU, and disks being of primary importance.

MySQL comes with a benchmark suite, which can be used to compare the performance of various platforms, including other databases.

MySQL was developed in Scandinavia and has had good support for other languages besides English. It is easy to display error messages in other languages or add a character set.

Tagged with:
Aug 04

A regular part of a database administrator’s job is to do preventative maintenance, as well as to repair things when they go wrong. In spite of the best efforts, data errors can occur, such as in the case of a power failure that interrupts a write. Usually you can correct these fairly painlessly.

There are four main tasks involved in checking and repairing:

  • Optimizing tables

  • Analyzing tables (analyzes and stores the key distribution for MyISAM and BDB tables)

  • Checking tables (checks the tables for errors, and, for MyISAM tables, updates the key statistics)

  • Repairing tables (repairs corrupted MyISAM tables)

Optimizing Tables

Tables that contain BLOB and VARCHAR fields will, over time, become less optimized. Because these field types are variable in length, when records are updated, inserted, or deleted, they will not always take the same amount of space, the records will start to become fragmented, and empty spaces will remain. Just like with a fragmented disk, this situation will slow performance, so to keep MySQL in tiptop shape, you should regularly defragment it. The way to do this is to optimize the table, which can be done in a number of ways. There’s the OPTIMIZE TABLE statement, the mysqlcheck utility (if the server is running), or the myisamchk utility (if the server is not running or there is no interaction with the table).

Optimizing currently works only with MyISAM and partially with BDB tables. With MyISAM tables, optimizing does the following:

  • Defragments tables where rows are split or have been deleted

  • Sorts the indexes if they have not been already

  • Updates the index statistics if they have not been already

With BDB tables, optimizing analyzes the key distribution (the same as ANALYZE TABLE; see the "Analyzing Tables with ANALYZE TABLE" section later in this chapter).

Optimizing Tables with the OPTIMIZE Statement

The OPTIMIZE statement is a SQL statement used when connected to a MySQL database. The syntax is as follows:

OPTIMIZE TABLE tablename

You can also optimize many tables at once, separating each with a comma:

mysql> OPTIMIZE TABLE customer,sales;
+------------------+----------+----------+-----------------------------+
| Table            | Op       | Msg_type | Msg_text                    |
+------------------+----------+----------+-----------------------------+
| firstdb.customer | optimize | status   | Table is already up to date |
| firstdb.sales    | optimize | status   | OK                          |
+------------------+----------+----------+-----------------------------+
2 rows in set (0.02 sec)

The customer table in this instance has already been optimized.

Optimizing Tables with mysqlcheck

mysqlcheck is a command-line utility that can perform numerous checking and repairing tasks besides optimization. A full description of all the mysqlcheck features follows later in the chapter in the section titled "Using mysqlcheck." The server must be running for you to use mysqlcheck. To optimize the customer table from the firstdb database, use the -o mysqlcheck option, as follows:

% mysqlcheck -o firstdb customer  -uroot -pg00r002b
firstdb.customer           Table is already up to date

mysqlcheck allows you to optimize more than one table at a time by listing all the tables after the database name:

% mysqlcheck -o firstdb customer sales  -uroot -pg00r002b
firstdb.customer           Table is already up to date
firstdb.sales              Table is already up to date

You could also optimize the entire database by leaving out any table references, with the following:

% mysqlcheck -o firstdb -uroot -pg00r002b

Optimizing Tables with myisamchk

Finally, you can use the myisamchk command-line utility when the server is down or not interacting with the server. (Flush the tables before running this statement if the server is up with mysqladmin flush-tables. You still need to make sure the server is not interacting with the table, though, or else corruption may result.) This is the oldest way of checking tables. You have to run myisamchk from the exact location of the table or specify the path leading to the table. A full description of all the myisamchk features follows later in this chapter in the section titled "Using myisamchk."

The equivalent of an optimize statement is as follows:

myisamchk --quick --check-only-changed --sort-index --analyze tablename

or as follows:

myisamchk -q -C -S -a tablename

For example:

% myisamchk --quick --check-only-changed --sort-index --analyze customer
- check key delete-chain
- check record delete-chain
- Sorting index for MyISAM-table 'customer'

The -r option repairs the table, but also eliminates wasted space:

% myisamchk -r sales   
- recovering (with sort) MyISAM-table 'sales'
Data records: 8
- Fixing index 1
- Fixing index 2

If you do not specify the path to the table index file, and you’re not in the right directory, you’ll get the following error:

% myisamchk -r customer
myisamchk: error: File 'customer' doesn't exist

Specifying the full path to the .MYI file corrects this:

% myisamchk -r /usr/local/mysql/data/firstdb/customer
- recovering (with keycache) MyISAM-table '/usr/local/mysql/data/firstdb/customer'
Data records: 0

Warning

Tables are locked during the optimization, so don’t run this during peak hours! Also, make sure you have a reasonable amount of free space on the system when running OPTIMIZE TABLE. If you try to run it when your system has almost or already run out of disk space, MySQL may not be able to complete the optimization, leaving your table unusable.

Optimizing is an important part of any administrative routine for databases that contain MyISAM tables and should be performed regularly.

Analyzing Tables

Analyzing tables improves performance by updating the index information for a table so that MySQL can make a better decision on how to join tables. The distribution of the various index elements is stored for later usage. (Analyzing currently only works with MyISAM and BDB tables.)

There are three ways to analyze a table:

  • When connected to MySQL, with the ANALYZE TABLE statement

  • With the mysqlcheck command-line utility

  • With the myisamcheck command-line utility

Regular analysis of tables can help performance and should be a regular part of any maintenance routine.

Analyzing Tables with ANALYZE TABLE

ANALYZE TABLE is a statement used when connected to a database on the server. The syntax is as follows:

ANALYZE TABLE tablename

For example:

mysql> ANALYZE TABLE sales;
+---------------+---------+----------+----------+
| Table         | Op      | Msg_type | Msg_text |
+---------------+---------+----------+----------+
| firstdb.sales | analyze | status   | OK       |
+---------------+---------+----------+----------+
1 row in set (0.00 sec)

The Msg_type (message type) is one of status, error, info, or warning. Here’s what would happen if the index file was missing altogether and you tried to analyze the table:

mysql> ANALYZE TABLE zz;
+------------+---------+----------+----------------------------------+
| Table      | Op      | Msg_type | Msg_text                         |
+------------+---------+----------+----------------------------------+
| firstdb.zz | analyze | error    | Table 'firstdb.zz' doesn't exist |
+------------+---------+----------+----------------------------------+
1 row in set (0.00 sec)

The table will only be analyzed again if it has changed since the last time it was analyzed:

mysql> ANALYZE TABLE sales;
+---------------+---------+----------+-----------------------------+
| Table         | Op      | Msg_type | Msg_text                    |
+---------------+---------+----------+-----------------------------+
| firstdb.sales | analyze | status   | Table is already up to date |
+---------------+---------+----------+-----------------------------+
1 row in set (0.00 sec)
Analyzing Tables with mysqlcheck

The mysqlcheck command-line utility is discussed fully later in this chapter in the section titled "Using mysqlcheck." The server needs to be running for you to use mysqlcheck, and it works only with MyISAM tables. To use it to analyze tables, you use the -a option:

% mysqlcheck -a firstdb sales -uroot -pg00r002b
firstdb.sales                                      OK

You can also analyze more than one table from a database by listing the tables after the database name:

% mysqlcheck -a firstdb sales customer -uroot -pg00r002b
firstdb.sales                 Table is already up to date
firstdb.customer              Table is already up to date

If you tried to analyze a table that does not support analysis (such as an InnoDB table), no harm would be done and the operation would just fail. For example:

% mysqlcheck -a firstdb innotest -uroot -pg00r002b
firstdb.innotest
error    : The handler for the table doesn't support check/repair

You could also analyze all tables in the database with by leaving out any table names:

% mysqlcheck -a firstdb innotest -uroot -pg00r002b

Analyzing Tables with myisamchk

The myisamchk command-line utility is discussed fully later in this chapter in the section titled "Using myisamchk." The server should either not be running, or you must be sure that there is no interaction with the tables with which you’re working. If the –skip-external-locking option is not on, you can safely use myisamchk to analyze tables, even if the server is running. The tables will be locked, affecting access, but there will be no erroneous reports. If –skip-external-locking is used, you’ll need to flush the tables before starting the analysis (with mysqladmin flush-tables) and ensure that there is no access. You may get invalid results if mysqld or anything else accesses the table while myisamchk is running. To analyze tables, use the -a option:

% myisamchk -a /usr/local/mysql/data/firstdb/sales   
Checking MyISAM file: /usr/local/mysql/data/firstdb/sales
Data records:       9   Deleted blocks:       0
- check file-size
- check key delete-chain
- check record delete-chain
- check index reference
- check data record references index: 1
- check data record references index: 2

Checking Tables

Errors can occur when the indexes are not synchronized with the data. System crashes or power failures can all cause situations where the tables have become corrupted. Corruption of the data is fairly rare; in most cases, the corruption is of the index files. These can be hard to spot, though you may notice information being returned slowly or data not being found that should be there. Checking tables should be the first thing you do when you suspect an error. Some of the symptoms of corrupted tables include errors such as the following:

  • Unexpected end of file.

  • Record file is crashed.

  • tablename.frm is locked against change.

  • Can’t find file tablename.MYI (Errcode: ###).

  • Got error ### from table handler. The perror utility gives more information about the error number. Just run perror (which is stored in the same directory as the other binaries such as mysqladmin) and the error number. For example:

    % perror 126
    126 = Index file is crashed / Wrong file format

Some of the other more common errors include:

126 = Index file is crashed / Wrong file format
127 = Record-file is crashed
132 = Old database file
134 = Record was already deleted (or record file crashed)
135 = No more room in record file
136 = No more room in index file
141 = Duplicate unique key or constraint on write or update
144 = Table is crashed and last repair failed
145 = Table was marked as crashed and should be repaired

Once connected to the MySQL server, you can issue a CHECK TABLE command, make use of the mysqlcheck utility (when the server is running), or use the myisamchk utility when the server has been stopped. Checking updates the index statistics and checks for errors.

If any errors are found, the table will need to be repaired (see the "Repairing Tables" section later in this chapter). Serious errors mark the table as corrupt, in which case it can no longer be used until it is repaired.

Tip

Always check tables after a power failure or a system crash. You can usually fix any corruption that has occurred before users notice any problems.

Checking Tables with CHECK TABLES

The syntax for CHECK TABLE is as follows:

CHECK TABLE tablename [option]

For example:

mysql> CHECK TABLE customer;
+------------------+-------+----------+----------+
| Table            | Op    | Msg_type | Msg_text |
+------------------+-------+----------+----------+
| firstdb.customer | check | status   | OK       |
+------------------+-------+----------+----------+
1 row in set (0.01 sec)

CHECK can check only MyISAM and InnoDB tables.

There are five options depending on the level of checking you want to do, as shown in Table 4

Table 4: CHECK TABLE Options

Option

Description

QUICK

This is the quickest check and does not scan the rows to check for wrong links.

FAST

Only checks tables that haven’t been closed properly.

CHANGED

Only checks tables that haven’t been closed properly or have been changed since last check.

MEDIUM

The default option. It scans rows to check that deleted links are correct. It also calculates a key checksum for the rows and verifies this with a calculated checksum for the keys.

EXTENDED

This is the slowest method, but it checks the table for complete consistency by doing a full key lookup for every index associated with each row.

 

The QUICK option is useful for checking tables where you don’t suspect any errors.

If an error or warning is returned, you should try and repair the table.

You can check more than one table at a time by listing the tables one after another,

for example:

mysql> CHECK TABLE sales,customer;
+------------------+-------+----------+----------+
| Table            | Op    | Msg_type | Msg_text |
+------------------+-------+----------+----------+
| firstdb.sales    | check | status   | OK       |
| firstdb.customer | check | status   | OK       |
+------------------+-------+----------+----------+
2 rows in set (0.01 sec)

Checking Tables with mysqlcheck

The mysqlcheck command-line utility can be used when the server is running and works only with MyISAM tables. It is described fully later in this chapter in the section titled "Using mysqlcheck." Table 5 lists the options.

The syntax is as follows:

mysqlcheck [options] databasename tablename[s]

For example:

% mysqlcheck -c firstdb customer -uroot -pg00r002b
firstdb.customer                               OK

Table 5: The mysqlcheck Options That Apply to Table Checking

Option

Description

–auto-repair

Used in conjunction with one of the check options, it will automatically beginto repair corrupted tables after the checks have completed.

-c, –check

Checks tables.

-C, –check-only-changed

Checks tables that have changed since the last check or were not closed properly.

-F, –fast

Checks tables that haven’t been closed properly.

-e, –extended

This is the slowest form for checking, but it will make sure the table is completely consistent. You can also use this option to repair, though itisusually not necessary.

-m, –medium-check

This is much faster than the extended check, and it finds the vast majority oferrors.

-q, –quick

The fastest check, this does not check table rows when checking. When repairing, it only repairs the index tree.

 

You can check more than one table by listing a number of tables after the database name:

% mysqlcheck -c firstdb sales customer -uroot -pg00r002b
firstdb.sales                                      OK
firstdb.customer                                   OK

You can check all tables in the database by just specifying the name of the database.

% mysqlcheck -c firstdb -uroot -pg00r002b

Checking Tables with myisamchk

When the server is shut down or there is no interaction with the tables you’re checking, you can use the myisamchk command-line option (described fully in the "Using myisamchk" section later in this chapter). If the –skip-external-locking option is not on, you can safely use myisamchk to check tables, even if the server is running. The tables will be locked, affecting access, but there will be no erroneous reports. If –skip-external-locking is used, you’ll need to flush the tables before starting the check (with mysqladmin flush-tables) and ensure that there is no access. You may get wrong results (with tables being marked as corrupted even when they are not) if mysqld or anything else accesses the table while myisamchk is running.

The syntax is as follows:

mysiamchk [options] tablename

The equivalent to the CHECK TABLE statement is the medium option:

myisamchk -m table_name 

The default for myisamchk is the ordinary check option (-c). There is also the fast check (-F), which only checks tables that haven’t been closed properly. This is not the same as the lowercase -f option, which is the force option, meaning the check continues even if errors occur. There is also the medium check (-m), slightly slower and more complete. The most extreme option is the -e option (that performs an extended check), which is the most thorough and slowest option. It’s also usually a sign of desperation; use this only when all other options have failed. Increasing the key_buffer_size variable can speed up the extended check (if you have enough memory). See Table 6 for the checking options.

Table 6: myisamchk Checking Options

Option

Description

-c, –check

Ordinary check and the default option.

-e, –extend-check

Slowest and most thorough form of check. If you are using –extended-check and have much memory, you should increase the value of key_buffer_size a lot!

-F, –fast

Fast check, which only checks tables that haven’t been closed properly.

-C, –check-only-changed

Checks only the tables that have been changed since the last check.

-f, –force

This runs the repair option if any errors are found in the table.

-i, –information

Displays statistics about the table that is checked.

-m, –medium-check

Medium check, faster than an extended check, and good enough for most cases.

-U, –update-state

Keeps information about when the table was checked and whether the table has crashed, which is useful for the -C option. Should not be used when the table is being used and the –skip-external-locking option is active.

-T, –read-only

Does not mark the table as checked (useful for running myisamchk when the server is active and the –skip-external-locking option is in use).

 

The following is a sample myisamchk output when errors are found:

% myisamchk largetable.MYI
Checking MyISAM file: Hits.MYI
Data records: 2960032   Deleted blocks:       0
myisamchk: warning: 1 clients is using or hasn't closed the table
properly
- check file-size
myisamchk: warning: Size of datafile is: 469968400 Should be: 469909252
- check key delete-chain
- check record delete-chain
- check index reference
- check data record references index: 1
- check data record references index: 2
- check data record references index: 3
myisamchk: error: Found 2959989 keys of 2960032
- check record links
myisamchk: error: Record-count is not ok; is 2960394 Should be: 2960032
myisamchk: warning: Found    2960394 parts   Should be: 2960032 parts

Repairing Tables

If you have checked the tables and errors have been found, you’ll need to repair them. There are various repair options available, depending on which method you use, but you may not have success. If the disk has failed, or if none of them work, the only option is to restore from your backup. Repairing a table can take up significant resources, both disk and memory:

  • Generally, repairing a table takes up twice as much disk space as the original data file (on the same disk). A quick repair (see the options in the following sections) is an exception because the data file is not modified.

  • Some space for the new index file (on the same disk as the original). The old index is deleted at the start, so this is usually not significant, but it will be if the disk is close to full.

  • With the standard and –sort-recover options, a sort buffer is created. This takes up the following amount of space (largest_key + row_pointer_length) * number_of_rows * 2. You can move some or all of this to memory (and increase the speed of the process) by increasing the size of the mysqld variable sort_buffer_size if you have the available memory. Otherwise, it is created as specified by the TMPDIR environment variable or the -t myisamchk option.

  • Memory usage is determined by the mysqld variables or the options set in the myisamchk command line (see the section titled "Using myisamchk").

If the error is caused by the table running out of space and the table type is InnoDB, you will have to enlarge the InnoDB tablespace. MyISAM tables have a huge theoretical size limit (eight million terabytes), but by default pointers are only allocated for 4GB. If the table reaches this limit, you can extend it by using the MAX_ROWS and AVG_ROW_LENGTH ALTER TABLE parameters. To prepare the table called limited for great things (currently it only has three records), you use the following:

mysql> ALTER TABLE limited MAX_ROWS=999999999999 AVG_ROW_LENGTH=100;
Query OK, 3 rows affected (0.28 sec)
Records: 3  Duplicates: 0  Warnings: 0

This allocates pointers for a much greater number of records. The AVG_ROW_LENGTH is used when BLOB and TEXT fields are present, and it gives MySQL an idea of the average size of a record, which it can then use for optimization purposes.

Repairing Non-MyISAM Table Types

The three methods of repairing discussed in the following sections work only with MyISAM tables. Some of the options have been reported to work occasionally with BDB tables, but they were not designed for this. Currently, the only way to repair corrupted BDB and InnoDB tables is to restore from backup.

Repairing Tables with REPAIR TABLE

You can run the REPAIR TABLE statement when connected to the MySQL server. It currently only works with MyISAM tables. See Table 7 for the options.

The syntax is as follows:

Table 10: Available REPAIR TABLE Options

Option

Description

QUICK

Fastest repair because the data file is not modified. It uses much less disk space as well because the data file is not modified.

EXTENDED

Attempts to recover every possible row from the data file. This option should not be used unless as a last resort because it may produce garbage rows.

USE_FRM

This is the option to use if the .MYI file is missing or has a corrupted header. It will rebuild the indexes from the definitions found in the .frm table definition file.

 

The following is an example of using REPAIR in the case of a missing .MYI file. Let’s delete the .MYI file of an existing table, t4.

% ls -l t4.*
-rw-rw----  1 mysql  mysql    10 Jun 14 02:00 t4.MYD
-rw-rw----  1 mysql  mysql  4096 Jun 14 02:00 t4.MYI
-rw-rw----  1 mysql  mysql  8550 Jun  8 10:46 t4.frm
% rm t4.MYI
% mysql -uguru2b -pg00r002b firstdb

A normal REPAIR does not work:

mysql> REPAIR TABLE t4;
+------------+--------+----------+--------------------------------------+
| Table      | Op     | Msg_type | Msg_text                             |
+------------+--------+----------+--------------------------------------+
| firstdb.t4 | repair | error    | Can't find file: 't4.MYD' (errno: 2) |
+------------+--------+----------+--------------------------------------+
1 row in set (0.47 sec)

The current error message (4.0.3) indicates that the .MYD file cannot be found, when it’s actually the .MYI file that’s missing. The error message is likely to have been clarified by the time you read this. To repair the table in this instance, you need to use the USE_FRM option, which, as the name suggests, uses the .frm definition file to re-create the .MYI index file:

mysql> REPAIR TABLE t4 USE_FRM;
+------------+--------+----------+------------------------------------+
| Table      | Op     | Msg_type | Msg_text                           |
+------------+--------+----------+------------------------------------+
| firstdb.t4 | repair | warning  | Number of rows changed from 0 to 2 |
| firstdb.t4 | repair | status   | OK                                 |
+------------+--------+----------+------------------------------------+
2 rows in set (0.46 sec)

Repairing Tables with mysqlcheck

The mysqlcheck command-line utility is used while the server is still running and works only with MyISAM tables. It is described fully later in this chapter in the "Using mysqlcheck" section. To repair tables, you use the -r option:

% mysqlcheck -r firstdb customer -uroot -pg00r002b
firstdb.customer                                   OK

You can repair multiple tables at the same time by listing the table names after the

database name:

% mysqlcheck -r firstdb customer sales -uroot -pg00r002b
firstdb.customer                                   OK
firstdb.sales                                      OK

If for some reason all tables in a database are corrupt, you can repair them all by just supplying the database name:

% mysqlcheck -r firstdb -uroot -pg00r002b
Repairing Tables with myisamchk

You can use the myisamchk command-line utility (described fully later in this chapter in the "Using myisamchk" section) repair tables (see Table 10.8).

Table 8: Repairing Tables with myisamchk

Option

Description

-D #, –data-file-length=#

Specifies the maximum length of the data file when re-creating it.

-e, –extend-check

Attempts to recover every possible row from the data file. This option should not be used unless as a last resort because it may produce garbage rows.

-f, –force

Overwrites old temporary files (that have an extension of .TMD) instead of aborting if it encounters a preexisting one.

-k #, keys-used=#

Specifies which keys to use, which can make the process faster. Each binary bit stands for one key starting at 0 for the first key.

-r, –recover

Repairs most corruption and should be the first option attempted. You can increase thesort_buffer_size to make the recovery go more quickly if you have the memory. This option will not recover from the rare form of corruption where a unique key is not unique.

-o, –safe-recover

A more thorough, yet slower repair option than -r that should be used only if -r fails. This reads through all rows and rebuilds the indexes based on the rows. It also uses less disk space than -r because a sort buffer is not created. You can increase the size of key_ buffer_size to improve repair speed.

-n, –sort-recover

Forces MySQL to use sorting to resolve the indexes, even if the resulting temporary files are large.

–character-sets-dir=…

The directory containing the character sets.

–set-character-set=name

Specifies a new character set for the index.

-t, –tmpdir=path

Specifies a new path for storing temporary files if you don’t want to use whatever the TMPDIR environment variable specifies.

-q, –quick

Fastest repair because the data file is not modified. Specifying the q twice (-q -q) will modify the data file if there are duplicate keys. Uses much less disk space as well because the data file is not modified.

-u, –unpack

Unpacks a file that has been packed with the myisampack utility.

 

The server should either not be running, or you must be sure there is no interaction with the tables with which you’re working, such as when you start MySQL with the –skip-external-locking option. If the –skip-external-locking option is not on, you can only safely use myisamchk to repair tables if you are sure there will be no simultaneous access. Whether –skip-external-locking is used or not, you’ll need to flush the tables before starting the repair (with mysqladmin flush-tables) and ensure that there is no access. You may get wrong results (with tables being marked as corrupted even when they are not) if mysqld or anything else accesses the table while myisamchk is running.

The syntax is as follows:

myisamchk [options] [tablenames]

You must run myisamchk from the directory containing the .MYI files or supply the path. The following examples show a repair in action, with MySQL deciding whether to use sorting or a keycache:

% myisamchk -r customer
- recovering (with keycache) MyISAM-table 'customer.MYI'
Data records: 0
% myisamchk -r sales   
- recovering (with sort) MyISAM-table 'sales.MYI'
Data records: 9
- Fixing index 1
- Fixing index 2

If you have lots of memory, besides increasing the size of sort_buffer_size and key_buffer_size as described previously, you can also set some other variables to make myisamchk perform more snappily. See the full myisamchk description later in this chapter in the "Using myisamchk" section.

Using mysqlcheck

The mysqlcheck utility is a boon to more recent users of MySQL because, beforehand, much of the repairing and checking functionality could only be used when the server was shut down. Luckily this limitation is a thing of the past with the mysqlcheck utility.

mysqlcheck uses the CHECK, REPAIR, ANALYZE, and OPTIMIZE statements to perform these tasks from the command line, which is useful for automated maintenance of your databases (see Table 9).

The syntax is as follows:

mysqlcheck [options] databasename [tablenames]

or as follows:

mysqlcheck [options] --databases databasename1 [databasename2 databasename 3 ...]

or as follows:


Table 9: Mysqlcheck Options

Option

Description

-A, –all-databases

Checks all available databases.

-1, –all-in-1

Combines queries for tables into one query per database (instead of one per table). Tables are in a comma-separated list.

-a, –analyze

Analyzes the listed tables.

–auto-repair

Automatically repairs tables if they are corrupted (after all tables in the query have been checked).

-#, –debug=…

Outputs a debug log.

–character-sets-dir=…

This specifies the directory where the character sets are.

-c, –check

Checks tables.

-C, –check-only-changed

Checks tables that have changed since the last check or were not closed properly.

–compress

Uses compression in the client/server protocol.

-?, –help

Displays the help message and exits.

-B, –databases

Lists a number of databases to check (all tables in the databases are checked).

–default-character-set=…

Sets the default character set.

-F, –fast

Checks tables that haven’t been closed properly.

-f, –force

Forces the process to continue even if it encounters an error.

-e, –extended

This is the slowest form for checking but will make sure the table is completely consistent. You can also use this option to repair, though it is usually not necessary.

-h, –host=…

Hostname to which to connect.

-m, –medium-check

Much faster than the extended check and finds the vast majority of errors.

-o, –optimize

Optimizes the tables.

-p, –password[=...]

The password with which to connect.

-P, –port=…

The port to use for connecting.

-q, –quick

The fastest check, this does not check table rows when checking. When repairing, it only repairs the index tree.

-r, –repair

Repairs most errors, except unique keys that somehow contain duplicates.

-s, –silent

Displays no output except for error messages.

-S, –socket=…

Specifies the socket file to use when connecting.

–tables

List of tables to check. With the -B option, this will take precedence.

-u, –user=#

Specifies the user to connect as.

-v, –verbose

Prints lots of output about the process.

-V, –version

Displays the version information and exits.

The mysqlcheck utility also has a feature that allows it to be run in different ways without specifying the options. By simply creating a copy of mysqlcheck with one of the following names, it will take that default behavior:

  • mysqlrepair: The default option is -r.

  • mysqlanalyze: The default option is -a.

  • mysqloptimize: The default option is -o.

The default option when it is named mysqlcheck is -c. All of these renamed files can have the full mysqlcheck functionality—it’s just that their default behavior is changed.

Using myisamchk

The myisamchk utility is the older utility, available since the early days of MySQL. It is also used to analyze, check, and repair tables, but care needs to be taken if you want to use it when the server is running. Table 10 describes the general myisamchk options, Table 11 describes the check options, Table 12 describes the repair options, and Table 13 describes other options.

The server should either not be running, or you must be sure there is no interaction with the tables with which you’re working, such as when you start MySQL with the –skip-external-locking option. If the –skip-external-locking option is not on, you can only safely use myisamchk to repair tables if you are sure there will be no simultaneous access. Whether or not –skip-external-locking is used, you’ll need to flush the tables before starting the repair (with mysqladmin flush-tables) and ensure that there is no access.

I suggest you rather use one of the other options if the server is running.

The syntax is as follows:

myisamchk [options] tablename[s]

You must run myisamchk from the directory where the .MYI index files are located unless you specify the path to them; otherwise you’ll get the following error:

% myisamchk -r sales.MYI
myisamchk: error: File 'sales.MYI' doesn't exist

Specifying the path solves the problem:

% myisamchk -r /usr/local/mysql/data/firstdb/sales.MYI
- recovering (with sort) MyISAM-table '/usr/local/mysql/data/firstdb/sales.MYI'
Data records: 9
- Fixing index 1
- Fixing index 2

The table name can be specified with or without the .MYI extension.

% myisamchk -r sales
- recovering (with sort) MyISAM-table 'sales'
Data records: 9
- Fixing index 1
- Fixing index 2
% myisamchk -r sales.MYI
- recovering (with sort) MyISAM-table 'sales.MYI'
Data records: 9
- Fixing index 1
- Fixing index 2

Warning

A common mistake is to try run myisamchk on an .MYD data file. Always use the .MYI index file!

You can use wildcard character to search all tables in a database directory (*.MYI) or even all tables in all databases:

Table 10: General myisamchk Options

Option

Description

-#, –debug=debug_options

Outputs a debug log. A common debug_option string is d:t:o,filename.

-?, –help

Displays a help message and exits.

-O var=option, –set-variable var=option

Sets the value of a variable. The possible variables and their default values for myisamchk can be examined with myisamchk –help.

-s, –silent

Only outputs error messages. A second s can be used to completely silence myisamchk.

-v, –verbose

Displays more information than usual. As with silent, multiple v’s can be used to output more information (-vv or -vvv).

-V, –version

Displays the myisamchk version details and exits.

-w, –wait

If the table is locked, -w will wait for the table to be unlocked rather than exiting with an error. If mysqld was running with the –skip-external-locking option, the table can only be locked by another myisamchk command.

 

By running myisamchk –help, besides the general options, you can see what variables you can change with the -O option and what the current settings are:

% myisamchk --help
..
Possible variables for option --set-variable (-O) are:
key_buffer_size       current value: 520192
myisam_block_size     current value: 1024
read_buffer_size      current value: 262136
write_buffer_size     current value: 262136
sort_buffer_size      current value: 2097144
sort_key_blocks       current value: 16
decode_bits           current value: 9
ft_min_word_len       current value: 4
ft_max_word_len       current value: 254
ft_max_word_len_for_sort  current value: 20

The space allocated by the key_buffer_size is used when doing an extended check or when indexes are inserted one row at a time (using the safe-recover option). sort_buffer_size is used in the default repair, when indexes are sorted in the repair.

To achieve a faster repair, set the sort_buffer_size to about one-quarter of the total available memory. Only one of the two variables is used at a time, so you don’t need to worry about running out of memory by making both values large.

Note

Inside the my.cnf (or my.ini) file, there are separate sections for mysqld and myisamchk. You can quite easily set the sort_buffer_size to a high value for repairing, and keep it lower if your system has other requirements for day-to-day running.


Table 11: myisamchk Check Options

Option

Description

-c, –check

Ordinary check and the default option.

-e, –extend-check

Slowest and most thorough form of check. If you are using –extended-check and don’t have much memory, you should increase the value of key_buffer_size a lot!

-F, –fast

Fast check that only checks tables that haven’t been closed properly.

-C, –check-only-changed

Checks only the tables that have been changed since the last check.

-f, –force

This runs the repair option if any errors are found in the table.

-i, –information

Displays statistics about the table that is checked.

-m, –medium-check

Medium check, faster than an extended check and good enough for most cases.

-U, –update-state

Keeps information about when the table was checked and whether the table has crashed, which is useful for the -C option. Should not be used when the table is being used and the –skip-external-locking option is active.

-T, –read-only

Does not mark the table as checked (useful for running myisamchk when the server is active and the –skip-external-locking option is in use).

Table 12: myisamchk Repair Options

Option

Description

-D #, –data-file-length=#

Specifies the maximum length of the data file when re-creating it.

-e, –extend-check

Attempts to recover every possible row from the data file. This option should not be used unless as a last resort because it may produce garbage rows.

-f, –force

Overwrites old temporary files (that have an extension of .TMD) instead of aborting if it encounters a preexisting one.

-k #, keys-used=#

Specifies the keys to use, which can make the process faster. Each binary bit stands for one key starting at 0 for the first key (for example, 1 is the first index, 10 is the second index).

-r, –recover

Repairs most corruption and should be the first option attempted. You can increase the sort_buffer_size to make the recover go more quickly if you have the memory. This option will not recover from the rare form of corruption where a unique key is not unique.

-o, –safe-recover

A more thorough, slower repair option than -r, which should be used only if -r fails. This reads through all rows and rebuilds the indexes based on the rows. It also uses less disk space than -r because a sort buffer is not created. You can increase the size of key_ buffer_size to improve repair speed.

-n, –sort-recover

Forces MySQL to uses sorting to resolve the indexes, even if the resulting temporary files are large.

–character-sets-dir=…

The directory containing the character sets.

–set-character-set=name

Specifies a new character set for the index.

-t, –tmpdir=path

Specifies a new path for storing temporary files if you don’t want to use the contents of the TMPDIR environment variable.

-q, –quick

Fastest repair as the data file is not modified. Running this option a second time will modify the data file if there are duplicate keys. Uses much less disk space as well because the data file is not modified.

-u, –unpack

Unpacks a file that has been packed with the myisampack utility.

Table 13: Other myisamchk Options

Option

Description

-a, –analyze

Analyzing tables improves performance by updating the index information for atable so that MySQL can make a better decision on how to join tables. The distribution of the various index elements is stored for later usage. This option isthe same as ANALYZE TABLE.

-d, –description

Displays a description of the table.

-A, –set-auto-increment[=value]

Sets the AUTO_INCREMENT counter to the specified value (or increments it by one if no value is supplied).

-S, –sort-index

Sorts the index tree blocks in descending order, which improves the performance of seeks and table scanning by key.

-R, –sort-records=#

Sorts records according to the index specified (index numbers begin from 1; you can use SHOW INDEX to see an ordered list). This can speed up queries that are ordered on this index, as well as ranged selects. It will probably be very slow if you sort a large table for the first time.

Running myisamchk with the -d option produces the following kind of output:

% myisamchk -d customer
MyISAM file:         customer
Record format:       Packed
Character set:       latin1 (8)
Data records:        3  Deleted blocks:                 0
Recordlength:        75
table description:
Key Start Len Index   Type
1      2         4      unique   long
Tagged with:
Aug 02

MySQL distributions come with a benchmark suite called run-all-tests. You can use it to test various DBMSs to see how well they perform. To use it, you need to have Perl, the Perl DBI module, and the DBD module for the DBMS you want to test. Table 1 explains the options for run-all-tests.


Table 1: Options for run-all-tests
Option Description
--comments Adds a comment to the benchmark output.
--cmp=server[,server...] Runs the test with limits from the specified servers. By running all servers with the same --cmp, the test results will be comparable between the different SQL servers.
--create-options=# Specifies an extra argument to all create statements. For example, to create all tables as BDB tables, you would use --create-options=TYPE=BDB.
--database Specifies the database in which the test tables are created. The default is the test database.
--debug Displays debugging information. You normally only use this when debugging a test.
--dir Indicates where the test results should be stored. The default is the defaultoutput.
--fast Allows the use of nonstandard ANSI SQL commands to make the test gofaster.
--fast-insert Uses fast inserts where possible, which include multiple value lists, such as INSERT INTO tablename VALUES (values),(values) or simply INSERT INTO tablename VALUES (values) rather than INSERT INTO tablename(fields) VALUES (values).
--field-count Specifies how many fields there are to be in the test table. Usually only used when debugging a test.
--force Continues the test even when encountering an error. Deletes tables before creating new ones. Usually only used when debugging a test.
--groups Indicates how many different groups there are to be in the test. Usually only used when debugging a test.
--lock-tables Allows the use of table locking to get more speed.
--log Saves the results to the --dir directory.
--loop-count (Default) Indicates how many times each test loop is to be executed. Usually only used when debugging a test.
--help Displays a list of options.
--host='host name' Specifies the host where the database server is located. The default islocalhost.
--machine="machine or os_name" The machine/operating system name that is added to the benchmark output filename. The default is the operating system name + version.
--odbc Uses the DBI ODBC driver to connect to the database.
--password='password' Specifies the password for the user the test connects as.
--socket='socket' Specifies the socket to connect with (if sockets are supported).
--regions Specifies how AND levels should be tested. Usually only used when debugging a test.
--old-headers Gets the old benchmark headers from the old RUN- file.
--server='server name' Specifies which DBMS on which to run the test. These can include Access, Adabas, AdabasD, Empress, Oracle, Informix, DB2, mSQL, MS-SQL, MySQL, Pg, Solid, and Sybase. The default is MySQL.
--silent Does not output information about the server when the test starts.
--skip-delete Specifies that the test tables created are not deleted. Usually only used when debugging a test.
--skip-test=test1[,test2,...] Excludes the specified tests when running the benchmark.
--small-test Speeds up the tests by using smaller limits.
--small-tables Uses fewer rows to run the tests. This would be used if the database cannot handle large tables for some reason (they could have small partitions, forexample).
--suffix Adds a suffix to the database name in the benchmark output filename. Used when you want to run multiple tests without overwriting the results. When using the --fast option, the suffix is automatically _fast.
--random Generates random initial values for the sequence of test executions, which could be used to imitate real conditions.
--threads=# Specifies the number of threads to use for multiuser benchmarks. The default is 5.
--tcpip Use TCP/IP to connect to the server. This allows the test to do many new connections in a row as the TCP/IP stack can be filled.
--time-limit Specifies a time limit in seconds for a test loop before the test ends, and the result estimated. The default is 600 seconds.
--use-old-results Uses the old results from the --dir directory instead of actually running the tests.
--user='user_name' Specifies the user to connect as.
--verbose Displays more info. Usually only used when debugging a test.
--optimization='some comments' Adds comments about optimizations done before the test.
--hw='some comments' Adds comments about hardware used for this test.
% cd sql-bench % perl run-all-tests --small-test --password='g00r002b' Benchmark DBD suite: 2.14 Date of test: 2002-07-21 21:35:42 Running tests on: Linux 2.2.5-15 i686 Arguments: --small-test Comments: Limits from: Server version: MySQL 4.0.1 alpha max log Optimization: None Hardware: ATIS: Total time: 19 wallclock secs ( 5.23 usr 0.96 sys + 0.00 cusr 0.00 csys = 0.00 CPU) alter-table: Total time: 2 wallclock secs ( 0.12 usr 0.03 sys + 0.00 cusr 0.00 csys = 0.00 CPU) big-tables: Total time: 1 wallclock secs ( 0.43 usr 0.10 sys + 0.00 cusr 0.00 csys = 0.00 CPU) connect: Total time: 8 wallclock secs ( 2.90 usr 0.66 sys + 0.00 cusr 0.00 csys = 0.00 CPU) create: Total time: 0 wallclock secs ( 0.15 usr 0.01 sys + 0.00 cusr 0.00 csys = 0.00 CPU) insert: Total time: 31 wallclock secs ( 8.47 usr 1.43 sys + 0.00 cusr 0.00 csys = 0.00 CPU) select: Total time: 55 wallclock secs (17.76 usr 1.71 sys + 0.00 cusr 0.00 csys = 0.00 CPU) transactions: Test skipped because the database doesn't support transactions wisconsin: Total time: 42 wallclock secs ( 9.55 usr 1.84 sys + 0.00 cusr 0.00 csys = 0.00 CPU) All 9 test executed successfully Totals per operation: Operation seconds usr sys cpu tests alter_table_add 1.00 0.07 0.00 0.00 92 alter_table_drop 0.00 0.03 0.00 0.00 46 connect 0.00 0.22 0.02 0.00 100 connect+select_1_row 1.00 0.27 0.04 0.00 100 connect+select_simple 1.00 0.27 0.04 0.00 100 count 1.00 0.13 0.00 0.00 100 count_distinct 1.00 0.13 0.02 0.00 100 count_distinct_2 1.00 0.16 0.02 0.00 100 count_distinct_big 1.00 0.12 0.04 0.00 30 count_distinct_group 1.00 0.17 0.00 0.00 100 count_distinct_group_on_key 1.00 0.13 0.01 0.00 100 count_distinct_group_on_key_parts 1.00 0.16 0.01 0.00 100 count_distinct_key_prefix 1.00 0.12 0.01 0.00 100 count_group_on_key_parts 1.00 0.09 0.00 0.00 100 count_on_key 20.00 6.11 0.60 0.00 5100 create+drop 0.00 0.01 0.00 0.00 10 create_MANY_tables 0.00 0.01 0.00 0.00 10 create_index 1.00 0.00 0.00 0.00 8 create_key+drop 0.00 0.12 0.01 0.00 100 create_table 1.00 0.03 0.00 0.00 31 delete_all_many_keys 1.00 0.08 0.00 0.00 1 delete_big 0.00 0.01 0.00 0.00 1 delete_big_many_keys 1.00 0.07 0.00 0.00 128 delete_key 0.00 0.06 0.01 0.00 100 delete_range 1.00 0.01 0.00 0.00 12 drop_index 0.00 0.00 0.00 0.00 8 drop_table 0.00 0.01 0.00 0.00 28 drop_table_when_MANY_tables 0.00 0.00 0.00 0.00 10 insert 57.00 13.90 2.51 0.00 44768 insert_duplicates 1.00 0.29 0.04 0.00 1000 insert_key 0.00 0.04 0.01 0.00 100 insert_many_fields 0.00 0.12 0.00 0.00 200 insert_select_1_key 0.00 0.00 0.00 0.00 1 insert_select_2_keys 0.00 0.00 0.00 0.00 1 min_max 1.00 0.06 0.01 0.00 60 min_max_on_key 17.00 8.12 0.64 0.00 7300 multiple_value_insert 0.00 0.03 0.00 0.00 1000 order_by_big 1.00 0.30 0.10 0.00 10 order_by_big_key 1.00 0.29 0.14 0.00 10 order_by_big_key2 1.00 0.28 0.12 0.00 10 order_by_big_key_desc 0.00 0.35 0.08 0.00 10 order_by_big_key_diff 0.00 0.35 0.05 0.00 10 order_by_big_key_prefix 1.00 0.31 0.09 0.00 10 order_by_key2_diff 0.00 0.01 0.00 0.00 10 order_by_key_prefix 0.00 0.02 0.00 0.00 10 order_by_range 0.00 0.03 0.00 0.00 10 outer_join 1.00 0.01 0.00 0.00 10 outer_join_found 1.00 0.01 0.01 0.00 10 outer_join_not_found 1.00 0.03 0.01 0.00 10 outer_join_on_key 0.00 0.01 0.00 0.00 10 select_1_row 1.00 0.27 0.06 0.00 1000 select_1_row_cache 1.00 0.18 0.07 0.00 1000 select_2_rows 1.00 0.43 0.05 0.00 1000 select_big 0.00 0.31 0.10 0.00 17 select_big_str 1.00 0.55 0.22 0.00 100 select_cache 4.00 0.95 0.18 0.00 1000 select_cache2 4.00 1.28 0.11 0.00 1000 select_column+column 1.00 0.35 0.06 0.00 1000 select_diff_key 0.00 0.02 0.00 0.00 10 select_distinct 1.00 0.30 0.06 0.00 80 select_group 4.00 0.61 0.09 0.00 391 select_group_when_MANY_tables 0.00 0.00 0.00 0.00 10 select_join 1.00 0.06 0.03 0.00 10 select_key 0.00 0.02 0.01 0.00 20 select_key2 0.00 0.02 0.00 0.00 20 select_key2_return_key 1.00 0.12 0.00 0.00 20 select_key2_return_prim 0.00 0.00 0.00 0.00 20 select_key_prefix 0.00 0.05 0.00 0.00 20 select_key_prefix_join 2.00 0.62 0.16 0.00 10 select_key_return_key 0.00 0.02 0.00 0.00 20 select_many_fields 1.00 0.31 0.10 0.00 200 select_range 2.00 0.23 0.05 0.00 41 select_range_key2 1.00 0.43 0.02 0.00 505 select_range_prefix 1.00 0.42 0.05 0.00 505 select_simple 0.00 0.21 0.04 0.00 1000 select_simple_cache 0.00 0.14 0.05 0.00 1000 select_simple_join 0.00 0.13 0.05 0.00 50 update_big 1.00 0.01 0.00 0.00 10 update_of_key 1.00 0.20 0.03 0.00 500 update_of_key_big 0.00 0.02 0.01 0.00 13 update_of_primary_key_many_keys 0.00 0.12 0.02 0.00 256 update_with_key 4.00 1.03 0.12 0.00 3000 update_with_key_prefix 1.00 0.58 0.01 0.00 1000 wisc_benchmark 2.00 0.70 0.16 0.00 34 TOTALS 156.00 43.84 6.55 0.00 76237

The benchmark suite is useful for comparing various platforms. MySQL comes with a set of results, but these are dated and not particularly useful. I suggest repeating the test yourself to make them meaningful in your situation.

It’s also important to benchmark your own applications (under the highest possible load) before you roll them out. An application that can help you impose load on your server is super-smack, downloadable from the MySQL site.

Another useful script distributed with MySQL is crash-me, which verifies the functionality on a specific installation and tests the reliability of the server under stress (see Table 2). It gets its name from the results when an installation fails the test. It’s also portable and can test multiple database platforms for comparison purposes. As a result of its behavior, it should never be run in a live environment. It can crash not only the database server, but it also takes significant amounts of memory, meaning it can impact on other programs running on the server. Be aware, though, that MySQL has developed it, so it naturally highlights MySQL strengths and downplays MySQL weaknesses for comparison purposes. For example, triggers and procedures, which MySQL does not currently implement, may seem from viewing the crash-me output to be as important as nonstandard MySQL features, such as using || for OR instead of string concatenation.

MySQL distributions come with a benchmark suite called run-all-tests. You can use it to test various DBMSs to see how well they perform. To use it, you need to have Perl, the Perl DBI module, and the DBD module for the DBMS you want to test. Table 1 explains the options for run-all-tests.

Table 2: Thecrash-meOptions

Option

Description

–help, –Information

Displays a help list of options.

–batch-mode

Runs the test without asking for input and exits if it encounters errors.

–comment=’some comment’

Adds the specified comment to the crash-me limit file.

–check-server

Does a new connection to the server every time it checks if the server isstillrunning. This can be useful if a previous query causes wrong data tostart being returned.

–database=’database’

Creates the test tables in this database. The default is test.

–dir=’directory_name’

Saves the output to this directory

–debug

Displays lots of output to assist in debugging if there is a problem.

–fix-limit-file

Reformats the crash-me limit file. This does not rerun the crash-me.

–force

Begins the test immediately, without warning and without waiting for input. Use this option to automate the test.

–log-all-queries

Displays all executed queries. Mostly used for debugging crash-me.

–log-queries-to-file=’filename’

Logs full queries to the specified file.

–host=’hostname’

Runs the test on the specified host. The default is localhost.

–password=’password’

Specifies the password for the current user.

–restart

Saves states during each test, making it possible, in the case of a crash, to continue from where it left off by restarting with the same options.

–server=’server name’

Specifies the server on which to run the test. These include Access, Adabas, AdabasD, Empress, Oracle, Informix, DB2, Mimer, mSQL, MS-SQL, MySQL, Pg, Solid, or Sybase. The default is MySQL. Other servers will not have their names reported.

–user=’user_name’

Specifies the username to connect as.

–start-cmd=’command to restart server’

Will use the specified command to restart the database server in the case of it dying. (The availability of this option says everything!)

–sleep=’time in seconds’

Specifies the time in seconds to wait before restarting the server. The default is 10 seconds.

 

A sample display of crash-me follows:

% perl crash-me --password='g00r002b'
Running crash-me 1.57 on 'MySQL 4.0.1 alpha max log'

I hope you didn't have anything important running on this server....
Reading old values from cache: /usr/local/mysql-max-4.0.1-alpha-pc-
linux-gnu-i686/sql-bench/limits/mysql.cfg

NOTE: You should be familiar with 'crash-me --help' before continuing!

This test should not crash MySQL if it was distributed together with
 the running MySQL version.
If this is the case you can probably continue without having to worry
 about destroying something.

Some of the tests you are about to execute may require a lot of
memory.  Your tests WILL adversely affect system performance. It's
not uncommon that either this crash-me test program, or the actual
database back-end, will DIE with an out-of-memory error. So might
any other program on your system if it requests more memory at the
wrong time.

Note also that while crash-me tries to find limits for the database server
it will make a lot of queries that can't be categorized as 'normal'.
It's not unlikely that crash-me finds some limit bug in your server so
if you run this test you have to be prepared that your server may die
during it!

We, the creators of this utility, are not responsible in any way if
your database server unexpectedly crashes while this program tries to
find the limitations of your server. By accepting the following
question with 'yes', you agree to the above!

You have been warned!

Start test (yes/no) ?
Tables without primary key: yes
SELECT without FROM: yes
Select constants: yes
Select table_name.*: yes
Allows ' and " as string markers: yes
Double '' as ' in strings: yes
Multiple line strings: yes
" as identifier quote (ANSI SQL): error
` as identifier quote: yes
[] as identifier quote: no
Column alias: yes
Table alias: yes
Functions: yes
Group functions: yes
Group functions with distinct: yes
Group by: yes
Group by position: yes
Group by alias: yes
Group on unused column: yes
Order by: yes
Order by position: yes
Order by function: yes
Order by on unused column: yes
Order by DESC is remembered: no
Compute: no
INSERT with Value lists: yes
INSERT with set syntax: yes
allows end ';': yes
LIMIT number of rows: with LIMIT
SELECT with LIMIT #,#: yes
Alter table add column: yes
Alter table add many columns: yes
Alter table change column: yes
Alter table modify column: yes
Alter table alter column default: yes
Alter table drop column: yes
Alter table rename table: yes
rename table: yes
truncate: yes
Alter table add constraint: yes
Alter table drop constraint: no
Alter table add unique: yes
Alter table drop unique: with drop key
Alter table add primary key: with constraint
Alter table add foreign key: yes
Alter table drop foreign key: with drop foreign key
Alter table drop primary key: drop primary key
Case insensitive compare: yes
Ignore end space in compare: yes
Group on column with null values: yes
Having: yes
Having with group function: yes
Order by alias: yes
Having on alias: yes
binary numbers (0b1001): no
hex numbers (0x41): yes
binary strings (b'0110'): no
hex strings (x'1ace'): no
Value of logical operation (1=1): 1
Simultaneous connections (installation default): 101
query size: 1048574

Supported sql types
Type character(1 arg): yes
Type char(1 arg): yes
Type char varying(1 arg): yes
Type character varying(1 arg): yes
Type boolean: no
Type varchar(1 arg): yes
Type integer: yes
Type int: yes
Type smallint: yes
Type numeric(2 arg): yes
Type decimal(2 arg): yes
Type dec(2 arg): yes
Type bit: yes
Type bit(1 arg): yes
Type bit varying(1 arg): no
Type float: yes
Type float(1 arg): yes
Type real: yes
Type double precision: yes
Type date: yes
Type time: yes
Type timestamp: yes
Type interval year: no
Type interval year to month: no
Type interval month: no
Type interval day: no
Type interval day to hour: no
Type interval day to minute: no
Type interval day to second: no
Type interval hour: no
Type interval hour to minute: no
Type interval hour to second: no
Type interval minute: no
Type interval minute to second: no
Type interval second: no
Type national character varying(1 arg): yes
Type national character(1 arg): yes
Type nchar(1 arg): yes
Type national char varying(1 arg): yes
Type nchar varying(1 arg): yes
Type national character varying(1 arg): yes
Type timestamp with time zone: no

Supported odbc types
Type binary(1 arg): yes
Type varbinary(1 arg): yes
Type tinyint: yes
Type bigint: yes
Type datetime: yes

Supported extra types
Type blob: yes
Type byte: no
Type long varbinary: yes
Type image: no
Type text: yes
Type text(1 arg): no
Type mediumtext: yes
Type long varchar(1 arg): no
Type varchar2(1 arg): no
Type mediumint: yes
Type middleint: yes
Type int unsigned: yes
Type int1: yes
Type int2: yes
Type int3: yes
Type int4: yes
Type int8: yes
Type uint: no
Type money: no
Type smallmoney: no
Type float4: yes
Type float8: yes
Type smallfloat: no
Type float(2 arg): yes
Type double: yes
Type enum(1 arg): yes
Type set(1 arg): yes
Type int(1 arg) zerofill: yes
Type serial: no
Type char(1 arg) binary: yes
Type int not null auto_increment: yes
Type abstime: no
Type year: yes
Type datetime: yes
Type smalldatetime: no
Type timespan: no
Type reltime: no
Type int not null identity: no
Type box: no
Type bool: yes
Type circle: no
Type polygon: no
Type point: no
Type line: no
Type lseg: no
Type path: no
Type interval: no
Type serial: no
Type inet: no
Type cidr: no
Type macaddr: no
Type varchar2(1 arg): no
Type nvarchar2(1 arg): no
Type number(2 arg): no
Type number(1 arg): no
Type number: no
Type long: no
Type raw(1 arg): no
Type long raw: no
Type rowid: no
Type mlslabel: no
Type clob: no
Type nclob: no
Type bfile: no
Remembers end space in char(): no
Remembers end space in varchar(): no
Supports 0000-00-00 dates: yes
Supports 0001-01-01 dates: yes
Supports 9999-12-31 dates: yes
Supports 'infinity dates: error
Type for row id: auto_increment
Automatic row id: _rowid

Supported sql functions

Supported odbc functions

Supported extra functions

Supported where functions

Supported sql group functions
Group function AVG: yes
Group function COUNT (*): yes
Group function COUNT column name: yes
Group function COUNT(DISTINCT expr): yes
Group function MAX on numbers: yes
Group function MAX on strings: yes
Group function MIN on numbers: yes
Group function MIN on strings: yes
Group function SUM: yes
Group function ANY: no
Group function EVERY: no
Group function SOME: no

Supported extra group functions
Group function BIT_AND: yes
Group function BIT_OR: yes
Group function COUNT(DISTINCT expr,expr,...): yes
Group function STD: yes
Group function STDDEV: yes
Group function VARIANCE: no

mixing of integer and float in expression: yes
No need to cast from integer to float: yes
Is 1+NULL = NULL: yes
Is concat('a',NULL) = NULL: yes
LIKE on numbers: yes
column LIKE column: yes
update of column= -column: yes
String functions on date columns: yes
char are space filled: no
DELETE FROM table1,table2...: no
Update with sub select: no
Calculate 1--1: yes
ANSI SQL simple joins: yes
max text or blob size: 1048543 (cache)
constant string size in where: 1048539 (cache)
constant string size in SELECT: 1048565 (cache)
return string size from function: 1047552 (cache)
simple expressions: 1837 (cache)
big expressions: 10 (cache)
stacked expressions: 1837 (cache)
tables in join: 63 (cache)
primary key in create table: yes
unique in create table: yes
unique null in create: yes
default value for column: yes
default value function for column: no
temporary tables: yes
create table from select: yes
index in create table: yes
null in index: yes
null in unique index: yes
null combination in unique index: yes
null in unique index: yes
index on column part (extension): yes
different namespace for index: yes
case independent table names: no
drop table if exists: yes
create table if not exists: yes
inner join: yes
left outer join: yes
natural left outer join: yes
left outer join using: yes
left outer join odbc style: yes
right outer join: yes
full outer join: no
cross join (same as from a,b): yes
natural join: yes
union: no
union all: no
intersect: no
intersect all: no
except: no
except all: no
except: no
except all: no
minus: no
natural join (incompatible lists): yes
union (incompatible lists): no
union all (incompatible lists): no
intersect (incompatible lists): no
intersect all (incompatible lists): no
except (incompatible lists): no
except all (incompatible lists): no
except (incompatible lists): no
except all (incompatible lists): no
minus (incompatible lists): no
subqueries: no
insert INTO ... SELECT ...: yes
atomic updates: no
views: no
foreign key syntax: yes
foreign keys: no
Create SCHEMA: no
Column constraints: no
Table constraints: no
Named constraints: no
NULL constraint (SyBase style): yes
Triggers (ANSI SQL): no
PSM procedures (ANSI SQL): no
PSM modules (ANSI SQL): no
PSM functions (ANSI SQL): no
Domains (ANSI SQL): no
many tables to drop table: yes
drop table with cascade/restrict: yes
-- as comment (ANSI): yes
// as comment: no
# as comment: yes
/* */ as comment: yes
insert empty string: yes
Having with alias: yes
table name length: 64 (cache)
column name length: 64 (cache)
select alias name length: +512 (cache)
table alias name length: +512 (cache)
index name length: 64 (cache)
max char() size: 255 (cache)
max varchar() size: 255 (cache)
max text or blob size: 1048543 (cache)
Columns in table: 3398 (cache)
unique indexes: 32 (cache)
index parts: 16 (cache)
max index part length: 255 (cache)
index varchar part length: 255 (cache)
indexes: 32
index length: 500 (cache)
max table row length (without blobs): 65534 (cache)
table row length with nulls (without blobs): 65502 (cache)
number of columns in order by: +64 (cache)
number of columns in group by: +64 (cache)
crash-me safe: yes
reconnected 0 times
Tagged with:
Aug 02

Until MySQL version 4.0.3, you always had to restart the server to change the variable values. Now, you can use the much more convenient SET statement to make a change without shutting down the server.

You can use the SET statement in two ways. The default is for the change you make to affect the SESSION only, meaning that when you connect next time (and for all other connections) the variable will still be at the setting specified in the configuration file. If you specify the GLOBAL keyword, all new connections will use the new value. When the server restarts, however, it will always use the values set in the configuration file, so you always need to make the changes there as well. To set a variable with the GLOBAL option, you need to have the SUPER permission.

The syntax is as follows:

SET [GLOBAL | SESSION] sql_variable=expression, [[GLOBAL | SESSION]–
   sql_variable=expression...]

For example, the following:

mysql> SET SESSION max_sort_length=2048;

is the same as this:

mysql> SET max_sort_length=2048;

There is an alternate syntax too, used for compatibility with other database management systems (DBMSs), using the @@ syntax, as follows:

SET @@{global | local}.sql_variable=expression, [@@{global |–
   local}.sql_variable=expression]

To repeat the previous example in this syntax, you use the following:

mysql> SET @@local.max_sort_length=2048;

SESSION and LOCAL are synonyms.

If, after experimenting with the new variable, you decide to return to the old value, there’s no need to trust your memory or to look it up in the configuration file. You can use the DEFAULT keyword to restore a GLOBAL value to the value in configuration file, or a SESSION value to the GLOBAL value. For example:

mysql> SET SESSION max_sort_length=DEFAULT;

and

mysql> SET GLOBAL max_sort_length=DEFAULT;
Tagged with:
Aug 01

Hardware is one of the easiest improvements (if you have the cash) you can make to a poorly performing database server. As a general rule of thumb, pack in as much memory as you can first, then use the fastest disks you can get, and finally get the fastest CPU (Central Processing Unit). The best is to benchmark your system, using the various tools available to your operating system to see whether it’s the CPU, memory, disk speed, or a combination that is the bottleneck. This will give you the best idea of the vagaries of your usage and assist you in upgrading. Running the benchmark suite  will also help show the performance of different kinds of tasks.

Memory

Memory is the most important element because it allows you to tweak the mysqld variables. Large amounts of memory mean you can create large key and table caches. Memory that is as large as possible allows MySQL to use quicker memory rather than disk as much as possible, and the quicker the memory is, the faster MySQL can access the data stored there. Large amounts of memory on its own is not as useful as if you actively tweaked the mysqld variables to make use of the extra memory, so you can’t be too lazy and just stick in the memory and wait for fireworks.

Disks

Ultimately, MySQL has to fetch the data from disk, and this is where fast disk access plays a role. The disk seek time is important because it determines how fast the physical disk can move to get to the data it needs, so you should choose the disk with the best disk seek time. Also, SCSI (small computer system interface) disks are usually faster than IDE (Intelligent [or Integrated] Drive Electronics) disks, so you’ll probably want these.

An important improvement you can make is to stripe data across multiple disks (where the OS breaks data in parts, spreading it evenly over multiple disks), as well as symlinking (where you create a link from the data directory to another disk). InnoDB tables have a mechanism to split data across multiple disks quite easily, but MyISAM tables do not (being made up of single files), so striping or other forms of RAID can be quite useful. "Multiple Drives," looks at these topics in more detail.

CPU

The faster the processor, the quicker any calculations can be done and the quicker the results sent back to the client. Besides processor speed, the bus speed and the size of the cache are important. An analysis of available processors is beyond the scope of this book and will probably be outdated before this book is even published, but be sure to investigate your processor possibilities carefully to see how it performs in various

Tagged with:
preload preload preload