高级 Linux 命令精通指南

作者:Arup Nanda Oracle ACE

2006 年 8 月发布

在 Sheryl Calish 撰写的“Linux 文件命令精通指南” 这篇出色的文章中,您学习到了一些对于 Linux 新手尤为重要的常用 Linux 命令。既然您现在已经掌握了基础知识,下面我们将介绍一些更为复杂但却非常有用的命令。

在这个共分 4 个部分的文章系列中,您将学习各种常用命令的一些并不被人们所熟知的使用技巧,以及可以使这些命令更为有用的用法变化形式。在学习本文章系列过程中,您将先后了解一些难于掌握的命令。

注意,根据您所使用的 Linux 的特定版本或编译的特定内核,这些命令可能会存在差别,但即便如此,这种差别也很小。

轻松更改所有者、组和权限

在 Sheryl 的文章中,您学习了如何使用 chown 和 chgrp 命令来更改文件的所有权和组。假设有如下几个文件:

# ls -l

total 8

-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1

-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file2

-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file3

-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file4

-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file5

-rwxr-xr-x 1 oracle dba 132 Aug 4 04:02 file6

并且您需要更改所有文件的权限以便与 file1 的权限匹配。当然,您可以执行 chmod 644 * 来进行此更改,但如果您要编写一个脚本来执行该操作,而事先却并不知道这些权限,那该怎么办?或者,您可能要基于许多不同的文件进行多个权限更改,但却发现逐个使用这些文件的权限并进行相应的修改并不可行。

一种更好的方法是使权限类似于另一个文件的权限。以下命令使 file2 的权限与 file1 相同:

chmod --reference file1 file2 

现在,如果您查看以下示例:

# ls -l file[12]

total 8

-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1

-rw-r--r-- 1 oracle dba 132 Aug 4 04:02 file2

file2 的权限完全按照 file1 中的权限进行了更改。您不必先获取 file1 的权限。

您还可以将同一技巧用于文件中的组成员关系。要使 file2 的组与 file1 相同,可以执行以下命令:

# chgrp --reference file1 file2

# ls -l file[12]

-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1

-rw-r--r-- 1 oracle users 132 Aug 4 04:02 file2

当然,适用于更改组的方法也同样适用于所有者。下面演示了如何将同一技巧用于所有权更改。如果权限如下所示:

# ls -l file[12] 

-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1

-rw-r--r-- 1 oracle dba 132 Aug 4 04:02 file2

则可以按以下方式更改所有权:

# chown --reference file1 file2

# ls -l file[12]

-rw-r--r-- 1 ananda users 70 Aug 4 04:02 file1

-rw-r--r-- 1 ananda users 132 Aug 4 04:02 file2

注意,组和所有者已经更改。

适用于 Oracle 用户的技巧

您可以使用该技巧根据某个参考可执行文件更改目录中 Oracle 可执行文件的所有权和权限。该技巧对于移植非常有用,在移植期间您可以(并且可能应该)以不同的用户身份安装文件,并在以后将这些文件转移至常规的 Oracle 软件所有者。

有关文件的详细说明

ls 命令及其许多参数提供了一些非常有用的文件信息。另一个不太为人所熟知的命令 stat 提供了一些更为有用的信息。

下面演示了如何对可执行文件“oracle”(位于 $ORACLE_HOME/bin 目录下)使用此命令。

# cd $ORACLE_HOME/bin

# stat oracle

