SlideShare une entreprise Scribd logo
1  sur  60
MySQL Technical Reference Manual.
What is MySQL?
MySQL is a SQL (Structured Query Language) database server. SQL is the most popular
database language in the world. MySQL is a client server implementation that consists of a server
daemon mysqld and many different client programs/libraries.
The main goals of MySQL are speed and robustness.
The base upon which MySQL is built is a set of routines that have been used in a highly
demanding production environment for many years.


The main features in MySQL
   •   Multi-threaded
   •   C, C++, JAVA, Perl, Python and TCL API’s.
   •   Lots of column types like: signed/unsigned integers 1,2,3,4,8 bytes long, FLOAT,
       CHAR,VARCHAR, TEXT, BLOB, DATE, SET and ENUM types.
   •   Join optimizer with one-sweep multi-join (all joins made in one pass).
   •   Full function support in the SELECT and WHERE parts.
       Example: select column1+column2 from table where column1/column2 > 0
   •   SQL functions are implemented through a very optimized class library and should be as
       fast as they can get! Usually there shouldn’t be any memory allocation at all after the
       query initialization.
   •   Full support for SQL GROUP BY and ORDER BY. Support for group functions (SUM,
       MAX and MIN).
   •   A privilege and password system with is very flexible and secure. Allows host based
       verification.
   •   All password traffic on the net is encrypted.
   •   Very fast B-tree disk tables with key compression.
   •   Fixed and variable length records.
   •   16 indexes/table. Each index may consist of 1 to 15 columns/parts of columns. Max key
       length is 127 bytes. A key may be a prefix of a CHAR field.
   •   ODBC Open-DataBase-Connectivity for Windows95 (with source). All ODBC 2.5
       functions and lots of others.
   •   In memory hash tables always used as temporary tables.
   •   Can handle big databases (we are using MySQL with some databases that contain
       50,000,000 records).
   •   All columns have default values. One can always use INSERT on any subset of columns.
   •   Uses GNU autoconf for portability.
   •   Written in C and C++. Tested with gcc 2.7.2.
   •   A thread based memory allocation system (very fast and no memory trashing).
   •   No memory leaks. Tested with a commercial memory leakage detector (purify).
   •   A very fast table check and repair utility (isamchk).
   •   All data saved in ISO8859_1 format. All comparisons for normal string columns are case
       insensitive.
                                                                                               1
