笔记: Xen VM 里面的 MySQL 服务器优化

我一直都对公司 Xen VM 的数据库服务器不满, 因为实在是太慢了. 但是几百个 GB 的商业数据我可不敢动, 于是先在测试服务器上证实一下我的想法. 测试环境是:

  • Dom0: Debian 6 Xen Hypervisor 64-bit, Xen 4.0
  • DomU: Debian 6  64-bit
  • MySQL server 5.1, innodb_file_per_table, pool=1GB, log=256MB
  • 硬盘就是普通的 SATA 7200RPM, VM 用的是 LVM 分区

然后我用之前写的一个小程序做批量更新, 32K 记录. 缺省配置下, 运行时长达到24分钟, 而优化后则只需要27秒. 差不多60倍?? 我都有点不敢相信了. 下面是对应的配置和测试数据. 每次更改配置后都会重启 MySQL, 因此不大可能是缓存在起作用.

Updating 32606 records (client table), InnoDB table, autocommit=true, file_per_table, pool=1GB, log=256MB

Default(Xen):
real 24m46.195s
TPS 21.9

(Xen)With innodb_flush_method=O_DIRECT
real 24m45.024s
TPS 21.95

(Xen)With innodb_flush_method=O_DIRECT, innodb_flush_log_at_trx_commit=0
real 0m37.873s
TPS 860.9

(Xen)With innodb_flush_method=O_DSYNC, innodb_flush_log_at_trx_commit=0
real 0m27.352s
TPS 1192

看来 innodb_flush_log_at_trx_commit 是关键, 按照文档设置为 0 的话每秒 flush 一次, 而不是每个 transaction.

通过实验, 我的判断基本被验证, 看来 Xen 对于磁盘 IO 的额外开销还真不小. 有机会还是把数据库直接跑在真刀真枪的物理层吧.

🙂

让Mysql server接受远程访问

一直以来,由于我没做过什么大网站,或者说没把任何网站做大 -_-b 总之我用的LAMP都在一个box里。那么如果把数据库服务隔离出来单独做一个box,该怎么办呢?

首先,修改mysql的配置文件(以mysql 5.0为例):

$ sudo vim /etc/mysql/my.cnf

找到

bind-address            = 127.0.0.1

将127.0.0.1替换为服务器的外部IP,然后存盘退出。

为了避免缓慢的远程连接,还必须在[mysqld]段加上:

skip-name-resolve

下一步是在mysql中为远程用户开启权限:

mysql>GRANT ALL ON your-database.* TO ‘your-user’@’client-name or IP’ [IDENTIFIED BY ‘yourpass’];

mysql>FLUSH PRIVILEDGES;

下一步,要确认firewall为mysql连接让路。以ufw为例:

$ sudo ufw allow 3306

这样简单的开放了3306端口,但没有做任何限制。差不多了吧,从client一端可以测试一下了:

$ mysql -h mysql-server -u your-user  [-p]

🙂

LAMP服务器的简单备份方法

我用CentOS作为网站服务器的OS,我是这样备份我的网站的。

以下简称网站服务器为C,我的电脑是A。首先,在C上用一段shell script备份网站:

backup.sh

#! /bin/bash
# This script is to backup the website files and db

mysqldump mydb -pmypass >/var/www/mysite/mydump.sql

datestamp=`date +%Y%m%d`
filewww=”/home/myuser/backup/mysite_””$datestamp””.zip”

zip -r $filewww /var/www/mysite

然后可以先运行一下这个script,看看结果是否符合预期。如果没问题,就可以将其加入到crontab了,每天自动运行。

59 3 * * * /bin/bash /home/myuser/backup.sh

这样C这边每天凌晨会备份一次并生成一个zip压缩包。但是把C的备份留在C就没意义了,我还要定期的把zip从C传到A。由于A不像C那样不间断运行的,所以如果从C向A传输就需要测试A是否在线,麻烦。不如让A取C上的zip。这就涉及到另一个问题,身份验证。

为一段自动运行的script提供password,我觉得不如使用public key验证来得专业,而且简单,两步就搞定:

ssh-keygen -t rsa

ssh-copy-id -i .ssh/id_rsa.pub [email protected]

这期间问到private key password时直接回车就行了;[email protected]的password还是需要输入的(否则……)。

下一步就是在A上写script,获取C上的备份,成功获取后删除C上的备份,并将A本机上超过一个月的备份删除。

backup-mysite.sh

#!/bin/bash
#by Raymond, Jun, 2009
#1, get backup files from …
#2, delete after a successful copy
scp [email protected]:/home/myuser/backup/*.zip /home/myuser/backup
if [ $? -eq 0 ]
then
ssh [email protected] rm /home/myuser/backup/*.zip
fi

#3, delete old backup files here
find /home/myuser/backup/*.zip -mtime +30 -exec rm {} \;

最后在把此script添加到A的crontab基本就没事了。过程类似上面的crontab,就偷懒不写了。注:懒是SA的美德。

Update: mysqldump –opt 对于恢复数据是个很好的开关.