Skip to content
RIPE NCC member · Local Internet RegistryCall us on 020 3318 3449sales@hosting-telecom.uk

MySQL on your own server

Cloud servers7 min read

The basics of working with MySQL on a VDS: users, privileges and moving a database.

Contents
  • MySQL databases are stored in /var/lib/mysql/db
  • phpMyAdmin – work with MySQL through a web interface

Installing from the Debian repositories

  • Install the MySQL server:
# apt-get install mysql-server
  • It starts automatically after installation. To start it manually, run:
# /etc/init.d/mysql start
  • You can see how it started in /var/log/syslog. Connect to the server:
# mysql -u root mysql
  • Change the administrator password and exit:
mysql> UPDATE user SET Password=PASSWORD('new_pass') WHERE user='root';
mysql> quit
  • Reload the server:
# /etc/init.d/mysql reload
  • Connect to the server again, this time with the password:
# mysql -u root -p mysql

Moving a database (backup and restore)

You can export a database with phpMyAdmin or mysqldump:

# mysqldump -u root -p DBName > mydb.sql

To export all databases, use the --all-databases option instead of DBName.

If mysqldump does not run, give the full path to it, which you can find with this command:

# find / -name mysqldump
/usr/local/mysql-3.23.54a-pc-linux-i686/bin/mysqldump

To import a database, first create an empty one — and, to be safe, drop the old one first:

# mysql -u root -p
mysql> drop database if exists DBName;
mysql> create database DBName;
mysql> quit

and then load the data into it:

# mysql -u root -p DBName < mydb.sql

If the MySQL root user has no password, the -p option is not needed; you can also give the password directly, without a space, for example -pPassWord. Next, make sure that the new database has the user that was used to access the database before. If it does not, the simple way to give a user all privileges is:

mysql> GRANT ALL PRIVILEGES ON dbName.* TO UserName@localhost IDENTIFIED BY 'UserPassword';

Moving users with their privileges

To move users automatically, you can use the pt-show-grants utility from the Percona Toolkit suite. pt-show-grants works with Percona Server, MariaDB and MySQL, in any version.

To create manually exactly the same user as on the old server, with the corresponding privileges, export the mysql database and pick out all the rows that relate to that user:

# mysqldump -u root -p mysql > mysqldb.sql

The file mysqldb.sql will contain something like this:

INSERT INTO db VALUES ('%','DBName','UserName','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
INSERT INTO host VALUES ('localhost','UserName','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y','Y');
INSERT INTO user VALUES ('localhost', 'UserName', '','N','N','N','N','N','N','N','N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', '', '', '', '', 0, 0, 0);

When moving from one MySQL version to another, bear in mind that the number of fields is likely to differ, so you will need to edit the INSERT command. The password hashing algorithm may also change. You can find out how many fields there are by running:

mysql> SHOW COLUMNS FROM db;

You can specify only the fields you are interested in, and the rest will take their default values:

INSERT INTO `user` (`Host`, `User`, `Select_priv`, `Insert_priv`, `Update_priv`, `Delete_priv`) VALUES ('localhost','stacc','Y','Y','Y','Y');

Load the database with the command:

# mysql -u root -p mysql < mysqldb.sql

Commands

OS commands

mysql -u root -p12345 postfix < DB.sqlrun SQL statements from a file in batch mode against the postfix database
/usr/bin/mysqlcheck -a DBName
or
mysqlcheck -S /opt/zimbra/db/mysql.sock -uroot -p DBName
Check the integrity of a database
mysqldump -u UserName -p DBName > mydb.sqlExport (dump) a MySQL database
mysqldump --no-data -u UserName -p DBName > schema.sqlExport only the structure of a MySQL database
gzip > mydb.sql.gzExport with compression
mysql -u UserName -p DBName < mydb.sqlImport a database
gunzip < mydb.sql.gz | mysql -u UserName -p DBNameDecompress and import

MySQL commands

SHOW DATABASES;show all existing databases
SHOW TABLES;show the tables in the current database
SHOW COLUMNS FROM user;show the fields of the user table
CREATE DATABASE db_name CHARACTER SET utf8 COLLATE utf8_general_ci;create the database db_name, set the table character set to utf-8, and choose general_ci as the collation (the rules for ordering letters when sorting)
USE mysql;switch to the mysql database
SELECT host,user FROM user;show the host and user fields of the user table
DROP TABLE transport;delete the transport table
DELETE FROM user WHERE user='acct' AND host='%';delete a specific record
UPDATE db SET Delete_priv='Y' WHERE user='acct';change the value of a field in a record
FLUSH PRIVILEGES;apply the changes you have made
ALTER TABLE mailbox ADD (uid int(10) unsigned DEFAULT '107' NOT NULL);add a mandatory uid field to the mailbox table, with a default value of 107
ALTER TABLE mailbox DROP uid;remove the uid field from the mailbox table
GRANT ALL PRIVILEGES ON DBName.* TO UserName@localhost IDENTIFIED BY '12345';give the user UserName, connecting from localhost with the password 12345, all privileges on the database DBName (creates the user if it does not exist)
If you get the error:
ERROR 1290 (HY000): The MariaDB server is running with the --skip-grant-tables option so it cannot execute this statement
run the command:
FLUSH PRIVILEGES;
USE mysql;
SELECT user,host,db FROM db;
show which users can connect, from where, and to which databases
CHECK TABLE TableName;check the integrity of the table TableName
REPAIR TABLE TableName;repair the table TableName

- You can insert a record into a database from bash like this (after defining the variables, of course):

echo "INSERT INTO table_name (\`in\`,\`out\`) VALUES ('$delta_in', '$delta_out');" > $tmp_dir/temp.sql
`mysql -u$db_user -p$db_pass $db_name < $tmp_dir/temp.sql`

How to reset the MySQL root password

The procedure:

  1. Stop the server
  2. Start it in a mode that skips privilege checks
  3. Log in as root without giving a password
  4. Change the root password
  5. Exit
  6. Restart the server

The commands:

# /etc/init.d/mysqld stop
# mysqld_safe --skip-grant-tables &
# mysql -u root mysql
mysql> update user set Password=PASSWORD('new_password') where User='root';
mysql> quit
# /etc/init.d/mysqld restart

How to convert tables from MyISAM to InnoDB

  • Find out which tables use the MyISAM engine
mysql> SELECT TABLE_SCHEMA as DbName ,TABLE_NAME as TableName ,ENGINE as Engine FROM information_schema.TABLES WHERE ENGINE='MyISAM' AND TABLE_SCHEMA NOT IN('mysql','information_schema','performance_schema');
+------------+-----------------+--------+
| DbName     | TableName       | Engine |
+------------+-----------------+--------+
| my_db_name | searchindex     | MyISAM |
| my_db_name | sw__searchindex | MyISAM |
+------------+-----------------+--------+
  • Convert these tables to InnoDB:
ALTER TABLE my_db_name.searchindex ENGINE = InnoDB;
ALTER TABLE my_db_name.sw__searchindex ENGINE = InnoDB;

How to find the size of a database and its tables

  • From the operating system:
# du -h /var/lib/mysql
  • From MySQL. Log in as the root user:
 mysql -u root -p

and run this command:

SELECT table_schema AS "Database name",
SUM(data_length + index_length) AS "Size in bytes"
FROM information_schema.TABLES
GROUP BY table_schema;

To show the size in megabytes, replace the second line with:

ROUND(SUM(data_length + index_length) / 1024 / 1024, 2) AS "Size in MB"

To find the size of all tables in all databases:

SELECT table_schema as `Database`, table_name AS `Table`, 
round(((data_length + index_length) / 1024 / 1024), 2) `Size in MB` 
FROM information_schema.TABLES 
ORDER BY (data_length + index_length) DESC;

Debugging

By default, MySQL does not log the commands that are run on it. You may need this to debug applications that talk to it, for example when setting up Courier. You can turn logging on in the file /etc/init.d/mysql by commenting out the original program start in the start section and adding the --log option:

# /usr/bin/mysqld_safe > /dev/null 2>&1 &
/usr/bin/mysqld_safe --log &

Troubleshooting

ERROR 2003 (HY000): Can't connect to MySQL server on '10.0.0.12' (111)

Cause: requests are not reaching the MySQL server. There can be many reasons.

Solution: in /etc/mysql/my.cnf change the bind-address setting from the default 127.0.0.1 to the IP address of the interface — for example, on an internal network:

bind-address = 10.0.0.12
  • Official MySQL documentation. The name of each HTML file is the command it describes, which makes it quick to find the page for the command you need.

Didn’t find the answer? Ask our support team — we’ll help.

Choose which cookies we may use. You can change your mind at any time with the “Cookie settings” link at the bottom of every page.

Necessary

Always active

They keep the site secure and remember your cookie choice. They don’t identify you.

Google Analytics counts visits and shows which pages people find useful, so we can improve the site. Which cookies