•   Full ISO8859_1 (Latin1) support. For example Scandinavian åäö is allowed in table and
       column names.
   •   Sorts by ISO8859_1 Latin1 (the Swedish way at the moment). It is possible to change
       this in the source by adding new sort order arrays.
   •   Alias on tables and columns as in the SQL92 standard. avg & count).
   •   INSERT,UPDATE and DELETE returns how many rows were affected.
   •   Function names do not clash with table or column names. For example ABS is a valid
       column name. The only restriction is that space is not allowed between a function name
       and the ’(’ when using functions.
   •   All MySQL commands have --help or -? for help.
   •   The server currently supports error messages to clients in many languages. See section
       What languages are supported by MySQL..
   •   The clients uses a TCP connection or unix socket when connecting to the MySQL server.
   •   User commands as show tables, show keys from table and show columns from Table

Problems starting MySQL
Check the log file to see if mysqld started up correctly.
cd <localstatedir default /usr/local/var>
tail <your host name>.log
To verify that MySQL is working, run the following tests:
> cd /usr/local/bin
> ./mysqlshow
+-----------+
| Databases |
+-----------+
| mysql |
+-----------+
> ./mysqlshow mysql
Database: mysql
+--------+
| Tables |
+--------+
| db |
| host |
| user |
+--------+
> ./mysql -e "select host,db,user from db" mysql
+------+--------+------+
| host | db | user |
+------+--------+------+
| % | test | |
| % | test_% | |
+------+--------+------+
There is also a benchmark suite so you can compare how MySQL perform on different platforms.
In the near future this will also be used to compare MySQL to other SQL databases.
> cd bench
> run-auto-increment-test
                                                                                            2
You can also run the tests in the test subdirectory. To run ‘auto_increment.tst’:
./mysql -vf test < ./tests/auto_increment.tst
24
Expected results are shown in the file ‘./tests/auto_increment.res’.

Automatic start/stop of MySQL
To start or stop MySQL use the following commands:
scripts/mysql.server stop
scripts/mysql.server start
You might want to add these start and stop commands in the appropriate places in your /etc/rc*
files
when you start using MySQL for production applications.

How to debug MySQL
If you are porting MySQL to an new system you should first try to get mysys/thr_lock and
mysys/thr_alarm to work. They shouldn’t core dump and not print any error (they also print a lot
of
other information). Also see the file ‘PORTING’ in the distribution.
By starting bin/safe_mysqld with --log you will get a log in
install-directory/var/’hostname’.log (the top level database directory). This log will
contain all successful connections and all commands issued to the MySQL server.
If you have compiled MySQL with --with-debug=yes you can can also get a very informative log
with:
libexec/mysqld --debug
which makes a large log in /tmp/mysql.trace. The default debug option is
d:i:t:o,/tmp/mysql.trace.
You can get a smaller log with:
libexec/mysqld --debug=d,info,query,general:o,/tmp/mysql.trace
or an even smaller (on stdout):
libexec/mysqld --debug=d,general,query
You can get more information about the debug switches by examining the file dbug/dbug.c.
If you have a problem with mysqld that it crashes and you want this quickly solved, you should
include a trace file with your mail if possible. Trace files can be posted directly to
@email{mysql-support@tcx.se} to avoid long messages to the standard mail list. If the trace file
is big
you should use ftp and send it to ftp://www.tcx.se/pub/mysql/secret/ together with a
mysqldump of any tables that you think can help to solve the problem. The context of the above
directory is hidden for outside users so no one except the TCX staff can look at what you send
into it.
Go to the first [p 5] , previous [p 19] , next [p 26] , last [p 87] section, table of contents [p 1] .
25
Go to the first [p 5] , previous [p 24] , next [p 30] , last [p 87] section, table of contents [p 1] .
How does MySQL privileges work
MySQL has a advanded but non standard security/privileges system.
How does the privilege system work?
The MySQL privilege system makes sure that each user may do exactly the things that they are


                                                                                                     3
supposed to be allowed to do. The system decides to grant different privileges depending on
which
user connects from which host to which database. The decision is based on the contents of
the three
tables in the MySQL database: user, host and db.
The grant tables privileges on rows are select, insert, update and delete.
The table and database privileges are create and drop. Create and drop are for both tables and
databases. Since a user with a drop grant can delete any table, this is the same thing as a drop
grant for
the database.
Other privileges give the right to use files (for LOAD DATA INFILE and SELECT INTO
OUTFILE)
and to use the administrative commands shutdown, reload, refresh and process, to get the
current
process list.
The privilege tables are read into mysqld with mysqladmin reload. If the privilege tables are
empty or non-existent or if the server is started with --skip-grant-tables, full access is
granted to everyone.
You can always test your privileges with the script mysqlaccess, which Yves Carlier has
provided
for the MySQL distribution. See section Why do I get ’Access denied’? [p 78]
The host and db fields may contain a SQL regexp with chars % and _. Leaving any of these
fields
empty is equivalent to setting it to ’%’.
A host may be localhost, a hostname, an IP number or an SQL expression. An empty host in
the db table means any host in the host table. An empty host in the host or user table means any
host that can create a TCP connection to your server.
A db is the name of a database or an SQL regexp.
An empty user field means any username will do.
An empty password means that the entry will only be used if no password is supplied.
The privileges from the user table are OR’ed to the db table. This means that a superuser only
needs to be in the user table with all privilege-flags set to Y.
Everything granted in the user table is valid for every database that cannot be found in the db
table.
For this reason, it might be wise to grant users (apart from superusers) privileges on a per-
database
basis only.
The host table is mainly there to maintain a list of "secure" servers. At TcX host contains a list of
all machines on the local network. These are granted all privileges.
26
The connecting user’s privileges are calculated by the following algorithm:
1. First sort all three tables by host by putting hosts without wildcards first, followed by hosts
with
wildcards and entries with host = "". Within each host, di.e. very much like GROUP BY
Host, sort by user using the same rules. Finally, in the db table, sort by db using the same rules.
In the steps below, we will look through the sorted tables and always use the first match found.
2. Get the privileges for the connecting user from the db table using the first match found. Call
this
set of privileges P.
                                                                                                    4
3. If host = "" for the entry found in the db table, AND P with the privileges for the host in the
host table, i.e. remove all privileges that are not "Y" in both. (If host <> "", P is not
affected. In suchcases, host must have matched the connecting host’s name at least partially.
Therefor it can be assumed that the privileges found in this row match the connecting host’s
profile.)
4. OR (add) P with the privileges for the user from the user table, i.e. add all privileges that are
"Y" in user.
The connecting user gets the set of privileges P.
Let’s show an example of the sorting and matching! Suppose that the user table contains this:
+-----------+----------+-
| Host | User | ...
+-----------+----------+-
| % | root | ...
| % | jeffrey | ...
| localhost | root | ...
| localhost | | ...
+-----------+----------+-
Then the search order will be:
localhost/root
localhost/any
any/jeffrey
any/root
So jeffrey attempting to connect on localhost will be matched by the localhost/any line, not by
the any/jeffrey line. The first match found is used!
So if you have access problems, print out the user table, sort it by hand, and see where the match
is
being made.
Here follows an example to add a user ’custom’ that can connect from hosts ’localhost’,
’server.domain’ and ’whitehouse.gov’. He wants to have password ’stupid’. The database
’bankacount’ he only want to use from ’localhost’ and the ’customer’ database he wants to be
able to
reach from all three hosts.
shell> mysql mysql.
mysql> insert into users (host,user,password)
values(’localhost’,’custom’,password(’stupid’));
mysql> insert into users (host,user,password)
values(’server.domain’,’custom’,password(’stupid’));
mysql> insert into users (host,user,password)
values(’whitehouse.gov’,’custom’,password(’stupid’));
27
mysql> insert into db
(host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv)
values
(’localhost’,’bankacount’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’);
mysql> insert into db
(host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv,
Create_priv,Drop_priv)
values
                                                                                                   5
(’%’,’customers’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’);
You can of course also use xmysqladmin, mysql_webadmin, mysqladmin and even xmysql to
insert/change and update values in the privilege tables. You can find these utilities in the Contrib
directory.
Adding new user privileges to MySQL
To add privileges to the MySQL database:
This assumes the current user has insert privileges for the mysql db table and reload privileges.
The
server (mysqld) has to be running. If it is not, start it with safe_mysqld --log &.
> mysql mysql
insert into user values
(’%’,’monty’,password(’something’),’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’) ;
insert into user (host,user,password) values(’localhost’,’dummy’,") ;
insert into user values (’%’,’admin’,",’N’,’N’,’N’,’N’,’N’,’N’,’Y’,’N’,’Y’,’Y’) ;
quit
> mysqladmin reload
This makes three new users:
Monty
Full superuser, but must use password when using MySQL.
admin
Doesn’t need a password but is only allowed to use mysqladmin reload, mysqladmin
refresh and mysqladmin processlist. May be granted individual database privileges
through table db.
dummy
Must be granted individual database privileges through table db.
Default privileges.
The default privileges (set in ‘scripts/mysql_install_db’) is that root can do anything. Any
user can do anything with any database whose name is ’test’ or starts with ’test_’. A normal user
can’t
use mysqladmin shutdown or mysqladmin processlist. See the script
(‘scripts/mysql_install_db’) for an example on how to add other users.
The privilege tables are read into mysqld with ’mysqladmin reload’. If the privilege tables are
empty
(or non-existent) full access are granted to everyone.
28
A example of permission setup.
A common mistake is to try something like:
INSERT INTO user VALUES
(’%’,’jeffrey’,’bLa81m0’,’Y’,’Y’,’Y’,’N’,’N’,’N’,’N’,’N’, ’N’,’N’);
Then (of course) a mysqladmin reload to make the authentication change take effect, then trying
to connect to the server:
$ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test Access denied
Try this instead:
INSERT INTO user VALUES
(’%’,’jeffrey’,password(’bLa81m0’),’Y’,’Y’,’Y’,’N’,’N’,’N’,’N’,’N’,’N’,’N’);
And like before mysqladmin reload to make the authentication change take effect.
Now things should work.
Go to the first [p 5] , previous [p 24] , next [p 30] , last [p 87] section, table of contents [p 1] .
29
                                                                                                       6
Go to the first [p 5] , previous [p 26] , next [p 52] , last [p 87] section, table of contents [p 1] .
MySQL language reference
Literals. How do you write strings and numbers?
STRINGS
A string may have ’ or " around it.
 is a escape character. The following escape characters are recognised:
0 A ascii 0 character.
n A newline character.
t A tab character.
r A return character.
b A backspace character.
’ A ’ character.
" A " character.
 A  character.
% A % character. This is used in wild-card strings to search after %.
_ A _ character. This is used in wild-card strings to search after _.
A ’ inside a string started with ’ may be written as ".
A " inside a string started with " may be written as "".
MySQL> select ’hello’, "’hello’", ’""hello""’, "’h"e"l"l"o"’, "hel""lo";
1 rows in set (0.00 sec)
+-------+---------+-----------+-------------+--------+
| hello | ’hello’ | ""hello"" | ’h’e’l’l’o’ | hel"lo |
+-------+---------+-----------+-------------+--------+
| hello | ’hello’ | ""hello"" | ’h’e’l’l’o’ | hel"lo |
+-------+---------+-----------+-------------+--------+
mysql> select ’hello’, "hello", ’""hello""’, "’ello", ’e"l"lo’, ’’hello’;
1 rows in set (0.00 sec)
+-------+-------+-----------+-------+--------+--------+
| hello | hello | ""hello"" | ’ello | e’l’lo | ’hello |
+-------+-------+-----------+-------+--------+--------+
| hello | hello | ""hello"" | ’ello | e’l’lo | ’hello |
+-------+-------+-----------+-------+--------+--------+
mysql> select "ThisnIsnFournlines";
1 rows in set (0.00 sec)
+--------------------+
| This
Is
Four
lines |
+--------------------+
| This
30
Is
Four
lines |
+--------------------+
If you want to insert binary data into a blob the following characters must be represented by
escape
sequences:
                                                                                                         7
0 Ascii 0. Should be replaced with "0" (A backslash and a 0 digit).
 Ascii 92, backslash
’ Ascii 39, Single quote
" Ascii 33, Double quote
NUMBERS
Integers are just a sequence of digits. Floats use . as a decimal separator.
Examples of valid numbers are: 1221, 294.42, -32032.6809e+10.
NULL
When using the text file export formats, NULL may be represented by N. See section LOAD
DATA
INFILE syntax [p 45]
Column types.
The following column types are supported:
Name Description Size
TINYINT [(max display size)]
[UNSIGNED] [ZEROFILL]
A very small integer. Signed range -128 - 127. Unsigned
range 0 - 255.
1
SMALLINT [(max display
size)]. [UNSIGNED]
[ZEROFILL]
A small integer. Signed range -32768 - 32767. Unsigned
range 0 - 65535.
2
MEDIUMINT [(max display
size)] [UNSIGNED]
[ZEROFILL]
A medium integer. Signed range -8388608-8388607.
Unsigned range 0 - 16777215.
3
INT [(max display size)]
[UNSIGNED] [ZEROFILL]
A normal integer. xSigned range -2147483648 -
2147483647. Unsigned range 0 - 4294967295.
4
BIGINT [(max display size)]
[UNSIGNED] [ZEROFILL]
A large integer. Signed range -9223372036854775808 -
9223372036854775807. Unsigned Range 0 -
18446744073709551615.
8
31
FLOAT(Precision)
A small floating point number. Precision can be 4 or 8.
FLOAT(4) is a single precision number and FLOAT(8) is a
double precision number (se the DOUBLE entry). This
syntax is for ODBC compatibility. Range
-3.402823466E+38F - -1.175494351E-38, 0,
                                                                                           8
-1.175494351E-38 - 3.402823466E+38F.
4
FLOAT [(max display
size,number of decimals)]
A small floating point number. Cannot be unsigned. Range
-3.402823466E+38F - -1.175494351E-38, 0,
-1.175494351E-38 - 3.402823466E+38F.
4
DOUBLE PRECISION [(max
display size,number of
decimals)]
A normal floating point number. Cannot be unsigned.
Range -1.7976931348623157E+308 -
-2.2250738585072014E-308, 0,
2.2250738585072014E-308 - 1.7976931348623157E+308.
8
REAL [(length,decimals)] Same as DOUBLE 8
DECIMAL [(max display
size,number of decimals)]
An unpacked floating point number. Cannot be unsigned.
Currently the same range maximum range as a double.
Behaves as a CHAR column
M+D
NUMERIC [(length,decimals)] Same as DECIMAL M+D
TIMESTAMP [(display size)] An automatic timestamp. 4
DATE
A type to store date information. Uses the
"YYYY-MM-DD" syntax, but may be updated with a
number or a string. Understands at least the following
syntaxes: ’YY-MM-DD’, ’YYYY-MM-DD’, ’YYMMDD’,
’YYMM’, ’YY’. Range 0000-00-00 to 9999-12-31.
4
TIME
A type to store time information. Uses the "HH:MM:SS"
syntax, but may be updated with a number or a string.
Understands at least the following syntaxes: ’HH:MM:DD,
’HHMMDD’, ’HHMM’, ’HH’.
3
DATETIME
A type to store date and time information. Format
"YYYY-MM-DD HH:MM:SS". Takes 8 bytes. Range
’0000-01-01 00:00:00’ - ’9999-12-31 23:59:59’.
8
CHAR(max_length) [binary]
A fixed length string that is always filled up with spaces to
the specified length. Range 1 - 255 characters. All end
space are removed when retrieved. Is sorted and compared
case insensitively unless the binary keyword is given.
M
                                                                9
VARCHAR(max_length)
[binary]
A variable length string that is stored with its length.
Maximum range 1 - 255 characters. Is sorted and compared
case insensitively unless the binary keyword is given.
L+1
TINYTEXT and TINYBLOB A TEXT/BLOB with max length of 255 characters. L + 1
TEXT and BLOB A TEXT/BLOB with max length of 65535 characters. L + 2
32
MEDIUMTEXT and
MEDIUMBLOB
A TEXT/BLOB with max length of 1677216 characters. L + 3
LONGTEXT and LONGBLOB
A TEXT/BLOB with max length of 4294967295
characters.
L+4
ENUM(’value’,’value2’,...)
A string object that can have only one set of allowed
values. See section More about data types [p 33] .
1 or
2
SET(’value’,’value2’,....)
A string object that can have one or many values of a set of
allowed values. See section More about data types [p 33] .
1-8
More about data types
Database size info.
In the above table L means the actual length of a instance and M the maximum length. So L+1
for
"abcd" means 5 bytes in the database.
If you use any data type with a L in the length field you will get a variable length record format.
The numeric types
All integer types can have a optional argument unsigned. This can be used when you only want
to
allow positive numbers in the column or you need a little bigger numerical range for the column.
Also for all integer columns the optional argument ZEROFILL means that the column will be
padded
with zeroes upto the maximum length.
Max display size and decimals are for formating and calculation of max column width.
TIMESTAMP type
Has a range of 1 Dec 1970 time 0.00 to sometime in the year 2106 and a resolution of one
second.
Will be automatically updated if not used in a statement that updates a row or if set to NULL.
Can be a
(part of) a key. Note that if you have many timestamp fields in a row, then only the first
timestamp
field will be automatically updated. Any timestamp field will be set to the current time if set to
NULL.

                                                                                                 10
Depending on the display size one gets one of the following formats: "YYYY-MM-DD
HH:MM:SS",
"YY-MM-DD HH:MM:SS", "YYYY-MM-DD" or "YY-MM-DD".
TEXT and BLOB types
These are objects that can have a variable length without upper limit. All TEXT and BLOB
objects are
stored with is length (saved in 1 to 4 bytes depending on the type of object). The maximum
TEXT and
BLOB length you can use is dependent on available memory and client buffers. The only
differences
between TEXT and BLOB is that TEXT is sorted and compared case insensitively while BLOB
is
compared case insensitive (by character values). TEXT and BLOB objects CANNOT be keys.
A BLOB is a binary large object which can hold any amount of data :) There are 4 kinds of blobs
See
section Column types. [p 31] . Normally one can regard a BLOB as a VARCHAR without a
specified
limit.
33
TEXT is a BLOB that is sorted and compared case insensitively.
There are some constraints because of the message buffer used. The default size of the buffer is
64K
for the server and 512K for the clients. To change the buffer length for the server, use mysqld -O
max_allowed_packet=max_blob_length. This allows the message buffer to grow up to this
limit when needed.
MyODBC defines BLOB:s as LONGVARBINARY and TEXT:s as LONGVARCHAR.
Restrictions for BLOB and TEXT columns:
1. A BLOB or TEXT cannot be a key or a part of a key
2. When one sorts or groups a BLOB or TEXT only the first max_sort_length (default 1024)
of the blob is used. This value can be changed by the -O option when starting the mysqld demon.
One can group on an expression involving a BLOB/TEXT: SELECT
id,SUBSTR(blob,1,100) GROUP BY 2
3. There is no end space truncation for BLOB and TEXT as there is for CHAR and VARCHAR.
ENUM type
A string object that can have only one set of allowed values. The value to be stored may be given
case
independently. If one tries to store a non existing value, "" is stored. If used in a number context
this
object returns/stores the value index. If there is less than 255 possible values this object occupies
1
byte, else two bytes (with a maximum of 65535 different values). Note that if a integer is put in
the
ENUM you get the corresponding string with the first counting as number zero. Sorting on
ENUM types
are done after the order of the strings in the enum.
For example the column test ENUM("one","two", "three") can have any off these values:
"one"
"two"
"three"
                                                                                                  11
SET type
A string object that can have one or many values of a set of allowed values. Each value is
separated by
a ’,’. If used in a number context this object returns/stores the bit positions of the used values.
This
object occupies (number_of_different_values-1)/8+1 bytes, rounded up to 1,2,3,4 or 8. One can’t
have
more than 64 different values. Note that if a integer is put in the SET you get the corresponding
string
with the first bit corresponding to the first string.Sorting on SET types are done numericaly.
For example the column test SET("one","two") can have any off these values:
""
"one"
"two"
"one,two"
34
Column indexes
You can have indexes on all MysQL column types except BLOB and TEXT. Using indexes on
the
relevant columns is the most important thing is getting you selects to run fast.
For CHAR and VARCHAR columns you can have a index on a prefix. The example below show
how
to create a index for the first 10 characters of a column. This is much faster and requires less disk
space than having a index on the whole field.
CREATE TABLE test (
name CHAR(200),
KEY name (last_name(10));
Multiple field indexes
MySQL can have one index on parts of different columns.
A multiple column key can be considered as a sorted array where the columns are concatenated.
Suppose that you have a table:
CREATE TABLE test (
id INT,
last_name CHAR(30),
first_name CHAR(30),
PRIMARY KEY (id),
KEY name (last_name,first_name));
Then the key ’name’ is a key over last_name and first_name.
The ’name’ key will be used in the following queries:
SELECT * FROM test WHERE last_name="Widenius";
SELECT * FROM test WHERE last_name="Widenius" AND first_name="Michael";
SELECT * FROM test WHERE last_name="Widenius" AND (first_name="Michael" OR
first_name="Monty");
SELECT * FROM test WHERE last_name="Widenius" and first_name >="M" and first_name <
"N";
The ’name’ key will NOT be used in the following queries:
SELECT * FROM test WHERE first_name="Michael";
SELECT * FROM test WHERE last_name="Widenius" or first_name="Michael";
Type mapping (to ease moving tabel definitions between different
                                                                                                  12
databases engines)
To support easier use of code from different SQL vendors, MySQL does supports the following
mappings:
35
binary(num) char(num) binary
char varying varchar
float4 float
float8 double
int1 tinyint
int2 smallint
int3 mediumint
int4 int
int8 bigint
long varbinary blob
long varchar text
middleint mediumint
varbinary(num) varchar(num) binary
CREATE TABLE syntax.
CREATE TABLE table_name ( create_definition,... )
create_definition:
column_name type [DEFAULT default_value] [NOT NULL | NULL] [ PRIMARY KEY ]
[reference_definition]
or PRIMARY KEY ( key_column_name,... )
or KEY [key_name] KEY( key_column_name,...)
or INDEX [key_name] ( key_column_name,...)
or UNIQUE [key_name] ( key_column_name,...)
or FOREIGN KEY key_name ( key_column_name,...) [reference_definition]
or CHECK (expr)
key_column_name:
column_name [ (length) ]
reference_definition:
REFERENCES table_name [( key_coulmn_name,...)]
[ MATCH FULL | MATCH PARTIAL]
[ ON DELETE reference_option]
[ ON UPDATE reference_option]
reference_option:
RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT
The FOREIGN KEY, CHECK and REFERENCE syntax are only for compatibility. They don’t
actually do anything.
If a column doesn’t have a DEFAULT value and is not declared as NOT NULL, the default
value is
NULL.
36
ZEROFILL means that number is pre-zeroed to maximal length. With INT(5) ZEROFILL a
value of 5 is retrieved as 00005.
BINARY means that the column will be compared case sensitive. The default is that all strings
are compared case insensitive. BINARY is ’sticky’ which means that if a column marked
’binary’ is used in a expression, the whole expression is compared ’binary’.
INDEX is only a synonym for KEY.
                                                                                            13
If one doesn’t assign a name to a key, the key will get the same name as the first key_column
with an optional _# to make it unique.
Key columns and timestamp columns can’t be NULL. For these columns the NULL attribute is
silently removed.
With column_name(length) syntax one can specify a key which is only a part of a string
column. This can make the index file much smaller.
A number column may have the additional attribute AUTO_INCREMENT to automatically get
the largest value+1 for each insert where column value is NULL or 0. See section How can I get
the unique ID for the last row? [p 83]
One can insert NULL for timestamp and auto_increment columns. This results in the current
time
/ the next number.
Blob columns can’t be keys.
When one groups on a blob only the first ’max_sort_length’ bytes are used See section
Limitations of BLOB and TEXT types [p 21] .
Deleted records are in a linked list and subsequent inserts will reuse old positions. To get smaller
files one can use the isamchk utility to reorganise tables.
Each null column takes 1 bit extra, rounded up to the nearest byte.
The maximum record length can be calculated as follows: 1+ sum_of_column_lengths +
null_columns/8 + number of variable length columns.
In some cases an attribute may silently change after creation: VARCHAR columns with a length
of
1 or 2 are changed to CHAR. When using one VARCHAR column all CHAR columns longer
than 2
are changed to VARCHAR’s.
On INSERT/UPDATE all strings (CHAR and VARCHAR) are silently chopped/padded to the
maximal length given by CREATE. All end spaces are also automatically removed. For example
VARCHAR(10) means that the column can contain strings with a length up to 10 characters.
Something/0 gives a NULL value.
The regular expression function (REGEXP and RLIKE) uses ISO8859-1 (Latin1) when deciding
the type of a character.
ALTER TABLE syntax
ALTER [IGNORE] TABLE table_name alter_specification [, alter_specification ...]
alter_specification:
ADD [COLUMN] create_definition
or CHANGE [COLUMN] old_column_name create_definition
or ALTER [COLUMN] column_name { SET DEFAULT literal | DROP DEFAULT }
or DROP [COLUMN] column_name
or DROP PRIMARY KEY
DROP INDEX key_name
ALTER TABLE works by creating a temporary table and copying all information to it and then
the old table is deleted and the new one is renamed. This is done in such a way that all updates
are automatically redirect to the new table without any failed updates. While the ALTER
TABLE
is working, the old table is readable for other clients. Table updates/writes to the table are stalled
37
and only executed after the new table is ready.
If IGNORE isn’t specified then the copy will be aborted and rolled back if there exists any
duplicated unique keys in the new table. This is a MySQL extension.
                                                                                                   14
The CHANGE column_name, DROP column_name and DROP INDEX are MySQL
extensions to ANSI SQL92.
The optional word COLUMN is a pure noise word and can be omitted.
The ADD and CHANGE takes the same create_definition as CREATE TABLE. See section
CREATE TABLE syntax. [p 36] .
ALTER COLUMN sets a new default value or removes the old default value for a column.
DROP INDEX removes an index. This is an MySQL extension.
The FOREIGN KEY syntax in MySQL exists only for compatibility with other SQL vendors
CREATE TABLE commands: It doesn’t do anything. See section How standards compatible are
MySQL [p 19]
If one drops a column_name which is part of some key, this key part is removed. If all key parts
are removed then the key is removed.
DROP PRIMARY KEY drops the first UNIQUE key in the table.
CHANGE tries to convert data to the new format as good as possible.
With mysql_info(MYSQL*) one can retrieve how many records were copied and how many
records were deleted because of multiple keys.
To use ALTER TABLE one has to have select, insert, delete, update, create and drop privileges
on the table.
DROP TABLE syntax.
DROP TABLE table_name [, table_name....]
Removes one or more tables. All the data and the definition is removed so take it easy with this
command!
DELETE syntax.
DELETE FROM table_name WHERE where_definition
Returns records affected.
If one does a delete without a where clause then the table is recreated which is much faster than
doing
a delete for each row. In these cases, the SQL command returns zero as affected records.
Using DELETE FROM table_name will work even if the data files do not exist as only
information from the table definition file, table_name.frm, is used.
All string comparisons are case independent with case according to ISO-8859-1 Latin1.
LIKE is allowed on numerical columns.
Compare with explicit NULL (column == NULL) is the same as if IS NULL was used (column
IS NULL). This is is done to be consistent with mSQL.
38
SELECT syntax
SELECT [STRAIGHT_JOIN] [DISTINCT | ALL] select_expression,... [INTO
OUTFILE ’file_name’ ...] [ FROM tables... [WHERE where_definition ]
[GROUP BY column,...] [ ORDER BY column [ASC | DESC] ,..] HAVING
where_definition [LIMIT [offset,] rows] [PROCEDURE procedure_name]]
Strings are automatically converted to numbers and numbers to strings when needed (ala perl). If
in a
compare operation ((=, <>, <= ,<, >=, >)) either if the arguments are numerical the
arguments are compared as numbers, else the arguments are compared as strings. All string
comparisons are by default done case-independent by ISO8859-1 (The Scandinavian letter set
which
also works excellent with English).
select 1 > "6x"; -> 0
select 7 > "6x"; -> 1
                                                                                                 15
select 0 > "x6"; -> 0
select 0 = "x6"; -> 1
A column name does not have to have a table prefix if the given column name is unique.
A select expression may be given an alias which will be column name and can be used when
sorting and grouping or in the HAVING clause.
select concat(last_name,’ ’,first_name) as name from table order by name
In LIKE expressions % and _ may be preceded with ’’ to skip the wild-card meaning.
A DATE is a string with one of the following syntaxes:
YYMMDD (Year is assumed to be 2000 if YY < 70.)
YYYYMMDD
YY.MM.DD Where ’.’ may be any non numerical separator.
YYYY.MM.DD Where ’.’ may be any non numerical separator.
IFNULL() and IF() returns number or string value according to use.
ORDER and GROUP columns may be given as column names, column alias or column numbers
in
SELECT clauses.
The HAVING clause can take any columns or alias in the select_expressions. It is applied last,
just before items are sent to the client, without any optimisation. Don’t use it for items that
should be in the WHERE clause. You can’t write (yet):
SELECT user,MAX(salary) FROM users GROUP BY users HAVING max(salary)>10
Change it to:
SELECT user,MAX(salary) AS sum FROM users GROUP BY users HAVING sum > 10
STRAIGHT_JOIN forces the optimiser to join the tables in the same order that the tables are
given in the FROM clause. One can use this to get a query to be done more quickly if the
optimiser joins the tables in not optimal order. See section EXPLAIN syntax. Get information
about a SELECT. [p 47]
LIMIT takes one or two numerical arguments.
If one argument, the argument indicates the maximum number of rows in a result.
If two arguments, the first argument says the offset to the first row to return, the second is
39
the maximum number of rows.
INTO OUTFILE ’filename’ writes the given set to a file. The file can not exist from before. See
section LOAD DATA INFILE syntax [p 45] .
Functions
A select_expression or where_definition can consist of any expression using the
following functions:
Group functions.
(
) Parenthesis
Normal mathematical operations.
+
-
*
/ A division by zero results in a NULL.
Bit functions. These have a range of maximum 64 bits because MySQL uses longlong arithmetic.
|
&
BIT_COUNT()
Number of set bits in an argument.
                                                                                            16
Normal logical. Returns TRUE (1) or FALSE (0).
NOT
!
OR
AND
Comparison operators. Returns TRUE (1) or FALSE (0). These functions work for both numbers
and
strings.
= Equal
<> Not equal. Synonym: !=
<= Smaller or equal.
< Smaller.
>= Bigger or equal
> Bigger
ISNULL(A)
Returns 1 if A is NULL else 0. Same as ’( A == NULL ’).
A BETWEEN B AND C
A is bigger or equal as B and A is smaller or equal to C. Is the same as (A >= B AND A <= C).
40
String comparison functions.
expr IN (value,...)
Returns 1 if expr is any of the values in the IN list, else it returns 0. If all values are constants,
then all values are evaluated according to the type of expr and sorted. The search for them item is
then done by using a binary search. This means IN is very quick when used with constants in the
IN part.
expr LIKE expr
SQL simple regular expression comparison. Returns TRUE (1) or FALSE (0). With LIKE you
have two wild characters. ’%’ stands for any number of characters, even zero characters. ’_’
stands exactly one character. If you want to search after a ’%’ or a ’_’ you must precede it with
a ’’ For example the string "Monty was here" is matched by "Monty%", "%Monty ___ h%"
and "%was%".
expr NOT LIKE expr
Returns TRUE (1) or FALSE (0).
expr REGEXP expr
Checks string against extended regular expr.
expr NOT REGEXP expr
Checks string against extended regular expr.
STRCMP()
Returns 0 if the strings are the same. Otherwise return -1 if first argument is smaller according to
sort-order, otherwise it returns 1.
Control flow functions.
IFNULL(A,B)
If A is not null it returns A, else B.
IF(A,B,C)
If A is true (<> 0 and <> NULL) then return B, else return C.
Mathematical functions. These returns NULL in the case of a error.
- Sign
ABS()
SIGN()
                                                                                                   17
Sign of argument. Returns -1, 0 or 1.
MOD()
% Module (like in C). Equivalent with MOD().
FLOOR()
CEILING()
ROUND()
EXP()
LOG()
LOG10()
POW()
SQRT()
PI()
COS()
SIN()
41
TAN()
TAN2()
ACOS()
ASIN()
ATAN()
RAND([integer_expr])
Returns a random float, 0 <= x <= 1.0, using integer_expr as the option seed value.
MIN()
Min value of arguments. Must have 2 or more arguments, else these are GROUP BY functions.
The arguments are compared as numbers.
MAX()
Max value of arguments. Must have 2 or more arguments, else these are GROUP BY functions.
The arguments are compared as numbers.
String functions.
ASCII(string_exp)
Returns the ASCII code value of the leftmost character of string_exp. If string_exp is NULL, it
then returns NULL.
CHAR(num,...)
Returns a string that consist of the characters given by the ASCII code values of the arguments.
NULLS are skipped.
CONCAT()
Concatenates strings. May have more than 2 arguments.
LENGTH()
Length of string. Synomyes: CHAR_LENGTH(), OCTET_LENGTH()
LOCATE(A,B)
Returns position of B substring in A. The first position is 1. Returns 9 if b is not in A.
LOCATE(A,B,C)
Returns position of B substring in A starting at C. Synonym: POSITION(B IN A)
LEFT(str,length)
Gets length characters from beginning of string.
RIGHT(str,right)
Gets length characters from end of string. Synonym: SUBSTRING(A FROM B)
LTRIM(str)
Removes space characters from the beginning of string.
                                                                                               18
RTRIM(str)
Removes space characters from the end of string.
TRIM([[ BOTH | LEADING | TRAILING] [ A ] FROM ] B)
Returns a character string with all A prefixes and/or suffixes removed from B. If BOTH,
LEADING and TRAILING isn’t used BOTH are assumed. If A is not given, then spaces are
removed.
SOUNDEX(str)
Gets a soundex string from str. Two strings that sound ’about the same’ should have identical
soundex strings. A ’standard’ soundex string is 4 long, but this function returns an arbitrary long
string. One can use SUBSTRING on the result to get a ’standard’ soundex string. All non alpha
characters are ignored in the given string. All characters outside the A-Z range are treated as
vocals.
SUBSTRING(A,B,C)
Returns substring from A starting at B with C chars.
42
SUBSTRING(A FROM B FOR C)
Same as SUBSTRING(A,B,C). This is ANSI SQL 92.
SUBSTRING(A FROM B)
Same as RIGHT(A,B). This is ANSI SQL 92.
SUBSTRING_INDEX(string,delimiter,count)
Returns the substring from ’string’ after ’count’ delimiters. If count is positive the strings are
searched from left else if count is negative the substrings are searched and returned from right.
substring("www.tcx.se",".",2) would return "www.tcx" and
substring("www.tcx.se",".",-2) would return "tcx.se".
REPLACE(A,B,C)
Replaces all occurrences of B in A with C.
REPEAT(string,count)
Repeats string count times. If count <= 0 returns a empty string. If string or count is NULL or
LENGTH(string)*count > max_allowed_size returns NULL.
INSERT(org,start,length,new)
Replaces substring org[start...length] with new. First position in string=1.
LCASE(A)
Changes A to lower case. Synonym: LOWER()
UCASE(A)
Changes a to upper case. Synonym: UPPER()
ENUM(A,a,b,c,d)
Returns 1 if A == a, 2 if A == b. If no match 0 is returned. A,a,b,c,d... are strings.
ELT(N,a,b,c,d,...)
Returns a if N == 1, b if N == 2. a,b,c,d are strings.
FIELD(A,a,b,c,d,...)
Returns index of A in the a,b,c... list. The complement of ELT().
Date and time functions.
PERIOD_ADD(P:N)
Adds N months to period P (of type YYMM or YYYYMM). Returns YYYYMM.
PERIOD_DIFF(A,B)
Returns months between periods A,B. A and B should be of format YYMM or YYYYMM.
Example: PERIOD_DIFF(9612,199712).
TO_DAYS(DATE)


                                                                                                 19
Changes a DATE to a daynumber. DATE may be a date string, a datetime string, a timestamp([6
|
8 | 14]) or a number of format YYMMDD or YYYYMMDD.
FROM_DAYS()
Changes a daynumber to a DATE.
WEEKDAY(DATE)
Gets weekday for date (0 = Monday, 1 = Tuesday). DATE may be a date string, a datetime
string,
a timestamp([6 | 8 | 14]) or a number of format YYMMDD or YYYYMMDD.
CURDATE()
Returns date of today. In form YYYYMMDD or "YYYY-MM-DD" depending on whether
CURDATE() is used in a number or string context. Synonymes: CURRENT_DATE().
CURTIME()
Returns current time in form HHMMSS or "HH:MM:SS", depending on whether CURTIME() is
used in a number or string context. Synonymes: CURRENT_TIME().
43
NOW()
Returns current time. In format YYYYMMDDHHMMSS or "YYYY-MM-DD HH:MM:SS"
depending on whether NOW() is used in a number or string context. Synonymes:
CURENT_TIMESTAMP(), SYSDATE().
UNIX_TIMESTAMP([DATE])
If called without any arguments a unix timestamp (seconds in GMT since 1970.01.01 00:00:00)
is returned. Normally it is called with a timestamp column as an argument in which case it
returns the timestamp. DATE may also be a date string, a datetime string, or a number of format
YYMMDD or YYYMMDD in local time.
FROM_UNIXTIME(unix_timestamp)
Returns a string of the timestamp in YYYY-MM-DD HH:MM:SS or YYYYMMDDHHMMSS
format depending on context.
SEC_TO_TIME(seconds)
Returns the hours, minutes and seconds of the argument in H:MM:SS or HMMSS format
depending on context.
Miscellaneous functions.
DATABASE()
Returns current database name.
USER()
Returns current user name. Synonymes: SESSION_USER() and SYSTEM_USER().
PASSWORD()
Calculates a password string. This must be used to store a password in the ’user’ grant table.
ENCRYPT(string[,salt])
Crypt messsage with the unix crypt() command. The salt should be a string with 2 characters.
LAST_INSERT_ID()
Returns the last automaticly generated value that was set in a auto_increment column. See
section
How can I get the unique ID for the last row? [p 83]
FORMAT(nr,NUM)
Formats number to a format like ’#,###,###.##’ with NUM decimals.
Functions for GROUP BY clause.
count(expr)
Number of rows. count(*) is optimised to return very quickly if no other column is used in the
                                                                                             20
SELECT.
avg(expr)
Average value of expr.
min(expr)
max(expr)
Minimum/Maximum value of expr. min() and max() may take a string argument and will then
return the minimum/maximum string value.
sum(expr)
Sum of expr.
std(expr)
Standard derivation of expression. This is a extension to ANSI SQL.
bit_or(expr)
The logical OR of all bits in expr. Caclulation done with 64 bits precision.
44
bit_and(expr)
The logical AND of all bits in expr. Caclulation done with 64 bits precision.
MySQL has extended the use of GROUP BY. You can use columns or calculations in the
SELECT
expressions which doesn’t appear in the GROUP BY part. This stands for ’any possible value for
this
group’. By using this, one can get a higher performance by avoiding sorting and grouping on
unnecessary items. For example, in the following query one doesn’t need to sort on b.name:
SELECT a.id,b.name,COUNT(*) from a,b WHERE a.id=b.id GROUP BY a.id
INSERT syntax
INSERT INTO table [ (column_name,...) ] VALUES (expression,...)
or INSERT INTO table [ (column_name,...) ] SELECT ....
An expression may use any previous column in column_name list (or table if no column name
list is
given).
The following holds for a multi-row INSERT statement:
The query cannot contain an ORDER BY clause.
The target table of the INSERT statement cannot appear in the FROM clause of the query.
If one uses INSERT INTO ... SELECT ... then one can get the following info string with
the C API function mysql_info(). @result{Records: 100 Duplicates: 0 Warnings: 0}
Duplicates are number of rows which couldn’t be written because some key would be duplicated.
Warnings are columns which were set to NULL, but have been declared NOT NULL. These will
be set to their default value.
If one sets a time stamp value to anything other than NULL, the time stamp value will be copied
to the result table.
Auto increment fields works as usual.
LOAD DATA INFILE syntax
LOAD DATA INFILE ’table_interval.text’ [REPLACE | IGNORE] INTO TABLE
table_interval [FIELDS [TERMINATED BY ’,’ [OPTIONALLY] ENCLOSED BY
’"’ ESCAPED BY ’’ ]] [LINES TERMINATED BY ’n’] [(field list)]
This is used to read rows from a text file, located on the server, at a very high speed. The server-
client
protocol doesn’t yet support files over a connection. If you only have the file on the client, use
rcp or
ftp to copy it, possibly compressed, to the server before using LOAD DATA INFILE.
                                                                                                 21
To write data to a text file, use the SELECT ... INTO OUTFILE ’interval.txt’ fields
terminated by ’,’ enclosed by ’"’ escaped by ’’ lines terminated
by ’n’ FROM .... syntax.
Normally you don’t have to specify any of the text file type options. The default is a compact
text file
with columns separated with tab characters and all rows end with a newline. Tabs, newlines and 
inside fields are prefixed with a . NULL’s are read and written as N.
45
FIELDS TERMINATED BY has the default value of t.
FIELDS [OPTIONALLY] ENCLOSED BY has the default value of ".
FIELDS ESCAPED BY has the default value of ’’.
LINES TERMINATED BY has the default value of ’n’.
FIELDS TERMINATED BY and LINES TERMINATED BY may be more than 1 character.
If LINES TERMINATED BY is an empty string and FIELDS TERMINATED BY is not empty
then
lines are also terminated with FIELDS TERMINATED BY.
If FIELDS TERMINATED BY and FIELDS ENCLOSED BY both are empty strings (") then
this
gives a fixed row format ("not delimited" import format). With a fixed row size NULL values
are
outputed as a blank string. If you specify OPTIONALLY in ENCLOSED BY, then only strings
are
enclosed in ENCLOSED BY by the SELECT ... INTO statement.
Duplicated ENCLOSED BY chars are removed from strings that start with ENCLOSED BY. For
example: With ENCLOSED BY ’"’:
"The ""BIG"" boss" -> The "BIG" boss
The "BIG" boss -> The "BIG" boss
If ESCAPED BY is not empty then the following characters will be prefixed with the escape
character: ESCAPED BY, ASCII 0, and the first character in any of FIELDS TERMINATED
BY,
FIELDS ENCLOSED BY and LINES TERMINATED BY.
If FIELDS ENCLOSED BY is not empty then NULL is read as a NULL value. If FIELDS
ESCAPED
BY is not empty then N is also read as a NULL value.
If REPLACE is used, then the new row will replace all rows which have the same unique key. If
IGNORE is used, the row will then be skipped if there already exist a record with an identical
unique
key. If none of the above options are used an error will be issued. The rest of the text file will be
ignored if one gets a duplicate key error.
Some possible cases that’s not supported by LOAD DATA:
Fixed size rows (FIELDS TERMINATED BY and FIELDS ENCLOSED BY both are empty)
and BLOB fields.
If some of the separators are a prefix of another.
FIELDS ESCAPED BY is empty and the data contains LINES TERMINATED BY or FIELDS
ENCLOSED BY followed by FIELDS TERMINATED BY.
All rows are read into the table. If a row has too few fields the rest of the fields are set to default
values.
For security reasons the text file must either reside in the database directory or be readable by all.


                                                                                                    22
For more information about the escaped syntax See section Literals. How do you write strings
and
numbers? [p 30] .
46
When the LOAD DATA query is done, one can get the following info string with the C API
function
mysql_info().
@result{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0}
Warnings are incremented for each column which can’t be stored without loss of precision, for
each
column which didn’t get a value from the read text line (happens if the line is too short) and for
each
line which has more data than can fit into the given columns.
Example that loads all fields;
LOAD DATA INFILE ’persondata.text’ INTO TABLE persondata;
See section How should I arrange my table to be as fast/small as possible? [p 59]
UPDATE syntax
UPDATE table SET column=expression,... WHERE where_definition
All updates are done from left to right. If one accesses a column in the expression update will
then use
the current value (a given value or the default value) of the column.
UPDATE persondata SET count=count+1
SHOW syntax. Get information about names of columns.
SHOW DATABASES [LIKE wild]
or SHOW TABLES [FROM database] [LIKE wild]
or SHOW COLUMNS FROM table [FROM database] [LIKE wild]
Gives information about databases, tables or columns. The wild is a LIKE string. FIELDS may
be
used as an alias for COLUMNS.
EXPLAIN syntax. Get information about a SELECT.
EXPLAIN SELECT select_options
Gives information about how and in which order tables are joined. With the help of EXPLAIN
one can
see when one has to add more keys to tables to get a faster select that uses keys to find the
records.
You can also see if the optimiser joins the tables in an optimal order. One can force the optimiser
to
use a specific join order with the STRAIGHT_JOIN option to select.
The different join types are:
system
The table has only 1 record (= system table)
const
The table has at most 1 matching record which will be read at the start of the query. All columns
in this table will be regarded as constants by the rest of the optimiser.
eq_ref
One record will be read from this table for each combination of the previous tables.
47
ref
All records with matching keys will be read from this table for each combination of the previous
                                                                                                23
tables.
all
A full table scan will be done for each combination of the previous tables.
DESCRIBE syntax. Get information about columns.
(DESCRIBE | DESC) table [column]
Gives information about columns. This command is for Oracle compatibility. See section SHOW
syntax. Get information about names of columns. [p 47] Column may be a column name or a
string.
Strings may contain wild cards.
Lock tables syntax
LOCK TABLES table_name [AS alias] READ|WRITE [, table_name READ|WRITE ] ...
UNLOCK TABLES
Locks tables for this thread. Many threads may have a READ lock on the same table, but one can
use
a table with a WRITE lock. One can’t update a table on which one has a read LOCK. When one
uses
LOCK TABLES one must lock all tables one is going to use!
LOCK TABLES t READ, t as t2 READ
SELECT * from t,t2;
All tables are automaticly unlocked when one issues another LOCK TABLES or if the
connection to
the server is closed.
SET OPTION syntax.
SET OPTION SQL_VALUE_OPTION=value, ...
The used options remain in effect for the whole current session.
The different options are:
SQL_SELECT_LIMIT=value
The maximum number of records to return in any select. If a select has a limit clause it overrides
this statement. The default value for a new connection is ’unlimited’.
SQL_BIG_TABLES= 0 | 1
If set to 1 then all temporary tables are stored on disk based. This will be a little slower, but one
will not get the error The table ### is full anymore for big selects that require big
temporary tables. The default value for a new connection is 0 (use in memory temporary tables).
SQL_BIG_SELECTS= 0 | 1
If set to 1 then MySQL will aborts if one will try to make a select with probably will take a very
long time. This is nice to SELECTS with a wrong WHERE statement. A big query is defined as
a
SELECT that will probably have to examine more than max_join_size rows. The default
value for a new connection is 0 (allow all SELECT’s).
48
GRANT syntax. (Compatibility function).
GRANT (ALL PRIVILEGES | (SELECT, INSERT, UPDATE, DELETE,
REFERENCES (column list), USAGE))
ON table TO user,... [WITH GRANT OPTION]
This command doesn’t do anything. It is only in MySQL for compatibility reasons. Privileges in
MySQL is handled with the mysql grant tables. See section How does the privilege system work?
[p
26]

                                                                                                  24
CREATE INDEX syntax (Compatibility function).
CREATE [UNIQUE] INDEX index_name ON table_name ( column_name,... )
This function doesn’t do anything. It is only in MySQL for compatibility reasons. You can create
new
index with ALTER TABLE. See section ALTER TABLE syntax [p 37]
DROP INDEX syntax (Compatibility function).
DROP INDEX index_name
This always succeeds. You can drop an index with ALTER TABLE. See section ALTER
TABLE
syntax [p 37]
Is MySQL picky about reserved words?
It seems that I can’t create a table with column names timestamp or group.
Functions don’t clash with table or column names. (For example ABS is an allowed column
name).
The only restriction is that space is not allowed between a function name and the ’(’ when using
functions.
The following are reserved words in MySQL. Most of them (for example) group, are forbidden
by
ANSI SQL92 as column and/or table names. A few are because MySQL needs them and is
(currently)
using a Yacc parser:
49
action add all alter and
as asc auto_increment between bigint
bit binary blob both by
cascade char character change check
column columns create data databases
date datetime dec decimal default
delete desc describe distinct double
drop escaped enclosed enum explain
fields float float4 float8 foreign
from for full grant group
having ignore in index infile
insert int integer interval int1
int2 int3 int4 int8 into
is key keys leading like
lines limit lock load long
longblob longtext match mediumblob mediumtext
mediumint middleint numeric no not
null on option optionally or
order outfile partial precision primary
procedure privileges read real references
regexp repeat replace restrict rlike
select set show smallint sql_big_tables
sql_big_selects sql_select_limit straight_join table tables
terminated text time timestamp tinyblob
tinytext tinyint trailing to unique
unlock unsigned update usage values
varchar varying with write where
                                                                                               25
zerofill
The following symbols (from the table above) are disallowed by ANSI SQL but allowed by
MySQL
as column/table names. This is because some of theese names are very natural names so a lot of
people has already used them.
ACTION
BIT
DATE
50
ENUM
NO
TEXT
TIME
TIMESTAMP
Go to the first [p 5] , previous [p 26] , next [p 52] , last [p 87] section, table of contents [p 1] .
51
Go to the first [p 5] , previous [p 30] , next [p 57] , last [p 87] section, table of contents [p 1] .
How safe/stable is MySQL
How stable is MySQL?
At TcX, MySQL has worked without any problems in our projects since nid 1996. When
released to a
wider public we noticed that there where some parts of ’untested code’ in MySQL that was
quickly
found by the new user group that don’t do queries exactly like we do at TcX. Each new release
have
had fewer non portability problems than the previous one, even though they have had a lot of
new
features, and we hope that one of the next releases will be possible to be labelled ’stable’.
Each release of MySQL has been usable and there has only been problems when users start to
use
code from ’the gray zones’. Naturally, outdoor users can’t know what the gray zones are and I
hope
this section will clarify those currently known.
We will here try to answer some of the more important questions that seems to concern a lot of
people
and clarify some issues. This section has been put together from the information that has come
forward in the mailing list which is very active in reporting bugs.
How stable is MySQL? Can I depend on MySQL in this project!
This is about the 3.21.x version of MySQL. All known and reported bugs are fixed in the latest
version with the exception of the bugs listed in the BUGS file which are things that are ’design’
related.
MySQL is written in multiple layers and different independent modules. Here is a list of the
different
modules and how tested each of them are.
The ISAM table handler. Stable
(ISAM) where all data is stored. In all MySQL releases there hasn’t been a single (reported) bug
in this code. The only known way to get a corrupted table is to kill the server in the middle of a
update and because all data is flushed to disk between each query even this is unlikely to destroy

                                                                                                    26
any data beyond rescue. There hasn’t been a single bug report about lost data because of bugs in
MySQL either.
The parser and lexical analyser. Stable
There hasn’t been a single reported bug in this system for a couple of months.
The C client code. Stable
No known problems. In early 3.20 releases there were some limitations in the send/receive buffer
size. In 3.21.x the send/receive buffer is now dynamic up to a default of 512K.
mysql, mysqladmin and mysqlshow. Stable
The command line clients have had very few bugs.
mysqldump and mysqlimport. Beta
Rewritten for 3.21.
Basic SQL. Stable
The basic SQL function system and string classes and dynamic memory handling. Not a single
reported bug on this system.
52
Query optimiser. Gamma
Some changes in 3.21.
Range optimiser. Alpha
Totally rewritten for 3.21.x
Join optimiser. Gamma
Small changes for 3.21.
GROUP BY, ORDER BY and related function COUNT(). Beta
Rewritten for 3.21 and throughly tested.
Locking. Gamma
This is very system dependent. One some system there is big problems to use standard OS
locking (fcntl). In these case one should run the MySQL demon with the --skip-locking flag.
Known problems are some Linux systems and SUNOS when using NFS mounted file systems.
Linux threads. Gamma
The only found problem is with the fcntl() call, which is fixed by using --skip-locking. Some
people have reported lockup problems with the 0.5 release.
Solaris 2.5+ pthreads. Stable
We use this for all our production work.
MIT threads (Other systems). Beta
No reported bugs since 3.20.15 and no known bugs since 3.20.16. On some system there is
’misfeature’ where some operations are quote slow (a 1/20 second sleep is done between each
query).
Other thread implementions. Alpha
The ports to other systems is very new and may still have bugs, either in MySQL or most often
in the thread implementation itself.
LOAD DATA..., INSERT ... SELECT. Stable
Some people have thought they have found bugs in this but has turned up being
misunderstandings. So check the manual before reporting bugs!
ALTER TABLE. Gamma
Partly rewritten for 3.21.
mysqlperl. Stable
No bugs reported except a lot of compiling and linking problems.
DBD. Beta
Now maintained by Jochen Wiedmann . Thanks!
                                                                                               27
mysqlaccess. Beta
Written and maintained by Yves.Carlier@rug.ac.be. Thanks!
The Technical Documentation. Beta
It is improving.
MyODBC (uses ODBC SDK 2.5). Beta
It seams to work well with some programs. There is some known problems with Office97.
PowerBuilder doesn’t work yet. Error messages aren’t returned right when using a Microsoft
New ODBC 3.0 driver but this may well be a bug in the Microsoft ODBC 3.0 driver. It isn’t fully
up to ODBC level 2 yet in every regard. (My personal opinion is that the ODBC levels are
defined in such a way that it’s almost impossible to make a simple ODBC driver that works with
all products). Sometimes the MyODBC code must be ported to ODBC 3.0.
TcX provides email support for paying customers, but the MySQL mailing list usually provides
answers to all common questions. Bugs are usually fixed right away with a patch that usually
works
and for serious bugs there is almost always a new release.
53
Why are there is so many release of MySQL? Is it because
there are so many bugs?
Well, MySQL is evolving quite rapidly here at TcX and we want to share this with other MySQL
users. We try to make a release when we have a very useful feature that others seem to have a
need
for.
We also try to help out users who request features that are easy to implement. We also take note
on
what our licensed users want to have and we especially take notes on what our extended email
supported customers want and try to help them out.
No one has to download a new release. The NEWS file will tell you if the new release has
something
you really want.
If there is, by any chance, a fatal bug in a release we will make a new release as soon as possible,
that
fixes the problem. We would like other companies to do this too :)
The 3.21.x version has had many big changes for portability to a lot of different systems. When
the
3.21 release is stable we will remove the alpha/beta suffix and move active development to the
3.22.
Bugs will still be fixed in the stable version. We don’t believe in a complete freeze, as this also
leaves
out bug fixes and things that ’must be done’. ’Somewhat freezed’ means that we will maybe add
small
things that ’almost surely will not affect anything thats already working’.
Checking a table for errors.
If MySQL crashed (for example if the computer is turned off) when all data is not written to disk
the
tables may have become corrupted. To check a table use:
isamchk table_name
This finds 99.99 % of all errors. What it can’t find is when only the data file has been corrupted.
isamchk -e table_name

                                                                                                 28
This goes through all data and does a complete check.
isamchk -ei table_name
As the above but it also prints some statistics.
We at TcX run a cron job on all our important tables once a week.
35 0 * * 0 /path/to/isamchk -s /path/to/dbs/*/*.ISM
This prints out any crashed tables so we can go and examine and repair them when needed.
As we haven’t had any unexpected crashed (without hardware trouble) tables for a couple of
years
now (this is really true), once a week is more than enough of us.
Of course, whenever the machine has done a reboot in the middle of a update one usually has to
check
all the tables that could have been affected. (This is a ’expected crashed table’)
We recommend that to start with one should do a isamchk -s on all updated tables each night
until
one gets to trust MySQL as much as we trust it.
54
Naturally, one could add a check to safe_mysql that, if there is an old pid file left after a reboot,
it
should check all tables that have been modified the last 24 hours.
How to repair tables.
The file format that MySQL uses to store data has been extensively tested, but there is always
instances (like a hard kill on the mysqld process in the middle of a write, a hardware error or a
unexpected shutdown of the computer) when some tables may be corrupted.
The sign of a corrupted table is usually when queries abort unexpectedly and one gets errors like:
table.frm is locked against change.
Can’t find file ’table.ISM’ (Errcode: ###)
Got error ### from table handler. (Error 135 is an exception in this case)
Unexpected end of file.
Record file is crashed.
In thess cases you have to repair your tables. The isamchk extern utility can usually detect and
fix
most things that can go wrong. See section The MySQL table check, optimize and repair
program [p
66] .
If you are going to use isamchk on very large files, you should first decide how much memory
you
want to give to isamchk. More memory gives more speed. For example, if you have more than
32M
ram, try:
isamchk -O sortbuffer=16M -O keybuffer=16M -O readbuffer=1M
-O writebuffer=1M .....
Part 1; Checking
Check the permissions of the table files. Make them readable for the user running mysqld.
cd to the database directory.
Run ’isamchk *.ISM’ or (’isamchk -e *.ISM’ if you have more time).
You only have to repair those tables that your isamchk gives an error. Use option -s to avoid
unnecessary information.
Part 2; Easy safe repair.
If you get weird errors when checking or repairing, like out of memory or if isamchk
                                                                                                  29
crashes, go to part 3.
Try first ’isamchk -rq table’. This will try to repair the .ISM file without touching the
important data table (.ISD). If the data file (.ISD) contains everything and the delete links
point at the right places in the data file, this should work and the table is fixed. Start
repairing next table.
Make a backup of the data file (table.ISD) before continuing.
Use ’isamchk -r table’. This will remove wrong records and deleted records from the data
file and reconstruct the index (.ISM) file.
If the above fails, use ’isamchk -ro table’. This is a little slower but a crash-safer version of
the above.
Part 3; Hard repair.
This should only happen if the first 16K block in the .ISM file is destroyed, contains wrong
information or if the .ISM is missing.
In this case we have to create a new .ISM file. Do as follows:
55
Move the data file .ISD file to some safe place.
Recreate the .ISM file from the .frm file:
shell> mysql database
mysql> delete from table_name;
mysql> quite
Copy (don’t move) the data file (.ISD) back on the newly created .ISD file
Go back to Part 2. (This shouldn’t be a endless loop). isamchk -rq should now work.
Part 4; Very hard repair.
This can only happen if the descriptor file (.frm) also has crashed. This should never happen,
because the .frm file isn’t written to after the table is created.
Restore the .frm file from a backup and go back to Part 3. You can also restore the .ISM file
and go back to Part 2. In the latter case you should start with ’isamchk -r’.
If you don’t have a backup but know exactly how the table was created, create a copy of the
table in another database and copy the .frm and .ISM file from there to your crashed
database and go back to Part 2;
Is there anything special to do when upgrading/downgrading
MySQL?
One can always move the MySQL form and data files between different versions on the same
architecture as long as one has the same base version of MySQL. The current base version is of
course
3. If one changes the sort order by recompiling MySQL one has to do a isamchk -rq on the tables.
Go to the first [p 5] , previous [p 30] , next [p 57] , last [p 87] section, table of contents [p 1] .
56
Go to the first [p 5] , previous [p 52] , next [p 65] , last [p 87] section, table of contents [p 1] .
How to get maximum performance out of MySQL
How does MySQL use memory ?
You can get the currently used buffer sizes with:
> ./mysqld --help
This should result in a list of all mysqld options and configurable variables like the following.
See
section How can I change the buffer sizes of mysqld ? [p 61] .
Possibly variables to option --set-variable (-O) are:
back_log current value: 5
join_buffer current value: 131072
                                                                                                       30
key_buffer current value: 1048568
max_allowed_packet current value: 65536
max_connections current value: 90
max_join_size current value: 4294967295
max_sort_length current value: 1024
net_buffer current value: 8192
record_buffer current value: 131072
table_cache current value: 64
tmp_table_size current value: 131072
sort_buffer current value: 2097144
All threads share the same base memory.
Nothing is memmaped yet (except compressed tables but that’s another story). This is because
32bit memory space of 4GB is not large enough for most large tables. When we get a system
with 64 bit address space we may add general support for memmaping.
When starting mysqld one can specify a key buffer. This will buffer all keys in all tables at
FIFO basis (variable keybuffer).
Each connection uses some thread space, a stack and a connection buffer (variable
net_buffer_length).
Each request doing a sequential scan over a table allocates a read buffer (variable record_buffer).
Each request doing a sort, allocates a sortbuffer and one or two temporary files. The maximum
extra disk-space needed is @math{(sort_key_length +sizeof(long))*2}.
All joins are done in one pass and most temporary tables are memory based (HEAP) tables.
Temporary tables with a big recordlength (= sum of all column length) or that contains BLOB’s
are stored on disk. One current problem is that if the HEAP table exceeds the size of
tmp_table_size, one will get the error: ’The table ### is full’. In the future we will fix this
by automatically changing the in memory (HEAP) table to a disk based (NISAM) table if
needed.
To go around this problem one can increase the -O tmp_table_size=# option to mysqld or
use the SQL option SQL_BIG_TABLES. See section SET OPTION syntax. [p 48] . In MySQL
3.20 the maximum size of the temporary table was recordbuffer*16, so if you are using this
version you have to increase recordbuffer. There also exists a patch to always store
temporary tables on disk, but this will affect the speed of all complicated queries.
Almost all memory used when parsing and calculating is done on a local memory store. No
memory overhead is needed for small items and the normal slow memory allocation/freeing is
avoided. Memory is only allocated for unexpectedly large strings (this is done with malloc/free).
57
Each index file is opened once and the data file is opened once for each concurrently running
thread. For each concurrent thread a table structure, column structures for each column and a
buffer that has the size of 3 * (maximum row length not counting BLOBS) is allocated. A BLOB
uses 5 to 8 bytes +length of blob data.
For each table having BLOBS, a buffer is enlarged dynamically to read in larger BLOB’s. If one
scans a table there will be a allocated buffer as large as the largest BLOB.
All used tables are saved in a cache and used by FIFO. Normally the cache is 64 tables. If a table
has been used by 2 running threads at the same time, there will be 2 entries of the table in the
cache.
A MySQLadmin refresh closes all tables that are not used and marks all used tables to be
closed when the running thread finishes. This will effectively free most used memory.
When running mysqld ps, other programs may report that is takes a lot of memory. This may be

                                                                                                31
caused by thread-stacks on different memory addresses. For example, the Solaris ps calculates
the
unused memory between stacks as used memory. You can verify this by checking available swap
with
’swap -s’. We have tested mysqld with commercial memory-leakage detectors so there should
not be
any memory leaks.
How does MySQL use keys?
All keys, PRIMARY, UNIQUE and INDEX(), are stored in B trees. Strings are automatically
prefixand
end-space compressed.
INDEX(col1, col2) creates a multiple index over the two columns. The key can be seen like a
concatenation of the given columns. If you use INDEX(col1), INDEX(col2) instead of
INDEX(col1,col2) you get two separate keys instead.
SELECT * FROM table WHERE col1=# AND col2=#
In a case of INDEX(col1,col2) the right row(s) can be fetched directly. In a case of
INDEX(col1),
INDEX(col2) the optimiser decides which index will find fewer rows and this index will be used
to
fetch the rows.
If the table has an index INDEX(col1,col2,col3....) the prefix of this can be used by the optimiser
to
find the rows. This means that the above gives you search capabilities on: INDEX(col1) and
INDEX(col1,col2) and INDEX(col1,col2,col3)...
MySQL can’t use a sub part of a key to locate rows through a key.
With the definition INDEX(col1,col2,col3):
SELECT * FROM table WHERE col1=#
SELECT * FROM table WHERE col2=#
SELECT * FROM table WHERE col2=# and col3=#
only the first query will use keys.
58
How does MySQL open & close tables?
The cache of open tables can grow to a maximum of table-cache (default 64, changeable with -O
table_cache=#). A table is never closed, except when the cache is full and another thread tries to
open
a table or if one uses ’mysqladmin refresh’.
When the limit is reached, MySQL closes as many tables as possible, until the cache size has
been
reached or there are no more unused tables. This means that if all tables are in use by some
threads,
there will be more open tables than the cache limit, but the extra tables will be closed eventually.
Tables are closed according to last-used order.
A table is opened (again) for each concurrent access. This means that if one has two threads
running
on the same table or access the table twice in the same query (with AS) the table needs to be
opened
twice. The first open of any table takes 2 file descriptors, each following use of the table takes
only
one file descriptor.
                                                                                                 32
How should I arrange my table to be as fast/small as possible?
Use NOT NULL if possible. It makes everything faster and you save 1 bit per column.
All columns have default values. Only insert when the default value isn’t acceptable. You don’t
have to insert the columns of a timestamp or an autoincremented key in the insert statement. See
section How can I get the unique ID for the last row? [p 83]
Use the smaller INT types if possible to get smaller tables. For example, MEDIUMINT is often
better than INT.
If you don’t have any VARCHAR columns, a fixed size record format will be used. This is much
faster but may unfortunately waste some space. See section What are the different row formats?
Or when to use VARCHAR/CHAR? [p 63] .
To make MySQL optimise queries better, run isamchk -a on the table once it is loaded with
relevant data. This updates a value for each index that tells how many rows that have the same
value for this key in average. Of course, this is always 1 for unique indexes.
To sort an index and data according to an index use isamchk -Sir1 (if you want so sort on
index 1). If you have a unique key that you want to read all records from in numeric order this is
a good way to make that faster.
When loading a table with data use LOAD DATA FROM INFILE. This is usually 20 times
faster than using a lot of INSERTs. If the text file isn’t on the server, rcp it to the server first. See
section LOAD DATA INFILE syntax [p 45] . You can even get more speed when loading data to
tables with many keys by doing:
Create the table in mysql or perl with CREATE TABLE....
Do a mysqladmin refresh.
Use isamchk -k0 database/table_name. This will remove all use of keys from
the table.
Insert data into the table with LOAD DATA INFILE....
If you have pack_isam and want to compress the table, run pack_isam on it.
Recreate the keys with isamchk -rq database/table_name.
Do mysqladmin refresh.
The other possibility to get some more speed to both LOAD DATA FROM INFILE and
INSERT is to enlarge the key buffer. This can be done with the -O key_buffer=# option to
(safe)mysqld. For example 16M should be a good value if you have much RAM :)
When dumping data as textfiles to other programs, use SELECT ... INTO OUTFILE. See
59
section LOAD DATA INFILE syntax [p 45] .
When doing many inserts/updates in a row, you can get more speed by using LOCK TABLES on
the tables. ...FROM INFILE... and ...INTO OUTFILE... are atomic so you don’t have
to use LOCK TABLES when using these. See section Lock tables syntax [p 48] .
To check how you are doing, run isamchk -evi on the .ISM file.
What affects the speed of the INSERT statement?
The time to insert a record consists of:
Connect: (3)
Sending query to server: (2)
Parsing query: (2)
Inserting record: (1 x size of record)
Inserting keys: (1 x keys)
Close: (1)
Where (number) is proportional time. This does not take into calculation the initial overhead to
open
tables (which is done once for each simultaneous running query).
                                                                                                      33
The size of the table slows down the insert of keys with N log N (B-trees).
What affects the speed of DELETE statement?
The delete time of a record is exactly proportional to the number of keys. To increase the seed of
deletes you can increase the size of the key cache. The default key cache is 1M and to get faster
deletes it should be increased a couple of times (try 16M if you have enough memory).
What kind of optimisation is done on the WHERE clause?
(Incomplete, MySQL does a lot of optimisations.)
Brace removal (all unnecessary braces are removed). ((a AND b) AND c OR (((a AND
b) AND (c AND d)))) -> (a AND b) OR (a AND b AND c AND d)
Constant folding. (a<b AND b=c) AND a=5 -> b>5 AND b=c A=5
Constant condition removal (needed because of constant folding). (b>=5 AND b=5) OR
(b=6 and 5=5) or (B=7 and 5=6) -> B=5 or B=6
All constant expressions used by keys are evaluated only once.
Return zero rows if impossible select.
HAVING is merged with WHERE if one doesn’t use GROUP BY or group functions.
For each sub join a simpler WHERE is constructed to get a fast WHERE evaluation for each sub
join and also to skip records as soon as possible.
Find all keys that may be used. Use the key which finds least records. A key is used for the
following cases: =, >, >=, <, <=, BETWEEN and a LIKE with a character prefix like
’something%’.
Remove keys that don’t span all AND levels.
have all preceding key_parts specified.
key = 1 or A = 10 -> NULL (can’t use key.)
60
key = 1 or A = 10 and key=2 -> key = 1 OR key = 2
key_part_1 = const and key_part_3 = const -> key_part_1 = const
Read all constant tables. A constant table is:
1. A table with 0 or 1 record.
2. A table which uses only other const tables and constants on a full unique key.
const_table.key = constant const_table.key_part_1 =
const_table2.column and const_table.key_part_2 = constant
Find the best join combination to join the tables, by trying all possibilities :(. If all columns in
ORDER BY and in GROUP comes from the same table, then this table is preferred first when
joining.
If there is a order clause and a different group clause or if the order or group contains columns
from other tables than the first table in the join cue, a temporary table is created.
For each table use a ranged key, if possible, to read records. Each table index is queried and if
there exists a key range that spans < 30% of the records then a key is used. If no such key can be
found a quick table scan is used.
Before each record is output-ed, skip those that match the HAVING clause.
How can I change the buffer sizes of mysqld ?
With the mysqld -O variable=size command. Example run:
> mysqld --help (or > mysqld -?)
>mysqld --help
/my/monty/sql/mysqld Ver 3.21.0-alpa for SOLARIS 2.5 (SPARCstation)
TcX Datakonsult AB, by Monty. This is FPL, not free software
This software comes with NO WARRANTY: see the file PUBLIC for details.
Starts the mysql server
Usage: /my/monty/sql/mysqld [OPTIONS]
                                                                                                  34
-b, --basedir=path path to installation directory
-h, --datadir=path path to the database root
-#, --debug=... output debug log. Often this is ’d:t:o,filename‘
-T, --debug-info print some debug info at exit
-?, --help display this help and exit
-L, --language=... client error messages in given language
-l, --log[=filename] log connections and queries to file
--log-update[=filename]
log updates to filename.# where # is a unique number
if not given.
--log-isam[=filename]
log all isam changes to file
-P, --port=... Port number to use for connection
-O, --set-variable var=option
give a variable an value. --help lists variables
--skip-new-routines don’t use new possible wrong routines.
--skip-grant-tables start without grant tables. This gives anyone FULL
ACCESS to all tables!
--skip-locking don’t use system locking. To use isamchk one has
to shut down the server.
--skip-name-resolve Don’t resolve hostnames.
All hostnames are IP’s or ’localhost’
--skip-new-routines don’t use new possible wrong routines.
--skip-unsafe-select skip unsafe select optimisations.
61
--socket=... Socket file to use for connection
-V, --version output version information and exit
Current base_dir: /my/monty
Current data_dir: data/
Current language: english/
Possibly variables to option --set-variable (-O) are:
back_log current value: 5
join_buffer current value: 131072
key_buffer current value: 1048568
max_allowed_packet current value: 65536
max_connections current value: 90
max_join_size current value: 4294967295
max_sort_length current value: 1024
net_buffer current value: 8192
record_buffer current value: 131072
table_cache current value: 64
tmp_table_size current value: 131072
sort_buffer current value: 2097144
> safe_mysqld -O key_buffer=512k -O sort_buffer=100k -O record_buffer=100k &
The key_buffer is shared by all threads, the rest are allocated when needed.
mysqld demon starts with a cd to ’mysql-data-dir’. After this, mysqld-data-dir is changed to ’./’
(current dir). All paths (databases, pid file, and log file) are prefixed with ’./’.
What options to use to get MySQL to run at full speed?
More memory gives more speed. You can try something like:
                                                                                                35
mysqld -O key_buffer=16m -O sort_buffer=1m -O record_buffer=512k
--skip-locking
--skip-locking disables file locking between SQL requests. If this is used then the following can
happen:
If mysqld or the machine crashes a table has a higher risk of being corrupted. Tables should at
least be checked with isamchk *.ISM after a crash.
One MUST flush all tables with mysqladmin refresh before one tries to check/repair tables
with isamchk. (isamchk -d table_name is always allowed).
The --skip-locking is default when compiling with MIT threads. This is because flock() isn’t
fully support by MIT threads on all platforms.
How to get MySQL to run as fast as possible with little
memory?
If there are very many connections, ’swapping problems’ may occur, unless mysqld hasn’t been
configured to use very little memory for each connection.
62
For example, for 200 open connections one should have a table cache of at least 200 *
(max_number
of tables in join).
Of course MIT threads may slow down everything a bit, but for key based selects a select is
usually
down in one time frame so there shouldn’t be a mutex locking/thread juggling.
If updates are a problem, updates can be delayed and then do many updates in a row later. Many
updates done in a row are much quicker than one at a time.
If the problem is with MIT threads and one is using FreeBSD x.x. upgrading to FreeBSD 3.0.(or
higher:) should help. This gives a possibility to use sockets (quicker than the current TCP/IP with
MIT
threads) and the thread package is much more integrated.
What are the different row formats? Or when to use
VARCHAR/CHAR?
Actually using no VARCHAR or BLOB types results in a fixed row size. Otherwise CHAR and
VARCHAR are the same.
You can check the format used in a table with isamchk -d.
MySQL has three different table formats:
1. Fixed length tables;
This is the default format.
All non packed columns are space filled.
Very quick.
Easy to cash.
Easy to reconstruct if crashed, of course, this only theoretical :-) as records are in fixed
positions.
Don’t have to be reorganised unless a huge number of records are deleted.
2. Dynamic tables
Is used if there exists any VARCHAR, TEXT or BLOB columns in a table.
All strings are dynamic (except if length < 3).
Each record is preceded with a bitmap for which columns are not empty (this isn’t the same
as null columns).
Each string is saved with a length byte + string. If string is zero length or a number is zero it
takes no extra space, just the zero length bit for each column.
Each record is uses the exact record space required. If a record becomes larger it is split into
                                                                                                  36
as many pieces as required.
Takes little disk space.
If records are changed a lot, isamchk -r should be run now and then to reorganise the
table. This is to get a better layout. Use isamchk -ei table_name for some statistics.
Not as easy to reconstruct because a record may be in many pieces and a link may be
missing.
The expected row length for dynamic sized records is: 3 + (number_of_columns + 7) / 8 +
(number of char columns) + packed_size_of_number_columns + length_of_strings +
(null_columns + 7) / 8. There will be a penalty of 6 bytes for each link. A dynamic record
will be linked whenever a update causes a enlargement of the record. Each new link will be
63
at least 20 bytes, so the next enlargement will probably go in the same link. If not, there will
be another link. You may check how many links there are with isamchk -ed. All links
may be removed with isamchk -r.
3. Compressed tables (this is only with UNIREG/pack_isam)
Read only tables.
Takes very little disk space. Minimises disk usage.
Each record is compressed separately (very little access overhead).
Can handle fixed or dynamic length records, but no BLOBs.
Can be uncompressed with isamchk.
Why so many open tables?
When you run mysqladmin status you get something like:
Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12
This can be somewhat perplexing if you only have 6 tables.
As MySQL is multithreaded it may have many queries on the same table at once. To minimise
the
problem with two threads having different states on the same file, I open the table again for each
concurrent thread. This takes some memory and one extra file descriptor for the data file. The
index
file descriptor is shared all threads.
Go to the first [p 5] , previous [p 52] , next [p 65] , last [p 87] section, table of contents [p 1] .
64
Go to the first [p 5] , previous [p 57] , next [p 75] , last [p 87] section, table of contents [p 1] .
MySQL Utilites
Overview of the different MySQL programs
All MySQL client that communicates with the server uses the following environment variables:
Name Description
MYSQL_UNIX_PORT The default socket. Used with ’localhost’.
MYSQL_TCP_PORT The default TCP port.
MYSQL_PWD The default password.
mysql
A SQL shell (with gnu readline). Supports interactive use or as a non interactive query tool.
When used interactively result is given in a ascii-table format, but when used as a filter the result
is a tab-separated output.
mysqlaccess
Script to check the privileges for a host, user and database combination.
mysqladmin
Administration utility. Create/Drop of databases, reload (read new users) and refresh (flush
tables
                                                                                                    37
to disk, reopen log files). Also gives version and process info.
mysqld
The SQL daemon. This should always be running.
mysqldump
Dump a MySQL database into a file with SQL statements or tab separated text files. Enchanted
freeware originally by Igor Romanenko.
mysqlimport
Imports text-file(s) into respective table(s). Can use all formats supported by LOAD DATA
INFILE. See section LOAD DATA INFILE syntax [p 45]
mysqlshow
Shows information about database, tables, fields and keys.
mysqlbug
This script should always be used when filing a bug report to the MySQL list.
mysql_install_db
Creates the MySQL grant tables with default privileges. This is usually only executed when
installing the first MySQL release on a new system.
isamchk
Check, optimise and repair MySQL tables.
make_binary_release
Makes a binary release of a compiled MySQL. This could be sent by ftp to
www.tcx.se/pub/mysql/Incoming for the convenience of other MySQL users.
msql2mysql
A shell script to convert a mSQL program to MySQL. Doesn’t handle all cases but gives a good
start when converting.
65
replace
Binary used for msql2mysql. Utility program to change strings in place in files or on stdin. Uses
a finite state machine to match longer strings first. Can be used to swap strings, for example
’replace a b b a -- files’ swaps ’a’ and ’b’ in the given files.
safe_mysqld
Starts the mysqld demon with some safety features. Restarts on error and has logging of runtime
information to a log file.
The MySQL table check, optimize and repair program
For infromation about how to use isamchk to repair a crached table: See section How to repair
tables.
[p 55] .
Getting low level table information
To get a description/statistics from a table use the forms below. We will explain some of the
information in more detail later.
isamchk -d table_name
isamchk in ’describe mode’. If one uses ’--skip-locking’ isamchk may report an error for a table
that is updated while isamchk runs, but there isn’t any risk of destroying data. A short form.
ISAM file: company.ISM
Data records: 1403698 Deleted blocks: 0
Recordlength: 226
Record format: Fixed length
table description:
Key Start Len Index Type

                                                                                               38
1 2 8 unique double
2 15 10 multip. text packed stripped
3 219 8 multip. double
4 63 10 multip. text packed stripped
5 167 2 multip. unsigned short
6 177 4 multip. unsigned long
7 155 4 multip. text
8 138 4 multip. unsigned long
9 177 4 multip. unsigned long
193 1 text
For explanations see below.
isamchk -d -v table_name
A little more verbose.
ISAM file: company.ISM
Isam-version: 2
Creation time: 1996-08-28 11:44:22
Recover time: 1997-01-12 18:35:29
Data records: 1403698 Deleted blocks: 0
Datafile: Parts: 1403698 Deleted data: 0
Datafilepointer (bytes): 3 Keyfile pointer (bytes): 3
Max datafile length: 3791650815 Max keyfile length: 4294967294
Recordlength: 226
Record format: Fixed length
r
table description:
66
Key Start Len Index Type Root Blocksize Rec/key
1 2 8 unique double 15845376 1024 1
2 15 10 multip. text packed stripped 25062400 1024 2
3 219 8 multip. double 40907776 1024 73
4 63 10 multip. text packed stripped 48097280 1024 5
5 167 2 multip. unsigned short 55200768 1024 4840
6 177 4 multip. unsigned long 65145856 1024 1346
7 155 4 multip. text 75090944 1024 4995
8 138 4 multip. unsigned long 85036032 1024 87
9 177 4 multip. unsigned long 96481280 1024 178
193 1 text
ISAM file
Name of isam file.
Isam-version
Version of isam format. Currently always 2.
Creation time
When was the data file created.
Recover time
When was the index/data file last reconstructed.
Data records
How many records/rows.
Deleted blocks
How many deleted blocks still have reserved space. See section How to repair tables. [p 55]
                                                                                              39
.
Datafile: Parts
For dynamic record format this shows how many data blocks there are. For a optimised table
without splits this is the same as Data records.
Deleted data
How many bytes of non reclaimed deleted data.
Datafile pointer
How many bytes the datafile pointer has. It is usually 2, 3 or 4 bytes. Most tables manage
with 2 bytes but this cannot be controlled from MySQL yet. For fixed tables this is a record
address. For dynamic tables this is a byte address.
Keyfile pointer
How many bytes has the datafile pointer. It is usually 1, 2 or 3 bytes. Most tables manage
with 2 bytes but this is calculated automatically by MySQL. It is always a block address.
Max datafile length
How long (in bytes) can the table’s data file (.ISD) get.
Max keyfile length
How long (in bytes) can the table’s key file (.ISM) get.
Recordlength
How much space does each record/row take.
Record format
Which format does each record/row have. This example uses Fixed length.
table description
A list of all keys in the table. For each key some low level information is presented.
Key
This key’s number.
Start
Where in the record/row does this index-part start.
67
Len
How long is this index-part. For packed numbers this should always be the full length
of the field. For strings it may be shorter than the full length.
Index
unique or multip.. If one value can exist multiple times in this index.
Type
What data-type does this index part have. This is a C data-type with the options packed,
stripped or empty.
Root
Address of the root index block.
Blocksize
The size of each index block. This is by default 1024 but may be changed a compile
time.
Rec/key
This is a statistical value used by the optimiser. It tells how many records there are per
value for this key. A unique key always has a value of 1. This may be updated after a
table is loaded (or greatly changed) with isamchk -a. If this is not updated at all, a
default value of 30 is given.
The 9th key is a multiple part key with two parts.
isamchk -eis table_name
Shows only the most important information from a table. Slow since it must read the whole table.
                                                                                             40
Checking ISAM file: company.ISM
Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4
Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4
Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3
Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3
Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4
Total: Keyblocks used: 98% Packed: 17%
Records: 1403698 M.recordlength: 226 Packed: 0%
Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00
Recordblocks: 1403698 Deleteblocks: 0
Recorddata: 317235748 Deleted data: 0
Lost space: 0 Linkdata: 0
User time 1626.51, System time 232.36
Maximum resident set size 0, Integral resident set size 0
Non physical pagefaults 0, Physical pagefaults 627, Swaps 0
Blocks in 0 out 0, Messages in 0 out 0, Signals 0
Voluntary contexts switches 639, Involuntary contexts switches 28966
Keyblocks used
How many percent of the keyblocks are used. Since this table has just been reorganised with
isamchk the values are very high (very near theoretical maximum).
Packed
MySQL tries to pack keys with a common suffix. This can only be used for
CHAR/VARCHAR/DECIMAL keys. For long strings like names, this can significantly reduce
the space used. In the above example the 4 key is 10 characters long and gets a 60%
reduction in space.
68
Max levels
How deep is the btree for this key. Large tables with long keys get high values.
Records
How many rows does the table have.
M.recordlength
Average recordlength. For fixed tables this is the recordlength.
Packed
MySQL strips spaces from the end of strings. How many percent did we save by doing this.
Recordspace used
How many percent of the datafile is used.
Empty space
How many percent of the datafile is unused.
Blocks/Record
How many blocks are there per record. This is always 1 for fixed format tables. This value
should stay as close to 1.0 as possible. If it gets to great you can reorganise the table with
isamchk. See section How to repair tables. [p 55] .
Recordblocks
How many blocks are used. For fixed format, this is the same as the number of records.
Deleteblocks
                                                                                                 41
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual
My sql technical reference manual

Contenu connexe

Tendances

Inno db datafiles backup and retore
Inno db datafiles backup and retoreInno db datafiles backup and retore
Inno db datafiles backup and retoreVasudeva Rao
 
Sql injection with sqlmap
Sql injection with sqlmapSql injection with sqlmap
Sql injection with sqlmapHerman Duarte
 
Cassandra 2.1 boot camp, Protocol, Queries, CQL
Cassandra 2.1 boot camp, Protocol, Queries, CQLCassandra 2.1 boot camp, Protocol, Queries, CQL
Cassandra 2.1 boot camp, Protocol, Queries, CQLJoshua McKenzie
 
SQLMAP Tool Usage - A Heads Up
SQLMAP Tool Usage - A  Heads UpSQLMAP Tool Usage - A  Heads Up
SQLMAP Tool Usage - A Heads UpMindfire Solutions
 
A brief introduction to PostgreSQL
A brief introduction to PostgreSQLA brief introduction to PostgreSQL
A brief introduction to PostgreSQLVu Hung Nguyen
 
Pluggable database tutorial 2
Pluggable database tutorial 2Pluggable database tutorial 2
Pluggable database tutorial 2Osama Mustafa
 
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadDevelopers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadmCloud
 

Tendances (14)

Sql Injection 0wning Enterprise
Sql Injection 0wning EnterpriseSql Injection 0wning Enterprise
Sql Injection 0wning Enterprise
 
Inno db datafiles backup and retore
Inno db datafiles backup and retoreInno db datafiles backup and retore
Inno db datafiles backup and retore
 
Sql injection with sqlmap
Sql injection with sqlmapSql injection with sqlmap
Sql injection with sqlmap
 
MySQL and its basic commands
MySQL and its basic commandsMySQL and its basic commands
MySQL and its basic commands
 
Cassandra 2.1 boot camp, Protocol, Queries, CQL
Cassandra 2.1 boot camp, Protocol, Queries, CQLCassandra 2.1 boot camp, Protocol, Queries, CQL
Cassandra 2.1 boot camp, Protocol, Queries, CQL
 
Postgresql
PostgresqlPostgresql
Postgresql
 
SQLMAP Tool Usage - A Heads Up
SQLMAP Tool Usage - A  Heads UpSQLMAP Tool Usage - A  Heads Up
SQLMAP Tool Usage - A Heads Up
 
A brief introduction to PostgreSQL
A brief introduction to PostgreSQLA brief introduction to PostgreSQL
A brief introduction to PostgreSQL
 
Perl Programming - 04 Programming Database
Perl Programming - 04 Programming DatabasePerl Programming - 04 Programming Database
Perl Programming - 04 Programming Database
 
Sqlmap
SqlmapSqlmap
Sqlmap
 
Pluggable database tutorial 2
Pluggable database tutorial 2Pluggable database tutorial 2
Pluggable database tutorial 2
 
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sadDevelopers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
Developers’ mDay 2021: Bogdan Kecman, Oracle – MySQL nekad i sad
 
2016 03 15_biological_databases_part4
2016 03 15_biological_databases_part42016 03 15_biological_databases_part4
2016 03 15_biological_databases_part4
 
Hbase
HbaseHbase
Hbase
 

En vedette

Lest weforget
Lest weforget Lest weforget
Lest weforget Mir Majid
 
.Net framework interview questions
.Net framework interview questions.Net framework interview questions
.Net framework interview questionsMir Majid
 
Employee Profile Management System
Employee Profile Management SystemEmployee Profile Management System
Employee Profile Management Systemncct
 
Employee Management System
Employee Management SystemEmployee Management System
Employee Management SystemAnjali Agrawal
 
Dfd and flowchart
Dfd and flowchartDfd and flowchart
Dfd and flowchartMir Majid
 
Employee Management System
Employee Management SystemEmployee Management System
Employee Management Systemvivek shah
 

En vedette (7)

Lest weforget
Lest weforget Lest weforget
Lest weforget
 
.Net framework interview questions
.Net framework interview questions.Net framework interview questions
.Net framework interview questions
 
Router bridge
Router bridgeRouter bridge
Router bridge
 
Employee Profile Management System
Employee Profile Management SystemEmployee Profile Management System
Employee Profile Management System
 
Employee Management System
Employee Management SystemEmployee Management System
Employee Management System
 
Dfd and flowchart
Dfd and flowchartDfd and flowchart
Dfd and flowchart
 
Employee Management System
Employee Management SystemEmployee Management System
Employee Management System
 

Similaire à My sql technical reference manual

Learn my sql at amc square learning
Learn my sql at amc square learningLearn my sql at amc square learning
Learn my sql at amc square learningASIT Education
 
SQL PPT.pptx
SQL PPT.pptxSQL PPT.pptx
SQL PPT.pptxKulbir4
 
Mysqlppt3510
Mysqlppt3510Mysqlppt3510
Mysqlppt3510Anuja Lad
 
MySQL Reference Manual
MySQL Reference ManualMySQL Reference Manual
MySQL Reference Manualwebhostingguy
 
Mysql Introduction
Mysql IntroductionMysql Introduction
Mysql Introductionhemant meena
 
My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)Gustavo Rene Antunez
 
My sql università di enna a.a. 2005-06
My sql   università di enna a.a. 2005-06My sql   università di enna a.a. 2005-06
My sql università di enna a.a. 2005-06YUCHENG HU
 
xjtrutdctrd5454drxxresersestryugyufy6rythgfytfyt
xjtrutdctrd5454drxxresersestryugyufy6rythgfytfytxjtrutdctrd5454drxxresersestryugyufy6rythgfytfyt
xjtrutdctrd5454drxxresersestryugyufy6rythgfytfytWrushabhShirsat3
 
Aioug vizag oracle12c_new_features
Aioug vizag oracle12c_new_featuresAioug vizag oracle12c_new_features
Aioug vizag oracle12c_new_featuresAiougVizagChapter
 
Performence tuning
Performence tuningPerformence tuning
Performence tuningVasudeva Rao
 
Online Mysql ppt training
Online Mysql ppt trainingOnline Mysql ppt training
Online Mysql ppt trainingvibrantuser
 

Similaire à My sql technical reference manual (20)

Learn my sql at amc square learning
Learn my sql at amc square learningLearn my sql at amc square learning
Learn my sql at amc square learning
 
SQL PPT.pptx
SQL PPT.pptxSQL PPT.pptx
SQL PPT.pptx
 
Mysqlppt3510
Mysqlppt3510Mysqlppt3510
Mysqlppt3510
 
Mysql tutorial
Mysql tutorialMysql tutorial
Mysql tutorial
 
MySQL Reference Manual
MySQL Reference ManualMySQL Reference Manual
MySQL Reference Manual
 
Mysql tutorial 5257
Mysql tutorial 5257Mysql tutorial 5257
Mysql tutorial 5257
 
Mysql Introduction
Mysql IntroductionMysql Introduction
Mysql Introduction
 
Performance Tuning
Performance TuningPerformance Tuning
Performance Tuning
 
Fudcon talk.ppt
Fudcon talk.pptFudcon talk.ppt
Fudcon talk.ppt
 
Mysql2
Mysql2Mysql2
Mysql2
 
Mysql
MysqlMysql
Mysql
 
Mysql2
Mysql2Mysql2
Mysql2
 
My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)My First 100 days with a MySQL DBMS (WP)
My First 100 days with a MySQL DBMS (WP)
 
My sql università di enna a.a. 2005-06
My sql   università di enna a.a. 2005-06My sql   università di enna a.a. 2005-06
My sql università di enna a.a. 2005-06
 
unit-ii.pptx
unit-ii.pptxunit-ii.pptx
unit-ii.pptx
 
xjtrutdctrd5454drxxresersestryugyufy6rythgfytfyt
xjtrutdctrd5454drxxresersestryugyufy6rythgfytfytxjtrutdctrd5454drxxresersestryugyufy6rythgfytfyt
xjtrutdctrd5454drxxresersestryugyufy6rythgfytfyt
 
Aioug vizag oracle12c_new_features
Aioug vizag oracle12c_new_featuresAioug vizag oracle12c_new_features
Aioug vizag oracle12c_new_features
 
Performence tuning
Performence tuningPerformence tuning
Performence tuning
 
Online Mysql ppt training
Online Mysql ppt trainingOnline Mysql ppt training
Online Mysql ppt training
 
Sql server basics
Sql server basicsSql server basics
Sql server basics
 

Plus de Mir Majid

Plus de Mir Majid (16)

Use case diagrams
Use case diagramsUse case diagrams
Use case diagrams
 
Dotnet basics
Dotnet basicsDotnet basics
Dotnet basics
 
Holographic memory
Holographic memoryHolographic memory
Holographic memory
 
Data recovery
Data recoveryData recovery
Data recovery
 
Simulation programs
Simulation programsSimulation programs
Simulation programs
 
8086 assembly language
8086 assembly language8086 assembly language
8086 assembly language
 
Compiler Design
Compiler DesignCompiler Design
Compiler Design
 
Assembler
AssemblerAssembler
Assembler
 
Lessons from life_2
Lessons from life_2Lessons from life_2
Lessons from life_2
 
Child faces 2
Child faces 2Child faces 2
Child faces 2
 
Time management
Time managementTime management
Time management
 
E hospital manager
E hospital managerE hospital manager
E hospital manager
 
Crypt
CryptCrypt
Crypt
 
Smart cards
Smart cardsSmart cards
Smart cards
 
Rfid
RfidRfid
Rfid
 
Rfid seminar
Rfid seminarRfid seminar
Rfid seminar
 

My sql technical reference manual

  • 1. MySQL Technical Reference Manual. What is MySQL? MySQL is a SQL (Structured Query Language) database server. SQL is the most popular database language in the world. MySQL is a client server implementation that consists of a server daemon mysqld and many different client programs/libraries. The main goals of MySQL are speed and robustness. The base upon which MySQL is built is a set of routines that have been used in a highly demanding production environment for many years. The main features in MySQL • Multi-threaded • C, C++, JAVA, Perl, Python and TCL API’s. • Lots of column types like: signed/unsigned integers 1,2,3,4,8 bytes long, FLOAT, CHAR,VARCHAR, TEXT, BLOB, DATE, SET and ENUM types. • Join optimizer with one-sweep multi-join (all joins made in one pass). • Full function support in the SELECT and WHERE parts. Example: select column1+column2 from table where column1/column2 > 0 • SQL functions are implemented through a very optimized class library and should be as fast as they can get! Usually there shouldn’t be any memory allocation at all after the query initialization. • Full support for SQL GROUP BY and ORDER BY. Support for group functions (SUM, MAX and MIN). • A privilege and password system with is very flexible and secure. Allows host based verification. • All password traffic on the net is encrypted. • Very fast B-tree disk tables with key compression. • Fixed and variable length records. • 16 indexes/table. Each index may consist of 1 to 15 columns/parts of columns. Max key length is 127 bytes. A key may be a prefix of a CHAR field. • ODBC Open-DataBase-Connectivity for Windows95 (with source). All ODBC 2.5 functions and lots of others. • In memory hash tables always used as temporary tables. • Can handle big databases (we are using MySQL with some databases that contain 50,000,000 records). • All columns have default values. One can always use INSERT on any subset of columns. • Uses GNU autoconf for portability. • Written in C and C++. Tested with gcc 2.7.2. • A thread based memory allocation system (very fast and no memory trashing). • No memory leaks. Tested with a commercial memory leakage detector (purify). • A very fast table check and repair utility (isamchk). • All data saved in ISO8859_1 format. All comparisons for normal string columns are case insensitive. 1
  • 2. Full ISO8859_1 (Latin1) support. For example Scandinavian åäö is allowed in table and column names. • Sorts by ISO8859_1 Latin1 (the Swedish way at the moment). It is possible to change this in the source by adding new sort order arrays. • Alias on tables and columns as in the SQL92 standard. avg & count). • INSERT,UPDATE and DELETE returns how many rows were affected. • Function names do not clash with table or column names. For example ABS is a valid column name. The only restriction is that space is not allowed between a function name and the ’(’ when using functions. • All MySQL commands have --help or -? for help. • The server currently supports error messages to clients in many languages. See section What languages are supported by MySQL.. • The clients uses a TCP connection or unix socket when connecting to the MySQL server. • User commands as show tables, show keys from table and show columns from Table Problems starting MySQL Check the log file to see if mysqld started up correctly. cd <localstatedir default /usr/local/var> tail <your host name>.log To verify that MySQL is working, run the following tests: > cd /usr/local/bin > ./mysqlshow +-----------+ | Databases | +-----------+ | mysql | +-----------+ > ./mysqlshow mysql Database: mysql +--------+ | Tables | +--------+ | db | | host | | user | +--------+ > ./mysql -e "select host,db,user from db" mysql +------+--------+------+ | host | db | user | +------+--------+------+ | % | test | | | % | test_% | | +------+--------+------+ There is also a benchmark suite so you can compare how MySQL perform on different platforms. In the near future this will also be used to compare MySQL to other SQL databases. > cd bench > run-auto-increment-test 2
  • 3. You can also run the tests in the test subdirectory. To run ‘auto_increment.tst’: ./mysql -vf test < ./tests/auto_increment.tst 24 Expected results are shown in the file ‘./tests/auto_increment.res’. Automatic start/stop of MySQL To start or stop MySQL use the following commands: scripts/mysql.server stop scripts/mysql.server start You might want to add these start and stop commands in the appropriate places in your /etc/rc* files when you start using MySQL for production applications. How to debug MySQL If you are porting MySQL to an new system you should first try to get mysys/thr_lock and mysys/thr_alarm to work. They shouldn’t core dump and not print any error (they also print a lot of other information). Also see the file ‘PORTING’ in the distribution. By starting bin/safe_mysqld with --log you will get a log in install-directory/var/’hostname’.log (the top level database directory). This log will contain all successful connections and all commands issued to the MySQL server. If you have compiled MySQL with --with-debug=yes you can can also get a very informative log with: libexec/mysqld --debug which makes a large log in /tmp/mysql.trace. The default debug option is d:i:t:o,/tmp/mysql.trace. You can get a smaller log with: libexec/mysqld --debug=d,info,query,general:o,/tmp/mysql.trace or an even smaller (on stdout): libexec/mysqld --debug=d,general,query You can get more information about the debug switches by examining the file dbug/dbug.c. If you have a problem with mysqld that it crashes and you want this quickly solved, you should include a trace file with your mail if possible. Trace files can be posted directly to @email{mysql-support@tcx.se} to avoid long messages to the standard mail list. If the trace file is big you should use ftp and send it to ftp://www.tcx.se/pub/mysql/secret/ together with a mysqldump of any tables that you think can help to solve the problem. The context of the above directory is hidden for outside users so no one except the TCX staff can look at what you send into it. Go to the first [p 5] , previous [p 19] , next [p 26] , last [p 87] section, table of contents [p 1] . 25 Go to the first [p 5] , previous [p 24] , next [p 30] , last [p 87] section, table of contents [p 1] . How does MySQL privileges work MySQL has a advanded but non standard security/privileges system. How does the privilege system work? The MySQL privilege system makes sure that each user may do exactly the things that they are 3
  • 4. supposed to be allowed to do. The system decides to grant different privileges depending on which user connects from which host to which database. The decision is based on the contents of the three tables in the MySQL database: user, host and db. The grant tables privileges on rows are select, insert, update and delete. The table and database privileges are create and drop. Create and drop are for both tables and databases. Since a user with a drop grant can delete any table, this is the same thing as a drop grant for the database. Other privileges give the right to use files (for LOAD DATA INFILE and SELECT INTO OUTFILE) and to use the administrative commands shutdown, reload, refresh and process, to get the current process list. The privilege tables are read into mysqld with mysqladmin reload. If the privilege tables are empty or non-existent or if the server is started with --skip-grant-tables, full access is granted to everyone. You can always test your privileges with the script mysqlaccess, which Yves Carlier has provided for the MySQL distribution. See section Why do I get ’Access denied’? [p 78] The host and db fields may contain a SQL regexp with chars % and _. Leaving any of these fields empty is equivalent to setting it to ’%’. A host may be localhost, a hostname, an IP number or an SQL expression. An empty host in the db table means any host in the host table. An empty host in the host or user table means any host that can create a TCP connection to your server. A db is the name of a database or an SQL regexp. An empty user field means any username will do. An empty password means that the entry will only be used if no password is supplied. The privileges from the user table are OR’ed to the db table. This means that a superuser only needs to be in the user table with all privilege-flags set to Y. Everything granted in the user table is valid for every database that cannot be found in the db table. For this reason, it might be wise to grant users (apart from superusers) privileges on a per- database basis only. The host table is mainly there to maintain a list of "secure" servers. At TcX host contains a list of all machines on the local network. These are granted all privileges. 26 The connecting user’s privileges are calculated by the following algorithm: 1. First sort all three tables by host by putting hosts without wildcards first, followed by hosts with wildcards and entries with host = "". Within each host, di.e. very much like GROUP BY Host, sort by user using the same rules. Finally, in the db table, sort by db using the same rules. In the steps below, we will look through the sorted tables and always use the first match found. 2. Get the privileges for the connecting user from the db table using the first match found. Call this set of privileges P. 4
  • 5. 3. If host = "" for the entry found in the db table, AND P with the privileges for the host in the host table, i.e. remove all privileges that are not "Y" in both. (If host <> "", P is not affected. In suchcases, host must have matched the connecting host’s name at least partially. Therefor it can be assumed that the privileges found in this row match the connecting host’s profile.) 4. OR (add) P with the privileges for the user from the user table, i.e. add all privileges that are "Y" in user. The connecting user gets the set of privileges P. Let’s show an example of the sorting and matching! Suppose that the user table contains this: +-----------+----------+- | Host | User | ... +-----------+----------+- | % | root | ... | % | jeffrey | ... | localhost | root | ... | localhost | | ... +-----------+----------+- Then the search order will be: localhost/root localhost/any any/jeffrey any/root So jeffrey attempting to connect on localhost will be matched by the localhost/any line, not by the any/jeffrey line. The first match found is used! So if you have access problems, print out the user table, sort it by hand, and see where the match is being made. Here follows an example to add a user ’custom’ that can connect from hosts ’localhost’, ’server.domain’ and ’whitehouse.gov’. He wants to have password ’stupid’. The database ’bankacount’ he only want to use from ’localhost’ and the ’customer’ database he wants to be able to reach from all three hosts. shell> mysql mysql. mysql> insert into users (host,user,password) values(’localhost’,’custom’,password(’stupid’)); mysql> insert into users (host,user,password) values(’server.domain’,’custom’,password(’stupid’)); mysql> insert into users (host,user,password) values(’whitehouse.gov’,’custom’,password(’stupid’)); 27 mysql> insert into db (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) values (’localhost’,’bankacount’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’); mysql> insert into db (host,db,user,Select_priv,Insert_priv,Update_priv,Delete_priv, Create_priv,Drop_priv) values 5
  • 6. (’%’,’customers’,’custom’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’); You can of course also use xmysqladmin, mysql_webadmin, mysqladmin and even xmysql to insert/change and update values in the privilege tables. You can find these utilities in the Contrib directory. Adding new user privileges to MySQL To add privileges to the MySQL database: This assumes the current user has insert privileges for the mysql db table and reload privileges. The server (mysqld) has to be running. If it is not, start it with safe_mysqld --log &. > mysql mysql insert into user values (’%’,’monty’,password(’something’),’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’,’Y’) ; insert into user (host,user,password) values(’localhost’,’dummy’,") ; insert into user values (’%’,’admin’,",’N’,’N’,’N’,’N’,’N’,’N’,’Y’,’N’,’Y’,’Y’) ; quit > mysqladmin reload This makes three new users: Monty Full superuser, but must use password when using MySQL. admin Doesn’t need a password but is only allowed to use mysqladmin reload, mysqladmin refresh and mysqladmin processlist. May be granted individual database privileges through table db. dummy Must be granted individual database privileges through table db. Default privileges. The default privileges (set in ‘scripts/mysql_install_db’) is that root can do anything. Any user can do anything with any database whose name is ’test’ or starts with ’test_’. A normal user can’t use mysqladmin shutdown or mysqladmin processlist. See the script (‘scripts/mysql_install_db’) for an example on how to add other users. The privilege tables are read into mysqld with ’mysqladmin reload’. If the privilege tables are empty (or non-existent) full access are granted to everyone. 28 A example of permission setup. A common mistake is to try something like: INSERT INTO user VALUES (’%’,’jeffrey’,’bLa81m0’,’Y’,’Y’,’Y’,’N’,’N’,’N’,’N’,’N’, ’N’,’N’); Then (of course) a mysqladmin reload to make the authentication change take effect, then trying to connect to the server: $ ./mysql -h sqlserver -u jeffrey -p bLa81m0 test Access denied Try this instead: INSERT INTO user VALUES (’%’,’jeffrey’,password(’bLa81m0’),’Y’,’Y’,’Y’,’N’,’N’,’N’,’N’,’N’,’N’,’N’); And like before mysqladmin reload to make the authentication change take effect. Now things should work. Go to the first [p 5] , previous [p 24] , next [p 30] , last [p 87] section, table of contents [p 1] . 29 6
  • 7. Go to the first [p 5] , previous [p 26] , next [p 52] , last [p 87] section, table of contents [p 1] . MySQL language reference Literals. How do you write strings and numbers? STRINGS A string may have ’ or " around it. is a escape character. The following escape characters are recognised: 0 A ascii 0 character. n A newline character. t A tab character. r A return character. b A backspace character. ’ A ’ character. " A " character. A character. % A % character. This is used in wild-card strings to search after %. _ A _ character. This is used in wild-card strings to search after _. A ’ inside a string started with ’ may be written as ". A " inside a string started with " may be written as "". MySQL> select ’hello’, "’hello’", ’""hello""’, "’h"e"l"l"o"’, "hel""lo"; 1 rows in set (0.00 sec) +-------+---------+-----------+-------------+--------+ | hello | ’hello’ | ""hello"" | ’h’e’l’l’o’ | hel"lo | +-------+---------+-----------+-------------+--------+ | hello | ’hello’ | ""hello"" | ’h’e’l’l’o’ | hel"lo | +-------+---------+-----------+-------------+--------+ mysql> select ’hello’, "hello", ’""hello""’, "’ello", ’e"l"lo’, ’’hello’; 1 rows in set (0.00 sec) +-------+-------+-----------+-------+--------+--------+ | hello | hello | ""hello"" | ’ello | e’l’lo | ’hello | +-------+-------+-----------+-------+--------+--------+ | hello | hello | ""hello"" | ’ello | e’l’lo | ’hello | +-------+-------+-----------+-------+--------+--------+ mysql> select "ThisnIsnFournlines"; 1 rows in set (0.00 sec) +--------------------+ | This Is Four lines | +--------------------+ | This 30 Is Four lines | +--------------------+ If you want to insert binary data into a blob the following characters must be represented by escape sequences: 7
  • 8. 0 Ascii 0. Should be replaced with "0" (A backslash and a 0 digit). Ascii 92, backslash ’ Ascii 39, Single quote " Ascii 33, Double quote NUMBERS Integers are just a sequence of digits. Floats use . as a decimal separator. Examples of valid numbers are: 1221, 294.42, -32032.6809e+10. NULL When using the text file export formats, NULL may be represented by N. See section LOAD DATA INFILE syntax [p 45] Column types. The following column types are supported: Name Description Size TINYINT [(max display size)] [UNSIGNED] [ZEROFILL] A very small integer. Signed range -128 - 127. Unsigned range 0 - 255. 1 SMALLINT [(max display size)]. [UNSIGNED] [ZEROFILL] A small integer. Signed range -32768 - 32767. Unsigned range 0 - 65535. 2 MEDIUMINT [(max display size)] [UNSIGNED] [ZEROFILL] A medium integer. Signed range -8388608-8388607. Unsigned range 0 - 16777215. 3 INT [(max display size)] [UNSIGNED] [ZEROFILL] A normal integer. xSigned range -2147483648 - 2147483647. Unsigned range 0 - 4294967295. 4 BIGINT [(max display size)] [UNSIGNED] [ZEROFILL] A large integer. Signed range -9223372036854775808 - 9223372036854775807. Unsigned Range 0 - 18446744073709551615. 8 31 FLOAT(Precision) A small floating point number. Precision can be 4 or 8. FLOAT(4) is a single precision number and FLOAT(8) is a double precision number (se the DOUBLE entry). This syntax is for ODBC compatibility. Range -3.402823466E+38F - -1.175494351E-38, 0, 8
  • 9. -1.175494351E-38 - 3.402823466E+38F. 4 FLOAT [(max display size,number of decimals)] A small floating point number. Cannot be unsigned. Range -3.402823466E+38F - -1.175494351E-38, 0, -1.175494351E-38 - 3.402823466E+38F. 4 DOUBLE PRECISION [(max display size,number of decimals)] A normal floating point number. Cannot be unsigned. Range -1.7976931348623157E+308 - -2.2250738585072014E-308, 0, 2.2250738585072014E-308 - 1.7976931348623157E+308. 8 REAL [(length,decimals)] Same as DOUBLE 8 DECIMAL [(max display size,number of decimals)] An unpacked floating point number. Cannot be unsigned. Currently the same range maximum range as a double. Behaves as a CHAR column M+D NUMERIC [(length,decimals)] Same as DECIMAL M+D TIMESTAMP [(display size)] An automatic timestamp. 4 DATE A type to store date information. Uses the "YYYY-MM-DD" syntax, but may be updated with a number or a string. Understands at least the following syntaxes: ’YY-MM-DD’, ’YYYY-MM-DD’, ’YYMMDD’, ’YYMM’, ’YY’. Range 0000-00-00 to 9999-12-31. 4 TIME A type to store time information. Uses the "HH:MM:SS" syntax, but may be updated with a number or a string. Understands at least the following syntaxes: ’HH:MM:DD, ’HHMMDD’, ’HHMM’, ’HH’. 3 DATETIME A type to store date and time information. Format "YYYY-MM-DD HH:MM:SS". Takes 8 bytes. Range ’0000-01-01 00:00:00’ - ’9999-12-31 23:59:59’. 8 CHAR(max_length) [binary] A fixed length string that is always filled up with spaces to the specified length. Range 1 - 255 characters. All end space are removed when retrieved. Is sorted and compared case insensitively unless the binary keyword is given. M 9
  • 10. VARCHAR(max_length) [binary] A variable length string that is stored with its length. Maximum range 1 - 255 characters. Is sorted and compared case insensitively unless the binary keyword is given. L+1 TINYTEXT and TINYBLOB A TEXT/BLOB with max length of 255 characters. L + 1 TEXT and BLOB A TEXT/BLOB with max length of 65535 characters. L + 2 32 MEDIUMTEXT and MEDIUMBLOB A TEXT/BLOB with max length of 1677216 characters. L + 3 LONGTEXT and LONGBLOB A TEXT/BLOB with max length of 4294967295 characters. L+4 ENUM(’value’,’value2’,...) A string object that can have only one set of allowed values. See section More about data types [p 33] . 1 or 2 SET(’value’,’value2’,....) A string object that can have one or many values of a set of allowed values. See section More about data types [p 33] . 1-8 More about data types Database size info. In the above table L means the actual length of a instance and M the maximum length. So L+1 for "abcd" means 5 bytes in the database. If you use any data type with a L in the length field you will get a variable length record format. The numeric types All integer types can have a optional argument unsigned. This can be used when you only want to allow positive numbers in the column or you need a little bigger numerical range for the column. Also for all integer columns the optional argument ZEROFILL means that the column will be padded with zeroes upto the maximum length. Max display size and decimals are for formating and calculation of max column width. TIMESTAMP type Has a range of 1 Dec 1970 time 0.00 to sometime in the year 2106 and a resolution of one second. Will be automatically updated if not used in a statement that updates a row or if set to NULL. Can be a (part of) a key. Note that if you have many timestamp fields in a row, then only the first timestamp field will be automatically updated. Any timestamp field will be set to the current time if set to NULL. 10
  • 11. Depending on the display size one gets one of the following formats: "YYYY-MM-DD HH:MM:SS", "YY-MM-DD HH:MM:SS", "YYYY-MM-DD" or "YY-MM-DD". TEXT and BLOB types These are objects that can have a variable length without upper limit. All TEXT and BLOB objects are stored with is length (saved in 1 to 4 bytes depending on the type of object). The maximum TEXT and BLOB length you can use is dependent on available memory and client buffers. The only differences between TEXT and BLOB is that TEXT is sorted and compared case insensitively while BLOB is compared case insensitive (by character values). TEXT and BLOB objects CANNOT be keys. A BLOB is a binary large object which can hold any amount of data :) There are 4 kinds of blobs See section Column types. [p 31] . Normally one can regard a BLOB as a VARCHAR without a specified limit. 33 TEXT is a BLOB that is sorted and compared case insensitively. There are some constraints because of the message buffer used. The default size of the buffer is 64K for the server and 512K for the clients. To change the buffer length for the server, use mysqld -O max_allowed_packet=max_blob_length. This allows the message buffer to grow up to this limit when needed. MyODBC defines BLOB:s as LONGVARBINARY and TEXT:s as LONGVARCHAR. Restrictions for BLOB and TEXT columns: 1. A BLOB or TEXT cannot be a key or a part of a key 2. When one sorts or groups a BLOB or TEXT only the first max_sort_length (default 1024) of the blob is used. This value can be changed by the -O option when starting the mysqld demon. One can group on an expression involving a BLOB/TEXT: SELECT id,SUBSTR(blob,1,100) GROUP BY 2 3. There is no end space truncation for BLOB and TEXT as there is for CHAR and VARCHAR. ENUM type A string object that can have only one set of allowed values. The value to be stored may be given case independently. If one tries to store a non existing value, "" is stored. If used in a number context this object returns/stores the value index. If there is less than 255 possible values this object occupies 1 byte, else two bytes (with a maximum of 65535 different values). Note that if a integer is put in the ENUM you get the corresponding string with the first counting as number zero. Sorting on ENUM types are done after the order of the strings in the enum. For example the column test ENUM("one","two", "three") can have any off these values: "one" "two" "three" 11
  • 12. SET type A string object that can have one or many values of a set of allowed values. Each value is separated by a ’,’. If used in a number context this object returns/stores the bit positions of the used values. This object occupies (number_of_different_values-1)/8+1 bytes, rounded up to 1,2,3,4 or 8. One can’t have more than 64 different values. Note that if a integer is put in the SET you get the corresponding string with the first bit corresponding to the first string.Sorting on SET types are done numericaly. For example the column test SET("one","two") can have any off these values: "" "one" "two" "one,two" 34 Column indexes You can have indexes on all MysQL column types except BLOB and TEXT. Using indexes on the relevant columns is the most important thing is getting you selects to run fast. For CHAR and VARCHAR columns you can have a index on a prefix. The example below show how to create a index for the first 10 characters of a column. This is much faster and requires less disk space than having a index on the whole field. CREATE TABLE test ( name CHAR(200), KEY name (last_name(10)); Multiple field indexes MySQL can have one index on parts of different columns. A multiple column key can be considered as a sorted array where the columns are concatenated. Suppose that you have a table: CREATE TABLE test ( id INT, last_name CHAR(30), first_name CHAR(30), PRIMARY KEY (id), KEY name (last_name,first_name)); Then the key ’name’ is a key over last_name and first_name. The ’name’ key will be used in the following queries: SELECT * FROM test WHERE last_name="Widenius"; SELECT * FROM test WHERE last_name="Widenius" AND first_name="Michael"; SELECT * FROM test WHERE last_name="Widenius" AND (first_name="Michael" OR first_name="Monty"); SELECT * FROM test WHERE last_name="Widenius" and first_name >="M" and first_name < "N"; The ’name’ key will NOT be used in the following queries: SELECT * FROM test WHERE first_name="Michael"; SELECT * FROM test WHERE last_name="Widenius" or first_name="Michael"; Type mapping (to ease moving tabel definitions between different 12
  • 13. databases engines) To support easier use of code from different SQL vendors, MySQL does supports the following mappings: 35 binary(num) char(num) binary char varying varchar float4 float float8 double int1 tinyint int2 smallint int3 mediumint int4 int int8 bigint long varbinary blob long varchar text middleint mediumint varbinary(num) varchar(num) binary CREATE TABLE syntax. CREATE TABLE table_name ( create_definition,... ) create_definition: column_name type [DEFAULT default_value] [NOT NULL | NULL] [ PRIMARY KEY ] [reference_definition] or PRIMARY KEY ( key_column_name,... ) or KEY [key_name] KEY( key_column_name,...) or INDEX [key_name] ( key_column_name,...) or UNIQUE [key_name] ( key_column_name,...) or FOREIGN KEY key_name ( key_column_name,...) [reference_definition] or CHECK (expr) key_column_name: column_name [ (length) ] reference_definition: REFERENCES table_name [( key_coulmn_name,...)] [ MATCH FULL | MATCH PARTIAL] [ ON DELETE reference_option] [ ON UPDATE reference_option] reference_option: RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT The FOREIGN KEY, CHECK and REFERENCE syntax are only for compatibility. They don’t actually do anything. If a column doesn’t have a DEFAULT value and is not declared as NOT NULL, the default value is NULL. 36 ZEROFILL means that number is pre-zeroed to maximal length. With INT(5) ZEROFILL a value of 5 is retrieved as 00005. BINARY means that the column will be compared case sensitive. The default is that all strings are compared case insensitive. BINARY is ’sticky’ which means that if a column marked ’binary’ is used in a expression, the whole expression is compared ’binary’. INDEX is only a synonym for KEY. 13
  • 14. If one doesn’t assign a name to a key, the key will get the same name as the first key_column with an optional _# to make it unique. Key columns and timestamp columns can’t be NULL. For these columns the NULL attribute is silently removed. With column_name(length) syntax one can specify a key which is only a part of a string column. This can make the index file much smaller. A number column may have the additional attribute AUTO_INCREMENT to automatically get the largest value+1 for each insert where column value is NULL or 0. See section How can I get the unique ID for the last row? [p 83] One can insert NULL for timestamp and auto_increment columns. This results in the current time / the next number. Blob columns can’t be keys. When one groups on a blob only the first ’max_sort_length’ bytes are used See section Limitations of BLOB and TEXT types [p 21] . Deleted records are in a linked list and subsequent inserts will reuse old positions. To get smaller files one can use the isamchk utility to reorganise tables. Each null column takes 1 bit extra, rounded up to the nearest byte. The maximum record length can be calculated as follows: 1+ sum_of_column_lengths + null_columns/8 + number of variable length columns. In some cases an attribute may silently change after creation: VARCHAR columns with a length of 1 or 2 are changed to CHAR. When using one VARCHAR column all CHAR columns longer than 2 are changed to VARCHAR’s. On INSERT/UPDATE all strings (CHAR and VARCHAR) are silently chopped/padded to the maximal length given by CREATE. All end spaces are also automatically removed. For example VARCHAR(10) means that the column can contain strings with a length up to 10 characters. Something/0 gives a NULL value. The regular expression function (REGEXP and RLIKE) uses ISO8859-1 (Latin1) when deciding the type of a character. ALTER TABLE syntax ALTER [IGNORE] TABLE table_name alter_specification [, alter_specification ...] alter_specification: ADD [COLUMN] create_definition or CHANGE [COLUMN] old_column_name create_definition or ALTER [COLUMN] column_name { SET DEFAULT literal | DROP DEFAULT } or DROP [COLUMN] column_name or DROP PRIMARY KEY DROP INDEX key_name ALTER TABLE works by creating a temporary table and copying all information to it and then the old table is deleted and the new one is renamed. This is done in such a way that all updates are automatically redirect to the new table without any failed updates. While the ALTER TABLE is working, the old table is readable for other clients. Table updates/writes to the table are stalled 37 and only executed after the new table is ready. If IGNORE isn’t specified then the copy will be aborted and rolled back if there exists any duplicated unique keys in the new table. This is a MySQL extension. 14
  • 15. The CHANGE column_name, DROP column_name and DROP INDEX are MySQL extensions to ANSI SQL92. The optional word COLUMN is a pure noise word and can be omitted. The ADD and CHANGE takes the same create_definition as CREATE TABLE. See section CREATE TABLE syntax. [p 36] . ALTER COLUMN sets a new default value or removes the old default value for a column. DROP INDEX removes an index. This is an MySQL extension. The FOREIGN KEY syntax in MySQL exists only for compatibility with other SQL vendors CREATE TABLE commands: It doesn’t do anything. See section How standards compatible are MySQL [p 19] If one drops a column_name which is part of some key, this key part is removed. If all key parts are removed then the key is removed. DROP PRIMARY KEY drops the first UNIQUE key in the table. CHANGE tries to convert data to the new format as good as possible. With mysql_info(MYSQL*) one can retrieve how many records were copied and how many records were deleted because of multiple keys. To use ALTER TABLE one has to have select, insert, delete, update, create and drop privileges on the table. DROP TABLE syntax. DROP TABLE table_name [, table_name....] Removes one or more tables. All the data and the definition is removed so take it easy with this command! DELETE syntax. DELETE FROM table_name WHERE where_definition Returns records affected. If one does a delete without a where clause then the table is recreated which is much faster than doing a delete for each row. In these cases, the SQL command returns zero as affected records. Using DELETE FROM table_name will work even if the data files do not exist as only information from the table definition file, table_name.frm, is used. All string comparisons are case independent with case according to ISO-8859-1 Latin1. LIKE is allowed on numerical columns. Compare with explicit NULL (column == NULL) is the same as if IS NULL was used (column IS NULL). This is is done to be consistent with mSQL. 38 SELECT syntax SELECT [STRAIGHT_JOIN] [DISTINCT | ALL] select_expression,... [INTO OUTFILE ’file_name’ ...] [ FROM tables... [WHERE where_definition ] [GROUP BY column,...] [ ORDER BY column [ASC | DESC] ,..] HAVING where_definition [LIMIT [offset,] rows] [PROCEDURE procedure_name]] Strings are automatically converted to numbers and numbers to strings when needed (ala perl). If in a compare operation ((=, <>, <= ,<, >=, >)) either if the arguments are numerical the arguments are compared as numbers, else the arguments are compared as strings. All string comparisons are by default done case-independent by ISO8859-1 (The Scandinavian letter set which also works excellent with English). select 1 > "6x"; -> 0 select 7 > "6x"; -> 1 15
  • 16. select 0 > "x6"; -> 0 select 0 = "x6"; -> 1 A column name does not have to have a table prefix if the given column name is unique. A select expression may be given an alias which will be column name and can be used when sorting and grouping or in the HAVING clause. select concat(last_name,’ ’,first_name) as name from table order by name In LIKE expressions % and _ may be preceded with ’’ to skip the wild-card meaning. A DATE is a string with one of the following syntaxes: YYMMDD (Year is assumed to be 2000 if YY < 70.) YYYYMMDD YY.MM.DD Where ’.’ may be any non numerical separator. YYYY.MM.DD Where ’.’ may be any non numerical separator. IFNULL() and IF() returns number or string value according to use. ORDER and GROUP columns may be given as column names, column alias or column numbers in SELECT clauses. The HAVING clause can take any columns or alias in the select_expressions. It is applied last, just before items are sent to the client, without any optimisation. Don’t use it for items that should be in the WHERE clause. You can’t write (yet): SELECT user,MAX(salary) FROM users GROUP BY users HAVING max(salary)>10 Change it to: SELECT user,MAX(salary) AS sum FROM users GROUP BY users HAVING sum > 10 STRAIGHT_JOIN forces the optimiser to join the tables in the same order that the tables are given in the FROM clause. One can use this to get a query to be done more quickly if the optimiser joins the tables in not optimal order. See section EXPLAIN syntax. Get information about a SELECT. [p 47] LIMIT takes one or two numerical arguments. If one argument, the argument indicates the maximum number of rows in a result. If two arguments, the first argument says the offset to the first row to return, the second is 39 the maximum number of rows. INTO OUTFILE ’filename’ writes the given set to a file. The file can not exist from before. See section LOAD DATA INFILE syntax [p 45] . Functions A select_expression or where_definition can consist of any expression using the following functions: Group functions. ( ) Parenthesis Normal mathematical operations. + - * / A division by zero results in a NULL. Bit functions. These have a range of maximum 64 bits because MySQL uses longlong arithmetic. | & BIT_COUNT() Number of set bits in an argument. 16
  • 17. Normal logical. Returns TRUE (1) or FALSE (0). NOT ! OR AND Comparison operators. Returns TRUE (1) or FALSE (0). These functions work for both numbers and strings. = Equal <> Not equal. Synonym: != <= Smaller or equal. < Smaller. >= Bigger or equal > Bigger ISNULL(A) Returns 1 if A is NULL else 0. Same as ’( A == NULL ’). A BETWEEN B AND C A is bigger or equal as B and A is smaller or equal to C. Is the same as (A >= B AND A <= C). 40 String comparison functions. expr IN (value,...) Returns 1 if expr is any of the values in the IN list, else it returns 0. If all values are constants, then all values are evaluated according to the type of expr and sorted. The search for them item is then done by using a binary search. This means IN is very quick when used with constants in the IN part. expr LIKE expr SQL simple regular expression comparison. Returns TRUE (1) or FALSE (0). With LIKE you have two wild characters. ’%’ stands for any number of characters, even zero characters. ’_’ stands exactly one character. If you want to search after a ’%’ or a ’_’ you must precede it with a ’’ For example the string "Monty was here" is matched by "Monty%", "%Monty ___ h%" and "%was%". expr NOT LIKE expr Returns TRUE (1) or FALSE (0). expr REGEXP expr Checks string against extended regular expr. expr NOT REGEXP expr Checks string against extended regular expr. STRCMP() Returns 0 if the strings are the same. Otherwise return -1 if first argument is smaller according to sort-order, otherwise it returns 1. Control flow functions. IFNULL(A,B) If A is not null it returns A, else B. IF(A,B,C) If A is true (<> 0 and <> NULL) then return B, else return C. Mathematical functions. These returns NULL in the case of a error. - Sign ABS() SIGN() 17
  • 18. Sign of argument. Returns -1, 0 or 1. MOD() % Module (like in C). Equivalent with MOD(). FLOOR() CEILING() ROUND() EXP() LOG() LOG10() POW() SQRT() PI() COS() SIN() 41 TAN() TAN2() ACOS() ASIN() ATAN() RAND([integer_expr]) Returns a random float, 0 <= x <= 1.0, using integer_expr as the option seed value. MIN() Min value of arguments. Must have 2 or more arguments, else these are GROUP BY functions. The arguments are compared as numbers. MAX() Max value of arguments. Must have 2 or more arguments, else these are GROUP BY functions. The arguments are compared as numbers. String functions. ASCII(string_exp) Returns the ASCII code value of the leftmost character of string_exp. If string_exp is NULL, it then returns NULL. CHAR(num,...) Returns a string that consist of the characters given by the ASCII code values of the arguments. NULLS are skipped. CONCAT() Concatenates strings. May have more than 2 arguments. LENGTH() Length of string. Synomyes: CHAR_LENGTH(), OCTET_LENGTH() LOCATE(A,B) Returns position of B substring in A. The first position is 1. Returns 9 if b is not in A. LOCATE(A,B,C) Returns position of B substring in A starting at C. Synonym: POSITION(B IN A) LEFT(str,length) Gets length characters from beginning of string. RIGHT(str,right) Gets length characters from end of string. Synonym: SUBSTRING(A FROM B) LTRIM(str) Removes space characters from the beginning of string. 18
  • 19. RTRIM(str) Removes space characters from the end of string. TRIM([[ BOTH | LEADING | TRAILING] [ A ] FROM ] B) Returns a character string with all A prefixes and/or suffixes removed from B. If BOTH, LEADING and TRAILING isn’t used BOTH are assumed. If A is not given, then spaces are removed. SOUNDEX(str) Gets a soundex string from str. Two strings that sound ’about the same’ should have identical soundex strings. A ’standard’ soundex string is 4 long, but this function returns an arbitrary long string. One can use SUBSTRING on the result to get a ’standard’ soundex string. All non alpha characters are ignored in the given string. All characters outside the A-Z range are treated as vocals. SUBSTRING(A,B,C) Returns substring from A starting at B with C chars. 42 SUBSTRING(A FROM B FOR C) Same as SUBSTRING(A,B,C). This is ANSI SQL 92. SUBSTRING(A FROM B) Same as RIGHT(A,B). This is ANSI SQL 92. SUBSTRING_INDEX(string,delimiter,count) Returns the substring from ’string’ after ’count’ delimiters. If count is positive the strings are searched from left else if count is negative the substrings are searched and returned from right. substring("www.tcx.se",".",2) would return "www.tcx" and substring("www.tcx.se",".",-2) would return "tcx.se". REPLACE(A,B,C) Replaces all occurrences of B in A with C. REPEAT(string,count) Repeats string count times. If count <= 0 returns a empty string. If string or count is NULL or LENGTH(string)*count > max_allowed_size returns NULL. INSERT(org,start,length,new) Replaces substring org[start...length] with new. First position in string=1. LCASE(A) Changes A to lower case. Synonym: LOWER() UCASE(A) Changes a to upper case. Synonym: UPPER() ENUM(A,a,b,c,d) Returns 1 if A == a, 2 if A == b. If no match 0 is returned. A,a,b,c,d... are strings. ELT(N,a,b,c,d,...) Returns a if N == 1, b if N == 2. a,b,c,d are strings. FIELD(A,a,b,c,d,...) Returns index of A in the a,b,c... list. The complement of ELT(). Date and time functions. PERIOD_ADD(P:N) Adds N months to period P (of type YYMM or YYYYMM). Returns YYYYMM. PERIOD_DIFF(A,B) Returns months between periods A,B. A and B should be of format YYMM or YYYYMM. Example: PERIOD_DIFF(9612,199712). TO_DAYS(DATE) 19
  • 20. Changes a DATE to a daynumber. DATE may be a date string, a datetime string, a timestamp([6 | 8 | 14]) or a number of format YYMMDD or YYYYMMDD. FROM_DAYS() Changes a daynumber to a DATE. WEEKDAY(DATE) Gets weekday for date (0 = Monday, 1 = Tuesday). DATE may be a date string, a datetime string, a timestamp([6 | 8 | 14]) or a number of format YYMMDD or YYYYMMDD. CURDATE() Returns date of today. In form YYYYMMDD or "YYYY-MM-DD" depending on whether CURDATE() is used in a number or string context. Synonymes: CURRENT_DATE(). CURTIME() Returns current time in form HHMMSS or "HH:MM:SS", depending on whether CURTIME() is used in a number or string context. Synonymes: CURRENT_TIME(). 43 NOW() Returns current time. In format YYYYMMDDHHMMSS or "YYYY-MM-DD HH:MM:SS" depending on whether NOW() is used in a number or string context. Synonymes: CURENT_TIMESTAMP(), SYSDATE(). UNIX_TIMESTAMP([DATE]) If called without any arguments a unix timestamp (seconds in GMT since 1970.01.01 00:00:00) is returned. Normally it is called with a timestamp column as an argument in which case it returns the timestamp. DATE may also be a date string, a datetime string, or a number of format YYMMDD or YYYMMDD in local time. FROM_UNIXTIME(unix_timestamp) Returns a string of the timestamp in YYYY-MM-DD HH:MM:SS or YYYYMMDDHHMMSS format depending on context. SEC_TO_TIME(seconds) Returns the hours, minutes and seconds of the argument in H:MM:SS or HMMSS format depending on context. Miscellaneous functions. DATABASE() Returns current database name. USER() Returns current user name. Synonymes: SESSION_USER() and SYSTEM_USER(). PASSWORD() Calculates a password string. This must be used to store a password in the ’user’ grant table. ENCRYPT(string[,salt]) Crypt messsage with the unix crypt() command. The salt should be a string with 2 characters. LAST_INSERT_ID() Returns the last automaticly generated value that was set in a auto_increment column. See section How can I get the unique ID for the last row? [p 83] FORMAT(nr,NUM) Formats number to a format like ’#,###,###.##’ with NUM decimals. Functions for GROUP BY clause. count(expr) Number of rows. count(*) is optimised to return very quickly if no other column is used in the 20
  • 21. SELECT. avg(expr) Average value of expr. min(expr) max(expr) Minimum/Maximum value of expr. min() and max() may take a string argument and will then return the minimum/maximum string value. sum(expr) Sum of expr. std(expr) Standard derivation of expression. This is a extension to ANSI SQL. bit_or(expr) The logical OR of all bits in expr. Caclulation done with 64 bits precision. 44 bit_and(expr) The logical AND of all bits in expr. Caclulation done with 64 bits precision. MySQL has extended the use of GROUP BY. You can use columns or calculations in the SELECT expressions which doesn’t appear in the GROUP BY part. This stands for ’any possible value for this group’. By using this, one can get a higher performance by avoiding sorting and grouping on unnecessary items. For example, in the following query one doesn’t need to sort on b.name: SELECT a.id,b.name,COUNT(*) from a,b WHERE a.id=b.id GROUP BY a.id INSERT syntax INSERT INTO table [ (column_name,...) ] VALUES (expression,...) or INSERT INTO table [ (column_name,...) ] SELECT .... An expression may use any previous column in column_name list (or table if no column name list is given). The following holds for a multi-row INSERT statement: The query cannot contain an ORDER BY clause. The target table of the INSERT statement cannot appear in the FROM clause of the query. If one uses INSERT INTO ... SELECT ... then one can get the following info string with the C API function mysql_info(). @result{Records: 100 Duplicates: 0 Warnings: 0} Duplicates are number of rows which couldn’t be written because some key would be duplicated. Warnings are columns which were set to NULL, but have been declared NOT NULL. These will be set to their default value. If one sets a time stamp value to anything other than NULL, the time stamp value will be copied to the result table. Auto increment fields works as usual. LOAD DATA INFILE syntax LOAD DATA INFILE ’table_interval.text’ [REPLACE | IGNORE] INTO TABLE table_interval [FIELDS [TERMINATED BY ’,’ [OPTIONALLY] ENCLOSED BY ’"’ ESCAPED BY ’’ ]] [LINES TERMINATED BY ’n’] [(field list)] This is used to read rows from a text file, located on the server, at a very high speed. The server- client protocol doesn’t yet support files over a connection. If you only have the file on the client, use rcp or ftp to copy it, possibly compressed, to the server before using LOAD DATA INFILE. 21
  • 22. To write data to a text file, use the SELECT ... INTO OUTFILE ’interval.txt’ fields terminated by ’,’ enclosed by ’"’ escaped by ’’ lines terminated by ’n’ FROM .... syntax. Normally you don’t have to specify any of the text file type options. The default is a compact text file with columns separated with tab characters and all rows end with a newline. Tabs, newlines and inside fields are prefixed with a . NULL’s are read and written as N. 45 FIELDS TERMINATED BY has the default value of t. FIELDS [OPTIONALLY] ENCLOSED BY has the default value of ". FIELDS ESCAPED BY has the default value of ’’. LINES TERMINATED BY has the default value of ’n’. FIELDS TERMINATED BY and LINES TERMINATED BY may be more than 1 character. If LINES TERMINATED BY is an empty string and FIELDS TERMINATED BY is not empty then lines are also terminated with FIELDS TERMINATED BY. If FIELDS TERMINATED BY and FIELDS ENCLOSED BY both are empty strings (") then this gives a fixed row format ("not delimited" import format). With a fixed row size NULL values are outputed as a blank string. If you specify OPTIONALLY in ENCLOSED BY, then only strings are enclosed in ENCLOSED BY by the SELECT ... INTO statement. Duplicated ENCLOSED BY chars are removed from strings that start with ENCLOSED BY. For example: With ENCLOSED BY ’"’: "The ""BIG"" boss" -> The "BIG" boss The "BIG" boss -> The "BIG" boss If ESCAPED BY is not empty then the following characters will be prefixed with the escape character: ESCAPED BY, ASCII 0, and the first character in any of FIELDS TERMINATED BY, FIELDS ENCLOSED BY and LINES TERMINATED BY. If FIELDS ENCLOSED BY is not empty then NULL is read as a NULL value. If FIELDS ESCAPED BY is not empty then N is also read as a NULL value. If REPLACE is used, then the new row will replace all rows which have the same unique key. If IGNORE is used, the row will then be skipped if there already exist a record with an identical unique key. If none of the above options are used an error will be issued. The rest of the text file will be ignored if one gets a duplicate key error. Some possible cases that’s not supported by LOAD DATA: Fixed size rows (FIELDS TERMINATED BY and FIELDS ENCLOSED BY both are empty) and BLOB fields. If some of the separators are a prefix of another. FIELDS ESCAPED BY is empty and the data contains LINES TERMINATED BY or FIELDS ENCLOSED BY followed by FIELDS TERMINATED BY. All rows are read into the table. If a row has too few fields the rest of the fields are set to default values. For security reasons the text file must either reside in the database directory or be readable by all. 22
  • 23. For more information about the escaped syntax See section Literals. How do you write strings and numbers? [p 30] . 46 When the LOAD DATA query is done, one can get the following info string with the C API function mysql_info(). @result{Records: 1 Deleted: 0 Skipped: 0 Warnings: 0} Warnings are incremented for each column which can’t be stored without loss of precision, for each column which didn’t get a value from the read text line (happens if the line is too short) and for each line which has more data than can fit into the given columns. Example that loads all fields; LOAD DATA INFILE ’persondata.text’ INTO TABLE persondata; See section How should I arrange my table to be as fast/small as possible? [p 59] UPDATE syntax UPDATE table SET column=expression,... WHERE where_definition All updates are done from left to right. If one accesses a column in the expression update will then use the current value (a given value or the default value) of the column. UPDATE persondata SET count=count+1 SHOW syntax. Get information about names of columns. SHOW DATABASES [LIKE wild] or SHOW TABLES [FROM database] [LIKE wild] or SHOW COLUMNS FROM table [FROM database] [LIKE wild] Gives information about databases, tables or columns. The wild is a LIKE string. FIELDS may be used as an alias for COLUMNS. EXPLAIN syntax. Get information about a SELECT. EXPLAIN SELECT select_options Gives information about how and in which order tables are joined. With the help of EXPLAIN one can see when one has to add more keys to tables to get a faster select that uses keys to find the records. You can also see if the optimiser joins the tables in an optimal order. One can force the optimiser to use a specific join order with the STRAIGHT_JOIN option to select. The different join types are: system The table has only 1 record (= system table) const The table has at most 1 matching record which will be read at the start of the query. All columns in this table will be regarded as constants by the rest of the optimiser. eq_ref One record will be read from this table for each combination of the previous tables. 47 ref All records with matching keys will be read from this table for each combination of the previous 23
  • 24. tables. all A full table scan will be done for each combination of the previous tables. DESCRIBE syntax. Get information about columns. (DESCRIBE | DESC) table [column] Gives information about columns. This command is for Oracle compatibility. See section SHOW syntax. Get information about names of columns. [p 47] Column may be a column name or a string. Strings may contain wild cards. Lock tables syntax LOCK TABLES table_name [AS alias] READ|WRITE [, table_name READ|WRITE ] ... UNLOCK TABLES Locks tables for this thread. Many threads may have a READ lock on the same table, but one can use a table with a WRITE lock. One can’t update a table on which one has a read LOCK. When one uses LOCK TABLES one must lock all tables one is going to use! LOCK TABLES t READ, t as t2 READ SELECT * from t,t2; All tables are automaticly unlocked when one issues another LOCK TABLES or if the connection to the server is closed. SET OPTION syntax. SET OPTION SQL_VALUE_OPTION=value, ... The used options remain in effect for the whole current session. The different options are: SQL_SELECT_LIMIT=value The maximum number of records to return in any select. If a select has a limit clause it overrides this statement. The default value for a new connection is ’unlimited’. SQL_BIG_TABLES= 0 | 1 If set to 1 then all temporary tables are stored on disk based. This will be a little slower, but one will not get the error The table ### is full anymore for big selects that require big temporary tables. The default value for a new connection is 0 (use in memory temporary tables). SQL_BIG_SELECTS= 0 | 1 If set to 1 then MySQL will aborts if one will try to make a select with probably will take a very long time. This is nice to SELECTS with a wrong WHERE statement. A big query is defined as a SELECT that will probably have to examine more than max_join_size rows. The default value for a new connection is 0 (allow all SELECT’s). 48 GRANT syntax. (Compatibility function). GRANT (ALL PRIVILEGES | (SELECT, INSERT, UPDATE, DELETE, REFERENCES (column list), USAGE)) ON table TO user,... [WITH GRANT OPTION] This command doesn’t do anything. It is only in MySQL for compatibility reasons. Privileges in MySQL is handled with the mysql grant tables. See section How does the privilege system work? [p 26] 24
  • 25. CREATE INDEX syntax (Compatibility function). CREATE [UNIQUE] INDEX index_name ON table_name ( column_name,... ) This function doesn’t do anything. It is only in MySQL for compatibility reasons. You can create new index with ALTER TABLE. See section ALTER TABLE syntax [p 37] DROP INDEX syntax (Compatibility function). DROP INDEX index_name This always succeeds. You can drop an index with ALTER TABLE. See section ALTER TABLE syntax [p 37] Is MySQL picky about reserved words? It seems that I can’t create a table with column names timestamp or group. Functions don’t clash with table or column names. (For example ABS is an allowed column name). The only restriction is that space is not allowed between a function name and the ’(’ when using functions. The following are reserved words in MySQL. Most of them (for example) group, are forbidden by ANSI SQL92 as column and/or table names. A few are because MySQL needs them and is (currently) using a Yacc parser: 49 action add all alter and as asc auto_increment between bigint bit binary blob both by cascade char character change check column columns create data databases date datetime dec decimal default delete desc describe distinct double drop escaped enclosed enum explain fields float float4 float8 foreign from for full grant group having ignore in index infile insert int integer interval int1 int2 int3 int4 int8 into is key keys leading like lines limit lock load long longblob longtext match mediumblob mediumtext mediumint middleint numeric no not null on option optionally or order outfile partial precision primary procedure privileges read real references regexp repeat replace restrict rlike select set show smallint sql_big_tables sql_big_selects sql_select_limit straight_join table tables terminated text time timestamp tinyblob tinytext tinyint trailing to unique unlock unsigned update usage values varchar varying with write where 25
  • 26. zerofill The following symbols (from the table above) are disallowed by ANSI SQL but allowed by MySQL as column/table names. This is because some of theese names are very natural names so a lot of people has already used them. ACTION BIT DATE 50 ENUM NO TEXT TIME TIMESTAMP Go to the first [p 5] , previous [p 26] , next [p 52] , last [p 87] section, table of contents [p 1] . 51 Go to the first [p 5] , previous [p 30] , next [p 57] , last [p 87] section, table of contents [p 1] . How safe/stable is MySQL How stable is MySQL? At TcX, MySQL has worked without any problems in our projects since nid 1996. When released to a wider public we noticed that there where some parts of ’untested code’ in MySQL that was quickly found by the new user group that don’t do queries exactly like we do at TcX. Each new release have had fewer non portability problems than the previous one, even though they have had a lot of new features, and we hope that one of the next releases will be possible to be labelled ’stable’. Each release of MySQL has been usable and there has only been problems when users start to use code from ’the gray zones’. Naturally, outdoor users can’t know what the gray zones are and I hope this section will clarify those currently known. We will here try to answer some of the more important questions that seems to concern a lot of people and clarify some issues. This section has been put together from the information that has come forward in the mailing list which is very active in reporting bugs. How stable is MySQL? Can I depend on MySQL in this project! This is about the 3.21.x version of MySQL. All known and reported bugs are fixed in the latest version with the exception of the bugs listed in the BUGS file which are things that are ’design’ related. MySQL is written in multiple layers and different independent modules. Here is a list of the different modules and how tested each of them are. The ISAM table handler. Stable (ISAM) where all data is stored. In all MySQL releases there hasn’t been a single (reported) bug in this code. The only known way to get a corrupted table is to kill the server in the middle of a update and because all data is flushed to disk between each query even this is unlikely to destroy 26
  • 27. any data beyond rescue. There hasn’t been a single bug report about lost data because of bugs in MySQL either. The parser and lexical analyser. Stable There hasn’t been a single reported bug in this system for a couple of months. The C client code. Stable No known problems. In early 3.20 releases there were some limitations in the send/receive buffer size. In 3.21.x the send/receive buffer is now dynamic up to a default of 512K. mysql, mysqladmin and mysqlshow. Stable The command line clients have had very few bugs. mysqldump and mysqlimport. Beta Rewritten for 3.21. Basic SQL. Stable The basic SQL function system and string classes and dynamic memory handling. Not a single reported bug on this system. 52 Query optimiser. Gamma Some changes in 3.21. Range optimiser. Alpha Totally rewritten for 3.21.x Join optimiser. Gamma Small changes for 3.21. GROUP BY, ORDER BY and related function COUNT(). Beta Rewritten for 3.21 and throughly tested. Locking. Gamma This is very system dependent. One some system there is big problems to use standard OS locking (fcntl). In these case one should run the MySQL demon with the --skip-locking flag. Known problems are some Linux systems and SUNOS when using NFS mounted file systems. Linux threads. Gamma The only found problem is with the fcntl() call, which is fixed by using --skip-locking. Some people have reported lockup problems with the 0.5 release. Solaris 2.5+ pthreads. Stable We use this for all our production work. MIT threads (Other systems). Beta No reported bugs since 3.20.15 and no known bugs since 3.20.16. On some system there is ’misfeature’ where some operations are quote slow (a 1/20 second sleep is done between each query). Other thread implementions. Alpha The ports to other systems is very new and may still have bugs, either in MySQL or most often in the thread implementation itself. LOAD DATA..., INSERT ... SELECT. Stable Some people have thought they have found bugs in this but has turned up being misunderstandings. So check the manual before reporting bugs! ALTER TABLE. Gamma Partly rewritten for 3.21. mysqlperl. Stable No bugs reported except a lot of compiling and linking problems. DBD. Beta Now maintained by Jochen Wiedmann . Thanks! 27
  • 28. mysqlaccess. Beta Written and maintained by Yves.Carlier@rug.ac.be. Thanks! The Technical Documentation. Beta It is improving. MyODBC (uses ODBC SDK 2.5). Beta It seams to work well with some programs. There is some known problems with Office97. PowerBuilder doesn’t work yet. Error messages aren’t returned right when using a Microsoft New ODBC 3.0 driver but this may well be a bug in the Microsoft ODBC 3.0 driver. It isn’t fully up to ODBC level 2 yet in every regard. (My personal opinion is that the ODBC levels are defined in such a way that it’s almost impossible to make a simple ODBC driver that works with all products). Sometimes the MyODBC code must be ported to ODBC 3.0. TcX provides email support for paying customers, but the MySQL mailing list usually provides answers to all common questions. Bugs are usually fixed right away with a patch that usually works and for serious bugs there is almost always a new release. 53 Why are there is so many release of MySQL? Is it because there are so many bugs? Well, MySQL is evolving quite rapidly here at TcX and we want to share this with other MySQL users. We try to make a release when we have a very useful feature that others seem to have a need for. We also try to help out users who request features that are easy to implement. We also take note on what our licensed users want to have and we especially take notes on what our extended email supported customers want and try to help them out. No one has to download a new release. The NEWS file will tell you if the new release has something you really want. If there is, by any chance, a fatal bug in a release we will make a new release as soon as possible, that fixes the problem. We would like other companies to do this too :) The 3.21.x version has had many big changes for portability to a lot of different systems. When the 3.21 release is stable we will remove the alpha/beta suffix and move active development to the 3.22. Bugs will still be fixed in the stable version. We don’t believe in a complete freeze, as this also leaves out bug fixes and things that ’must be done’. ’Somewhat freezed’ means that we will maybe add small things that ’almost surely will not affect anything thats already working’. Checking a table for errors. If MySQL crashed (for example if the computer is turned off) when all data is not written to disk the tables may have become corrupted. To check a table use: isamchk table_name This finds 99.99 % of all errors. What it can’t find is when only the data file has been corrupted. isamchk -e table_name 28
  • 29. This goes through all data and does a complete check. isamchk -ei table_name As the above but it also prints some statistics. We at TcX run a cron job on all our important tables once a week. 35 0 * * 0 /path/to/isamchk -s /path/to/dbs/*/*.ISM This prints out any crashed tables so we can go and examine and repair them when needed. As we haven’t had any unexpected crashed (without hardware trouble) tables for a couple of years now (this is really true), once a week is more than enough of us. Of course, whenever the machine has done a reboot in the middle of a update one usually has to check all the tables that could have been affected. (This is a ’expected crashed table’) We recommend that to start with one should do a isamchk -s on all updated tables each night until one gets to trust MySQL as much as we trust it. 54 Naturally, one could add a check to safe_mysql that, if there is an old pid file left after a reboot, it should check all tables that have been modified the last 24 hours. How to repair tables. The file format that MySQL uses to store data has been extensively tested, but there is always instances (like a hard kill on the mysqld process in the middle of a write, a hardware error or a unexpected shutdown of the computer) when some tables may be corrupted. The sign of a corrupted table is usually when queries abort unexpectedly and one gets errors like: table.frm is locked against change. Can’t find file ’table.ISM’ (Errcode: ###) Got error ### from table handler. (Error 135 is an exception in this case) Unexpected end of file. Record file is crashed. In thess cases you have to repair your tables. The isamchk extern utility can usually detect and fix most things that can go wrong. See section The MySQL table check, optimize and repair program [p 66] . If you are going to use isamchk on very large files, you should first decide how much memory you want to give to isamchk. More memory gives more speed. For example, if you have more than 32M ram, try: isamchk -O sortbuffer=16M -O keybuffer=16M -O readbuffer=1M -O writebuffer=1M ..... Part 1; Checking Check the permissions of the table files. Make them readable for the user running mysqld. cd to the database directory. Run ’isamchk *.ISM’ or (’isamchk -e *.ISM’ if you have more time). You only have to repair those tables that your isamchk gives an error. Use option -s to avoid unnecessary information. Part 2; Easy safe repair. If you get weird errors when checking or repairing, like out of memory or if isamchk 29
  • 30. crashes, go to part 3. Try first ’isamchk -rq table’. This will try to repair the .ISM file without touching the important data table (.ISD). If the data file (.ISD) contains everything and the delete links point at the right places in the data file, this should work and the table is fixed. Start repairing next table. Make a backup of the data file (table.ISD) before continuing. Use ’isamchk -r table’. This will remove wrong records and deleted records from the data file and reconstruct the index (.ISM) file. If the above fails, use ’isamchk -ro table’. This is a little slower but a crash-safer version of the above. Part 3; Hard repair. This should only happen if the first 16K block in the .ISM file is destroyed, contains wrong information or if the .ISM is missing. In this case we have to create a new .ISM file. Do as follows: 55 Move the data file .ISD file to some safe place. Recreate the .ISM file from the .frm file: shell> mysql database mysql> delete from table_name; mysql> quite Copy (don’t move) the data file (.ISD) back on the newly created .ISD file Go back to Part 2. (This shouldn’t be a endless loop). isamchk -rq should now work. Part 4; Very hard repair. This can only happen if the descriptor file (.frm) also has crashed. This should never happen, because the .frm file isn’t written to after the table is created. Restore the .frm file from a backup and go back to Part 3. You can also restore the .ISM file and go back to Part 2. In the latter case you should start with ’isamchk -r’. If you don’t have a backup but know exactly how the table was created, create a copy of the table in another database and copy the .frm and .ISM file from there to your crashed database and go back to Part 2; Is there anything special to do when upgrading/downgrading MySQL? One can always move the MySQL form and data files between different versions on the same architecture as long as one has the same base version of MySQL. The current base version is of course 3. If one changes the sort order by recompiling MySQL one has to do a isamchk -rq on the tables. Go to the first [p 5] , previous [p 30] , next [p 57] , last [p 87] section, table of contents [p 1] . 56 Go to the first [p 5] , previous [p 52] , next [p 65] , last [p 87] section, table of contents [p 1] . How to get maximum performance out of MySQL How does MySQL use memory ? You can get the currently used buffer sizes with: > ./mysqld --help This should result in a list of all mysqld options and configurable variables like the following. See section How can I change the buffer sizes of mysqld ? [p 61] . Possibly variables to option --set-variable (-O) are: back_log current value: 5 join_buffer current value: 131072 30
  • 31. key_buffer current value: 1048568 max_allowed_packet current value: 65536 max_connections current value: 90 max_join_size current value: 4294967295 max_sort_length current value: 1024 net_buffer current value: 8192 record_buffer current value: 131072 table_cache current value: 64 tmp_table_size current value: 131072 sort_buffer current value: 2097144 All threads share the same base memory. Nothing is memmaped yet (except compressed tables but that’s another story). This is because 32bit memory space of 4GB is not large enough for most large tables. When we get a system with 64 bit address space we may add general support for memmaping. When starting mysqld one can specify a key buffer. This will buffer all keys in all tables at FIFO basis (variable keybuffer). Each connection uses some thread space, a stack and a connection buffer (variable net_buffer_length). Each request doing a sequential scan over a table allocates a read buffer (variable record_buffer). Each request doing a sort, allocates a sortbuffer and one or two temporary files. The maximum extra disk-space needed is @math{(sort_key_length +sizeof(long))*2}. All joins are done in one pass and most temporary tables are memory based (HEAP) tables. Temporary tables with a big recordlength (= sum of all column length) or that contains BLOB’s are stored on disk. One current problem is that if the HEAP table exceeds the size of tmp_table_size, one will get the error: ’The table ### is full’. In the future we will fix this by automatically changing the in memory (HEAP) table to a disk based (NISAM) table if needed. To go around this problem one can increase the -O tmp_table_size=# option to mysqld or use the SQL option SQL_BIG_TABLES. See section SET OPTION syntax. [p 48] . In MySQL 3.20 the maximum size of the temporary table was recordbuffer*16, so if you are using this version you have to increase recordbuffer. There also exists a patch to always store temporary tables on disk, but this will affect the speed of all complicated queries. Almost all memory used when parsing and calculating is done on a local memory store. No memory overhead is needed for small items and the normal slow memory allocation/freeing is avoided. Memory is only allocated for unexpectedly large strings (this is done with malloc/free). 57 Each index file is opened once and the data file is opened once for each concurrently running thread. For each concurrent thread a table structure, column structures for each column and a buffer that has the size of 3 * (maximum row length not counting BLOBS) is allocated. A BLOB uses 5 to 8 bytes +length of blob data. For each table having BLOBS, a buffer is enlarged dynamically to read in larger BLOB’s. If one scans a table there will be a allocated buffer as large as the largest BLOB. All used tables are saved in a cache and used by FIFO. Normally the cache is 64 tables. If a table has been used by 2 running threads at the same time, there will be 2 entries of the table in the cache. A MySQLadmin refresh closes all tables that are not used and marks all used tables to be closed when the running thread finishes. This will effectively free most used memory. When running mysqld ps, other programs may report that is takes a lot of memory. This may be 31
  • 32. caused by thread-stacks on different memory addresses. For example, the Solaris ps calculates the unused memory between stacks as used memory. You can verify this by checking available swap with ’swap -s’. We have tested mysqld with commercial memory-leakage detectors so there should not be any memory leaks. How does MySQL use keys? All keys, PRIMARY, UNIQUE and INDEX(), are stored in B trees. Strings are automatically prefixand end-space compressed. INDEX(col1, col2) creates a multiple index over the two columns. The key can be seen like a concatenation of the given columns. If you use INDEX(col1), INDEX(col2) instead of INDEX(col1,col2) you get two separate keys instead. SELECT * FROM table WHERE col1=# AND col2=# In a case of INDEX(col1,col2) the right row(s) can be fetched directly. In a case of INDEX(col1), INDEX(col2) the optimiser decides which index will find fewer rows and this index will be used to fetch the rows. If the table has an index INDEX(col1,col2,col3....) the prefix of this can be used by the optimiser to find the rows. This means that the above gives you search capabilities on: INDEX(col1) and INDEX(col1,col2) and INDEX(col1,col2,col3)... MySQL can’t use a sub part of a key to locate rows through a key. With the definition INDEX(col1,col2,col3): SELECT * FROM table WHERE col1=# SELECT * FROM table WHERE col2=# SELECT * FROM table WHERE col2=# and col3=# only the first query will use keys. 58 How does MySQL open & close tables? The cache of open tables can grow to a maximum of table-cache (default 64, changeable with -O table_cache=#). A table is never closed, except when the cache is full and another thread tries to open a table or if one uses ’mysqladmin refresh’. When the limit is reached, MySQL closes as many tables as possible, until the cache size has been reached or there are no more unused tables. This means that if all tables are in use by some threads, there will be more open tables than the cache limit, but the extra tables will be closed eventually. Tables are closed according to last-used order. A table is opened (again) for each concurrent access. This means that if one has two threads running on the same table or access the table twice in the same query (with AS) the table needs to be opened twice. The first open of any table takes 2 file descriptors, each following use of the table takes only one file descriptor. 32
  • 33. How should I arrange my table to be as fast/small as possible? Use NOT NULL if possible. It makes everything faster and you save 1 bit per column. All columns have default values. Only insert when the default value isn’t acceptable. You don’t have to insert the columns of a timestamp or an autoincremented key in the insert statement. See section How can I get the unique ID for the last row? [p 83] Use the smaller INT types if possible to get smaller tables. For example, MEDIUMINT is often better than INT. If you don’t have any VARCHAR columns, a fixed size record format will be used. This is much faster but may unfortunately waste some space. See section What are the different row formats? Or when to use VARCHAR/CHAR? [p 63] . To make MySQL optimise queries better, run isamchk -a on the table once it is loaded with relevant data. This updates a value for each index that tells how many rows that have the same value for this key in average. Of course, this is always 1 for unique indexes. To sort an index and data according to an index use isamchk -Sir1 (if you want so sort on index 1). If you have a unique key that you want to read all records from in numeric order this is a good way to make that faster. When loading a table with data use LOAD DATA FROM INFILE. This is usually 20 times faster than using a lot of INSERTs. If the text file isn’t on the server, rcp it to the server first. See section LOAD DATA INFILE syntax [p 45] . You can even get more speed when loading data to tables with many keys by doing: Create the table in mysql or perl with CREATE TABLE.... Do a mysqladmin refresh. Use isamchk -k0 database/table_name. This will remove all use of keys from the table. Insert data into the table with LOAD DATA INFILE.... If you have pack_isam and want to compress the table, run pack_isam on it. Recreate the keys with isamchk -rq database/table_name. Do mysqladmin refresh. The other possibility to get some more speed to both LOAD DATA FROM INFILE and INSERT is to enlarge the key buffer. This can be done with the -O key_buffer=# option to (safe)mysqld. For example 16M should be a good value if you have much RAM :) When dumping data as textfiles to other programs, use SELECT ... INTO OUTFILE. See 59 section LOAD DATA INFILE syntax [p 45] . When doing many inserts/updates in a row, you can get more speed by using LOCK TABLES on the tables. ...FROM INFILE... and ...INTO OUTFILE... are atomic so you don’t have to use LOCK TABLES when using these. See section Lock tables syntax [p 48] . To check how you are doing, run isamchk -evi on the .ISM file. What affects the speed of the INSERT statement? The time to insert a record consists of: Connect: (3) Sending query to server: (2) Parsing query: (2) Inserting record: (1 x size of record) Inserting keys: (1 x keys) Close: (1) Where (number) is proportional time. This does not take into calculation the initial overhead to open tables (which is done once for each simultaneous running query). 33
  • 34. The size of the table slows down the insert of keys with N log N (B-trees). What affects the speed of DELETE statement? The delete time of a record is exactly proportional to the number of keys. To increase the seed of deletes you can increase the size of the key cache. The default key cache is 1M and to get faster deletes it should be increased a couple of times (try 16M if you have enough memory). What kind of optimisation is done on the WHERE clause? (Incomplete, MySQL does a lot of optimisations.) Brace removal (all unnecessary braces are removed). ((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b) OR (a AND b AND c AND d) Constant folding. (a<b AND b=c) AND a=5 -> b>5 AND b=c A=5 Constant condition removal (needed because of constant folding). (b>=5 AND b=5) OR (b=6 and 5=5) or (B=7 and 5=6) -> B=5 or B=6 All constant expressions used by keys are evaluated only once. Return zero rows if impossible select. HAVING is merged with WHERE if one doesn’t use GROUP BY or group functions. For each sub join a simpler WHERE is constructed to get a fast WHERE evaluation for each sub join and also to skip records as soon as possible. Find all keys that may be used. Use the key which finds least records. A key is used for the following cases: =, >, >=, <, <=, BETWEEN and a LIKE with a character prefix like ’something%’. Remove keys that don’t span all AND levels. have all preceding key_parts specified. key = 1 or A = 10 -> NULL (can’t use key.) 60 key = 1 or A = 10 and key=2 -> key = 1 OR key = 2 key_part_1 = const and key_part_3 = const -> key_part_1 = const Read all constant tables. A constant table is: 1. A table with 0 or 1 record. 2. A table which uses only other const tables and constants on a full unique key. const_table.key = constant const_table.key_part_1 = const_table2.column and const_table.key_part_2 = constant Find the best join combination to join the tables, by trying all possibilities :(. If all columns in ORDER BY and in GROUP comes from the same table, then this table is preferred first when joining. If there is a order clause and a different group clause or if the order or group contains columns from other tables than the first table in the join cue, a temporary table is created. For each table use a ranged key, if possible, to read records. Each table index is queried and if there exists a key range that spans < 30% of the records then a key is used. If no such key can be found a quick table scan is used. Before each record is output-ed, skip those that match the HAVING clause. How can I change the buffer sizes of mysqld ? With the mysqld -O variable=size command. Example run: > mysqld --help (or > mysqld -?) >mysqld --help /my/monty/sql/mysqld Ver 3.21.0-alpa for SOLARIS 2.5 (SPARCstation) TcX Datakonsult AB, by Monty. This is FPL, not free software This software comes with NO WARRANTY: see the file PUBLIC for details. Starts the mysql server Usage: /my/monty/sql/mysqld [OPTIONS] 34
  • 35. -b, --basedir=path path to installation directory -h, --datadir=path path to the database root -#, --debug=... output debug log. Often this is ’d:t:o,filename‘ -T, --debug-info print some debug info at exit -?, --help display this help and exit -L, --language=... client error messages in given language -l, --log[=filename] log connections and queries to file --log-update[=filename] log updates to filename.# where # is a unique number if not given. --log-isam[=filename] log all isam changes to file -P, --port=... Port number to use for connection -O, --set-variable var=option give a variable an value. --help lists variables --skip-new-routines don’t use new possible wrong routines. --skip-grant-tables start without grant tables. This gives anyone FULL ACCESS to all tables! --skip-locking don’t use system locking. To use isamchk one has to shut down the server. --skip-name-resolve Don’t resolve hostnames. All hostnames are IP’s or ’localhost’ --skip-new-routines don’t use new possible wrong routines. --skip-unsafe-select skip unsafe select optimisations. 61 --socket=... Socket file to use for connection -V, --version output version information and exit Current base_dir: /my/monty Current data_dir: data/ Current language: english/ Possibly variables to option --set-variable (-O) are: back_log current value: 5 join_buffer current value: 131072 key_buffer current value: 1048568 max_allowed_packet current value: 65536 max_connections current value: 90 max_join_size current value: 4294967295 max_sort_length current value: 1024 net_buffer current value: 8192 record_buffer current value: 131072 table_cache current value: 64 tmp_table_size current value: 131072 sort_buffer current value: 2097144 > safe_mysqld -O key_buffer=512k -O sort_buffer=100k -O record_buffer=100k & The key_buffer is shared by all threads, the rest are allocated when needed. mysqld demon starts with a cd to ’mysql-data-dir’. After this, mysqld-data-dir is changed to ’./’ (current dir). All paths (databases, pid file, and log file) are prefixed with ’./’. What options to use to get MySQL to run at full speed? More memory gives more speed. You can try something like: 35
  • 36. mysqld -O key_buffer=16m -O sort_buffer=1m -O record_buffer=512k --skip-locking --skip-locking disables file locking between SQL requests. If this is used then the following can happen: If mysqld or the machine crashes a table has a higher risk of being corrupted. Tables should at least be checked with isamchk *.ISM after a crash. One MUST flush all tables with mysqladmin refresh before one tries to check/repair tables with isamchk. (isamchk -d table_name is always allowed). The --skip-locking is default when compiling with MIT threads. This is because flock() isn’t fully support by MIT threads on all platforms. How to get MySQL to run as fast as possible with little memory? If there are very many connections, ’swapping problems’ may occur, unless mysqld hasn’t been configured to use very little memory for each connection. 62 For example, for 200 open connections one should have a table cache of at least 200 * (max_number of tables in join). Of course MIT threads may slow down everything a bit, but for key based selects a select is usually down in one time frame so there shouldn’t be a mutex locking/thread juggling. If updates are a problem, updates can be delayed and then do many updates in a row later. Many updates done in a row are much quicker than one at a time. If the problem is with MIT threads and one is using FreeBSD x.x. upgrading to FreeBSD 3.0.(or higher:) should help. This gives a possibility to use sockets (quicker than the current TCP/IP with MIT threads) and the thread package is much more integrated. What are the different row formats? Or when to use VARCHAR/CHAR? Actually using no VARCHAR or BLOB types results in a fixed row size. Otherwise CHAR and VARCHAR are the same. You can check the format used in a table with isamchk -d. MySQL has three different table formats: 1. Fixed length tables; This is the default format. All non packed columns are space filled. Very quick. Easy to cash. Easy to reconstruct if crashed, of course, this only theoretical :-) as records are in fixed positions. Don’t have to be reorganised unless a huge number of records are deleted. 2. Dynamic tables Is used if there exists any VARCHAR, TEXT or BLOB columns in a table. All strings are dynamic (except if length < 3). Each record is preceded with a bitmap for which columns are not empty (this isn’t the same as null columns). Each string is saved with a length byte + string. If string is zero length or a number is zero it takes no extra space, just the zero length bit for each column. Each record is uses the exact record space required. If a record becomes larger it is split into 36
  • 37. as many pieces as required. Takes little disk space. If records are changed a lot, isamchk -r should be run now and then to reorganise the table. This is to get a better layout. Use isamchk -ei table_name for some statistics. Not as easy to reconstruct because a record may be in many pieces and a link may be missing. The expected row length for dynamic sized records is: 3 + (number_of_columns + 7) / 8 + (number of char columns) + packed_size_of_number_columns + length_of_strings + (null_columns + 7) / 8. There will be a penalty of 6 bytes for each link. A dynamic record will be linked whenever a update causes a enlargement of the record. Each new link will be 63 at least 20 bytes, so the next enlargement will probably go in the same link. If not, there will be another link. You may check how many links there are with isamchk -ed. All links may be removed with isamchk -r. 3. Compressed tables (this is only with UNIREG/pack_isam) Read only tables. Takes very little disk space. Minimises disk usage. Each record is compressed separately (very little access overhead). Can handle fixed or dynamic length records, but no BLOBs. Can be uncompressed with isamchk. Why so many open tables? When you run mysqladmin status you get something like: Uptime: 426 Running threads: 1 Questions: 11082 Reloads: 1 Open tables: 12 This can be somewhat perplexing if you only have 6 tables. As MySQL is multithreaded it may have many queries on the same table at once. To minimise the problem with two threads having different states on the same file, I open the table again for each concurrent thread. This takes some memory and one extra file descriptor for the data file. The index file descriptor is shared all threads. Go to the first [p 5] , previous [p 52] , next [p 65] , last [p 87] section, table of contents [p 1] . 64 Go to the first [p 5] , previous [p 57] , next [p 75] , last [p 87] section, table of contents [p 1] . MySQL Utilites Overview of the different MySQL programs All MySQL client that communicates with the server uses the following environment variables: Name Description MYSQL_UNIX_PORT The default socket. Used with ’localhost’. MYSQL_TCP_PORT The default TCP port. MYSQL_PWD The default password. mysql A SQL shell (with gnu readline). Supports interactive use or as a non interactive query tool. When used interactively result is given in a ascii-table format, but when used as a filter the result is a tab-separated output. mysqlaccess Script to check the privileges for a host, user and database combination. mysqladmin Administration utility. Create/Drop of databases, reload (read new users) and refresh (flush tables 37
  • 38. to disk, reopen log files). Also gives version and process info. mysqld The SQL daemon. This should always be running. mysqldump Dump a MySQL database into a file with SQL statements or tab separated text files. Enchanted freeware originally by Igor Romanenko. mysqlimport Imports text-file(s) into respective table(s). Can use all formats supported by LOAD DATA INFILE. See section LOAD DATA INFILE syntax [p 45] mysqlshow Shows information about database, tables, fields and keys. mysqlbug This script should always be used when filing a bug report to the MySQL list. mysql_install_db Creates the MySQL grant tables with default privileges. This is usually only executed when installing the first MySQL release on a new system. isamchk Check, optimise and repair MySQL tables. make_binary_release Makes a binary release of a compiled MySQL. This could be sent by ftp to www.tcx.se/pub/mysql/Incoming for the convenience of other MySQL users. msql2mysql A shell script to convert a mSQL program to MySQL. Doesn’t handle all cases but gives a good start when converting. 65 replace Binary used for msql2mysql. Utility program to change strings in place in files or on stdin. Uses a finite state machine to match longer strings first. Can be used to swap strings, for example ’replace a b b a -- files’ swaps ’a’ and ’b’ in the given files. safe_mysqld Starts the mysqld demon with some safety features. Restarts on error and has logging of runtime information to a log file. The MySQL table check, optimize and repair program For infromation about how to use isamchk to repair a crached table: See section How to repair tables. [p 55] . Getting low level table information To get a description/statistics from a table use the forms below. We will explain some of the information in more detail later. isamchk -d table_name isamchk in ’describe mode’. If one uses ’--skip-locking’ isamchk may report an error for a table that is updated while isamchk runs, but there isn’t any risk of destroying data. A short form. ISAM file: company.ISM Data records: 1403698 Deleted blocks: 0 Recordlength: 226 Record format: Fixed length table description: Key Start Len Index Type 38
  • 39. 1 2 8 unique double 2 15 10 multip. text packed stripped 3 219 8 multip. double 4 63 10 multip. text packed stripped 5 167 2 multip. unsigned short 6 177 4 multip. unsigned long 7 155 4 multip. text 8 138 4 multip. unsigned long 9 177 4 multip. unsigned long 193 1 text For explanations see below. isamchk -d -v table_name A little more verbose. ISAM file: company.ISM Isam-version: 2 Creation time: 1996-08-28 11:44:22 Recover time: 1997-01-12 18:35:29 Data records: 1403698 Deleted blocks: 0 Datafile: Parts: 1403698 Deleted data: 0 Datafilepointer (bytes): 3 Keyfile pointer (bytes): 3 Max datafile length: 3791650815 Max keyfile length: 4294967294 Recordlength: 226 Record format: Fixed length r table description: 66 Key Start Len Index Type Root Blocksize Rec/key 1 2 8 unique double 15845376 1024 1 2 15 10 multip. text packed stripped 25062400 1024 2 3 219 8 multip. double 40907776 1024 73 4 63 10 multip. text packed stripped 48097280 1024 5 5 167 2 multip. unsigned short 55200768 1024 4840 6 177 4 multip. unsigned long 65145856 1024 1346 7 155 4 multip. text 75090944 1024 4995 8 138 4 multip. unsigned long 85036032 1024 87 9 177 4 multip. unsigned long 96481280 1024 178 193 1 text ISAM file Name of isam file. Isam-version Version of isam format. Currently always 2. Creation time When was the data file created. Recover time When was the index/data file last reconstructed. Data records How many records/rows. Deleted blocks How many deleted blocks still have reserved space. See section How to repair tables. [p 55] 39
  • 40. . Datafile: Parts For dynamic record format this shows how many data blocks there are. For a optimised table without splits this is the same as Data records. Deleted data How many bytes of non reclaimed deleted data. Datafile pointer How many bytes the datafile pointer has. It is usually 2, 3 or 4 bytes. Most tables manage with 2 bytes but this cannot be controlled from MySQL yet. For fixed tables this is a record address. For dynamic tables this is a byte address. Keyfile pointer How many bytes has the datafile pointer. It is usually 1, 2 or 3 bytes. Most tables manage with 2 bytes but this is calculated automatically by MySQL. It is always a block address. Max datafile length How long (in bytes) can the table’s data file (.ISD) get. Max keyfile length How long (in bytes) can the table’s key file (.ISM) get. Recordlength How much space does each record/row take. Record format Which format does each record/row have. This example uses Fixed length. table description A list of all keys in the table. For each key some low level information is presented. Key This key’s number. Start Where in the record/row does this index-part start. 67 Len How long is this index-part. For packed numbers this should always be the full length of the field. For strings it may be shorter than the full length. Index unique or multip.. If one value can exist multiple times in this index. Type What data-type does this index part have. This is a C data-type with the options packed, stripped or empty. Root Address of the root index block. Blocksize The size of each index block. This is by default 1024 but may be changed a compile time. Rec/key This is a statistical value used by the optimiser. It tells how many records there are per value for this key. A unique key always has a value of 1. This may be updated after a table is loaded (or greatly changed) with isamchk -a. If this is not updated at all, a default value of 30 is given. The 9th key is a multiple part key with two parts. isamchk -eis table_name Shows only the most important information from a table. Slow since it must read the whole table. 40
  • 41. Checking ISAM file: company.ISM Key: 1: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 2: Keyblocks used: 98% Packed: 50% Max levels: 4 Key: 3: Keyblocks used: 97% Packed: 0% Max levels: 4 Key: 4: Keyblocks used: 99% Packed: 60% Max levels: 3 Key: 5: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 6: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 7: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 8: Keyblocks used: 99% Packed: 0% Max levels: 3 Key: 9: Keyblocks used: 98% Packed: 0% Max levels: 4 Total: Keyblocks used: 98% Packed: 17% Records: 1403698 M.recordlength: 226 Packed: 0% Recordspace used: 100% Empty space: 0% Blocks/Record: 1.00 Recordblocks: 1403698 Deleteblocks: 0 Recorddata: 317235748 Deleted data: 0 Lost space: 0 Linkdata: 0 User time 1626.51, System time 232.36 Maximum resident set size 0, Integral resident set size 0 Non physical pagefaults 0, Physical pagefaults 627, Swaps 0 Blocks in 0 out 0, Messages in 0 out 0, Signals 0 Voluntary contexts switches 639, Involuntary contexts switches 28966 Keyblocks used How many percent of the keyblocks are used. Since this table has just been reorganised with isamchk the values are very high (very near theoretical maximum). Packed MySQL tries to pack keys with a common suffix. This can only be used for CHAR/VARCHAR/DECIMAL keys. For long strings like names, this can significantly reduce the space used. In the above example the 4 key is 10 characters long and gets a 60% reduction in space. 68 Max levels How deep is the btree for this key. Large tables with long keys get high values. Records How many rows does the table have. M.recordlength Average recordlength. For fixed tables this is the recordlength. Packed MySQL strips spaces from the end of strings. How many percent did we save by doing this. Recordspace used How many percent of the datafile is used. Empty space How many percent of the datafile is unused. Blocks/Record How many blocks are there per record. This is always 1 for fixed format tables. This value should stay as close to 1.0 as possible. If it gets to great you can reorganise the table with isamchk. See section How to repair tables. [p 55] . Recordblocks How many blocks are used. For fixed format, this is the same as the number of records. Deleteblocks 41