﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-JAVA学习之路</title><link>http://www.blogjava.net/joaquin25/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 12 Apr 2026 06:01:28 GMT</lastBuildDate><pubDate>Sun, 12 Apr 2026 06:01:28 GMT</pubDate><ttl>60</ttl><item><title>Flex事件机制</title><link>http://www.blogjava.net/joaquin25/articles/245046.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Mon, 08 Dec 2008 07:59:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/245046.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/245046.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/245046.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/245046.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/245046.html</trackback:ping><description><![CDATA[
		<p>转自：<a href="http://hi.baidu.com/doltcat/blog/item/9a22e22a5221952bd52af13e.html">http://hi.baidu.com/doltcat/blog/item/9a22e22a5221952bd52af13e.html</a><br /><br />很多开发人员都知道如何使用事件机制，但却不理解事件机制的基本工作原理。在这里我们探讨一下ActionScript 3的事件机制(无论是新手还是老手，我相信看到最后肯定对你有所帮助<img src="http://st.blog.163.com/style/common/htmlEditor/portrait/face/preview/face1.gif" /> )。<br /><strong>1. 首先来看一下事件机制中的几个基本概念：</strong></p>
		<ul>
				<li>
						<strong>event objects</strong>(这里我们姑且叫它事件对象)：所有的事件对象都是flash.events.Event或者其子类。比如说鼠标事件MouseEvent，计时器事件TimerEvent。每个事件对象中都包括事件类型(type)和事件源(target)，便于event listener知道该事件的类型以及是谁抛出这样的事件。 
</li>
				<li>
						<strong>event dispatchers</strong>(姑且叫它事件源):是事件发起的主体。所有的dispatcher都是EventDispatcher或其子类。事件触发源必须提供API让listener进行对该事件的注册(register)。 
</li>
				<li>
						<strong>event listeners</strong>(姑且叫它事件监听器):在AS 3.0中它往往表现为一个函数。我们必须为每个特殊的事件和事件源注册一个监听器，当事件发生的时候，事件源(dispatcher)会通知该监听器去处理制定的事件。 </li>
		</ul>
		<p>
				<strong>2. 如何注册监听器(registering Listener)<br /></strong>在AS 3.0中可以通过下面的语法格式进行注册。<br /><font color="#ff0000" size="3"><strong>dispatcher.addEventListener(eventName, listener);<br /></strong></font>当然在Flex中还有另外一种格式，在mxml文件中对一个控件的事件直接制定一个处理函数，如<br /><font color="#ff0000" size="3"><strong>&lt;mx:Button label="TestClick" click="clickHandler()"/&gt;</strong></font></p>
		<p>
				<strong>3. 如何删除监听器(removing Listener)</strong>
				<br />在AS 3.0中以下面的格式进行删除<br />circle.removeEventListener(MouseEvent.CLICK, onClick);<br />应该很容易理解。<br />但这里确有一点很重要：尽量删除你已经不再使用的事件监听器，这个涉及到Flex 内存泄漏的问题，以后会有详细介绍。</p>
		<p>
				<strong>4. 理解事件阶段(Event Phases)</strong>
				<br />我们把事件触发源分为两类：一类是那些显示在界面中的元素抛出的事件，一类是那些不在界面中显示的元素抛出的事件。很简单，举个例子：第一类如URLLoader对象去load图片或其他资源所抛出的如complete事件，就属于第一类。界面上的一个按钮所抛出的click事件就是第二类，它会触发一个事件流，引发一系列的事件，它又分三个阶段：捕获(capture)，执行(target) 和冒泡(bubble)，姑且这样表达这三个阶段。</p>
		<ul>
				<li>
						<strong>捕获阶段(capture)</strong>
						<br />在这个阶段，Flash Player会去查找事件的触发源，它是通过根显示元素(root display object)逐层向下寻踪，直到找到事件的发起源头，如你在button上click后，Flash Player找到的事该button对象。在这个阶段监视器(listener)默认是不会收到任何消息的(默认只在target和bubble阶段收到消息)。<br />如果你想在捕获阶段让listener收到消息并有所动作，那么你可以在注册的时候改变第三个参数为true，如下面的方法：object.addEventListener(MouseEvent.CLICK, onClick, true);<br />该阶段听起来很陌生，事实上它很少使用。但它却在事件流中扮演很重要的角色。它可以在事件到达子元素(child elements)之前被application捕获，当然也就可以阻 止事件到达子元素。 
</li>
				<li>
						<strong>目标执行阶段(target)</strong>
						<br />在这个阶段是事件的执行阶段，也就是我们常用的用来处理事件流的代码。 
</li>
				<li>
						<strong>冒泡阶段(bubble)</strong>
						<br />最后的这个阶段其实就是第一个阶段的逆向过程。它就是在事件代码执行完毕后通过子元素逐级向父元素发出该事件，一直到根元素。在这个阶段你不需要特别的为监听器指定什么，你只要正常的注册事件就可以了。监听器会在该阶段收到通知。但前提是该事件是能够bubble的。 </li>
		</ul>
		<p>
				<strong>5. 事件的优先级(Event Prioriy)</strong>
				<br />事件优先级我们用的很少，但理解它却很重要，但你添加一个事件的时候你可以设置监听器的优先级，优先级越高，你的监听器函数会越早被调用到。当然两个优先级相同的监听器是根据他们被添加的顺序来决定优先级的。这个优先级指的是在同一个事件阶段(如capture,target,or bubble).一次，事件处理的优先级是先看阶段再看优先级的。</p>
		<p>
				<strong>6. 弱引用(Weak Reference)</strong>
				<br />弱引用时事件处理中非常重要的概念。要理解它为什么这么重要，你首先要理解Flash Player是如何进行垃圾回收的(garbage collection).</p>
		<p>顾名思义，垃圾回收就是回收那些不再使用的资源，主要是内存资源，否则会致系统崩溃。</p>
		<p>Flash Player是通过引用计数器(reference counting)以及标记与清除(mark and sweep)来实现垃圾回收的。<br />引用计数器简单的讲就是给每个对象分配的技术器，一旦该对象的计数器为0时，就表示该对象可能不再被使用，可以安全的清除了。它的弊端就是不能解决循环引用问题，一旦出现循环引用，就不能通过该方法进行垃圾回收。<br />而标记与清除(mark and sweep)就是为了解决循环引用问题的。它是通过在程序中遍历每个活动的、可到达的节点，一旦发现一些节点是处在活动节点之外的，就被认为不再有用，就可以被回收了。<br />这两种机制是联合运行在垃圾回收过程中来保证正确回收资源。但他们并不能回收程序错误导致的垃圾。而监听器的注册就最容易导致这个问题的发生。</p>
