Archive for the 'Database' Category
Benchmarking Metrics for MySQL Data Purge
MySQL是个非常优秀的免费数据库,下面是我周末做Data Purge的部分记录,可以用做将来的参考之用:
硬件:AMD Opteron 265 1.8G(Cache 1M), RAM:1G, HD: 350G,算是配置比较差的一台服务器。请注意,下面所提到的数据和您的服务器性能有很大的关系。
// Delete Data
2009-09-03 19:45:45 Start…
Row Count: 46500394(46M)
DELETE FROM atedata WHERE DATE < ’2009-06-01 00:00:00′
Row Count: 22699749(22M)
2009-09-03 21:18:06 End…
从上面可以看出,删除数据是比较慢的操作,46M条的数据,删除到22M条,总共用了大概93分钟,大概255,921rows/min。删除操作所需时间主要和将要删除的数据量是成正比的,删除的记录数越多,所用的时间也越多。
// Optimize Table
2009-09-04 21:33:54 Start…
Row Count: 23051455(23M) – 7.1GiB
optimize table atedata
Row Count: 23051455(23M) – 3.4GiB
2009-09-04 22:15:37 End…
对于数据量比较大的表,比如超过1G,如果只是简单的用DELETE删除了数据,这些数据所占据的磁盘空间并没有被释放,在MySQL里我们称之为:Overhead。只有对表做了OPTIMIZE操作,才能真正的释放它。
从上面的数据可以看出,优化前,表大小是7.1G,优化后表大小为3.4G,表的记录数没有变化,用时42分钟,平均88MiB每分钟。该操作耗时大致和(Table Size – Overhead)的差成正比。对于那种比较大的表,千万不要删除了几百条记录就做Optimize操作,因为它太耗费时间了,我们可以累积到一定数量再做。
Optimize命令执行后,MySQL会生产一个临时的.TMD文件,MySQL的状态显示Repair by sorting,它其实就是优化后的表。这个过程很漫长,做完后,还有一步是重建索引,MySQL状态显示Repair with Keycache,结束的时候会有个.TMM的临时文件生成,它可能就是.MYI文件的拷贝,不过官方文档没有说明,只是猜测。
在创建索引文件的过程中(Repair with Keycache),它的耗时和表的索引多少有很大的关系,我没有验证,但我们可以猜测:索引越多,这个过程就越长。
由于在表很大的情况下,做类似DELETE、OPTIMIZE、ALTER等操作,都是非常的耗时间,所以我们在设计系统的时候就需要提前考虑到:
- 保存数据的时间长度
- 做Data Purge的周期、方法策略
- 数据备份的策略
- Data Purge的过程中,系统该如何应对(以上操作都会造成MySQL被锁定,数据库无法使用)
- 等等
如果数据量不大的话,另当别论。
MySQL Replication Setup
MySQL虽然是一款免费的服务器,但其功能和性能均表现不错,下面简单的介绍一下如何设置Replication Server,即主从热备份。这样做的好处之一是可以把比较耗资源的查询操作转移到从服务器上,从而提高系统整体性能。(比如,本文的background是:有一两百台producer服务器向master的MySQL进行查询和修改操作,并同时还有若干的外部系统(consumer)需要查询这个master数据库,为了分担master的loading,所以我们引入了一个或者多个slave,让外部的系统转而查询slave,达到某种意义上的负载均衡)
本操作的环境为:
- CentOS 5.2
- MySQL-server-community-5.1.23-0.rhel4
- 需要同步的数据库por和misc中有旧的数据,如果是空的库,下面的操作就简单一些了。
- 这里待复制的两个库por和misc均使用MyISAM引擎
Step I:
首先编辑主服务器的my.cnf,下面是个例子:
[mysqld]
…
log-bin=mysql-bin
binlog-do-db=por
binlog-do-db=misc
binlog-ignore-db=mysql
server-id=1
…
Replaction是基于log文件的,所以这里必须打开MySQL的log功能,log-bin参数指明log文件的前缀,binlog-do-db参数指明你要同步的数据库名,binlog-ignore-db指明你不想同步的数据库名(在本次安装方案中,有些多余,不过我没有测试去掉它会如何)
还有一个重要的是要设置master服务器的ID,也就是serer-id。接下来,在master上创建一个用户同步的用户:
mysql> GRANT REPLICATION SLAVE ON *.*
-> TO 'repl'@'%' IDENTIFIED BY 'this_is_your_password';
Step II
重启MySQL服务器,这样就会生成log文件,通常在/var/lib/mysql下,然后用root登录,执行如下命令
mysql> FLUSH TABLES WITH READ LOCK;
这样做的目的是,让master服务器停止更新操作,可以为接下来的同步数据做一个干净的copy。
Step III
进入/var/lib/mysql 将你要同步的的数据库打包,比如这里为:por.tar和misc.tar
然后在MySQL命令行下执行:
show master status;
系统提示:
mysql> show master status;
+——————+———–+——————-+——————+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+——————+———–+——————-+——————+
| mysql-bin.000001 | 106| por,misc,por,misc | mysql,mysql |
+——————+———–+——————-+——————+
1 row in set (0.00 sec)
这时候你就可以解除锁定了:
mysql> UNLOCK TABLES;
Step IV:
下面开始设置slave server
编辑slave 的my.cnf如下:
[mysqld]
…
server-id=2
master-host=165.204.233.38
master-user=repl
master-password=this_is_your_password
master-port=3306
master-connect-retry=60
…
Step V:
重启Slave,用root登录,执行如下命令:
>stop slave;
> change master to
-> master_host=’165.204.233.38′,
-> master_user=’repl’,
-> master_password=’this_is_your_password’,
-> master_log_file=’mysql-bin.000001′, // 注意这里的文件名就是上面提到的 show master status中显示的文件名
-> master_log_pos=106; // 注意这里的便宜值就是上面提到的 show master status中显示的偏移值
> slave start;
完毕。
测试一下吧,在master里面建一个新的table,看看是否在slave中出现。
附录:
- 如果你同步不成功,请查看MySQL的日志 缺省位于:/var/log/mysqld.log
- 最好主从服务器使用同一版本的MySQL
- 这里所配置的只是Replication Server,不是MySQL Cluster,不要混为一谈