Tuesday, December 05, 2006

小心时区陷阱(一)

不知道大家有没有碰到过这样的问题,原本好好的当前时区时间突然变为 0 时区时间。

这个问题困扰了我很久,原因有二:
1、程序不是个单文件脚本
2、单元测试无法重现错误

后来在同事的帮助下,总算找到了问题所在

localtime(3) calls tzset(3), but localtime_r(3) not.
threaded perl localtime() calls localtime_r(3) instead of localtime(3)

来看一下 Date::Simple 的一段源代码

sub format {
my ($self,$format)=@_;

$format= $fmts{refaddr($self)||''} || $fmts{ref($self)} || $Standard_Format
if @_==1;

return "$self" unless defined ($format);
require POSIX;
local $ENV{TZ} = 'UTC+0';
return POSIX::strftime ($format, _gmtime ($self));
}

POSIX::strftime() 调用 tzset() 时看到的环境变量 $ENV{TZ} 是 UTC+0。在这之后就有问题了,如果使用 localtime(),因为 localtime_r(3) 并不会调用 tzset(),所以即使环境变量 $ENV{TZ} 已经恢复原值,localtime() 查看内部变量的时候,还是之前的 UTC+0。

至于为什么 localtime_r(3) 不像 localtime(3) 一样调用 tzset(3) 根据环境变量重设时区,我理解下来的主要原因是因为,它是线程不安全的。可能会出现下面这种情况

thread1
thread2
tzset()
tzset()
localtime()
localtime()

另外,关于环境变量 $ENV{TZ}存在(exists),但其值为空的时候,也会得到 UTC+0 的结果。

相关链接:
perlbug #26136

Monday, November 13, 2006

Friday, November 03, 2006

AppLocale 和乱码

在安装 AppLocale 之后,微软安装程序包(MSI)的执行就会出现乱码。
网上广为流传的一个方法是把下面这个文件的内容清空,并将属性改为只读。

C:\WINDOWS\AppPatch\AppLoc.tmp


另有说法是直接删除亦可,并不会影响 AppLocale 的正常使用。

Monday, October 30, 2006

不那么成功的 Mozilla Firefox 2.0

在经历了短暂的亲密接触之后,工作和娱乐我都降级成了 1.5.0.7,很遗憾。

我很少降级软件,除非迫不得已。

2.0 的 UI 改进并不大,但是挺漂亮的,我很喜欢。至于把关闭按钮添加到每个标签页上,我倒觉得是个见仁见智的事情。除此以外,对我来说,就没有什么变化了。

工作环境下,2.0 本身并没有什么问题,蛮好的。但是,LiveHTTPHeaders 还没兼容 2.0,而对于我的工作来说,有时候它还真是那么得重要。在没找到替代插件之前,我能做的只能是降级 2.0。

娱乐环境下,出于不知名的原因,2.0 频频死机。好好的就失去响应了,还是缓不过神的那种。我现在用的网络本来就不好,这样一来,简直就是雪上加霜。没辙儿,怎么地我也犯不着跟自己过不去,降!

就这样,恋恋不舍地,我离开了 2.0。

Tuesday, October 24, 2006

外壳程序意外停止,Explorer.exe 被重新启动。

被这个问题困扰了一个星期,症状为:

在某些(我没能归纳出来)情况下,按下 Ctrl 键,Explorer.exe(不是浏览器,是最基础的那个 Explorer) 就崩溃重启了。没有错误报告,只能在事件查看器中发现来源于 Winlogon 的上述信息,事件 ID:1002。对其他程序倒是毫无影响,但是我就完全用不了 Ctrl+C/V 来操作文件了,甚是痛苦。

网上搜索了好几圈,看到有类似的问题,但是都没能解决我的问题。期间还差点弄爆系统,只要一按键盘,鼠标键盘全部失去响应,亏得有系统还原(擦把汗 -_-||)。最后总算撇到一文提到了金山词霸,嘿,还真对上号了!关闭 CB 就 OK。后来装了 CB 2005 的 SP1,就没有问题了。

小记一把,留作备忘。

Friday, October 20, 2006

MySQL 连接 localhost

在使用 mysql 连接 localhost 时,情况并不是表面上看起来的那样子。

举个例子:
$ mysql -u root test

这里没有指定主机,所以连接的是 localhost,若你是用 yum/apt-get/urpmi 等 RPM 管理工具安装了 MySQL 的话,这里称其为数据库 A,那么应该是很顺利地连接上了。然后,再安装一个 MySQL,称之为数据库 B,使用其他端口,比如 3307,再尝试连接。
$ mysql -u root -P 3307 test

