2011年2月16日星期三

MySQL在线增量备份

    增量备份的好处是可以节省备份的时间和占用的磁盘空间,可以根据业务和数据的特性,指定不同的全备和增量备份策略。
  
    备份最好是在slave上面进行,这样可以不对主库造成任何影响。使用xtrabackup这个工具能实现在线全备和在线增量备份,步骤如下:

    1、先做一个全备份
xtrabackup --backup --datadir=/data/iscsi/db/ --target-dir=/data/backups/mysql/

    2、每天增量备份

xtrabackup --backup --target-dir=/data/backups/inc/tue/   --incremental-basedir=/data/backups/mysql/       #Suppose the full backup is on Monday,Create an incremental backup on Tuesday

xtrabackup --backup --target-dir=/data/backups/inc/wed/   --incremental-basedir=/data/backups/inc/tue/     #Create an incremental backup on Wednesday

发生异常需要恢复时:

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/mysql/                                               #Prepare the base backup from Monday

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/mysql/  --incremental-dir=/data/backups/inc/tue/     #Roll Monday's data forward to the state on Tuesday

xtrabackup --prepare --apply-log-only --target-dir=/data/backups/mysql/  --incremental-dir=/data/backups/inc/wed/     #Roll forward again to the state on Wednesday

    你可以用脚本程序和crontab一起来控制全备和增量备份的策略,将备份放在远程的服务器上面(可以在数据库服务器上面连接盘柜),达到数据安全的目的。

2011年2月15日星期二

在线做MySQL slave

    之前给MySQL master做slave的时候,为了保证数据一致性,一般选择read lock或者停机,使用直接拷贝文件或者mysqldump的方法来实现。这种方法会使master在一段时间内不可写,影响业务的正常使用。

    有没有更好的方法,可以在master可读写的情况下,生成一个数据没有差错的slave呢?用innobackupex可以实现。具体的原理可以去看文档。实现步骤如下:

    1. on slave:
          nc -l 9999 | cat - > /data/backups/backup.tar
    2. on master:
          innobackupex --stream=tar --slave-info ./ | nc desthost 9999
    3. on slave:
          cd /data/backups/
          tar -ixvf /data/backups/backup.tar
          innobackupex --apply-log  --use-memory 5000M /data/backups

  

2010年12月27日星期一

MySQL profile中'Sending data'很慢的问题

这几天,对MySQL(5.0.77)数据库中一个几百行记录的表(用于任务分配,读写比较频繁),进行的一个简单查询,从1s逐渐增大到15s。

mysql> select id from t_task limit 1;
+----------+
| id       |
+----------+
| 22865305 |
+----------+
1 row in set (15.24 sec)
Profiling的结果是:
 mysql> show profile for query 1;
+--------------------------------+-----------+
| Status                         | Duration  |
+--------------------------------+-----------+
| starting                       |  0.000014 |
| checking query cache for query |  0.000032 |
| Opening tables                 |  0.000012 |
| System lock                    |  0.000003 |
| Table lock                     |  0.000006 |
| init                           |  0.000010 |
| optimizing                     |  0.000003 |
| statistics                     |  0.000006 |
| preparing                      |  0.000004 |
| executing                      |  0.000003 |
| Sending data                   | 15.242734 |
| end                            |  0.000011 |
| query end                      |  0.000002 |
| freeing items                  |  0.000013 |
| logging slow query             |  0.000003 |
| logging slow query             |  0.000002 |
| cleaning up                    |  0.000002 |
+--------------------------------+-----------+
17 rows in set (0.00 sec)
从字面意思看,是慢在‘传输数据’这一步。

‘Sending data’的意义查不到具体的说明,这里http://forums.mysql.com/read.php?24,241461,242012#msg-242012有人说是:
Each time means the time elapsed between the previous event and the new event. So, the line:
| Sending data | 0.00016800 |
means that 0.00016800 seconds elapsed between "executing" and "Sending data". It is, it takes 0.00016800 seconds to execute the query.



可以在sql_select.cc里面看到源代码(在里面搜索Sending data),可以看到do_select的时间也算在‘sending data‘里面了。


所以这个‘sending data‘并不只是数据传输的时间,也包含select的时间。有人就这个语义含糊的问题给MySQL报过bug:http://bugs.mysql.com/bug.php?id=52492,但是不了了之。

这个问题最初怀疑是网卡有问题(这台机器之前网卡有问题,更新过驱动),但是新建一张表结构一样,数据量一样的表,做同样的查询,速度又很快。又怀疑是磁盘问题,因为根据pk的查询都很快(因为簇集索引所以都缓存在内存里面),vmstat和iostat都没有发现异常。

准备晚上升级MySQL,并使用HP BL460刀片机替换这台出过硬件故障的IBM x3650M2。

2010年11月29日星期一

动态控制MySQL慢查询日志的设置

To control the slow log at runtime, use the global slow_query_log and slow_query_log_file system variables. Set slow_query_log to 0 (or OFF) to disable the log or to 1 (or ON) to enable it. Set slow_query_log_file to specify the name of the log file. If a log file already is open, it is closed and the new file is opened.Set long_query_time to specify the seconds。
设置完成后,你可以通过select @@slow_query_log来确认是否设置成功。