Friday, October 12, 2018

管理 Linux 系统中的用户

管理 Linux 系统中的用户

也许你的 Lniux 用户并不是愤怒的公牛,但是当涉及管理他们的账户的时候,能让他们一直开心也是一种挑战。监控他们当前正在访问的东西,追踪他们他们遇到问题时的解决方案,并且保证能把他们在使用系统时出现的重要变动记录下来。这里有一些方法和工具可以使这份工作轻松一点。

配置账户

添加和移除账户是管理用户中最简单的一项,但是这里面仍然有很多需要考虑的选项。无论你是用桌面工具或是命令行选项,这都是一个非常自动化的过程。你可以使用命令添加一个新用户,像是 adduser jdoe,这同时会触发一系列的事情。使用下一个可用的 UID 可以创建 John 的账户,或许还会被许多用以配置账户的文件所填充。当你运行 adduser 命令加一个新的用户名的时候,它将会提示一些额外的信息,同时解释这是在干什么。
  1. $ sudo adduser jdoe
  2. Adding user 'jdoe' ...
  3. Adding new group `jdoe' (1001) ...
  4. Adding new user `jdoe' (1001) with group `jdoe' ...
  5. Creating home directory `/home/jdoe' ...
  6. Copying files from `/etc/skel' …
  7. Enter new UNIX password:
  8. Retype new UNIX password:
  9. passwd: password updated successfully
  10. Changing the user information for jdoe
  11. Enter the new value, or press ENTER for the default
  12. Full Name []: John Doe
  13. Room Number []:
  14. Work Phone []:
  15. Home Phone []:
  16. Other []:
  17. Is the information correct? [Y/n] Y
像你看到的那样,adduser 将添加用户的信息(到 /etc/passwd 和 /etc/shadow 文件中),创建新的家目录,并用 /etc/skel 里设置的文件填充家目录,提示你分配初始密码和认定信息,然后确认这些信息都是正确的,如果你在最后的提示 “Is the information correct” 处的答案是 “n”,它将回溯你之前所有的回答,允许修改任何你想要修改的地方。
创建好一个用户后,你可能会想要确认一下它是否是你期望的样子,更好的方法是确保在添加第一个帐户之前,“自动”选择与您想要查看的内容相匹配。默认有默认的好处,它对于你想知道他们定义在哪里有所用处,以防你想作出一些变动 —— 例如,你不想家目录在 /home 里,你不想用户 UID 从 1000 开始,或是你不想家目录下的文件被系统上的每个人都可读。
adduser 如何工作的一些细节设置在 /etc/adduser.conf 文件里。这个文件包含的一些设置决定了一个新的账户如何配置,以及它之后的样子。注意,注释和空白行将会在输出中被忽略,因此我们可以更加集中注意在设置上面。
  1. $ cat /etc/adduser.conf | grep -v "^#" | grep -v "^$"
  2. DSHELL=/bin/bash
  3. DHOME=/home
  4. GROUPHOMES=no
  5. LETTERHOMES=no
  6. SKEL=/etc/skel
  7. FIRST_SYSTEM_UID=100
  8. LAST_SYSTEM_UID=999
  9. FIRST_SYSTEM_GID=100
  10. LAST_SYSTEM_GID=999
  11. FIRST_UID=1000
  12. LAST_UID=29999
  13. FIRST_GID=1000
  14. LAST_GID=29999
  15. USERGROUPS=yes
  16. USERS_GID=100
  17. DIR_MODE=0755
  18. SETGID_HOME=no
  19. QUOTAUSER=""
  20. SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)"
可以看到,我们有了一个默认的 shell(DSHELL),UID(FIRST_UID)的开始数值,家目录(DHOME)的位置,以及启动文件(SKEL)的来源位置。这个文件也会指定分配给家目录(DIR_HOME)的权限。
其中 DIR_HOME 是最重要的设置,它决定了每个家目录被使用的权限。这个设置分配给用户创建的目录权限是 755,家目录的权限将会设置为 rwxr-xr-x。用户可以读其他用户的文件,但是不能修改和移除他们。如果你想要更多的限制,你可以更改这个设置为 750(用户组外的任何人都不可访问)甚至是 700(除用户自己外的人都不可访问)。
任何用户账号在创建之前都可以进行手动修改。例如,你可以编辑 /etc/passwd 或者修改家目录的权限,开始在新服务器上添加用户之前配置 /etc/adduser.conf 可以确保一定的一致性,从长远来看可以节省时间和避免一些麻烦。
/etc/adduser.conf 的修改将会在之后创建的用户上生效。如果你想以不同的方式设置某个特定账户,除了用户名之外,你还可以选择使用 adduser 命令提供账户配置选项。或许你想为某些账户分配不同的 shell,请求特殊的 UID,完全禁用登录。adduser 的帮助页将会为你显示一些配置个人账户的选择。
  1. adduser [options] [--home DIR] [--shell SHELL] [--no-create-home]
  2. [--uid ID] [--firstuid ID] [--lastuid ID] [--ingroup GROUP | --gid ID]
  3. [--disabled-password] [--disabled-login] [--gecos GECOS]
  4. [--add_extra_groups] [--encrypt-home] user
每个 Linux 系统现在都会默认把每个用户放入对应的组中。作为一个管理员,你可能会选择以不同的方式去做事。你也许会发现把用户放在一个共享组中可以让你的站点工作的更好,这时,选择使用 adduser 的 --gid 选项去选择一个特定的组。当然,用户总是许多组的成员,因此也有一些选项去管理主要和次要的组。

处理用户密码

一直以来,知道其他人的密码都是一个不好的念头,在设置账户时,管理员通常使用一个临时的密码,然后在用户第一次登录时会运行一条命令强制他修改密码。这里是一个例子:
  1. $ sudo chage -d 0 jdoe
当用户第一次登录的时候,会看到像这样的事情:
  1. WARNING: Your password has expired.
  2. You must change your password now and login again!
  3. Changing password for jdoe.
  4. (current) UNIX password:

添加用户到副组

添加用户到副组中,你可能会用如下所示的 usermod 命令 —— 添加用户到组中并确认已经做出变动。
  1. $ sudo usermod -a -G sudo jdoe
  2. $ sudo grep sudo /etc/group
  3. sudo:x:27:shs,jdoe
记住在一些组,像是 sudo 或者 wheel 组中,意味着包含特权,一定要特别注意这一点。

移除用户,添加组等