你会发现,连上的还是数据库 A,而不是 B。

为啥乜?
因为连的是 localhost。

这种情况下,mysql 是通过 unix socket 而不是 tcp/ip 连接数据库的。所以,在本地有多个数据库的时候,用 -S 参数连接能保证 DWIM。举个例子:
$ mysql -u root -S /tmp/mysql_another.sock test

当然,也可以这样:
$ mysql -u root -h 192.168.0.1 -P 3307 test

只是 unix socket 方式可以获得更高的效率,闻得一说有 30% 之多,啧啧。

Thursday, October 19, 2006

MySQL 的 Control-C

Changes in release 5.0.25 (15 September 2006)

For the mysql client, typing Control-C causes mysql to attempt to kill the current statement. If this cannot be done, or Control-C is typed again before the statement is killed, mysql exits. Previously, Control-C caused mysql to exit in all cases. (Bug#17926; see also Bug#1989)

MySQL 总算解决这个问题了,放弃执行正在运行的 SQL 指令。

以往如果误执行了一个巨慢的 SQL 指令,通常的做法是 Control-C 退出并重新进入 MySQL 命令行环境,列出所有执行线程,找出那个慢郎中并杀之。现在好了,直接 Control-C 就能搞定了。

5.1 系在较早之前就加入了此功能,4.1 系至今没有同步此更新的迹象,遗憾……

Bug#1989 was submitted at 1 Dec 2003 12:51

忍不住牢骚一句,这个改进未免也来得太慢了一些啊!

Friday, October 06, 2006

heartbeat 学习笔记(二)

在 IP 的 failover 搞定之后,其他资源的添加就简单多了。
我这里要做的是把 Pound 挂到 heartbeat 下面去。需要添加的是一个支持 start & stop 的脚本,这里是个最简单的例子:
$ cat /etc/ha.d/resource.d/pound

#!/bin/sh

start() {
pound -f /etc/pound.cfg -p /var/run/pound.pid
}

stop() {
kill `cat /var/run/pound.pid`
rm -f /var/run/pound.pid
}

case "$1" in
start)
start
;;

stop)
stop
;;

*)
echo $"Usage: $0 {start|stop}"
;;
esac

然后把它添加到 haresources 中去:
$ cat /etc/ha.d/haresources

master_node 192.168.1.100 pound

至于 Pound 的设置,这里就略过不表了,搞定收工。

Thursday, October 05, 2006

heartbeat 学习笔记(一)

测试环境:
OS: CentOS 4.3
heartbeat: 1.2.3.cvs.20050927-1.c
两个节点,捆绑资源为 ipfail

/etc/ha.d/ha.cf 和 /etc/ha.d/haresources 基本上是照猫画虎,两个节点完全相同。认证模式为 crc,使用以太网接口、UDP单播方式通信。条件限制,没用使用串口。可用性测试为第三台主机不间断 ping virtual ip。auto_failback 设为 on。

下面我将主节点称为 A 节点,从节点称为 B 节点。
首先启动 A 节点的 heartbeat 服务,若不启动 B 节点的 heartbeat 服务,那么只有经过 initdead 时间后,A 节点才会启用本地资源;否则,在节点间发生通信后,根据设置文件及各节点的状态,A 节点会立即启用本地资源,这里指的是 virtual ip。

在 heartbeat 的文档中提到,ipfail 需要指定普通节点以外的 Ping 节点,以帮助各节点判断网络状况。Ping 节点一般可以是可用性比较高的网关路由器等。在实际测试中,从效果来看,有没有 Ping 节点并不影响效果。没有做更进一步的分析,跳过。

在启动各节点的 heartbeat 后,virtual ip 在 A 节点上正常启用了。然后关闭 A 节点的 heartbeat 来模拟 A 节点不可用的情况,B 节点顺利接过了 virtual ip。再启动 A 节点的 heartbeat,因为 auto_failback 为 on,所以 A 节点又重新接管 virtual ip。两次切换都没有影响第三台主机 ping 的结果,一直处于可用状态。

参考资料:
Linux HA
Linux 上的高可用中间件

Wednesday, October 04, 2006

NotiCPAN 正式上线

虽然功能不全,不过站点看起来已经不是那么得简陋了,接下来就是逐步完善功能了。

当前状态:
用户数:19
订阅数:318