(list open files) 是一个列出当前系统打开文件的工具!
原理:
在linux环境下,任何事物都以文件的形式存在,系统在后台都为应用程序分配了一个对应的文件描述符,该文件描述符为应用程序与基础操作系统之间的交互提供了通用接口。因此通过lsof工具能够查看应用程序打开文件的描述符列表,以便查看应用程序的信息!
用法以及含义:
losf 的语法:
lsof [options] filename
如果不使用参数的话,默认显示所有进程打开的所有文件。
[root@rac3 ~]# lsof | more
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
init 1 root cwd DIR 8,3 4096 2 /
init 1 root rtd DIR 8,3 4096 2 /
init 1 root txt REG 8,3 43496 2450664 /sbin/init
init 1 root mem REG 8,3 95464 1764613 /lib64/libselinux.so.1
init 1 root 10u FIFO 0,17 1204 /dev/initctl
migration 2 root cwd DIR 8,3 4096 2 /
migration 2 root rtd DIR 8,3 4096 2 /
migration 2 root txt unknown /proc/2/exe
rpc.statd 2567 root 0u CHR 1,3 1432 /dev/null
sdpd 2643 root 2u CHR 1,3 1432 /dev/null
oracle 10970 oracle 17u IPv6 21324 UDP rac3:30005
sdpd 2643 root 4u sock 0,5 7350 can t identify protocol
sdpd 2643 root 5u unix 0xffff81012e52e380 7358 /var/run/sdp
rpc.statd 2567 root 4w FIFO 0,6 7128 pipe
rpc.statd 2567 root 5u unix 0xffff81013f84cb80 7131 socket
rpc.statd 2567 root 7u IPv4 7218 TCP *:3com-amp3 (LISTEN)
lsof输出各列信息的意义如下:
COMMAND:进程的名称!
PID: 进程标识符!
USER: 进程所有者!
FD: 文件描述符,应用程序通过文件描述符识别该文件。如cwd、txt等!
TYPE: 文件类型,如DIR、REG,MEM等!
DEVICE: 指定磁盘的名称!
SIZE: 文件的大小!
NODE: 索引节点(文件在磁盘上的标识)!
NAME: 打开的文件名称 !
FD 列中的文件描述符意义:
cwd 表示应用程序的当前工作目录,也是该应用程序启动的目录,除非它本身对这个目录进行更改。
txt 表示该类型的文件是程序代码,如应用程序二进制文件本身或共享库,如上列表中显示的/sbin/init程序。
数值 表示应用程序的文件描述符,打开该文件时返回的整数。如上的最后一行文件/dev/initctl,其文件描述符为 10;/dev/null的描述符为2!
u 表示该文件被打开并处于读取/写入模式,而不是只读(r)或只写(w)模式。大写的W表示该应用程序具有对整个文件的写锁。该文件描述符用于确保每次只能打开一个应用程序实例!
初始打开每个应用程序时,都具有三个文件描述符,从0到2,分别表示标准输入、输出和错误流。所以大多数应用程序所打开的文件的FD都是从3开始。
Type 列中的文件描述符意义:
REG 表示文件
DIR 表示目录
CHR 表示字符设备
BLK 表示和块设备
UNIX 表示UNIX 域套接字
FIFO 表示先进先出(FIFO)队列
IPv4 表示网际协议(IP)套接字。
了解了lsof的原理,那losf到底有什么用呢?下面介绍losf的用处
1 查看端口的使用 比如1521,查看有多少机器建立了与当前机器oracle数据库的连接!
oracle@rac3:/home/oracle>lsof -i :1521 | more
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
oracle 329 oracle 13u IPv4 6167257 TCP dba-host1.hz.ali.com:1521->10.250.3.44:44782 (ESTABLISHED)
oracle 331 oracle 15u IPv4 6167274 TCP dba-host1.hz.ali.com:1521->10.250.3.56:45332 (ESTABLISHED)
oracle 515 oracle 15u IPv4 6167700 TCP dba-host1.hz.ali.com:1521->10.250.3.47:43180 (ESTABLISHED)
oracle 1436 oracle 15u IPv4 6169854 TCP dba-host1.hz.ali.com:1521->10.249.196.131:39527 (ESTABLISHED)
oracle 1468 oracle 15u IPv4 6169968 TCP dba-host1.hz.ali.com:1521->10.250.3.34:52021 (ESTABLISHED)
oracle 1470 oracle 15u IPv4 6169977 TCP dba-host1.hz.ali.com:1521->10.250.3.34:52022 (ESTABLISHED)
查看mysql的3306 rac3-->rac4 是一个主从架构
[root@rac3 ~]# lsof -i :3306
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
mysqld 3181 mysql 12u IPv6 8063 TCP *:mysql (LISTEN)
mysqld 3181 mysql 39u IPv6 8070 TCP rac3:mysql->rac4:36554 (ESTABLISHED)
2 查看某个用户打开的类型mem的文件:
[root@rac3 ~]# lsof -a -u oracle -d mem | more
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
bash 9625 oracle mem REG 8,3 139416 1764595 /lib64/ld-2.5.so
bash 9625 oracle mem REG 8,3 1713160 1764596 /lib64/libc-2.5.so
bash 9625 oracle mem REG 8,3 23360 1764602 /lib64/libdl-2.5.so
bash 9625 oracle mem REG 8,3 15584 1764624 /lib64/libtermcap.so.2.0.8
bash 9625 oracle mem REG 8,3 53880 1764315 /lib64/libnss_files-2.5.so
bash 9625 oracle mem REG 8,3 56462864 4447583 /usr/lib/locale/locale-archive
bash 9625 oracle mem REG 8,3 25464 4541667 /usr/lib64/gconv/gconv-modules.cache
oracle 10970 oracle mem REG 0,20 16777216 21166 /dev/shm/ora_yangdb_98305_0
oracle 10970 oracle mem REG 0,20 0 21167 /dev/shm/ora_yangdb_98305_1
oracle 10970 oracle mem REG 0,20 0 21168 /dev/shm/ora_yangdb_98305_2
oracle 10970 oracle mem REG 0,20 0 21169 /dev/shm/ora_yangdb_98305_3
...省略...
3 查看那些程序在使用某个文件:
[root@rac3 ~]# lsof /opt/mysql/data/
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
mysqld 3181 mysql cwd DIR 8,3 4096 2842467 /opt/mysql/data/
4 恢复误删除的文件:
os 原理:
当进程打开了某个文件时,只要该进程保持打开该文件,即使将其删除,它依然存在于磁盘中。这意味着,进程并不知道文件已经被删除,它仍然可以向打开该文件时提供给它的文件描述符进行读取和写入。除了该进程之外,这个文件是不可见的,因为已经删除了其相应的目录索引节点。
在/proc 目录下,其中包含了反映内核和进程树的各种文件。/proc目录挂载的是在内存中所映射的一块区域,所以这些文件和目录并不存在于磁盘中,因此当我们对这些文件进行读取和写入时,实际上是在从内存中获取相关信息。
大多数与lsof相关的信息都存储于以进程的PID命名的目录中,即/proc/123中包含的是 PID为123的进程的信息。
这里引用一个kamus的文章《Linux/Unix恢复误删除的文件恢复》,此文比较详细的介绍了具体的恢复步骤,同时也告诉我们对于数据库的操作一定要谨慎小心!