File: `oracle'

Size: 93300148 Blocks:182424 IO Block:4096 Regular File

Device: 343h/835d Inode: 12009652 Links: 1

Access: (6751/-rwsr-s--x) Uid:( 500/ oracle) Gid:( 500/ dba)

Access: 2006-08-04 04:30:52.000000000 -0400

Modify: 2005-11-02 11:49:47.000000000 -0500

Change: 2005-11-02 11:55:24.000000000 -0500

注意使用该命令获得的信息:除了通常的文件大小(也可以使用 ls -l 命令获得)以外,您还获得了该文件占用的块数。通常的 Linux 块大小为 512 字节,因此一个大小为 93,300,148 字节的文件将占用 (93300148/512=) 182226.85 个块。由于块都是完整占用,因此该文件使用了一些整数个数的块。无需猜测就可以获得确切的块数。

您还可以从以上输出中获得文件所有权的 GID 和 UID,以及权限的八进制表示形式 (6751)。如果要将文件恢复到它现在具有的相同权限,可以使用 chmod 6751 oracle ,而不是显式拼写这些权限。

以上输出最有用的部分是文件访问时间戳信息。该输出显示,该文件被访问的时间是 2006-08-04 04:30:52(显示在“Access:”的旁边),即 2006 年 8 月 4 日上午 4:30:52。这是某个人开始使用数据库的时间。该文件的修改时间是 2005-11-02 11:49:47(显示在“Modify:”的旁边)。最后,“Change:”旁边的时间戳显示文件状态更改的时间。

stat 命令的修改符 -f 显示了有关文件系统(而非文件)的信息:

# stat -f oracle

File: "oracle"

ID: 0 Namelen:255 Type:ext2/ext3

Blocks: Total: 24033242 Free: 15419301 Available: 14198462 Size: 4096

Inodes: Total: 12222464 Free: 12093976

另一个选项 -t 显示了完全相同的信息,只不过是在一行中显示的:

# stat -t oracle 

oracle 93300148 182424 8de9 500 500 343 12009652 1 0 0 1154682061

1130950187 1130950524 4096

这对 shell 脚本非常有用,在 shell 脚本中可以使用一个简单的 cut 命令获得值以进行进一步处理。

适用于 Oracle 用户的技巧

重新链接 Oracle(通常在安装补丁过程中执行)时,将在创建新的可执行文件之前将现有可执行文件的名称更改为其他名称。例如,可以使用以下命令重新链接所有实用程序

relink utilities

该命令对 sqlplus 可执行文件进行重新编译,此外还执行其他操作。它将现有的可执行文件 sqlplus 命名为 sqlplusO。如果重新编译由于某种原因失败,则 relink 进程会将 sqlplusO 重命名为 sqlplus,并撤销更改。同样,如果在应用补丁后发现功能问题,则可以通过手动重命名文件来快速撤销补丁。

下面演示了如何对这些文件使用 stat:

# stat sqlplus*

File: 'sqlplus'

Size: 9865 Blocks:26 IO Block:4096 Regular File

Device: 343h/835d Inode:9126079 Links: 1

Access: (0751/-rwxr-x--x) Uid:( 500/ oracle) Gid:( 500/ dba)

Access: 2006-08-04 05:15:18.000000000 -0400

Modify: 2006-08-04 05:15:18.000000000 -0400

Change: 2006-08-04 05:15:18.000000000 -0400



File: 'sqlplusO'

Size: 8851 Blocks:24 IO Block:4096 Regular File

Device: 343h/835d Inode:9125991 Links: 1

Access: (0751/-rwxr-x--x) Uid:( 500/ oracle) Gid:( 500/ dba)

Access: 2006-08-04 05:13:57.000000000 -0400

Modify: 2005-11-02 11:50:46.000000000 -0500

Change: 2005-11-02 11:55:24.000000000 -0500

输出显示 sqlplusO 的修改时间是 2005 年 11 月 11 日,而 sqlplus 的修改时间是 2006 年 8 月 4 日,该时间也是 sqlplusO 的状态更改时间。该输出表明,sqlplus 的原始版本从 2005 年 11 月 11 到 2006 年 8 月 4 日这段时间内一直正常运行。如果要诊断某些功能问题,则该信息将是一个非常不错的起点。除了文件更改以外,如果您知道权限的更改时间,则可以将它与发觉的 任何功能问题联系起来。

另一个重要的输出是文件大小,不同的文件存在不同的大小(sqlplus 的大小为 9865 字节,而 sqlplusO 的大小为 8851),这表明版本不仅仅经过重新编译,实际上这些版本通过其他库进行了更改(也许是这样)。文件大小的不同还指示了某些问题的可能原因。

文件类型

查看文件时,如何知道它的文件类型?命令 file 可以显示文件类型。例如:

# file alert_DBA102.log

alert_DBA102.log:ASCII text

文件 alert_DBA102.log 是一个 ASCII 文本文件。来看看更多示例:

# file initTESTAUX.ora.Z

initTESTAUX.ora.Z:compress'd data 16 bits

该示例指示文件是压缩文件,但如何知道文件的压缩类型?方法之一是将该文件解压缩并再次运行它;但这实际上是几乎不可能的。一种更简便的方法是使用参数 -z

# file -z initTESTAUX.ora.Z

initTESTAUX.ora.Z:ASCII text (compress'd data 16 bits)

另一种方法是显示符号链接:

# file spfile+ASM.ora.ORIGINAL   

spfile+ASM.ora.ORIGINAL:symbolic link to

/u02/app/oracle/admin/DBA102/pfile/spfile+ASM.ora.ORIGINAL

尽管该方法很有用,但所指向的文件的类型是什么?可以使用选项 -l ,而不必再次运行文件:

# file -L spfile+ASM.ora.ORIGINAL

spfile+ASM.ora.ORIGINAL:data

该示例清楚地表明该文件是数据文件。注意,与 init.ora 不同的是,spfile 文件是一个二进制文件;因此文件显示为数据文件。

适用于 Oracle 用户的技巧

假设您要在用户转储目标目录中搜索某个跟踪文件,但不知道该文件是否位于其他目录并只以一个符号链接形式存在,或某个人是否压缩了该文件(甚至对其进行了重命名)。有一点您是知道的:该文件肯定是一个 ascii 文件。下面演示了如何执行操作:

file -Lz * | grep ASCII | cut -d":"-f1 | xargs ls -ltr

该命令将检查 ASCII 文件(即使它们经过了压缩)并按时间顺序将其列出。

比较文件

如何判断两个文件(file1 和 file2)是否相同?方法有多种,每种方法都有其自身的优点。

diff 最简单的命令是 diff ,用于显示两个文件之间的差别。以下是这两个文件的内容:

# cat file1

In file1 only

In file1 and file2

# cat file2

In file1 and file2

In file2 only

使用 diff 命令能够了解这两个文件之间的差别,如下所示:

# diff file1 file2

1d0

< In file1 only

2a2

> In file2 only

#

在以上输出中,第一列中的“<”表示该行位于上面最先提到的文件(即 file1)中。第一列中的“>”表示该行位于第二个文件 (file2) 中。输出第一行中的字符 1d0 显示为了作用于文件 file1(以使其与 file2 相同)而在 sed 中必须执行的操作。

另一个选项 -y 显示了相同的输出,只不过输出是并排显示的:

# diff -y file1 file2 -W 120

In file1 only <

In file1 and file2 In file1 and file2

> In file2 only



-W 选项是可选的;它仅指示该命令使用宽度为 120 个字符的屏幕输出,这对于包含长行的文件很有用。

如果只希望了解文件是否不同,而不必知道如何不同,则可以使用 -q 选项。

# diff -q file3 file4

# diff -q file3 file2

Files file3 and file2 differ

由于文件 file3 和 file4 相同,因此没有输出;在另一个示例中,将报告文件存在差别。

如果要编写 shell 脚本,则采用以下方式生成可以分析的输出可能比较有用。-u 选项可以执行该操作:

# diff -u file1 file2        

--- file1 2006-08-04 08:29:37.000000000 -0400

+++ file2 2006-08-04 08:29:42.000000000 -0400

@@ -1,2 +1,2 @@

-In file1 only

In file1 and file2

+In file2 only

以上输出显示了这两个文件的内容,但并未显示重复内容,第一列中的 + 号和 - 号指示文件中的行。第一列中的任何字符均未指示这两个文件中同时存在的内容。

该命令可以识别空格。如果要忽略空格,请使用 -b 选项。使用 -B 选项忽略空白行。最后,使用 -i 忽略大小写。

diff 命令还可以应用于目录。命令

diff dir1 dir2

显示文件文件存在于任一目录中;无论文件是存在于这两个目录中的一个,还是同时存在于这两个目录中。如果它找到同名的子目录,则不会继续查看任何单个文件是否存在差别。示例如下:

# diff DBA102 PROPRD     

Common subdirectories:DBA102/adump and PROPRD/adump

Only in DBA102:afiedt.buf

Only in PROPRD:archive

Only in PROPRD:BACKUP

Only in PROPRD:BACKUP1

Only in PROPRD:BACKUP2

Only in PROPRD:BACKUP3

Only in PROPRD:BACKUP4

Only in PROPRD:BACKUP5

Only in PROPRD:BACKUP6

Only in PROPRD:BACKUP7

Only in PROPRD:BACKUP8

Only in PROPRD:BACKUP9

Common subdirectories:DBA102/bdump and PROPRD/bdump

Common subdirectories:DBA102/cdump and PROPRD/cdump

Only in PROPRD:CreateDBCatalog.log

Only in PROPRD:CreateDBCatalog.sql

Only in PROPRD:CreateDBFiles.log

Only in PROPRD:CreateDBFiles.sql

Only in PROPRD:CreateDB.log

Only in PROPRD:CreateDB.sql

Only in DBA102:dpdump

Only in PROPRD:emRepository.sql

Only in PROPRD:init.ora

Only in PROPRD:JServer.sql

Only in PROPRD:日志

Only in DBA102:oradata

Only in DBA102:pfile

Only in PROPRD:postDBCreation.sql

Only in PROPRD:RMANTEST.sh

Only in PROPRD:RMANTEST.sql

Common subdirectories:DBA102/scripts and PROPRD/scripts

Only in PROPRD:sqlPlusHelp.log

Common subdirectories:DBA102/udump and PROPRD/udump

注意,普通的子目录只按这种方式报告,而不进行比较。如果要进一步深究,并比较这些子目录中的文件,则应使用以下命令:

diff -r dir1 dir2

该命令将采用递归方式进入每个子目录,以比较文件并报告同名文件之间的差别。

适用于 Oracle 用户的技巧

diff 的一种常见用法是区分不同的 init.ora 文件。作为一种最佳实践,我在更改之前通常对文件进行复制并重命名(例如,将 initDBA102.ora 复制并重命名为 initDBA102.080306.ora 以表示 2006 年 8 月 3 日)。文件所有版本之间的一个简单的 diff 就可以快速指出哪些内容发生更改以及更改时间。

这是一个非常强大的用于管理 Oracle 根目录的命令。作为最佳实践,我在应用补丁时从不更新 Oracle 根目录。例如,假设当前的 Oracle 版本为 10.2.0.1。ORACLE_HOME 可能为 /u01/app/oracle/product/10.2/db1。当需要将它更新为 10.2.0.2 时,我不会对此 Oracle 根目录打补丁。相反,我将在 /u01/app/oracle/product/10.2/db2 上启动一个全新的安装,然后对该根目录打补丁。准备就绪后,我使用以下命令:

# sqlplus / as sysdba

SQL> shutdown immediate

SQL> exit

# export ORACLE_HOME=/u01/app/oracle/product/10.2/db2

# export PATH=$ORACLE_HOME/bin:$PATH

# sqlplus / as sysdba

SQL> @$ORACLE_HOME/rdbms/admin/catalog



...

等等。

该方法的目的是不破坏原始的 Oracle 根目录,因此我可以在出现问题时轻松地进行恢复。这还意味着数据库关闭并再次启动,而且瞬间即可完成。如果我将补丁直接安装到 Oracle 根目录上,则必须长时间(补丁应用的整个持续时间)关闭数据库。此外,如果补丁应用由于某种原因出现故障,则不必清理 Oracle 根目录。

既然有多个 Oracle 根目录,那如何查看哪些内容发生了更改?方法其实很简单,我可以使用以下命令:

diff -r /u01/app/oracle/product/10.2/db1 /u01/app/oracle/product/10.2/db2 | 

grep -v Common

该命令显示了两个 Oracle 根目录之间的差别,以及同名文件之间的差别。某些重要的文件(如 tnsnames.ora、listener.ora 以及 sqlnet.ora)不会有太大的差别,但如果差别很大,那么我就需要知道差别的原因。

cmp. 命令 cmp 类似于 diff

# cmp file1 file2   

file1 file2 differ:byte 10, line 1

只要遇到差别就会返回输出。可以使用此输出标识文件在何处可能存在差别。与 diff 一样,cmp 有很多选项,其中最重要的选项是 -s 选项,它只返回一个代码:

  • 如果文件相同,则返回 0
  • 如果文件不同,则返回 1
  • 如果无法进行比较,则返回某个非零数字

示例如下:

# cmp -s file3 file4

# echo $?

0

特殊变量 $? 指示返回代码来自上次执行的命令。在本示例中,该变量为 0,表示文件 file1 和 file2 相同。

# cmp -s file1 file2

# echo $?

1

表示 file1 和 file2 不同。

cmp 的这个属性对于 shell 脚本非常有用,因为在 shell 脚本中您只希望检查两个文件是否存在差别,而不必检查差别是什么。该命令的另一个重要用途是比较二进制文件,而 diff 对于比较二进制文件可能并不可靠。

适用于 Oracle 用户的技巧

回顾一下上一个提示,当您重新链接 Oracle 可执行文件时,旧版本在被覆盖之前将一直保留。因此,在重新链接时,可执行文件 sqlplus 重命名为“sqlplusO”,并且新编译的 sqlplus 置于 $ORACLE_HOME/bin 中。那么,如何确保刚刚创建的 sqlplus 存在差别?只需使用以下命令:

# cmp sqlplus sqlplusO

sqlplus sqlplusO differ:byte 657, line 7

如果检查大小:

# ls -l sqlplus*

-rwxr-x--x 1 oracle dba 8851 Aug 4 05:15 sqlplus

-rwxr-x--x 1 oracle dba 8851 Nov 2 2005 sqlplusO

即使这两个示例中的大小完全相同,cmp 也可以证明这两个程序存在差别。

comm. 命令 comm 与其他命令相似,只是输出分三列显示,并且列之间由制表符分隔。示例如下:

# comm file1 file2

In file1 and file2

In file1 only

In file1 and file2

In file2 only

本部分中的命令摘要


命令用途

chmod

使用 - -reference 参数更改文件权限

chown

使用 - -reference 参数更改文件所有者

chgrp

使用 - -reference 参数更改文件的组

stat

查找文件的扩展属性,如文件的上次访问时间

file

查找文件类型,如 ASCII、数据等

diff

查看两个文件之间的差别

cmp

比较两个文件

comm

了解两个文件的相同内容,并分三列显示输出

md5sum

计算文件的 MD5 散列值(用于确定文件是否已更改)

如果您想要查看某个文件的内容(另一个文件中不存在这些内容),而不仅仅是差别(SQL 语言中 MINUS 实用程序的排序),则该命令将很有用。-1 选项将不显示在第一个文件中找到的内容:

# comm -1 file1 file2

In file1 and file2

In file2 only

md5sum. 该命令将生成文件的 32 位 MD5 散列值:

# md5sum file1

ef929460b3731851259137194fe5ac47 file1

可以将两个具有相同校验和的文件视为相同。而该命令的用途并不仅仅限于比较文件。它还可以提供一种机制来确保文件的完整性。

假设您有两个需要保护的重要文件,file1 和 file2。可以使用 --check 选项检查并确保文件未更改。首先,为这些重要文件创建校验和文件,然后对其进行安全保存:

# md5sum file1 file2 > f1f2 

以后,当您要验证这些文件是否仍保持不变时,可执行如下操作:

# md5sum --check f1f2      

file1:OK

file2:OK

这清楚地表明文件未被修改。现在,更改一个文件并检查 MD5:

# cp file2 file1

# md5sum --check f1f2

file1:FAILED

file2:OK







在本系列的第 1 部分 中,您学习了一些有用但并不广为人知的命令,以及各种常用命令的一些人们并不熟知的参数,它们可以帮助您更高效地完成工作。继续学习本系列,您将了解到一些对 Oracle 用户(无论是开发人员还是 DBA)很有帮助的更高级的 Linux 命令。

alias 和 unalias

假设您要检查 shell 中设置的 ORACLE_SID 环境变量。您必须键入:

echo $ORACLE_HOME

作为 DBA 或开发人员,您需要频繁使用此命令,很快就会对输入这 16 个字符感到厌倦。有没有更简单的方法?

当然有:您可以使用 alias 命令。使用该方法,您可以创建一个简短的别名(如 "os")来代表整条命令:

alias os='echo $ORACLE_HOME'

现在,每次要检查 ORACLE_SID 时,您只需键入 "os"(没有引号),Linux 就会执行别名代表的命令。

然而,如果您注销并重新登录,别名就不见了,您需要再次输入 alias 命令。要取消这个步骤,您只需将该命令置于 shell 的配置文件中。对于 bash,配置文件为主目录中的 .bash_profile(注意文件名前面的句点,它是文件名的一部分)。对于 bourne 和 korn shell,配置文件为 .profile;对于 c-shell,配置文件为 .chsrc。

您可以使用任何名称创建别名。例如,我总是将 rm -i 命令的别名创建为 rm ,从而使它成为交互式命令。

alias rm=’rm -i’

我每次执行 rm 命令后,如果不输入 "y",Linux 就会提示我进行确认,而不会删除该文件,因此不会出现意外删除重要文件的情况。另外,我也以相同的方式使用 mv (以一个新名称另存该文件,防止意外覆盖现有的文件)和 cp (复制该文件)。

以下是一些我喜欢定义的非常有用的别名:

alias bdump='cd $ORACLE_BASE/admin/$ORACLE_SID/bdump' alias l='ls -d .* --color=tty' alias ll='ls -l --color=tty' alias mv='mv -i' alias oh='cd $ORACLE_HOME' alias os='echo $ORACLE_SID' alias rm='rm -i' alias tns='cd $ORACLE_HOME/network/admin'

要查看 shell 中已定义的别名,使用 alias 即可,无需任何参数。

但这里有一个小问题。我已经定义了一个别名 rm 来执行 rm -i 。每次我试图删除一个文件时,该命令都会提示我进行确认。但如果我要删除多个文件并确信无需确认即可删除时,该怎么办?

解决方案很简单:要取消该别名,然后只使用命令,我需要输入两个单引号:

$ ''rm *

注意,rm 命令前面有两个单引号 ('),而不是两个双引号。这将取消别名 rm 。另一种方法是使用反斜线 (/):

$ /rm *

要删除一个以前定义的别名,只需使用 unalias 命令:

$ unalias rm

ls

ls 是简单的常用命令,但几乎从未发挥其全部潜力。如果不加任何选项,则 ls 仅以表格格式显示所有文件和目录。

$ ls admin has mesg precomp apex hs mgw racg assistants install network rdbms ... output snipped ...

要以列表形式显示所有文件和目录,使用 -1 选项(数字 1,不是字母 "l")。

$ ls -1 admin apex assistants ... output snipped ...

在其中的文件名需要传给另一个程序或命令以进行操作的 shell 脚本中,该选项很有用。

您一定使用过用来显示文件和目录所有属性的 -l 选项(字母 "l",不是数字 "1")。让我们再看看它的作用方式:

$ ls -l total 272 drwxr-xr-x 3 oracle oinstall 4096 Sep 3 03:27 admin drwxr-x--- 7 oracle oinstall 4096 Sep 3 02:32 apex drwxr-x--- 7 oracle oinstall 4096 Sep 3 02:29 assistants

第一列显示了文件类型及文件的权限:"d" 代表目录,"-" 代表普通文件,"c" 代表字符设备,"b" 代表块设备,"p" 代表命名管道,"l"(字母 L 的小写形式,不是 I)代表符号链接。

一个非常有用的选项是 --color,它根据文件类型用多种颜色显示文件。以下是一个示例屏幕截图:

注意,file1 和 file2 是普通文件。link1 是符号链接,显示为红色;dir1 是目录,显示为黄色;pipe1 是命名管道,显示为其它颜色以便于识别。

在某些版本中,ls 命令自带预先安装的别名(在上一部分中进行了描述),如 ls --color; ,因此您键入 "ls" 时将看到彩色的文件。然而,该方法可能并不符合需要,尤其是当您的输出如上所示时。您可以更改颜色,但只需关闭别名就可以更快地达成您的需要:

$ alias ls="''ls"

另一个有用的选项是 -F 选项,它在每个文件后面添加一个符号来显示文件的类型:在目录后面添加 "/",在符号链接后面添加 "@",在命名管道后面添加 "|"。

$ ls -F dir1/ file1 file2 link1@ pipe1|

如果某个目录下面包含一个子目录,您希望只列出该目录,则 ls -l 还将显示该子目录中的内容。例如,假设该目录结构如下所示:

/dir1 +-->/subdir1 +--> subfile1 +--> subfile2

目录 dir1 含有一个子目录 subdir1 和两个文件:subfile1 和 subfile2。如果您只希望查看目录 dir1 的属性,则执行以下命令:

$ ls -l dir1 total 4 drwxr-xr-x 2 oracle oinstall 4096 Oct 14 16:52 subdir1 -rw-r--r-- 1 oracle oinstall 0 Oct 14 16:48 subfile1 -rw-r--r-- 1 oracle oinstall 0 Oct 14 16:48 subfile2

注意,输出中未列出目录 dir1,而是显示了该目录的内容。处理目录时需要该行为。如果仅希望显示 dir1 目录,则需要使用 -d 命令。

$ ls -dl dir1 drwxr-xr-x 3 oracle oinstall 4096 Oct 14 16:52 dir1

如果您注意以下 ls -l 的输出:

-rwxr-x--x 1 oracle oinstall 10457761 Apr 6 2006 rmanO -rwxr-x--x 1 oracle oinstall 10457761 Sep 23 23:48 rman -rwsr-s--x 1 oracle oinstall 93300507 Apr 6 2006 oracleO -rwx------ 1 oracle oinstall 93300507 Sep 23 23:49 oracle

您会发现文件的大小是用字节显示的。显示小文件时,这样做可能很简单。当文件大小很大时,较长的数字可能难以阅读。此时,使用选项 "-h" 以易读的格式来显示大小就很方便了。

$ ls -lh -rwxr-x--x 1 oracle oinstall 10M Apr 6 2006 rmanO -rwxr-x--x 1 oracle oinstall 10M Sep 23 23:48 rman -rwsr-s--x 1 oracle oinstall 89M Apr 6 2006 oracleO -rwx------ 1 oracle oinstall 89M Sep 23 23:49 oracle

注意文件大小是如何用 M(代表兆字节)、K(代表千字节)等显示的。

$ ls -lr

参数 -r 以相反的顺序显示输出。在该命令中,文件将以相反的字母顺序显示。

$ ls -lR

-R 操作符使 ls 命令以递归方式执行,即进入子目录并显示其中的文件。

如果希望按从大到小的顺序显示文件怎么办?使用 -S 参数即可以实现此操作。

$ ls -lS total 308 -rw-r----- 1 oracle oinstall 52903 Oct 11 18:31 sqlnet.log -rwxr-xr-x 1 oracle oinstall 9530 Apr 6 2006 root.sh drwxr-xr-x 2 oracle oinstall 8192 Oct 11 18:14 bin drwxr-x--- 3 oracle oinstall 8192 Sep 23 23:49 lib

xargs

大多数 Linux 命令都会产生输出:文件列表、字符串列表等。但如果要使用其他某个命令并将前一个命令的输出作为参数该怎么办?例如,file 命令显示文件类型(可执行文件、ascii 文本等);您可以处理输出,使其仅显示文件名,现在您希望将这些名称传递给 ls -l 命令以查看时间戳记。xargs 命令就是用来完成此项工作的。它允许您对输出执行其他某些命令。记住下面这个来自于第 1 部分中的语法:

file -Lz * | grep ASCII | cut -d":" -f1 | xargs ls -ltr 让我们来剖析这个命令字符串。第一个,file -Lz * ,用于查找是符号链接或者经过压缩的文件。它将输出传递给下一个命令 grep ASCII ,该命令在其中搜索 "ASCII" 字符串并产生如下所示的输出: alert_DBA102.log: ASCII English text alert_DBA102.log.Z: ASCII text (compress'd data 16 bits) dba102_asmb_12307.trc.Z: ASCII English text (compress'd data 16 bits) dba102_asmb_20653.trc.Z: ASCII English text (compress'd data 16 bits) 由于我们只对文件名感兴趣,因此我们应用下一个命令 cut -d":" -f1 ,仅显示第一个字段: alert_DBA102.log alert_DBA102.log.Z dba102_asmb_12307.trc.Z dba102_asmb_20653.trc.Z

现在,我们希望使用 ls -l 命令,将上述列表作为参数进行传递,一次传递一个。xargs 命令允许您这样做。最后一部分,xargs ls -ltr ,用于接收输出并对其执行 ls -ltr 命令,如下所示:

ls -ltr alert_DBA102.log ls -ltr alert_DBA102.log.Z ls -ltr dba102_asmb_12307.trc.Z ls -ltr dba102_asmb_20653.trc.Z

因此,xargs 本身虽然没有多大用处,但在与其他命令相结合时,它的功能非常强大。

下面是另一个示例,我们希望计算这些文件中的行数:

$ file * | grep ASCII | cut -d":" -f1 | xargs wc -l 47853 alert_DBA102.log 19 dba102_cjq0_14493.trc 29053 dba102_mmnl_14497.trc 154 dba102_reco_14491.trc 43 dba102_rvwr_14518.trc 77122 total

(注:上述任务还可用以下命令完成:)

$ wc -l ‘file * | grep ASCII | cut -d":" -f1 | grep ASCII | cut -d":" -f1‘

xargs 版本用于阐释概念。Linux 可以用几种方法来完成同一个任务;请使用最适合您的情况的方法。

使用该方法,您可以快速重命名目录中的文件。

$ ls | xargs -t -i mv {} {}.bak

-i 选项告诉 xargs 用每项的名称替换 {}。-t 选项指示 xargs 先打印命令,然后再执行。

另一个非常有用的操作是当您使用 vi 打开要编辑的文件时:

$ file * | grep ASCII | cut -d":" -f1 | xargs vi

该命令使用 vi 逐个打开文件。当您希望搜索多个文件并打开它们进行编辑时,使用该命令非常方便。

它还有几个选项。最有用的可能是 -p 选项,它使操作具有可交互性:

$ file * | grep ASCII | cut -d":" -f1 | xargs -p vi vi alert_DBA102.log dba102_cjq0_14493.trc dba102_mmnl_14497.trc
dba102_reco_14491.trc dba102_rvwr_14518.trc ?...

此处的 xarg 要求您在运行每个命令之前进行确认。如果您按下 "y",则执行命令。当您对文件进行某些可能有破坏且不可恢复的操作(如删除或覆盖)时,您会发现该选项非常有用。

-t 选项使用一个详细模式;它显示要运行的命令,是调试过程中一个非常有帮助的选项。

如果传递给 xargs 的输出为空怎么办?考虑以下命令:

$ file * | grep SSSSSS | cut -d":" -f1 | xargs -t wc -l wc -l 0 $ 在此处,搜索 "SSSSSS" 后没有匹配的内容;因此 xargs 的输入均为空,如第二行所示(由于我们使用 -t 这个详细选项而产生的结果)。虽然这可能会有所帮助,但在某些情况下,如果没有要处理的内容,您可能希望停止 xargs ;如果是这样,可以使用 -r 选项: $ file * | grep SSSSSS | cut -d":" -f1 | xargs -t -r wc -l $

如果没有要运行的内容,该命令退出。

假设您希望使用 rm 命令(该命令将作为 xargs 命令的参数)删除文件。然而,rm 只能接受有限数量的参数。如果您的参数列表超出该限制怎么办?xargs 的 -n 选项限制单个命令行的参数个数。

下面显示了如何限制每个命令行仅使用两个参数:即使向 xargs ls -ltr 传递五个文件,但每次向 ls -ltr 仅传递两个文件。

$ file * | grep ASCII | cut -d":" -f1 | xargs -t -n2 ls -ltr ls -ltr alert_DBA102.log dba102_cjq0_14493.trc -rw-r----- 1 oracle dba 738 Aug 10 19:18 dba102_cjq0_14493.trc -rw-r--r-- 1 oracle dba 2410225 Aug 13 05:31 alert_DBA102.log ls -ltr dba102_mmnl_14497.trc dba102_reco_14491.trc -rw-r----- 1 oracle dba 5386163 Aug 10 17:55 dba102_mmnl_14497.trc -rw-r----- 1 oracle dba 6808 Aug 13 05:21 dba102_reco_14491.trc ls -ltr dba102_rvwr_14518.trc -rw-r----- 1 oracle dba 2087 Aug 10 04:30 dba102_rvwr_14518.trc

使用该方法,您可以快速重命名目录中的文件。

$ ls | xargs -t -i mv {} {}.bak

-i 选项告诉 xargs 用每项的名称替换 {}。

rename

正如您所知道的那样,mv 命令对文件进行重命名。例如,

$ mv oldname newname 将 oldname 文件重命名为 newname。但如果您不知道文件名,那该怎么办?rename 命令在此处就可以大显身手了。 rename .log .log.‘date +%F-%H:%M:%S‘ *

用 .log.<日期格式> 替换所有扩展名为 .log 的文件。因此,sqlnet.log 变为 sqlnet.log.2006-09-12-23:26:28。

find

最受 Oracle 用户欢迎的命令之一是 find 命令。到目前为止,您了解了如何使用 find 在给定目录中查找文件。下面的示例显示在当前目录中查找以单词 "file" 开头的文件:

$ find . -name "file*" ./file2 ./file1 ./file3 ./file4

然而,如果您希望搜索 FILE1、FILE2 等名称怎么办?-name "file*" 不会与之匹配。对于区分大小写的搜索,可以使用 -iname 选项:

$ find . -iname "file*" ./file2 ./file1 ./file3 ./file4 ./FILE1 ./FILE2

您可以限制搜索范围,仅搜索特定类型的文件。例如,上述命令将获得所有类型的文件:普通文件、目录、符号链接等。如果仅搜索普通文件,可使用 -type f 参数。

$ find . -name "orapw*" -type f ./orapw+ASM ./orapwDBA102 ./orapwRMANTEST ./orapwRMANDUP ./orapwTESTAUX

-type 可以接受修饰符 f(普通文件)、l(符号链接)、d(目录)、b(块设备)、p(命名管道)、c(字符设备)、s(套接字)。

对上述命令的一个小技巧是,将其与您在第 1 部分中学到的 file 命令相结合。file 命令告诉您文件的类型。您可以将其作为 find 命令的输出的后处理器进行传递。-exec 参数执行该参数后面的命令。在该示例中,在 find 后执行的命令是 file

$ find . -name "*oraenv*" -type f -exec file {} /; ./coraenv: Bourne shell script text executable ./oraenv: Bourne shell script text executable

当您希望弄清楚 ASCII 文本文件是否可能是某种类型的 shell 脚本时,该命令非常有用。

如果您用 -ok 替换 -exec,则执行该命令之前要求您先进行确认。下面就是一个例子:

$ find . -name "sqlplus*" -ok {} /; < {} ... ./sqlplus > ? y SQL*Plus: Release 9.2.0.5.0 - Production on Sun Aug 6 11:28:15 2006 Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved. Enter user-name: / as sysdba Connected to: Oracle9i Enterprise Edition Release 9.2.0.5.0 - 64bit Production With the Partitioning, Real Application Clusters, OLAP and Oracle Data Mining options JServer Release 9.2.0.5.0 - Production SQL> exit Disconnected from Oracle9i Enterprise Edition Release 9.2.0.5.0 - 64bit Production With the Partitioning, Real Application Clusters, OLAP and Oracle Data Mining options JServer Release 9.2.0.5.0 - Production < È* ... ./sqlplusO > ? n $ 在此示例中,我们要求 shell 查找所有以 "sqlplus" 开头的程序并执行它们。注意,-ok 与 {} 之间什么都没有,因此仅执行找到的文件。shell 找到两个文件 — sqlplus 和 sqlplusO — 并在每次找到后询问您是否希望执行文件。我们针对 "sqlplus" 回答 "y",因此执行该文件。退出之后,shell 提示您找到了第二个文件 (sqlplusO),再次要求您确认,我们回答 "n",因此不执行该文件。

适用于 Oracle 用户的技巧

Oracle 产生许多不必要的文件:跟踪文件、日志文件、转储文件等。如果不定期清理,这些文件就会占满文件系统,从而导致数据库暂停。

为了避免出现这种情况,只需搜索扩展名为 "trc" 的文件,如果这些文件的存在时间超过三天,则将其删除。一个简单的命令即可实现该操作:

find . -name "*.trc" -ctime +3 -exec rm {} /;

要强制删除存在不到三天的文件,请使用 -f 选项。

		

find . -name "*.trc" -ctime +3 -exec rm -f {} /;

如果只想列出文件:

find . -name "*.trc" -ctime +3 -exec ls -l {} /;

m4

该命令接受一个输入文件并用所传递的参数替换其中的字符串,类似于替换变量。例如,以下是一个输入文件:

$ cat temp The COLOR fox jumped over the TYPE fence.

如果要用 "brown" 替换字符串 "COLOR",用 "broken" 替换 "TYPE",您可以使用以下命令:

$ m4 -DCOLOR=brown -DTYPE=broken temp The brown fox jumped over the broken fence. Else, if you want to substitute "white" and "high" for the same: $ m4 -DCOLOR=white -DTYPE=high temp The white fox jumped over the high fence.

whence 和 which

这两个命令用于找到所提到的可执行文件在用户路径中的存储位置。在路径中找到可执行文件之后,这两个命令的行为基本相同,都显示文件的路径:

$ which sqlplus /u02/app/oracle/products/10.2.0.1/db1/bin/sqlplus $ whence sqlplus /u02/app/oracle/products/10.2.0.1/db1/bin/sqlplus

输出完全相同。然而,如果在路径中未找到可执行文件,则两者的行为不同。which 命令生成一条显式消息:

$ which sqlplus1 /usr/bin/which: no sqlplus1 in (/u02/app/oracle/products/10.2.0.1/db1/bin:/usr
/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin)

whence 命令不生成任何消息:

$ whence sqlplus1]

而是返回到 shell 提示符。如果在路径中未找到可执行文件,这将很有帮助(不显示消息):

$ whence invalid_command $ which invalid_command which: no invalid_command in (/usr/kerberos/sbin:/usr/kerberos/bin:/bin:/sbin:
/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin: /usr/bin/X11:/usr/X11R6/bin:/root/bin)

如果 whence 在路径中未找到可执行文件,它不返回任何消息,但返回代码不为零。在 shell 脚本中可以利用这个事实;例如:

RC=‘whence myexec‘ If [ $RC -ne "0" ]; then echo "myexec is not in the $PATH" fi

它的一个非常有用的选项是 -i 选项,该选项显示别名以及可执行文件(如果有的话)。例如,您在本文开始部分了解了别名的用法。rm 命令实际上是我的 shell 中的一个别名,系统中某处也有一个 rm 命令。

$ which ls /bin/ls $ which -i ls alias ls='ls --color=tty' /bin/ls

其默认行为是显示可执行文件在路径中的首次出现。如果可执行文件位于路径的多个目录中,则忽略其后的出现。您可以通过 -a 选项查看可执行文件的所有出现位置。

$ which java /usr/bin/java $ which -a java /usr/bin/java /home/oracle/oracle/product/11.1/db_1/jdk/jre/bin/java

top

top 命令可能是 Oracle DBA 在 Linux 上管理数据库时最有用的命令。如果系统很慢,您可能希望查看谁在占用所有 CPU 和/或内存。要显示最大进程,可以使用 top 命令。

注意,与其他命令不同,top 不会产生输出,屏幕内容保持不变。它刷新屏幕以显示新信息。因此,如果您只执行 top 并保持屏幕一直开启,则屏幕始终显示最新信息。要停止并退出 shell,可以按下 Ctrl-C。

$ top 18:46:13 up 11 days, 21:50, 5 users, load average: 0.11, 0.19, 0.18 151 processes: 147 sleeping, 4 running, 0 zombie, 0 stopped CPU states: cpu user nice system irq softirq iowait idle total 12.5% 0.0% 6.7% 0.0% 0.0% 5.3% 75.2% Mem: 1026912k av, 999548k used, 27364k free, 0k shrd, 116104k buff 758312k actv, 145904k in_d, 16192k in_c Swap: 2041192k av, 122224k used, 1918968k free 590140k cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 451 oracle 15 0 6044 4928 4216 S 0.1 0.4 0:20 0 tnslsnr 8991 oracle 15 0 1248 1248 896 R 0.1 0.1 0:00 0 top 1 root 19 0 440 400 372 S 0.0 0.0 0:04 0 init 2 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 keventd 3 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kapmd 4 root 34 19 0 0 0 SWN 0.0 0.0 0:00 0 ksoftirqd/0 7 root 15 0 0 0 0 SW 0.0 0.0 0:01 0 bdflush 5 root 15 0 0 0 0 SW 0.0 0.0 0:33 0 kswapd 6 root 15 0 0 0 0 SW 0.0 0.0 0:14 0 kscand 8 root 15 0 0 0 0 SW 0.0 0.0 0:00 0 kupdated 9 root 25 0 0 0 0 SW 0.0 0.0 0:00 0 mdrecoveryd ... output snipped ...

让我们来看看产生的不同类型的信息。第一行:

18:46:13 up 11 days, 21:50, 5 users, load average: 0.11, 0.19, 0.18

显示当前时间 (18:46:13),该系统已经运行了 11 天;并且已经工作了 21 小时 50 秒。后面显示的分别是最近 1、5、15 分钟的系统平均负载 (0.11、0.19、0.18)。(顺便提一下,您也可以通过执行 uptime 命令来获得这些信息。)

如果不需要平均负载,按下字母 "l"(小写字母 L);它将关闭。要再次将其打开,按下 l。第二行:

151 processes: 147 sleeping, 4 running, 0 zombie, 0 stopped

显示进程数、运行的进程数、休眠的进程数等。第三行和第四行:

CPU states: cpu user nice system irq softirq iowait idle total 12.5% 0.0% 6.7% 0.0% 0.0% 5.3% 75.2%

显示 CPU 利用率的详细信息。上面一行显示用户进程占用了 CPU 的 12.5%,系统占用了 6.7%。用户进程中包括 Oracle 进程。按下 "t" 可以关闭和打开这三行。如果有多个 CPU,屏幕将在每行显示一个 CPU 的信息。

接下来的两行:

Mem: 1026912k av, 1000688k used, 26224k free, 0k shrd, 113624k buff 758668k actv, 146872k in_d, 14460k in_c Swap: 2041192k av, 122476k used, 1918716k free 591776k cached

显示可用的和已利用的内存。内存总量为 "1026912k av"(大约 1GB),其中只有 26224k(即 26MB)是可用的。交换空间为 2GB;但几乎并未使用。要关闭和打开这两行,可以按下 "m"。

其余的显示内容以表格格式显示进程。下面对各列进行解释:

描述
PID进程的进程 ID
USER 运行该进程的用户
PRI 进程的优先级
NInice 值:该值越高,任务的优先级越低
SIZE 该进程使用的内存(代码+数据+堆栈)
RSS 该进程使用的物理内存
SHARE 该进程使用的共享内存
STAT

该进程的状态,用代码显示。一些主要的状态代码包括:
R — 正在运行
S — 正在休眠
Z — 迟滞
T — 已停止

您还会看到第二个和第三个字符,它们表示:
W — 已换出的进程
N — 正 nice 值
%CPU 该进程使用的 CPU 百分比
%MEM 该进程使用的内存百分比
TIME 该进程使用的总 CPU 时间
CPU 如果这是一个多处理器系统,该列指明正在其上运行进程的 CPU 的 ID。
COMMAND该进程发出的命令

显示 top 时,您可以按几个键来设置希望的显示格式。按下大写字母 M 键可根据内存使用情况对输出进行排序。(注意,使用小写字母 m 将在显示屏的顶部打开或关闭内存汇总行。)当您希望了解谁在占用内存时,该键非常有用。示例输出如下:

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 31903 oracle 15 0 75760 72M 72508 S 0.0 7.2 0:01 0 ora_smon_PRODB2 31909 oracle 15 0 68944 66M 64572 S 0.0 6.6 0:03 0 ora_mmon_PRODB2 31897 oracle 15 0 53788 49M 48652 S 0.0 4.9 0:00 0 ora_dbw0_PRODB2

既然您了解了如何解释输出,我们来看看如何使用命令行参数。

最有用的参数是 -d,它指示两次屏幕刷新之间的延迟。要每秒刷新一次,则使用 top -d 1

另一个有用的选项是 -p。如果您希望只监视几个进程而并非全部,可以在 -p 选项后指定这几个进程。要监视进程 13609、13608 和 13554,执行以下命令:

top -p 13609 -p 13608 -p 13554

这将以和 top 命令相同的格式显示结果,但只显示特定进程的信息。

适用于 Oracle 用户的技巧

众所周知,使用 top 实用程序分析数据库服务器的性能非常方便。下面是部分 top 输出。

20:51:14  up 11 days, 23:55,  4 users,  load average: 0.88, 0.39, 0.27 

113 processes: 110 sleeping, 2 running, 1 zombie, 0 stopped

CPU states: cpu user nice system irq softirq iowait idle

total 1.0% 0.0% 5.6% 2.2% 0.0% 91.2% 0.0%

Mem: 1026912k av, 1008832k used, 18080k free, 0k shrd, 30064k buff

771512k actv, 141348k in_d, 13308k in_c

Swap: 2041192k av, 66776k used, 1974416k free 812652k cached



PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND

16143 oracle 15 0 39280 32M 26608 D 4.0 3.2 0:02 0 oraclePRODB2...

5 root 15 0 0 0 0 SW 1.6 0.0 0:33 0 kswapd

... output snipped ...


我们来仔细分析此输出。首先,您需要注意 CPU states 下面的 "idle" 列;该列为 0.0%,这意味着 CPU 被完全占用来执行某项任务。问题是 CPU 在做什么?将注意力转向 "system" 列,就在左侧不远处;该列显示 5.6%。这说明,系统本身占用的 CPU 并不多。再向左就是 "user" 列,该列显示 1.0%。由于用户进程还包括 Oracle,因此 Oracle 并未占用 CPU 周期。那么,到底是什么占用了整个 CPU?

答案就在同一行右侧 "iowait" 列下面,该列为 91.2%。一切都明白了:91.2% 的 CPU 时间都在等待 IO。

为什么会有这么多的 IO 等待?答案在显示内容中。注意最消耗资源的进程的 PID:16143 您可以使用以下查询来确定该进程在做什么:

select s.sid, s.username, s.program

from v$session s, v$process p

where spid = 16143

and p.addr = s.paddr

/



SID USERNAME PROGRAM

------------------- -----------------------------





在此部分中,了解用于监视物理组件的高级 Linux 命令

Linux 系统由若干主要物理组件组成,如 CPU、内存、网卡和存储设备。要有效地管理 Linux 环境,您应该能够以合理的精度测量这些资源的各种指标 — 每个组件处理多少资源、是否存在瓶颈等。

在本系列的其他部分中,您已经学习了处于宏级别的用于测量指标的一些命令。但在此部分中,您将了解专门用于监视物理组件的高级 Linux 命令。具体而言,您将了解以下类别的命令:

组件

命令

内存

free、vmstat、mpstat、iostat、sar

CPU

vmstat、mpstat、iostat、sar

I/O

vmstat、mpstat、iostat、sar

进程

ipcs、ipcrm

正如您所见,某些命令出现在多个类别中。这是由于这些命令可以执行很多任务。某些命令比较适合于某些组件,例如 iostat 适合 I/O,但是您应该了解它们工作的差别并使用您更熟悉的命令。

在多数情况下,单个命令可能对于了解实际发生的情况没什么用。要获取所需的信息,您应该了解多个命令。

free

一个常见的问题是“我的应用程序和各种服务器、用户和系统进程正在使用多少内存?”或者“现在有多少内存可用?”如果正在运行的进程使用的内存大于可用 RAM,则需要将这些进程移到交换区。因此,一个补充问题是“正在使用多少交换区空间?”

free 命令将回答所有这些问题。而且,一个非常有用的选项 –m 可以显示可用内存(以 MB 为单位):

# free -m total used free shared buffers cached Mem: 1772 1654 117 0 18 618 -/+ buffers/cache: 1017 754 Swap: 1983 1065 918

以上输出显示系统具有 1,772 MB 的 RAM,已使用 1,654 MB,还有 117 MB 内存可用。第二行显示在物理内存中缓冲区和缓存大小的更改。第三行显示交换区利用情况。

要以 KB 或 GB 为单位显示以上内容,请将 -m 选项分别替换为 -k 或 -g。使用 –b 选项将以字节为单位。

# free -b total used free shared buffers cached Mem: 1858129920 1724039168 134090752 0 18640896 643194880 -/+ buffers/cache: 1062203392 795926528 Swap: 2080366592 1116721152 963645440

–t 选项在输出底部显示总数(物理内存和交换区的总和):

# free -m -t total used free shared buffers cached Mem: 1772 1644 127 0 16 613 -/+ buffers/cache: 1014 757 Swap: 1983 1065 918 Total: 3756 2709 1046

尽管 free 不显示百分比,但是我们可以提取并格式化输出的特定部分,将已使用的内存仅显示为总数的百分比:

# free -m | grep Mem | awk '{print ($3 / $2)*100}' 98.7077

这在具体数据非常重要的 shell 脚本中非常方便。例如,您可能希望在可用内存的百分比低于特定阈值时触发一个警报。

同样,要发现已使用交换区空间的百分比,您可以发出:

free -m | grep -i Swap | awk '{print ($3 / $2)*100}'

可以使用 free 查看应用程序施加的内存负载。例如,启动备份应用程序之前检查可用内存,启动之后立即检查可用内存。两者之差就是备份应用程序消耗的内存。

针对 Oracle 用户的用法

那么,您如何使用该命令管理运行 Oracle 环境的 Linux 服务器呢?性能问题的一个最常见原因是内存不足,从而导致系统临时将内存区域“交换”到磁盘中。某种程度的交换可能是必然的,但是交换过多则表示可用内存不足。

而现在,您可以使用 free 获得可用内存信息,紧接着使用 sar 命令(稍后介绍)检查内存和交换区消耗的历史趋势。如果交换区的使用是暂时的,则可能出现一次高峰,但是如果明确要经过一段时间,则应注意。持续的内存过载可能有几个明显且可能的疑点:

  • 较大的 SGA 高于可用内存
  • 在 PGA 上分配了大量内存
  • 某些进程出现泄露内存的错误

对于第一种情况,应确保 SGA 低于可用内存。根据经验,对 SGA 使用大约物理内存的 40%,当然,应根据具体情况定义该参数。对于第二种情况,应尝试减少查询中的大量缓冲区分配。对于第三种情况,应使用 ps 命令(在本系列的之前部分中介绍过)确定可能泄露内存的具体进程。

ipcs

当某个进程运行时,它会夺取“共享内存”。该进程可能拥有一个或很多个共享内存段。进程之间彼此(“进程间通信”或 IPC)发送消息并使用信号。要显示有关共享内存段、IPC 消息队列以及信号的信息,可以使用一个命令:ipcs。

–m 选项非常受欢迎;它显示共享内存段。

# ipcs -m ------ Shared Memory Segments -------- key shmid owner perms bytes nattch status 0xc4145514 2031618 oracle 660 4096 0 0x00000000 3670019 oracle 660 8388608 108 0x00000000 327684 oracle 600 196608 2 dest 0x00000000 360453 oracle 600 196608 2 dest 0x00000000 393222 oracle 600 196608 2 dest 0x00000000 425991 oracle 600 196608 2 dest 0x00000000 3702792 oracle 660 926941184 108 0x00000000 491529 oracle 600 196608 2 dest 0x49d1a288 3735562 oracle 660 140509184 108 0x00000000 557067 oracle 600 196608 2 dest 0x00000000 1081356 oracle 600 196608 2 dest 0x00000000 983053 oracle 600 196608 2 dest 0x00000000 1835023 oracle 600 196608 2 dest

该输出表明服务器正在运行 Oracle 软件,显示了各种共享内存段。每个共享内存段由显示在“shmid”列下面的共享内存 ID 唯一标识。(稍后,您将看到如何使用该列值。)显然,“owner”显示内存段的所有者,“perms”列显示权限(与 unix 权限相同),“bytes”显示字节大小。

-u 选项显示一个非常快速的摘要:

# ipcs -mu ------ Shared Memory Status -------- segments allocated 25 pages allocated 264305 pages resident 101682 pages swapped 100667 Swap performance: 0 attempts 0 successes

–l 选项显示限定值(相对于当前值):

# ipcs -ml ------ Shared Memory Limits -------- max number of segments = 4096 max seg size (kbytes) = 907290 max total shared memory (kbytes) = 13115392 min seg size (bytes) = 1

如果您看到当前值处于或接近限定值,则应该考虑提高限定值。

可以使用 shmid 值获取具体共享内存段的详细图片。–i 选项可以完成该操作。下面是查看 shmid 3702792 详细信息的方法:

# ipcs -m -i 3702792 Shared memory Segment shmid=3702792 uid=500 gid=502 cuid=500 cgid=502 mode=0660 access_perms=0660 bytes=926941184 lpid=12225 cpid=27169 nattch=113 att_time=Fri Dec 19 23:34:10 2008 det_time=Fri Dec 19 23:34:10 2008 change_time=Sun Dec 7 05:03:10 2008

稍后,本文将采用一个示例向您介绍如何解释以上输出。

-s 显示系统中的信号:

# ipcs -s ------ Semaphore Arrays -------- key semid owner perms nsems 0x313f2eb8 1146880 oracle 660 104 0x0b776504 2326529 oracle 660 154 … and so on …

它显示一些有价值的数据。它显示 ID 为 1146880 的信号数组具有 104 个信号,另一个数组具有 154 个信号。如果您增加信号,则总值必须低于内核参数 (semmax) 定义的上限。安装 Oracle 数据库软件时,预安装的检查程序将检查 semmax 的设置。之后,当系统达到稳定状态时,您可以检查实际的利用情况,然后相应地调整内核值。

针对 Oracle 用户的用法

如何查看 Oracle 数据库实例使用的共享内存段?为此,请使用 oradebug 命令。首先以 sysdba 身份连接到数据库:

# sqlplus / as sysdba

在 SQL 中,使用 oradebug 命令,如下所示:

SQL> oradebug setmypid Statement processed. SQL> oradebug ipc Information written to trace file.

要查找跟踪文件的名称,执行以下命令:

SQL> oradebug TRACEFILE_NAME /opt/oracle/diag/rdbms/odba112/ODBA112/trace/ODBA112_ora_22544.trc

现在,如果打开该跟踪文件,将会看到共享内存 ID。下面是该文件的节选:

Area #0 `Fixed Size' containing Subareas 0-0 Total size 000000000014613c Minimum Subarea size 00000000 Area Subarea Shmid Stable Addr Actual Addr 0 0 17235970 0x00000020000000 0x00000020000000 Subarea size Segment size 0000000000147000 000000002c600000 Area #1 `Variable Size' containing Subareas 4-4 Total size 000000002bc00000 Minimum Subarea size 00400000 Area Subarea Shmid Stable Addr Actual Addr 1 4 17235970 0x00000020800000 0x00000020800000 Subarea size Segment size 000000002bc00000 000000002c600000 Area #2 `Redo Buffers' containing Subareas 1-1 Total size 0000000000522000 Minimum Subarea size 00000000 Area Subarea Shmid Stable Addr Actual Addr 2 1 17235970 0x00000020147000 0x00000020147000 Subarea size Segment size 0000000000522000 000000002c600000 ... and so on ...

