2007年10月31日星期三

真正的“AI”,是不是可以这样?

看到Cat Chen S.T.A.L.K.E.R中胡侃这个游戏的AI如何优秀,不禁产生了一种念头,一种新的AI实现思路。

AI就是人工智能,通俗一点说就是控制游戏中NPC如何行动的指令,简单的AI很容易公式化,比如反恐精英cs中的bot,基本上都是按照脚本的规定来行动,更复杂和高级的AI会加入思考、互动的因素,也就更"聪明"一些。

AI往高了说,属于计算机科学的尖端领域,但往简单了说,只不过是科学家设计好公式,利用计算机运算速度快的优势来模拟的思考过程罢了,高深也就高深在了公式/算法和了,计算机只是一个跑得比较快,会先飞的笨鸟罢了。但在很多时候,AI还无法达到普通人的程度,这也就是我的念头了,能否在游戏中,用玩家行为来作为AI,或者为AI提供数据呢?

假想一个游戏,分为两个阵营,拉据战的格局,苏、德双方展开坦克大战,攻夺据点。把游戏分为两个服务器,苏服和德服,苏服上的玩家都是苏军,敌人是AI,不过这个AI就是德服上扮演德军的玩家。这样,以往的NPC就不会再笨呼呼的了,而是"像"真实的玩家一样战斗,甚至血少的时候也会偷懒等等。

最关键的,就是要体现不同于单机游戏的,真实的模拟另一个服务器上玩家的行为模式,同时还要和玩家之间对战区分开来。比如坦克的配置是copy玩家数据,而作为AI的坦克被打爆了玩家可不会掉经验等等。能够把这两点都体现出来,现在的游戏好像还没有。

还想到一个更远一点的例子,在mmorpg中打怪的时候,怪物一般都形成规律了,在什么地方、有什么招数,怎么配置队伍就能打倒它,甚至捡到相同的宝贝。。。这样不腻么?为高级玩家开通变身为怪的功能吧。呼呼,别人组队再来打toj的时候,怎么怪物变了?以前都呆着不动的,今天满大街溜达,也不发招。。。如此这般,也等于是在这段时期内用人的智慧让npc更加完善了,如果聪明的玩家还会在变身为怪物的时候,模拟真实怪物的以为,诱骗其它玩家上钩的话就更加有趣了。

想法扯完了,写完再想实现起来还是有些难度的,不过算是一个思路吧,不要一味钻进如何完善npc自身"功能"的死胡同,引入玩家的隐式互动。关于那个苏德坦克大战的游戏,以前倒还真是玩过(直接玩家对抗的),不过好像网站上不去了,http://www.blitz1941.com/ ,我这里也仅存三张截图,还算有一定代表性,一起怀念一下吧:



Go to ImageShack® to Create your own Slideshow

Source: http://www.fwolf.com/blog/post/364

2007年10月30日星期二

将情感进销存的编码从gb2312改变为utf8

应一个朋友的需要,用免费开源的情感进销存给他开小店用,刚开始嘛,先试试看好用不。好像情感是国内仅存的免费、开源,又能用,还有人继续维护的进销存软件了,挺难得的。

情感进销存默认的编码全部都是gb2312的,从数据库到html,而我的环境自然是全utf8编码的ubuntu,如果是一次性转换的话,手工也是可以作的,但情感进销存如果出新版,还得从头改过,所以搞了个小脚本来自动转换:

#!/bin/bash

find . -name "*.txt" |xargs -I '{}' iconv_gb2u '{}'
find . -name "*.htm" |xargs -I '{}' iconv_gb2u '{}'
find . -name "*.php" |xargs -I '{}' iconv_gb2u '{}'
find . -name "*.sql" |xargs -I '{}' iconv_gb2u '{}'

