Linux 命令行上的文字处理

总是有些用户, 明明是自己手抖点错了, 却偏偏要怪服务器出问题. 如果让我选择相信一个人还是一台机器, 那… 还是选机器比较放心. 当然也不能冤枉好人, 于是如何从若干 GB 的服务器日志里找到线索就成为解决问题的关键了.

首先是 grep. grep 就好像是个过滤器, 将无关的内容滤掉, 却从不漏下真相. 假设服务器日志是 server.log, 其中包含时间, 地点, 人物:

1, 找出所有含 beijing 的记录

grep beijing server.log

2, 包含 2013-12-01 当天, 在 beijing 关于 user 的记录

grep  -E -e ‘2013-12-01.*beijing.*user’ server.log

3, 也可以将 grep 串联起来, 逐步缩小包围圈, 这样如果个别记录不符合时间, 地点, 人物的顺序, 也不会被漏掉. 当然我觉得日志还是规矩一点的好.

grep ‘2013-12-01’ server.log |grep beijing |grep user

另外作为开发人员, 使用 grep 来分析代码也很不错的. 找到目标之后, 很可能需要生成一个报表, 最简单的就是 cut 命令了. 假设日志格式是”date time location user action”, 如果我们只需要”date time user action”, 那么

grep beijing server.log| cut -d ‘ ‘ -f1,2,4,5

其中 -d ‘ ‘ 指定使用空格 ‘ ‘ 来做分隔符, -f1,2,4,5 就分别代表需要输出的字段, 因为 location 是第三个, 因此 3 没有出现. 比 cut 强大的多的就是 awk 了, 生成一个有小计/总计什么的表格完全是小菜. 不过这个不是我的兴趣, 所以就点到为止.

🙂

用 MariaDB 替换 MySQL

ice_logo-5dcea9e47b780ff52f75c3c3304d54827f56211e

自从 MySQL 被邪恶的 Oracle 收购后, 貌似就到了后娘手里, 基本没什么发展. 不过还好, 原创班子已另起炉灶, 在 MySQL 5.5 的基础上做出很多改良, 发布了 MariaDB 5.5. 另外一个好消息就是终于看到了国人在开源圈子里的贡献: MariaDB 10.x 分支就包含了来自淘宝的两处贡献:

https://mariadb.com/kb/en/what-is-mariadb-100/ <–在这页上找 taobao 即可.

希望这样的案例越来越多吧. 免费使用开源软件, 在事业成功之后回馈开源社区, 这是个良性循环.

目前我试用了 MariaDB 5.5, 是 MySQL 5.5 的完美替代品. 安装方法在此:

https://downloads.mariadb.org/mariadb/repositories/#mirror=aarnet_pty_ltd&distro=Debian&distro_release=squeeze&version=5.5

另外如果用 Ruby 的 mysql2 gem 的话, 需要安装 libmariadbclient-dev(debian/ubuntu). 而如果 innotop 这个小工具不灵的话, 很可能需要安装 libterm-readkey-perl.

🙂

 

小试分身 MySQL Replication

打理数据库服务器, 再怎么优化终究会面临一台再强的服务器也不够用的时候. 那就使用多台服务器做 Replication 吧. 先从2台 MySQL 服务器开始, 一台为主, 另一台为从. 基本的步骤是(装系统/装软件/配置网络连接什么的就略过了…

1, 在主服务器的配置(/etc/mysql/my.cnf)里添加

[mysqld]
log-bin=/var/log/mysql/mysql-bin.log
server-id=1

然后重新启动 mysql 服务.

2, 在从服务器的配置里添加

[mysqld]
server-id=2

然后重新启动.

3, 在主服务器上添加 replication 专用用户, 例如 repl

create user ‘repl’@’%.<domain.name>’ identified by ‘<pass>’ ;
grant replication slave on *.* to ‘repl’@’%.<domain.name>’ ;
flush privileges ;

4, 锁定主数据库, 记录 bin-log 指针位置并导出数据

flush tables with read lock;
show master status;

记录下来 show 命令的输出的 <log file> <position> 后面有用. 然后使用 mysqldump 导出数据的快照, 用另一个会话, 前面那个不要关, 否则锁定状态就失效了, 到导致数据被更新而不一致.

mysqldump –all-databases > all.sql

可以利用 md5 来验证一下磁盘上的快照文件是否有瑕疵

mysqldump –all-databases | tee all.sql | md5
md5 all.sql

5, 主数据库上的操作完成了, 解锁, 恢复上线:

unlock tables;

6, 确定从数据库还没有打开”从属”模式, 然后导入数据快照(我喜欢用pv查看进展)

slave stop;

pv -p all.sql | mysql

7, 告诉从数据库, 它的主库在哪里

change master to master_host=<host>, master_user=’repl’, master_password='<pass>’, master_log_file='<log file>’, master_log_pos=<position>, …
start slave;

8, 监视日志文件, 看看是否存在错误

tail -f /var/log/daemon.log

另外可以测试一下在主数据库里做的更新会不会出现在从数据库里面.  🙂

PS. 在 Debian + MySQL 5.5 上实验成功, 但以上笔记是过后补写的, 如有错误, 欢迎指出.

PPS. 来自 MySQL 娘家的参考 http://dev.mysql.com/doc/refman/5.5/en/replication-howto.html

笔记: 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 的额外开销还真不小. 有机会还是把数据库直接跑在真刀真枪的物理层吧.

🙂