共享内存 id 以红色粗体显示。可以使用该共享内存 ID 来获取共享内存的详细信息:

# ipcs -m -i 17235970

另一个有用的观察是 lpid 的值 — 最后一个接触共享内存段的进程的进程 ID。要展示该属性的值,使用 SQL*Plus 从另一个会话连接到该实例。

# sqlplus / as sysdba

在该会话中,查找服务器进程的 PID:

SQL> select spid from v$process 2 where addr = (select paddr from v$session 3 where sid = 4 (select sid from v$mystat where rownum < 2) 5 ); SPID ------------------------ 13224

现在,针对同一共享内存段再次执行 ipcs 命令:

# ipcs -m -i 17235970 Shared memory Segment shmid=17235970 uid=500 gid=502 cuid=500 cgid=502 mode=0660 access_perms=0660 bytes=140509184 lpid=13224 cpid=27169 nattch=113 att_time=Fri Dec 19 23:38:09 2008 det_time=Fri Dec 19 23:38:09 2008 change_time=Sun Dec 7 05:03:10 2008

注意,lpid 的值已经从原来的值 12225 更改为 13224。lpid 显示最后一个接触共享内存段的进程的 PID。

该命令自身的价值不大。下一个命令 ipcrm 允许您基于输出采取操作,正如您将在下一部分所见。

