MySQL
From Consultancy.EdVoncken.NET
MySQL is a popular Open Source database, mostly used in web environments.
Contents |
Overview
Relevant files and directories on Linux:
- /etc/my.cnf
- Configuration file for mysqld startup, parsed by /etc/init.d/mysqld
- /var/lib/mysql
- Default location for databases
- /ver/log/mysqld.log
- Default error-log
Additional information:
Postinstall actions
Initial actions on the database
Before handing over a MySQL database server to the client make sure that the default settings are altered since these are fairly insecure.
On unix MySQL will listen both to a socket file and a network interface. Unless needed the network interface should be disabled since it is often not needed and posses a security risk.
To do this login to the database
# mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 6635 to server version: 5.0.27 Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql>
Then remove the test database
mysql> drop database test; Query OK, 0 rows affected (0.00 sec)
Remove all users except root on localhost
mysql> use mysql Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed mysql> delete from user where not (host="localhost" and user="root"); Query OK, 3 rows affected (0.01 sec)
Change the database user from root to mysqldba (or anything else).
mysql> update user set user="mysqldba" where user="root"; Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0 mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
NOTE the flush is required
mysql> SET PASSWORD FOR 'mysqldba'@'localhost' = PASSWORD('S3cr3t!');
Query OK, 0 rows affected (0.00 sec)
Backup
MySQL has multiple storage engines, one of these is InnoDB unlike MyISAM (which is the default) it stores all data in a single (binary) file. This means that on an active database you run a high risk that the file is in flux during backup. The solutions to this is failry simple: Dump the database localy and backup the dump.
Example dump script
#!/bin/bash
#
#
export PATH=/usr/bin:$PATH
TS_START=`date +%s`
BACKUPDIR="/var/backup"
FILETS=$(date +%d%B%Y_%H%M)
# Set the database name
DATABASE="databasename"
# Set the output file
OUTFILE="${BACKUPDIR}/${DATABASE}_${FILETS}.sql"
# Make the actual dump
mysqldump --add-drop-database --password=dbpasswd --quick \
--quote-names --user=dbuser --result-file=$OUTFILE $DATABASE
# compress the dump (tends to be a bit bloated)
/bin/gzip $OUTFILE
TS_END=`date +%s`
echo "$TS_START $TS_END" | awk '{ printf "backup took %d seconds", ( $2 - $1 ) }' | logger
Stick this in e.g. '/etc/cron.daily/backupdb.sh' with permissions 500. Then a daily dump of the database is made in '/var/backup'. This can then be used either to restore a database or to write a decent backup to tape.
A thing often overlooked is the permissions within MySQL also called GRANTS. To dump this in a usable way you can use mysqldumpall, described below.
MySQL Management and Monitoring Tools
phpMyAdmin
myTop
mytop requires the Perl module Term::Readkey. This is installed from CPAN, the Comprehensive Perl Archive Network:
perl -MCPAN -e shell ... cpan> install Term::ReadKey cpan> quit
mysqldumpall
Solid local backups of you MySQL databases http://www.biomechs.nl/scripts/mysqldumpall (docu)
Common Issues
Temporary directory too small for MySQL
The systemwide TMP-directories are max. 2GB in size. MySQL uses the TMP-directory for table copies, for example during "optimize". This implies that the maximum size would be limited to around 2GB, which is not acceptable.
Solution: I've created a TMP-directory specifically for MySQL, and added a setting in /etc/my.cnf to make these change take effect:
[root@nlvud140 /]# ls -ld /var/lib/mysql-tmp/ drwxr-x--- 2 mysql mysql 4096 Jan 24 11:39 /var/lib/mysql-tmp/
[root@nlvud140 /]# cat /etc/my.cnf [mysqld] datadir=/var/lib/mysql tmpdir=/var/lib/mysql-tmp socket=/var/lib/mysql/mysql.sock # Default to using old password format for compatibility with mysql 3.x # clients (those using the mysqlclient10 compatibility package). old_passwords=1 [mysql.server] user=mysql basedir=/var/lib [mysqld_safe] err-log=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid
Host is not allowed to connect to this MySQL server
When trying to connect to the database server remotely, you may encounter the following error:
[root@nlvud141 ~]# mysql -h mysql.gdc1.ce.philips.com ERROR 1130 (00000): #HY000Host 'nlvud141.gdc1.ce.philips.com' is not allowed to connect to this MySQL server
This error is confusing at first; we're not even at the user/password stage, as was verified using telnet:
[root@nlvud141 ~]# telnet mysql 3306 Trying 130.144.23.140... Connected to nlvud140.gdc1.ce.philips.com (130.144.23.140). Escape character is '^]'. [#HY000Host 'nlvud141.gdc1.ce.philips.com' is not allowed to connect to this MySQL server Connection closed by foreign host.
It turns out that MySQL checks if there is any user with sufficient privileges to access MySQL from that remote host, even before presenting the user/password dialog.
Solution: create a dummy user named "remote-access", with no privileges at all. I set a generated password on this account, to prevent anonymous logins.