月度归档: 2009 年 5 月

Oracle惊魂

今天中午,上演了一场Oracle数据库惊魂。

我们生产环境使用Oracle RAC,Oracle有两个节点,在中午11点30左右的时候,发现节点1故障,SSH不能连接,应用反映出来数据库连接不正常,此时节点2正常,由于SSH不能连接,也无法判断节点1服务器到底出现什么故障,所以,我让IT支持同事通知IDC重起节点1的机子,谁知噩梦开始发生,IDC工作人员竟然重起了节点2,导致两个节点都瘫痪,也不知道使我们机子的标签贴的有问题还是中国电信的工作水平是如此这般,无奈之下,只能等待,并通知IDC还是要重起节点1的机子,非常诡异的是节点2这台本来正常的机子,在重起后竟然SSH不能连接,真是祸不单行啊,在节点1的机子启动后,它上面的Oracle服务也恢复了正常,接下来只能再通知IDC重起节点2,此时只能保佑不要连不上,还算幸运,在几分钟的等待之后,节点2终于启动了,也能SSH上了,其Oracle服务器也在启动,我同时用crs_stat -t在观察节点状态,发现只有ora.ordb2.gsd处于UNKNOWN 状态,其他的都已经ONLINE了,用crs_stop ora.ordb2.gsd不行将其停掉,出现错误

Attempting to stop `ora.ordb2.gsd` on member `ordb2`
`ora.ordb2.gsd` on member `ordb2` has experienced an unrecoverable failure.
Human intervention required to resume its availability.
CRS-0216: Could not stop resource ‘ora.ordb2.gsd’.

crs_start ora.ordb2.gsd也不行

CRS-1028: Dependency analysis failed because of:
‘Resource in UNKNOWN state: ora.ordb2.gsd’
CRS-0223: Resource ‘ora.ordb2.gsd’ has placement error.

这是又急坏了我和远程支持我们的DBA,最后通过命令crs_stop ora.ordb2.gsd -f停止了ora.ordb2.gsd,再crs_start ora.ordb2.gsd,终于好了,Oracle恢复了正常。

PHP中的时间时区运算

我在测试twitter的API时,在它返回的用户信息里,关于用户时区的信息有两个

<utc_offset>28800</utc_offset>
<time_zone>Beijing</time_zone>

我希望利用这两个数值,得到用户的的DateTimeZone,直接new DateTimeZone(‘Beijing’)是不行的,我看了PHP的API,时区里是没有“Beijing”的,中国的时区应该是“Asia/Shanghai”,看来这个“Beijing”只是用来显示的,我又查了DateTimeZone的API,里面也没有根据UTC Offset值取得DateTimeZone的方法,看来不能通过这样的方法来做了。

utc_offset这个值是应该表示与UTC标准时间相差的秒数,测试下面的代码

$datetimezone = new DateTimeZone(‘Asia/Shanghai’);
$datetime = new DateTime(“now”,$datetimezone);
echo $datetime->getOffset();

结果显示28800,没错,时区“Asia/Shanghai”与UTC的时间差是28800秒,也就是8个小时(我们在东8区)。

在PHP中使用time()或是DateTime对象,在不指定DateTimeZone时,其默认的DateTimeZone就是UTC,产生的时间就是UTC时间,把这个时间加上Offset值之后,就可以显示出本时区的正确时间了,比如下面的代码

$datetime = time();
echo date(“y-m-d H:i:s”,$datetime);
echo “<br/>”;
$datetime = $datetime + 28800;
echo date(“y-m-d H:i:s”,$datetime);

输入的结果是
09-05-13 04:21:44
09-05-13 12:21:44

上面是UTC的时间,而下面的是北京时间。

在我们设计数据的时候,时间字段设计为长整数字段比较方便,存放UTC的time()的Unix时间戳,用户可以自己定义所在的时区,通过Offset,最终显示给用户其时区的时间。我感觉Java里的TimeZone似乎要更灵活一些,可以这样TimeZone.getTimeZone(“GMT+08:00”)

另外:在PHP里取得所有可用时区的方法是DateTimeZone::listIdentifiers()。

5.12纪念

纪念5.12汶川大地震

距离2008年5.12汶川大地震已经一年了,5.12注定是让中国人永远不能忘记的日子,回想去年地震后的日日夜夜,时时刻刻都会为震区的人们伤感或感动。