ipcrm

既然您已经标识了共享内存和其他 IPC 指标,那么使用它们做什么呢?之前您看到过一些用法,如标识 Oracle 使用的共享内存、确保为共享内存设置了内核参数等等。另一个常见的应用是删除共享内存、IPC 消息队列或信号数组。

要删除某个共享内存段,注意 ipcs 命令输出中它的 shmid。然后使用 –m 选项删除该段。要删除 ID 为 3735562 的段,使用:

# ipcrm –m 3735562

这将删除该共享内存。还可以使用该命令删除信号和 IPC 消息队列(使用 –s 和 –q 参数)。

针对 Oracle 用户的用法

有时当您关闭数据库实例时,Linux 内核可能未完全清除共享内存段。留下的共享内存没有什么用处,但它会占用系统资源,从而使可用于其他进程的内存更少。这种情况下,可以检查 “oracle”用户所拥有的任何延迟共享内存段,然后删除它们,如果有这样的段,使用 ipcrm 命令。

vmstat

vmstat 是最早用于显示所有与内存和进程相关信息的命令,调用时,该命令会持续运行并发布其信息。它有两个参数:

# vmstat <interval> <count>

<interval> 是两次运行之间的时间间隔,以秒为单位。<count> 是 vmstat 重复的次数。下面是当我们希望 vmstat 每隔 5 秒运行一次并在第 10 次运行后停止时的示例。每 5 秒之后都会输出一行并显示此时的统计信息。

