文件系统的组成
Linux 文件系统会为每个文件分配两个数据结构:索引节点(index node) 和 目录项(directory entry),它们主要用来记录文件的元信息和目录层次结构。
-
索引节点,也就是
inode
,用来记录文件的元信息,比如 inode 编号、文件大小、访问权限、创建时间、修改时间、数据在磁盘的位置等等。索引节点是文件的唯一标识,它们之间一一对应,也同样都会被存储在硬盘中,所以索引节点同样占用磁盘空间。 -
目录项,也就是
dentry
,用来记录文件的名字、索引节点指针以及与其他目录项的层级关联关系。多个目录项关联起来,就会形成目录结构,但它与索引节点不同的是,目录项是由内核维护的一个数据结构,不存放于磁盘,而是缓存在内存。 由于索引节点唯一标识一个文件,而目录项记录着文件的名,所以目录项和索引节点的关系是多对一,也就是说,一个文件可以有多个别字。比如,硬链接的实现就是多个目录项中的索引节点指向同一个文件。
注意,目录也是文件,也是用索引节点唯一标识,和普通文件不同的是,普通文件在磁盘里面保存的是文件数据,而目录文件在磁盘里面保存子目录或文件。
目录项和目录是一个东西吗? 虽然名字很相近,但是它们不是一个东西,目录是个文件,持久化存储在磁盘,而目录项是内核一个数据结构,缓存在内存。 如果查询目录频繁从磁盘读,效率会很低,所以内核会把已经读过的目录用目录项这个数据结构缓存在内存,下次再次读到相同的目录时,只需从内存读就可以,大大提高了文件系统的效率。 注意,目录项这个数据结构不只是表示目录,也是可以表示文件的。 那文件数据是如何存储在磁盘的呢? 磁盘读写的最小单位是扇区,扇区的大小只有 512B 大小,很明显,如果每次读写都以这么小为单位,那这读写的效率会非常低。 所以,文件系统把多个扇区组成了一个逻辑块,每次读写的最小单位就是逻辑块(数据块),Linux 中的逻辑块大小为 4KB,也就是一次性读写 8 个扇区,这将大大提高了磁盘的读写的效率。
-
扇区: 文件是存储在硬盘上的,硬盘的最小存储单位叫做“扇区”(sector),每个扇区存储512字节。
-
block(块):一般连续八个扇区组成一个"块"(block),一个块是4K大小,是文件存取的最小单位。
-
inode(索引节点): 元信息(包含除了文件名以外的文件属性,比如文件的创建者、创建日期、文件大小、文件权限等)
inode 和block之间的关系
inode 编号
每一个 inode 都有一个编号,系统根据 inode 编号可以快速的计算出 inode 信息在磁盘 inodes 存储区的偏移,然后从中获取 inode 信息,再根据 inode信息中记录的 Block 块位置,从Block存储区读出文件内容
inode 编号在一个文件系统中是唯一的,多个文件系统之间可能会出现相同的编号,前面的磁盘存储结构示意图中 /dev/vda1
和 /dev/vda2
在各自的文件系统中 inode 编号是唯一的
创建一个新文件的时候,文件名和对应的 inode 编号会存储在目录文件的Block块中(关于目录文件后面会讲到)
文件的 inode 信息中记录了文件 Block 块的位置,Block块中存储着文件的内容,可以使用 ls -i
命令查看文件的 inode 编号
从例子中可以看出,每个 inode 节点大小为 256 字节。通过 df -i
命令可以查看每个文件系统中 inode 的使用情况
df -i Filesystem Inodes IUsed IFree IUse% Mounted on devtmpfs 482393 339 482054 1% /dev tmpfs 484984 1 484983 1% /dev/shm tmpfs 484984 433 484551 1% /run tmpfs 484984 16 484968 1% /sys/fs/cgroup /dev/vda1 2621440 157202 2464238 6% / tmpfs 484984 1 484983 1% /run/user/0
字段解释:
Filesystem:文件系统
Inodes: 文件系统中 inodes 总数量
IUsed: inodes 已经使用了的数量
IFree: inodes 可供使用的数量
IUse%: 已经使用了的 inodes 百分比
Mounted on: 文件系统的挂载点
文件系统中的 inodes 数量在安装系统或格式化磁盘分区的时候已经分配好了,也就是说 inodes 数量是有限的,所以 inodes 数量有可能耗尽的,耗尽之后就会出现磁盘还有空间,但是无法创建新文件的情况
目录文件
Linux 中所有的一切都是文件,包括进程、线程、目录等。每个文件都有对应的 inode 编号
当打开目录时,实际上是打开一个目录文件,目录的存储结构是目录子项列表,每个目录子项由 文件名、文件名对应的 inode 编号 组成
stat 显示文件 时间调整信息 atime(access time):最近访问 最后一次访问文件的时间 mtime(modify):最近更改 最后一次更改文件内容的时间 ctime(change time):最近改动 最后一次改变文件元信息的时间
执行文件命令对inode号的影响具体取决于所执行的命令类型。
对于cp
(复制)命令,当复制一个文件时,系统会分配一个新的inode号码,并且在inode表中创建相应的条目,然后才会将文件内容复制到新文件中。这意味着新文件会有一个新的inode号码。
对于mv
(移动/重命名)命令,如果源文件和目标文件在同一文件系统内,mv操作实际上不会改变inode号码,它只是创建了一个新的目录项,并更新了文件名到inode号码的映射,同时删除了旧的目录项。如果源文件和目标文件不在同一文件系统内,那么mv操作相当于先复制后删除,这会导致新的inode号码的分配。
至于rm
(删除)命令,它会减少文件的链接数,如果链接数变为0,则会释放该inode号码,使得这个inode号码可以被重新使用。同时,数据块会被放到可用空间列表中,并删除目录中的目录项。
-
cp 命令:分配一个空闲的inode号,在inode表中生成新条目在目录中创建一个目录项,将名称与inode编号关联拷贝数据生成新的文件
-
rm 命令:硬链接数递减,从而释放的inode号可以被重用,块放在空闲列表中,删除目录项数据实际上不会马上被删除,但当另一个文件使用数据块时将被覆盖。
-
mv命令:如果mv命令的目标和源在同一设备,不影响inode表(除时间戳)或磁盘上的数据位置;系统会删除旧的目录对应关系,新建目录对应关系。
-
vim编辑器 :
vim编辑器改变文件内容,是先创建一个新的swp文件,编辑的内容也是在swp文件中进行,当用户保存时,swp文件就会替换当前文件,因此inode号会发生改变
-
利用echo命令往文件中加内容 :
对原文件进行操作,只改变原文件的内容,其他没有任何影响,inode号不发生改变
linux系统下各种日志文件的介绍
日志文件的作用
日志文件用于记录linux系统的各种运行信息的文件,相当于linux主机的日记,不同的日志文件记载了不同类型的信息,如Linux内核消息、用户登录事件、程序错误等。日志文件对于诊断和解决问题很有帮助,因为linux运行的程序通常把系统的消息和错误写入对应的日志文件,这样系统可以有据可查, 此外,当主机遭受攻击时,日志文件还可以帮助寻找攻击者留下的痕迹。
日志文件的分类
1.内核及系统日志: 内核及系统日志:这种日志数据由系统服务rsyslog同-管理,根据其主配置文件/etc/rsyslog.conf中的设置决定将内核消息及各种系统程序消息记录到什么位置。系统中大部分的程序会把自己的日志文件交由rsyslog管理,因而这些应用程序使用的日志记录格式都很相似。
2.用户日志: 用于记录Linux系统用户登录及退出系统的相关信息,包括用户名、登录的终端、登录时间、来源主机、正在使用的进程操作等。
3.程序旧志 :有些应用程序会选择独立管理一份日志文件 ,而不是交给rsyslog服务管理,用于记录本程序运行过程中的各种事件信息。于这些程序只负责管理自己的日志文件,因此不同程序所使用的日志记录格式也会存在较大的差异。
/var/log/inessages | 记录Linux内核消息及各种应用程序的公共日志信息,包括启动、I/O错误、网络错误、程序故障等。对于未使用独立日志文件的应用程序或服务,一般都可以从该日志文件中获得相关的事件记录信息 |
---|---|
/var/log/cron | 记录crondi计划任务产生的事件信息 |
/var/log/dmesg | 记录Linux系统在引导过程中的各种事件信息 |
/var/log/maillog | 记录进入或发出系统的电子邮件活动 |
/var/log/lastlog | 记录每个用户最近的登录事件 |
/var/log/secure | 记录用户认证相关的安全事件信息 |
/var/log/wtmp | 记录每个用户登录、注销及系统启动和停机事件 |
/var/log/btmp | 记录失败的、错误的登录尝试及验证事件 |
日志消息等级
在Linux内核中,根据日志消息的重要程度不同,将其分为不同的优先级别(数字等级越小,优先级越高,消息越重要)
等级 | 等级信息 | 效果 |
---|---|---|
0 | EMERG (紧急) | 会导致主机系统不可用的情况 |
1 | ALERT (警告) | 必须马上采取措施解决的问题 |
2 | CRIT (严重) | 比较严重的情况 |
3 | ERR(错误) | 运行出现错误 |
4 | WARNING (提醒) | 可能影响系统功能 ,需要提醒用户的重要事件 |
5 | NOTICE (注意) | 不会影响正常功能,但是需要注意的事件 |
6 | INFO(信息) | 一般信息 |
7 | DEBUG (调试) | 程序或系统调试信息等 |
内核及大多数系统消息都被记录到公共日志文件/var/loq/messaqes中,而其他一些程序消息被记 录到各自独立的日志文件中 对于rsyslog服务统管理的大部分日志文件,使用的日志记录格式基本上都是相同的。以公共日志/var/loq/messaqes文件的记录格式为例,其中每一行表示一条日志消息,每一条消息均包括以下
四个字段: 时间标签:消息发出的日期和时间 主机名:生成消息的计算机的名称 子系统名称:发出消息的应用程序的名称 消息:消息的具体内容
日志主要配置文件
内核及系统日志由系统服务 rsyslog 统一管理,主配置文件为/etc/rsyslog.conf
服务名称
-
auth (LOG_AUTH) :安全和认证相关消息,不推荐使用authpriv替代;
-
authpriv (LOG_AUTHPRIV) :安全和认证相关消息,私有;
-
cron (LOG_CRON) :系统定时任务cront与at产生的相关日志;
-
daemon (LOG_DAEMON) :各个守护进程产生的日志;
-
ftp (LOG_FTP) :ftp守护进程产生的日志;
-
kern (LOG_KERN) :内核产生的日志;
-
local0-local7 (LOG_LOCAL0-7) :为本地使用预留的服务;
-
lpr (LOG_LPR) :打印产生的日志;
-
mail (LOG_MAIL) :邮件收发日志;
-
news (LOG_NEWS) :与新闻服务器相关的日志;
-
syslog (LOG_SYSLOG) :有syslog服务产生的日志;
-
user (LOG_USER) :用户等级类别的日志;
-
uucp (LOG_UUCP) :uucp子系统的日志信息; …
连接符号
-
" . " :只要比后面的等级高的(包含该等级)日志都记录下来;
-
" .= " :只记录所需等级的日志,其他等级不记录;
-
" .! " :除了该等级的日志外其他等级全部记录;
“*”代表所有日志等级,比如:“authpriv.*”代表authpriv认证信息服务产生的日志,所有的日志等级 都记录 “.”代表只要比后面的等级高的(包含该等级)日志都记录下来。比如:“cron.info”代表cron服务产生的 日志,只要日 志等级大于等于info级别,就记录 “.=”代表只记录所需等级的日志,其他等级的都不记录。比如:“*.=emerg”代表人和日志服务产生的日志,只要等级是 emerg等级就记录。这种用法及少见,了解就好 “.!”代表不等于,也就是除了该等级的日志外,其他等级的 日志都记录。
日志轮替
日志轮替的作用就是把旧的日志文件移动并改名,同时建立新的空日志文件,当旧日志文件超过保存的范围之后,就会进行删除,若配置文件中有 dateext 参数,则日志文件名称不会重叠,此参数不需要日志文件改名,只需要保存指定的日志个数,删除多余的日志文件即可;
若没有 dateext ,那么日志文件就需要进行改名了,第一次进行日志轮替时,当前的 secure 日志会自动改名为 secure.1 ,然后新建 secure 日志用来保存新的日志,当第二次进行轮替时, secure.1 会自动改名为 secure.2 ,当前的 secure 日志会自动改名为 secure.1 然后也会新建 secure 日志,用来保存新日志,以此类推;
logrotate配置文件的主要参数
-
daily :日志的轮替周期是每天;
-
weekly :日志的轮替周期是每周;
-
monthly :日志的轮替周期是每月;
-
rotate number :保留日志文件的个数,0代表无备份;
-
compress :日志轮替时旧日志文件是否进行压缩;
-
create mode owner group :创建新日志文件时是否指定日志的权限、所属者、所属组;
-
mail address :当日志轮替时,输出内容通过邮件外发到指定地址;
-
missingok :如果日志不存在,则忽略该日志的告警信息;
-
notifempty :如果日志文件为空,则不进行日志轮替;
-
minsize number :日志轮替最小值,达到该值才会进行轮替;
-
size number :设置轮替为指定大小,超过此大小则进行轮替,取消时间轮替;
-
dateext :以日期作为日志轮替的文件后缀;
-
sharedscripts :在此关键字之后的脚本只执行一次;
-
prerotate/endscript :在日志轮替之前执行脚本命令,endscript表示脚本结束;
-
posttrotate/endscript :在日志轮替之后执行脚本命令,endscript表示脚本结束;
logger的使用
logger 是一个shell 命令接口,可以通过该接口使用Syslog的系统日志模块,还可以 从命令行直接向系统日志文件写入一行信息。
-
-i 在每行都记录进程ID
-
-t 日志中的每一行都加一个error标签
-
-p 指定自定义的日志设备,和配置文件的