<img src ="http://www.blogjava.net/joaquin25/aggbug/245046.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-12-08 15:59 <a href="http://www.blogjava.net/joaquin25/articles/245046.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VNCServer 配置 及Vncview的使用</title><link>http://www.blogjava.net/joaquin25/articles/216640.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Tue, 22 Jul 2008 08:18:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/216640.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/216640.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/216640.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/216640.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/216640.html</trackback:ping><description><![CDATA[转自：<a href="http://blog.csdn.net/huxinghua/archive/2007/06/12/1648965.aspx">http://blog.csdn.net/huxinghua/archive/2007/06/12/1648965.aspx</a><br /><br />VNCServer 配置 及Vncview的使用<br />1、vncserver服务的启动<br />    redhat 及fedora 一般都自动安装了vncserver了 只要在服务列表中选中启动一下就可以了<br />2、vncserver的配置<br />    通过编辑文件$HOME/.vnc/xstartup来启动你喜欢的窗口管理器。使用startkde &amp;来启动KDE，使用gnome-session &amp;来启动GNOME，fvwm2 &amp;来启动FVWM2 。下面是一个例子<br />#####################################################<br />#!/bin/sh 
<p># Uncomment the following two lines for normal desktop:<br /># unset SESSION_MANAGER<br /># exec /etc/X11/xinit/xinitrc</p><p>[ -x /etc/vnc/xstartup ] &amp;&amp; exec /etc/vnc/xstartup<br />[ -r $HOME/.Xresources ] &amp;&amp; xrdb $HOME/.Xresources<br />xsetroot -solid grey<br />vncconfig -iconic &amp;<br />#xterm -geometry 80x24+10+10 -ls -title "$VNCDESKTOP Desktop" &amp;<br />gnome-session<br />#startkde<br />#twm &amp;<br />##########################################################<br />3、开始使用<br />    在启动前还是要运行一个东西的，可以使用telnet用自己的用户登录远程系统<br />运行vncserver ，若要定义界面大小，颜色看 vncserver --help，若是第一次运行<br />会提示输入口令，远程登录的口令，跟用户口令没关系的。口令修改可以使用<br />vncpasswd程序。运行成功后会有桌面号的提示类似:1  :2  的。记住桌面号。退<br />出telnet。每次服务器重器后都需要运行一次。<br /><br />4、登录<br />    在windows下载一个winvnc，安装完成后，不用启动服务，使用它的查看器就<br />可以了。输入vnc服务器 地址:桌面号 ，再输入口令就可以使用了。注意，每次<br />使用完，请千万不要注销掉系统，直接关闭winvnc查看器就可以了，只要服务器<br />没问题，可以再次使使用winvnc继续连接。<br />5、关闭服务器上自己的vnc连接<br />    vncserver -kill  :桌面号<br />6、如何使服务器开机自动运行vncserver 不需要自己telnet<br />    使用linuxconf来设置vncserver启动脚本(/etc/init.d/vncserver)实现系统自启动时启动vncserver。但是默认的启动脚本灵活性不够，因此编辑/etc/init.d/vncserver,修改：</p><p>"su - ${display##*:} -c "cd &amp;&amp; [ -f .vnc/passwd ]<br />&amp;&amp; vncserver :${display%%:*}""<br />为：</p><p>"su - ${display##*:} -c "cd &amp;&amp; [ -f .vnc/passwd ]<br />&amp;&amp; vncserver ${ARGS} :${display%%:*}""<br />然后编辑/etc/sysconfig/vncservers：<br /># The VNCSERVERS variable is a list of<br /># display:user pairs.<br />#<br /># Uncomment the line below to start a VNC server on<br /># display :1 as my 'myusername' (adjust this to your<br /># own). You will also need to set a VNC password;<br /># run 'man vncpasswd' to see how to do that.<br />#<br /># DO NOT RUN THIS SERVICE if your local area network<br /># is untrusted! For a secure way of using VNC, see<br /># &lt;<a href="http://www.uk.research.att.com/vnc/sshvnc.html">URL:http://www.uk.research.att.com/vnc/sshvnc.html</a>&gt;.</p><p>VNCSERVERS="1:jdimpson"<br />ARGS="-geometry 1024x768 -alwaysshared "<br />在ARGS中修改"1024x768"来适应自己的X桌面实际参数配置。可以在这里添加任何其他VNC服务器参数配置。在VNCSERVERS中修改jdimpson为你希望运行VNC桌面的用户。VNCSERVERS中的1表示VNC以桌面1运行，如果希望添加其他的桌面，可以修改配置如下：<br />VNCSERVERS="1:jdimpson 2:phred 3:sysadmin"<br />在RedHat系统上，使用以下命令启动VNC：<br />/etc/init.d/vncserver start<br />现在你就可以使用VNC任何客户端来使用VNC桌面。 <br /></p><img src ="http://www.blogjava.net/joaquin25/aggbug/216640.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-22 16:18 <a href="http://www.blogjava.net/joaquin25/articles/216640.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>VNCserver的配置</title><link>http://www.blogjava.net/joaquin25/articles/216638.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Tue, 22 Jul 2008 08:17:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/216638.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/216638.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/216638.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/216638.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/216638.html</trackback:ping><description><![CDATA[
		<div>转自：<a href="http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246151026a5e079714c52ce963c365bf40d0bf7f03470321e22b186c88257debc9823288c2623706bd50050990dea960673ce64cc0bfeaf68bbe7e732e2ee8f94990344ca22432797f0fa005d558c&amp;p=8f769a4186cc40a90ebfc6645a52&amp;user=baidu">http://cache.baidu.com/c?m=9f65cb4a8c8507ed4fece7631046893b4c4380146d96864968d4e414c42246151026a5e079714c52ce963c365bf40d0bf7f03470321e22b186c88257debc9823288c2623706bd50050990dea960673ce64cc0bfeaf68bbe7e732e2ee8f94990344ca22432797f0fa005d558c&amp;p=8f769a4186cc40a90ebfc6645a52&amp;user=baidu</a><br />1 问题如下</div>
		<div>/etc/sysconfig/vncservers---配置文件作用去掉最后两行的注释</div>
		<div>
				<a name="baidusnap1">
				</a>
				<b style="COLOR: black; BACKGROUND-COLOR: #a0ffff">no</b>
				<a name="baidusnap2">
				</a>
				<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">route</b>
				<a name="baidusnap3">
				</a>
				<b style="COLOR: black; BACKGROUND-COLOR: #ff9999">to</b>
				<a name="baidusnap4">
				</a>
				<b style="COLOR: black; BACKGROUND-COLOR: #ff66ff">host</b>
		</div>
		<div>是防火墙的原因---必须得研究好防火墙</div>
		<div>本地可以<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>，本地可以访问zhanglinux.org:1158/em</div>
		<div>我一直以为是没有路由导致的</div>
		<div>
				<b style="COLOR: black; BACKGROUND-COLOR: #99ff99">route</b>
				<span>   add   default   gw   192.168.0.254</span>
		</div>
		<div>经过一系列的测试发现是防火墙的问题。以后在研究网络问题时，首先要注意防火墙的设置。先取消防火墙的设置，在没有防火墙的基础上，实现连通。之后再设置防火墙。防火墙对于网络的安全控制，以及网络访问上都至关重要。这是个基础性的问题。从今天的实践可以看出，基础的把握能力不够。</div>
		<div>2 软件下载</div>
		<div>windows <b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>---http://download.pchome.net/php/tdownload2.php?sid=2603&amp;url=/internet/server/remote/<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>-3.3.7-x86_win32.zip&amp;svr=1&amp;typ=0</div>
		<div>linux <b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>--http://mirror.etf.bg.ac.yu/fedora/development/i386/Fedora/RPMS/<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>-4.1.1-34.i386.rpm</div>
		<div>ps: http://rpmfind.net 找需要的包。由于学校的proxy服务器设置老出问题，本来用yum install -y 通用包名--非常方便，不得不用老土的rpm -Uvh , rpm -q 这两条命令都非常重要了。</div>
		<div> </div>
		<div>3 安装: rpm -Uvh *rpm</div>
		<div>注意依赖~~~</div>
		<div>4 在X桌面下设置服务器允许连接，同时可以设置连接密码。</div>
		<div>http://www.linuxsir.org/bbs/showthread.php?t=262457</div>
		<div>上面的问题，我这里是由于firewall导致的---可在X桌面设置防火墙</div>
		<div> </div>
		<div>－－－－－－－－－－－－－－－－－－－－具体使用方法－－－－－－－－－－－－</div>
		<div>启vncserver: vncserver即可，第一次会提示你输入密码; </div>
		<div>关闭: </div>
		<div>vncserver -kill :桌面号 </div>
		<div>或者使用系统自带脚本：</div>
		<div>补充VNCServer的命令行启动、关闭方法： </div>
		<div>1)服务器端启动： </div>
		<div>#vncserver </div>
		<div>$vncserver </div>
		<div>注意到每个用户都可以启动自己的vncserver，每个用户可以启动多个vncserver，用显示端口号:1，:2，:3等等来标识。 </div>
		<div>2) 客户端： </div>
		<div>a）在linux下，运行vncviewer命令即可，服务器地址的写法形如192.168.3.119:1 </div>
		<div>b）在windows下，运行windows版本的vncviewer即可，用法与linux下相近。 </div>
		<div>c）用浏览器（平台无关），作为java applet来实现，以形如http://192.168.3.119:5801的方式来启动 </div>
		<div>3) 密码修改： </div>
		<div>第一次启动vncserver会提示输入密码，以后要修改的话，运行： </div>
		<div>#vncpassword </div>
		<div>4) 停止<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b> server： </div>
		<div>#vncserver -kill :1 </div>
		<div>#vncserver -kill :2 </div>
		<div>注意到vncserver只能由启动它的用户来关闭，即时是root也不能关闭其它用户开启的vncserver，除非用kill命令暴力杀死进程。 </div>
		<div>5) 指定显示端口号启动<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">VNC</b> server： </div>
		<div>#vncserver :3 </div>
		<div>$vncserver :6 </div>
		<div>6) 设置<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">VNC</b> server分辨率： </div>
		<div>#vncserver -geometry 800x600 </div>
		<div>#vncserver -geometry 640x480 </div>
		<div>7) 设置vncserver的色深： </div>
		<div>8位为256色，16位为64k色 </div>
		<div>#vncserver -depth 8 </div>
		<div>#vncserver -depth 16 </div>
		<div>稳定性设置： </div>
		<div>vncserver默认在多个客户机连接同一个vncserver的显示端口时，vncserver端口旧连接，而为新连接服务，可通过-dontdisconnect拒绝新连接请求而保持旧的连接。 </div>
		<div>9) 设置vncserver的同一个显示端口可以连接多个客户机 </div>
		<div>#vncserver -alwaysshared</div>
		<div> </div>
		<div>10) 默认远程登陆启动的是kde桌面（如果安装系统时安装了的话），如果修改登陆的图形界面？当在oracle用户下面启用vncserver的时候，在oracle用户的家目录下会自动创建一个.<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>的文件夹，在该文件夹下面有一个文件，是xstartup,编辑这个文件，将所有的行都注释掉，然后在最后加一行：</div>
		<div>gnome-session &amp;</div>
		<div>保存文件，重启vncserver，就会发现登陆的图形界面已经变成了你想要的样式了。</div>
		<div>比如：</div>
		<div>服务端</div>
		<div>[root@zhanglinux .<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>]# vncserver :3</div>
		<div> </div>
		<div>You will require a password <b style="COLOR: black; BACKGROUND-COLOR: #ff9999">to</b> access your desktops.</div>
		<div> </div>
		<div>Password:</div>
		<div>Password must be at least 6 characters - try again</div>
		<div>Password:</div>
		<div>Password must be at least 6 characters - try again</div>
		<div>Password:</div>
		<div>Verify:</div>
		<div>New 'zhanglinux.org:3 (root)' desktop is zhanglinux.org:3</div>
		<div> </div>
		<div>Creating default startup script /root/.<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>/xstartup</div>
		<div>Starting applications specified in /root/.<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>/xstartup</div>
		<div>Log file is /root/.<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>/zhanglinux.org:3.log</div>
		<div> </div>
		<div>客户端</div>
		<div>登录时:vncviewer ip:3</div>
		<div>登录之后，查看默认端口5900 对应进程名<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>-serv</div>
		<div>[root@zhanglinux .<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>]# netstat -na | grep 5900</div>
		<div>tcp<span>        0      0 202.116.130.243:5900        202.116.130.241:1729        ESTABLISHED</span></div>
		<div>退出vncviewer </div>
		<div>[root@zhanglinux .<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>]# netstat -na | grep 5900</div>
		<div>tcp<span>        0      0 0.0.0.0:5900                0.0.0.0:*                   LISTEN</span></div>
		<div> </div>
		<div>----------------------------------------------------------------------------</div>
		<div>终于解决了<b style="COLOR: black; BACKGROUND-COLOR: #ffff66">vnc</b>启动时加入服务的问题 [http://bbs.chinaunix.net/viewthread.php?tid=149091]</div>
		<div>我就没做了，个人觉得没多大必要，需要才启动。</div>
		<div>vi /etc/rc.d/init.d/vncserver 服务启动相关设置</div>
		<div>----------------------------------------------------------------------------</div>
<img src ="http://www.blogjava.net/joaquin25/aggbug/216638.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-22 16:17 <a href="http://www.blogjava.net/joaquin25/articles/216638.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>找不到libexpat.so.0这么解决 </title><link>http://www.blogjava.net/joaquin25/articles/216392.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Mon, 21 Jul 2008 08:44:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/216392.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/216392.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/216392.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/216392.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/216392.html</trackback:ping><description><![CDATA[libexpat.so.1是libexpat.so.0的升级版本，只需加一个链接即可以。<br />#ln -s /usr/lib/libexpat.so.1 /usr/lib/libexpat.so.0<br /><img src ="http://www.blogjava.net/joaquin25/aggbug/216392.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-21 16:44 <a href="http://www.blogjava.net/joaquin25/articles/216392.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix培训教材整理之动态命令集</title><link>http://www.blogjava.net/joaquin25/articles/215865.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Fri, 18 Jul 2008 08:53:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/215865.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/215865.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/215865.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/215865.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/215865.html</trackback:ping><description><![CDATA[
		<table cellspacing="0" cellpadding="0" width="100%" align="center" border="0">
				<font class="htd" id="" font_word??="" font-size:14px;="" font-family:宋体,="" verdana,="" arial,="" helvetica,="" sans-serif;??="">转自：<a href="http://unix-cd.com/unixcd12/article_5443.html">http://unix-cd.com/unixcd12/article_5443.html</a><br /><br />onstat 命令<br /><br />            语法 onstat [-s] [-i] [-p] [-y]<br /><br />            onstat    将系统从off-line模式变为on-line模式<br /><br />            onstat -s   将系统从off-line模式变为quiescent模式<br /><br />            onstat -i   初始化系统<br /><br />            onstat -p   在共享内存初始化时，不搜索，删除临时表<br /><br />            onstat -y   对提示自动回答yes<br /><br />                          oninit -- 键入此命令可以获得使用帮助    <br /><br />      onstat 命令用来改变系统的运行模式。其中-i选项用于初始化系统的root dbspace。注意，root-dbspace一旦被初始化，则等于整个数据库系统被初始化。<br /><br />      如果用户希望在计算机启动时自动自动启动动态服务器系统，请在系统初启文件（在许多UNIX系统中为/etc/rc）中加入onstat命令（不加任何选项）。<br /><br />      onmode 命令    <br /><br />            语法： onmode [-k] [-m] [-s] [-u] [-y]<br /><br />            onmode -k     执行立即shutdown，将系统变为off-line模式<br /><br />            onmode -m     将系统从quiescent模式变为on-line模式<br /><br />            onmode -s     执行graceful shutdown<br /><br />            onmode -u      执行immediate shutdwon<br /><br />            onmode -y     对提示自动回答yes      <br /><br />      onmode 命令同样用于改变动态服务器的运行模式。除了上述选项外,onmode还有很多与改变系统运行模式无关的选项。<br /><br />      利用onspaces命令创建数据空间<br /><br />            语法： onspaces -c [-b] [-d] [-z] [-m] [-o] [-p] <br /><br />              [-s] [-t]<br /><br />            -c      创建blobspace或dbspace<br /><br />            -b blobspace blobspace名<br /><br />            -d dbspace   dbspace名<br /><br />            -g page size  blobpages大小<br /><br />            -m mirror    镜像设备设的全路径名和偏移量（KB)<br /><br />            -o offset    偏移量（KB)<br /><br />            -p pathname   chunk设备的全路径名<br /><br />            -s size    dbspace大小（KB)<br /><br />            -t       创建临时dbspace<br /><br />          onspaces命令用于创建数据空间、临时空间和存储blob数据的空间（blobspace)。键入onspaces--可以获得该命令的联机帮助。利用onstat <br /><br />        -D或onstat -d可以看到系统中的关于数据空间的重要信息。包括：chunk的状态、空闲、每一chunk读写的次数。系统中可能包括的多个系统空间，特别当进行数据分片后，我们建议用户最好能利用命令行来创建数据空间。<br /><br />      可以利用如下命令创建数据空间：<br /><br />      onspaces -c -d datadbs1 -o 0 -p /dev/rrvol3 -s 60000<br /><br />      可以用如下的方式创建临时数据空间：<br /><br />      onspaces -c -d tempdbs1 -t -o 0 -p /dev/rrvol5 -s 80000<br /><br />      在系统中，临时数据空间非常重要，通常情况下，应将多个临时数据空间分布在独立的物理设备上。<br /><br />      利用onspaces命令删除数据空间<br /><br />            增加或删除chunks<br /><br />            语法： onspaces -a -d [-m] [-o] [-p]<br /><br />            -a spacename    为dbspace新增chunk<br /><br />            -m pathname    镜像设备的全路径名和偏移量（KB）<br /><br />            -o offset      主设备的偏移量（KB)<br /><br />            -p pathname     chunk设备的全路径名<br /><br />            -s size      chunk大小<br /><br />            -d spacename    删除chunk<br /><br />            -o offset      chunk设备的偏移量（KB)<br /><br />      onspaces不仅能创建数据空间还能删除数据空间、临时数据空间或存储blob数据的空间。在删除数据空间时，必须首先保证它是无用的，即该数据空间上无数据库或表。<br /><br />      如需删除数据空间，请键入如下命令：onspaces -d dbspace_name /blobspace_name<br /><br />      数据空间最初由一个chunk（first chunk）构成，一旦其空间用尽，用户必须追加chunk为了提高系统性能，用户在为数据空间分配chunk时需要计算以保证它的大小能适应未来的需要，否则在追加chunk的时候，它与先前的chunk在物理上不一定相邻，导致增加读取数据的时间。关于如何计算空间需求将在以后章节中阐述。利用onspaces命令可以对数据空间增加或者删除chunk,除此之外，利用该命令还可以完成如下任务：启动镜像、中止镜像或改变chunk的状态。<br /><br />      例如可以用如下命令为数据空间增加chunk：<br /><br />      onspaces -a -d datadbs1 -0 60002 -p /dev/rrvol3 -s 60000<br /><br />      再如可以用如下方式从数据空间中删除chunk：<br /><br />      onspaces -d datadbs1 -o 60002 -p /dev/rrvol3 -s 60000<br /><br />      onparams 命令<br /><br />            语法：onparams -a -d -p [-d] [-s] [-l]<br /><br />            -a     新增逻辑日志<br /><br />            -d dbspace 指定日志存放的dbspace<br /><br />            -s size   新增逻辑日志的大小（KB）<br /><br />            -d     删除逻辑日志<br /><br />            -l logid  指定删除一个逻辑日志<br /><br />            -p     改变物理日志<br /><br />            -d dbspace 新物理日志存放的dbspace名<br /><br />            -s size  物理日志大小（KB)<br /><br />      系统在初始化时自动地在root dbspace中创建逻辑日志和物理日志。在DBMS系统中，尤其在OLTP环境下，数据库的操作非常频繁，日志中必须记录大量的信息，所以用户最好能将多个日志文件分布在不同的设备上。有一种非常简单的方法： <br /><br />        即按所需大小创建逻辑日志，同时创建一个较小的物理日志，系统初始化完毕后，再将物理日志移至其它设备。关于如何确定所需的物理日志的大小，将在以后的章节详述。<br /><br />      利用onstat -l命令可以看出系统中所有新增的逻辑日志被标识为A。这些逻辑日志只有在系统进行归档后才会真正被使用。为了激活这些逻辑日志有一种简单的方法：执行一次“伪”归档。具体步骤如下：<br /><br />将参数TAPEDEV设置为/dev/null然后运行一次ontape -s。也可以执行onbar -F命令。由于伪归档并不真正归档系统信息，所以千万要适时地对系统进行真正的归档操作。<br /><br />      只有在逻辑日志真正无用时才能将其删除。利用onstat -l 可以看出所有的空闲日志被标记为F。如果逻辑日志中包含事务回滚或快速恢复所需的信息，该逻辑日志是不能被删除的。利用onstat　-l命令可以看出接受当前事务的日志被标记为C。如果逻辑日志包括最后一个检查点记录，它也是不能被删除的，只有当检查点记录被写入下一个日志忠并且上一个日志被备份后，该日志才能被删除。利用onstat <br /><br />        -l命令可以看出包含最后一个检查点记录的日志被标记为L。用户可以利用onmode -c命令强制写检查点记录直至最后一个检查点记录被写入所要求的日志为止。<br /><br />      onstat 工具      <br /><br />        显示动态服务器共享内存中的信息<br /><br />        涉及少量磁盘I/O操作<br /><br />        将对系统性能的影响极小<br /><br />        提供关于系统有价值得信息<br /><br />        命令行交互式监控系统<br /><br />        在此将讲解onstat 的各种重要选项，请熟悉它们的使用      <br /><br />      onstat命令是一种非常有用的系统实时监控工具。该命令直接从共享内存的数据结构中读取信息，报告当时的系统状况。通常onstat 命令不会进行磁盘I/O操作，也不会对系统资源加锁，所以它对系统性能的影响减少到最小。简言之，onstat是informix提供的一种交互式的系统监控工具。<br /><br />      onstat 的一些常用选项：<br /><br />      onstat --     列出所有选项<br /><br />      onstat -i     设置进入交互模式<br /><br />      onstat -      显示运行模式和数据库引擎状态<br /><br />      onstat -g sub_option 运行多线索选项<br /><br />      onstat -r &lt;<i>value</i>&gt; 每隔&lt;<i>value</i>&gt;秒后重复选项<br /><br />      onstat -g act   显示系统中所有的活动线索<br /><br />      onstat -g ath -r 2 每隔两秒显示系统中所有的活动的线索       <br /><br />      系统监控界面            <br /><br />              sysmaster数据库在系统初始化时自动创建<br /><br />              数据库中包括指向系统共享内存结构数据字典信息<br /><br />              提供瞬时的系统性能和状态信息<br /><br />              提供SQL界面了解数据字典信息<br /><br />              允许管理员将系统管理工作自动化<br /><br />              用于执行重复性的监控任务<br /><br />       系统监控界面（system Monitoring Interface --SMI)是一种基于SQL的系统工具，用户通过SMI可以非常方便地获取系统信息。系统在初始化时，自动地在root <br /><br />        dbapace创建sysmaster系统数据库。每一系统包括一个sysmaster数据库，该数据库中的大部分表为虚表，是指向共享内存中数据结构的指针。利用SMI可以自动监控系统，特别是在执行重复任务时。<br /><br />      sysmaster数据库是只读的，即不允许对其进行INSERT UPDATE,或DELETE操作。所有用户都拥有对该数据库的查询权限。<br /><br />      在系统初始化后，用户一定要注意检查sysmaster数据库是否建立成功。创建sysmaster数据库的信息都保存在消息日志文件中（online.log)请注意由于所有的DDL语句都将被记录在日志中，所以一定要在日志文件中留出足够的空间以保证创建sysmaster所需。<br /><br />      sysmaster数据库模式记录在$INFORMIXDIR/etc/sysmaster.sql文件中。<br /><br />      oncheck 命令      <br /><br />        检查动态服务器磁盘上的数据结构<br /><br />        定位并修补损坏的索引和数据<br /><br />        有磁盘I/O操作<br /><br />        一些操作在处理时将在表上加锁      <br /><br />      oncheck命令用于修复磁盘上损坏的索引和数据页，该命令也可用于检查并打印系统的数据结构。在使用oncheck时一定要当心，因为改命令的某些选项会对表加共享锁，例如：oncheck  -pt<br /><br />      为防止对系统的损坏，系统会对所有共享内存中的数据进行一次一致性检查。一旦发现数据页出现一致性错误或发现索引错误，系统将把问题和可能的解决方案（利用oncheck)写入消息日志文件，并返回isam错误代码105。<br /><br />      如果发现一致性错误信息，用户应该立即关闭系统并按消息日志文件中的提示运行oncheck。如果oncheck运行失败，则应尝试卸出表再重新装入；如果是索引得问题，则应先删除索引再重建之。如果所有这些步骤都失败了，只有根据原有的系统归档备份来恢复系统。<br /><br />      下面的命令可以提供extend信息：<br /><br />      oncheck –pe<br /></font>
				<tbody>
				</tbody>
		</table>
<img src ="http://www.blogjava.net/joaquin25/aggbug/215865.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-18 16:53 <a href="http://www.blogjava.net/joaquin25/articles/215865.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix培训教材整理之FAQ</title><link>http://www.blogjava.net/joaquin25/articles/215864.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Fri, 18 Jul 2008 08:52:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/215864.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/215864.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/215864.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/215864.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/215864.html</trackback:ping><description><![CDATA[转自：<a href="http://unix-cd.com/unixcd12/article_5444.html">http://unix-cd.com/unixcd12/article_5444.html</a><br /><br />为什么在一个有30000条记录并且建立有索引的表进行操作很慢，怎么办？<br /><br />      30000条记录并不是太多，你会感觉有慢不应该是记录数太多的缘故，原因可能是每条记录太长，或者你的机器的性能十分低，不过还是有一些方法可能会对性能有所帮助：<br /><br />      1.更新统计信息（update satistics on tablename）,这很容易作，并且有可能会带来性能的提高。<br /><br />      2.删除，然后再重新创建索引。这样作能够增加索引的连续性。但是要求是DBA或者有创建索引的权限。<br /><br />      3.ALTER INDEX idxname TO CLUSTER： 这样作的目的是重新创建表并且通过索引来重新排列记录。结果是强制使记录在逻辑上连续，并且提高物理上的连续性。这样作的代价最大，但是效果最好。但是，一个表中只能有一个cluster index，并且，重新排列记录可能会强迫其他的查询使用其他的索引。作这种工作，你必须要为DBA或者有alter table 的权限。并且请注意，在你运行cluster index的时候，你必须要有足够的空间，因为在为一个表创建cluster index的时候，会拷贝表中所有的记录到一个临时表中，在临时表中进行排序操作，然后会删除原来的表，然后将临时表的名字改为原始表的名字。因此，如果这个表中的数据变化很大，如经常要进行大量的插入/删除的操作，这样作的好处就体现不出来。       <br /><br />     应该使用online的mirroring功能吗？<br /><br />      informix6.0以上的版本开始支持镜像（mirroring)，镜像可以将相同的数据复制到多个磁盘上，当一个磁盘坏掉，online可以继续使用镜像磁盘来代替坏掉的磁盘。<br /><br />      一些操作系统(如HP-UX)也提供镜像的功能，还有硬件方式的镜像，三种镜像方式哪一种更好呢？<br /><br />      通常硬件镜像更好。因为它最快，然后是操作系统的镜像，最后才是ONLINE镜像。ONLINE镜像需要作一些逻辑上的运算，用于判断如何处理down掉的chunk。而是使用HP-UX或者硬件上的镜像不会出现这种情况。<br /><br />      HP的逻辑卷管理可以让你以“stripe的方式将extents以轮转的方式分别存储在多个磁盘上。如果你使用数据分片策略，这也许会/也许不会带来性能的提高。<br /><br />      如果你使用HP-UX的磁盘镜像，在主磁盘繁忙的时候，读盘操作会被转移到镜像盘上，在磁盘负载很重的情况下，这会带来很大的性能提高。       <br /><br />      关于NFS？<br /><br />      1.我们可以在远程主机上运行应用程序吗？（如C程序，shell <i>script</i>s,perl <i>script</i>s等等）运行的性能和在本地运行同样的程序相比如何？<br /><br />      由于NFS mounts远程主机上的文件系统到你的本地计算机，你可以象存取本地磁盘一样存取远程文件系统。这对性能的影响不大。<br /><br />      2.运行NFS需要什么软件？<br /><br />      只需要NFS和TCP/IP。<br /><br />      3.管理NFS是否困难？<br /><br />      主要的困难来自你必须要维护你的分布式文件的UID和GID必须要同步。使用NIS会使这项工作变得容易一点。<br /><br />      如何使用cron自动进行数据库备份？<br /><br />      echo <i>'</i>\n0<i>'</i> | tbtape -s 1 | head -100 <br /><br />       如何知道一个表存在在哪些dbspace上?<br /><br />      以下是一些sql语句：<br /><br />      SELECT TRUNC(partnum/16777216) dbspace, COUNT(*) tables, <br /><br />      SUM(nrows) tot_rows, SUM(nrows*rowsize) bytes FROM systables <br /><br />      WHERE tabtype = <i>'</i>T<i>'</i> GROUP BY 1 ORDER BY 1; <br /><br />      如果你在你的数据库中创建一个叫做<i>'</i>dbspaces<i>'</i>的表，然后将onstat -D的输出的dbspace名称放入这个表中，然后你就可以用：<br /><br />      SELECT dbs_name[1,12] dbspace, <br /><br />      COUNT(*) tables, SUM(nrows) tot_rows, <br /><br />      SUM(nrows*rowsize) bytes <br /><br />      FROM systables, dbspaces <br /><br />      WHERE tabtype = <i>'</i>T<i>'</i> <br /><br />      AND dbs_no = trunc(partnum/16777216)<br /><br />       GROUP BY 1 ORDER BY 1; <br /><br />      输出为：<br /><br />      dbspace    tables  tot_rows  bytes <br /><br />      mcs_aaaaa   28    51     3715 <br /><br />      mcs_catalog  22    2695    114810 <br /><br />      mcs_eeeee   25    224     45446 <br /><br />      mcs_fffff   32    1412    201445 <br /><br />      mcs_mmmmm   35    165     262599 <br /><br />      mcs_wwwww   28    449     79385<br /><br />      注意：（“byte仅仅为数据的字节数，不包括索引和其他的开销）<br /><br />        怎样使用“informix”用户和informix组？<br /><br />      1.是否应该使用informix帐号来管理数据库，例如：grant/revoke权限，创建/删除表，dbload等等。<br /><br />      2.应该创建一个单独的帐号来作这些事情吗？为什么？<br /><br />      3.是否应该用informix帐号来管理数据库应用程序，并且将所有的用户置于这个组内，？<br /><br />      我们仅仅使用informix帐号来进行DBA的管理工作，而不是用它来做所有的事情，你应该有一个informix帐号和一个informix组，帐号和组都是唯一的。在informix组中只应该有informix一个用户。<br /><br />      我们有一个“应用”帐号，这个帐号是所有的非系统表的属主，并且用它设置所有的权限，拥有所有的资源，数据，和可执行目录和代码。这样做的目的是隔离数据管理和服务器管理两种不同的工作。DBA的功能是独立的，（并且只有一个人可以执行这个工作），如果你的数据库规模很大或者即将变得很大，你会体会到这样作的好处。<br /><br />      如果你脱离这个原则，会出现严重的安全隐患。informix组内的其他用户可以执行INFORMIXDIR目录下的很多应用程序，而这些应用程序你一定不希望由他去执行。所以没有必要去冒险将所有的用户放在informix组中。<br /><br />      如何知道数据库应用使用CPU的时间？<br /><br />      通常在UNIX下面，可以使用time命令来得出一个进程说所占用的CPU的时间：<br /><br />      $ /bin/time test.4ge<br /><br />      real 9.0<br /><br />      user 1.6<br /><br />      sys .14<br /><br />      在这里，1.6＋1.4 就是程序test.4ge所消耗的所有的CPU的时间。而“real”在这里不是特别重要。<br /><br />      然而在informix的环境中，time命令忽略了一个重要的方面，sqlturbo(数据库引擎）所使用的CPU时间。而且，如果你在一个应用程序中使用一个RUN语句，还要增加命令被RUN语句触发的时间。<br /><br />      一些操作系统(SCO Unix, Unix SVR4) 有一个叫做<i>'</i>timex的命令，使用这个命令可以获得进程和其子进程所使用的CPU时间，在使用timex命令之前必须先打开记帐功能。<br /><br />      要打开记帐功能，首先用root用户登录系统，然后运行：<br /><br />      OS      COMMAND <br /><br />      --------   ------------------------------------- <br /><br />      SCO Unix   $ /usr/lib/acct/accton /usr/adm/pacct <br /><br />      Unix SVR4   $ /usr/lib/acct/accton /var/adm/pacct <br /><br />      Others OS   $ man acct <br /><br />       当记帐功能打开之后，你就可以执行timex命令。使用-p选项（可以获得子进程使用的CPU时间）。<br /><br />      $ timex -p fglgo test.4gi<br /><br />       ******** <br /><br />      COMMAND       RT  END   REAL  * CPU * CHARS   BLOCKS <br /><br />      NAME USER TTYNAME  TIME TIME  (SECS) *(SECS)*TRNSFD   R/W <br /><br />      fglgo ignacio ttyp0 17:35:05 17:35:05 0.59 * 3.02 * 26256 9 <br /><br />      #sqlturbo ignacio ttyp0 17:35:05 17:35:05 0.56 * 4.26 * 32248 12 <br /><br />      ******** <br /><br />      ‘timex<i>'</i>输出了两条记录，一条是应用程序本身，一条是sqlturbo所占用的CPU时间。如果在应用中使用了RUN语句，<i>'</i>timex<i>'</i>中还会有第三条记录包括run语句触发命令的时间。<br /><br />      为了获得整个CPU的使用时间，你必须将各个CPU字段中的时间加起来。<br /><br />      Total_CPU_time = fglgo_time + sqlturbo_time = 3.02 secs + 4.26 secs ==&gt; <br /><br />        Total_CPU_time = 7.28 secs <br /><br />      通常在想比较程序的两个不同版本的执行时间的时候可以使用timex。如果你要使用4GL程序（可能使用一条insert语句，或者提交一些存储过程），<i>'</i>timex<i>'</i>会告诉你哪个版本更好。而，当你可以根据CHARS TRNSFD字段来判断应用程序和sqlturbo之间 数据交换的频繁程度。<br /><br />      使用ISQL/DBACCESS来进行SELECT语句优化需要注意哪些事项？<br /><br />      当你使用ISQL/DBACCESS等工具来进行select语句的设计和优化的时候，请确认在你运行这个select语句的时候，将select <br /><br />        语句的输出定向到/dev/null文件中去。因为如果将ISQL/DBACCESS的输出到屏幕的时候，一次只输出一屏的数据，因此会造成时间上的延续。<br /><br />      如何知道一个database存储在哪个dbspace上面？<br /><br />      申明：如果使用create table ... in dbspace....语句，即使用数据分片，下面的的方法也许不会有用，但是大多少情况下都是可以用的：<br /><br />      对sysmaster表使用以下的语句：<br /><br />      select b.dbsname, a.name <br /><br />      from sysdbspaces a, systabnames b<br /><br />       where a.dbsnum= partdbsnum(b.partnum) <br /><br />      and b.tabname=<i>"</i>systables<i>"</i> and b.dbsname=<i>"</i>yourdbname<i>"</i> <br /><br />             在7.x以上的版本，可以用：<br /><br />      SELECT DBINFO(<i>"</i>DBSPACE<i>"</i>, HEX(partnum))<br /><br />       FROM systables WHERE tabname = <i>"</i>systables<i>"</i> <br /><br />      On 5.x instances, try: SELECT HEX(partnum) <br /><br />      FROM systables WHERE tabname = <i>"</i>systables<i>"</i> <br /><br />      在输出的最开始的两个字符（在0x的后面）可以看到chunk号， 通过这个chunk号，可以用onstat -d来获得dbspaces的名称。<br /><br />      如何找出数据库中使用的磁盘I/O最多的哪些线索？<br /><br />      在sysmaster数据库中运行以下的sql语句：<br /><br />      SELECT p.sid, username, tty, seqscans, dsksorts, <br /><br />      total_sorts from syssesprof p, syssessions s <br /><br />      WHERE p.sid = s.sid; <br /><br />      装载数据的时候如何清除掉重复的记录？<br /><br />      假设使用的是informix 7.22版本：执行如下的语句：<br /><br />      SET INDEXES idx_name DISABLED; <br /><br />      START VIOLATIONS TABLE FOR tab_name;<br /><br />       SET INDEXES idx_name ENABLED even better, <br /><br />      SET INDEXES idx_name FILTERING WITHOUT ERROR <br /><br />      然后装载数据<br /><br />      所有的重复的数据都将被放到violation和diagnositc表中，然后你就可以通过在violation表中调试哪些错误的记录，然后再将它们插入到主表中去。<br /><br />      为什么使用High Performance Loader装载数据的时候没有错误信息？<br /><br />      检查violation表，如果你没有特意对其命名的话，这些表的名称都是table_vio<br /><br />      和table_dia。在vio表中是出错记录，在dia表中是产生这些错误的原因。你可以使用tuple_id字段将两个表连接起来，并在HPL手册中查找出错的原因。<br /><br />      如何使用SMI表来查找一个表所占用的磁盘空间的大小？<br /><br />      执行以下sql语句：<br /><br />      select s.name dbspace, n.dbsname database, <br /><br />      sum(ti_nptotal) total, sum(ti_npused) used, <br /><br />      sum(ti_npdata) data, sum(ti_npused) - sum(ti_npdata) idx <br /><br />      from systabinfo i,systabnames n, sysdbspaces s <br /><br />      where i.ti_partnum = n.partnum and partdbsnum(i.ti_partnum)=s.dbsnum <br /><br />         group by 1,2 <br /><br />      order by 1,2        <br /><br />      如何在UNIX上存取NT上面的数据库？<br /><br />      UNIX系统之间可以通过设置.rhosts和hosts,equiv文件来实现UNIX系统之间存储数据库，而在NT下面将hosts.equiv文件放在c:\winnt\system32\drivers\etc下面即可。<br /><br />      如何判断数据库性能变差是由于网络的原因？<br /><br />      很多性能的问题是由于网络引起的，包括网络硬件故障和网络设置的问题。要确认是否存在网络方面的问题，可以在服务器上执行以下几个命令：<br /><br />      arp -a<br /><br />      netstat -r<br /><br />      如果这执行这两个命令后的输出不正常，就可以判定网络存在问题。当arp -a 命令的输出发生暂停，并且显示一个IP地址，你就可以找到故障发生的节点（这并不能说明这个节点本身有问题）。当netstat -r的输出发生暂停，可能存在路由方面的问题，如果需要，可以用“snoop”命令来进行进一步的检查，直到找到问题的根源。<br /><br />       如何启动KAIO（异步IO)<br /><br />      KAIO (Kernel Asyncronous I/O) 是informix7.x的一个特征，大多数的平台都支持这种特征，<br /><br />      假设：<br /><br />      1）你的平台支持这个功能（检查$INFORMIXDIR/release版本中的内容看看是否你的平台支持KAIO)<br /><br />      2)你使用的是裸分区<br /><br />      以下是一些UNIX系统启动KAIO的步骤：<br /><br />      HP-UX：<br /><br />      1.关闭online<br /><br />      2.安装特殊的设备驱动程序<br /><br />     进入SAM  kernel cfg; drivers; select asyncdsk; actions; add driver to <br /><br />        kernel; create a new kernel; move kernel into place and continue shutdown <br /><br />        [reboot] now... <br /><br />      3.创建特殊的异步设备文件<br /><br />      mknod /dev/async c 101 1 <br /><br />      4.临时设置KAIO环境变量。这个变量需要在启动脚本中进行设置：<br /><br />      export KAIOON=1 <br /><br />      5.启动online<br /><br />      6.检查KAIO线索<br /><br />      使用命令onstat -g ath<br /><br />             AIX 4.1.5 <br /><br />      /usr/sbin/mkdev -l aio0 <br /><br />      你必须在每次系统启动的时候作这些工作，或者将其放在/etc/inittab文件中：<br /><br />      kaio:2:wait:/usr/sbin/mkdev -l aio0        <br /><br />      如何使用onbar对一个dbspace进行在线的热恢复<br /><br />      export ARCHIVE_TEST=true        <br /><br />      使用onstat -d 来选择一个你想要将其标记为down的chunk,并且找到其对应的dbspace名<br /><br />      onmode -o <i>'</i>chunk number<i>'</i>; - 对每个被标记为down状态的chunk执行这个操作<br /><br />      onmode -O ：让down掉的dbspaces不会堵塞checkpoints的发生，－回答‘YES’会将发生I/O错误的          dbspaces变为不可用状态，并且要求从归档数据中恢复这个dbspace。<br /><br />      onbar -r <i>'</i>dbspace name<i>'</i><br /><br />      哪些查询只能使用单线索（不能并行化）？      <br /><br />        查询中不包含任何“并行”操作（扫描，连接，集合，分组）。<br /><br />        查询使用CURSOR STABILITY ISOLATION LEVEL优化。<br /><br />        查询使用光标，如cursor FOR UPDATE or WITH HOLD <br /><br />        查询中包含有SPL调用。<br /><br />      如何加速排序和创建索引的速度？<br /><br />      对于大的排序操作象创建索引和更新统计信息，将环境变量PSORT_DBTEMP 尽可能的设置为较大的值（最少为3，记住这个最小值可能会限制排序数据的大小）。同时，，设置PSORT_NPROCS 为一个20到40之间的一个值也会加快排序的速度，只要你可以为一个任务分配足够多的资源。这样作可能会为你节约15或者20分钟的排序时间。<br /><br />      可以将ontape输出到一个磁盘的文件中吗？<br /><br />      informix支持将ontape输出到一个文件中。<br /><br />      然而，因为ontape默认是输出到磁带设备上，并且所有的动作都是以此为基础的。你有“责任”做所有的这些事情来满足程序的需求。（如模拟一个压缩操作，当磁带满的时候换带。处理倒带操作，逻辑日志的输出和溢出等等）你可以在互联网上informix用户组站点（<img src="http://unix-cd.com/unixcd12/skin/skin_1/small/url.gif" align="absMiddle" border="0" /><a href="http://www.iiug.org/" target="_blank"><font color="#002c99">http://www.iiug.org</font></a>）上找到一些shell 脚本可以用来来模拟以上的功能。<br /><br />      输出文件的大小的能够到达多大而不会出错，这个大小高度依赖操作系统和ontape的版本。在Informix Dynamic Server versions 7.2以前的版本，ontape支持的文件不能超过2GB。在7.2以上的版本中，这个限制来自操作系统，一般还是2GB，编写写一个程序，当磁盘文件的大小快要到达2GB的时候就交换到另外一个文件，让ontape认为是正在换带，这并不是特别难。当然，挑战来自为这些文件作标记，并且让它们在ontape进行数据恢复的时候能够以正确的顺序来读取这些文件。<br /><br />      如果是“关键”的系统，你必须要“彻底”测试归档和恢复功能是否能够正常进行。并且保存好磁盘的规划信息，详细做好文档记录，让除你之外的其它人根据这些文档就可以处理灾难发生时候的数据恢复。<br /><br /> <br /><br /> <br /><br />一四　INFORMIX-OnLine故障诊断与排除<br /><br /> <br /><br />1）系统不能进入静态方式<br /><br />      开放系统以其无与伦比的能力连接不同的计算机软件，硬件。在这种环境下，诊断问题时就需要关注问题的全局与细节。本文就如果诊断INFORMIX-Online的问题给出了良好的建议。<br /><br />      诊断问题的症状<br /><br />      系统管理员诊断问题时首先要定义问题的症状。      <br /><br />        系统是否难于进入静态（quiescent)状态？            <br /><br />        是否有非正常结束的INFORMIX系统进程？            <br /><br />        系统进程是否定期挂起？      <br /><br />      下面的讨论指出如何定位系统问题，讨论可能的起因，并对这些问题的解决提出建议。       <br /><br />      系统不能进入静态方式<br /><br />         该症状常常伴有一条错误信息。一般错误是：<br /><br />      tbinit:fatal error in shared memory creation (共享内存生成时有严重错误）<br /><br />      检查系统初始化时定义的系统日志文件来发现错误的出处。该日志的缺省名为$INFORMIXDIR/online.log。在此文件中会看到与下面相近的信息：<br /><br />      16:00:56 Cannot Open Primary Chunk <i>'</i>/dev/turbo_root<i>'</i>,errno = 13<br /><br />        16:00:56 Cannot Open Primary Chunk <i>'</i>/dev/turbo_root<i>'</i>,errno = 13<br /><br />        16:00:56 I/O error,Primary Chunk <i>'</i>dev/turbo_root<i>'</i> -- Offline<br /><br />        16:00:56 I/O lseek() chunk 1,pagenum 0, pagecnt 1 --&gt;errno =9<br /><br />        16:00:56 INFORMIX-Online Stopped<br /><br />      这些错误是由UNIX权限问题造成的。OnLine产品需要由root来安装。系统的部分可执行程序应属于root或者root有权限。所有INFORMIX系统文件的属主及权限都应该记录在$INFORMIXDIR/etc/onlinefiles中。检查所有OnLine文件权限，属主，属组是否正确。<br /><br />      也应检查chunk的权限，保证CHUNK有UNIX权限660(crw-rw----)，其属主，属组为informix,建议管理员使用系统管理员实用程序tbmonitor定义OnLine系统配置。初始化例程自动进行权限检查，计算可利用的磁盘空间，但如果配置文件是直接修改的，就并非如此了。<br /><br />      如果系统日志文件中并未记录有用的错误信息，而OnLine系统刚刚升级，则应检查确认页大小（与OnLine产品一道发送的缺省配置文件中定义）是否已经改变。若页大小变化了，就必须从老系统输出的数据（dbexport）再将数据输入到新系统上去（用dbimport)。       <br /><br />      错误tbinit:fatal error in shared memory creation 经常伴有操作系统错误或者附加的OnLine错误。这也能用来判定问题为什么会发生。下列错误说明为何共享内存不能生成。      <br /><br />        tbinit:shmget[EEXIT][17]:            <br /><br />         tbinit:shmget[EINVAL][22]:   <br /><br />        tbinit shmat[EINVAL][22]:                  <br /><br />        tbinit shmget[ENOSPC][28]:<br /><br />        Bad Primary Chunk <i>'</i>/dev/devname<i>'</i>                  <br /><br />        tbinit:shmget[EEXIST][17]:             <br /><br />      tbinit:shmget[EEXIT][17]:<br /><br />      这个错误表明共享内存段在申请的内存位置上已经存在。tbinit进程从环境变量TBCONFIG指定的文件读取配置。若TBCONFIG未指定，tbinit从$INFORMIXDIR/etc/tbconfig文件读取配置。一旦获取配置信息，tbinit派生一个子进程，它将成为tbinit后台进程。tbinit后台进程用唯一的SERVERNUM值做一部分输入值来计算共享内存键值，唯一的SERVERNUM值确保每个OnLine系统生成自己特定的共享内存空间。仔细检查以保证文件配置正确，SERVERNUM的值唯一。       <br /><br />      tbinit:shmget [EINVAL][22]:or tbinit:shmat[EINVAL][22]<br /><br />      当无效参数传递给UNIX调用时，UNIX产生错误。用OnLine术语来说这意味着tbinit申请的共享内存未被分配。一旦UNIX接受SERVERNUM和共享内存键值，tbinit便可将Online共享内存段附加在它的虚拟地址空间上。虚拟地址，共享内存段要附加的tbinit（或其他的用户进程）的内存空间是由SHMBASE定义的。若SHMBASE的值不合法，或申请共享内存大于共享内存核心参数允许的值时，或共享内存段由于边界对齐问题而无法连续分配时，UNIX会认为传给共享内存附加调用的内存值是无效的。<br /><br />      现在对UNIX核心参数作一回顾，以下描述的时有关共享内存配置的参数。      <br /><br />      核心参数<br /><br />      SHMSIZE 是操作系统范围内共享内存段的最大值（以k为单位）。<br /><br />      SHMMAX 是操作系统范围内共享内存段的最大值（以字节为单位）。<br /><br />      SHMMIN 是操作系统范围内共享内存段的最小值（以字节为单位）。<br /><br />      SHMMNI 是操作系统范围内共享内存标识的最小数值。<br /><br />      SHMLBA 是共享内存低段地址，也就是附加共享内存的边界地址<br /><br />      SHMSEG 是每个进程附加共享内存段的最大数目。<br /><br />      SHMALL 时系统范围内共享内存的最大量。<br /><br />      信号灯分配参数<br /><br />      SEMMNI 是操作系统范围内信号灯标识的最大值<br /><br />      SEMMNS 是操作系统范围内信号灯的最大值<br /><br />      SEMMSL 是每个标识信号灯的最大值。       <br /><br />      参数值的定义<br /><br />      SHMALL*操作系统页大小＝全部可能的共享内存（以字节为单位）。<br /><br />      SHMMAX=SHMSIZE*1024.<br /><br />      SHMMNI*SHMMAX=操作系统范围内可编址的共享内存（以字节为单位）。<br /><br />      SHMSEG*SHMMAX=一个操作系统进程可编址的共享内存（以字节为单位）。      <br /><br />      参数设置指导：<br /><br />      规则1 SHMALL * 页大小 &gt;= SHMSEG * SHMMAX<br /><br />      规则2 SHMALL * 页大小 ＝ SHMNI * SHMMAX<br /><br />      规则3 SHMMSL = 主机用户进程数/25<br /><br />      规则4 SHMMAX &gt; SHMLBA<br /><br />      tbinit: shmget[ENOSPC][28]:<br /><br />      当系统申请空间，而设备已满时，UNIX产生该错误。UNIX申请共享内存的交换区，保证交换空间驻留的设备上有足够的空间。没有足够的共享内存ID时也会发生错误，检查系统SHMMNI核心参数。       <br /><br />      Bad Primary Chunk <i>'</i>/dev/devname<i>'</i><br /><br />      由于控制器，硬件或者权限问题，使得向chunk写失败时，Online标记该chunk为down，这样做的目的是为了通知管理员数据完整性已经被破坏，检查系统日志文件中I/O错误。以下是典型的硬件I/O错误的例子：<br /><br />      I/O error,Primary Chunk <i>'</i>/dev/rdsk/devname<i>'</i> -- Offline<br /><br />      I/O read(),Chunk 2,pagenum 272714,pagecnt 1 --&gt;errno =5<br /><br />      I/O write() chunk 2,pagenum 2,pagecnt 1 --&gt; errno = 5<br /><br />      发生I/O错误时，检查控制器和硬件。许多UNIX系统提供检查未安装原始设备的低级别实用程序，不要在未安装的原始设备上使用fsck命令，这是因为fsck会覆盖设备上存储的信息，为恢复系统，INFORMIX建议管理员恢复最后的存档，用日志恢复失败了的写操作。<br /><br />      一旦共享内存初始化完成，物理日志从上一次检查点开始检查物理日志的前象，如果该记录存在，开始FAST RECOVERY,进入物理恢复，每个前映象写回到磁盘上正确的位置上，一旦完成后，逻辑恢复开始，并处理上次检查点之后逻辑日志中记录所对应的事务，如果快速恢复非正常结束，或是不能让OnLine进入静态（Quiescent)方式，则让OnLine进入脱机（off-line)方式，再启动OnLine。若OnLiner仍不能进入静态方式，则应该恢复系统存档。 <br /><br />2）　　OnLine非正常结束<br /><br />            OnLine非正常结束时，描述有关OnLine进入脱机方式原因的信息将写入日志，下面时OnLine结束时系统日志中登陆日志的示例：      <br /><br />      Process Aborted Abnormally: pid=22500 user=210 us=c003f15c flags=a01      <br /><br />      Process Aborted Abnormally (critial section):pid=22500 user=210 flag=a01<br /><br />      INFORMIX-OnLine entering ABORT mode!!! INFORMIX-OnLine Stopped       <br /><br />      日志条目显示一个进入临界状态的sqlturbo进程非正常结束，临界状态是指一个进程执行写调用而不能被中断所用的术语。如果一个进程处于临界状态时非正常结束，OnLine为保护数据完整性而进入脱机方式。当OnLine重新启动时会执行快速恢复，回滚所有未完成的事务。<br /><br />      如果持有锁存器（latch)的进程非正常结束，OnLine也会非正常结束。锁存器用于控制对诸如缓冲区，锁定表等共享内存资源的访问。为防止干涉其它进程申请共享内存资源，INFORMIX OnLine控制对有锁存器的资源表的访问。<br /><br />      虽然OnLine后台进程对夭折的进程进行日常的清理工作，但数据一致性阻止后台进程在清除过程中释放共享内存锁存器。对后台进程来说，判断用户进程是否完成对数据库的修改是不可能的。为解脱这以一困境，OnLine强制自己进入脱机方式。当OnLine回到联机（Online)方式时，自动进行快速恢复。快速恢复使OnLine达到与最后一个完成事务一致的状态。<br /><br />      当持有锁存器的进程结束时，会生成以下的条目：<br /><br />      Process Aborted Abnormally: pid=10743 user=104 us=60204c flags=21<br /><br />      Process Aborted Abnormally (latch): pid=10743 user=104 flags=21<br /><br />      INFORMIX-OnLine entering ABORT MODE!!!<br /><br />      -- OnLine Aborting -- us=6019a8,pid=11987,uid=1000<br /><br />      这些日志条目提供的信息在判定进程为何非正常结束时十分有用，条目中各域的定义如下：<br /><br />      pid---------sqlturbo UNIX进程id<br /><br />      user--------真正用户id<br /><br />      us----------共享内存中用户结构的地址<br /><br />      flags-------定义如下<br /><br />      0x0000001------0x0000001 正在使用的用户结构<br /><br />      0x0000002------0x0000002 等待锁存器<br /><br />      0x0000004------0x0000004 等待锁<br /><br />      0x0000008------0x0000008 等待缓冲区<br /><br />      0x0000010------0x0000010 等待检查点<br /><br />      0x0000020------0x0000020 等待读取调用<br /><br />      0x0000040------0x0000040 向存档磁道写逻辑日志<br /><br />      0x0000080 等待清除长事务<br /><br />      0x0000100------0x0000080 特定turbo检测用户<br /><br />      0x0000200 处于事务中<br /><br />      0x0000400 进程在回滚<br /><br />      0x0000800------0x0000100 处于临界状态的进程继续...<br /><br />      0x0001000------0x0000200 特定的后台进程<br /><br />      0x0002000 开始工作日志登记<br /><br />      0x0004000------0x0000400 存档<br /><br />      0x0008000------0x0000800 清除死进程<br /><br />      0x0020000------0x00002000 特定缓冲区刷新进程<br /><br />      0x0010000------0x0002000 等待逻辑缓冲区写入<br /><br />      0x0040000------0x0004000 该进程是远程服务器<br /><br />      0x0080000 该进程正完成远程任务<br /><br />      0x0100000------0x0008000死锁超时<br /><br />      -----------0x00010000-----普通锁超时<br /><br />      -----------0x00020000-----超时等待期已结束<br /><br />      -----------0x00040000-----等待事务<br /><br />         以上的日志条目中,sqlturbo进程的UNIX进程id为10743，真正用户id为104，共享内存中用户结构的地址为0x60204c,标志显示用户结构正在使用中，OnLine引擎正处于读取调用之中（0x00000001,&amp;0x00000020)。<br /><br />      这个信息可以标识非正常结束的用户，查明他或她是否遇到意外的错误，或以某种方式导致进程的非正常结束。用户不应对Informix进程使用kill -9命令。管理员可以用onmode -z pid命令中止某一个sqlturbo线索。如果进程正持有锁存器或处于临界状态，tbmode命令不会立即中止该进程。<br /><br />3）　OnLine进程似乎被挂起<br /><br />         当OnLine用户抱怨他们的进程被挂起，或者不能与OnLine相互作用时，运行onstat -a ,获得有关问题的本质信息。onstat是OnLine提供的实用程序，是用来监视系统的命令。它提供了与tb_Monitor（onmonitor)实用程序相近的，但更为详尽的统计数字。<br /><br />      OnLine挂起的最明显的原因时逻辑日志已充满而且需要备份。在tbstat输出中检查逻辑日志的状态。在逻辑日志填满后备份日志，就会让OnLine继续处理事务。<br /><br />      进程必须等待检查点完成。检查点请求可以阻止进程进入临界状态或者获得锁存器资源。onstat显示的第1行为状态行，它会显示是否申请了检查点。如果条件成立，有可能是检查点在等待资源。检查用户结构下的等待队列来找出资源的地址。一旦定位到资源，判定拥有该资源的用户进程状态。已经进入临界状态，或是持有锁存器资源的进程可以阻止检查点的完成。例如，存档进程在磁带改换期间一直持有一个锁存器，并禁止检查点的发生。      <br /><br />      帮助诊断问题的实用程序    <br /><br />          实用程序名<br /><br />          目的<br /><br />          描述<br /><br />          使用        <br /><br />          dbexport<br /><br />          卸成ascii文件<br /><br />          把数据库卸到磁盘或磁带上，生成包含表结构的数据库.sql文件。结构并不包含extent大小<br /><br />          数据库移植到其它平台                <br /><br />          dbimport<br /><br />          加载ascii文件<br /><br />          从dbexport生成的数据库结构及ascii数据，生成并加载数据库，直接由磁盘或磁带加载。<br /><br />          由其它平台输入数据 <br /><br />          tbunload<br /><br />          卸成二进制文件<br /><br />          将数据库或表的数据影象，卸到磁盘或磁带上，用于页大小，机器结构相同的OnLine系统<br /><br />          高效的，真正二进制方式卸数据 <br /><br />          tbload<br /><br />          由二进制文件加载<br /><br />          由tbunload生成的磁带加载数据库或表<br /><br />          高效的，数据库数据加载方式 <br /><br />          tbinit<br /><br />          管理<br /><br />          初始化共享内存，启动共享内存后台进程<br /><br />          tbmonitor命令行 <br /><br />          tbmode<br /><br />          管理<br /><br />          使OnLine脱机或联机，中止OnLine进程<br /><br />          tbmonitor命令行 <br /><br />          tbmonitor<br /><br />          管理<br /><br />          由管理员来开启OnLine系统，报告OnLine系统状态，执行存档，恢复备份逻辑日志，改变系统状态<br /><br />          交互式全功能管理程序 <br /><br />          tbparams<br /><br />          管理<br /><br />          由管理员用来增加或删除逻辑日志，改变物理日志的大小及位置<br /><br />          tbmonitor命令行 <br /><br />          tbspaces<br /><br />          管理<br /><br />          由管理员用来增加或删除dbspace或blobspace,为它们增加chunk,改变状态<br /><br />          tbmonitor命令行                 <br /><br />          tbstat<br /><br />          系统检测员<br /><br />          提供有关OnLine状态，共享内存资源的详细信息<br /><br />          报告/debug工具                 <br /><br />          tbtape<br /><br />          管理<br /><br />          在磁带上作系统存档，或备份逻辑日志<br /><br />          tbmonitor命令行                 <br /><br />          tblog<br /><br />          系统检测员<br /><br />          提供有关逻辑日志条目的详细信息<br /><br />          报告/debug工具                 <br /><br />          tbcheck<br /><br />          系统检测员<br /><br />          报告并检查OnLine系统完整性，执行数据，索引页，extent，位图页的低级别检测，提供有关保留页，extent和系统信息<br /><br />          报告/debug工具<br /><br />     <br /><br /> <br /><br />一五　监视Informix-Online动态服务器<br /><br />                                         <br /><br />        onstat 和oncheck实用工具                        <br /><br />        onperf实用工具         <br /><br />      什么是信息日志       <br /><br />      online信息日志是一个操作系统的文件。在Online信息日志中包括的信息通常不需要立刻进行处理。通过设置ONCONFIG文件中MSGPATH的值，你可以指定信息日志的路径名。为了得到OnLine信息日志的名字和20条最新的记录，应执行onstat -m命令。<br /><br />      利用ON-Monitor监视<br /><br />      ON-Monitor提供了一个全面监视Online的简单方法。大多数监视功能在Status菜单下都是可用的。       <br /><br />      利用SMI表监视<br /><br />      系统监视界面(SMI)表是OnLine管理的专用表。它包含了有关数据库服务器状态的动态信息。你可以对它们使用SELECT语句来决定你想要了解有关数据库服务器的几乎任何事情。      <br /><br />      利用onstat和oncheck实用工具监视<br /><br />      onstat 和oncheck提供了一种从命令行监视OnLine信息的方法。       <br /><br />      onstat 与oncheck的比较<br /><br />      onstat 实用工具从共享内存读数据并报告在命令执行期间内的精确统计结果。也就是说，onstat描述在处理期间动态改变的信息，如缓冲区，锁和用户的情况。<br /><br />      oncheck实用工具主要倾向于显示配置和磁盘的使用信息，这些信息驻留在磁盘上，而且变化较少。       <br /><br />      使用onperf监视<br /><br />      onLine包括称为onperf图形监视工具。这个工具能够 <br /><br />        监视onstat提供的大多数信息。<br /><br />      下面介绍使用命令行实用工具onstat<br /><br />      onstat -c oncheck -pr   　　检查配置信息<br /><br />     onstat -m;onstat -p   　　　 检查检查点信息      <br /><br />      onstat -g seg        　　　 监视共享内存段       <br /><br />      onstat -p:                 可获得有关被高速缓冲的读写的统计信息。包括：                    <br /><br />                      从共享内存缓冲区读的数目（bufreads）,<br /><br />                      从高速缓存读的百分比（%cached）<br /><br />                      写共享内存的数目(bufwrits)<br /><br />                      向高速缓存写的百分比（%cached）                      <br /><br />      onstat -B：         可获得下面的缓冲区信息:         <br /><br />                      每个普通共享内存缓冲区的地址<br /><br />                      当前共享内存中的所有内存页的页号<br /><br />                      当前占有缓冲区的线程的地址<br /><br />                      等待各缓冲区的第一个线程的地址        <br /><br />      onstat -b：        可获得下面各个缓冲区上的信息:         <br /><br />                      当前占用各缓冲区的线索的地址<br /><br />                      缓冲区中页的页号<br /><br />                      缓冲区中页的类型<br /><br />                      缓冲区设置锁定的类型<br /><br />                      当前占用缓冲区的线程的地址<br /><br />                      等待各缓冲区的第一个线程的地址<br /><br />      你可以把用户线程的地址与在onstat -u显示中出现的地址进行比较，以获得会话id号。<br /><br />      onstat -k:         显示有关活动的锁定信息。 <br /><br />                      产生锁定的用户线索<br /><br />                      锁的类型<br /><br />                      锁的范围<br /><br />         onstat -g glo    显示有关当前正在运行的各个虚处理机信息，以及各虚处理机类的累加信息（从系统启动开始）。<br /><br />      onstat -u       显示有关所有需要RSAM任务控制块结构的活动线程的信息。活动线程包括属于用户会话的线程，和一些相应的服务器daemons线索.还包括如下信息：      <br /><br />        各个线程的地址<br /><br />        标志出线索的当前状态<br /><br />        有关线程属于会话的会话id和用户登录id.为0的会话id表示daemon线程。<br /><br />        线程是否在等待特定的资源和该资源的地址<br /><br />        线程占用的锁的数目<br /><br />        线程已执行的读调用数和写调用数<br /><br />        自最近一次的OnLine初始化以来，分配出去的并发用户线索的最大数目<br /><br />      onstat -g ses       <br /><br />      可以监视分配一个线索的资源。<br /><br />      onstat -x：<br /><br />      显示关于每个打开事务的下列信息：        <br /><br />        事务在共享内存中的地址<br /><br />        事务的当前状态<br /><br />        事务处于什么阶段<br /><br />        事务的特征<br /><br />        拥有事务的线程<br /><br />        事务占用锁定的数量<br /><br />        记录begin work记录的逻辑日志文件<br /><br />        隔离级<br /><br />        试图开始恢复线程的数目<br /><br />        事务协调者<br /><br />        从你最近一次初始化OnLine到现在的并发事务的最大数      <br /><br />      onstat -g sql       <br /><br />      获得有关各个线索执行最后的sql语句的摘要信息。<br /><br />      onstat -l       <br /><br />      显示物理日志信息,逻辑日志信息和单个的逻辑日志文件上的信息，包括：      <br /><br />        逻辑日志文件描述符的地址<br /><br />        逻辑日志文件的Logid号<br /><br />        指示各个日志状态的状态标记.<br /><br />        日志文件的唯一id<br /><br />        文件的起始页<br /><br />        文件大小(以页为单位),已使用的页面数,以及已使用的页面所占的比率<br /><br />      onstat -d       <br /><br />      列出所有的dbspaces和blobspaces,以及在这些空间中的所有大块和相关的信息。      <br /><br />        可提供的大块信息有：<br /><br />        大块地址<br /><br />        大块号和相关联的dbspace号<br /><br />        在设备中的偏移量(单位是页面)<br /><br />        大块尺寸<br /><br />        大块内可用页的数量<br /><br />        可用blobspace大致数量<br /><br />        物理设备的路径名                   <br /><br />      onstat -g iof       <br /><br />      显示从个大块中读的数量和写入各大块的数量.如果一大块具有相对很大数量的I/O活动,<br /><br />      这一大块可能正成为系统瓶颈。此选项有助于监视对于经过分片的表的不同分段的I/O需求的分布是否均衡。<br /><br />      Oncheck -pe       <br /><br />      可得到大块信息的物理布局<br /><br />       Dbspace 名，所有者，以及dbspace的建立日期 <br /><br />      大块的页大小（以页为单位），使用的页数量和可用页的数量<br /><br />      大块内的所有表以及它们的初始页号，以页数为单位的表长度的列表<br /><br />      oncheck -pt       <br /><br />      可执行带有数据库名和表名参数的oncheck -pt命令来获得下列数据库或表中各个tblspace的信息范围数量<br /><br />      第一个范围的大小<br /><br />      下一个范围的大小<br /><br />      分配的页数<br /><br />      使用的页数<br /><br />      oncheck -pB       <br /><br />      可执行带有作为参数的数据库名或表名的oncheck -pB命令。<br /><br />      在所有的blobspaces中该表或数据库使用blob页的数量<br /><br />      该表或数据库中的各个blob,blobpage的满程度<br /><br />      监视数据复制状态       <br /><br />      可监视OnLine数据库服务器的数据复制状态，来确定下列信息：      <br /><br />        数据库服务器类型（主要的，从属的，或标准的）<br /><br />        其它配对数据库服务器的名字<br /><br />        数据复制是否在运行<br /><br />        数据复制参数的值      <br /><br />      onstat -g dri       <br /><br />      可得到整个数据复制的监视信息。            <br /><br />        数据库服务器类型<br /><br />        数据复制状态（开，或关）<br /><br />        配对的数据库服务器<br /><br />        最新的数据复制检查点<br /><br />        数据复制配置参数值  <br /><br /> <br /><br /> <br /><br />附录：<br /><br />    主要SQL语句详解<br /><br />CREATE DATABASE database_name [WITH LOG IN “pathname”]<br /><br /> <br /><br />创建数据库。<br /><br />database_name：数据库名称。<br /><br /> “pathname”：事务处理日志文件。<br /><br /> 创建一database_name.dbs目录，存取权限由GRANT设定，无日志文件就不能使用<br /><br /> BEGIN WORK等事务语句（可用START DATABASE语句来改变）。<br /><br /> 可选定当前数据库的日志文件。<br /><br />如：select dirpath form systables where tabtype = “L”;<br /><br /> 例：create databse customerdb with log in “/usr/john/log/customer.log”;<br /><br /> DATABASE databse-name [EXCLUSIVE] <br /><br />选择数据库。<br /><br />database_name：数据库名称。<br /><br /> EXCLUSIVE：独占状态。<br /><br /> 存取当前目录和DBPATH中指定的目录下的数据库，事务中处理过程中不要使用此语句。<br /><br /> 例：dtabase customerdb;<br /><br /> CLOSE DATABASE <br /><br />关闭当前数据库。<br /><br />database_name：数据库名称。<br /><br /> 此语句之后，只有下列语句合法：<br /><br />CREATE DATABASE； DATABASE； DROP DATABSE； ROLLFORWARD DATABASE；<br /><br /> 删除数据库前必须使用此语句。<br /><br />例：close database;<br /><br /> DROP DATABASE database_name <br /><br />删除指定数据库。<br /><br />database_name：数据库名称。<br /><br /> 用户是DBA或所有表的拥有者；删除所有文件，但不包括数据库目录；不允许删除当前数据库（须先关闭当前数据库）；事务中处理过程中不能使用此语句，通过ROLLBACK WORK 也不可将数据库恢复。<br /><br /> 例：drop databse customerdb;<br /><br />CREATE [TEMP] TABLE table-name (column_name datatype [NOT NULL], …) <br /><br /> [IN “pathname”]<br /><br /> 创建表或临时表。<br /><br />table-name ：表名称。<br /><br /> column_name：字段名称。<br /><br /> data-type：字段数据类型。<br /><br /> path-name：指定表的存放位置<br /><br /> TEMP用于指定建立临时表；表名要唯一，字段要唯一；有CONNECT权限的用户可建立临时表；创建的表缺省允许CONNECT用户存取，但不可以ALTER。<br /><br /> 例：create table user<br /><br /> ( c0 serial not null, c1 char (10),<br /><br />  c2 char(2),<br /><br />  c3 smallint,<br /><br />  c4 decimal(6,3),<br /><br />  c5 date<br /><br /> ) in “usr/john/customer.dbs/user;<br /><br />ALTER TABLE <br /><br />ALTER TABLE table-name <br /><br /> {ADD (newcol_name newcol_type [BEFORE oldcol_name], …) | DROP (oldcol_name, …)<br /><br /> | MODIFY (oldcol_name newcol_type [NOT NULL], … )}, …<br /><br /> 修改表结构。<br /><br />table-name：表名称。<br /><br /> newcol_name：新字段名称<br /><br /> newcol_type：新字段类型<br /><br /> oldcol_name：老字段名称<br /><br /> 可以使用单个或多个ADD子句、DROP子句、MODIFY子句，但某个字句失败，操作即中止；原字段是NULL，不允许MODIFY为NOT NULL，除非所有NULL字段中均非空，反之可以；ALTER使用者是表的拥有者或拥有DBA权限，或被授权；事务中处理过程中不要使用此语句。<br /><br /> 例：alter table user<br /><br /> add ( c6 char(20) before c5);  <br /><br />RENAME TABLE oldname TO newname <br /><br />修改表名。<br /><br />oldname：原名称。<br /><br /> newname：新名称。<br /><br /> RENAME使用者是表的拥有者或拥有DBA权限，或被授权；事务中处理过程中不要使用此语句。<br /><br /> 例：rename user to bbb;<br /><br />DROP TABLE table-name <br /><br />删除表。<br /><br />table-name：表名称。<br /><br /> 删除表意味着删除其中所有数据、各字段上的索引及对表的赋权、视图等；用户不能删除任何系统目录表；语句使用者是表拥有者或拥有DBA权限，事务中处理过程中不要使用此语句。<br /><br />RENAME COLUMN table.oldcolumn， TO newcolumn <br /><br />修改字段名。<br /><br />table.oldcolumn：表名及原字段名称<br /><br /> newcolumn：新字段名称。<br /><br /> 语句使用者是表的拥有者或拥有DBA权限或有ALTER权限的用户，事务中处理过程中不要使用此语句。<br /><br /> 例：rename column user.c6 to c7;<br /><br />CREATE VIEW view-name column-list <br /><br />CREATE VIEW view-name column-list AS select_statement [WITH CHECK OPTION]<br /><br /> 创建视图。<br /><br />view-name：视图名称。<br /><br /> column-list：字段列表。<br /><br /> select_statement：SELECT语句。<br /><br /> 以下语句不使用视图：ALTER TABLE，DROP INDEX，ALTER INDEX，LOCK TABLE，CREATE INDEX， RENAME TABLE；视图将延用基表的字段名，对表达式等虚字段和多表间字段重名必须指明标识其字段名；若对视图中某些字段命名，则所有字段都必须命名；视图中数据类型延用基表中的数据类型，虚字段起诀于表达式；不能使用ORDER BY和UNION子句；对视图中所有的字段要有SELECT权限；事务中处理过程中使用此语句，即使事务回滚，视图也将建立，不能恢复。<br /><br /> 例：create view v_user as select * from user where c1 = “B1”;<br /><br /> DROP VIEW view-name <br /><br />删除视图。<br /><br />view-name：视图名称。<br /><br /> 用户可删除自己建立的视图；视图的后代视图也被删除；事务中处理中不要使用此语句。<br /><br />例：drop view v_user;<br /><br />CREATE INDEX  <br /><br />CREATE [UNIQUE/DISTINCT] [CLUSTER] INDEX index_name ON table_name<br /><br /> ([column_name ASC/DESC],…) <br /><br /> 创建索引。<br /><br />index_name：索引名称。<br /><br /> table_name：表名称。<br /><br /> column_name：字段名称。<br /><br /> UNIQUE/DISTINCT：唯一索引。<br /><br /> CLUSTER：使表的物理存放顺序按索引排列。<br /><br /> ASC/DESC：升序或降序，缺省升序。<br /><br /> 语句执行时，将表的状态置为EXCLUSIVE；复合索引最多包含8个字段，所有字段长度和不得大于120字节；事务中处理过程中使用此语句，即使事务回滚，索引将建立，不能恢复。<br /><br /> 例：create cluster index ix_user on user(c5);<br /><br />ALTER INDEX index-name TO [NOT] CLUSTER <br /><br />修改索引性质。<br /><br />index-name：索引名称。<br /><br /> TO [NOT] CLUSTER：去掉或加上CLUSTER属性。<br /><br /> 语句执行时，将表的状态置为EXCLUSIVE；事务中处理过程中使用此语句，即使事务回滚，索引性质将改变，不能恢复。<br /><br /> 例：alter index ix_user to not cluster;<br /><br />DROP INDEX index-name <br /><br />删除索引。<br /><br />index-name：索引名称。<br /><br /> 语句使用者是索引的拥有者或拥有DBA权限，事务中处理过程中不要使用此语句，否则事务无法恢复。<br /><br /> 例：drop index ix_user;<br /><br />CREATE SYNONYM synonym FOR table-name <br /><br />创建同义名。<br /><br />synonym：同义名<br /><br /> table-name：表名称<br /><br /> 数据库的创建者可以使用同义名；没有赋予同义名权限的用户不能使用同义名；同义名不能和表名相同；事务中处理过程中不要使用此语句。<br /><br />例：create synonym user_alias for user;<br /><br /> DROP SYNONYM synonym<br /><br />删除同义名。<br /><br />synonym：同义名<br /><br /> 可以删除自己建立的同义名；事务中处理过程中不要使用此语句，否则无法恢复。<br /><br />例：drop synonym user_alias;<br /><br /> UPDATE STATISTICS [FOR TABLE table-name]<br /><br /> 更新数据库的统计数字。<br /><br />table-name：表名称<br /><br /> 此语句仅作用于当前数据库；可提高查询效率；只有执行此语句，才改变统计数据。<br /><br />例：update statistics for table user;<br /><br />    主要SQL语句详解<br /><br />GRANT {DBA|RESOURCE|CONNECT} TO {PUBLIC|user-list}  授权命令。<br /><br /> PUBLIC|user-list：全部或指定的用户。<br /><br />  三种权限居且仅居其一，事务处理过程中不要执行GRANT语句。<br /><br />  例：grant resource to pulbic;<br /><br />   GRANT tab-privilege ON table-name TO {PUBLIC|user-list} [WITH GRANT OPTION]  <br /><br /> 授表级权限。<br /><br />  tab-privilege：表级权限。<br /><br />  table-name：表名称。<br /><br /> PUBLIC|user-list：全部或指定的用户。<br /><br /> [WITH GRANT OPTION]：表示被授权用户有否权限进行二次授权。<br /><br />  用户可以在自己建立表达式或被[WITH GRANT OPTION]准许的表中进行赋权；限定越多的权限优先级越高。<br /><br />  例：grant update(c1,c6) on user to dick with grant option;  <br /><br /> 附（INFORMIX的权限）<br /><br />  (1) 数据库的权限（控制对数据库的访问以及数据库中表的创建和删除）   <br /><br /> DBA权限：全部权利，修改系统表，建立和删除表与索引、增加和恢复表数据，以及授予其他用户数据库权限等；<br /><br /> RESOURCE权限：允许对数据库表中的数据进行存取，建立永久性表以及索引。<br /><br /> CONNECT权限：只允许对数据库表中的数据进行存取，建立和删除视图与临时表。<br /><br />  (2)表级权限（对表的建立、修改、检索和更新等权限）   <br /><br />  ALTER：更改权限<br /><br /> DELETE：删除权限<br /><br /> INDEX：索引权限<br /><br /> INSERT：插入权限<br /><br /> SELECT [(cols)]：指定字段或所有字段上的查询权限，不指明字段缺省为所有字段。<br /><br /> UPDATE [(cols)] ：指定字段或所有字段上的更新权限，不指明字段缺省为所有字段。<br /><br /> ALL [PRIVILEGES]：以上所有表级权限  <br /><br />     REVOKE {DBA|RESOURCE|CONNECT} FROM {PUBLIC|user-list} <br /><br /> 收权命令。<br /><br /> PUBLIC|user-list：全部或指定的用户。<br /><br />  三种权限居且仅居其一，事务处理过程中不要执行GRANT语句。<br /><br />  例：revoke resource from john;<br /><br /> REVOKE tab-privilege ON table-name FROM {PUBLIC|user-list} <br /><br /> 收表级权限。<br /><br />  tab-privilege：表级权限。<br /><br />  table-name：表名称。<br /><br /> PUBLIC|user-list：全部或指定的用户。<br /><br /> [WITH GRANT OPTION]：表示被授权用户有否权限进行二次授权。<br /><br />  用户只能取消由其本人赋予其他用户的表级存取权限；不能取消自己的权限，对SELECT和UPDATE作取消时，将取消所有表中字段的SELECT 和UPDATE权限。<br /><br />  例；revoke update on user from dick;<br /><br />    LOCK TABLE table-name IN {SHARE|EXCLUSIVE} MODE <br /><br /> 记录级加锁和表级加锁或文件加锁。<br /><br />  table-name：表名称。<br /><br /> SHARE：允许读表中数据，但不允许作任何修改<br /><br /> EXCLUSIVE：禁止其他任何形式访问表<br /><br />  每次只能对表琐定一次；事务处理过程中，BEGIN WORK后立即执行LOCK TABLE以取代记录级加锁，COMMIT WORK和ROLLBACK WORK语句取消所有对表的加锁；若没有事务处理，锁将保持到用户退出或执行UNLOCK为止。<br /><br />  例：lock table user in exclusive mode; <br /><br />  UNLOCK TABLE table-name <br /><br /> 取消记录级加锁和表级加锁或文件加锁。<br /><br />  table-name：表名称。<br /><br />  例：unlock user;  <br /><br />  SET LOCK MODE TO [NOT] WAIT <br /><br /> 改变锁定状态。<br /><br /> TO [NOT]：等待解锁，有可能被死锁或不等待并提示错误信息，表示此记录被锁，缺省值。<br /><br />  访问一个EXCLUSIVE状态下的记录，将返回一个错误。 <br /><br />  START DATABSE db_name [WITH LOG IN “pathname”] <br /><br /> 启动事务处理。<br /><br /> “pathname”：事务处理日志文件。<br /><br /> 执行该语句前，需要先关闭当前数据库。<br /><br /> 例；clost database;<br /><br />  start databse customer with log in “/usr/john/log/customer.log”;<br /><br />   BEGIN WORK <br /><br /> 开始事务。例：begin work;  <br /><br />  COMMIT WORK <br /><br /> 提交（正常结束）事务。例：commit work;   <br /><br />  ROLLBACK WORK <br /><br /> 回滚（非正常结束）事务。例：rollback work;   <br /><br />  SELECT  <br /><br />  SELECT select_list FROM tab_name|view_name <br /><br /> WHERE condition <br /><br /> GROUP BY column_name <br /><br /> HAVING condition <br /><br /> ORDER BY column_list <br /><br /> INTO TEMP table_name<br /><br /> 查询语句。<br /><br />  select_list：选择表或*<br /><br />  tab_name：表名称<br /><br />  view_name：视图名称。<br /><br />  condition：查询条件，可使用BETWEEN、IN、LIKE、IS NULL、LIKE、MATCHES、NOT、<br /><br />  AND、OR、=、!=或&lt;&gt;、&gt;、　&gt;= 、&lt;=、&lt;、ALL、ANY、SOME<br /><br />  column_name：分组字段名称<br /><br />  condition：群聚条件<br /><br />  column_list：排序字段列表，缺省ASC，可指定DSC；排序时，NULL值小于非零值。<br /><br />  table_name：临时表名称<br /><br /> 例：略<br /><br /> 附（常用函数）<br /><br /> (1)集合函数：<br /><br /> count(*)、<br /><br /> sum(数据项/表达式)、avg(数据项/表达式)、max(数据项/表达式)、min(数据项/表达式)<br /><br />  count(distinct 数据项/表达式)、sum(distinct数据项/表达式)、avg(distinct数据项/表达式)<br /><br /> (2)代数函数和三角函数<br /><br /> HEX(数据项/表达式)、ROUND(数据项/表达式)、TRUNC(数据项/表达式)、<br /><br /> TAN(数据项/表达式)、ABS(数据项/表达式)、MOD(被除数,除数)<br /><br /> (3)统计函数<br /><br />  标准差，stdev()、方差，variance()、范围，rang()<br /><br /> (4)时间函数<br /><br /> DAY(日期/时间表达式)：返回数字型<br /><br /> MONTH(日期/时间表达式)：返回整数<br /><br /> WEEKDAY(日期/时间表达式)：0&amp;#0;&amp;#0;6，0星期天，1星期一；返回整数<br /><br /> YEAR(日期/时间表达式)、返回整数<br /><br /> DATE(非日期表达式)：返回日期型<br /><br /> EXTEND(日期/时间表达式,[第一个至最后一个])：返回指定的整数<br /><br /> MDY(月,日,年)：返回日期型<br /><br /> CURRENT：返回日期型<br /><br />  (5)时间函数<br /><br /> ROUND()，四舍五入。如：ROUND(10.95,position)position进行四舍五入的前一位置<br /><br /> TRUNC()，截取。如：TRUNC(10.95,0)position截取的位置<br /><br /> INFORMIX临时表在下列情况下自动取消：<br /><br /> A.退出数据库访问工具（如DBACCESS）<br /><br /> B.SQL通话结束（DISCONNECT）<br /><br /> C.发出取消表语句<br /><br /> D.退出程序时  <br /><br />  INSERT    INSERT INTO view_name|table_name [(column_list)] <i>value</i>S (<i>value</i>_list)<br /><br />  或 INSERT INTO view_name|table_name [(column_list)] select_statement<br /><br /> 插入数据<br /><br />    view_name|table_name：视图名或表名称<br /><br />    column_list：数据项列表。<br /><br />    <i>value</i>_list：值列表<br /><br />    select_statement：查询语句。<br /><br /> 例：略  <br /><br />  DELETE FROM view_name|table_name WHERE search-conditions    删除语句。<br /><br />    view_name|table_name：视图名或表名称<br /><br />    search-conditions；删除条件<br /><br /> 例：略   <br /><br />  UPDATE   UPDATE view_name|table_name SET column_1 = <i>value</i>_1ist  WHERE search_conditions<br /><br /> 或UPDATE view_name|table_name SET column_1|* = <i>value</i>_1ist  WHERE search_conditions<br /><br /> 更新数据语句。<br /><br />    view_name|table_name：表名称或视图表名称<br /><br />    <i>value</i>_1ist：字段值<br /><br />    search_conditions：更新数据的条件<br /><br /> 例：略   <br /><br />  CHECK TABLE table-name  检查索引语句。<br /><br /> 语句使用者是表的拥有者或拥有DBA权限；不能对systable使用此语句。<br /><br /> 例：略   <br /><br />  REPAIR TABLE table-name  修复索引。<br /><br /> 语句使用者是表的拥有者或拥有DBA权限；不能对systable使用此语句。<br /><br /> 例：略   <br /><br />  LOAD FROM “file-name” INSERT INTO table_name [(column_name[,…])]  将文本数据栽入表中。<br /><br /> 例：load form “aa.txt” insert into user;   <br /><br />  UNLOAD TO “pathname”  将表中数据卸为文本。<br /><br /> 例：unload to “aa.txt” select * from user;   <br /><br />  INFO  系统信息查询。<br /><br /> INFO TABLES：得到当前数据库上表的名字。<br /><br /> INFO columns FOR table_name：指定表上的字段信息。<br /><br /> INFO INDEXES FOR table_name：指定表上的索引信息。<br /><br /> INFO [ACCESS|PRIVILEGES] FOR table_name：指定表上的存取权限。<br /><br /> INFO STATUS FOR table_name：指定表的状态信息。  <br /><br /> <br /><br />INFORMIX SQL 实践与技巧(1)<br /><br />      如何加快sql的执行速度？<br /><br />      1.select 语句中使用sort,或join<br /><br />      如果你有排序和连接操作，你可以先select数据到一个临时表中，然后再对临时表进行处理。因为临时表是建立在内存中，所以比建立在磁盘上表操作要快的多。<br /><br />      如：<br /><br />      SELECT time_records.*, case_name <br /><br />      FROM time_records, OUTER cases <br /><br />      WHERE time_records.client = <i>"</i>AA1000<i>"</i> <br /><br />      AND time_records.case_no = cases.case_no <br /><br />      ORDER BY time_records.case_no <br /><br />      这个语句返回34个经过排序的记录，花费了5分钟42秒。而：<br /><br />      SELECT time_records.*, case_name <br /><br />      FROM time_records, OUTER cases <br /><br />      WHERE time_records.client = <i>"</i>AA1000<i>"</i> <br /><br />      AND time_records.case_no = cases.case_no <br /><br />      INTO temp foo; <br /><br />      SELECT * from foo ORDER BY case_no <br /><br />      返回34条记录，只花费了59秒。       <br /><br />      2.使用not in 或者not exists 语句<br /><br />      下面的语句看上去没有任何问题，但是可能执行的非常慢：<br /><br />      SELECT code FROM table1 <br /><br />      WHERE code NOT IN ( SELECT code FROM table2 ) <br /><br />      如果使用下面的方法：<br /><br />      SELECT code, 0 flag <br /><br />      FROM table1 <br /><br />      INTO TEMP tflag; <br /><br />      然后：<br /><br />      UPDATE tflag SET flag = 1<br /><br />       WHERE code IN ( SELECT code <br /><br />      FROM table2 <br /><br />      WHERE tflag.code = table2.code ); <br /><br />      然后：<br /><br />      SELECT * FROM <br /><br />      tflag <br /><br />      WHERE flag = 0; <br /><br />      看上去也许要花费更长的时间，但是你会发现不是这样。<br /><br />      事实上这种方式效率更快。有可能第一种方法也会很快，那是在对相关的每个字段都建立了索引的情况下，但是那显然不是一个好的注意。<br /><br />      3.避免使用过多的“or<br /><br />      如果有可能的话，尽量避免过多地使用or：<br /><br />      WHERE a = <i>"</i>B<i>"</i> OR a = <i>"</i>C<i>"</i> <br /><br />      要比 <br /><br />      WHERE a IN (<i>"</i>B<i>"</i>,<i>"</i>C<i>"</i>) <br /><br />      慢。<br /><br />      有时甚至UNION会比OR要快。<br /><br />     4.使用索引。      <br /><br />        在所有的join和order by 的字段上建立索引。<br /><br />        在where中的大多数字段建立索引。<br /><br />        WHERE datecol &gt;= <i>"</i>this/date<i>"</i> AND datecol <br /><br />          要比 <br /><br />          WHERE datecol BETWEEN <i>"</i>this/date<i>"</i> AND <i>"</i>that/date<i>"</i> 慢       <br /><br />      如何在shell脚本中使用一个sql查询的结果？<br /><br />      以下的是一个运行在sh/ksh下面的脚本。在online中，如果你想要更新一个有许多表的数据库的统计信息。这个脚本不太好。因为这个脚本只能单个处理数据库中的表，而不能同时处理大量的表。<br /><br />      例子：<br /><br />      # update_em <br /><br />      # Run UPDATE STATISTICS on a table by table basis <br /><br />      # <br /><br />      DATABASE=$1 <br /><br />      if [ -z <i>"</i>$DATABASE<i>"</i> ] <br /><br />      then <br /><br />      echo <i>"</i>usage: update_em dbname<i>"</i> &gt;&amp;2 <br /><br />      exit 1 <br /><br />      fi <br /><br />      isql $DATABASE -  dev/null | isql $DATABASE - <br /><br />      output to pipe <i>"</i>cat<i>"</i> without headings <br /><br />      select <i>"</i>update statistics for table <i>"</i>, tabname, <i>"</i>;<i>"</i> <br /><br />      from systables where tabid &gt;= 100 order by tabname; <br /><br />      EOF<br /><br />       exit 0        <br /><br />      也许你已经注意到exit的返回值对不同的isql不是都相同，因此这样作不是很可靠，代替通过$?来检查返回值的更好的主意是将标准错误重定向到一个文件中，然后在这个文件中grep <br /><br />        “error。例如：<br /><br />      # Generate the data <br /><br />      isql -qr $stage.err <br /><br />      database $database; <br /><br />      select ... <br /><br />      ! <br /><br />      # Check for errors <br /><br />      if grep -i <i>"</i>error<i>"</i> $stage.err &gt;/dev/null <br /><br />      then<br /><br />       ...error_handler... <br /><br />      fi<br /><br />       <br /><br />      为什么不能对一个计算产生的字段创建视图？<br /><br />      问题：为什么我不能创建视图：<br /><br />      CREATE VIEW tst AS <br /><br />      SELECT ship_charge - totval cout <br /><br />      FROM orders WHERE ship_charge &gt; 0; <br /><br />      回答：你应该这样写：<br /><br />      CREATE VIEW tst (cout) AS <br /><br />      SELECT ship_charge - totval <br /><br />      FROM orders WHERE ship_charge &gt; 0;       <br /><br />      如何只select 出数据库中的部分数据（例如10％）。<br /><br />      问题：如果你想要得到一个select 语句正常返回的数据的一部分，例如：<br /><br />      SELECT firstname, lastname, city, state <br /><br />      FROM bigdatabase <br /><br />      WHERE state = <i>"</i>TX<i>"</i><br /><br />      回答：<br /><br />      有一个方法可以返回一个近似值，只需要在where后加上：<br /><br />      AND rowid=(trunc(rowid/x)*x) <br /><br />      其中的x代表你想要返回的总的记录的1/x。需要说明的是，这种方法只能返回一个近似的值，并且表中的数据在物理上分布的连续性。       <br /><br />      如何创建一个表结构和永久表完全一致的临时表。<br /><br />      例如：CREATE TEMP TABLE mytemp (prodno LIKE product.prodno <br /><br />      desc LIKE product.desc) <br /><br />      你可以使用如下的语句：<br /><br />      SELECT prodno, desc FROM product <br /><br />      WHERE ROWID = -1 <br /><br />      INSERT INTO TEMP mytemp<br /><br />    INFORMIX SQL 实践与技巧(2)<br /><br />      如何更改serial类型下一次插入操作产生的值？<br /><br />      我们知道serial类型的字段是系统自动增加的整数字段，那么怎样能控制下一个serial类型字段的值。<br /><br />      想要下一个插入的serial类型的值比默认值大，可以用：<br /><br />      ALTER TABLE tabname MODIFY( ser_col_name SERIAL([new_start_number])<br /><br />      想要下一个插入的serial类型的值比默认的值要小，首先需要将serial类型重新置为1：<br /><br />      INSERT INTO table (serial_column) <i>value</i>S (2147483647); <br /><br />      INSERT INTO table (serial_column) <i>value</i>S (0); -- 重新从1开始! <br /><br />      ....然后执行ALTER TABLE(就像上面的做法一样）。       <br /><br />      如何在发生错误的时候终止sql脚本的执行？<br /><br />      如果你创建了一个sql脚本，并且在UNIX命令行中使用以下的方式来执行这个脚本：<br /><br />      $ dbaccess   &lt;database&gt; &lt;脚本文件名&gt;<br /><br />      这时，脚本中的所有的sql语句都会被执行，即使其中的一个sql语句发生了错误。例如，如果你脚本中为如下的语句：<br /><br />      BEGIN WORK; <br /><br />      INSERT INTO history <br /><br />      SELECT * <br /><br />      FROM current <br /><br />      WHERE month = 11; <br /><br />      DELETE FROM current <br /><br />      WHERE month = 11; <br /><br />      COMMIT WORK; <br /><br />      如果INSERT语句失败了，DELETE语句仍旧会继续执行。直到commit work。这样的后果可能会很严重。你可以通过设置一个环境变量来防止这种情况的发生。<br /><br />      DBACCNOIGN=1<br /><br />      如何设置decimal字段运算结果的精度？<br /><br />      假定你使用dbaccess或者isql，设置环境变量DBFLTMASK=6 就可以设置为小数点后面6位，比如：<br /><br />      CREATE TEMP TABLE t <br /><br />      ( col_a DECIMAL(8,4) NOT NULL, <br /><br />      col_b DECIMAL(8,4) NOT NULL, <br /><br />      col_c DECIMAL(8,4) NOT NULL <br /><br />      ); <br /><br />      INSERT INTO t <i>value</i>S(1.2345, 3.4567, 5.6789); <br /><br />      SELECT (col_a + col_b) / col_c AS <i>value</i> FROM t; <br /><br />      <i>value</i> 0.826075 <br /><br />      如果DBFLTMASK=7<br /><br />      <i>value</i> 0.8260755<br /><br />          为什么我们有时会遇到sysprocplan表被锁的提示？<br /><br />      sysprocplan表是sysmaster库中的一个表，其中记录存储过程经过优化的查询计划。每当查询树中的数据库对象有任何结构上的变化，这个查询计划就会自动更新。如果对查询树中存在的任何表有update <br /><br />        statistics操作，也会自动更新查询计划。在查询计划更新的时候，会对sysporcplan表中的相关记录加锁。<br /><br />      注意：每次你对一个表更新统计的时候，也同时会更新于这个表相关的存储过程，即UPDATE STATISTICS FOR PROCEDURE 。<br /><br /> <br /><br />      你可以作的另外一件事情就是：在存储过程中使用SET OPTIMIZATION LOW，这会让优化器在存储过程运行的时候不会试图去重新优化它。否则存储过程通常都会被重新优化一次。<br /><br />      如何删除掉表中重复的记录？<br /><br />      假设“keycol”字段的值唯一，而且没有对表进行分片，并且没有其它的人正在删除sometable中的记录，你可以执行如下的SQL：<br /><br />      delete from sometable as a <br /><br />      where rowid  (select min(rowid) from sometable where keycol = a.keycol)<br /><br />      如果这个表使用表分片，rowid不存在，你还可以用如下的方法：<br /><br />      BEGIN WORK; <br /><br />      SELECT DISTINCT * FROM Table INTO TEMP Temp1; <br /><br />      DELETE FROM Table WHERE 1 = 1; <br /><br />      INSERT INTO Table SELECT * FROM Temp1; <br /><br />      COMMIT WORK; 　<br /><br />      对于规模较小或中等的表，并且你有足够的存储空间来存储整个的临时表的时候，这种方法通常十分有效。<br /><br />      如何加快SELECT COUNT(DISTINCT)的速度。<br /><br />      通常“SELECT COUNT(DISTINCT)”这样的操作要花费比较长的时间，如果你这样作：<br /><br />      SELECT UNIQUE xxx INTO TEMP XXX <i>"</i> 然后再<i>"</i>SELECT COUNT(*) FROM TEMP XXX<i>"</i> <br /><br />      这样通常可以提高几倍的效率。<br /><img src ="http://www.blogjava.net/joaquin25/aggbug/215864.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-18 16:52 <a href="http://www.blogjava.net/joaquin25/articles/215864.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix培训教材整理之系统维护技巧谈</title><link>http://www.blogjava.net/joaquin25/articles/215863.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Fri, 18 Jul 2008 08:51:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/215863.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/215863.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/215863.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/215863.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/215863.html</trackback:ping><description><![CDATA[转自：<a href="http://unix-cd.com/unixcd12/article_5445.html">http://unix-cd.com/unixcd12/article_5445.html</a><br /><br />Informix是一种大型的数据库管理系统，具有先进的技术、性能与可靠性，在全球范围的各种应用中使用十分广泛，包括政府、金融保险、邮政电信、制造及零售等重要行业或领域。本文根据笔者在SCO <br /><br />        Unix／Xenix上使用 <br /><br />        Informix－4GL与Informix－SQL的经验，简要介绍Informix系统维护中的几个较为特殊的问题及其处理方法。 <br /><br />      　　表文件的修复： <br /><br />      　　Informix的数据库是指由若干张表所构成的集合，其中每一张表对应着两个文件，即数据文件(后缀为.dat)与索引文件(后缀为.idx)。当系统出现异常、死机、掉电或非正常关闭时，有时会使一些使用中的表文件未能正常关闭而出现毁损，当系统再次对这些表进行相关操作时，就会报告“不能检索下一条记录”、“不能删除记录”等错误信息。 <br /><br />通常，数据文件是很少发生问题的。要判别数据文件是否正常，只需执行select ＊ from 〈table—name〉语句或类似的语句即可，但不能使用where、order by等子句，以免利用到索引文件，目的就是纯粹从数据文件中依次读取数据。如果数据读取顺利且记录个数正确，表明该文件完好无损；反之，则有问题，通常只能用其数据备份来恢复。 <br /><br />     如果数据文件正确无误，那么就该检查相应的索引文件。Informix提供有一个实用程序bcheck，专门用来检查与修复索引文件，即依次比较数据文件与索引文件，倘若不一致，就询问是否删除和重建有问题的索引。bcheck有许多选项可供选用，其中－n和－y用于对所有的提问都回答“no”或“yes”，让系统自动进行一系列的操作。其语法如下： <br /><br />      　　bcheck <br /><br />        [选项] 〈表文件名〉       <br /><br />      　　要检查表的索引文件，应先运行bcheck <br /><br />        －n命令。如果一切正常， <br /><br />        说明索引没有问题。一旦发现有错误报告（如有多少个错误数据记录指针、丢失了多少个数据记录指针或索引结点指针等），则再执行bcheck <br /><br />        －y 命令即可将其修复。 <br /><br />      　　Informix－SQL中的语句check <br /><br />        table 〈表名〉与repair <br /><br />        table 〈表名〉在运行时分别以选项－n与－y调用bcheck命令，功能一样，不同的只是使用表名而不是表文件名。 <br /><br />      　　如果索引文件没有相应的读写权限， <br /><br />        或者没有正确指明其路径， <br /><br />        在bcheck时会出现“无法打开索引文件”的信息。如果索引文件被删除或格式被破坏了，也有同样的信息。此时可从数据备份中将对应的索引文件拷贝回来，也可暂时创建一个字段与索引均与原表完全一致的新表并将其索引文件拷贝给原表，再运行bcheck <br /><br />        －y命令修复。 <br /><br />      　　表空间的回收 <br /><br />  　　Informix对数据表的管理方式较为特殊，当数据量增加时，表所占用的磁盘空间随之增加；但数据记录被删除时，原先所占用的空间暂不释放，依然由该表所控制，作为日后增加记录时使用。为提高系统的性能及有关各表的查询速度，应及时回收这种“空闲”的磁盘空间。 <br /><br />      　　使用bcheck －s命令可回收索引文件的空间，其中－s  选项的作用是重新估算索引文件的大小。要同时回收数据文件与索引文件的空间，可让DBMS(数据库管理系统)去做表结构的修改工作，但修改前后的表结构及有关权限要保证一样。可利用Informix－SQL达此目的，最为保险的做法是先给相应的表增加一个字段，再将该字段删除。也可利用alter <br /><br />        table 命令“欺骗”DBMS去修改表的结构，如alter <br /><br />        table aa modify(bb smallint)，其中aa表的字段bb的类型本来就是smallint。       <br /><br />      　　表的迁移 <br /><br />      　　任何一个Informix数据库都有九个系统表，用于记录数据库的有关信息，其中系统表systables(用于描述数据库中的各表)中的字段dirpath指明各表文件的绝对路径或相对路径。       <br /><br />      　　Informix数据库的搜索路径一般由环境变量DBPATH来设定，系统根据DBPATH的正确设定即可找到相应的数据库及其各表。迁移Informix数据库表时（比如从Unix/Xenix的根文件系统迁移到分离的文件系统/u），只要重新设定DBPATH，通常系统即可正常运行。如果报告某些表找不到了（实际上这些表文件还在，且有关权限也对），问题就在于systables <br /><br />        表中的dirpath字段值采用了绝对路径， <br /><br />        此时要用update命令修正其值，最好改用相对路径，即直接改为表文件名。    <br /><br />      　　系统查询的优化 <br /><br />         　　Informix在执行查询（特别是多表查询）指令前，会利用其所提供的优化器(cost－based <br /><br />        optimizer，基于成本的优化器)，依据当时系统所记载的有关各表的相关信息，按照一定的判断法则进行分析并选择出一条最有效率的途径来执行。系统必须掌握各表的正确数据，才不至于做出错误的选择。但出于系统效率上的考虑，不可能随时修改记录各表最新状况的相关文件，否则会增加许多额外的输入/输出负担。因此， <br /><br />        应定期执行这种信息的更新操作。 <br /><br />      　　在Informix数据库的系统表systables中有一字段nrows，专门用来记录各表的记录个数。优化器在运行法则判断时，各表的nrows <br /><br />        值具有很高的参考价值。nrows的更新可通过如下命令来完成，即： <br /><br />      　　update <br /><br />        statistics [for table 〈table—name〉]         <br /><br />      　　其中，方括号[]中的子句是可选的，用于指定表名，以对该表进行更新；否则,将对数据库中的各表进行全部更新。<br /><br /> <br /><br />一一　Informix数据库安全性<br /><br /> <br /><br />      informix动态服务器提供两个级别的访问特权，来保证数据库的安全性。数据库特权控制对数据库的访问和在数据库上创建表和索索引的权力。表的特权指定用户在特定的表上所能进行的操作。 <br /><br />      informix动态服务器支持表级的修改，插入和删除的安全性，同时增强了列级的更新和查询的安全性。分离特权语句用于向用户授予适当的访问基级别的特权，或回收特权。由于informx安全性是在用户级别上的，因此，不需要进行分离的数据库登录。 <br /><br />     存储过程通过建立他们自己的，有别于数据库的许可权限而提供了附加的安全机制。存储过程的所有者向用户授予执行该存储过程的权限，允许用户执行该存储过程中所有的SQL操作，但对其他的数据库访问加以限制。通过使用存储过程来限制用户执行某些用户执行某些数据库的操作，数据库管理员可以提高系统的安全性 <br /><br />      安全审计<br /><br />      INFORMIX动态服务器提供的安全审计功能对用来操作的每一个数据库对象提供跟踪和操作记录。这一功能符合“美国国家计算机安全中心”提出的C2级安全要求模型。<br /><br />       借助于INFORMIX动态服务器，你可以对系统中用户的活动进行选择性监控。安全审计的界面是由命令行驱动的，或是有参数调节控制的，它允许你指定对某一特定用户的特定活动进行监控。<br /><br />    Informix数据一致性<br /><br />      如果说高可用性能保证系统级的完整性，那么数据的一致性是在事务级保证完整性。INFORMIX动态服务器通过事务日志和内部一致性检查、创建和加强封锁过程、隔离级别和业务规则来保证数据的一致性。<br /><br />      事务日志<br /><br />      如果一个操作不能完成，则已经完成的那部分事务必须从数据库中清除，以保持数据的一致性。为了清楚部分完成的事务，INFORMIX动态服务器在逻辑日志中对所有事务的历史记录进行维护，并以这些事务记录作为依据，将数据库恢复到事务之前的状态。<br /><br />      内部一致性检查<br /><br />      内部一致性检查为提醒管理员数据或系统的不一致状态而专门设计。INFORMIX动态服务器包含一个数据级的检查机制，它能够发现由于硬件或操作系统故障而引起的数据不一致。如果发现了不一致，该内部机制就自动向INFORMIX动态服务器消息日志发消息。<br /><br />      为了玫厝范ú灰恢碌脑颍琁NFORMIX动态服务器管理员可以指导用户来设置一致性检查环境变量，这些变量产生诊断结果（例如，在不一致发生的共享内存中的内容），来帮助确定不一致发生的原因。<br /><br />      封锁和处理的独立性<br /><br />      为了保持数据的一致性，所需的另一个重要的功能是封锁过程和处理的独立性。这些安全性措施保护当前正在被访问或修改的数据不会被其它用户更改。       <br /><br />      封锁<br /><br />      数据库服务器引入封锁机制来防止错误的发生。锁是一个程序加在数据片断上的声明或限制。数据库服务器保证只要数据是被封锁的，其它任何数据库服务器进程都不能对其进行修改。当另一数据库服务器程序要求对该数据库进行修改时，数据库服务器使该程序要么等待，要么返回一个错误。<br /><br />      INFORMIX动态服务器还能防止死锁的发生。死锁是两个用户都封锁着另一个用户所等待得数据。例如，用户A封锁了一个元组，并且在用户A访问B所封锁的数据之前不会将其释放。INFORMIX动态服务器能立即检测到死锁的发生，并向第二个程序发出出错消息，以防止死锁状态的出现。<br /><br />      一个表或事务的吞吐量会受封锁策略的影响。使用排它锁对数据进行访问的应用会发现其它的数据库服务器进程都在花时间等待对数据进行访问。因此，INFORMIX动态服务器提供了几个不同级别的封锁。数据库服务器可以在单个记录、页面、表和数据库的级别上加锁。<br /><br />      在创建表和改变表结构时，可以指定记录和页面级别的封锁。在用户应用中可以指定表和数据库级别的封锁。       <br /><br />      隔离级别<br /><br />      隔离级别是读操作独立于其它并发数据库服务进程的程度；其它进程可以对你正在读的记录进行什么修改，以及你可以对其它进程正在读或修改的哪些记录进行读操作。<br /><br />      隔离级别只能影响读操作，它们不作用于其它的语句，如插入，删除，更新等。INFORMIX动态服务器有四个隔离级别：脏读、提交读、游标的稳定性、以及重复读。<br /><br />      脏读是隔离级别中最简单的一个，它实际上根本没有提供任何独立性。当一个程序使用脏读来访问数据时，它不加锁。对于脏读，用户可以读任何数据，包括以提交的未提交的。<br /><br />      提交读保证INFORMIX动态服务器只能读提交给数据库的记录。在对记录进行访问之前，数据库服务器检查是否有更新进程给该记录加了锁。如果没有加锁，数据库服务器就对该数据进行访问。提交读保证数据库服务器不会读未提交的数据，因为在作了修改而又没有提交的记录上加了锁。<br /><br />      下一个隔离级别是游标的稳定性。使用游标的稳定性时，数据库服务器在所读的最新记录上加上锁。每次仅对一个记录加锁；每当读新的记录时，就将原来的锁释放。这个孤立级别保证程序在读的当前的记录不会被改变。<br /><br />      重复读保证在读操作过程中，所得到的结果与在该事务中其它时刻得到的结果是一致的。重复读不仅在所读的记录上加共享锁，而且还阻止其它用户违反数据库的读锁标准向数据库中增加记录或更新记录。       <br /><br />      业务规则<br /><br />      业务规则能增强字段级的数据一致性，这些规则指定数据可能的值、列的缺省值，以及列与列之间的关系。<br /><br />      业务规则必须由对数据进行访问和操作的应用来限定。但是，INFORMIX动态服务器不依赖于应用来实现这些规则。实际上，INFORMIX动态服务器可以独立实现这些规则。责任的集中减轻了用户应用的负担，并保证了业务规则的继承性。<br /><br />      INFORMIX动态服务器支持完整性约束、存储过程和触发器，从而保证业务规则。<br /><br />      完整性约束<br /><br />      INFORMIX支持ANSI SQL的完整性约束，保证信息不会被不当地删除，插入的数据满足字段的特殊要求。INFORMIX动态服务器提供两种类型的完整性约束：参照完整性和实体完整性。<br /><br />      参照完整性允许用户定义和保证字段之间的关系。例如，INFORMIX动态服务器的参照完整性可以保证，对于主表中有关的一个实体的信息，如果在子表中存在相应的信息的话，那么主表信息不会被删除。这就保证不会在某客户的订单存在的情况下将该客户删除。<br /><br />      实体完整性为特定字段规定合法取值范围。这样的检查允许DBA对所允许的值的范围作出规定。缺省值允许用户指定符合字段数据类型的任何智值作为缺省值。<br /><br />      存储过程 存储过程是以命名过程的形式存储在数据库中的SQL命令和编程语句，以保证常用操作的一致实现。存储过程在数据库中，而不是在应用程序中对常用的优化过的应用例程进行维护。<br /><br />      存储过程减少数据库操作所需要的网络流量。因为存储过程可在一个命令中处理多个任务（如插入、更新和删除）。在处理请求之后，存储过程仅返回满足条件的结果，而不是每一个查询结果的集合。       <br /><br />      触发器<br /><br />      触发器是唤醒存储过程的另一种方法。与应用程序调用存储过程来实现业务规则的方法不同，触发器可以被定义为：在需要进行插入、删除、和更新的时候，启动数据库服务器自动执行存储过程（或SQL语句）。<br /><br />      由于触发器是存储在系统数据字典中的，因此不需要应用程序来完成维护触发器代码。同样，由于无法绕过触发器，所以跨所有事务的完整性约束也得到了保证。<br /><br />Informix安全审计       <br /><br />      什么是安全审计<br /><br />      安全审计可以创建用户在数据库中活动的事件记录，通过这些记录可检查不平常或可疑的数据库活动。<br /><br />      可以记录的事件有：      <br /><br />        成功或者失败的操作。你可以只记录成功的操作，或者只记录失败的操作，或者两种都记录。<br /><br />        online系统的连接。你可以记录与online系统建立连接的情况，包括是谁建立了这个连接，在什么时刻<br /><br />        系统和数据库管理事件。任何管理事件例如增加dbspaces和chunks，归档，赋权，回收权限，或者当前的事务日志都可以被审计。<br /><br />        数据库和表的操作。select,insert,update,或者delete语句都可以被审计，但是不允许只对某一个表的操作进行审计。<br /><br />      审计是如何工作的<br /><br />      管理员首先要创建audit masks（审计掩码），一个audit masks就像一个过滤器，检查用户的活动是否应该被审计。audit masks存储在sysmaster数据库的sysaudit表中。<br /><br />      如果执行数据库操作，而这个操作在被审计的范围内，online会自动在审计日志中插入一条记录。审计日志是一个UNIX文件，其中保存有审计的记录。这个文件有可能会变得很大，主要看audit masks中包括的操作的数量和操作的类型。<br /><br />      对每一个数据库用户可以有单独的user mask（用户掩码）。另外，管理员可以设置一个默认掩码，这样没有设置user mask的用户就可以使用这个默认的掩码。<br /><br />      审计掩码<br /><br />      审计掩码告诉online什么事件需要被审计。审计掩码的种类如下：      <br /><br />        单独的审计掩码（indiviual masks)。单独审计掩码是为每一个用户创建的掩码，其作用是对每一个用户的活动进行审计的。<br /><br />        默认的用户掩码(_default masks)。默认的用户掩码会被用在任何没有单独设置掩码的用户上。<br /><br />        必须的用户掩码(_require masks)。必须的用户掩码会忽略单独用户掩码和默认用户掩码中的内容。任何在_require用户掩码中设置的事件都会被审计，而不管用户的单独掩码中是否设置了这些事件。<br /><br />        排它用户掩码（_exclusive masks)。排它用户掩码同样会覆盖单独的用户掩码和默认用户掩码。其中包含的事件不会被审计，即使这些事件存在于单独的用户掩码和默认用户掩码中。这些事件不会覆盖_require掩码中的事件。      <br /><br />      你也许想要对有经验的用户很少事件进行审计，对没有经验的用户更多的事件进行审计。为了达到这种目的，为有经验的用户创建一个单独审计掩码其中包括较少的事件。为所有的其它用户创建一个默认审计掩码，其中列出更全面的审计事件。<br /><br />      管理员必须创建所有的掩码；_default,_require,_exclude和单独用户掩码。       <br /><br />      审计角色<br /><br />      在7.10.UD1之后，审计角色可以在用户之间实现独立的审计功能。      <br /><br />        数据库系统安全官员（DBSSO)的责任是维护审计掩码。<br /><br />        审计分析官员（AAO)分析审计记录，发现安全问题。      <br /><br />      为了更高的安全性，DBSSO,AAO，和ONLINE管理员应该由不同的人员来担当。<br /><br />      要设置基于角色的存取控制，ONLINE系统管理员应该设置两个环境变量。$DBSSOOWNER环境变量应该在DBSSO的登录脚本之中。$AAOWNER环境变量应该设置在AAO的登录脚本中。如果设置了这两个变量：      <br /><br />        只有AAO可以打开或者关闭审计功能。<br /><br />        只有DBSSO可以使用onaudit工具来维护审计掩码。<br /><br />      设置安全审计<br /><br />      设置安全审计的步骤：<br /><br />      1.打开安全审计。<br /><br />      2.设置审计参数。<br /><br />      3.创建审计掩码和审计事件。<br /><br />      打开审计功能：<br /><br />      有两种方法可以打开安全审计：使用onaudit工具，或者通过配置参数。在7.10UD1之前，这些参数是在$ONCONFIG文件中设置，在7.10UD1之后，这些参数在$INFORMIXDIR/aaodir/adtcfg文件中设置。<br /><br />      安全审计在你第一次初始化或者关闭和重新启动online的时候生效。你必须明确地打开审计功能：<br /><br />      作为informix用户，运行以下的命令：<br /><br />      onaudit -1 1<br /><br />      审计功能会立即对任何的新的连接生效。这个命令同时会修改ADTMODE配置参数，这样在下一次online启动的时候会自动生效。<br /><br />      也可以通过修改ADTMODE参数为1来打开安全审计。在修改了这个配置参数之后，你必须重新启动online，让改动生效。在ONLINE7.10.UD1版本之前，这个参数在$ONCONFIG文件中配置，在这个版本之后，这个参数在$INFORMIXDIR/aaodir/adtcfg文件中设置，并增加了更多的功能：<br /><br />      ADTMODE=1 写到informix审计记录中。不自动审计DBSSO和DBSA活动。<br /><br />      ADTMODE=2 写到操作系统的审计记录中。这个选项只在操作系统支持审计的时候才会生效。不自动审计DBSSO和DBSA的活动。<br /><br />      ADTMODE=3 写到INFORMIX审计记录中。自动审计所有的DBSSO活动。<br /><br />      ADTMODE=4 写到操作系统审计记录中。自动审计所有的DBSSO活动。<br /><br />      ADTMODE=5 写到INFORMIX审计记录中。自动审计DBSA活动。<br /><br />      ADTMODE=6 写到操作系统审计记录中。自动审计DBSA活动。<br /><br />      ADTMODE=7 写到INFORMIX审计记录中。自动审计所有DBSSO和DBSA活动     <br /><br />      设置审计文件参数：<br /><br />      1.指定审计文件的目录：<br /><br />      onaudit -p /work/audit<br /><br />      或者ADTPATH /work/audit<br /><br />      2.指定审计文件的大小：<br /><br />      onaudit<br /><br />      onaudit -s 50000<br /><br />      或者ADTSIZE 50000<br /><br />      在创建审计掩码之前需要设置其它的两个审计参数，它们是：<br /><br />      审计文件所在的目录。审计文件中存储所有用户的审计记录。首先创建一个目录。确保这个目录的权限为只能被INFORMIX帐号存取。<br /><br />      在online处于启动状态的时候，你可以通过执行如下的命令来修改审计目录：<br /><br />      onaudit -p 路径<br /><br />      其中路径名为将要放置审计文件的路径名。onaudit命令同时会修改ADTPATH配置参数的值。<br /><br />      你可以手工修改ADTPATH参数的值。然尔通过这种方式，你必须关闭和重新启动ONLINE，让改动生效。<br /><br />      默认文件大小。 ONLINE在ADTSIZE配置参数中限制了审计文件的大小。当审计文件的大小到达ADTSIZE的时候，一个新的审计文件会在ADTPATH路径下创建。<br /><br />      你可以通过onaudit工具来修改审计文件的大小，同时会修改ADTSIZE配置参数，这个大小的单位是字节：<br /><br />      onaudit -s 50000<br /><br />      你可以手工修改ADTSIZE参数的值。然尔通过这种方式，你必须关闭和重新启动ONLINE，让改动生效。<br /><br />      通过限制审计文件的大小，你可以周期性地将旧的审计文件归档或者删除。你也可以在当前的审计文件没有满的时候自动启动一个新的审计文件，方法是执行如下命令：<br /><br />      onaudit -n<br /><br />      设置错误参数<br /><br />      最后，你可以指定由于某种原因导致不能写审计文件的情况下，系统执行什么操作：<br /><br />      停止(0)模式－在一个用户会话试图写一个审计文件，但是写文件失败，它会等待，然后每秒重试一次。在审计文件可以写之前，这个会话不能做任何操作。<br /><br />      继续（1）模式－这种模式意味着会话会继续下去，即使不能够写审计日志，online的信息日志中会接到一条错误信息，说日志文件不能存取和更新。<br /><br />      HALT(0)是默认的错误模式。<br /><br />      你可以通过两种办法来修改错误模式。<br /><br />      使用onaudit工具：<br /><br />      onaudit -e error-mode<br /><br />      这个命名执行的同时会修改ADTERR配置参数。<br /><br />      修改在$ONCONFIG文件中的ADTERR参数的值，为了让这个改变生效，你必须重新启动online。<br /><br />      显示审计配置<br /><br />      你可以运行onaudit -c 命令来显示审计的配置：如<br /><br />      onaudit -c<br /><br />      Current audit system configuration:<br /><br />      ADTMODE =1<br /><br />      ADTERR = 0<br /><br />      ADTPATH = /work/tmpaudit<br /><br />      ADTSIZE = 5000<br /><br />      Audit file =1<br /><br />      如果online DBSERVERNAME为online1shm,当前的审计文件名为：<br /><br />      online1shm.1<br /><br />      使用onaudit设置掩码<br /><br />      onaudit工具同时用来维护审计掩码。可以用它来增加，删除，修改或者输出一个掩码。<br /><br />      _default,_require和_exclude掩码<br /><br />      在增加单独的用户掩码之前，你应该首先设置_default,_require和_exclude掩码,因为这些掩码会决定什么审计事件会被放置在单独用户掩码之中，它们应该被先创建。_require和_exclude掩码中的审计事件会覆盖任何单独的用户掩码。<br /><br />      使用-a选项增加一个掩码，。使用-e选项可以增加事件。<br /><br />      增加一个_default掩码：<br /><br />      onaudit -a -u _default -e +ACTB<br /><br />      增加一个_require掩码：<br /><br />      onauit -a -u _require -e +GRTB,GRDB<br /><br />      增加一个_exclude掩码：<br /><br />      onaudit -a -u _exclude -e +RDRW<br /><br />      单独的用户掩码<br /><br />      要为单独用户创建掩码，在-u 选项之后指定一个登录名。<br /><br />      如果你有一组用户有相似的审计事件，你可以创建一个掩码模板，要创建一个模本掩码，使用-u选项指定模本名。模本名必须以下划线（_)开头，并且不能超过8个字符。<br /><br />      要利用这个模本创建一个用户掩码，使用-r选项来执行这个模本名。你还可以使用-e选项来增加或者删除模本中的事件。在下例中，用户eric会接收_advance模本中指定的所有的事件（DRTB,DRDB)。用户lucy会接收_advance模本中的所有事件，然后再加上ALTB事件。<br /><br />      增加一个单独的用户掩码：<br /><br />      onaudit -a -u liz -e +DRTB,DRDB<br /><br />      增加一个掩码模本：<br /><br />      onaudit -a -u _advance -e +DRTB,DRDB<br /><br />      应用一个模本给一个用户：<br /><br />      onaudit -a -u eric -r _advance<br /><br />      onaudit -a -u lucy -r _advance -e +ALTB<br /><br />      显示掩码<br /><br />      你可以使用-o选项来列出一个掩码中的所有事件，如：<br /><br />      onaudit -o -u liz<br /><br />      Onaudit -- Audit Subsystem Configuration Utility<br /><br />      copyrigt (c) Informix Software,Inc.,1993<br /><br />      liz     -DRDB,DRTB<br /><br />       如果不使用-u指定某个用户，可以列出所有的掩码。<br /><br />      你可以让online只列出成功或者只列出失败的事件方法是在onaudit命令的事件参数之前加上S和F。如果在事件之前没有S或者F，成功和失败的事件都会被审计。<br /><br />      例子：<br /><br />      仅仅审计成功的事件，在事件的前面加上S。<br /><br />      +SDLRW(只记录成功的记录删除）<br /><br />      +FDLRW(只记录失败的记录删除）<br /><br />      修改一个掩码<br /><br />      onaudit -m -u artdy -e -ADCK<br /><br />      删除一个掩码<br /><br />      onaudit -d -u artdy<br /><br />      可以使用-m选项来增加或者删除一个已经存在的掩码中的事件，使用（＋）加号可以增加事件，使用(-)号，可以删除事件。<br /><br />      分析审计文件<br /><br />      分析审计文件可以使用两种方式：      <br /><br />      通过onshowaudit工具。onshowaudit工具可以重指定的审计文件中提取审计记录<br /><br />      通过数据库表的方式，使用SQL来进行查询。onshowaudit工具可以产生一个文件，然后利用dbload和sql中的load语句将这个文件装载到一个数据库的表中，然后你就可以使用SQL语句来对这个表进行查询      <br /><br />      只有informix用户才能使用onshowaudit工具。<br /><br />       1.使用onshowaudit分析审计记录<br /><br />      你可以使用onshowaudit来提取和列出审计记录。      <br /><br />        通过指定审计文件（-f audit_file)。如果使用-f选项，只有指定的审计文件被提取 。如果没有使用-f选项，会自动顺序从最早的文件进行提取。 <br /><br />        通过指定用户名（-u login)。只提取指定用户产生的审计记录。一次只能指定一个用户名。<br /><br />         通过数据库服务器名（-s server_name)。只提取指定的主机产生的审计记录。      <br /><br />      2.装载审计记录进一个表<br /><br />      你可以使用如下步骤，将审计记录装载如一个表中，然后就可以使用sql语句对其进行分析。<br /><br />      1.创建一个审计数据库，和一个审计表。<br /><br />      2.创建一个可以装载的审计文件：<br /><br />         onshowaudit -1&gt;log_records<br /><br />      3.如果使用dbload,创建一个load命令文件：<br /><br />        FILE log_records delimiter | 17;<br /><br />        INSERT INTO audit_table;<br /><br />      4.如果使用dbload,运行dbload命令:<br /><br />        dbload -d audit -c cmd_file<br /><br />      5.如果使用load，运行以下的SQL语句<br /><br />        load from <i>'</i>log_records<i>'</i> insert into audit_table<br /><br />      关闭审计功能<br /><br />      要关闭审计，你可以执行onaudit命令，指定-1 0 选项，这会立即关闭审计功能。<br /><br />      你同样也可以修改$ONCONFIG文件中的ADTMODE配置参数，但是审计只会在系统下一次启动的时候才会关闭。<br /><br /> <br /><br />一二　INFORMIX动态服务器表分片策略的计划和调整<br /><br /> <br /><br />     “数据分片”允许在表一级对数据存储进行控制。“表分片”是INFORMIX数据库的一个特征。用户可以对表中的记录或索引进行分组，并且存储在不同的位置，这样可以将数据存储到多个磁盘上，从而减少对磁盘I/O的竞争。数据分片的方案以及分片数据所存放的一组dbspace构成了“分片策略”。数据分片有两种基本类型：基于轮转分片和  “基于表达式分片”，对于“基于轮转法分片”，正如其名字一样，数据是根据轮转法方式存入表中的。“基于表达式分片”则根据表中的一个或多个字段对分片的规则进行定义。一般在预知查询条件时采用这种方式，从而避免查询中对某些分片的扫描。<br /><br />        对“表中的数据”和索引进行分片主要是为了提高应程序的效率，由于INFORMIX动态服务器可以并行地扫描多个磁盘上的数据，从而实现内部查询的并行操作，因此采用”分片“技术可以提高查询效率。内部查询的并行化有助于减少对一个复杂查询的响应时间。”表分片“技术与并行数据查询（PDQ）特征联系在一起使用，这样INFORMIX服务器可以分配多条线索。从所有数据分片上并行地选取数据。此外，还可以仅仅对包含“目标数据”的数据分片进行扫描。从而大幅度地提高了整个系统效率。“DATASKIP这一个特征还允许用户跳过那些出现故障或者不包含“目标数据”的数据分片，当某些数据所在的盘出现故障时，就可以体现出高度的“数据可获得性” <br /><br />        我们通过大量的数据分片将数据分布在许多的磁盘上，也实现了外部查询的并行操作。这样在大量用户对同一个表进行访问时，可以减少I/O的竞争，每秒钟完成的事务数（系统吞吐能力）也得到了提高。“表分片”技术还通过对存储在dbspace上的数据分片进行备份/恢复操作。<br /><br />      分片方案<br /><br />         在“创建表”和“创建索引”时候均可以用到分片方案。索引可以附加在与其相关联的数据上，或与数据分离存放。一个索引如果出现在对表数据的分片方案中，就可以认为索引已经附加在数据上。另外一个方面，如果索引的分片方案与数据不同，就称为索引与数据分离。这种情况下，索引存放在指定的dbspace上。<br /><br />        “数据分片”方式主要有两种：“基于轮转法”和“基于表达式”的方案，<br /><br />      轮转法方案<br /><br />         轮转法（PR)所使用的分片规则是系统内部定义的。使用这种方案，新追加的记录被存放在轮转法方式指定的下一个数据分片。记录所插入的第一个数据分片也是随机选定，例如，下列语法用于创建一个名为xyz的表：<br /><br />      CREATE TABLE xyz FRAGMENT BY ROUND ROBIN <br /><br />       IN dbspace1,dbspace2......dbspaceN<br /><br />      INFORMIX不支持用轮转法方式创建索引，因为这样会降低系统性能。轮转法方案的优点在于各数据分片上数据量是比较均匀的，对记录进行更新时，并不需要对记录进行转移。然而轮转法有一个缺陷，在进行一个查询时，要扫描所有的数据分片。因此，轮转法方案不支持DATASKIP，不允许INFORMIX动态服务器越过某个数据分片。如果不支持DATASKIP，同时又有一个数据分片出现错误，那么整个查询将会失败，因为不能确定出现故障的数据分片上是否有符合条件的数据记录存在。轮转法方案适用的情况是：用户需要快速加载数据，用户预先不知道数据访问的方式。用户的数据经常更新，或者是用户对于数据分布方式未知。<br /><br />      “基于表达式”的分片方式<br /><br />      对于“基于表达式的分片方案“，用户可以用下面两种规则对数据进行分片”<br /><br />        范围规则<br /><br />        绝对规则<br /><br />      范围规则<br /><br />        范围规则用SQL的关系或逻辑操作定义表的数据分片的边界。范围规则可以包含关系操作符，比如 &gt;,&lt;,&gt;=,&lt;=,还可以包含一些逻辑操作符，比如AND。范围规则最好根据表的某一个字段进行分片，但也可以根据两个或者多个字段进行分片。下面的分片实例运行效率并不很高，因为向表中插入一行时候需要进行太多的运算。所有不符合表达式条件的记录将放在REMAINDER dbspace中。基于“范围表达式”的分片方案可以确保只对包含目标数据的数据分片进行扫描。<br /><br />      下面是一个采用“基于范围表达式分片方案”创建表的例子：<br /><br />      CREATE TABLE xyz (aa integer....)<br /><br />      FRAGMENT BY EXPRESSION<br /><br />      aa&lt;=100 IN dbspace1<br /><br />      aa&gt;1000 AND aa&lt;2000 IN dbspace2<br /><br />      REMAINDER IN dbspace3<br /><br />       绝对规则<br /><br />        “绝对规则”使用了SQL的关系与逻辑操作符。与“范围规则”不同，“绝对规则”运行用户采用关系操作符与逻辑操作符对规则进行定义。此外，表中可以有多个字段参与分片。<br /><br />      例： FRAGMENT BY EXAMPLE<br /><br />      zipcode=94536 OR zipcode=94538 IN dbspace<br /><br />      zipcode=94025 OR zipcode=92310 IN dbspace<br /><br />      REMAIDER IN dbspace3<br /><br />      对于以上这种分片方案，必须知道每一个邮政编码所联系的数据个数，以确保每个数据分片上的数据量比较平衡，从而使INFORMIX动态服务器减少扫描的数据分片的数目。指定分片方案时，要确保数据分片之间不互相重叠。此外，定义数据分片时可以不包括REMAINDER分片。<br /><br />      分片的基本原则<br /><br />        “数据分片”的表达式必须尽可能简单，因为执行较复杂的表达式将加重CPU的负荷。同时，数据库中并不是每一个表都需要分片，除非能从“数据分片”中得到显著的收益。“分片”的表达式因为能确保磁盘I/O操作均衡，尽管我们没必要制定一个均衡的数据分片方案。如果大量的查询只对表数据中很小的区域进行访问，那么应该用表达式将那些被频繁访问的数据分片到多个盘上，尽管这样的分片也许数据量并不均衡。表达式应该把限制性最强的部分放在前面。对表达式进行修正是为了减少表达式的计算量，减少每次访问的数据量，从而最终减轻CPU的负荷。如果表达式中第一个不等式的结果为假，那么整个表达式的结果也将为假，因此不必计算表达式的其它部分(AND表达式）。比如说，为了插入数值25，下列表达式需要计算6个不等式：<br /><br />       x&gt;=1 and x&lt;=10 in dbspace1<br /><br />       x&gt;10 and x&lt;=20 in dbspace2<br /><br />       x&gt;20 and x&lt;=30 in dbspace3<br /><br />      如果用如下表达式，则只需要计算4个不等式：<br /><br />       x&lt;=10 and x&gt;=1 in dbspace1<br /><br />       x&lt;=20 and x&gt;10 in dbspace2<br /><br />       x&lt;=30 and x&gt;20 in dbspace3<br /><br />        分片的表达式中应该避免数据类型的转换。例如，日期数据类型在表达式中内部转换为整数类型。对于频繁更新的字段进行分片，会带来许多管理上附加工作。例如，如果根据一个日期字段进行分片，而超过保存日期的记录被删除，那么包含”超期数据”的数据分片将最终变空。这样就需要删除旧的数据分片，并为最新日期的记录创建一个新的数据分片。<br /><br />      “分片”策略的设计<br /><br />        一个“分片”策略包含数据分布方案以及数据分片所存放的一组dbspace。制定“数据分片”策略时需要根据分片的目标以及数据库的信息，诸如硬件/软件特性、查询特性、数据分布等作出决策。同时还需要知道一个现存的未分片数据库是否做转换，以及是否需要临时创建相应的应用程序。在前面的例子中，已经预知查询的方式，则可以加以利用。我们还应考虑到查询方式在将来的不断变化，诸如数据库的区域和/或帐户的附加部分，这一点也很重要。<br /><br />        “数据分片”的目标包括最大程度的内部查询并行化、外部查询并行化、提高数据可用性、更细的备份/恢复粒度以及更强的数据加载效率。<br /><br />        数据分片获得“内部查询并行化”：是指INFORMIX动态服务器充分发挥“数据分片”与PDQ功能的优势，并行地处理一个复杂的查询。这是决策支持系统(DSS)一类应用程序的主要目标。DSS查询从一个表中顺序读出大量数据记录。我们推荐使用数据分片。选择“轮转法”分片方案还是“基于表达式”的分片方案取决于查询特征、数据分布等因素，一般来说，当用户不能确定根据表中哪一个字段做“基于表达式”的分片，从而保持数据分片的均衡，或者不知道数据访问的方式时，我们推荐采用“轮转法”方式。“轮转法”方式不支持对索引的分片，因为扫描线索要越过分片的边界去读取索引，这样会导致效率的下降。“分片策略”还应该确保数据均衡的分布在不同的数据分片上，确保并行顺序扫描能均衡地完成。<br /><br />         数据分片获得“外部查询的并行化”：是指在大量用户运行较小的查询、返回少量的数据的条件下，INFORMIX动态服务器最大程度提高性能的能力。一般来讲，对于“存在大量用户，需要实时响应的应用程序，称为联机事务处理（OLTP)。OLTP查询总是在同一时间访问数据的一小部分区域，总是随机地对一些数据行进行更新或者删除操作。这些操作总是和”索引扫描”有关。在这种情况下，应该用表达式将数据表和索引表进行分片，从而允许查询在扫描过程过中某些数据分片。如果不考虑I/O竞争，数据分片和索引分片可以在同一个盘上，并使用同样的“分片”策略。另一方面，在一个大系统中如果额外有空余的盘，并且磁盘I/O可能成为潜在的瓶颈，那么最后将索引单独建在一块盘上。调换一下顺序，当按照某一字段创建索引时候，如果每一个查询都根据同一字段访问数据时，我们也可以使用与“数据分片”不相同的策略对索引进行分片。这种情况下，最好在WHERE子句中使用另外一个字段，“分片”策略的理想化程度取决于数据的分布和对表的查询的分布情况。我们的目标通过数据分布消除I/O瓶颈，尽管每个数据分片上的数据量可能不太均匀。<br /><br />        数据分片增强“数据可获得性”：是指可以在某些数据分片发生故障的时候，数据库仍然能接受应用程序的查询请求。这种能力是有INFORMIX动态服务器的DATASKIP特征提供的。<br /><br />         数据分片“增强数据加载的性能”：尤其适用于”周期性地加载几个G的数据，从而需要快速加载技术”的大型应用程序。将数据 分片到不同的磁盘上，可以使数据自动地进行并行加载，这是通过使用多个I/O流向数据分片所驻留的磁盘上写数据而达到的。轮转法分片方案应该最能保证快速数据加载，因为复杂表达式的计算会加重CPU的负荷，如果采取较简单的表达式并将每个数据分片放在单独的盘上，用“基于表达式”的分片方案同样可以保证快速加载数据。<br /><br />      以下是“确定合理的分片策略”所必须的步骤：<br /><br />      硬件/软件特征<br /><br />         要搞清楚硬件平台，如CPU的速度，数目，磁盘数目，大小，磁盘控制器的数目，以及与每个控制器相连接的磁盘数目，等等。这些信息对于确认表分片的数目以及怎样存放数据分片以减少I/O竞争，都是十分有用的。除了可用的磁盘外，对于每个表的数据分片的数目都有一定的上限，这些限制与分片的目标有关，如果分片的主要目的是增强内部查询的并行程度，那么系统CPU的数目和数据总线的带宽将限制一个表所能得到的并行线索的最大数目。另一个方面，如果分片的主要目标是增强外部查询的并行程度，那么分片的数目可大于CPU的数目，从而保证数据分布在许多磁盘上，在OLTP条件下可以允许用户并发地访问不同的磁盘，然而，当数据分片的容量变小的时候，应用程序会寻找多个数据分片，同时对寻找的结果进行合并。这些都会降低查询的效率。<br /><br />        对于具有高速CPU和低速盘的系统，每个表的分片数目可以超过物理CPU的实际个数。<br /><br />        所选的硬件平台 的操作系统类型和编译器对选择“分片”方案也是一个重要的因素。有的操作系统擅长处理MOD操作以及数据类型转换。<br /><br />      了解查询的特征<br /><br />      要了解一个应用程序到底是OLTP还是DSS类型，还要了解SELECT语句查询用的频繁还是update/delete操作频繁。如果查询多用SELECT语句，还要确定带有         “group by,order by等复杂子句查询的执行频度。对于这些情况的了解有助于平衡I/O，消除瓶颈。检查每个SELECT 查询的选择性以及返回数据的比例。如果一个查询的选择性（selectivity)很大，就需要为查询创建索引。检查有无JOIN操作，并确认JOIN操作的主码是什么。如果在DSS查询中总对某一特定的表进行JOIN操作，那么这个表应该被分片到不同的磁盘上以避免I/O瓶颈。检查每个查询的查询条件。最后将所涉及的表中的字段画一个矩阵。接着将某一查询中用做查询条件的字段填上“+”字符。有了这个矩阵，我们可确认在所有的查询中，哪个查询条件最常用。这一信息与每一查询的执行频度一起，有助于确认对哪个字段做“基于表达式的分片”收益最大。检查数据是怎样被访问的，即数据是通过“顺序读取”还是通过“INDEX  SCAN被访问。为每一个查询配备“SET EXPLAIN 子句，加上表的模式信息，可以达到以上目标。<br /><br />      数据分布及特征<br /><br />      确认表中用户查询条件的字段的取值范围。确认表中每一取值范围内符合记录的个数。在许多DSS类应用程序中，结果是从几个GB的数据或几个月，甚至一年的数据中得出来的。在这种条件下，很容易确认某一州，某个城市的记录数，或者是整个月的数据供以后使用。如果大多数查询将某个州和某月作为筛选条件，那么这些字段是参与”基于表达式”的分片方式的最佳选择。此外，还应了解表中数据被修改的速率，诸如增、删、改等。<br /><br /> <br /><br />一二　使用IDS中的SMI表向用户发送“广播信息”<br /><br />           <br /><br />      INFORMIX－Online以SQL表的形式向用户提供监控信息。这些被称作系统监控接口（SMI)的表，可以在非并行状态下方便地提供INFORMIX动态服务器的信息。有一个存储过程可借助这些信息，向当前Online例程连接的用户提供广播信息。<br /><br />      SMI表<br /><br />      当INFORMIX动态服务器最初初始化时，在消息日志中出现了提示信息：“sysmaster数据库被创建。这个数据库包括所有SMI表，每个Online例程都有自己的sysmaster数据库。在sysmaster数据库中的表，是基于磁盘的SQL表表或视图在共享内存中的组合，被称为伪表。<br /><br />      对于查询语言来说，SMI表和普通SQL表是一样的，因此SQL语句可以充分发挥其优势，检索当前Online例程的信息。INFORMIX动态服务器依赖于这些SMI表中的信息，认识到这一点很重要。因此，对这些表的信息进行各更新或修正会产生不可预知的后果。用户应该把SMI表中的信息看做是只读信息。SMI表的信息还可以用来监控磁盘的使用、表的状态，chunk的状态、系统的效率、备份（ON_Archive)的状态以及其它信息。<br /><br />      Syssessions表<br /><br />      本文的例子要向当前所有用户发出”广播信息，所以SMI表中”Syssessions”有其重要。该表包含了当前与Online例程相连接的所有用户信息。当用户连接到数据库引擎时，就在该表中加入一条新的记录。当用户与Online例程分离时，这个用户在syssessions表中的记录就被取消。在该表的各个字段中，下面几个字段对于本文的存储过程来说非常重要：<br /><br />      Sid<br /><br />         Session ID:在与其它SMI表连接时非常有用<br /><br />      Usename <br /><br />        Puser ID:用户的UNIX登录名<br /><br />      Hostname<br /><br />        Hostname of Client:用户客户端的主机名<br /><br />      tty<br /><br />        User<i>'</i>s of stderrFile：客户端的全路径<br /><br />      syssession表中还可读到许多字段，包括每个用户session的当前状态。但对本文的存储过程而言，不涉及到这些字段。这些字段在《INFORMIX动态服务器管理员指南》中有详细介绍。<br /><br />      本文示例中存储过程所涉及到的具体问题<br /><br />      首先，有必要对存储过程中关于算法和具体语法的一些具体问题做必要的解释。最初，存储过程对终端设备执行一个回应，对远端用户进行写操作。因为在UNIX平台上没有标准的远程“写”命令。所以这种方法只不过是权宜之计。要注意在syssession表中，tty字段只有16个字符的长度。在同一个系统中，这个长度不足以指定一个终端设备或机器名。同时，请注意存储过程中出现的“”语法。这是在“存储过程语言”（SPL)中包含双引号的用法。<br /><br />      一个向全体用户发布“广播信息”的存储过程<br /><br />      create procedure public_address(mesg_str char(80))<br /><br />      define user_name char(10);<br /><br />      define mach_name char(16);<br /><br />      define tty_name char(20);<br /><br />      define cmd_line char(160);       <br /><br />      foreach c_user_list_1 for<br /><br />      select unique username,hostsname,tty<br /><br />        into user_name,mach_name,tty_name<br /><br />        from sysmaster:syssessions<br /><br />        where username is not null and username!= and <br /><br />          hostname is not null and hostname !=  and<br /><br />        tty is not null and tty!=       <br /><br />      let cmd_line=rsh  ||mach_name|| echo<i>'</i>||meg_str||<i>'</i>&gt;<br /><br />      ||tty_name||;<br /><br />         system cmd_line;<br /><br />         end foreach<br /><br />      end procedure -- public address;       <br /><br />      运行上例中的存储过程<br /><br />      因为上面例子中的存储过程在运行中用到了sysmaster数据库中的信息，执行起来就相当简明。为了准备并运行下列存储过程，要做以下工作：<br /><br />      1.启动dbaccess，连接到一个常规数据库上（不要选择sysmaster)<br /><br />      2.在“Query Language菜单下运行上述语句<br /><br />      3.Online例程会在屏幕上向用户发”消息“<br /><br />      4.EXECUTE PROCEUDRE public_address(Hi Vern)<br /><br />      确认”Hi Vern被发送给所有用户－不论是本地用户，还是远程用户。<br /><br />      结论:<br /><br />      本文展示了关于SMI的一个表的简单应用，利用SMI表所能提供的信息，以及强有力的SQL工具，以及各种前后端工具，我们能作得更多的工作。SMI表可以提供许多极有帮助的信息，这完全取决于你的具体需求。<br /><img src ="http://www.blogjava.net/joaquin25/aggbug/215863.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-18 16:51 <a href="http://www.blogjava.net/joaquin25/articles/215863.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix培训教材整理之OnLine动态服务器运行模式管理</title><link>http://www.blogjava.net/joaquin25/articles/215862.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Fri, 18 Jul 2008 08:49:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/215862.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/215862.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/215862.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/215862.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/215862.html</trackback:ping><description><![CDATA[
		<p>转自：<a href="http://unix-cd.com/unixcd12/article_5446.html">http://unix-cd.com/unixcd12/article_5446.html</a><br /><br />动态服务器的系统结构<br /><br />      INFORMIX动态服务器采用的是一种多线索体系结构，这就意味着一个进程利用自己的多个线索可以同时完成多个任务，因而整个系统只需要较少的进程就足以完成DBMS的任务。<br /><br />      动态服务器系统由三个主要组件构成：共享内存，进程和磁盘。共享内存包括三个段：驻留段。虚拟段和消息段。驻留段主要用作磁盘数据的缓存。虚拟段主要用作内存池以支持进程及相关的会话（session)和线索。当客户与服务器利用共享内存进行通信时，消息段将用作两者之间的消息缓冲区。<br /><br />      系统中还包括若干构成数据库服务器的UNIX进程，称为oninit.这些进程被称为虚拟处理器（VP）(virtual processors)。每一VP隶属于某一虚拟处理类。而每一虚拟处理器类都负责完成一类特定的任务。<br /><br />      系统的磁盘组件由多个原始磁盘空间组成，称为chunk,chunk以页（page)为基本单位。多个chunk集合逻辑上构成了数据空间（dbspace)。数据空间用于存储数据库、表、系统信息以及物理日志和逻辑日志。一个数据空间至少包括一个chunk.<br /><br />      共享内存段<br /><br />      动态服务器的共享内存由三个段构成：      <br /><br />        驻留段主要用作缓冲池，内含逻辑日志和物理日志的缓冲区以及其他系统数据结构。驻留段的大小主要有系统参数BUFFERS决定。<br /><br />        虚拟段主要用作内存池以支持会话和线索。根据用途的不同，内存池可以进一步分为：会话池、多线索池、字典池、存储过程池、排序池、大缓冲池以及全局池。内存池的分配和释放是动态进行的。内存池分配单位大小为8k。如果已有虚拟段耗尽，动态服务器可以根据onconfig参数再次动态申请。虚拟内存段的初始大小由参数SHMVIRTSIZE决定，其增量由参数SHMADD决定，但整个共享内存段的大小不能超过SHMTOTAL。<br /><br />        如果客户与服务器利用共享内存进行通讯，消息段将用作通讯缓冲区。每一用户连接（利用共享内存进行通讯）大致占用12K空间。用户连接的数量在参数NETTYPE中定义。      <br /><br />      用户可以利用ipcs或onstat -g seg 命令来监控共享内存段的状态。<br /><br />      虚拟处理器（Virtual Processors)      <br /><br />            虚拟处理器类<br /><br />          oninit    cpu类： 运行所有用户线索和部分系统线索（所有线索的95％）                <br /><br />          oninit    AIO类： 运行所有内部线索以执行I/O，日志写除外                 <br /><br />          oninit    PIO类： 运行内部线索写物理日志                 <br /><br />          oninit    LIO类： 运行内部线索写逻辑日志                 <br /><br />          oninit    SHM类： 运行共享内存通讯线索                 <br /><br />          oninit    TLI类： 运行内部TLI网络通讯线索                 <br /><br />          oninit    SOC类： 运行内部Sockets网络通讯线索                 <br /><br />          oninit    MSC类： 运行其它任务线索                 <br /><br />          oninit    ADM类： 运行时钟                 <br /><br />          oninit    OPT类： 负责管理BLOB将传至光盘子系统                 <br /><br />          oninit    ADT类： 运行安全审计线索              <br /><br />      数据库系统服务器由若干称为oninit的UNIX进程组成，在系统中这些进程被称为虚拟处理器（VP）。所有VP都是可执行程序oninit的实体。每一VP属于一种特定的虚拟处理器类，而不同的虚拟处理器类分别完成不同的任务。每一虚拟处理器可含的VP数量由下列参数决定：“<br /><br />        CPU     NUMCPUVPS<br /><br />        AIO     NUMAIOVPS<br /><br />        PIO     自动启动一个VP。如果物理日志被镜像，将启动两个VP<br /><br />        LIO     自动启动一个VP。如果逻辑日志被镜像，将启动两个VP<br /><br />        SHM     NETTYPE<br /><br />        TLI     NETTYPE<br /><br />        SOC     NETTYPE<br /><br />        MSC     自动启动一个VP<br /><br />        ADM     自动启动一个VP<br /><br />        OPT     STAGEBLOB被设置，然后自动启动一个VP<br /><br />        ADT     ADTMODE被设置，然后自动启动一个VP<br /><br />      用户可以利用PS 或者onstat -g glo命令监控VP的状态<br /><br />      线索<br /><br />      onstat -g ath    显示所有线索<br /><br />      onstat -g act    显示活动线索<br /><br />      onstat -g rea    显示所有就绪线索<br /><br />      在动态服务器中，线索是在oninit中的一段被执行的指令流。通过多线索机制，可以让一个进程同时为多个任务服务而不必生成多个OS级进程。进程oninit可以启动多个线索，各线索顺序执行，并在适当地时候把控制权转移给其它线索。在多线索进程中每一线索都有自己的执行环境，包括自己的代码空间和自己的局部变量。一个多线索进程负责多个线索间的正文切换。<br /><br />      在系统中，线索只能有两种存在状态：要么正在某个VP上运行，要么在某一队列排队等待。在就绪队列中保存了所有已就绪只待执行的线索的正文。一旦出现空闲VP，该VP就从就绪队列中选取一个线索执行，而选取的标准由内部的优先机制决定。<br /><br />      在特定的时候，当前运行的线索会把对VP的控制权转移给其它线索。有如下几种可以导致控制权的转移：      <br /><br />        等待磁盘读写操作<br /><br />        等待应用程序的请求<br /><br />        等待获得锁或其它资源<br /><br />        将运行机会转给其它线索      <br /><br />       一旦线索交出控制权，该线索的context就将被列入等待或睡眠队列中。所有等待某种操作的线索进入等待队列，而所有需要稍后被唤醒的线索进入睡眠队列。<br /><br />      磁盘组件<br /><br />      在动态服务器中以页（page)作为基本存储和I/0单位。页大小因机器和操作系统的不同而不同，一般为2k，也可能为4k，用户无法改变页大小。<br /><br />        分配给系统使用的连续磁盘空间的单位称为chunk。chunk由多个页构成。它是一个典型的UNIX原始设备。chunk的大小由系统管理员设定。      <br /><br />        数据空间（dbspace)是多个chunk的逻辑集合。每一数据空间至少包括一个chunk。数据库和表创建在指定的数据空间上。系统必须至少包括一个数据空间： <br /><br />          root dbspace。在该空间中存储着关于系统的信息。            <br /><br />        物理日志（physical log)由连续的磁盘空间构成，其存储着共享内存缓冲区中所有已修改的数据页（但尚未写入磁盘中）被修改前的映象。因而物理日志主要用于快速恢复。只有当数据页在首次被修改时，系统才会将其映象写入物理日志。<br /><br />        逻辑日志（logical logs)也是由连续的磁盘空间构成，其存储着事务记录、DDL语句和checkpoint记录。由管理员设定逻辑日志的数目。系统循环使用逻辑日志。在系统第一次初始化时，物理日志和逻辑日志都自动建立在root dbspace上。<br /><br /> <br /><br />九　初始化Informix动态服务器<br /><br />     步骤：<br /><br />            　onstat工具<br /><br />              为每一台机器安装软件<br /><br />              检查$INFOMRIXDIR/release目录下的release notes<br /><br />              配置推荐的核心配置参数<br /><br />              准备磁盘空间<br /><br />              设置所需环境变量<br /><br />              创建一个sqlhosts文件<br /><br />              在$INFORMIXDIR/etc目录下设置onconfig文件<br /><br />              利用oninit工具初始化online      <br /><br />      初始化动态服务器的步骤如上所示。<br /><br />      用户在初始化系统签应该执行阅读$INFORMIXDIR/release目录下的release note。在该文件中包括了许多与操作系统、内核参数以及系统更新相关的重要信息。<br /><br />      机器在出厂时已预置了核心配置参数，但如果用户自己需要，则需要进一步调整这些参数。关于核心参数配置请检查release notes。<br /><br />      为系统准备磁盘空间时，必须首先正确设置如下权限：<br /><br />      chmod 660 device_name<br /><br />      chgrp informix device_name<br /><br />      chown informix device_name<br /><br />      我们建议用户最好能为原始设备建立链接文件，原因有二个：<br /><br />      1.可以利用链接命令描述设备使用信息，例如那一个chunk在使用那一个设备；<br /><br />      2.便于恢复。<br /><br />      在UNIX系统中利用ln命令建立链接<br /><br />          环境变量<br /><br />            INFORMIXDIR     设置为informix产品所在的目录<br /><br />            PATH        包括INFORMIXDIR/bin<br /><br />            ONCONFIG      设置onconfig文件名<br /><br />            INFOMRIXSERVER   设为维onconfig参数中的DBSERVERNAM值<br /><br />            PSORT_NPROCS     设置为物理CPU VPs数<br /><br />      我们推荐所有的informix和数据库用户使用korn shell。注册环境必须在注册时自动设置。一般来说，所有环境变量在.profile中设置。我们希望所有系统用户使用同一注册文件。Informix必须设置的环境变量如上所示。<br /><br />      连接三角<br /><br />      客户与动态服务器的连接包括三个部分。环境变量INFORMIXSERVER是指向通讯配置文件内某一条目的指针。通讯配置文件的默认路径和名称为 <br /><br />        $/INFOMRIXDIR/etc/sqlhosts。该文件的第一个字段包含了配置参数DBSERVERNAME或DBSERVERALIASES的值，其中DBSERVERNAME只能有一个，而用户可以通过环境变量INFORMIXSQLHOSTS改变通讯配置文件的存储路径及名称。<br /><br />      通讯配置文件（sqlhosts)的记录格式如下：<br /><br />      dbservername netttype hostsname servicename<br /><br />      各字段的含义如下：      <br /><br />        dbservername     onconfig 文件中的DBSERVERNAME或DBSERVERALIASES<br /><br />        nettype                             <br /><br />                      对于共享内存连接来说是onipcshm      <br /><br />                      对于TLI TCP/IP连接来说是ontlitcp<br /><br />                      对于sockets TCP/IP连接来说是onsockcp<br /><br />         hostname       机器的主机名<br /><br />       　servicename     文件/etc/services中的服务名，对于共享内存连接方式无用<br /><br />          系统初始化<br /><br />            #root dbspace配置<br /><br />            ROOTNAME       rootdbs       #root dbspace名<br /><br />            ROOTPATH       /dev/online_root   #构成root dbspace的设备路径<br /><br />            ROOTOFFSET      0          #root dbspace设备的偏移量（Kbyte)<br /><br />            ROOTSIZE       50000         #root dbspace大小（Kbyte)<br /><br />            #磁盘镜像配置参数  <br /><br />            MIRROR        0           #镜像标志（YES=1,NO=0)<br /><br />            MIRRORPATH                 #镜像root dbspace设备额路径<br /><br />            MIRROROFFSET     0          #镜像root dbspace设备的偏移量<br /><br />            #物理日志配置<br /><br />            PHYSDBS       rootdbs       #物理日志（dbspace)的位置<br /><br />            PHYSFILE       1000         #物理日志文件大小（Kbytes)<br /><br />            #逻辑日志配置<br /><br />            LOGFILES       10          #逻辑日志文件数量<br /><br />            LOGSIZE       3000         #逻辑日志大小（Kbyte)             <br /><br />      动态服务器的初始化包括两部分：磁盘初始化，创建root dbsapce。root dbspace中有12页专门用于存放系统信息，称为系统保留页。剩余空间中包含被称为chunk <br /><br />        free list的页，50页tblspace ,4页database tablespace。在root dbspace中还存储sysmaster和sysutils数据库。<br /><br />      在系统初始化时，物理日志和逻辑日志都自动建立在root dbspace中。逻辑日志的最优大小很难确定，因为与各系统的事务活动状况紧密相关。刚开始时可以将其大小设置为3至5MB,如果不够可以随时追加。<br /><br />      在初始化时应创建一个较小的物理日志。因为在DBMS系统中，尤其在OLTP环境下，数据库的操作非常频繁，日志中必须记录大量的信息，所以用户最好能将多个日志分布在不同的设备上。有一种非常简单的方法：既在系统初始化完毕后，将物理日志移至其它设备，并扩大其空间。一般来说物理日志大一些为好（300M-500M），这样可以避免频繁地初始化检查点（物理日志75％满时进行）。<br /><br />      请一定牢记，root dbspace的位置和初始chunk的大小是无法改变的，除非重新初始化系统，但这将清除现有系统中的所有信息。<br /><br />      root dbspace的镜像功能可以在初始化时打开也可以在以后打开。      <br /><br />      消息和磁带参数<br /><br />            #诊断<br /><br />            MSGPATH       /dev/informix/online.log   #系统消息日志文件路径<br /><br />            CONSOLE      /dev/console          #系统控制台消息路径<br /><br />            ALARMPROGRAM    /usr/informix/log_full.sh   #报警程序路径及名称<br /><br />            #系统归档磁带设备<br /><br />            TAPEDEV       /dev/null           #磁带设备路径<br /><br />            TAPEBLK       16              #磁带块大小（Kbytes)<br /><br />            TAPESIZE       10240             #磁带最大容量（Kbytes)<br /><br />            #日志归档磁带设备<br /><br />            LTAPEDEV      /dev/null           ＃日志磁带设备路径<br /><br />            LTAPEBLK      16               #日志磁带设备大小（Kbytes)<br /><br />            LTAPESIZE     10240             #输出到磁带上的最大数据量（Kbytes)<br /><br />            STAGEBLOB                     #INFORMIX光机缓冲区<br /><br />               变量MSGPATH中记录了系统消息日志文件的位置和名称。在运行时应随时监控该文件。用户可以另开出一屏，对该文件运行tail -f。系统消息将不断地添加在消息文件后，用户应该经常注意该文件的长度。<br /><br />      我们建议应将CONSOLE重定向到一个与MSGPATH同一目录下的文件上。<br /><br />      磁带设备参数用户系统归档和逻辑日志备份。参数ALARMPROGRAM被自动设置为log_full.sh。该文件在逻辑日志满时，自动启动ON_BAR备份逻辑日志。如果不需要此功能，只需要将ALARMPROGRAM设置为no_log.sh文件。<br /><br />      差数STAGEBLOB只对INFORMIX DYnamic Server/Optical系统有效。<br /><br />      系统配置<br /><br />            #系统配置<br /><br />            SERVERNUM      1            #每个服务器的唯一值<br /><br />            DBSERVERNAME     onlineshm        #数据库服务器主名<br /><br />            DBSERVERALLASES   onlinesoc        #数据库服务器别名<br /><br />            NETTYPE       ipcshm,,10,CPU      #为nettype配置轮询线索<br /><br />            NETTYPE       soctcp,2.25.NET<br /><br />            DEADLOCK_TIMEOUT  60            #在分布环境下等待锁的最长时间<br /><br />            RESIDENT       1            #强制驻留标志（YES=1,NO=0)<br /><br />            MULTIPROCESSOR   1             #0单处理器，1多处理器<br /><br />            NUMCPUVPS      10            #用户cpu vps 数量<br /><br />            SINGLE_CPU_VP    0            #如果非0，限制CPU VP为1<br /><br />            NOAGE        1            #进程调度<br /><br />            AFF_SPROC      0            #绑定初始处理器<br /><br />            AFF_NPROCS     10            #绑定处理器数<br /><br />          动态服务器必须具有唯一的SERVERNUM。给参数用作系统共享内存段的码（key)。客户连接时根据参数DBSERVERNAME确认服务器，所以该参数也必须唯一，同时它也必须与通讯配置文件中的条目匹配。DBSERVDERNAME或DBSERVDERALIASES都必须与一种通讯接口（共享内存，tli,sockets)相应。在通讯配置文件中必须包括所有的服务器名。<br /><br />      如果系统内存严重不足，UNIX会将某些进程整个交换出实存。通过设置RESIDENT参数，可以保证共享内存的驻留段始终在共享内存中不会被交换到磁盘上，否则系统的性能将会受到极大的影响。<br /><br />      许多UNIX操作系统会降低长时间运行的进程的优先级。组成服务器的oninit进程因而会受到影响，导致系统性能下降。参数NOAGE将禁止这种情况的发生。该参数与系统平台有关。如果在系统中出现上述现象，但系统又不支持NOAGE参数，可以利用renice命令提高优先级。ps命令的PRI列表示进程的优先级。在某些系统上，利用top命令也可以显示进程优先级。<br /><br />      NETTYPE<br /><br />      参数NETTYPE中定义了客户与动态服务器连接的方式。如果要与系统连接，就必须为每一类连接定义一个NETTYPE以记录网络和通讯协议的类型。<br /><br />      NETTYPE的第二个字段指定了为该协议启动的轮询（poll)线索数。这些轮询线索负责客户与服务器间的通讯。一般来说，一个轮询线索最多可以为100个用户服务。关于如何配置线索数目才能达到最优，将在以后的章节中详细讨论。<br /><br />      NETTYPE的第三个字段决定了该协议的连接数。共享内存协议利用此参数决定共享内存消息段的大小。NETTYPE的最后一个字段决定了轮询线索应在那一种VP类上运行。有两种VP类可以选择：CPU或NET。属于NET类的VP包括SOC,TLI或SHM。在CPU <br /><br />        VP上运行的效率最高，但只能运行一种通讯协议。<br /><br />      如果轮询线索运行在CPU VP上，轮询线索数不能超过CPU VP数。但如果轮询线索运行在NET类VP上，轮询线索数将决定SOC，TLI，或共享内存VP的数量，意即系统将为每一轮询线索启动一个NET类VP<br /><br />      如果如下设置NETTYPE<br /><br />      sockcp,2,10,NET<br /><br />      系统会启动两个SOC VP。<br /><br />      注意每一轮询线索能支持的连接数即为最大用户数，所以上例中的设置能支持20个用户。请不要超过最大用户限制，否则会给轮询线索带来许多负担。<br /><br />      配置CPU VP<br /><br />      正确配置CPU VP的数量对于系统的性能有很大的影响。系统需要有足够多的CPU VP来加速线索的执行从而保证系统中其它进程能占用足够的CPU时间。<br /><br />      具体的配置方法如下：<br /><br />      利用onstat -g rea 命令监控线索就绪队列。检查CPU VP类线索的数目是否总是大于CPU VP地数量。若是，则表明总是有有一些CPU线索在等待CPU VP，应该增加CPU VP数量。<br /><br />      命令onstat -glo可以显示CPU VP的信息。<br /><br />      从系统的角度来说应随时监控分析CPU的使用情况，以了解系统是否还要潜力可挖。有很多系统提供这一类工具，例如sar。只要有CPU空闲时间或I/0等待时间，就说明可以增加CPU VP数量以完成更多的任务（在相同时间内）。但如果系统CPU资源已充分利用，增加CPU VP的数量也不会提高系统性能。<br /><br />      处理器绑定<br /><br />      所谓处理器绑定（processor affinity)是特定的进程只能在特定的CPU上执行。特定的CPU仍然能为其它进程服务，但特定的进程只能在该CPU上执行，如果平台支持，INFORMIX动态服务器可以将CPU VP（oninit)绑定到指定的处理器上。<br /><br />      处理器从0开始连续编号。在某些SMP平台上，由一个CPU专门处理系统中断。如果配置的CPU VP数量小于物理处理器数量，则应避免将CPU VP绑定到处理中断的CPU上。利用mpstat 命令可以查出那一个CPU处理中断（由intr列标识）。<br /><br />      如果系统用户非常多（&gt;300).用户进程可能会与CPU VP争夺处理器。此时可以将CPU VP绑定到一些处理器上，而将用户进程绑定到另外的处理器上。例如，系统有16个CPU，则将CPU VP绑定到0至10号CPU上，而将所有的应用进程绑定到11-15号进程上。如何在这两类进程分配CPU数目，需要通过测试才能达到较优的性能。<br /><br />      配置环境<br /><br />      共享内存参数的最优配置依赖于动态服务器的运行环境。我们讨论的系统运行环境包括：数据载入，索引建立，OLTP和DSS。在实际的系统中，最好为上述不同的环境分别建立参数配置文件<br /><br />      例如：<br /><br />      数据载入:     onconfig.load<br /><br />      索引建立:     onconfig.index<br /><br />      OLTP:       onconfig.oltp<br /><br />      DSS:        onconfig.dss<br /><br />OnLine的操作模式      <br /><br />        off-Line（离线模式）          <br /><br />         Quiescent（静态模式）          <br /><br />        On_Line（联机模式）          <br /><br />        Shutdown（关闭模式）          <br /><br />        Recovery（恢复模式）<br /><br />      OnLine系统有以下几种工作模式<br /><br />      脱机模式：    OnLine没有运行，共享内存没有分配<br /><br />      初始化模式：   一种过渡模式，发生在OnLine进行初始化，脱机模式到静态模式转换过程中。<br /><br />      静态模式：    oninit进程正在运行，共享内存资源已经分配，但是系统不允许数据库用户对数据库进行存取操作，只有管理员（由informix登陆的用户）能够存取                  OnLine系统。<br /><br />      联机模式：    系统启动并且运行，数据库用户可以正常使用系统<br /><br />      关闭模式：    系统已启动并且正在运行，当前的用户可以继续使用系统，但是新的用户不允许使用系统<br /><br />      恢复模式：   系统正在进行快速恢复，或者由系统归档数据进行恢复。快速恢复是offline模式向静态模式转换过程的过程中发生。这个恢复过程需要一些时间，这个时间和要恢复的数据量的大小有关。<br /><br />      2.普通OnLine进程<br /><br />      INFORMIX-OnLine动态服务器使用几个叫oninit的进程来进行自身的操作。通常系统中都会有几个oninit进程存在；每一个进程都被称为OnLine系统的一个虚拟处理器。<br /><br />      oninit进程是作为root来运行的。这是虚拟处理器初始化任务必须要使用的用户权限，另外，由于oninit进程时作为root用户来运行的，所以对于保护进程是有利的，因为普通用户不能够kill掉root用户的进程。<br /><br />      onstat工具能够读取并报告OnLine系统的共享内存结构，-g glo选项会显示单独的oninit进程的信息，其中包括进程的ID,虚拟处理器的类，用户CPU，和系统CPU的情况。<br /><br />      $ onstat -g glo<br /><br />      3.UNIX级别的共享内存<br /><br />      UNIX命令ipcs可以用来检查操作系统级别的共享内存段和信号量分配情况。有的平台上可能没有这个命令<br /><br />      ipcs命令会打印出当前你的系统中处于活动状态的共享内存的信息。对每一个资源，这个命令会显示：<br /><br />      TYPE        包括信息队列（q），共享内存段（m),或者信号灯（s)。<br /><br />      ID         资源条目的唯一的表示号<br /><br />      KEY        应用程序存取资源使用的参数。<br /><br />      MODE        存取模式和许可权限的标记<br /><br />      OWNER and GROUP   登录名和用户属主的组号，OnLine使用的所有的共享内存资源的属主的属主为root和informix组。<br /><br />      OnLine共享内存使用的基本键值为0x52564801。SERVERNUM的值乘上0X10000并且加上这个值就为共享内存的键值。这就是，如果你的SERVERNUM的值为2，你的共享内存段的键值为0x52564801+(2*0x10000)=0x52584801。如果SERVERNUM的值为6，产生的键值就为0x525c4801。<br /><br />      4.更改运行模式：MODE菜单<br /><br />      $ onmonitor<br /><br />      使用onmonitor命令的主菜单中的mode菜单可以显示如下的mode选项：<br /><br />      startup     将OnLine从离线状态带到静态模式。它会启动OnLine进程并且分配共享内和信号量资源。<br /><br />      On_Line   将系统由静态模式变为联机模式。在这种模式下用户可以使用系统。<br /><br />      Graceful-Shutdown   被用来将系统由联机模式变为静态模式。这个命令让当前的用户继续工作但是拒绝新的用户使用系统。当所有的用户离开系统，就将系统变为静态        模式。5分钟显示一次当前的用户列表。<br /><br />      Immediate-Shutdown  用来将系统由联机模式立即转换为静态模式。并且中断当前所有活动用户的操作，回滚任何打开的事务，并且将系统变为静态模式。<br /><br />      Take_Offline     被用来将系统由静态模式变为离线模式。如果当前系统处于联机模式，首先要进行immediate-Shutdown操作。<br /><br />      ５.恢复模式<br /><br />      在两种环境下，OnLine的操作模式会为恢复模式：      <br /><br />        在恢复进行当中，系统会处于快速恢复模式直到恢复完成。<br /><br />        在快速恢复中。<br /><br />        6.使用oninit工具来改变OnLine模式<br /><br />      oninit工具可以用来改变OnLine系统的操作模式。oninit工具的参数如下：<br /><br />      oninit    将OnLine由离线模式变为联机模式<br /><br />      oninit -s   将OnLine由离线模式变为静态模式<br /><br />      oninit -i   初始化OnLine的root dbspace。<br /><br />      oninit -p   在共享内存初始化的时候不搜寻和删除临时表。<br /><br />      oninit -y   在系统提示的时候自动回答yes。<br /><br />       警告：在通常情况下不要使用-i参数。因为它会破坏现有的所有数据。<br /><br />      提示：如果你想要在你的机器重启动的时候就自动启动OnLine系统到联机模式，你可以将oninit命令，加入到你的系统的启动脚本中（多数UNIX机器是/etc/rc)。<br /><br />      7.使用onmode工具来更改OnLine模式 <br /><br />      使用命令onmode可以改变OnLine系统的操作模式：<br /><br />      -k   执行一个Immediate-Shutdown并且将系统由静态模式变为离线模式。<br /><br />      -m   将系统由静态模式变为联机模式<br /><br />      -s   执行一个graceful_Shutdown.<br /><br />      -u   执行一次Immediate-Shutdown<br /><br />      -y   对所有的提示自动回答yes，必须和其他的选项一起使用。<br /><br />      onmode命令还有许多其他和OnLine系统操作模式无关的的参数<br /></p>
<img src ="http://www.blogjava.net/joaquin25/aggbug/215862.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-18 16:49 <a href="http://www.blogjava.net/joaquin25/articles/215862.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix培训教材整理之监视OnLine性能</title><link>http://www.blogjava.net/joaquin25/articles/215861.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Fri, 18 Jul 2008 08:49:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/215861.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/215861.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/215861.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/215861.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/215861.html</trackback:ping><description><![CDATA[missing to be add later.<img src ="http://www.blogjava.net/joaquin25/aggbug/215861.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-18 16:49 <a href="http://www.blogjava.net/joaquin25/articles/215861.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Informix培训教材整理之OnLine的设置对性能的影响</title><link>http://www.blogjava.net/joaquin25/articles/215858.html</link><dc:creator>joaquin25</dc:creator><author>joaquin25</author><pubDate>Fri, 18 Jul 2008 08:48:00 GMT</pubDate><guid>http://www.blogjava.net/joaquin25/articles/215858.html</guid><wfw:comment>http://www.blogjava.net/joaquin25/comments/215858.html</wfw:comment><comments>http://www.blogjava.net/joaquin25/articles/215858.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/joaquin25/comments/commentRss/215858.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/joaquin25/services/trackbacks/215858.html</trackback:ping><description><![CDATA[转自：<a href="http://unix-cd.com/unixcd12/article_5448.html">http://unix-cd.com/unixcd12/article_5448.html</a><br /><br />系统与原始磁盘空间<br /><br />      应使用原始磁盘空间，不要使用文件系统空间。原始磁盘空间意味着通过一个字符模式特殊文件（在ls -l 命令显示的第一列总出现的一个<i>'</i>c<i>'</i>)访问一个原始磁盘分区，不是指磁盘空间相关联的块模式特殊文件（为ls-l 命令显示的第1列为<i>'</i>b<i>'</i>)，也不是指卷管理控制设备以及其它任何不是原始磁盘分区的设备。<br /><br />      更新统计<br /><br />      这是十分重要的。当相关各列上的数值分布发生明显变化时，适时运行UPDATE STATISTICS命令后能使数据分布和统计数据得到更新。<br /><br />      对建有索引的列运行UPDATE STATISTICS HIGH，对其它所有列使用UPDATE STATISTICS MEDIUM.由于UPDATE STATISTICS处理的内部并行程度低，因而使用多个并发任务进行更新统计会改善全局的吞吐量。可能需要增加DBUPSPACE 环境变量的值。<br /><br />      预读<br /><br />      对非并行顺序扫描（只对数据、只按索引，按索引/数据）十分有用。通过onstat -p监测。如果ixda-RA,idx_RA及da_RA的总和与RA-pgsused接近，则要增加预读参数，如果它们的总和远远小于RA-pgsused,则要减小相应参数，通常保持RA_PAGES&lt;=32,并使RA_THRESHOLD大约等于PA_PAGES的一半。<br /><br />      OLTP与DSS<br /><br />      OLTP的特点：<br /><br />      用户多<br /><br />      高事务率<br /><br />      在数据处理方面，事务相对较小<br /><br />      明显的页操作（插入/更新/删除）<br /><br />      通过索引的快速数据访问<br /><br />      高度使用缓冲区快速缓存<br /><br />      并行范围有限<br /><br />          DSS特点<br /><br />      涉及大量数据<br /><br />      很少的写操作（除临时空间和数据加载之外）<br /><br />      用户相对较少<br /><br />      处理大批数据的大量、复杂查询<br /><br />      主要通过顺序扫描访问数据<br /><br />      并行范围广<br /><br />      磁盘分布与分片<br /><br />      磁盘硬件的选项：<br /><br />      传输速度高，定位时间少<br /><br />      大量的小盘比少量的大盘好<br /><br />      避免控制器过载<br /><br />       将Online磁盘空间与其它系统操作分开<br /><br />      文件系统<br /><br />      交换空间<br /><br />      将物理、逻辑日志分开<br /><br />      对于有大量的写操作（插入、更新、删除）的任何Online应用环境应将逻辑和物理日志分别放在不同的磁盘/控制器上。在放置物理、逻辑日志的磁盘上不要再放其它数据。<br /><br />      将逻辑日志放在不同的磁盘上<br /><br />      避免当前日志于各份日志之间出现冲突      <br /><br />      减少磁头移动       <br /><br />      如果可能的话，控制原始分区的分配以减少磁头的移动      <br /><br />      控制表分割       <br /><br />      尽量防止表分为多个段（extent),这对OnLine 5.0及以前的各版十分重要。      <br /><br />      避免过多的chunk<br /><br />      即使没有dirty页，大量的chunk也会明显增加检查点的时间。<br /><br />      明智地使用数据分片       <br /><br />        不要对小表进行分片<br /><br />        不要对所有的表进行分片<br /><br />        确定数据量大且频繁访问重要表<br /><br />        将表的每个分片放在单独的磁盘上<br /><br />        使用轮转（round robin)方式分割索引要小心      <br /><br />      　OLTP--轮询方式分割数据，分离（也可分割）索引<br /><br />      　通常为使OLTP性能最佳，要考虑用轮询方式将使用高的大表分割到不同磁盘的DBSPACE中（为分散多个磁盘间I/O)。这些表的索引也应明确地生成在特定的dbspace上（与数据不同的磁盘上)。也可以按表达式进行分片。<br /><br />      DSS--轮转或基于表达式方式分割数据，无索引或尽量少<br /><br />      通常为使DSS性能最佳，考虑哪种方式分割大表最好，是轮询还是表达式方式，对不同的表使用不同的分片方式，其目标是为了平衡总体I/O，并可以使优化器对频繁运行的查询消除对不必要分片的扫描<br /><br />      基于表达式方式分片<br /><br />      表达式应该简洁。对给定的dbspace，首先使用最有约束力的、限制条件最多的表达式：<br /><br />   例如使用x&lt;=10 and x&gt;=1 in dbspace1,而不要使用x&gt;=1 and x&lt;=10 in dbspace1。        将访问频度高的 dbspace放在访问频度低的dbspace前<br /><br />        避免使用进行类型转换的表达式<br /><br />        不要按经常改换值得列进行分片<br /><br />        在分片间进行的移动要付出额外的开销<br /><br />        仔细选择表达式<br /><br />        为了均衡I/O负载，而不是数据量<br /><br />        为了帮助消除查询中无需扫描的段<br /><br />        避免使用REMAINDER IN子句      <br /><br />      使用多个数据库临时空间（DBSPACETEMP)<br /><br />      如果DBSPACETEMP列出多个dbspace的话，将大大并行涉及临时空间的操作。如使用多个临时dbspace，将它们放在与其它活动频繁的dbspace不同、且彼此分开的磁盘上。       <br /><br />      OPTCOMPIND<br /><br />      OLTP--设置为0<br /><br />      对OLTP，应避免使用散列（hash)连接，因为该连接方式将大量消耗处理器资源。<br /><br />      DSS--设置为2<br /><br />      对DSS，散列连接可以提供很好的连接性能。       <br /><br />      LRUS最少4，否则等于NUMCPUVPS       <br /><br />      缓冲区<br /><br />      对OLTP而言，需要较大的缓冲区池和较高的缓存命中率<br /><br />      对典型的OLTP工作负载，当大量访问在系统的缓存中的页时可以获得最好的性能，为了实现这点需要有大小合适的缓存区。通过onstat -p可以显示出缓存的效率，它将显示读、写的快速缓存命中百分率。在可用内存的限制下，要尽可能地提高该数字，通常获得95％以上的读命中率和85以上的写命中率是可能的。<br /><br />      对DSS而言，通常一个较小的缓冲区就够了<br /><br />      对典型的DSS工作负载，多数数据访问是有light scan扫描完成的，而不通过缓冲池，造成不需要使用大量缓冲池的后果。内存应由DS_TOTAL_MEMORY分配，以便有足够的内存用于扫描缓冲区，散列连接等。       <br /><br />      Bufferd Logging 与UnBuffered Logging<br /><br />      Bufferd Logging 比UnBuffered Logging性能好<br /><br />      使用Buffered Logging,逻辑日志缓冲区只在充满时才向磁盘刷新。使用UnBuffered Logging,每次事务提交都会强制一次日志缓冲区刷新。注意由于逻辑日志缓冲区对所有的数据库是公用的，所以即使仅有一个活动频繁的数据库使用非缓冲日志也会大大降低使用缓冲日志带来的益处。<br /><br />      Buffered Logging 不如 UnBufferd Logging安全<br /><br />      由于日志缓冲区充满时才进行刷新，如果系统出现故障，则日志缓冲区的内容会被丢失。当然发生故障时，缓冲区会良好保存未写向磁盘的提交记录，Online快速恢复将回滚这些事务。所有数据库自身保持一致，而从应用程序的观点看，应用程序认为已经成功提交的事务实际上却回滚了，这是不一致的。       <br /><br />      CKPTINTVL参数<br /><br />      正常操作期间，两个主要的事件会导致检查点发生：超过检查点时间间隔或是物理日志75％已充满。在检查点间的工作量决定了系统故障后快速恢复所需要的时间长短。<br /><br />      如果恢复时间十分重要，则应设置检查点间隔以使恢复时间可以接受，否则可以加长时间间隔，从而让系统根据物理日志充满度（75％）来决定何时生成检查点。<br /><br />        连接<br /><br />      客户机－－－－数据库服务器和数据库服务器－－－－客户机<br /><br />      选择最佳的通讯机制<br /><br />      本地客户机：共享内存和管道<br /><br />      对于与服务器运行在同一主机上的客户机，应选择共享内存（ipcshm)或管道（ipcstr)方式。管道通常要比共享内存方式更快、更灵活、更安全、避免让本地客户使用网络连接（TCP/IP)，因为那样比ipcshm或ipcstr连接性能要大大降低。<br /><br />      远端客户机：TCP/IP<br /><br />      远端客户要使用TCP/IP,只有在特殊情况下才使用Netware IPX/SPX进行连接。改变缓冲区大小（FET_BUF_SIZE环境变量）以及socket缓冲区大小（在sqlhosts文件中设置）观察其效果。使用前面叙述的方法减少客户机/服务器间的交换量。<br /><br />      轮询线索和网络VP<br /><br />      轮询线索处理从客户机送来的数据<br /><br />      从服务器到客户机的数据是由各自的sqlexec线索来发送的。<br /><br />      一个轮询线索可以处理大约200个典型客户机<br /><br />      数目要依许多因素而定，此处只是个原则数字。<br /><br />      对大量非常活跃的客户，或大量的数据输入可能需要更多的轮询线索。<br /><br />      轮询线索在CPU虚处理器（内联轮询）（inline poll)或NET VP中。<br /><br />      任意时刻，只有一个“内联”的协议<br /><br />        内联轮询线索<br /><br />      客户数目越少，性能越好<br /><br />      可以帮助TCP/IP<br /><br />      增加CPU VP额外开支<br /><br />      不可有多于CPU VP数目的轮询线索<br /><br />      用于轮询线索的NET VP<br /><br />      对大量的客户而言，可能会提供更好的性能<br /><br />      想要多少就可以有多少轮询线索<br /><br />      可减轻CPU VP的工作负荷<br /><br />      监视会话<br /><br />      可以用onstat 及SMI监视会话<br /><br />      应检查有问题的会话过程<br /><br />      线索的数目<br /><br />      磁盘I/O<br /><br />      内存的使用情况<br /><br />      SQL语句<br /><br />       SINGLE_CPU_VP标志<br /><br />      让系统消除一些互斥操作<br /><br />       如只使用一个CPU虚处理器，并确信不需要再动态增加，一定要设置ONCONFIG文件中的SINGLE_CPU_VP标志为ON。这样可以让Online <br /><br />        消除许多用于内部CPU VP同步的互斥调用 <br /><img src ="http://www.blogjava.net/joaquin25/aggbug/215858.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/joaquin25/" target="_blank">joaquin25</a> 2008-07-18 16:48 <a href="http://www.blogjava.net/joaquin25/articles/215858.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>