# vmstat 5 10 procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu---- r b swpd free buff cache si so bi bo in cs us sy id wa 0 0 1087032 132500 15260 622488 89 19 9 3 0 0 4 10 82 5 0 0 1087032 132500 15284 622464 0 0 230 151 1095 858 1 0 98 1 0 0 1087032 132484 15300 622448 0 0 317 79 1088 905 1 0 98 0 … shows up to 10 times.

该输出显示有关系统资源的大量信息。我们来详细介绍它们:

procs

显示进程数

r

等待运行的进程。系统上的负载越多,等待运行 CPU 周期的进程数量越多。

b

不可中断睡眠的进程,也称为“被阻塞”的进程。这些进程最有可能等待 I/O,但也可能等待其他事情。

有时,还存在另外一列,该列位于标题“w”下,显示可以运行但已经交换到交换区域中的进程数。

“b”下的数值应接近于 0。如果“w”下的数值很高,可能需要更多内存。

下表显示了内存指标:

swpd

虚拟内存或交换内存的数量(以 KB 为单位)

free

可用物理内存的数量(以 KB 为单位)

buff

用作缓冲区的内存数量(以 KB 为单位)

cache

用作缓存的物理内存数量(以 KB 为单位)

缓冲区内存用来存储文件元数据(如 i-nodes)以及原始块设备中的数据。缓存内存用于文件数据本身。

