This document is designed to be a cheat-sheet for MySQL. I don’t plan to cover everything, just most things that a novice MySQL DBA is likely to need often or in a hurry.
If you are going to provide a database service to other machines edit /etc/mysql/my.cnf and set the bind-address parameter to a suitable value. A value of 0.0.0.0 will cause it to accept connections on any of the server’s addresses. I recommend using a private address range (10.0.0.0/8, 192.168.0.0/16, or 172.16.0.0/12) for such database connections and ideally a
back-end VLAN or Ethernet switch that doesn’t carry any public data.
For the purpose of this post let’s consider the MySQL server to have a private IP address of 192.168.42.1. So you want the my.cnf file to have bind-address = 192.168.42.1
To start mysql administration use the command mysql -u root. In Debian the root account has no password by default, on CentOS 5.x starting mysql for the first time gives a message:
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
To do so, start the server, then issue the following commands:
/usr/bin/mysqladmin -u root password ‘new-password’
/usr/bin/mysqladmin -u root -h server password ‘new-password’
That is wrong, for the second mysqladmin command you need a “-p” option (or you can reverse the order of the commands).
There is also the /usr/bin/mysql_secure_installation script that has an interactive dialog for locking down the MySQL database.
Administrative Password Recovery
If you lose the administration password the recovery process is as follows:
- Stop the mysqld, this may require killing the daemon if the password for the system account used for shutdown access is also lost.
- Start mysqld with the --skip-grant-tables option.
- Use SQL commands such as “UPDATE mysql.user SET Password=PASSWORD('password') WHERE User='root';” to recover the passwords you need.
- Use the SQL command “FLUSH PRIVILEGES;“
- Restart mysqld in the normal manner.
For an account to automatically login to mysql you need to create a file named ~/.my.cnf with the following contents:
Replace USERNAME. PASSWORD, and DBNAME with the appropriate values. They are all optional parameters. This saves using mysql client parameters -u parameter for the username, “-p for the password, and specifying the database name on the command line. Note that using the “-pPASSWORD” command-line option to the mysql client is insecure on multi-user systems as (in the absence of any security system such as SE Linux) any user can briefly see the password via ps.
Note that the presence of the database= option in the config file breaks mysqlshow and mysqldump for MySQL 5.1.51 (and presumably earlier versions too). So it’s often a bad idea to use it.
To grant all access to a new database:
CREATE DATABASE foo_db;
GRANT ALL PRIVILEGES ON foo_db.* to 'user'@'10.1.2.3' IDENTIFIED BY 'pass';
Where 10.1.2.3 is the client address and pass is the password. Replace 10.1.2.3 with % if you want to allow access from any client address.
Note that if you use “foo_db” instead of “foo_db.*” then you will end up granting access to foo_db.foo_db (a table named foo_db in the foo_db database) which generally is not what you want.
To grant read-only access replace “ALL PRIVILEGES” with “SELECT“.
To show what is granted to the current user run “SHOW GRANTS;” .
To show the privs for a particular user run “SHOW GRANTS FOR ‘user’@’10.1.2.3’;”
To show all entries in the user table (user-name, password, and hostname):
SELECT Host,User,Password FROM user;
To do the same thing at the command-line:
echo “SELECT Host,User,Password FROM user;” | mysql mysql
To revoke access:
REVOKE ALL PRIVILEGES ON foo_db.* FROM email@example.com IDENTIFIED BY ‘pass’;
To test a user’s access connect as the user with a command such as the following:
mysql -u user -h 10.1.2.4 -p foo_db
Then test that the user can create tables with the following mysql commands:
CREATE TABLE test (id INT);
DROP TABLE test;
Listing the Databases
To list all databases that are active on the selected server run “mysqlshow“, it uses the same methods of determining the username and password as the mysql client program.
To list all tables in a database run “SHOW TABLES;” . For more detail select from INFORMATION_SCHEMA.TABLES or run “SHOW TABLE STATUS;”
For example to see the engine that is used for each table you can use the command echo “SELECT table_schema, table_name, engine FROM INFORMATION_SCHEMA.TABLES;” |mysql.
But INFORMATION_SCHEMA.TABLES is only in Mysql 5 and above, for prior versions you can use mysqldump -d to get the schema, or “SHOW CREATE TABLE table_name;” at the command-line.
Also the mysqldump program can be used to display the tables in a database via “mysqlshow database” or the columns in a table via “mysqlshow database table“.
To list active connections: “SHOW PROCESSLIST;”
The program mysqldump is used to make a SQL dump of the database. EG: “mysqldump mysql” to dump the system tables. The data compresses well (being plain text of a regular format) so piping it through “gzip -9” is a good idea. To backup the system database you could run “mysqldump mysql | gzip -9 > mysql.sql.gz“. To restore simply run “mysql -u user database < file“, in the case of the previous example “zcat mysql.sql.gz | mysql -u root database“.
To dump only selected tables you can run “mysqldump database table1 [table2]“.
The option --skip-extended-insert means that a single INSERT statement will be used for each row. This gives a bigger dump file but allows running diff on multiple dump files.
The option --all-databases or -A dumps all databases.
The option --add-locks causes the tables to be locked on insert and improves performance.
Note that mysqldump blocks other database write operations so don’t pipe it through less or any other process that won’t read all the data in a small amount of time.
mysqldump -d DB_NAME dumps the schema.
The option --single-transaction causes mysqldump to use a transaction for the dump (so that the database can be used in the mean time). This only works with INNODB. To convert a table to INNODB the following command can be used:
ALTER TABLE tablename ENGINE = INNODB;
To create a slave run mysqldump with the --master-data=1.
When a master has it’s binary logs get too big a command such as “PURGE MASTER LOGS BEFORE ‘2008-12-02 22:46:26’;” will purge the old logs. An alternate version is of the form “PURGE MASTER LOGS TO ‘mysql-bin.010’;“. The MySQL documentation describes how to view the slave status to make sure that this doesn’t break replication.