Linux 系统也提供了命令去移除账户、添加新的组、移除组等。例如,deluser 命令,将会从 /etc/passwd 和 /etc/shadow 中移除用户登录入口,但是会完整保留他的家目录,除非你添加了 --remove-home 或者 --remove-all-files 选项。addgroup 命令会添加一个组,按目前组的次序给他下一个 ID(在用户组范围内),除非你使用 --gid 选项指定 ID。
  1. $ sudo addgroup testgroup --gid=131
  2. Adding group `testgroup' (GID 131) ...
  3. Done.

管理特权账户

一些 Linux 系统中有一个 wheel 组,它给组中成员赋予了像 root 一样运行命令的能力。在这种情况下,/etc/sudoers 将会引用该组。在 Debian 系统中,这个组被叫做 sudo,但是以相同的方式工作,你在 /etc/sudoers 中可以看到像这样的引用:
  1. %sudo ALL=(ALL:ALL) ALL
这个基础的设定意味着,任何在 wheel 或者 sudo 组中的成员,只要在他们运行的命令之前添加 sudo,就可以以 root 的权限去运行命令。
你可以向 sudoers 文件中添加更多有限的特权 —— 也许给特定用户运行一两个 root 的命令。如果这样做,您还应定期查看 /etc/sudoers 文件以评估用户拥有的权限,以及仍然需要提供的权限。
在下面显示的命令中,我们看到在 /etc/sudoers 中匹配到的行。在这个文件中最有趣的行是,包含能使用 sudo 运行命令的路径设置,以及两个允许通过 sudo 运行命令的组。像刚才提到的那样,单个用户可以通过包含在 sudoers 文件中来获得权限,但是更有实际意义的方法是通过组成员来定义各自的权限。
  1. # cat /etc/sudoers | grep -v "^#" | grep -v "^$"
  2. Defaults env_reset
  3. Defaults mail_badpass
  4. Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"
  5. root ALL=(ALL:ALL) ALL
  6. %admin ALL=(ALL) ALL <== admin group
  7. %sudo ALL=(ALL:ALL) ALL <== sudo group

登录检查

你可以通过以下命令查看用户的上一次登录:
  1. # last jdoe
  2. jdoe pts/18 192.168.0.11 Thu Sep 14 08:44 - 11:48 (00:04)
  3. jdoe pts/18 192.168.0.11 Thu Sep 14 13:43 - 18:44 (00:00)
  4. jdoe pts/18 192.168.0.11 Thu Sep 14 19:42 - 19:43 (00:00)
如果你想查看每一个用户上一次的登录情况,你可以通过一个像这样的循环来运行 last 命令:
  1. $ for user in `ls /home`; do last $user | head -1; done
  2. jdoe pts/18 192.168.0.11 Thu Sep 14 19:42 - 19:43 (00:03)
  3. rocket pts/18 192.168.0.11 Thu Sep 14 13:02 - 13:02 (00:00)
  4. shs pts/17 192.168.0.11 Thu Sep 14 12:45 still logged in
此命令仅显示自当前 wtmp 文件变为活跃状态以来已登录的用户。空白行表示用户自那以后从未登录过,但没有将其调出。一个更好的命令是过滤掉在这期间从未登录过的用户的显示:
  1. $ for user in `ls /home`; do echo -n "$user ";last $user | head -1 | awk '{print substr($0,40)}'; done
  2. dhayes
  3. jdoe pts/18 192.168.0.11 Thu Sep 14 19:42 - 19:43
  4. peanut pts/19 192.168.0.29 Mon Sep 11 09:15 - 17:11
  5. rocket pts/18 192.168.0.11 Thu Sep 14 13:02 - 13:02
  6. shs pts/17 192.168.0.11 Thu Sep 14 12:45 still logged
  7. tsmith
这个命令会打印很多,但是可以通过一个脚本使它更加清晰易用。
  1. #!/bin/bash
  2. for user in `ls /home`
  3. do
  4. echo -n "$user ";last $user | head -1 | awk '{print substr($0,40)}'
  5. done
有时,此类信息可以提醒您用户角色的变动,表明他们可能不再需要相关帐户。

与用户沟通

Linux 提供了许多方法和用户沟通。你可以向 /etc/motd 文件中添加信息,当用户从终端登录到服务器时,将会显示这些信息。你也可以通过例如 write(通知单个用户)或者 wall(write 给所有已登录的用户)命令发送通知。
  1. $ wall System will go down in one hour
  2. Broadcast message from shs@stinkbug (pts/17) (Thu Sep 14 14:04:16 2017):
  3. System will go down in one hour
重要的通知应该通过多个管道传递,因为很难预测用户实际会注意到什么。mesage-of-the-day(motd),wall 和 email 通知可以吸引用户大部分的注意力。

注意日志文件

更多地注意日志文件上也可以帮你理解用户活动。事实上,/var/log/auth.log 文件将会为你显示用户的登录和注销活动,组的创建等。/var/log/message 或者 /var/log/syslog 文件将会告诉你更多有关系统活动的事情。

追踪问题和请求

无论你是否在 Linux 系统上安装了票务系统,跟踪用户遇到的问题以及他们提出的请求都非常重要。如果请求的一部分久久不见回应,用户必然不会高兴。即使是纸质日志也可能是有用的,或者更好的是,有一个电子表格,可以让你注意到哪些问题仍然悬而未决,以及问题的根本原因是什么。确保解决问题和请求非常重要,日志还可以帮助您记住你必须采取的措施来解决几个月甚至几年后重新出现的问题。

总结

在繁忙的服务器上管理用户帐户部分取决于从配置良好的默认值开始,部分取决于监控用户活动和遇到的问题。如果用户觉得你对他们的顾虑有所回应并且知道在需要系统升级时会发生什么,他们可能会很高兴。

如何在 Linux 中配置基于密钥认证的 SSH

如何在 Linux 中配置基于密钥认证的 SSH

什么是基于 SSH 密钥的认证?

众所周知,Secure Shell,又称 SSH,是允许你通过无安全网络(例如 Internet)和远程系统之间安全访问/通信的加密网络协议。无论何时使用 SSH 在无安全网络上发送数据,它都会在源系统上自动地被加密,并且在目的系统上解密。SSH 提供了四种加密方式,基于密码认证,基于密钥认证,基于主机认证和键盘认证。最常用的认证方式是基于密码认证和基于密钥认证。
在基于密码认证中,你需要的仅仅是远程系统上用户的密码。如果你知道远程用户的密码,你可以使用 ssh user@remote-system-name 访问各自的系统。另一方面,在基于密钥认证中,为了通过 SSH 通信,你需要生成 SSH 密钥对,并且为远程系统上传 SSH 公钥。每个 SSH 密钥对由私钥与公钥组成。私钥应该保存在客户系统上,公钥应该上传给远程系统。你不应该将私钥透露给任何人。希望你已经对 SSH 和它的认证方式有了基本的概念。
这篇教程,我们将讨论如何在 Linux 上配置基于密钥认证的 SSH。

在 Linux 上配置基于密钥认证的 SSH

为方便演示,我将使用 Arch Linux 为本地系统,Ubuntu 18.04 LTS 为远程系统。
本地系统详情:
  • OS: Arch Linux Desktop
  • IP address: 192.168.225.37/24
远程系统详情:
  • OS: Ubuntu 18.04 LTS Server
  • IP address: 192.168.225.22/24

本地系统配置

就像我之前所说,在基于密钥认证的方法中,想要通过 SSH 访问远程系统,需要将公钥上传到远程系统。公钥通常会被保存在远程系统的一个 ~/.ssh/authorized_keys 文件中。
注意事项:不要使用 root 用户生成密钥对,这样只有 root 用户才可以使用。使用普通用户创建密钥对。
现在,让我们在本地系统上创建一个 SSH 密钥对。只需要在客户端系统上运行下面的命令。
  1. $ ssh-keygen
上面的命令将会创建一个 2048 位的 RSA 密钥对。你需要输入两次密码。更重要的是,记住你的密码。后面将会用到它。
样例输出:
  1. Generating public/private rsa key pair.
  2. Enter file in which to save the key (/home/sk/.ssh/id_rsa):
  3. Enter passphrase (empty for no passphrase):
  4. Enter same passphrase again:
  5. Your identification has been saved in /home/sk/.ssh/id_rsa.
  6. Your public key has been saved in /home/sk/.ssh/id_rsa.pub.
  7. The key fingerprint is:
  8. SHA256:wYOgvdkBgMFydTMCUI3qZaUxvjs+p2287Tn4uaZ5KyE [email protected]
  9. The key's randomart image is:
  10. +---[RSA 2048]----+
  11. |+=+*= + |
  12. |o.o=.* = |
  13. |.oo * o + |
  14. |. = + . o |
  15. |. o + . S |
  16. | . E . |
  17. | + o |
  18. | +.*o+o |
  19. | .o*=OO+ |
  20. +----[SHA256]-----+
如果你已经创建了密钥对,你将看到以下信息。输入 y 就会覆盖已存在的密钥。
  1. /home/username/.ssh/id_rsa already exists.
  2. Overwrite (y/n)?
请注意密码是可选的。如果你输入了密码,那么每次通过 SSH 访问远程系统时都要求输入密码,除非你使用了 SSH 代理保存了密码。如果你不想要密码(虽然不安全),简单地敲两次回车。不过,我建议你使用密码。从安全的角度来看,使用无密码的 ssh 密钥对不是什么好主意。这种方式应该限定在特殊的情况下使用,例如,没有用户介入的服务访问远程系统。(例如,用 rsync 远程备份……)
如果你已经在个人文件 ~/.ssh/id_rsa 中有了无密码的密钥,但想要更新为带密码的密钥。使用下面的命令:
  1. $ ssh-keygen -p -f ~/.ssh/id_rsa
样例输出:
  1. Enter new passphrase (empty for no passphrase):
  2. Enter same passphrase again:
  3. Your identification has been saved with the new passphrase.
现在,我们已经在本地系统上创建了密钥对。接下来,使用下面的命令将 SSH 公钥拷贝到你的远程 SSH 服务端上。
  1. $ ssh-copy-id sk@192.168.225.22
在这里,我把本地(Arch Linux)系统上的公钥拷贝到了远程系统(Ubuntu 18.04 LTS)上。从技术上讲,上面的命令会把本地系统 ~/.ssh/id_rsa.pub 文件中的内容拷贝到远程系统 ~/.ssh/authorized_keys 中。明白了吗?非常棒。
输入 yes 来继续连接你的远程 SSH 服务端。接着,输入远程系统用户 sk 的密码。
  1. /usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
  2. /usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
  3. sk@192.168.225.22's password:
  4. Number of key(s) added: 1
  5. Now try logging into the machine, with: "ssh 'sk@192.168.225.22'"
  6. and check to make sure that only the key(s) you wanted were added.
如果你已经拷贝了密钥,但想要替换为新的密码,使用 -f 选项覆盖已有的密钥。
  1. $ ssh-copy-id -f sk@192.168.225.22
我们现在已经成功地将本地系统的 SSH 公钥添加进了远程系统。现在,让我们在远程系统上完全禁用掉基于密码认证的方式。因为我们已经配置了密钥认证,因此不再需要密码认证了。

在远程系统上禁用基于密码认证的 SSH

你需要在 root 用户或者 sudo 执行下面的命令。
禁用基于密码的认证,你需要在远程系统的终端里编辑 /etc/ssh/sshd_config 配置文件:
  1. $ sudo vi /etc/ssh/sshd_config
找到下面这一行,去掉注释然后将值设为 no:
  1. PasswordAuthentication no
重启 ssh 服务让它生效。
  1. $ sudo systemctl restart sshd

从本地系统访问远程系统

在本地系统上使用命令 SSH 你的远程服务端:
  1. $ ssh sk@192.168.225.22
输入密码。
样例输出:
  1. Enter passphrase for key '/home/sk/.ssh/id_rsa':
  2. Last login: Mon Jul 9 09:59:51 2018 from 192.168.225.37
  3. sk@ubuntuserver:~$
现在,你就能 SSH 你的远程系统了。如你所见,我们已经使用之前 ssh-keygen 创建的密码登录进了远程系统的账户,而不是使用当前账户实际的密码。
如果你试图从其它客户端系统 ssh(远程系统),你将会得到这条错误信息。比如,我试图通过命令从 CentOS SSH 访问 Ubuntu 系统:
样例输出:
  1. The authenticity of host '192.168.225.22 (192.168.225.22)' can't be established.
  2. ECDSA key fingerprint is 67:fc:69:b7:d4:4d:fd:6e:38:44:a8:2f:08:ed:f4:21.
  3. Are you sure you want to continue connecting (yes/no)? yes
  4. Warning: Permanently added '192.168.225.22' (ECDSA) to the list of known hosts.
  5. Permission denied (publickey).
如你所见,除了 CentOS(LCTT 译注:根据上文,这里应该是 Arch)系统外,我不能通过其它任何系统 SSH 访问我的远程系统 Ubuntu 18.04。

为 SSH 服务端添加更多客户端系统的密钥

这点非常重要。就像我说过的那样,除非你配置过(在之前的例子中,是 Ubuntu),否则你不能通过 SSH 访问到远程系统。如果我希望给更多客户端予以权限去访问远程 SSH 服务端,我应该怎么做?很简单。你需要在所有的客户端系统上生成 SSH 密钥对并且手动拷贝 ssh 公钥到想要通过 ssh 访问的远程服务端上。
在客户端系统上创建 SSH 密钥对,运行:
  1. $ ssh-keygen
输入两次密码。现在,ssh 密钥对已经生成了。你需要手动把公钥(不是私钥)拷贝到远程服务端上。
使用以下命令查看公钥:
  1. $ cat ~/.ssh/id_rsa.pub
应该会输出类似下面的信息:
  1. ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCt3a9tIeK5rPx9p74/KjEVXa6/OODyRp0QLS/sLp8W6iTxFL+UgALZlupVNgFjvRR5luJ9dLHWwc+d4umavAWz708e6Na9ftEPQtC28rTFsHwmyLKvLkzcGkC5+A0NdbiDZLaK3K3wgq1jzYYKT5k+IaNS6vtrx5LDObcPNPEBDt4vTixQ7GZHrDUUk5586IKeFfwMCWguHveTN7ykmo2EyL2rV7TmYq+eY2ZqqcsoK0fzXMK7iifGXVmuqTkAmZLGZK8a3bPb6VZd7KFum3Ezbu4BXZGp7FVhnOMgau2kYeOH/ItKPzpCAn+dg3NAAziCCxnII9b4nSSGz3mMY4Y7 ostechnix@centosserver
拷贝所有内容(通过 USB 驱动器或者其它任何介质),然后去你的远程服务端的终端,像下面那样,在 $HOME 下创建文件夹叫做 .ssh。你需要以 root 身份执行命令(注:不一定需要 root)。
  1. $ mkdir -p ~/.ssh
现在,将前几步创建的客户端系统的公钥添加进文件中。
  1. echo {Your_public_key_contents_here} >> ~/.ssh/authorized_keys
在远程系统上重启 ssh 服务。现在,你可以在新的客户端上 SSH 远程服务端了。
如果觉得手动添加 ssh 公钥有些困难,在远程系统上暂时性启用密码认证,使用 ssh-copy-id 命令从本地系统上拷贝密钥,最后禁用密码认证。
推荐阅读:
好了,到此为止。基于密钥认证的 SSH 提供了一层防止暴力破解的额外保护。如你所见,配置密钥认证一点也不困难。这是一个非常好的方法让你的 Linux 服务端安全可靠。

Thursday, October 4, 2018

TOP参数解释

TOP参数解释


第一行 分别显示:系统当前时间 系统运行时间 当前用户登陆数 系统负载。
  系统负载(load average),这里有三个数值,分别是系统最近1分钟,5分钟,15分钟的平均负载。一般对于单个处理器来说,负载在0 — 1.00 之间是正常的,超过1.00就要引起注意了。在多核处理器中,你的系统均值不应该高于处理器核心的总数。

第二行 分别显示:total进程总数、 running正在运行的进程数、 sleeping睡眠的进程数、stopped停止的进程数、 zombie僵尸进程数。

第三行
分别显示:
%us用户空间占用CPU百分比、
%sy内核空间占用CPU百分比、
%ni用户进程空间内改变过优先级的进程占用CPU百分比、
%id空闲CPU百分比、
%wa等待输入输出(I/O)的CPU时间百分比 、
%hi指的是cpu处理硬件中断的时间、%si指的是cpu处理软中断的时间 、
%st用于有虚拟cpu的情况,用来指示被虚拟机偷掉的cpu时间。
通常id%值可以反映一个系统cpu的闲忙程度。

第四行 MEM :total 物理内存总量、    used 使用的物理内存总量、free 空闲内存总量、    buffers 用作内核缓存的内存量。

第五行 SWAP:total 交换区总量、     used使用的交换区总量、free 空闲交换区总量、 cached缓冲的交换区总量。
buffers和cached的区别需要说明一下,buffers指的是块设备的读写缓冲区,cached指的是文件系统本身的页面缓存。它们都是linux操作系统底层的机制,目的就是为了加速对磁盘的访问。
第六行  PID(进程号)、 USER(运行用户)、PR(优先级)、NI(任务nice值)、VIRT(虚拟内存用量)VIRT=SWAP+RES 、RES(物理内存用量)、SHR(共享内存用量)、S(进程状态)、%CPU(CPU占用比)、%MEM(物理内存占用比)、TIME+(累计CPU占 用时间)、 COMMAND 命令名/命令行。
下面简单介绍top命令的使用方法:
top [-] [d] [p] [q] [c] [C] [S] [s]  [n]
运维必会!
参数说明
d指定每两次屏幕信息刷新之间的时间间隔。当然用户可以使用s交互命令来改变之。
p通过指定监控进程ID来仅仅监控某个进程的状态。
q该选项将使top没有任何延迟的进行刷新。如果调用程序有超级用户权限,那么top将以尽可能高的优先级运行。
S指定累计模式。
s使top命令在安全模式中运行。这将去除交互命令所带来的潜在危险。
i使top不显示任何闲置或者僵死进程。
c显示整个命令行而不只是显示命令名。
下面介绍在top命令执行过程中可以使用的一些交互命令
  从使用角度来看,熟练的掌握这些命令比掌握选项还重要一些。
  这些命令都是单字母的,如果在命令行选项中使用了s选项,则可能其中一些命令会被屏蔽掉。

Ctrl+L 擦除并且重写屏幕。

h或者? 显示帮助画面,给出一些简短的命令总结说明。
k 终止一个进程。系统将提示用户输入需要终止的进程PID,以及需要发送给该进程什么样的信号。一般的终止进程可以使用15信号;如果不能正常结束那就使用信号9强制结束该进程。默认值是信号15。在安全模式中此命令被屏蔽。
i 忽略闲置和僵死进程。这是一个开关式命令。
q 退出程序。
r 重新安排一个进程的优先级别。系统提示用户输入需要改变的进程PID以及需要设置的进程优先级值。输入一个正值将使优先级降低,反之则可以使该进程拥有更高的优先权。默认值是10。
s 改变两次刷新之间的延迟时间。系统将提示用户输入新的时间,单位为s。如果有小数,就换算成m s。输入0值则系统将不断刷新,默认值是5 s。需要注意的是如果设置太小的时间,很可能会引起不断刷新,从而根本来不及看清显示的情况,而且系统负载也会大大增加。
f或者F 从当前显示中添加或者删除项目。
o或者O 改变显示项目的顺序。
l 切换显示平均负载和启动时间信息。
m 切换显示内存信息。
t 切换显示进程和CPU状态信息。
c 切换显示命令名称和完整命令行。
M 根据驻留内存大小进行排序。
P 根据CPU使用百分比大小进行排序。
T 根据时间/累计时间进行排序。
W 将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。
Shift+M 可按内存占用情况进行排序。

sysstat 说明


[root@www ~]# yum install sysstat -y
[root@www ~]# vmstat --help
usage: vmstat [-V] [-n] [delay [count]]
              -V prints version.
              -n causes the headers not to be reprinted regularly.
              -a print inactive/active page stats.
              -d prints disk statistics
              -D prints disk table
              -p prints disk partition statistics
              -s prints vm table
              -m prints slabinfo
              -t add timestamp to output
              -S unit size
              delay is the delay between updates in seconds.
              unit size k:1000 K:1024 m:1000000 M:1048576 (default is K)
              count is the number of updates.12345678910111213141516
例子:每隔1秒获取1次,次数不限

[root@www ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 547332 177544 535336    0    0     1     6    5   41  1  0 98  0  0   
 0  0      0 547324 177544 535336    0    0     0     0  210  445  1  0 99  0  0   
 0  0      0 547324 177544 535336    0    0     0     0  195  435  0  0 100  0  0
 0  0      0 547324 177544 535336    0    0     0     0  208  440  1  0 99  0  0   
 0  0      0 547332 177544 535336    0    0     0     0  209  446  0  0 100  0  0
 0  0      0 547332 177544 535336    0    0     0     0  207  442  1  1 98  0  0   
 0  0      0 547332 177544 535336    0    0     0     0  201  438  0  0 100  0  0
^C1234567891011
#r表示CPU排队的情况,b代表 进程堵塞,等待io
每隔1秒获取1次,次数10次

[root@www ~]# vmstat 1 10
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 547340 177544 535344    0    0     1     6    5   41  1  0 98  0  0   
 0  0      0 547332 177544 535344    0    0     0    28  210  453  1  1 97  1  0   
 0  0      0 547332 177544 535344    0    0     0     0  200  433  0  0 100  0  0
 0  0      0 547332 177544 535344    0    0     0     0  211  445  1  0 99  0  0   
 0  0      0 547332 177544 535344    0    0     0     0  201  439  0  1 99  0  0   
 0  0      0 547332 177544 535344    0    0     0     0  197  436  0  0 100  0  0
 0  0      0 547332 177544 535344    0    0     0     0  201  442  1  0 99  0  0   
 0  0      0 547324 177544 535348    0    0     0     0  240  484  2  1 97  0  0   
 0  0      0 547324 177544 535348    0    0     0     0  203  438  0  0 100  0  0
 0  0      0 547324 177544 535348    0    0     0     0  197  430  1  0 99  0  0    12345678910111213
mpstat
查看所有CPU的平均值

[root@www ~]# mpstat 1
Linux 2.6.32-431.23.3.el6.x86_64 (www)  08/30/2016  _x86_64_    (1 CPU)
05:13:22 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:13:23 PM  all    1.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.00
105:13:24 PM  all    0.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00  100.00
05:13:25 PM  all    2.00    0.00    1.00    0.00    0.00    0.00    0.00    0.00   97.00
05:13:26 PM  all    1.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   99.00
^C12345678
不解释——————————

[root@www ~]# mpstat 1 10
Linux 2.6.32-431.23.3.el6.x86_64 (www)  08/30/2016  _x86_64_    (1 CPU)
05:13:38 PM  CPU    %usr   %nice    %sys %iowait    %irq   %soft  %steal  %guest   %idle
05:13:39 PM  all    2.00    0.00    0.00    0.00    0.00    0.00    0.00    0.00   98.00
05:13:40 PM  all    0.00    0.00    1.00    0.00    0.00    0.00    0.00    0.00   99.00
05:13:41 PM  all    1.01    0.00    0.00    0.00    0.00    0.00    0.00    0.00   98.99
.................1234567
上述是CPU监控,CPU监控主要靠经验。因为业务不同指标不同,指标越低越好是不变的道理

内存硬盘监控:


硬盘格式化后分成块(blog)
内存默认是页(大小4kb)读取按照页来进行读取
内存:free   vmstat

[root@www ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          1875       1338        537          0        173        523
-/+ buffers/cache:        640       1234
Swap:            0          0          0
提示:云主机是没有Swap分区的123456
total 总内存
used 已使用内存
free 空闲内存
shared 共享内存(进程间相互通信使用共享内存)
buffers 缓冲
cached 缓存
Centos7 会有一个available,活动内存
#云服务器一般不分配swap分区,物理机能不使用交换分区就不使用交换分区
vmstat命令

[root@www ~]# vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 550628 177684 536324    0    0     1     6    7   46  1  0 98  0  0   
 0  0      0 550620 177684 536324    0    0     0    40  187  429  0  0 100  0  0
 0  0      0 550620 177684 536324    0    0     0     0  183  427  1  0 99  0  0   
 0  0      0 550620 177684 536324    0    0     0     0  197  436  0  1 99  0  01234567
swpd交换分区的大小
free可用的物理内存大小
buff 缓冲区的大小
cache 缓存区的大小
si  数据从交换分区读取到内存的大小
so 数据从内存到交换分区
bi 从交换分区读到内存(block)
bo 内存写到硬盘的
内存达到多少报警呢? 80%
1
正常是一个进程启动后会一直往上升,最后到达一个平稳期
硬盘:IOPS  IO’s Per Second        iotop   df -h  iostat
  顺序IO(快)
  随机IO(慢)
查看磁盘剩余空间

[root@www ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvda1       40G  4.1G   34G  11% /
tmpfs           938M     0  938M   0% /dev/shm1234
监控磁盘IO  iotop

[root@www ~]# yum install iotop -y1
iotop

可以使用dd命令生成一个文件夹进行测试
生成命令如下:

[root@www ~]# dd if=/dev/zero of=/tmp/1.txt bs=1M count=1000
1000+0 records in
1000+0 records out
1048576000 bytes (1.0 GB) copied, 20.509 s, 51.1 MB/s
[root@www ~]# ls -lh /tmp/1.txt
-rw-r--r-- 1 root root 1000M Aug 30 19:48 /tmp/1.txt123456
此时IO写入如下图

iostat命令,可以看到那块磁盘,比iotop更加细致

[root@www ~]# iostat 1 2
Linux 2.6.32-431.23.3.el6.x86_64 (www)  08/30/2016  _x86_64_    (1 CPU)
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.10    0.00    0.27    0.16    0.00   98.46
Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
xvda              1.51         2.26        17.09     986748    7467560
avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           1.02    0.00    0.00    0.00    0.00   98.98
Device:            tps   Blk_read/s   Blk_wrtn/s   Blk_read   Blk_wrtn
xvda              0.00         0.00         0.00          0          012345678910
tps 设备每秒的传输次数(每秒多少的io请求)
Blk_read/s 每秒从设备读取的数据量
Blk_wrtn/s 每秒像设备写入的数据量
Blk_read   写入数据的总数
Blk_wrtn    读取数据的总数

每个系统管理员都要知道的 30 个 Linux 系统监控工具

每个系统管理员都要知道的 30 个 Linux 系统监控工具


您需要监控 Linux 服务器的性能吗?试试用这些内置命令和附加工具吧!大多数 Linux 发行版都附带了大量的监控工具。这些工具提供了获取系统活动的相关指标。您可以使用这些工具来查找性能问题的可能原因。本文提到的是一些基本的命令,用于系统分析和服务器调试等,例如:找出系统瓶颈磁盘(存储)瓶颈CPU 和内存瓶颈网络瓶颈

1. top - 进程活动监控命令top 命令会显示 Linux 的进程。它提供了一个运行中系统的实时动态视图,即实际的进程活动。默认情况下,它显示在服务器上运行的 CPU 占用率最高的任务,并且每五秒更新一次。相关链接: Linux 如何查看 CPU 利用率?

2. vmstat - 虚拟内存统计vmstat 命令报告有关进程、内存、分页、块 IO、中断和 CPU 活动等信息。

# vmstat 3输出示例:

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu------
 r b swpd free buff cache si so bi bo in cs us sy id wa st
 0 0 0 2540988 522188 5130400 0 0 2 32 4 2 4 1 96 0 0
 1 0 0 2540988 522188 5130400 0 0 0 720 1199 665 1 0 99 0 0
 0 0 0 2540956 522188 5130400 0 0 0 0 1151 1569 4 1 95 0 0
 0 0 0 2540956 522188 5130500 0 0 0 6 1117 439 1 0 99 0 0
 0 0 0 2540940 522188 5130512 0 0 0 536 1189 932 1 0 98 0 0
 0 0 0 2538444 522188 5130588 0 0 0 0 1187 1417 4 1 96 0 0
 0 0 0 2490060 522188 5130640 0 0 0 18 1253 1123 5 1 94 0 0

显示 Slab 缓存的利用率

# vmstat -m

获取有关活动和非活动内存页面的信息

# vmstat -a

相关链接: 如何查看 Linux 的资源利用率从而找到系统瓶颈?

3. w - 找出登录的用户以及他们在做什么w 命令 显示了当前登录在该系统上的用户及其进程。

# w username
# w vivek

输出示例:

17:58:47 up 5 days, 20:28, 2 users, load average: 0.36, 0.26, 0.24
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
root pts/0 10.1.3.145 14:55 5.00s 0.04s 0.02s vim /etc/resolv.conf
root pts/1 10.1.3.145 17:43 0.00s 0.03s 0.00s w

4. uptime - Linux 系统运行了多久uptime 命令可以用来查看服务器运行了多长时间:当前时间、已运行的时间、当前登录的用户连接数,以及过去 1 分钟、5 分钟和 15 分钟的系统负载平均值。

# uptime

输出示例:18:02:41 up 41 days, 23:42, 1 user, load average: 0.00, 0.00, 0.001 可以被认为是最佳负载值。不同的系统会有不同的负载:对于单核 CPU 系统来说, 1 到3 的负载值是可以接受的;而对于 SMP(对称多处理)系统来说,负载可以是 6 到 10 。

5. ps - 显示系统进程ps 命令显示当前运行的进程。要显示所有的进程,请使用 -A 或 -e 选项:

# ps -A

输出示例:PID TTY TIME CMD
 1 ? 00:00:02 init
 2 ? 00:00:02 migration/0
 3 ? 00:00:01 ksoftirqd/0
 4 ? 00:00:00 watchdog/0
 5 ? 00:00:00 migration/1
 6 ? 00:00:15 ksoftirqd/1
....
.....
 4881 ? 00:53:28 java
 4885 tty1 00:00:00 mingetty
 4886 tty2 00:00:00 mingetty
 4887 tty3 00:00:00 mingetty
 4888 tty4 00:00:00 mingetty
 4891 tty5 00:00:00 mingetty
 4892 tty6 00:00:00 mingetty
 4893 ttyS1 00:00:00 agetty
12853 ? 00:00:00 cifsoplockd
12854 ? 00:00:00 cifsdnotifyd
14231 ? 00:10:34 lighttpd
14232 ? 00:00:00 php-cgi
54981 pts/0 00:00:00 vim
55465 ? 00:00:00 php-cgi
55546 ? 00:00:00 bind9-snmp-stat
55704 pts/1 00:00:00 ps

ps 与 top 类似,但它提供了更多的信息。显示长输出格式

# ps -Al

显示完整输出格式(它将显示传递给进程的命令行参数):

# ps -AlF显示线程(轻量级进程(LWP)和线程的数量(NLWP))
# ps -AlFH在进程后显示线程# ps -AlLm显示系统上所有的进程# ps ax
# ps axu显示进程树
# ps -ejH
# ps axjf
# pstree显示进程的安全信息
# ps -eo euser,ruser,suser,fuser,f,comm,label
# ps axZ
# ps -eM显示指定用户(如 vivek)运行的进程
# ps -U vivek -u vivek u设置用户自定义的输出格式
# ps -eo pid,tid,class,rtprio,ni,pri,psr,pcpu,stat,wchan:14,comm
# ps axo stat,euid,ruid,tty,tpgid,sess,pgrp,ppid,pid,pcpu,comm
# ps -eopid,tt,user,fname,tmout,f,wchan显示某进程(如 lighttpd)的 PID
# ps -C lighttpd -o pid=或
# pgrep lighttpd或
# pgrep -u vivek php-cgi显示指定 PID(如 55977)的进程名称
# ps -p 55977 -o comm=找出占用内存资源最多的前 10 个进程
# ps -auxf | sort -nr -k 4 | head -10找出占用 CPU 资源最多的前 10 个进程
# ps -auxf | sort -nr -k 3 | head -10相关链接: 显示 Linux 上所有运行的进程

6. free - 内存使用情况free 命令显示了系统的可用和已用的物理内存及交换内存的总量,以及内核用到的缓存空间。

# free

输出示例:total used free shared buffers cached
Mem: 12302896 9739664 2563232 0 523124 5154740
-/+ buffers/cache: 4061800 8241096
Swap: 1052248 0 1052248相关链接:
1. 获取 Linux 的虚拟内存的内存页大小(PAGESIZE)
2. 限制 Linux 每个进程的 CPU 使用率
3. 我的 Ubuntu 或 Fedora Linux 系统有多少内存?

7. iostat - CPU 平均负载和磁盘活动iostat 命令用于汇报 CPU 的使用情况,以及设备、分区和网络文件系统(NFS)的 IO 统计信息。

# iostat输出示例:

Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in)   06/26/2009
avg-cpu: %user %nice %system %iowait %steal %idle
 3.50 0.09 0.51 0.03 0.00 95.86
Device: tps Blk_read/s Blk_wrtn/s Blk_read Blk_wrtn
sda 22.04 31.88 512.03 16193351 260102868
sda1 0.00 0.00 0.00 2166 180
sda2 22.04 31.87 512.03 16189010 260102688
sda3 0.00 0.00 0.00 1615 0相关链接: 如何跟踪 Linux 系统的 NFS 目录或磁盘的 IO 负载情况

8. sar - 监控、收集和汇报系统活动sar 命令用于收集、汇报和保存系统活动信息。要查看网络统计,请输入:

# sar -n DEV | more显示 24 日的网络统计:

# sar -n DEV -f /var/log/sa/sa24 | more您还可以使用 sar 显示实时使用情况:

# sar 4 5

输出示例:

Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in)       06/26/2009
06:45:12 PM CPU %user %nice %system %iowait %steal %idle
06:45:16 PM all 2.00 0.00 0.22 0.00 0.00 97.78
06:45:20 PM all 2.07 0.00 0.38 0.03 0.00 97.52
06:45:24 PM all 0.94 0.00 0.28 0.00 0.00 98.78
06:45:28 PM all 1.56 0.00 0.22 0.00 0.00 98.22
06:45:32 PM all 3.53 0.00 0.25 0.03 0.00 96.19
Average: all 2.02 0.00 0.27 0.01 0.00 97.70相关链接:如何将 Linux 系统资源利用率的数据写入文件中如何使用 kSar 创建 sar 性能图以找出系统瓶颈

9. mpstat - 监控多处理器的使用情况mpstat 命令显示每个可用处理器的使用情况,编号从 0 开始。命令 mpstat -P ALL 显示了每个处理器的平均使用率:

# mpstat -P ALL

输出示例:

Linux 2.6.18-128.1.14.el5 (www03.nixcraft.in)       06/26/2009
06:48:11 PM CPU %user %nice %sys %iowait %irq %soft %steal %idle intr/s
06:48:11 PM all 3.50 0.09 0.34 0.03 0.01 0.17 0.00 95.86 1218.04
06:48:11 PM 0 3.44 0.08 0.31 0.02 0.00 0.12 0.00 96.04 1000.31
06:48:11 PM 1 3.10 0.08 0.32 0.09 0.02 0.11 0.00 96.28 34.93
06:48:11 PM 2 4.16 0.11 0.36 0.02 0.00 0.11 0.00 95.25 0.00
06:48:11 PM 3 3.77 0.11 0.38 0.03 0.01 0.24 0.00 95.46 44.80
06:48:11 PM 4 2.96 0.07 0.29 0.04 0.02 0.10 0.00 96.52 25.91
06:48:11 PM 5 3.26 0.08 0.28 0.03 0.01 0.10 0.00 96.23 14.98
06:48:11 PM 6 4.00 0.10 0.34 0.01 0.00 0.13 0.00 95.42 3.75
06:48:11 PM 7 3.30 0.11 0.39 0.03 0.01 0.46 0.00 95.69 76.89相关链接: 多处理器的 Linux 上单独显示每个 CPU 的使用率 .

10. pmap - 监控进程的内存使用情况pmap 命令用以显示进程的内存映射,使用此命令可以查找内存瓶颈。# pmap -d PID显示 PID 为 47394 的进程的内存信息,请输入:

# pmap -d 47394

输出示例:

47394: /usr/bin/php-cgi
Address Kbytes Mode Offset Device Mapping
0000000000400000 2584 r-x-- 0000000000000000 008:00002 php-cgi
0000000000886000 140 rw--- 0000000000286000 008:00002 php-cgi
00000000008a9000 52 rw--- 00000000008a9000 000:00000 [ anon ]
0000000000aa8000 76 rw--- 00000000002a8000 008:00002 php-cgi
000000000f678000 1980 rw--- 000000000f678000 000:00000 [ anon ]
000000314a600000 112 r-x-- 0000000000000000 008:00002 ld-2.5.so
000000314a81b000 4 r---- 000000000001b000 008:00002 ld-2.5.so
000000314a81c000 4 rw--- 000000000001c000 008:00002 ld-2.5.so
000000314aa00000 1328 r-x-- 0000000000000000 008:00002 libc-2.5.so
000000314ab4c000 2048 ----- 000000000014c000 008:00002 libc-2.5.so
.....
......
..
00002af8d48fd000 4 rw--- 0000000000006000 008:00002 xsl.so
00002af8d490c000 40 r-x-- 0000000000000000 008:00002 libnss_files-2.5.so
00002af8d4916000 2044 ----- 000000000000a000 008:00002 libnss_files-2.5.so
00002af8d4b15000 4 r---- 0000000000009000 008:00002 libnss_files-2.5.so
00002af8d4b16000 4 rw--- 000000000000a000 008:00002 libnss_files-2.5.so
00002af8d4b17000 768000 rw-s- 0000000000000000 000:00009 zero (deleted)
00007fffc95fe000 84 rw--- 00007ffffffea000 000:00000 [ stack ]
ffffffffff600000 8192 ----- 0000000000000000 000:00000 [ anon ]
mapped: 933712K writeable/private: 4304K shared: 768000K最后一行非常重要:mapped: 933712K 映射到文件的内存量writeable/private: 4304K 私有地址空间shared: 768000K 此进程与其他进程共享的地址空间相关链接: 使用 pmap 命令查看 Linux 上单个程序或进程使用的内存1 2/ 2 页下一页查看其它分页:

11. netstat - Linux 网络统计监控工具netstat 命令显示网络连接、路由表、接口统计、伪装连接和多播连接等信息。

# netstat -tulpn
# netstat -nat

12. ss - 网络统计ss 命令用于获取套接字统计信息。它可以显示类似于 netstat 的信息。不过 netstat 几乎要过时了, ss 命令更具优势。要显示所有 TCP 或 UDP 套接字:

# ss -t -a或# ss -u -a显示所有带有 SELinux 安全上下文Security Context 的 TCP 套接字:
# ss -t -a -Z请参阅以下关于 ss 和 netstat 命令的资料:ss:显示 Linux TCP / UDP 网络套接字信息使用 netstat 命令获取有关特定 IP 地址连接的详细信息

13. iptraf - 获取实时网络统计信息iptraf 命令是一个基于 ncurses 的交互式 IP 网络监控工具。它可以生成多种网络统计信息,包括 TCP 信息、UDP 计数、ICMP 和 OSPF 信息、以太网负载信息、节点统计信息、IP 校验错误等。它以简单的格式提供了以下信息:基于 TCP 连接的网络流量统计基于网络接口的 IP 流量统计基于协议的网络流量统计基于 TCP/UDP 端口和数据包大小的网络流量统计基于二层地址的网络流量统计图 02:常规接口统计:基于网络接口的 IP 流量统计图 03:基于 TCP 连接的网络流量统计相关链接: 在 Centos / RHEL / Fedora Linux 上安装 IPTraf 以获取网络统计信息

14. tcpdump - 详细的网络流量分析tcpdump 命令是简单的分析网络通信的命令。您需要充分了解 TCP/IP 协议才便于使用此工具。例如,要显示有关 DNS 的流量信息,请输入:

# tcpdump -i eth1 'udp port 53'查看所有去往和来自端口 80 的 IPv4 HTTP 数据包,仅打印真正包含数据的包,而不是像 SYN、FIN 和仅含 ACK 这类的数据包,请输入:# tcpdump 'tcp port 80 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'显示所有目标地址为 202.54.1.5 的 FTP 会话,请输入:

# tcpdump -i eth1 'dst 202.54.1.5 and (port 21 or 20'打印所有目标地址为 192.168.1.5 的 HTTP 会话:

# tcpdump -ni eth0 'dst 192.168.1.5 and tcp and port http'使用 wireshark 查看文件的详细内容,请输入:

# tcpdump -n -i eth1 -s 0 -w output.txt src or dst port 8015. iotop - I/O 监控iotop 命令利用 Linux 内核监控 I/O 使用情况,它按进程或线程的顺序显示 I/O 使用情况。

$ sudo iotop输出示例:相关链接: Linux iotop:什么进程在增加硬盘负载

16. htop - 交互式的进程查看器htop 是一款免费并开源的基于 ncurses 的 Linux 进程查看器。它比 top 命令更简单易用。您无需使用 PID、无需离开 htop 界面,便可以杀掉进程或调整其调度优先级。

$ htop输出示例:相关链接: CentOS / RHEL:安装 htop——交互式文本模式进程查看器

17. atop - 高级版系统与进程监控工具atop 是一个非常强大的交互式 Linux 系统负载监控器,它从性能的角度显示最关键的硬件资源信息。您可以快速查看 CPU、内存、磁盘和网络性能。它还可以从进程的级别显示哪些进程造成了相关 CPU 和内存的负载。

$ atop相关链接: CentOS / RHEL:安装 atop 工具——高级系统和进程监控器

18. ac 和 lastcomm您一定需要监控 Linux 服务器上的进程和登录活动吧。 psacct 或 acct 软件包中包含了多个用于监控进程活动的工具,包括:ac 命令:显示有关用户连接时间的统计信息lastcomm 命令 :显示已执行过的命令accton 命令:打开或关闭进程账号记录功能sa 命令:进程账号记录信息的摘要相关链接: 如何对 Linux 系统的活动做详细的跟踪记录

19. monit - 进程监控器monit 是一个免费且开源的进程监控软件,它可以自动重启停掉的服务。您也可以使用 Systemd、daemontools 或其他类似工具来达到同样的目的。 本教程演示如何在 Debian 或 Ubuntu Linux 上安装和配置 monit 作为进程监控器 。

20. NetHogs - 找出占用带宽的进程NetHogs 是一个轻便的网络监控工具,它按照进程名称(如 Firefox、wget 等)对带宽进行分组。如果网络流量突然爆发,启动 NetHogs,您将看到哪个进程(PID)导致了带宽激增。

$ sudo nethogs相关链接: Linux:使用 Nethogs 工具查看每个进程的带宽使用情况

21. iftop - 显示主机上网络接口的带宽使用情况iftop 命令监听指定接口(如 eth0)上的网络通信情况。 它显示了一对主机的带宽使用情况。

$ sudo iftop

22. vnstat - 基于控制台的网络流量监控工具vnstat 是一个简单易用的基于控制台的网络流量监视器,它为指定网络接口保留每小时、每天和每月网络流量日志。

$ vnstat相关链接:为 ADSL 或专用远程 Linux 服务器保留日常网络流量日志CentOS / RHEL:安装 vnStat 网络流量监控器以保留日常网络流量日志CentOS / RHEL:使用 PHP 网页前端接口查看 Vnstat 图表

23. nmon - Linux 系统管理员的调优和基准测量工具nmon 是 Linux 系统管理员用于性能调优的利器,它在命令行显示 CPU、内存、网络、磁盘、文件系统、NFS、消耗资源最多的进程和分区信息。

$ nmon相关链接: 安装并使用 nmon 工具来监控 Linux 系统的性能

24. glances - 密切关注 Linux 系统glances 是一款开源的跨平台监控工具。它在小小的屏幕上提供了大量的信息,还可以工作于客户端-服务器模式下。$ glances相关链接: Linux:通过 Glances 监控器密切关注您的系统

25. strace - 查看系统调用想要跟踪 Linux 系统的调用和信号吗?试试 strace 命令吧。它对于调试网页服务器和其他服务器问题很有用。了解如何利用其 追踪进程 并查看它在做什么。

26. /proc 文件系统 - 各种内核信息/proc 文件系统提供了不同硬件设备和 Linux 内核的详细信息。更多详细信息,请参阅 Linux 内核 /proc 文档。常见的 /proc 例子:

# cat /proc/cpuinfo
# cat /proc/meminfo
# cat /proc/zoneinfo
# cat /proc/mounts

27. Nagios - Linux 服务器和网络监控Nagios 是一款普遍使用的开源系统和网络监控软件。您可以轻松地监控所有主机、网络设备和服务,当状态异常和恢复正常时它都会发出警报通知。 FAN 是“全自动 Nagios”的缩写。FAN 的目标是提供包含由 Nagios 社区提供的大多数工具包的 Nagios 安装。FAN 提供了标准 ISO 格式的 CD-Rom 镜像,使安装变得更加容易。除此之外,为了改善 Nagios 的用户体验,发行版还包含了大量的工具。

28. Cacti - 基于 Web 的 Linux 监控工具Cacti 是一个完整的网络图形化解决方案,旨在充分利用 RRDTool 的数据存储和图形功能。Cacti 提供了快速轮询器、高级图形模板、多种数据采集方法和用户管理功能。这些功能被包装在一个直观易用的界面中,确保可以实现从局域网到拥有数百台设备的复杂网络上的安装。它可以提供有关网络、CPU、内存、登录用户、Apache、DNS 服务器等的数据。了解如何在 CentOS / RHEL 下 安装和配置 Cacti 网络图形化工具 。

29. KDE 系统监控器 - 实时系统报告和图形化显示KSysguard 是 KDE 桌面的网络化系统监控程序。这个工具可以通过 ssh 会话运行。它提供了许多功能,比如可以监控本地和远程主机的客户端-服务器模式。前端图形界面使用传感器来检索信息。传感器可以返回简单的值或更复杂的信息,如表格。每种类型的信息都有一个或多个显示界面,并被组织成工作表的形式,这些工作表可以分别保存和加载。所以,KSysguard 不仅是一个简单的任务管理器,还是一个控制大型服务器平台的强大工具。图 05:KDE System Guard {图片来源:维基百科}详细用法,请参阅 KSysguard 手册 。

30. GNOME 系统监控器系统监控程序能够显示系统基本信息,并监控系统进程、系统资源使用情况和文件系统。您还可以用其修改系统行为。虽然不如 KDE System Guard 强大,但它提供的基本信息对新用户还是有用的:显示关于计算机硬件和软件的各种基本信息Linux 内核版本GNOME 版本硬件安装的内存处理器和速度系统状况可用磁盘空间进程内存和交换空间网络使用情况文件系统列出所有挂载的文件系统及其基本信息图 06:Gnome 系统监控程序福利:其他工具更多工具:nmap - 扫描服务器的开放端口lsof - 列出打开的文件和网络连接等ntop 基于网页的工具 - ntop 是查看网络使用情况的最佳工具,与 top 命令之于进程的方式类似,即网络流量监控工具。您可以查看网络状态和 UDP、TCP、DNS、HTTP 等协议的流量分发。Conky - X Window 系统下的另一个很好的监控工具。它具有很高的可配置性,能够监视许多系统变量,包括 CPU 状态、内存、交换空间、磁盘存储、温度、进程、网络接口、电池、系统消息和电子邮件等。GKrellM - 它可以用来监控 CPU 状态、主内存、硬盘、网络接口、本地和远程邮箱及其他信息。mtr - mtr 将 traceroute 和 ping 程序的功能结合在一个网络诊断工具中。vtop - 图形化活动监控终端

Oracle数据库面试题

Oracle数据库面试题【转载】

1. Oracle跟SQL Server 2005的区别? 
宏观上:
1). 最大的区别在于平台,oracle可以运行在不同的平台上,sql server只能运行在windows平台上,由于windows平台的稳定性和安全性影响了sql server的稳定性和安全性
2). oracle使用的脚本语言为PL-SQL,而sql server使用的脚本为T-SQL
微观上: 从数据类型,数据库的结构等等回答
2. 如何使用Oracle的游标? 
1).  oracle中的游标分为显示游标和隐式游标
2).  显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;隐式游标是在执行插入 (insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。
3). 显式游标的操作:打开游标、操作游标、关闭游标;PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它
3. Oracle中function和procedure的区别? 
1). 可以理解函数是存储过程的一种
2). 函数可以没有参数,但是一定需要一个返回值,存储过程可以没有参数,不需要返回值
3). 函数return返回值没有返回参数模式,存储过程通过out参数返回值, 如果需要返回多个参数则建议使用存储过程
4). 在sql数据操纵语句中只能调用函数而不能调用存储过程
4. Oracle的导入导出有几种方式,有何区别? 
1). 使用oracle工具 exp/imp
2). 使用plsql相关工具
方法1. 导入/导出的是二进制的数据, 2.plsql导入/导出的是sql语句的文本文件
5. Oracle中有哪几种文件?
数据文件(一般后缀为.dbf或者.ora),日志文件(后缀名.log),控制文件(后缀名为.ctl)
6. 怎样优化Oracle数据库,有几种方式? 
个人理解,数据库性能最关键的因素在于IO,因为操作内存是快速的,但是读写磁盘是速度很慢的,优化数据库最关键的问题在于减少磁盘的IO,就个人理解应该分为物理的和逻辑的优化, 物理的是指oracle产品本身的一些优化,逻辑优化是指应用程序级别的优化
物理优化的一些原则:
1). Oracle的运行环境(网络,硬件等)
2). 使用合适的优化器
3). 合理配置oracle实例参数
4). 建立合适的索引(减少IO)
5). 将索引数据和表数据分开在不同的表空间上(降低IO冲突)
6). 建立表分区,将数据分别存储在不同的分区上(以空间换取时间,减少IO)
   逻辑上优化: 
1). 可以对表进行逻辑分割,如中国移动用户表,可以根据手机尾数分成10个表,这样对性能会有一定的作用
2). Sql语句使用占位符语句,并且开发时候必须按照规定编写sql语句(如全部大写,全部小写等)oracle解析语句后会放置到共享池中
如: select * from Emp where name=?  这个语句只会在共享池中有一条,而如果是字符串的话,那就根据不同名字存在不同的语句,所以占位符效率较好
3). 数据库不仅仅是一个存储数据的地方,同样是一个编程的地方,一些耗时的操作,可以通过存储过程等在用户较少的情况下执行,从而错开系统使用的高峰时间,提高数据库性能
4). 尽量不使用*号,如select * from Emp,因为要转化为具体的列名是要查数据字典,比较耗时
5). 选择有效的表名
对于多表连接查询,可能oracle的优化器并不会优化到这个程度, oracle 中多表查询是根据FROM字句从右到左的数据进行的,那么最好右边的表(也就是基础表)选择数据较少的表,这样排序更快速,如果有link表(多对多中间表),那么将link表放最右边作为基础表,在默认情况下oracle会自动优化,但是如果配置了优化器的情况下,可能不会自动优化,所以平时最好能按照这个方式编写sql
6). Where字句 规则
Oracle 中Where字句时从右往左处理的,表之间的连接写在其他条件之前,能过滤掉非常多的数据的条件,放在where的末尾, 另外!=符号比较的列将不使用索引,列经过了计算(如变大写等)不会使用索引(需要建立起函数), is null、is not null等优化器不会使用索引
7). 使用Exits Not Exits 替代 In  Not in
8). 合理使用事务,合理设置事务隔离性
数据库的数据操作比较消耗数据库资源的,尽量使用批量处理,以降低事务操作次数
7. Oracle中字符串用什么符号链接? 
Oracle中使用 || 这个符号连接字符串 如 ‘abc’ || ‘d’
8. Oracle分区是怎样优化数据库的? 
Oracle的分区可以分为:列表分区、范围分区、散列分区、复合分区。
1).  增强可用性:如果表的一个分区由于系统故障而不能使用,表的其余好的分区仍可以使用;
2).  减少关闭时间:如果系统故障只影响表的一部份分区,那么只有这部份分区需要修复,可能比整个大表修复花的时间更少;
3).  维护轻松:如果需要得建表,独产管理每个公区比管理单个大表要轻松得多;
4).  均衡I/O:可以把表的不同分区分配到不同的磁盘来平衡I/O改善性能;
5).  改善性能:对大表的查询、增加、修改等操作可以分解到表的不同分区来并行执行,可使运行速度更快
6).  分区对用户透明,最终用户感觉不到分区的存在。
9. Oracle是怎样分页的? 
Oracle中使用rownum来进行分页, 这个是效率最好的分页方法,hibernate也是使用rownum来进行oralce分页的
select * from
  ( select rownum r,a from tabName where rownum <= 20 )
where r > 10
10. Oralce怎样存储文件,能够存储哪些文件? 
Oracle 能存储 clob、nclob、 blob、 bfile
Clob  可变长度的字符型数据,也就是其他数据库中提到的文本型数据类型
Nclob 可变字符类型的数据,不过其存储的是Unicode字符集的字符数据
Blob  可变长度的二进制数据
Bfile  数据库外面存储的可变二进制数据
11. Oracle中使用了索引的列,对该列进行where条件查询、分组、排序、使用聚集函数,哪些用到了索引? 
均会使用索引, 值得注意的是复合索引(如在列A和列B上建立的索引)可能会有不同情况
12. 数据库怎样实现每隔30分钟备份一次? 
通过操作系统的定时任务调用脚本导出数据库
13. Oracle中where条件查询和排序的性能比较? 
Order by使用索引的条件极为严格,只有满足如下情况才可以使用索引,
1). order by中的列必须包含相同的索引并且索引顺序和排序顺序一致
2). 不能有null值的列
所以排序的性能往往并不高,所以建议尽量避免order by
14. 解释冷备份和热备份的不同点以及各自的优点? 
冷备份发生在数据库已经正常关闭的情况下,将关键性文件拷贝到另外位置的一种说法
热备份是在数据库运行的情况下,采用归档方式备份数据的方法
冷备的优缺点:
1).是非常快速的备份方法(只需拷贝文件)
2).容易归档(简单拷贝即可)
3).容易恢复到某个时间点上(只需将文件再拷贝回去)
4).能与归档方法相结合,作数据库“最新状态”的恢复。
5).低度维护,高度安全。
冷备份不足:
1).单独使用时,只能提供到“某一时间点上”的恢复。
2).在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。
3).若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。
4).不能按表或按用户恢复。

热备的优缺点 
1).可在表空间或数据文件级备份,备份时间短。
2).备份时数据库仍可使用。
3).可达到秒级恢复(恢复到某一时间点上)。
4).可对几乎所有数据库实体作恢复。
5).恢复是快速的,在大多数情况下在数据库仍工作时恢复。
热备份的不足是:
  1).不能出错,否则后果严重。
  2).若热备份不成功,所得结果不可用于时间点的恢复。
  3).因难于维护,所以要特别仔细小心,不允许“以失败而告终”。
15. 解释data block , extent 和 segment的区别? 
data block 数据块,是oracle最小的逻辑单位,通常oracle从磁盘读写的就是块
extent 区,是由若干个相邻的block组成
segment段,是有一组区组成
tablespace表空间,数据库中数据逻辑存储的地方,一个tablespace可以包含多个数据文件
16. 比较truncate和delete命令 ? 
1). Truncate 和delete都可以将数据实体删掉,truncate 的操作并不记录到 rollback日志,所以操作速度较快,但同时这个数据不能恢复 
2). Delete操作不腾出表空间的空间
3). Truncate 不能对视图等进行删除
4). Truncate是数据定义语言(DDL),而delete是数据操纵语言(DML)
17. 解释什么是死锁,如何解决Oracle中的死锁? 
简言之就是存在加了锁而没有解锁,可能是使用锁没有提交或者回滚事务,如果是表级锁则不能操作表,客户端处于等在状态,如果是行级锁则不能操作锁定行
解决办法:
1). 查找出被锁的表
select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id;
   
select b.username,b.sid,b.serial#,logon_time
from v$locked_object a,v$session b
where a.session_id = b.sid order by b.logon_time;
2). 杀进程中的会话
alter system kill session "sid,serial#";
18. 简述oracle中 dml、ddl、dcl的使用 
Dml 数据操纵语言,如select、update、delete,insert
Ddl 数据定义语言,如create table 、drop table 等等
Dcl 数据控制语言, 如 commit、 rollback、grant、 invoke等
19. 说说oracle中的经常使用到得函数 
Length 长度、 lower 小写、upper 大写, to_date 转化日期, to_char转化字符
Ltrim 去左边空格、 rtrim去右边空格,substr取字串,add_month增加或者减掉月份、to_number转变为数字
20. 怎样创建一个存储过程, 游标在存储过程怎么使用, 有什么好处? 
附:存储过程的一般格式,游标使用参考问题
1 .使用游标可以执行多个不相关的操作.如果希望当产生了结果集后,对结果集中的数据进行多种不相关的数据操作
2. 使用游标可以提供脚本的可读性
3. 使用游标可以建立命令字符串,使用游标可以传送表名,或者把变量传送到参数中,以便建立可以执行的命令字符串.
但是个人认为游标操作效率不太高,并且使用时要特别小心,使用完后要及时关闭
存储过程优缺点:
优点:
1. 存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
2. 可保证数据的安全性和完整性。
3. 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。
      通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
3. 再运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。 由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。
4. 可以降低网络的通信量, 不需要通过网络来传送很多sql语句到数据库服务器了
5. 使体现企业规则的运算程序放入数据库服务器中,以便集中控制
       当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。企业规则的特点是要经常变化,如果把体现企业规则的运算程序放入应用程序中,则当企业规则发生变化时,就需要修改应用程序工作量非常之大(修改、发行和安装应用程序)。如果把体现企业规则的 运算放入存储过程中,则当企业规则发生变化时,只要修改存储过程就可以了,应用程序无须任何变化。
缺点:
1. 可移植性差
2. 占用服务器端多的资源,对服务器造成很大的压力
3. 可读性和可维护性不好

Create  [or replace]  procedure 过程名字(参数 …)as
vs_ym_sn_end CHAR(6);     --同期终止月份
CURSOR cur_1 IS   --定义游标(简单的说就是一个可以遍历的结果集)
SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,SUM(usd_amt)/10000 usd_amt_sn
FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_sn_beg
  AND ym <= vs_ym_sn_end
GROUP BY area_code,CMCODE;
BEGIN
--用输入参数给变量赋初值,用到了Oralce的SUBSTR TO_CHAR ADD_MONTHS TO_DATE 等很常用的函数。
vs_ym_beg := SUBSTR(is_ym,1,6);
vs_ym_end := SUBSTR(is_ym,7,6);
vs_ym_sn_beg := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,"yyyymm"), -12),"yyyymm");
vs_ym_sn_end := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,"yyyymm"), -12),"yyyymm");
--先删除表中特定条件的数据。
DELETE FROM xxxxxxxxxxx_T WHERE ym = is_ym;
  --然后用内置的DBMS_OUTPUT对象的put_line方法打印出影响的记录行数,其中用到一个系统变量SQL%rowcount
DBMS_OUTPUT.put_line("del上月记录="||SQL%rowcount||"条");

INSERT INTO xxxxxxxxxxx_T(area_code,ym,CMCODE,rmb_amt,usd_amt)
SELECT area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000
FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_beg
  AND ym <= vs_ym_end
GROUP BY area_code,CMCODE;

DBMS_OUTPUT.put_line("ins当月记录="||SQL%rowcount||"条");
--遍历游标处理后更新到表。遍历游标有几种方法,用for语句是其中比较直观的一种。
FOR rec IN cur_1 LOOP
  UPDATE xxxxxxxxxxx_T
  SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn
   WHERE area_code = rec.area_code
   AND CMCODE = rec.CMCODE
   AND ym = is_ym;
END LOOP;
COMMIT;
--错误处理部分。OTHERS表示除了声明外的任意错误。SQLERRM是系统内置变量保存了当前错误的详细信息。
EXCEPTION
   WHEN OTHERS THEN
      vs_msg := "ERROR IN xxxxxxxxxxx_p("||is_ym||"):"||SUBSTR(SQLERRM,1,500);
   ROLLBACK;
   --把当前错误记录进日志表。
   INSERT INTO LOG_INFO(proc_name,error_info,op_date)
   VALUES("xxxxxxxxxxx_p",vs_msg,SYSDATE);
   COMMIT;
   RETURN;
END;
21. 怎样创建一个一个索引,索引使用的原则,有什么优点和缺点 
创建标准索引:
CREATE  INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空间名;
创建唯一索引:
CREATE unique INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空间名;
创建组合索引:
CREATE INDEX 索引名 ON 表名 (列名1,列名2)  TABLESPACE 表空间名;
创建反向键索引:
CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空间名;
索引使用原则:
索引字段建议建立NOT NULL约束
经常与其他表进行连接的表,在连接字段上应该建立索引;
经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引;
可选择性高的关键字 ,应该建立索引;
可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率
复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
A、正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上;
B、复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;否则单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
频繁DML的表,不要建立太多的索引;
不要将那些频繁修改的列作为索引列;
索引的优缺点:
有点:
1. 创建唯一性索引,保证数据库表中每一行数据的唯一性
2. 大大加快数据的检索速度,这也是创建索引的最主要的原因
3. 加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4. 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
缺点:
1. 索引创建在表上,不能创建在视图上
2. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
3. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
4. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度

22. 怎样创建一个视图,视图的好处, 视图可以控制权限吗? 
create view 视图名 as select 列名 [别名]  …  from 表 [unio [all] select … ] ]
好处:
1. 可以简单的将视图理解为sql查询语句,视图最大的好处是不占系统空间
2. 一些安全性很高的系统,不会公布系统的表结构,可能会使用视图将一些敏感信息过虑或者重命名后公布结构
3. 简化查询
可以控制权限的,在使用的时候需要将视图的使用权限grant给用户
23. 怎样创建一个触发器, 触发器的定义, 触发器的游标怎样定义 
CREATE [OR REPLACE] TIGGER触发器名 触发时间 触发事件
 ON表名
 [FOR EACH ROW]
 BEGIN
  pl/sql语句
    CURSOR  游标名 is  SELECT * FROM 表名 (定义游标)
  END
 其中:
 触发器名:触发器对象的名称。
 由于触发器是数据库自动执行的,因此该名称只是一个名称,没有实质的用途。
触发时间:指明触发器何时执行,该值可取:
before---表示在数据库动作之前触发器执行;
after---表示在数据库动作之后出发器执行。
触发事件:指明哪些数据库动作会触发此触发器:                     
   insert:数据库插入会触发此触发器;

24. oracle创建表的几种方式;应该注意些什么 
不知道这个题目是不是记错了,感觉很怪
1. 使用图形工具创建表
2. 使用数据ddl语句创建表
3. 可以在plsql代码中动态创建表
应该注意: 是否有创建表的权限, 使用什么表空间等
25. 怎样将一个旧数据库数据移到一个新的数据库 
1. Imp/exp将数据库中的数据导入到新的库中
2. 如果是存储迁移直接将存储设备挂到新机器上
26. 主键有几种; 
字符型,整数型、复合型
27. oracle的锁又几种,定义分别是什么; 
1.  行共享锁 (ROW SHARE)
2.  行排他锁(ROW EXCLUSIVE)
3 . 共享锁(SHARE)
4.  共享行排他锁(SHARE ROW EXCLUSIVE)
5.  排他锁(EXCLUSIVE)
使用方法:
SELECT * FROM order_master WHERE vencode="V002"
FOR UPDATE WAIT 5;
LOCK TABLE order_master IN SHARE MODE;
LOCK TABLE itemfile IN EXCLUSIVE MODE NOWAIT;
ORACLE锁具体分为以下几类:
1.按用户与系统划分,可以分为自动锁与显示锁
自动锁:当进行一项数据库操作时,缺省情况下,系统自动为此数据库操作获得所有有必要的锁。
显示锁:某些情况下,需要用户显示的锁定数据库操作要用到的数据,才能使数据库操作执行得更好,显示锁是用户为数据库对象设定的。
2 . 按锁级别划分,可分为共享锁与排它锁
共享锁:共享锁使一个事务对特定数据库资源进行共享访问——另一事务也可对此资源进行访问或获得相同共享锁。共享锁为事务提供高并发性,但如拙劣的事务设计+共享锁容易造成死锁或数据更新丢失。
排它锁:事务设置排它锁后,该事务单独获得此资源,另一事务不能在此事务提交之前获得相同对象的共享锁或排它锁。
3.按操作划分,可分为DML锁、DDL锁
DML锁又可以分为,行锁、表锁、死锁
行锁:当事务执行数据库插入、更新、删除操作时,该事务自动获得操作表中操作行的排它锁。
表级锁:当事务获得行锁后,此事务也将自动获得该行的表锁(共享锁),以防止其它事务进行DDL语句影响记录行的更新。事务也可以在进行过程中获得共享锁或排它锁,只有当事务显示使用LOCK TABLE语句显示的定义一个排它锁时,事务才会获得表上的排它锁,也可使用LOCK TABLE显示的定义一个表级的共享锁(LOCK TABLE具体用法请参考相关文档)。
死锁:当两个事务需要一组有冲突的锁,而不能将事务继续下去的话,就出现死锁。
如事务1在表A行记录#3中有一排它锁,并等待事务2在表A中记录#4中排它锁的释放,而事务2在表A记录行#4中有一排它锁,并等待事务; 1在表A中记录#3中排它锁的释放,事务1与事务2彼此等待,因此就造成了死锁。死锁一般是因拙劣的事务设计而产生。死锁只能使用SQL下:alter system kill session "sid,serial#";或者使用相关操作系统kill进程的命令,如UNIX下kill -9 sid,或者使用其它工具杀掉死锁进程。
DDL锁又可以分为:排它DDL锁、共享DDL锁、分析锁
排它DDL锁:创建、修改、删除一个数据库对象的DDL语句获得操作对象的 排它锁。如使用alter table语句时,为了维护数据的完成性、一致性、合法性,该事务获得一排它DDL锁。
共享DDL锁:需在数据库对象之间建立相互依赖关系的DDL语句通常需共享获得DDL锁。
如创建一个包,该包中的过程与函数引用了不同的数据库表,当编译此包时,该事务就获得了引用表的共享DDL锁。
分析锁:ORACLE使用共享池存储分析与优化过的SQL语句及PL/SQL程序,使运行相同语句的应用速度更快。一个在共享池中缓存的对象获得它所引用数据库对象的分析锁。分析锁是一种独特的DDL锁类型,ORACLE使用它追踪共享池对象及它所引用数据库对象之间的依赖关系。当一个事务修改或删除了共享池持有分析锁的数据库对象时,ORACLE使共享池中的对象作废,下次在引用这条SQL/PLSQL语句时,ORACLE重新分析编译此语句。
4.内部闩锁
内部闩锁:这是ORACLE中的一种特殊锁,用于顺序访问内部系统结构。当事务需向缓冲区写入信息时,为了使用此块内存区域,ORACLE首先必须取得这块内存区域的闩锁,才能向此块内存写入信息。

28. 在java种怎样调用oracle存储过程; 
在java中使用 CallableStatement调用存储过程
创建需要的测试表:create table Test(tid varchar2(10),tname varchar2(10));
  第一种情况:无返回值.
      create or replace procedure test_a(param1 in varchar2,param2 in varchar2) as
       begin
            insert into test value(param1,param2);
     end;
Java调用代码:
package com.test;
import java.sql.*;
import java.io.*;
import java.sql.*;
public class TestProcA
{
   public TestProcA(){
   }
   public static void main(String []args)
   {
        ResultSet rs = null;
        Connection conn = null;
        CallableStatement proc = null;
        try{
       Class.forName("oracle.jdbc.driver.OracleDriver");
conn =  DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:test", "test", "test");
          proc = conn.prepareCall("{ call test_a(?,?) }");
          proc.setString(1, "1001");
          proc.setString(2, "TestA");
          proc.execute();
        }catch(Exception e){
     e.printStackTrace();
}finally{
           try{
       if(null!=rs){
                 rs.close();

          if(null!=proc){
                    proc.close();
          }

          if(null!=conn){
                    conn.close();
          }
       }
           }catch(Exception ex){
           }
        }
   }
}

第二种情况:有返回值的存储过程(返回值非列表).
存储过程为:
create or replace procedure test_b(param1 in varchar2,param2 out varchar2)
as
begin
    select tname into param2 from test where tid=param1;
end;

Java调用代码:
package com.test;
import java.sql.*;
import java.io.*;
import java.sql.*;

public class TestProcB
{
   public TestProcB(){
   }
   public static void main(String []args)
   {
        Connection conn = null;
        CallableStatement proc = null;
     
        try{
          Class.forName("oracle.jdbc.driver.OracleDriver");
          conn =  DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:test", "test", "test");
          proc = conn.prepareCall("{ call test_b(?,?) }");
          proc.setString(1, "1001");
          proc.registerOutParameter(2, Types.VARCHAR);
          proc.execute();
          System.out.println("Output is:"+proc.getString(2));
        }catch(Exception e){
     e.printStackTrace();
}finally{
           try{
          if(null!=proc){
                    proc.close();
          }

          if(null!=conn){
                    conn.close();
          }

           }catch(Exception ex){
           }
        }
   }
}

第三种情况:返回列表.

由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了.要分两部分来写:
create or replace package tpackage as
type t_cursor is ref cursor;
procedure test_c(c_ref out t_cursor);
end ;

create or replace package body tpackage as
procedure test_c(c_ref out t_cursor) is
   begin
      open c_ref for select * from test;
  end test_c;
end tpackage;

Java调用代码:
package com.test;
import java.sql.*;
import java.io.*;
import java.sql.*;

public class TestProcB
{
   public TestProcB(){
   }
 
   public static void main(String []args)
   {
        Connection conn = null;
        CallableStatement proc = null;
        ResultSet rs =  null;
        try{
          Class.forName("oracle.jdbc.driver.OracleDriver");
          conn =  DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:test", "test", "test");
          proc = conn.prepareCall("{? = call tpackage.test_b(?) }");
         
          proc.registerOutParameter(1, OracleTypes.CURSOR);
          proc.execute();
          while(rs.next()){
              System.out.println(rs.getObject(1) + "\t" + rs.getObject(2));
          }
        }catch(Exception e){
     e.printStackTrace();
}finally{
           try{
          if(null!=rs){
              rs.close();
             if(null!=proc){
                    proc.close();
             }

             if(null!=conn){
                    conn.close();
             }
          }
          }catch(Exception ex){
           }
        }
   }
}

29. rowid, rownum的定义 
1. rowid和rownum都是虚列
2. rowid是物理地址,用于定位oracle中具体数据的物理存储位置
3. rownum则是sql的输出结果排序,从下面的例子可以看出其中的区别。
30. oracle中存储过程,游标和函数的区别 
游标类似指针,游标可以执行多个不相关的操作.如果希望当产生了结果集后,对结果集中的数据进行多 种不相关的数据操作
函数可以理解函数是存储过程的一种; 函数可以没有参数,但是一定需要一个返回值,存储过程可以没有参数,不需要返回值;两者都可以通过out参数返回值, 如果需要返回多个参数则建议使用存储过程;在sql数据操纵语句中只能调用函数而不能调用存储过程
31. 使用oracle 伪列删除表中重复记录: 
Delete  table t  where t.rowid!=(select  max(t1.rowid)  from  table1 t1 where  t1.name=t.name)

Oracle面试题(基础篇)

Oracle面试题(基础篇)


1. Oracle跟SQL Server 2005的区别?
宏观上:
1). 最大的区别在于平台,oracle可以运行在不同的平台上,sql server只能运行在windows平台上,由于windows平台的稳定性和安全性影响了sql server的稳定性和安全性
2). oracle使用的脚本语言为PL-SQL,而sql server使用的脚本为T-SQL
微观上: 从数据类型,数据库的结构等等回答

2. 如何使用Oracle的游标?
1).  oracle中的游标分为显示游标和隐式游标
2).  显示游标是用cursor...is命令定义的游标,它可以对查询语句(select)返回的多条记录进行处理;隐式游标是在执行插入 (insert)、删除(delete)、修改(update)和返回单条记录的查询(select)语句时由PL/SQL自动定义的。
3). 显式游标的操作:打开游标、操作游标、关闭游标;PL/SQL隐式地打开SQL游标,并在它内部处理SQL语句,然后关闭它

3. Oracle中function和procedure的区别?
1). 可以理解函数是存储过程的一种
2). 函数可以没有参数,但是一定需要一个返回值,存储过程可以没有参数,不需要返回值
3). 函数return返回值没有返回参数模式,存储过程通过out参数返回值, 如果需要返回多个参数则建议使用存储过程
4). 在sql数据操纵语句中只能调用函数而不能调用存储过程

4. Oracle的导入导出有几种方式,有何区别?
1). 使用oracle工具 exp/imp
2). 使用plsql相关工具
方法1. 导入/导出的是二进制的数据, 2.plsql导入/导出的是sql语句的文本文件
5. Oracle中有哪几种文件?
数据文件(一般后缀为.dbf或者.ora),日志文件(后缀名.log),控制文件(后缀名为.ctl)

6. 怎样优化Oracle数据库,有几种方式?
个人理解,数据库性能最关键的因素在于IO,因为操作内存是快速的,但是读写磁盘是速度很慢的,优化数据库最关键的问题在于减少磁盘的IO,就个人理解应该分为物理的和逻辑的优化, 物理的是指oracle产品本身的一些优化,逻辑优化是指应用程序级别的优化
物理优化的一些原则:
1). Oracle的运行环境(网络,硬件等)
2). 使用合适的优化器
3). 合理配置oracle实例参数
4). 建立合适的索引(减少IO)
5). 将索引数据和表数据分开在不同的表空间上(降低IO冲突)
6). 建立表分区,将数据分别存储在不同的分区上(以空间换取时间,减少IO)
   逻辑上优化:
1). 可以对表进行逻辑分割,如中国移动用户表,可以根据手机尾数分成10个表,这样对性能会有一定的作用
2). Sql语句使用占位符语句,并且开发时候必须按照规定编写sql语句(如全部大写,全部小写等)oracle解析语句后会放置到共享池中
如: select * from Emp where name=?  这个语句只会在共享池中有一条,而如果是字符串的话,那就根据不同名字存在不同的语句,所以占位符效率较好
3). 数据库不仅仅是一个存储数据的地方,同样是一个编程的地方,一些耗时的操作,可以通过存储过程等在用户较少的情况下执行,从而错开系统使用的高峰时间,提高数据库性能
4). 尽量不使用*号,如select * from Emp,因为要转化为具体的列名是要查数据字典,比较耗时
5). 选择有效的表名
对于多表连接查询,可能oracle的优化器并不会优化到这个程度, oracle 中多表查询是根据FROM字句从右到左的数据进行的,那么最好右边的表(也就是基础表)选择数据较少的表,这样排序更快速,如果有link表(多对多中间表),那么将link表放最右边作为基础表,在默认情况下oracle会自动优化,但是如果配置了优化器的情况下,可能不会自动优化,所以平时最好能按照这个方式编写sql
6). Where字句 规则
Oracle 中Where字句时从右往左处理的,表之间的连接写在其他条件之前,能过滤掉非常多的数据的条件,放在where的末尾, 另外!=符号比较的列将不使用索引,列经过了计算(如变大写等)不会使用索引(需要建立起函数), is null、is not null等优化器不会使用索引
7). 使用Exits Not Exits 替代 In  Not in
8). 合理使用事务,合理设置事务隔离性
数据库的数据操作比较消耗数据库资源的,尽量使用批量处理,以降低事务操作次数

7. Oracle中字符串用什么符号链接?
Oracle中使用 || 这个符号连接字符串 如 ‘abc’ || ‘d’
8. Oracle分区是怎样优化数据库的?
Oracle的分区可以分为:列表分区、范围分区、散列分区、复合分区。
1).  增强可用性:如果表的一个分区由于系统故障而不能使用,表的其余好的分区仍可以使用;
2).  减少关闭时间:如果系统故障只影响表的一部份分区,那么只有这部份分区需要修复,可能比整个大表修复花的时间更少;
3).  维护轻松:如果需要得建表,独产管理每个公区比管理单个大表要轻松得多;
4).  均衡I/O:可以把表的不同分区分配到不同的磁盘来平衡I/O改善性能;
5).  改善性能:对大表的查询、增加、修改等操作可以分解到表的不同分区来并行执行,可使运行速度更快
6).  分区对用户透明,最终用户感觉不到分区的存在。

9. Oracle是怎样分页的?
Oracle中使用rownum来进行分页, 这个是效率最好的分页方法,hibernate也是使用rownum来进行oralce分页的
select * from
  ( select rownum r,a from tabName where rownum <= 20 )
where r > 10
10. Oralce怎样存储文件,能够存储哪些文件?
Oracle 能存储 clob、nclob、 blob、 bfile
Clob  可变长度的字符型数据,也就是其他数据库中提到的文本型数据类型
Nclob 可变字符类型的数据,不过其存储的是Unicode字符集的字符数据
Blob  可变长度的二进制数据
Bfile  数据库外面存储的可变二进制数据
11. Oracle中使用了索引的列,对该列进行where条件查询、分组、排序、使用聚集函数,哪些用到了索引?
均会使用索引, 值得注意的是复合索引(如在列A和列B上建立的索引)可能会有不同情况
12. 数据库怎样实现每隔30分钟备份一次?
通过操作系统的定时任务调用脚本导出数据库

13. Oracle中where条件查询和排序的性能比较?
Order by使用索引的条件极为严格,只有满足如下情况才可以使用索引,
1). order by中的列必须包含相同的索引并且索引顺序和排序顺序一致
2). 不能有null值的列
所以排序的性能往往并不高,所以建议尽量避免order by

14. 解释冷备份和热备份的不同点以及各自的优点?
冷备份发生在数据库已经正常关闭的情况下,将关键性文件拷贝到另外位置的一种说法
热备份是在数据库运行的情况下,采用归档方式备份数据的方法
冷备的优缺点:
1).是非常快速的备份方法(只需拷贝文件) 
2).容易归档(简单拷贝即可) 
3).容易恢复到某个时间点上(只需将文件再拷贝回去) 
4).能与归档方法相结合,作数据库“最新状态”的恢复。 
5).低度维护,高度安全。 
冷备份不足: 
1).单独使用时,只能提供到“某一时间点上”的恢复。 
2).在实施备份的全过程中,数据库必须要作备份而不能作其它工作。也就是说,在冷备份过程中,数据库必须是关闭状态。 
3).若磁盘空间有限,只能拷贝到磁带等其它外部存储设备上,速度会很慢。 
4).不能按表或按用户恢复。 

热备的优缺点
1).可在表空间或数据文件级备份,备份时间短。 
2).备份时数据库仍可使用。 
3).可达到秒级恢复(恢复到某一时间点上)。 
4).可对几乎所有数据库实体作恢复。 
5).恢复是快速的,在大多数情况下在数据库仍工作时恢复。 
热备份的不足是: 
  1).不能出错,否则后果严重。 
  2).若热备份不成功,所得结果不可用于时间点的恢复。 
  3).因难于维护,所以要特别仔细小心,不允许“以失败而告终”。

15. 解释data block , extent 和 segment的区别?
data block 数据块,是oracle最小的逻辑单位,通常oracle从磁盘读写的就是块
extent 区,是由若干个相邻的block组成
segment段,是有一组区组成
tablespace表空间,数据库中数据逻辑存储的地方,一个tablespace可以包含多个数据文件
16. 比较truncate和delete命令 ?
1). Truncate 和delete都可以将数据实体删掉,truncate 的操作并不记录到 rollback日志,所以操作速度较快,但同时这个数据不能恢复
2). Delete操作不腾出表空间的空间
3). Truncate 不能对视图等进行删除
4). Truncate是数据定义语言(DDL),而delete是数据操纵语言(DML)
17. 解释什么是死锁,如何解决Oracle中的死锁?
简言之就是存在加了锁而没有解锁,可能是使用锁没有提交或者回滚事务,如果是表级锁则不能操作表,客户端处于等在状态,如果是行级锁则不能操作锁定行
解决办法:
1). 查找出被锁的表
select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id;
    
select b.username,b.sid,b.serial#,logon_time
from v$locked_object a,v$session b
where a.session_id = b.sid order by b.logon_time;
2). 杀进程中的会话
alter system kill session "sid,serial#";
18. 简述oracle中 dml、ddl、dcl的使用
Dml 数据操纵语言,如select、update、delete,insert
Ddl 数据定义语言,如create table 、drop table 等等
Dcl 数据控制语言, 如 commit、 rollback、grant、 invoke等
19. 说说oracle中的经常使用到得函数
Length 长度、 lower 小写、upper 大写, to_date 转化日期, to_char转化字符
Ltrim 去左边空格、 rtrim去右边空格,substr取字串,add_month增加或者减掉月份、to_number转变为数字
20. 怎样创建一个存储过程, 游标在存储过程怎么使用, 有什么好处?
附:存储过程的一般格式,游标使用参考问题
1 .使用游标可以执行多个不相关的操作.如果希望当产生了结果集后,对结果集中的数据进行多种不相关的数据操作
2. 使用游标可以提供脚本的可读性
3. 使用游标可以建立命令字符串,使用游标可以传送表名,或者把变量传送到参数中,以便建立可以执行的命令字符串.
但是个人认为游标操作效率不太高,并且使用时要特别小心,使用完后要及时关闭
存储过程优缺点:
优点:
1. 存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
2. 可保证数据的安全性和完整性。
3. 通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。
      通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
3. 再运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。这种已经编译好的过程可极大地改善SQL语句的性能。 由于执行SQL语句的大部分工作已经完成,所以存储过程能以极快的速度执行。
4. 可以降低网络的通信量, 不需要通过网络来传送很多sql语句到数据库服务器了
5. 使体现企业规则的运算程序放入数据库服务器中,以便集中控制
       当企业规则发生变化时在服务器中改变存储过程即可,无须修改任何应用程序。企业规则的特点是要经常变化,如果把体现企业规则的运算程序放入应用程序中,则当企业规则发生变化时,就需要修改应用程序工作量非常之大(修改、发行和安装应用程序)。如果把体现企业规则的 运算放入存储过程中,则当企业规则发生变化时,只要修改存储过程就可以了,应用程序无须任何变化。
缺点:
1. 可移植性差
2. 占用服务器端多的资源,对服务器造成很大的压力
3. 可读性和可维护性不好

Create  [or replace]  procedure 过程名字(参数 …)as
vs_ym_sn_end CHAR(6);     --同期终止月份
CURSOR cur_1 IS   --定义游标(简单的说就是一个可以遍历的结果集)
SELECT area_code,CMCODE,SUM(rmb_amt)/10000 rmb_amt_sn,SUM(usd_amt)/10000 usd_amt_sn
FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_sn_beg
  AND ym <= vs_ym_sn_end
GROUP BY area_code,CMCODE;
BEGIN
--用输入参数给变量赋初值,用到了Oralce的SUBSTR TO_CHAR ADD_MONTHS TO_DATE 等很常用的函数。
vs_ym_beg := SUBSTR(is_ym,1,6);
vs_ym_end := SUBSTR(is_ym,7,6);
vs_ym_sn_beg := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_beg,"yyyymm"), -12),"yyyymm");
vs_ym_sn_end := TO_CHAR(ADD_MONTHS(TO_DATE(vs_ym_end,"yyyymm"), -12),"yyyymm");
--先删除表中特定条件的数据。
DELETE FROM xxxxxxxxxxx_T WHERE ym = is_ym;
  --然后用内置的DBMS_OUTPUT对象的put_line方法打印出影响的记录行数,其中用到一个系统变量SQL%rowcount
DBMS_OUTPUT.put_line("del上月记录="||SQL%rowcount||"条");

INSERT INTO xxxxxxxxxxx_T(area_code,ym,CMCODE,rmb_amt,usd_amt)
SELECT area_code,is_ym,CMCODE,SUM(rmb_amt)/10000,SUM(usd_amt)/10000
FROM BGD_AREA_CM_M_BASE_T
  WHERE ym >= vs_ym_beg
  AND ym <= vs_ym_end
GROUP BY area_code,CMCODE;

DBMS_OUTPUT.put_line("ins当月记录="||SQL%rowcount||"条");
--遍历游标处理后更新到表。遍历游标有几种方法,用for语句是其中比较直观的一种。
FOR rec IN cur_1 LOOP
  UPDATE xxxxxxxxxxx_T
  SET rmb_amt_sn = rec.rmb_amt_sn,usd_amt_sn = rec.usd_amt_sn
   WHERE area_code = rec.area_code
   AND CMCODE = rec.CMCODE
   AND ym = is_ym;
END LOOP;
COMMIT;
--错误处理部分。OTHERS表示除了声明外的任意错误。SQLERRM是系统内置变量保存了当前错误的详细信息。
EXCEPTION
   WHEN OTHERS THEN
      vs_msg := "ERROR IN xxxxxxxxxxx_p("||is_ym||"):"||SUBSTR(SQLERRM,1,500);
   ROLLBACK;
   --把当前错误记录进日志表。
   INSERT INTO LOG_INFO(proc_name,error_info,op_date)
   VALUES("xxxxxxxxxxx_p",vs_msg,SYSDATE);
   COMMIT;
   RETURN;
END;
21. 怎样创建一个一个索引,索引使用的原则,有什么优点和缺点
创建标准索引:
CREATE  INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空间名;
创建唯一索引:
CREATE unique INDEX 索引名 ON 表名 (列名)  TABLESPACE 表空间名;
创建组合索引:
CREATE INDEX 索引名 ON 表名 (列名1,列名2)  TABLESPACE 表空间名;
创建反向键索引:
CREATE INDEX 索引名 ON 表名 (列名) reverse TABLESPACE 表空间名;
索引使用原则:
索引字段建议建立NOT NULL约束
经常与其他表进行连接的表,在连接字段上应该建立索引;
经常出现在Where子句中的字段且过滤性很强的,特别是大表的字段,应该建立索引;
可选择性高的关键字 ,应该建立索引;
可选择性低的关键字,但数据的值分布差异很大时,选择性数据比较少时仍然可以利用索引提高效率
复合索引的建立需要进行仔细分析;尽量考虑用单字段索引代替:
A、正确选择复合索引中的第一个字段,一般是选择性较好的且在where子句中常用的字段上;
B、复合索引的几个字段经常同时以AND方式出现在Where子句中可以建立复合索引;否则单字段索引;
C、如果复合索引中包含的字段经常单独出现在Where子句中,则分解为多个单字段索引;
D、如果复合索引所包含的字段超过3个,那么仔细考虑其必要性,考虑减少复合的字段;
E、如果既有单字段索引,又有这几个字段上的复合索引,一般可以删除复合索引;
频繁DML的表,不要建立太多的索引;
不要将那些频繁修改的列作为索引列;
索引的优缺点:
有点:
1. 创建唯一性索引,保证数据库表中每一行数据的唯一性
2. 大大加快数据的检索速度,这也是创建索引的最主要的原因
3. 加速表和表之间的连接,特别是在实现数据的参考完整性方面特别有意义。
4. 在使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间。
缺点:
1. 索引创建在表上,不能创建在视图上
2. 创建索引和维护索引要耗费时间,这种时间随着数据量的增加而增加
3. 索引需要占物理空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果要建立聚簇索引,那么需要的空间就会更大
4. 当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,降低了数据的维护速度

22. 怎样创建一个视图,视图的好处, 视图可以控制权限吗?
create view 视图名 as select 列名 [别名]  …  from 表 [unio [all] select … ] ]
好处:
1. 可以简单的将视图理解为sql查询语句,视图最大的好处是不占系统空间
2. 一些安全性很高的系统,不会公布系统的表结构,可能会使用视图将一些敏感信息过虑或者重命名后公布结构
3. 简化查询
可以控制权限的,在使用的时候需要将视图的使用权限grant给用户
23. 怎样创建一个触发器, 触发器的定义, 触发器的游标怎样定义
CREATE [OR REPLACE] TIGGER触发器名 触发时间 触发事件
 ON表名
 [FOR EACH ROW]
 BEGIN
  pl/sql语句
    CURSOR  游标名 is  SELECT * FROM 表名 (定义游标)
  END
 其中:
---------------------

  DAILY CHECKLIST Oracle Database instance is running or not select name,open_mode from V$database; Note: Check the Oracle databases are ru...