下表显示了交换活动:

si

将内存从磁盘交换回物理 RAM 的速率(以 KB/秒为单位)

so

将内存从物理 RAM 交换到磁盘的速率(以 KB/秒为单位)

下表显示了 I/O 活动:

bi

系统向块设备发送数据的速率(以块/秒为单位)

bo

系统从块设备中读取数据的速率(以块/秒为单位)

下表显示了系统相关活动:

in

系统每秒接收到的中断数

cs

在进程空间中切换上下文的速率(以数量/秒为单位)

最后这张表可能用得最多 — 有关 CPU 负载的信息:

us

显示花费在用户进程中的 CPU 百分比。Oracle 进程属于这一类。

sy

系统进程(如所有根进程)使用的 CPU 百分比

id

可用 CPU 百分比

wa

花费在“等待 I/O”上的百分比

让我们看一看如何解释这些值。输出的第一行是自从系统重新启动以来所有指标的平均值。因此,忽略该行,因为它并不显示当前状态。其他行显示实时指标。

理想情况下,等待或阻塞的进程数量(位于“procs ”标题下)应该为 0 或接近于 0。如果数值较高,则表示系统没有足够的资源(如 CPU、内存或 I/O)。诊断性能问题时该信息非常有用。

“swap”下的数据表明交换是否过多。如果交换过多,则表明物理内存可能不足。应该减少内存需求或增加物理 RAM。

io ”下的数据表示往返于磁盘的数据流。这表明正在进行的磁盘活动量,这并不一定表明存在问题。如果您看到“proc ”和“b ”列(正在阻塞的进程)下有较大的数值和较高的 I/O,则可能出现了严重的 I/O 争用问题。

cpu ”标题下是最有用的信息。“id ”列显示空闲 CPU。如果用 100 减去该数值,则会得到繁忙 CPU 的百分比。还记得本系列的另一个部分中描述的 top 命令吗?该命令还显示 CPU 的空闲百分比数值。区别是:top 显示每个 CPU 的空闲百分比,而 vmstat 显示所有 CPU 的空闲百分比。

vmstat 命令还显示 CPU 使用情况的划分:Linux 系统使用多少、用户进程使用多少以及等待 I/O 使用多少。通过该划分,您可以确定 CPU 消耗的组成。如果系统 CPU 负载较高,能表明正在运行某个根进程(如备份)吗?

一段时间内的系统负载应该一致。如果系统显示较高的数值,请使用 top 命令确定占有 CPU 的系统进程。

针对 Oracle 用户的用法

Oracle 进程(后台进程和服务器进程)和用户进程(sqlplus、apache 等)位于“us ”下。如果该数值较高,则使用 top 来确定进程。如果“wa ”列显示较高的数值,则表明 I/O 系统无法跟上读取或写入的数量。有时这可能是因为在数据库中进行大量更新,从而导致日志切换以及后续的大量存档进程。但是,如果它持续显示一个较大的数值,则表明可能存在 I/O 瓶颈。

Oracle 数据库中的 I/O 瓶颈可能会造成严重的问题。与性能问题不同,慢速 I/O 可能导致控制文件写入速度缓慢,这会导致等待获取控制文件的进程加入队列。如果等待超过 900 秒且等待者是关键进程(如 LGWR),则会关闭数据库实例。

如果您看到很多交换,可能是 SGA 的太大,以至于物理内存容纳不下。应该减小 SGA 大小或增加物理内存。

mpstat

另一个用于获取 CPU 相关统计信息的有用的命令是 mpstat。下面是一个示例输出:

# mpstat -P ALL 5 2 Linux 2.6.9-67.ELsmp (oraclerac1) 12/20/2008 10:42:38 PM CPU %user %nice %system %iowait %irq %soft %idle intr/s 10:42:43 PM all 6.89 0.00 44.76 0.10 0.10 0.10 48.05 1121.60 10:42:43 PM 0 9.20 0.00 49.00 0.00 0.00 0.20 41.60 413.00 10:42:43 PM 1 4.60 0.00 40.60 0.00 0.20 0.20 54.60 708.40 10:42:43 PM CPU %user %nice %system %iowait %irq %soft %idle intr/s 10:42:48 PM all 7.60 0.00 45.30 0.30 0.00 0.10 46.70 1195.01 10:42:48 PM 0 4.19 0.00 2.20 0.40 0.00 0.00 93.21 1034.53 10:42:48 PM 1 10.78 0.00 88.22 0.40 0.00 0.00 0.20 160.48 Average: CPU %user %nice %system %iowait %irq %soft %idle intr/s Average: all 7.25 0.00 45.03 0.20 0.05 0.10 47.38 1158.34 Average: 0 6.69 0.00 25.57 0.20 0.00 0.10 67.43 724.08 Average: 1 7.69 0.00 64.44 0.20 0.10 0.10 27.37 434.17

它显示了系统中 CPU 的各种统计信息。–P ALL 选项指示该命令显示所有 CPU 的统计信息,而不只是特定 CPU 的统计信息。参数 5 2 指示该命令每隔 5 秒运行一次,共运行 2 次。以上输出首先显示了所有 CPU 的合计指标,然后显示了每个 CPU 各自的指标。最后,在结尾处显示所有 CPU 的平均值。

让我们看一看这些列值的含义:

%user

表示处理用户进程所使用 CPU 的百分比。用户进程是用于应用程序(如 Oracle 数据库)的非内核进程。在本示例输出中,用户 CPU 百分比非常低。

 

 

%nice

表示使用 nice 命令对进程进行降级时 CPU 的百分比。在之前的部分中已经对 nice 命令进行了介绍。简单来说,nice 命令更改进程的优先级。

 

 

%system

表示内核进程使用的 CPU 百分比

 

 

%iowait

表示等待进行 I/O 所使用的 CPU 时间百分比

 

 

%irq

表示用于处理系统中断的 CPU 百分比

 

 

%soft

表示用于软件中断的 CPU 百分比

 

 

%idle

显示 CPU 的空闲时间

 

 

%intr/s

显示每秒 CPU 接收的中断总数

当您拥有前面所述的 vmstat 时,您可能想知道 mpstat 命令的作用。差别很大:mpstat 可以显示每个处理器的统计,而 vmstat 显示所有处理器的统计。因此,编写糟糕的应用程序(不使用多线程体系结构)可能会运行在一个多处理器机器上,而不使用所有处理器。从而导致一个 CPU 过载,而其他 CPU 却很空闲。通过 mpstat 可以轻松诊断这些类型的问题。

针对 Oracle 用户的用法

与 vmstat 相似,mpstat 命令还产生与 CPU 有关的统计信息,因此所有与 CPU 问题有关的讨论也都适用于 mpstat。当您看到较低的 %idle 数字时,您知道出现了 CPU 不足的问题。当您看到较高的 %iowait 数字时,您知道在当前负载下 I/O 子系统出现了某些问题。该信息对于解决 Oracle 数据库性能问题非常方便。

iostat

性能评估的一个主要部分就是磁盘性能。iostat 命令提供了存储接口的性能指标。

# iostat Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 avg-cpu: %user %nice %sys %iowait %idle 15.71 0.00 1.07 3.30 79.91 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn cciss/c0d0 4.85 34.82 130.69 307949274 1155708619 cciss/c0d0p1 0.08 0.21 0.00 1897036 3659 cciss/c0d0p2 18.11 34.61 130.69 306051650 1155700792 cciss/c0d1 0.96 13.32 19.75 117780303 174676304 cciss/c0d1p1 2.67 13.32 19.75 117780007 174676288 sda 0.00 0.00 0.00 184 0 sdb 1.03 5.94 18.84 52490104 166623534 sdc 0.00 0.00 0.00 184 0 sdd 1.74 38.19 11.49 337697496 101649200 sde 0.00 0.00 0.00 184 0 sdf 1.51 34.90 6.80 308638992 60159368 sdg 0.00 0.00 0.00 184 0 ... and so on ...

输出的开始部分显示了可用 CPU 和 I/O 等待时间等指标,与您在 mpstat 命令中看到的相同。

输出的下一部分显示对系统上每个磁盘设备非常重要的指标。让我们看一看这些列的含义:

Device

设备名称

tps  

每秒的传输数量,例如,每秒的 I/O 操作数。注:这只是 I/O 操作的数量;每个操作可能非常大,也可能非常小。

Blk_read/s  

每秒从该设备读取的块数。通常,块的大小为 512 字节。这是一个磁盘利用率较好的值。

Blk_wrtn/s  

每秒写入该设备的块数

Blk_read  

到目前为止从该设备读取的块数。注意,这并不是正在发生的情况。很多块已经从该设备读取。可能现在什么也没有读取。观察一段时间,看是否有变化。

Blk_wrtn

写入该设备的块数。

在一个拥有很多设备的系统中,输出可能需要通过屏幕多次滚动 — 这使得某些内容较难检查,尤其当您查找特定设备时更是如此。可以通过将该设备作为参数传递只获得特定设备的指标。

# iostat sdaj Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 avg-cpu: %user %nice %sys %iowait %idle 15.71 0.00 1.07 3.30 79.91 Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn sdaj 1.58 31.93 10.65 282355456 94172401

开始部分显示的 CPU 指标可能没什么用处。要取消在输出开始部分显示的与 CPU 有关的统计信息,使用 -d 选项。
 
可以将可选参数放在结尾处,让 iostat 以固定的时间间隔显示设备统计信息。要每隔 5 秒获取一次该设备的统计信息,共 10 次,执行以下命令:

# iostat -d sdaj 5 10 You can display the stats in kilobytes instead of just bytes using the -k option: # iostat -k -d sdaj Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 Device: tps kB_read/s kB_wrtn/s kB_read kB_wrtn sdaj 1.58 15.96 5.32 141176880 47085232

尽管以上输出可能非常有帮助,但很多信息并不容易显示。例如,磁盘问题的一个主要原因是磁盘服务时间,即,磁盘将数据送达请求该数据的进程的时间。要获得该级别的指标,我们需要使用 -x 选项获得磁盘的“扩展”统计信息。

# iostat -x sdaj Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 avg-cpu: %user %nice %sys %iowait %idle 15.71 0.00 1.07 3.30 79.91 Device: rrqm/s wrqm/s r/s w/s rsec/s wsec/s rkB/s wkB/s avgrq-sz avgqu-sz await svctm %util sdaj 0.00 0.00 1.07 0.51 31.93 10.65 15.96 5.32 27.01 0.01 6.26 6.00 0.95

让我们看一看这些列的含义:

Device

设备名称

rrqm/s

每秒合并的读请求数。磁盘请求排成队列。只要可能,内核就会尝试将多个请求合并成一个请求。该指标测量读取传输的合并请求数。

wrqm/s  

与读取类似,这是合并的写请求数。

r/s  

每秒向该设备发出的读请求数

w/s 

同样,它是每秒向该设备发出的写请求数

rsec/s 

每秒从该设备读取的扇区数

wsec/s   

每秒写入该设备的扇区数

rkB/s   

每秒从该设备读取的数据,以 KB/秒为单位

wkB/s

写入该设备的数据,以 kb/s 为单位

avgrq-sz

读请求的平均大小(扇区数)

avgqu-sz  

该设备的请求队列的平均长度

await 

设备发出 I/O 请求经过的平均时间,以毫秒为单位。这是服务时间与队列中的等待时间的总和。

svctm 

设备的平均服务时间,以毫秒为单位

%util

设备的带宽利用率。如果该值接近于 100%,则表明该设备已饱和。

它包含大量信息,如何有效地使用这些信息是一个挑战。下一部分介绍如何使用输出。

用法

可以使用这些命令的组合从输出中获取一些有意义的信息。记住,在从进程获取请求时磁盘速度可能很慢。磁盘中的数据到达队列所花费的时间称为服务时间。如果您想找出服务时间最长的磁盘,执行以下命令:

# iostat -x | sort -nrk13 sdat 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 18.80 0.00 64.06 64.05 0.00 sdv 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 17.16 0.00 18.03 17.64 0.00 sdak 0.00 0.00 0.00 0.14 0.00 1.11 0.00 0.55 8.02 0.00 17.00 17.00 0.24 sdm 0.00 0.00 0.00 0.19 0.01 1.52 0.01 0.76 8.06 0.00 16.78 16.78 0.32 ... and so on ...

这表明磁盘 sdat 的服务时间最长(64.05 毫秒)。为什么时间这么长呢?可能性很多,但最可能的原因有三个:

  1. 该磁盘获取了大量请求,以至于平均服务时间长。
  2. 该磁盘利用已移到可能的最大带宽。
  3. 该磁盘原本速度就很慢。

查看输出,我们看到读取数/秒和写入数/秒为 0.00(几乎没有发生任何事件),因此我们可以排除第一种可能性。利用率也为 0.00%(最后一列),因此我们可以排除第二种可能性。这就剩下了第三种可能性。但得出该磁盘原本速度慢的结论之前,我们需要更加仔细地观察该磁盘。我 们可以只检查该磁盘,每隔 5 秒 检查一次,共 10 次。

# iostat -x sdat 5 10

如果输出显示相同的平均服务时间、读取速率和利用率,则可以断定最有可能是第三种情况。如果这些数值发生了变化,我们可以获取更详细的线索来了解该设备服务时间较长的原因。

同样,可以对读取速率列进行排序,以显示处于恒定读取速率下的磁盘。

# iostat -x | sort -nrk6 sdj 0.00 0.00 1.86 0.61 56.78 12.80 28.39 6.40 28.22 0.03 10.69 9.99 2.46 sdah 0.00 0.00 1.66 0.52 50.54 10.94 25.27 5.47 28.17 0.02 10.69 10.00 2.18 sdd 0.00 0.00 1.26 0.48 38.18 11.49 19.09 5.75 28.48 0.01 3.57 3.52 0.61 ... and so on ...

该 信息可以帮助您查找“热”磁盘,即进行很多读取或写入的磁盘。如果该磁盘的确“热”,则应确定“热”的原因;可能是该磁盘上定义的某个文件系统正在进行大 量读取操作。如果是这种情况,则应考虑将该文件系统在多个磁盘之间进行条带化,以分发负载,从而最大程度地减小某个特定磁盘“热”的可能性。

sar

通过前面的讨论,我们发现:获取实时指标并不是唯一重要的事情;历史趋势也同等重要。

此外,考虑这样一种情况:有人多次报告某个性能问题,但当您进行调查时发现一切都回归正常。如果没有当时的任何具体数据,则很难诊断过去出现的性能问题。最后,您将希望检查过去几天的性能数据,以决定某些设置或进行调整。

sar 实用程序实现了这个目标。sar 代表 System Activity Recorder,它在一个特殊的位置(/var/log/sa 目录)记录 Linux 系统的主要组件(CPU、内存、磁盘、网络等)的指标。每天的数据记录在一个名为 sa<nn> 的文件中,其中 <nn> 是每月中的第 nn 天(两位数字)。例如,文件 sa27 包含该月第 27 日的数据。可以通过 sar 命令查询该数据。

使用 sar 的最简单方法是不带任何参数或选项。示例如下:

# sar Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 12:00:01 AM CPU %user %nice %system %iowait %idle 12:10:01 AM all 14.99 0.00 1.27 2.85 80.89 12:20:01 AM all 14.97 0.00 1.20 2.70 81.13 12:30:01 AM all 15.80 0.00 1.39 3.00 79.81 12:40:01 AM all 10.26 0.00 1.25 3.55 84.93 ... and so on ...

输出显示在 10 分钟的间隔内收集的与 CPU 有关的指标。这些列的含义如下:

CPU

CPU 标识符;“all”表示所有 CPU

%user

用户进程使用的 CPU 百分比。Oracle 进程属于这一类。

%nice

在 nice 优先级下执行的 CPU 利用率百分比

%system

执行系统进程的 CPU 百分比

%iowait

等待进行 I/O 操作的 CPU 百分比

%idle

等待工作的 CPU 空闲百分比

从以上输出,您可能以为系统已经得到了很好的平衡;但实际上是严重利用不足(从较高的空闲百分比可以看出)。进一步查看输出,我们看到以下内容:

... continued from above ... 03:00:01 AM CPU %user %nice %system %iowait %idle 03:10:01 AM all 44.99 0.00 1.27 2.85 40.89 03:20:01 AM all 44.97 0.00 1.20 2.70 41.13 03:30:01 AM all 45.80 0.00 1.39 3.00 39.81 03:40:01 AM all 40.26 0.00 1.25 3.55 44.93 ... and so on ...

这告诉我们另外一回事:在 3:00 和 3:40 之间某些用户进程加载了该系统。可能是在执行开销比较大的查询,也可能是正在运行某个 RMAN 作业,从而消耗了这么多 CPU。这就是 sar 命令非常有用之处,该命令重放记录的数据,显示从某个特定时间起而不是现在的数据。这样您就完全实现了在该部分开头所述的三个目标:获取历史数据、查找使 用模式以及了解趋势。

如果您想查看特定日期的 sar 数据,只需使用下面所示的 -f 选项打开具有该文件名的 sar(打开第 26 日的数据)

# sar -f /var/log/sa/sa26

与 vmstat 或 mpstat 一样,该命令还可以显示实时数据。要每隔 5 秒获取一次数据,共 10 次,请使用:

# sar 5 10 Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 01:39:16 PM CPU %user %nice %system %iowait %idle 01:39:21 PM all 20.32 0.00 0.18 1.00 78.50 01:39:26 PM all 23.28 0.00 0.20 0.45 76.08 01:39:31 PM all 29.45 0.00 0.27 1.45 68.83 01:39:36 PM all 16.32 0.00 0.20 1.55 81.93 … and so on 10 times …

您注意到 CPU 下的“all”值了吗?它意味着是所有 CPU 的总计统计信息。这比较适合单处理器系统,但在多处理器系统中,您可能希望获取各个 CPU 的统计信息以及总计统计信息。-P ALL 选项可以实现该目标。

#sar -P ALL 2 2 Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 01:45:12 PM CPU %user %nice %system %iowait %idle 01:45:14 PM all 22.31 0.00 10.19 0.69 66.81 01:45:14 PM 0 8.00 0.00 24.00 0.00 68.00 01:45:14 PM 1 99.00 0.00 1.00 0.00 0.00 01:45:14 PM 2 6.03 0.00 18.59 0.50 74.87 01:45:14 PM 3 3.50 0.00 8.50 0.00 88.00 01:45:14 PM 4 4.50 0.00 14.00 0.00 81.50 01:45:14 PM 5 54.50 0.00 6.00 0.00 39.50 01:45:14 PM 6 2.96 0.00 7.39 2.96 86.70 01:45:14 PM 7 0.50 0.00 2.00 2.00 95.50 01:45:14 PM CPU %user %nice %system %iowait %idle 01:45:16 PM all 18.98 0.00 7.05 0.19 73.78 01:45:16 PM 0 1.00 0.00 31.00 0.00 68.00 01:45:16 PM 1 37.00 0.00 5.50 0.00 57.50 01:45:16 PM 2 13.50 0.00 19.00 0.00 67.50 01:45:16 PM 3 0.00 0.00 0.00 0.00 100.00 01:45:16 PM 4 0.00 0.00 0.50 0.00 99.50 01:45:16 PM 5 99.00 0.00 1.00 0.00 0.00 01:45:16 PM 6 0.50 0.00 0.00 0.00 99.50 01:45:16 PM 7 0.00 0.00 0.00 1.49 98.51 Average: CPU %user %nice %system %iowait %idle Average: all 20.64 0.00 8.62 0.44 70.30 Average: 0 4.50 0.00 27.50 0.00 68.00 Average: 1 68.00 0.00 3.25 0.00 28.75 Average: 2 9.77 0.00 18.80 0.25 71.18 Average: 3 1.75 0.00 4.25 0.00 94.00 Average: 4 2.25 0.00 7.25 0.00 90.50 Average: 5 76.81 0.00 3.49 0.00 19.70 Average: 6 1.74 0.00 3.73 1.49 93.03 Average: 7 0.25 0.00 1.00 1.75 97.01

这表示 CPU 标识符(以 0 开头)以及每个 CPU 的统计信息。在输出的结尾处,您将看到每个 CPU 的平均运行情况。

命令 sar 不仅用于获取与 CPU 有关的统计信息。对于获取与内存有关的统计信息也非常有用。-r 选项显示大量利用内存的情况。

# sar -r Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 12:00:01 AM kbmemfree kbmemused %memused kbbuffers kbcached kbswpfree kbswpused %swpused kbswpcad 12:10:01 AM 712264 32178920 97.83 2923884 25430452 16681300 95908 0.57 380 12:20:01 AM 659088 32232096 98.00 2923884 25430968 16681300 95908 0.57 380 12:30:01 AM 651416 32239768 98.02 2923920 25431448 16681300 95908 0.57 380 12:40:01 AM 651840 32239344 98.02 2923920 25430416 16681300 95908 0.57 380 12:50:01 AM 700696 32190488 97.87 2923920 25430416 16681300 95908 0.57 380