76年唐山地震时,我尚未出生,我不曾了解地震给人们带来的伤痛有多深,2008年,我的孩子1岁,看着他快乐的在阳光下游戏,想起汶川废墟下的一个个曾经一样鲜活的孩子的生命,他们父母心中的那种痛……

希望在地震中逝去的人们安息,而生者永远坚强,快乐幸福的生活。

Sphinx+Mysql初使用体验

应用越来越多的需要全文搜索技术来支撑,在Java中可以使用Lucene,一个非常优秀的引擎,在Hibernate中也整合了Lucene来做检索,但在使用PHP的过程中迫切需要找一个优秀的全文搜索引擎(虽然也可以把PHP和Lucene结合起来使用,但有些另类,有些生产环境也不能同时支持),以前在网上看到一些Sphinx的文章,一直没有实践,昨天我就花了一天的时间,配置测试了一下Sphinx。

由于我的PHP没有编译Sphinx模块,所以我主要是配置Sphinx+Mysql,在Mysql上测试全文搜索的效果,Mysql、Sphinx、中文分词的编译安装过程不详述,下面两篇文章挺好,安装时可以参考

Mysql+sphinx+中文分词简介

基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计

我的编译安装过程没有遇到什么麻烦,就是编译Mysql的时候比较长,而且要注意把Innodb的引擎编译进去,我的Mysql编译参数如下

./configure –with-plugins=sphinx,innobase,heap –prefix=/usr/local/mysql –enable-assembler –with-charset=utf8 –with-extra-charsets=all –enable-thread-safe-client –with-big-tables –with-readline –with-ssl –with-embedded-server –enable-local-infile

比较奇怪的是innodb是支持了,heap不支持,这个问题下次再研究。

通过编译Mysql,使Mysql支持了Sphinx存储引擎,试了一下Sphinx的例子,成功搜索到了数据,如果我们要对自己的数据做索引,就要研究一下Sphinx的配置文件了。

Sphinx的配置文件在其安装目录下的etc目录下,你可以参考其例子的sphinx.conf创建自己的配置文件,在sphinx里有主要要配置的有两大块,一部分是source(数据源),另一部分是index(索引),source里面定义了连接数据库的参数,取得源数据的SQL,也就是你要索引的数据的取得 SQL(Sphinx是支持不同数据源的,我这里只测试SQL),source可以有继承关系,继承的source可以用来做取得增量数据,index里面定义了使用哪个source,index存放的路径、字符集、辞典等等,index也可以继承,继承的index用来做增量索引。由此可见source 和index都是根据你的需要配置的,可以取得多个数据源的数据,可以建立多个索引。

增量索引的小困惑,我在数据库中增加了2条记录,执行

/usr/local/sphinx/bin/indexer –rotate –config /usr/local/sphinx/etc/sphinx.conf test1stemmed

看到有两个文档被加入索引(增量部分),之后我执行

/usr/local/sphinx/bin/indexer –rotate –merge test1 test1stemmed –merge-dst-range deleted 0 0

将增量索引并入主索引,这是可以查询到新插入的数据,这时我再继续插入一条数据,执行

/usr/local/sphinx/bin/indexer –rotate –config /usr/local/sphinx/etc/sphinx.conf test1stemmed

提示信息是有3个文档被加入索引,让我非常奇怪,因为上两条纪录已经并入主索引了,这次怎么还会索引呢?之后我执行

/usr/local/sphinx/bin/indexer –rotate –config /usr/local/sphinx/etc/sphinx.conf test1

更新主索引,之后再执行/usr/local/sphinx/bin/indexer –rotate –config /usr/local/sphinx/etc/sphinx.conf test1stemmed提示没有索引加入,这样就正确了,如果按照测试的结果,增量索引和主索引更新执行的时间要计划好。

关于中文分词–LibMMSeg:LibMMSeg 是Coreseek.com为 Sphinx 全文搜索引擎设计的中文分词软件包,其在GPL协议下发行的中文分词法,采用Chih-Hao Tsai的MMSEG算法。

同时Coreseek.com提供了一份Sphinx的中文文档,里面有比较详细的配置说明,是很好的参考资料,非常感谢开源人士做出的贡献。