#echo "Modify libs/mysql.class.php, change set names gbk to utf8."
# echo "Modify tpls/head.htm, head.emp.html, change http-equiv gbk to utf9"
replace "charset=gbk" "charset=utf8" -- install/*.php
replace "CHARSET=gbk" "charset=utf8" -- install/*.php
replace "SET NAMES 'gbk'" "SET NAMES 'utf8'" -- libs/mysql.class.php
replace "charset=gbk" "charset=utf8" -- tpls/*.htm

# For safe
chmod -x `basename $0`

其中用到的iconv_gb2u也是一个小脚本,作用是使用iconv命令把gb2312编码的文件转换为utf8,原生的iconv只能转换,不能回写同名文件,用这个脚本写到临时文件再拷回来覆盖。

再转回来说咱们的php程序的编码转换,首先要把所有的文件编码都转换了,包括txt类型的readme说明文件,htm类型的模板,php类型的程序,主要是为了看里面的注释,以及sql类型的数据库定义,里面还有初始化的数据,所以必须进行编码转换。这些转换用iconv就可以了,用 find配合xargs一次性全部转换完毕。

接下来install/*.php中替换的是html页面的编码,以及执行安装sql创建数据表时指定表的默认编码;libs/mysql.class.php是连接数据库后指定客户端连接的字符集;tpls/*.htm则是替换html页面中的编码定义。这些用到了replace命令,replace可以把文件中的一个字符串替换为另外一个字符串,好像是mysql附带的实用小程序,在本例中够用了,再复杂一点的情况可以考虑使用 sed,多行、正则替换都能够完成。

最后一句就简单了,如果对一个文件执行两次iconv,第一次把gb2312转成了utf8,可第二次就不知道转换成哪国编码了,所以为了避免程序被误运行两次,去掉可执行属性。

以后用起来就简单了,如果情感进销存再发布新版,先解压到一个临时文件夹,用这个脚本进行转换之后,再覆盖拷贝过来就可以了。

Source: http://www.fwolf.com/blog/post/363

2007年10月26日星期五

磁带机的简单使用

环境:Ubuntu 7.04 feisty, HP DAT-72 usb外置磁带机。

基本概念

  • 磁带是线性存储设备,没有什么分区表的概念,磁头在哪里,就从哪里开始读。
  • 磁带机好像只能用root用户操作。
  • 磁带上可以划分存储空间,每个存储空间有一个file number,从0开始顺序排列。
  • 磁头在存储空间中的位置用block number来表示,0代表开始,大于0的整数代表块,比如39代表磁头在本file number的第39块的位置,而-1则代表磁头位于本file number的结尾。
  • 同样一部磁带机,用/dev/st0时是当自动回卷设备使用,每次操作完成之后,磁头都返回file number=0, block number=0, BOT的位置;而用/dev/nst0调用时,操作完成时磁头就停在那个位置,不会回到开头。
  • 使用nst非回卷方式,用tar tvf列文件,只有当block number=0时才能出内容,并且列完之后block number为大于0的整数,注意这并不代表本段存储空间的结尾(-1)。

由于磁带机本身具有压缩功能,所以添加文件的时候不建议指定zip或者bz2压缩,因为如果一点点压缩后的数据损坏,会导致全部内容不可识别;如果的确需要压缩的话,可以压缩成本地文件再存储到磁带上,减少对其他文件的影响。

自动回卷的使用方式

这种方式比较简单,用tar直接操作即可,基本上和tar操作本地文件相同。

往新磁带上存储文件,注意如果磁带上已有文件,会被覆盖掉:

tar cvf /dev/st0 file_to_store

向磁带上添加文件:

tar rvf /dev/st0 file_to_store

更新磁带上的同名文件:

tar uvf /dev/st0 file_to_store

列出磁带上的现有文件:

tar tvf /dev/st0

删除磁带上的文件:

tar vf /dev/st0 --delete file_to_delete

但我使用这个命令的时候总是提示错误,文件倒是删掉了,可查看的时候也总有错误信息,难道是无法删除,或者只能全部xvf出来再存到磁带上?不过我们也应当养成一个好的习惯,每次向磁带机存储文件的时候一定要在文件名中带上日期标记。

非自动回卷的使用方式

一般这样使用,都是用到多个存储空间file number的时候;如果还是一个存储段,只是手工移动文件指针就没有什么意义了。

在操作上,文件的存储方式和自动回卷是基本相同的,不同之处在于要注意磁头的位置,并且手工进行必要的位移,以一个新磁带的操作为例来说明(status我只截取有用的部分显示):

# mt -f /dev/nst0 status
file number = 0
block number = 0
General status bits on (41010000):
BOT ONLINE IM_REP_EN

存入一个新的文件A:

# tar cvf /dev/nst0 A
A
# mt -f /dev/nst0 status
file number = 1
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

注意这时磁头已经移动到了第二段存储空间了,现在再存入一个新的文件B,当然B和A是不在一个存储空间中的:

# tar cvf /dev/nst0 B
B
# mt -f /dev/nst0 status
file number = 2
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

磁头又移动到第三段存储空间了,如果要查看刚才存的第二段存储空间中的内容,需要先移动磁头:

# mt -f /dev/nst0 bsf 2
# mt -f /dev/nst0 status
file number = 0
block number = -1
General status bits on (1010000):
ONLINE IM_REP_EN

# mt -f /dev/nst0 fsf 1
# mt -f /dev/nst0 status
file number = 1
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

由于有存储空间结束标记,所以这里采用退2进1的方式,详细的磁头移动方式可以看man mt。然后查看文件列表:

# tar tvf /dev/nst0
-rw-r--r-- root/root 21194792 2007-10-24 11:37 B
# mt -f /dev/nst0 status
file number = 1
block number = 2070
General status bits on (1010000):
ONLINE IM_REP_EN

列出文件列表之后,磁头停在了文件结束的位置,但不是存储空间的结尾。现在移动磁头到本段存储空间的开始,并且添加文件C:

# mt -f /dev/nst0 bsf 1
# mt -f /dev/nst0 status
file number = 0
block number = -1
General status bits on (1010000):
ONLINE IM_REP_EN

# mt -f /dev/nst0 fsf 1
# mt -f /dev/nst0 status
file number = 1
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

# tar rvf /dev/nst0 C
C
# mt -f /dev/nst0 status
file number = 2
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

首先还是要移动磁头,到这里基本上可以发现mt的fsf和bsf的规律了,fsf是磁头向前移动,并且总是停留在block number = 0的位置,而bsf是磁头向后移动,总是停留在 block number = -1的位置。添加完成文件之后,磁头又定位到了第三个存储空间(下一个)的开始。现在我们依然是移动磁头到第二段存储空间开始,并且用覆盖方式添加文件D:

# mt -f /dev/nst0 bsf 2
# mt -f /dev/nst0 fsf 1
# mt -f /dev/nst0 status
file number = 1
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

# tar cvf /dev/nst0 D
D
# mt -f /dev/nst0 status
file number = 2
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

文件D是用覆盖方式添加的,所以刚才添加的文件B和C现在应该都消失了:

# mt -f /dev/nst0 bsf 2
# mt -f /dev/nst0 fsf 1
# mt -f /dev/nst0 status
file number = 1
block number = 0
General status bits on (81010000):
EOF ONLINE IM_REP_EN

# tar tvf /dev/nst0
-rw-r--r-- root/root 34201298 2007-10-24 11:57 D
# mt -f /dev/nst0 status
file number = 1
block number = 3341
General status bits on (1010000):
ONLINE IM_REP_EN

完成,回卷磁带,从开始一直tvf:

# mt -f /dev/nst0 rewind
# tar tvf /dev/nst0
-rw-r--r-- root/root 341054 2007-10-24 11:37 A

# tar tvf /dev/nst0
# tar tvf /dev/nst0
-rw-r--r-- root/root 34201298 2007-10-24 11:57 D

# tar tvf /dev/nst0
# tar tvf /dev/nst0

# tar tvf /dev/nst0
tar: /dev/nst0: Cannot read: Input/output error
tar: At beginning of tape, quitting now
tar: Error is not recoverable: exiting now

# mt -f /dev/nst0 status
file number = 2
block number = -1
General status bits on (9010000):
EOD ONLINE IM_REP_EN

现在,能看懂这个了么?我用空行隔开的位置正好是block number为0的位置。还有一些其他的操作就比较简单了:

出带,将磁带卷至初始位置然后从磁带机内弹出
# mt –f /dev/nst0 offline

清除磁带中的所有内容,特慢,还伤带,轻易不要用
# mt –f /dev/nst0 erase

我的几个疑问

  • 如何删除file number?
  • 既然磁带是线性存储,如果向前面一个file number中添加中间,存储空间不够怎么办?
  • 如何查看磁带剩余空间?

小结

搞明白磁带机的存储方式和基本操作,用起来就简单了。个人感觉如果要存的文件数量不多,尤其是只需要存几个大文件的情况,直接用自动回卷方式,只使用一个存储空间就可以了,这样操作比较简单。如果一定要用磁带存储复杂结构的数据,可以考虑手工在各个存储空间之间来回切换的方式,原理都是一样,只是更高一点点的技巧和小心。

参考

Source: http://www.fwolf.com/blog/post/362

转换AVCHD的m2ts文件到avi

Sony的硬盘录像机是好东西,高清晰、宽屏幕录像,大容量存储,可录的时候爽了,后期浏览和加工转换实在是不方便(这位仁兄也有同样感受: Jeff Cai的流水账 - Play with AVCHD,机型都是Sony HDR-SR1),无论想在哪台电脑上浏览录像,都要装一个Sony Handycam Application Software软件(安装盘仅400M),这个软件也相当霸道,不让选择安装位置、安装哪些组件,甚至不允许单独安装其中的某一个程序,安装完成后居然还提示要重启xp,当然不重启我试了也能使用。注册媒体库位置的时候不让选择网上邻居资源或者映射的网络驱动器。

如果这些都不是问题的话,录像文件拷出来能用其他工具浏览或加工也行啊,可偏偏他的录像格式m2ts(扩展名MTS)目前支持的工具还相当少,不过还是在网上找到了一些文章,能够用开源工具进行转换。Sony自带软件也能转换成通用格式,不过我的印象是会损失一些清晰度,用肉眼就能轻易的分辨出来的差异。参考文章:

基本思路都是这样的:

  • 用xporthdmv把m2ts转换为mpv和mpa格式
  • 用ldecod把mpv转换为yuv格式
  • 用yuv4mpeg把yuv转换为y4m格式
  • mpa直接当ac3格式的音频使用
  • 用ffmpeg合成视频和音频部分为avi格式(avi就是一个容器)

讨论中还有一些其他的提示:

  • ffmpeg可以用mencoder替代
  • ldecod生成的yuv文件大小可以达到4G/分钟,不过可以用命名管道(named pipe)来省去使用中间文件
  • 视频和音频的同步,pal格式录像可以设定fps为25,ntsc格式录像可以使用参数-r 29.97。

参考文章中的第一篇给了一个附件,这个很好用,下载下来解包,里面的readme.txt和Makefile解释了使用方法,不过在ubuntu下使用的话,建议先作以下几步准备工作:

  • 安装svn客户端
  • 用apt安装x264-bin和ffmpeg以及mplayer
  • 在'src/JM/ldecod'目录下创建一个空的子目录'obj'
  • 脚本运行之后会自动转换samplevideo.avi,会用去一些时间,想省略的话把这个文件删除或改名即可
  • download文件中有一句set version=12.2,现在的jm版本已经是12.4了,更新之,不然下载不到(404错误)

然后就简单了:

  • ./download
  • ./compile
  • ./install

或者再用installasroot安装,你就可以使用m2tstoavi了:

$ m2tstoavi
usage: /usr/local/bin/m2tstoavi filename.m2ts ...

我也转了一个自己录的文件,完成后发现视频、音频不同步,并且播放速度很慢,可能是一些设置参数的问题,转换方式肯定是没有问题的,并且好像是目前最好的方式了。(修改/usr/local/bin/m2tstoavi,注意上面说的pal和ntsc制式的区别)mplayer播放最终生成的avi文件,信息如下:

Playing samplevideo.avi.
AVI file format detected.
VIDEO: [h264] 1440x1080 24bpp 29.970 fps 13323.1 kbps (1626.4 kbyte/s)
Clip info:
Software: MEncoder 2:1.0~rc1-0ubuntu9.1
open: No such file or directory
[MGA] Couldn't open: /dev/mga_vid
open: No such file or directory
[MGA] Couldn't open: /dev/mga_vid
[VO_TDFXFB] Can't open /dev/fb0: No such file or directory.
[VO_3DFX] Unable to open /dev/3dfx.
It seems there is no Xvideo support for your video card available.
Run 'xvinfo' to verify its Xv support and read DOCS/HTML/en/video.html#xv!
See 'mplayer -vo help' for other (non-xv) video out drivers. Try -vo x11
Opening video filter: [screenshot]
==========================================================================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
Selected video codec: [ffh264] vfm: ffmpeg (FFmpeg H.264)
==========================================================================
==========================================================================
Forced audio codec: mad
Opening audio decoder: [liba52] AC3 decoding with liba52
Using SSE optimized IMDCT transform
Using MMX optimized resampler
AUDIO: 48000 Hz, 2 ch, s16le, 448.0 kbit/29.17% (ratio: 56000->192000)
Selected audio codec: [a52] afm: liba52 (AC3-liba52)
==========================================================================
AO: [alsa] 48000Hz 2ch s16le (2 bytes per sample)
Starting playback...
VDec: vo config request - 1440 x 1080 (preferred colorspace: Planar YV12)
VDec: using Planar YV12 as output csp (no 0)
Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.
SwScaler: reducing / aligning filtersize 5 -> 4
SwScaler: reducing / aligning filtersize 5 -> 4
SwScaler: reducing / aligning filtersize 1 -> 1
SwScaler: reducing / aligning filtersize 5 -> 4

SwScaler: BICUBIC scaler, from yuv420p to bgr24 using MMX2
SwScaler: using 4-tap MMX scaler for horizontal luminance scaling
SwScaler: using 4-tap MMX scaler for horizontal chrominance scaling
SwScaler: using n-tap MMX scaler for vertical scaling (BGR)
SwScaler: using MMX2 YV12->BGR24 Converter
SwScaler: 1440x1080 -> 1920x1080
VO: [x11] 1440x1080 => 1920x1080 Planar YV12
A:4358.2 V: 2.9 A-V:4355.240 ct: 0.297 89/ 89 148% 0% 1.1% 37 0

有时间了再仔细研究视频、音频不同步和播放速度很慢的问题。不过还是那句话,技术都是好东西,可对商业利益的无止境追求使他们变成了恶魔。

软件环境:Ubuntu 7.04 Feisty

Source: http://www.fwolf.com/blog/post/361

2007年10月22日星期一

通过代理更新Gregarius

Gregarius是我现在使用的rss阅读器,其它在线的比如google reader、zhuaxia我网速太慢,使用不顺畅,纯离线方式的吧,比如liferea,在浏览的时候依然要解析html和联网(feed内容中有图像),还是在本机架一个Gregarius,cron定时更新,然后用firefox看方便,保存有价值的文章也更方便。

原先更新都是用wget:

wget --no-check-certificate -O /tmp/gregarius.update https://my_local_machine_name/gregarius/update.php  

wget的输出会已本地用户邮件形式被mutt收下来,设定好之后,有一段没时间看rss也没在意,这天忽然发现原来wget只要retry 3、4次就能更新完全部feed,现在需要十几次,而我的feed增长显然没达到这种程度;并且有些网站在Gregarius中看到已经很久没有更新了(-t 1可以指定只retry一次,默认是20次,-t 0为无限制retry下去)。同时在feed管理中看到,很多网站的名字都加上了删除线,比如" 月光博客",最后终于发现,这些名字打上了删除线的blog的feed全部托管在feedburner,并且内容全部没有更新,原因,自然是开始于前段时间的feedburner无法访问。

feedburner无法访问我倒不怕,我一直都在本机用squid、privoxy、tor智能中转web访问请求,现在只要让gregarius更新feed时用上我这个本地的代理服务器squid就可以了,看了一下gregarius的代码,远程读取rss使用的是 Snoopy类,本地文件为extlib/Snoopy.class.inc,调用是在extlib/rss_fetch.inc文件中,大概第317行,function _fetch_remote_file 部分,在这里添加如下内容即可:

$client->read_timeout = MAGPIE_FETCH_TIME_OUT;
$client->use_gzip = MAGPIE_USE_GZIP;

// 这几行是添加的内容,其它是原文件中的 Modify by Fwolf @ 2007-10-14
// Use proxy localhost:3128 when fetch feed
$client->proxy_host = "localhost";
$client->proxy_port = "3128";
$client->_isproxy = true;
$client->read_timeout = 0; // tor via squid is slow
//

if (is_array($headers) ) {
$client->rawheaders = $headers;
}

就这么简单,$client的设置参照Snoopy类的定义即可,然后调用不再使用wget,而是直接运行update.php:

cd /local/path/to/gregarius; php -f update.php

这样更新的结果会清晰的输出:

Engadget Simplified Chinese ...
OK (HTTP 200), 3 New Items

玩意儿 ...
OK (304 Not modified), 0 New Items

津津乐道 ...
HTTP Timeout (Local cache), 0 New Items

小众软件 ...
OK (HTTP 200), 0 New Items

如果加上-- --silent就没有输出了,第一个--是给截止php接收参数的参数,--silent才是给update.php用的。

本文针对Gregarius 0.5.5 revision1761。

Source: http://www.fwolf.com/blog/post/360

2007年10月14日星期日

Feisty下的alsa怎么不响了?

我的Ubuntu feisty是从dapper直接升级过来的,现在好像还记得刚升级完之后,用mplayer放电影没声音,声音驱动换oss就没事了,也没太在意。后来开始用mame玩模拟器游戏 ,一直没有声音,就以为是mame或者rom的问题。再后来发现mame有关于声音的设置,而别人的介绍里面说的mame没有声音的问题不是好几年之前的,就是一些rom中本来就不包含声音的情况。从这里开始察觉,是我机器的问题,具体说就是alsa声音驱动不响了。

硬件不会有问题,驱动换oss马上放电影就出声,所以问题在软件上,到网上一查,alsa没有声音的情况还不少,但好像都不顶用。

最后翻到了ubuntu Edgy升级到Feisty后系统没有声音,问题解决,我和他的情况相同,果然是$HOME/.asoundrc文件的问题。

升级到Feisty之后,在$HOME下有两个文件,.asoundrc.asoundconf和.asoundrc,.asoundrc的有效内容只有一行:

 

就是引用.asoundrc.asoundconf的内容,相当于一个Include语句,而.asoundrc.asoundconf的内容有4行:

!defaults.pcm.card I82801BAICH2
defaults.ctl.card I82801BAICH2
defaults.pcm.device 0
defaults.pcm.subdevice -1

这个是系统默认的配置,此文件系统也不建议直接修改,只要注释/取消注释.asoundrc文件中的那一句就可以了。不用重启机器,甚至也不用重启X,只要注释掉.asoundrc中那一句,alsa立刻就好了,mame里也有声音了,mplayer里选择alsa声音驱动也有声音了;而只要取消注释,mame和mplayer里就没有声音了,所以确定就是这里的问题。

看了一下.asoundrc.asoundconf配置文件选项的官方解释,感觉那4句哪一句都挺正确的,可就是只起反作用。

所以,下次alsa不响的时候,记得先看看这两个配置文件。

Source: http://www.fwolf.com/blog/post/359

单网卡双ip连接nfs服务器,好像不行

环境:防火墙作为网关,下设两个网段,A网段为192.168.0.0/24,防火墙上的网关地址为192.168.0.1,有一服务器地址为192.168.0.2;B网段为192.168.2.0/24,防火墙上的网关地址为192.168.2.1,有一客户机地址为192.168.2.5,只有一块网卡,需要增设一个ip,连接A网段服务器上的nfs服务。服务器和客户机操作系统均为ubuntu 7.04。

nfs服务器比较好架,apt安装nfs-kernel-server及相关包即可,默认服务端口2049不动,配置文件/etc/exports的内容为:

/home/fwolf     192.168.0.5(rw,sync,subtree_check)
/home/share *(ro,subtree_check)

不要装成了nfs-user-server,那个是nfs v2,不是nfs v3,不支持4G以上的文件。限制了/home/fwolf只有主机192.168.0.5才能访问。客户端可以收工mountnfs服务器:

sudo mount -t nfs svrname:/home/fwolf local_mount_point

也可以写到fstab中:

svrname:/home/fwolf        local_mount_point nfs     defaults 0 0

如果现在用B网段的客户机访问A网段的服务器,因为路由走的是防火墙(防火墙的配置好像也有点问题,不过改不了,不行的根源可能就在于此),防火墙上看到客户机的地址是防火墙上配置的另外一个C网段地址,所以要给客户机增加一个A网段的ip,不通过防火墙直接访问。

单网卡增加双ip要用到别名,所以/etc/network/interfaces文件的内容如下:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
address 192.168.2.5 netmask 255.255.255.0 auto eth0:0 iface eth0:0 inet static address 192.168.0.5 netmask 255.255.255.0

两个地址都不设置gateway,然后在rc.local中添加静态路由设置:

route add -net  192.168.0.0/24  gw   192.168.0.1     dev eth0:0
route add default gw 192.168.2.1 dev eth0

然后重启网络并执行rc.local:

sudo /etc/init.d/networking restart; sudo /etc/rc.local

现在,看一下路由表:

$ route
Kernel IP routeing table
Destination Gateway Genmask Flags Metric Ref Use Iface
192.168.0.0 192.168.0.1 255.255.255.0 UG 0 0 0 eth0
192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
192.168.2.0 * 255.255.255.0 U 0 0 0 eth0
default 192.168.2.1 0.0.0.0 UG 0 0 0 eth0

按照设想,如果从客户机上访问A网段,那么应该对应路由表的第一行,使用网关192.168.0.1,服务器上看到的地址自然就是192.168.0.5,如果访问其他网段,应该走默认网关192.168.2.1,对应本机ip地址192.168.2.5。但是,我的实践证明并不是这样,甚至在rc.local加上了下面几句中任何一句或者全部也不行:

route add -net 192.168.0.0/24 dev eth0:0
route add -host 192.168.0.2 dev eth0:0
route add -host 192.168.0.2 gw 192.168.0.1 dev eth0:0

偶尔的时候,能够成功,但是感觉不稳定,所以算是失败了,感觉有3种可能:

  • 防火墙工作方式问题,这个自然没法改动了
  • 路由命令添加得不对,我觉得应该没错误吧
  • 此路根本不通,单网卡不能设多ip,只能用多网卡,我觉得这个不太可能

暂时的,只能放宽nfs地址限制,或者用速度较慢(尤其在局域网内)的sshfs来实现了。

参考

Source: http://www.fwolf.com/blog/post/358

2007年10月8日星期一

在Ubuntu上安装sybase ASE 15.0.2


开始之前

先把ubuntu装上,用7.04的server安装盘默认安装即可,先装i386的,如果sybase安装顺利,再试试64位的sybase是否好用。

从sybase网站上注册免费用户之后,可以下载免费的ASE Express Edition 下载页面),目前的版本是15.0.2,限制只能使用1个cpu,2G内存和管理5G数据,更详细的资料在快速安装手册中。

如果您也想自己装一个试试,建议您先跳过下面这一段。

安装

下载后的ase1502_xe_linux.tgz,直接解压到一个目录,比如ase1502中,然后运行./setup就可以开始安装了。默认的安装是java图形界面的,而我是远程ssh上去装的,所以加上-console参数运行setup。首先是欢迎信息:

Welcome to the InstallShield Wizard for Sybase Adaptive Server Enterprise Suite
version 15.0.2 GA

The InstallShield Wizard will install Sybase Adaptive Server Enterprise Suite
on your computer. Shut down all Sybase products, then click Next to begin
installation.

Press 1 for Next, 3 to Cancel or 4 to Redisplay [1]

按1继续,接着是选择用户协议类型:

What would you like to install?

Product License

1. Adaptive Server Enterprise for evaluation
2. Adaptive Server Enterprise (Developer Edition)
3. Adaptive Server Enterprise (Express Edition)

Enter one of the options above : [1] 3

1是体验版,应该是有时间限制,2是开发者版,有连接数限制,所以选3继续:

 1)  All regions
Please enter the number of the location you are installing. (1-1) [1]

选择自己所在的地区,只有1可选,应该没什么用处。但如果你仔细看了用户协议,会看到被美国实行贸易禁运的国家比如伊朗、伊拉克等等是禁止下载使用的。选择后会出现完整的用户协议,可以按回车一屏一屏的读完,或者用q退出,然后记得按y同意此用户协议,

Please enter the directory where you would like to install the products or
press ENTER to accept the default.

Destination Directory [/opt/sybase]

选择安装目录,我觉得用默认的就可以,如果目录不存在,还得确认创建新目录;如果目录已经存在,也会让你确认,不过是确认删除其中的所有文件:

      1. Yes
2. No

The directory does not exist. Do you want to create it? [2] 1

然后就是选择安装哪些内容了:

Choose the setup type that best suits your needs.

[X] 1 - Typical
The program will be installed with the suggested configuration.
Recommended for most users.

[ ] 2 - Full
The program will be installed with all the products and features.

[ ] 3 - Custom
The program will be installed with the features you choose.
Recommended for advanced users.

To select an item enter its number, or 0 when you are finished: [0]

如果没有特殊要求,Typical就够用了,如果想自行选择安装内容,可以选3 - Custom:

Select the features for "Sybase Adaptive Server Enterprise Suite" you would
like to install:

Sybase Adaptive Server Enterprise Suite

To select/deselect a feature or to view its children, type its number:

1. +[x] Sybase Servers
2. +[x] Connectivity
3. +[x] ASE Data Providers
4. +[x] Language Modules
5. +[x] jConnect for JDBC
6. [ ] Shared
7. +[x] Sybase Software Asset Management
8. +[x] Sybase Unified Agent
9. +[x] ASE Administration Tools

Other options:

0. Continue installing

Enter command [0]

默认就是除了6 Shared,其他的都安装。最后,安装程序会把所有选项列出来供检查:

Sybase Adaptive Server Enterprise Suite will be installed in the following
location:

/opt/sybase

with the following features:

Sybase Servers
Adaptive Server Enterprise
ASE Agent Plugin
Replicator
Connectivity
Open Client
Common ctlib files
Common dblib files
Common Connectivity Components
ASE Data Providers
ASE ODBC Driver
Unicode/MultiByte Conversion Support
Sample Programs
Language Modules
English Language Module
jConnect for JDBC
JDBC Driver
Sybase Software Asset Management
SySAM License Utilities
Sybase Unified Agent
Unified Agent Server
Agent Management Console
ASE Administration Tools
Interactive SQL
Sybase Central
Adaptive Server Plugin
SySAM Plugin

for a total size:

410.8 MB

Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

然后终于开始安装了,进度条作得蛮可爱的:

Installing Sybase Adaptive Server Enterprise Suite. Please wait...

|-----------|-----------|-----------|------------|
0% 25% 50% 75% 100%
||||||||||||||||||||||||||||||||||||||||||||||||||

Creating uninstaller...

-------------------------------------------------------------------------------
The InstallShield Wizard has successfully installed Sybase Adaptive Server
Enterprise Suite. Choose Next to continue the wizard.

Press 1 for Next, 3 to Cancel or 4 to Redisplay [1]

接下来是配置向导,首先是email alert,用于接收数字资产变化的更新通知,显然对个人用户来讲没什么用处:

Please configure the Sybase Software Asset Management (SySAM) email alert
mechanism. When configured, specified recipients will receive email
notifications about SySAM events that may need administrator attention.

Do you want to configure email alerts?

1. Yes
2. No

Enter one of the options above : [1]
SMTP server host name [smtp] smtp.gmail.com SMTP server port number [25] 465 Sender email [root] sybase@svr6 Recipient emails [root] svr6@gmail.com Message Severity for email alerts(信息发送级别,达到级别的才会发送邮件,1为最低/敏感的级别,3为最高/不敏感的级别)

1. INFORMATIONAL
2. WARNING
3. ERROR

Enter one of the options above : [2]

确认后就进入创建服务器的向导了,天知道上面的邮件设置能否正常发信:

The Adaptive Server Enterprise suite contains a number of programs in addition
to the Adaptive Server Enterprise database server. At this point in the
installation you can choose to configure various products. If you select the
options on this screen, you will be given the option of specifying
configuration options for each product or to allow the installer to set default
values for these on the next screen. If you do not choose to configure the
products at this time, you can configure them using the ASE configuration
utility at a later time.

Please deselect any products that you do not want to configure now :

[X] 1 - Configure new Adaptive Server
[X] 2 - Configure new Backup Server
[X] 3 - Configure new Monitor Server
[X] 4 - Configure new XP Server
[X] 5 - Configure Unified Agent

To select an item enter its number, or 0 when you are finished: [0]

直接确认,安装全部服务器:

You have chosen to configure the products listed below. You can accept default
configuration values or provide customized values for the configuration options
required by each product. If you do not select custom configuration below, this
installer will configure the products you have selected with default values. If
you accept default values at this time you can change the configuration values
for a product at a later time.

Please select the products that you want to custom configure.

[ ] 1 - Custom configure new Adaptive Server
[ ] 2 - Custom configure new Backup Server
[ ] 3 - Custom configure new Monitor Server
[ ] 4 - Custom configure new XP Server
[ ] 5 - Custom configure Unified Agent

To select an item enter its number, or 0 when you are finished: [0]

看上去和刚才的选择类似,不过这里是选择哪些服务器要用自定义设置,否则就采用默认设置快速创建了。我全部采用自定义设置([]里是默认设置,什么不输入就使用这个值了):

Please enter custom configuration values for the new Adaptive Server

Adaptive Server Name [SVR6]
Port Number [5000]
Error Log [/opt/sybase/ASE-15_0/install/SVR6.log] /home/sybase/svr6.log
Page Size

1. 2k
2. 4k
3. 8k
4. 16k

Select a page size : [1]
Master Device [/opt/sybase/data/master.dat] /home/sybase/master.dat
Master Device Size (MB) [30] 60
Master Database Size (MB) [13] 30
System Procedure Device [/opt/sybase/data/sysprocs.dat] /home/sybase/sysprocs.dat
System Procedure Device Size (MB) [132] 150 (系统存储过程库比以前的11.9.2版本大了很多)
System Procedure Database Size (MB) [132] 150
System Device [/opt/sybase/data/sybsysdb.dat] /home/sybase/sybsysdb.dat
System Device Size (MB) [1] 20
System Database Size (MB) [1] 10

Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

然后是backup server的设置:

Please enter custom configuration values for the new Backup Server

Backup Server Name [SVR6_BS]
Port Number [5001]
Error Log [/opt/sybase/ASE-15_0/install/SVR6_BS.log] /home/sybase/svr6_bs.log

Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

Monitor Server:

Please enter custom configuration values for the new Monitor Server

Monitor Server Name [SVR6_MS]
Port Number [5002]
Error Log [/opt/sybase/ASE-15_0/install/SVR6_MS.log] /home/sybase/svr6_ms.log

Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

XP Server:

Please enter custom configuration values for the new XP Server

Port Number [5003]
Error Log [/opt/sybase/ASE-15_0/install/SVR6_XP.log] /home/sybase/svr6_xp.log

Press 1 for Next, 2 for Previous, 3 to Cancel or 4 to Redisplay [1]

然后是选择发现sybase服务的方法(这样客户端就不需要interface文件了),JINI需要架设单独的服务器,个人测试用UDP方式就够了,不过只能发现同一子网中的服务:

Discovery Services provide client applications the ability to find Sybase
resources within an enterprise environment without the need for local interface
file definitions. UA currently supports two discovery methods: JINI and UDP.

JINI requires a dedicated JINI server to provide discovery services and can
provide these services throughout the enterprise. UDP does not require a
dedicated server but is limited to discovery within the local subnet.

Adaptor

1. JINI
2. UDP

Select the adaptor for the Self Discovery Service. [2]

然后是选择用户统一认证方式,我觉得没有特殊理由,就用默认的好了,和11.9.2的使用习惯应该是相同的:

Please select and order the security login modules for the Unified Agent.

Simple Login: authenticates user ID/password against entries within a UA
configuration file.

ASE Login Module: delegates authenticationto an appropriate role ( e.g.,
sa_role, sso_role, etc.) within the ASE.

NT/Unix Proxy login Module: delegates authentication to a user group in the
underlying operating system (e.g., Administrators, root, etc.).

1. Simple Login Module true
2. ASE Login Module true
3. Unix Proxy Login Module false

Select a login module to modify. Enter "0" when you are done: [0]

最后,依然是把所有设置print出来检查,其中Unified Agent部分的有些内容应该以后会用到:

   Unified Agent - Security Login Modules

CSI.loginModule.1.provider com.sybase.ua.services.security.simple.SimpleLoginModule
CSI.loginModule.1.controlFlag sufficient
CSI.loginModule.1.options.moduleName Simple Login Module
CSI.loginModule.1.options.username uafadmin
CSI.loginModule.1.options.password ******
CSI.loginModule.1.options.roles uaAgentAdmin,uaPluginAdmin
CSI.loginModule.1.options.encrypted false

CSI.loginModule.2.provider com.sybase.ua.services.security.ase.ASELoginModule
CSI.loginModule.2.controlFlag sufficient
CSI.loginModule.2.options.moduleName ASE Login Module

终于又开始创建服务器了,不幸又遇到了错误:

Building Adaptive Server 'SVR6':
Writing entry into directory services...
Directory services entry complete.
Building master device...
Task failed
Server 'SVR6' was not created.
/opt/sybase/ASE-15_0/bin/dataserver: error while loading shared libraries:
libstdc++.so.5: cannot open shared object file: No such file or directory

其它服务器创建倒是很正常,除了连不上主服务器:

Building Backup Server 'SVR6_BS':
Writing entry into directory services...
Directory services entry complete.
Writing RUN_SVR6_BS file...
RUN_SVR6_BS file complete.
Starting server...
Server started.
Server 'SVR6_BS' was successfully created.

Building Monitor Server 'SVR6_MS':
Writing entry into directory services...
Directory services entry complete.
Writing RUN_SVR6_MS file...
RUN_SVR6_MS file complete.
Unable to log in to Adaptive Server 'SVR6'.
Unable to boot 'SVR6_MS' because Monitor Server must be able to log in to
Adaptive Server.
Server 'SVR6_MS' was not created.

Building XP Server 'SVR6_XP':
Writing entry into directory services...
Directory services entry complete.
Server 'SVR6_XP' was successfully created.
'SVR6_XP' will be started when needed by the Adaptive Server.

主服务器可能是缺少库文件,安装上libstdc++5包(会自动安装gcc-3.3-base包),用sybase用户进入,设定好环境变量,在.bashrc里添加上两行:

. ~/SYBASE.sh
. ~/ASE150.sh

再用rs文件创建服务器(记得先关掉已经启动的backup服务器,删掉/opt/sybase目录)。但,依然是错误:

   Building Adaptive Server 'SVR6':
Writing entry into directory services...
Directory services entry complete.
Building master device...
Task failed
dataserver: master device size for this server: 60.0 Mb
Server 'SVR6' was not created.
dataserver: master database size for this server: 13.0 Mb
dataserver: model database size for this server: 3.0 Mb

log的最后部分是:

   00:00000:00000:2007/09/17 02:31:14.28 kernel Encryption provider
initialization succeeded on engine 0.
00:00000:00000:2007/09/17 02:31:14.28 kernel engine 0, os pid 28397 online
Segmentation fault

上网查资料,又加上了LD_POINTER_GUARD=0参数(这个是0或者1得来回试试,看哪个行),终于行了:

Building Adaptive Server 'SVR6':
Writing entry into directory services...
Directory services entry complete.
Building master device...
Master device complete.
Writing RUN_SVR6 file...
RUN_SVR6 file complete.
Starting server...
Server started.
Building sysprocs device and sybsystemprocs database...
sysprocs device and sybsystemprocs database created.
Running installmaster script to install system stored procedures...
installmaster: 10% complete.
installmaster: 20% complete.
installmaster: 30% complete.
installmaster: 40% complete.
installmaster: 50% complete.
installmaster: 60% complete.
installmaster: 70% complete.
installmaster: 80% complete.
installmaster: 90% complete.
installmaster: 100% complete.
installmaster script complete.
Creating two-phase commit database...
Two phase commit database complete.
Installing common character sets (Code Page 437, Code Page 850, ISO Latin-1,
Macintosh and HP Roman-8)...
Character sets installed.
Setting server name in Adaptive Server...
Server name added.
Server 'SVR6' was successfully created.

安装小结

Sybase对服务器环境比较挑剔,我的服务器操作系统是Ubuntu 7.04:

  • 首先libaio是需要的,apt安装即可,表现为libaio-devlibaio1两个包。
  • 设置shmmax,在/etc/sysctl.conf中加入kernel.shmmax=2147483648(2G共享内存),重启,或者直接echo 2147483648 > /proc/sys/kernel/shmmax,或者用sysctl -p直接加载。查询目前的共享内存设置用sysctl kernel.shmmax ,单位为字节,sybase应该是需要至少64M,建议根据机器配置情况,设置为总内存的一半,或者256M以上。
  • 安装上libstdc++5包,会自动安装gcc-3.3-base包。
  • 手工创建sybase用户,把/home/sybase的权限设给它,并设置$HOME/opt/sybase,当然,这一步也可以在安装完sybase、创建服务器之前作。
  • 在sybase用户的bashrc中添加LD_POINTER_GUARD=0(注:我把sybase的默认shell从sh改成bash了,好像RHEL中需要指定这个环境变量为1),在bashrc增加两个sh脚本的调用(. ~/SYBASE.sh. ~/ASE150.sh)。
  • 文档中建议使用sybase用户来进行安装,不过我是用root用户安装的,好像也没有遇到太多问题,安装完成后把/opt/sybase整体chown一下。

服务器设置

更改sa密码

格式为sp_password oldpassword,newpassword,比如:

>sp_password null,"new_password"
>go

服务器的字符集

默认字符集是"iso_1 (ISO 8859-1), a binary sort order, and English as the default language.",我们一般使用的字符集是cp936或者utf8,下面就把服务器字符集调整为utf8。

没有用sp_configure来配置服务器字符集,而是采用sqlloc.rs方式,rs文件内容如下:

sybinit.release_directory: /opt/sybase
sqlsrv.server_name: SVR6
sqlsrv.sa_login: sa
sqlsrv.sa_password:
sqlsrv.default_language: us_english
sqlsrv.language_install_list: USE_DEFAULT
sqlsrv.language_remove_list: USE_DEFAULT
sqlsrv.default_characterset: utf8
sqlsrv.characterset_install_list: USE_DEFAULT
sqlsrv.characterset_remove_list: USE_DEFAULT
sqlsrv.sort_order: binary

运行之:

sybase@svr6:~$ sqllocres -r sqlloc.rs
Installing sort order 'Binary ordering, for the ISO 10646-1, UTF-8 multibyte
encodin...' in the Adaptive Server...
Sort Order 'Binary ordering, for the ISO 10646-1, UTF-8 multibyte encodin...'
was successfully installed in the Adaptive Server.
Making 'UTF-8' the Adaptive Server's default character set...
Making 'Binary ordering, for the ISO 10646-1, UTF-8 multibyte encodin...' the
Adaptive Server's default sort order...
The Adaptive Server's default character set is now 'UTF-8'.
The Adaptive Server's default sort order is now 'Binary ordering, for the ISO
10646-1, UTF-8 multibyte encodin...'.
Done

在isql中检查转换结果:

1> sp_helpsort
2> go
...
Character Set = 190, utf8
Unicode 3.1 UTF-8 Character Set
Class 2 Character Set
Sort Order = 50, bin_utf8
Binary sort order for the ISO 10646-1, UTF-8 multibyte encodin
g character set (utf8).
(return status = 0)
1> select @@client_csname
2> go

------------------------------
utf8

(1 row affected)

简单试了一下,客户端是cp936字符集的时候,服务器能够正常的转换编码。

还有一个问题需要在数据转移时考虑,原来的服务器字符集是cp936,在转移数据的时候应该会遇到字段长度不够的情况,需要把字段长度增加为现在的3/2倍。

Adaptive Server Enterprise 15.0 - Datatypes

客户端的字符集设置需要修改$SYBASE/locales/locales.dat,在指定的操作系统如[win32]段,添加:

locale = default, us_english, cp936

就可以了,在数据传输过程中sybase会自动进行cp936和utf8之间的转换。一点小问题:我在linux下用sqsh连接服务器,不管-J参数怎么设置,select @@client_csname都是NULL,不过中文好像也能够正常使用(linux为Ubuntu,字符集为en_US.utf8)

其它关于字符集的参考资料:

自定义cfg文件

内存
max memory = 1048576

2k的页大小,设置2G的内存,XE版中设置超过这个值的话,反而会被ASE拒绝,使用默认值49152。

cpu
max online engines = 1

其实这一项使用DEFAULT即可,因为XE的限制,设置多了也不会起作用。

其他参数
number of user connections = 300
number of locks = 10000 (ASE 15默认值就是这个)
lock scheme = datarows
identity burning set factor

这个是用来自动分配identity列的值的,sybase采用预分配区间的方式,所以重启或rollback事务会产生断带,这个参数就是用来控制断带的大小的,公式为:

identity burning set factor(F) = N * power(10, 7 - M)

其中N是每次分配的种子数量,M为identity列的长度。反过来,想知道每次会分配多少种子数,公式就是:

N = F * power(10, M - 7)

在我这里,identity列长度为8/numeric(8,0),identity burning set factor设置为10,每次的种子分配就是100个,最大的断带也就是100。

其它文档中提到,但是不需要运行的

  • installmaster
  • installcommit 两阶段提交或分布式事务(two-phase commit or distributed transactions)
  • installsecurity (Sybase auditing feature)
  • instmsgs.ebf (brings your Adaptive Server messages up to the level of this EBF)
  • installjsdb (Job Scheduler feature enabled)and(upgrade the Job Scheduler Templates)
  • installmontables (update the Monitoring Tables' definitions)

文档中都有详细说明,用isql执行相应sql文件即可,我没有装。

创建init.d脚本

我的安装并没有自动在/etc/init.d/下创建控制服务的脚本,所以只能自己按照SQL Relay 上的例子创建一个了(有一点点改动):

#!/bin/sh

export SYBASE=/opt/sybase
export PATH=$PATH:$SYBASE/ASE-15_0/bin:$SYBASE/ASE-15_0/install
export LD_POINTER_GUARD=0
#echo 268435456 > /proc/sys/kernel/shmmax
case "$1" in
start)
for i in `ls $SYBASE/ASE-15_0/install/RUN_*`
do
su -c "$SYBASE/ASE-15_0/install/startserver -f $i" > /dev/null 2>&1;
#su -c "$SYBASE/ASE-15_0/install/startserver -f $i"
done
;;
stop)
kill `ps -efa | grep sybase | grep -v grep | awk '{print $2}'`
;;
*)
echo $"Usage: $0 {start|stop}"
exit 1
esac

exit 0

这里还有一个更好的脚本,主要是关闭使用的不是kill,而是数据库自身的shutdown功能),针对我的平台,我有略微改动,建议大家使用这个或参照修改:

#!/bin/bash
# Author: MichaelBibby
# Date: 2007.06.19
# description: Normal RC script for SYBASE.

SYBASE_USERNAME="sa"
SYBASE_PASSWORD=""

export LD_POINTER_GUARD=0
export SYBASE=/opt/sybase
export SYBASE_HOME='/opt/sybase'
export SYBASE_OCS='OCS-15_0'
export SYBASE_ASE='ASE-15_0'
# ************************************************
# Warnning: Modify the RUN_xxx to fit your need.
# Your startup script will be such as:
# ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER}
# ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER_BACKUP}
export SERVER='SVR6'
export SERVER_BACKUP='SVR6_BS'
# For multi-server
# export SERVER='server1 server2'
# export SERVER_BACKUP='server1_backup server2_backup'
# ************************************************

export LIB="${SYBASE_HOME}/${SYBASE_OCS}/lib"
export PATH=$PATH:"${SYBASE_HOME}/${SYBASE_ASE}/bin:${SYBASE_HOME}/${SYBASE_ASE}/install:${SYBASE_HOME}/${SYBASE_OCS}/bin"

start_db()
{
su -p sybase -c "${SYBASE_HOME}/${SYBASE_ASE}/install/startserver
-f ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER}"

su -p sybase -c "${SYBASE_HOME}/${SYBASE_ASE}/install/startserver
-f ${SYBASE_HOME}/${SYBASE_ASE}/install/RUN_${SERVER_BACKUP}"
}

stop_db()
{
# Error: Site 'SVR6_BS' not found in sysservers/ User default back_srv name.
${SYBASE_HOME}/${SYBASE_OCS}/bin/isql
-U${SYBASE_USERNAME}
-P${SYBASE_PASSWORD}
-S${SERVER} </dev/null
if [ X"$?" == X"0" ]; then
stop_db
else
exit 0
fi
;;
status) status_db ;;
*) echo "USAGE: $0 [start|stop|status|restart]" ;;
esac

把这个脚本ln为/etc/init.d/sybase就可以用来控制服务了。

开机后自动启动

把刚才创建的/etc/init.d/sybase这个文件ln到各个rc目录下就可以了:

cd /etc/rc0.d/
ln -s ../init.d/sybase K90sybase
cd /etc/rc1.d/
ln -s ../init.d/sybase K90sybase
cd /etc/rc2.d/
ln -s ../init.d/sybase S90sybase
cd /etc/rc3.d/
ln -s ../init.d/sybase K90sybase
cd /etc/rc4.d/
ln -s ../init.d/sybase K90sybase
cd /etc/rc5.d/
ln -s ../init.d/sybase K90sybase
cd /etc/rc6.d/
ln -s ../init.d/sybase K90sybase
cd /etc/rcS.d/
ln -s ../init.d/sybase S90sybase

绑定两个ip地址

默认情况下,sybase只在一个ip地址上监听,如果在interfaces文件中强行添加其他的ip,或者是其他的端口,比如这样:

SVR6
master tcp ether svr6 5000
query tcp ether svr6 5000
master tcp ether svr6 4000
query tcp ether svr6 4000
master tcp ether 192.168.0.106 5008
query tcp ether 192.168.0.106 5008

都用svr6这个名字,5000和4000端口都可以监听成功,但第二个106的地址监听不成功:

00:00000:00008:2007/09/18 13:43:49.84 kernel  network name svr6, interface IPv4, address 0.0.0.0, type tcp, port 5000, filter NONE 
00:00000:00008:2007/09/18 13:43:49.84 kernel network name svr6, interface IPv4, address 0.0.0.0, type tcp, port 4000, filter NONE
00:00000:00008:2007/09/18 13:43:55.17 kernel ninit: cannot find host 192.168.0.106 00:00000:00008:2007/09/18 13:43:55.17 kernel Cannot allocate resources for listener with protocol tcp, host 192.168.0.106 , port 5008, engine 0.

所以变通的办法无外乎两种,一种是用防火墙把另外一个ip地址的端口作dnat转发过来,另外一种就是修改hosts文件,把svr6的地址指定为0.0.0.0,个人认为第二种方式较好一些,并且试验成功。

创建数据库

设定以后的用户数据库不要默认创建在master设备上

1> sp_diskdefault master, defaultoff
2> go

更改tempdb的大小(建议使用下面ram设备的方式)

先查看tempdb的状态:sp_helpdb tempdb,默认是创建在master设备上,大小为4M,而将临时数据库放在单独的设备上更好,现在就来调整:

> disk init     # 初始化设备
> name="tempdb_dev", # 设备名称,遵守sybase标识符规则
> physname="/opt/sybase/tempdb.dat", #设备物理地址,最好用绝对地址
> vdevno=13, # 设备编号(需要唯一,我刚装上的系统,master是0,sysprocsdev是1,systemdbdev是2,再新建就该用3了)
> dsync=false, # 关闭I/O缓存,提升性能
> size=15360 # 设备大小,默认是以块为单位(一般512字节或者2k),不过建议使用尺寸,比如"200M"或者"1g",这样更容易掌握一些)
> go

将临时数据库扩展到该一个设备上,注意这里的单位是M

> alter database tempdb on tempdb_dev=30
> go

打开tempdb数据库,从段上删除master设备

> use tempdb
> go
> sp_dropsegment default, tempdb, master
> go
> sp_dropsegment logsegment, tempdb, master
> go
> sp_dropsegment system, tempdb, master
> go

设置tempdb为第一个recover的库(好像没必要)

-- make the second tempdb the first user db to be recovered.
> sp_dbrecovery_order tempdb_report, 1
> go

参考:disk init手册

把tempdb创建在ram设备上

首先创建虚拟的ram设备,挂载上(默认的大小单位好像是1k,但建议适当多划分一点空间留给文件系统和容纳计算误差,比如我想用30M的tempdb,就划了33000),创建设备文件,并更改文件权限:

mkdir /home/sybase/tempdb
mke2fs -q -m0 /dev/ram0 33000
mount -t ext2 /dev/ram0 /home/sybase/tempdb
?? touch /home/sybase/tempdb/tempdb.dat (第一次创建的时候不建文件,加在启动脚本里再用touch?)
chown -R sybase:sybase /home/sybase/tempdb

然后在这个设备文件上创建sybase数据库设备,并把tempdb转移过来,首先创建设备:

> disk init name="tempdb_dev", phyname="/home/sybase/tempdb/tempdb.dat", vdevno=3,dsync=false,size="30M"
> go

在新设备上分配空间:

> use master
> alter database tempdb on tempdb_dev=30
> go
Extending database by 15360 pages (30.0 megabytes) on disk tempdb_dev

从旧设备(master)上删除段:

> use tempdb
> go
> sp_dropsegment "default", tempdb, master
> go
> sp_dropsegment logsegment, tempdb, master
> go
> sp_dropsegment system, tempdb, master
> go

回收旧设备上的空间,还是直接修改系统表最简单,不过最好先查询一下,对照sysusages表的内容进行适应性调整:

> sp_configure "allow update", 1
> go
> begin tran
> delete from sysusages where dbid=2 and segmap=0
> go
> update sysusages set lstart=0 where dbid=2
> go
> commit
> go
> sp_configure "allow update", 0
> go

还有一种用临时表,写日志然后截断日志的方式,可以参考同一设备数据库如何分离日志与数据,不过我作的时候没有成功,还因为日志堵塞动弹不得(我循环了50万次都没事,然后全部 delete from就出事了 :);另外一次是在执行sql insert into t select id from t时,第一次执行没事,5万条数据出来了,第二次再执行。。。死掉了)。可以用sp_helpdb tempdb查设备和段分配情况,

为了在重启的时候也能正常创建ram盘,还要在上面说过的服务控制脚本中添加创建并使用ram盘的内容,即在start_db的开始部分加上:

start_db()
{
echo "Mounting ramdisk for tempdb ..."
mke2fs -q -m0 /dev/ram0 33000
mount -t ext2 /dev/ram0 /home/sybase/tempdb
touch /home/sybase/tempdb/tempdb.dat
chown -R sybase:sybase /home/sybase/tempdb
......

在stop_db()的结尾部分加上:

    ......
echo "Dismounting ramdisk of tempdb ..."
umount /home/sybase/tempdb

if [ X"$?" == X"0" ]; then
exit 0
else
exit 1
fi
} // end of func stop_db

两个疑惑的地方及我看到的结果:

  • mke2fs创建的ram盘占用实际的内存么?好像不占,分配到文件上才占。
  • sybase重启后,tempdb会重用大小和以前不同的同名设备文件么?会的,tempdb的机制和其他用户库不一样。

参考:

搞定收工,可以正式建库配置应用数据库了,再推荐几个sybase的资料:

Source: http://www.fwolf.com/blog/post/357