让我们看一看每个列的含义:

kbmemfree

此时可用内存的数量,以 KB 为单位

kbmemused 

此时已使用的内存数量,以 KB 为单位

%memused

已使用内存的百分比

kbbuffers 

用作缓冲区的内存百分比

kbcached

用作缓存的内存百分比

kbswpfree

此时可用交换区空间的大小,以 KB 为单位

kbswpused 

此时已使用的交换空间大小,以 KB 为单位

%swpused 

此时已使用交换区的百分比

kbswpcad

此时缓存的交换区大小,以 KB 为单位

在输出的结尾处,您将看到该时间段内的平均数字。

还可以获取与特定内存有关的统计信息。-B 选项显示与分页有关的活动。

# sar -B Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 12:00:01 AM pgpgin/s pgpgout/s fault/s majflt/s 12:10:01 AM 134.43 256.63 8716.33 0.00 12:20:01 AM 122.05 181.48 8652.17 0.00 12:30:01 AM 129.05 253.53 8347.93 0.00 ... and so on ...

该列显示当时 而不是现在的指标。

pgpgin/s

每秒从磁盘分到内存中的页面数

pgpgout/s

每秒从内存分到磁盘的页面数

fault/s

每秒的页面故障数

majflt/s

每秒的主要页面故障数

要获得与交换有关活动的类似输出,可以使用 -W 选项。

# sar -W Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 12:00:01 AM pswpin/s pswpout/s 12:10:01 AM 0.00 0.00 12:20:01 AM 0.00 0.00 12:30:01 AM 0.00 0.00 12:40:01 AM 0.00 0.00 ... and so on ...

尽管这些列可能无需加以说明,下面还是提供了每列的说明:

pswpin/s

每秒从磁盘交换回内存的内存页数

pswpout/s

每秒从内存交换到磁盘的内存页数

如果您看到交换很多,则表示可能有内存不足问题。这不是定论,而是出现问题的可能性比较大。

要获得磁盘设备的统计,请使用 -d 选项:

# sar -d Linux 2.6.9-55.0.9.ELlargesmp (prolin3) 12/27/2008 12:00:01 AM DEV tps rd_sec/s wr_sec/s 12:10:01 AM dev1-0 0.00 0.00 0.00 12:10:01 AM dev1-1 5.12 0.00 219.61 12:10:01 AM dev1-2 3.04 42.47 22.20 12:10:01 AM dev1-3 0.18 1.68 1.41 12:10:01 AM dev1-4 1.67 18.94 15.19 ... and so on ... Average: dev8-48 4.48 100.64 22.15 Average: dev8-64 0.00 0.00 0.00 Average: dev8-80 2.00 47.82 5.37 Average: dev8-96 0.00 0.00 0.00 Average: dev8-112 2.22 49.22 12.08

下面是对各列的说明。同样,它们也表示当时的指标。

tps

每秒进行的传输数。传输数就是 I/O 操作数。注:这只是操作数量,每个操作可能很大,也可能很小。因此,单独这个并不能说明全部问题。

rd_sec/s

每秒从磁盘读取的扇区数

wr_sec/s

每秒写入磁盘的扇区数

要获得历史网络统计信息,使用 -n 选项:

# sar -n DEV | more Linux 2.6.9-42.0.3.ELlargesmp (prolin3) 12/27/2008 12:00:01 AM IFACE rxpck/s txpck/s rxbyt/s txbyt/s rxcmp/s txcmp/s rxmcst/s 12:10:01 AM lo 4.54 4.54 782.08 782.08 0.00 0.00 0.00 12:10:01 AM eth0 2.70 0.00 243.24 0.00 0.00 0.00 0.99 12:10:01 AM eth1 0.00 0.00 0.00 0.00 0.00 0.00 0.00 12:10:01 AM eth2 0.00 0.00 0.00 0.00 0.00 0.00 0.00 12:10:01 AM eth3 0.00 0.00 0.00 0.00 0.00 0.00 0.00 12:10:01 AM eth4 143.79 141.14 73032.72 38273.59 0.00 0.00 0.99 12:10:01 AM eth5 0.00 0.00 0.00 0.00 0.00 0.00 0.00 12:10:01 AM eth6 0.00 0.00 0.00 0.00 0.00 0.00 0.00 12:10:01 AM eth7 0.00 0.00 0.00 0.00 0.00 0.00 0.00 12:10:01 AM bond0 146.49 141.14 73275.96 38273.59 0.00 0.00 1.98 … and so on … Average: bond0 128.73 121.81 85529.98 27838.44 0.00 0.00 1.98 Average: eth8 0.00 0.00 0.00 0.00 0.00 0.00 0.00 Average: eth9 3.52 6.74 251.63 10179.83 0.00 0.00 0.00 Average: sit0 0.00 0.00 0.00 0.00 0.00 0.00 0.00

总而言之,使用 sar 命令的这些选项可以获得组件的指标:

使用该选项 …

… 获得有关以下组件的统计信息:

-P

特定 CPU

-d

磁盘

-r

内存

-B

分页

-W

交换

-n

网络

是否希望在一个输出中获得所有可用的统计信息?不必使用所有这些选项调用 sar,您可以改用 -A 选项,该选项显示存储在 sar 文件中的所有统计信息。

结论

总之,使用这些有限的命令集,可以处理与 Linux 环境中的资源管理有关的大多数任务。建议在您的环境中练习这些方法,以使您自己熟悉这些命令以及此处所述的选项。

在接下来的部分中,您将了解如何监视和管理网络。还将了解帮助您管理 Linux 环境的各种命令:发现谁已经登录、设置 shell 配置文件、使用 cpio 和 tar 进行备份等等。

深入阅读


Arup Nanda ( arup@proligence.com ) 担任专职 Oracle DBA 已逾 12 年,他拥有 Oracle 数据库技术各个领域的经验,2003 年被 Oracle 杂志授予“年度 DBA”称号。Arup 经常在 Oracle 相关的活动中发表演讲并为 Oracle 相关刊物撰写文章,他还是一位 Oracle ACE 总监 。他与其他人合作编写了四本书,其中包括 《RMAN Recipes for Oracle Database 11g:A Problem Solution Approach》


159 SYS rman@prolin2 (TNS V1-V3)

rman 进程在进行与 CPU 周期相关的 IO 等待。该信息可以帮助您确定接下来的操作流程。

skill 和 snice

通过前面的讨论,您已经了解了如何识别占用 CPU 的资源。如果您发现了一个占用大量 CPU 和内存的进程,但又不想停止它,该怎么办?考虑下面的 top 输出:

$ top -c -p 16514 23:00:44 up 12 days, 2:04, 4 users, load average: 0.47, 0.35, 0.31 1 processes: 1 sleeping, 0 running, 0 zombie, 0 stopped CPU states: cpu user nice system irq softirq iowait idle total 0.0% 0.6% 8.7% 2.2% 0.0% 88.3% 0.0% Mem: 1026912k av, 1010476k used, 16436k free, 0k shrd, 52128k buff 766724k actv, 143128k in_d, 14264k in_c Swap: 2041192k av, 83160k used, 1958032k free 799432k cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 16514 oracle 19 4 28796 26M 20252 D N 7.0 2.5 0:03 0 oraclePRODB2...

既然您确认进程 16514 占用了大量内存,您就可以使用 skill 命令“冻结”它,而不是停止它。

$ skill -STOP 1

之后,检查 top 输出:

23:01:11 up 12 days, 2:05, 4 users, load average: 1.20, 0.54, 0.38 1 processes: 0 sleeping, 0 running, 0 zombie, 1 stopped CPU states: cpu user nice system irq softirq iowait idle total 2.3% 0.0% 0.3% 0.0% 0.0% 2.3% 94.8% Mem: 1026912k av, 1008756k used, 18156k free, 0k shrd, 3976k buff 770024k actv, 143496k in_d, 12876k in_c Swap: 2041192k av, 83152k used, 1958040k free 851200k cached PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 16514 oracle 19 4 28796 26M 20252 T N 0.0 2.5 0:04 0 oraclePRODB2...

现在,CPU 从 0% 空闲变为 94% 空闲。该进程被有效冻结。过一段时间之后,您可能希望唤醒该进程:

$ skill -CONT 16514

如果希望暂时冻结进程以便为完成更重要的进程腾出空间,该方法非常有用。

此命令用途很广。如果您要停止 "oracle" 用户的所有进程,只需要一个命令即可实现:

$ skill -STOP oracle

可以使用用户、PID、命令或终端 id 作为参数。以下命令可停止所有 rman 命令。

$ skill -STOP rman

如您所见,skill 决定您输入的参数(进程 ID、用户 ID 或命令)并进行相应操作。这可能会导致在某些情况下出现这样的问题:您可能具有同名的用户和命令。最好的示例是 "oracle" 进程,通常由用户 "oracle" 运行。因此,当您希望停止名为 "oracle" 的进程时,可执行以下命令:

$ skill -STOP oracle

用户 "oracle" 的所有进程都停止,包括您可能要使用的会话。要非常明确地执行命令,您可以选择使用一个新参数指定参数的类型。要停止一个名为 oracle 的命令,可执行以下命令:

$ skill -STOP -c oracle

snice 命令的功能与 skill 类似。但它用于降低进程的优先级,而不是停止进程。首先,检查 top 输出:

PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 3 root 15 0 0 0 0 RW 0.0 0.0 0:00 0 kapmd 13680 oracle 15 0 11336 10M 8820 T 0.0 1.0 0:00 0 oracle 13683 oracle 15 0 9972 9608 7788 T 0.0 0.9 0:00 0 oracle 13686 oracle 15 0 9860 9496 7676 T 0.0 0.9 0:00 0 oracle 13689 oracle 15 0 10004 9640 7820 T 0.0 0.9 0:00 0 oracle 13695 oracle 15 0 9984 9620 7800 T 0.0 0.9 0:00 0 oracle 13698 oracle 15 0 10064 9700 7884 T 0.0 0.9 0:00 0 oracle 13701 oracle 15 0 22204 21M 16940 T 0.0 2.1 0:00 0 oracle

现在,将 "oracle" 进程的优先级降低四个点。注意,该值越高,优先级越低。

$ snice +4 -u oracle PID USER PRI NI SIZE RSS SHARE STAT %CPU %MEM TIME CPU COMMAND 16894 oracle 20 4 38904 32M 26248 D N 5.5 3.2 0:01 0 oracle

注意,NI 列(nice 值)现在是 4,优先级现在设置为 20,而不是 15。这对于降低优先级非常有帮助。



md5sum:WARNING:1 of 2 computed checksums did NOT match

输出清楚地表明 file1 已被修改。

适用于 Oracle 用户的技巧

md5sum 是一个非常强大的用于安全性实施的命令。您所管理的某些配置文件(如 listener.ora、tnsnames.ora 和 init.ora)对于成功的 Oracle 基础架构非常重要,任何修改都可能会导致停机。这些通常是更改控制过程的一部分。不要相信别人所说的这些文件并未更改,使用 MD5 校验和执行该命令。创建一个校验和文件,并在每次执行计划的更改时重新创建该文件。作为合规性的一部分,使用 md5sum 命令检查该文件。如果某个人无意中更新了这些重要文件中的一个,您就会立即捕获更改。

同样,您还可以为 $ORACLE_HOME/bin 中的所有可执行文件创建 MD5 校验和,并不断比较它们以捕获未授权的修改。

结论

到目前为止,您只学习了对于高效执行作业比较有用的 Linux 命令的一部分。在下一部分中,我将介绍一些更复杂但却很有用的命令,如 stracewhereisreniceskill 等。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值