【linux系统命令④】、文件系统

(由于以下内容纯经手打,有些过于白话,且省事尽量无配图,不明之处敬请留言!)


简介:(文件系统)

我们知道linux使用了树形文件存储结构,也就是目录加文件,然后子目录再有文件,树状递归;

不过对于硬件磁盘和计算机而言,无论什么数据,都是二进制0和1,我们知道,磁盘有扇区,数据就罗列存放在里面,但是我们的肉眼是无法识别的,就是看到了你也不懂啊,电影里面那些满屏0和1的炫酷场面,现实中基本是不存在的;当然有时你觉得的你牛逼,是因为你圈子小,我想发明和研发它的人员应该能看懂吧;所以问题来了,为了让我们能够读懂数据并使用它,就必须需要一种翻译的机制存在用户和磁盘之间啊;

而linux则采用了文件系统+vfs虚拟文件系统的方法来组织数据咯;virtual file system就不多说了!

 /proc 虚拟文件系统,也就是最小系统目录,可以查看一些硬件、内核、进程等运行状态

文件系统,即操作系统用于明确磁盘或分区上相关文件的方法和数据结构,通俗的说就是给磁盘一个组织文件的方法;可能你还不明白,但是格式化你应该知道,如我们常说的格式化成ntfs、fat、ext4;

也就是说,文件系统就是分区组织数据文件的结构类型,有别于我们把分区组织一起的分区表称为磁盘分区结构,即我们常说的mgr、gpt;

一、linux文件系统:ext2、ext3、ext4  

linux可以支持多种不同的文件系统,其中系统使用的一般为ext系列,目前最常用的是ext4;

除此之外还支持zfs、iso9660、vfat、msdos、smbfs、nfs等,还可以加载模块来支持更多文件系统;

ext2:(the second extended file system)

linux最早使用的是minix,其局限性很大,比如文件名最长14个字符,文件最大64MB,后被ext2取代;

ext2拥有就好的存储性能,采取将文件数据存放在数据块中的方法来存储数据,事实上大部分文件系统都是这样;每个文件和目录都用一个inode指定,也就是节点id,但是ext2没有日志功能,你懂的不安全;

于是ext3应运而生,兼容ext2并支持日志功能,先在日志文件系统写入相关信息,在真实写入数据;

ext4更牛逼了,兼容2和3,更有日志校验、多块分配、预分配、支持更多节点和块等很多优点的;

当然如果旧版本向先版本文件系统转换,还是很简单的!

①、linux文件系统升级:ext2–>ext3、ext3–>ext4

首先ext2–>ext3使用命令tune2fs即可:

[root@Moni ~]# tune2fs -j /dev/sdb1
注意

tune2fs命令是调整和查看ext2/ext3文件系统,也是检查文件系统的重要命令,就像当windows系统出现突然断电或意外死机强制关机的情况下,再次启动系统会进行系统自检的操作,linux也一样,并且我们还可以通过tune2fs命令来进行自定义自检周期和方式,并默认情况下如果系统检测到文件系统有错误,会设置文件系统在下次启动的时候执行fsck检测:

  1. tune2fs m 1 /dev/sda1 将/dev/sda1分区的保留比调为1%
  2. tune2fs r 40000 /dev/sda1 调整/dev/hda1分区的保留空间为40000个磁盘块
  3. tune2fs c l /dev/hda1 关闭强制检查挂载次数限制。
  4. tune2fs i 10 /dev/hda1 10天后检查
  5. tune2fs i 1d /dev/hda1 1天后检查
  6. tune2fs i 3w /dev/hda1 3周后检查
  7. tune2fs i 6m /dev/hda1 半年后检查
  8. tune2fs i 0 /dev/hda1 禁用时间检查(tune2fs -l /dev/sdb1 | grep -E ‘Maximum mount count:|Check interval’)
  9. tune2fs -o acl,user_xattr /dev/hda1 设置/dev/hda1挂载选项,启用Posix Access Control Lists和用户指定的扩展属性
  10. tune2fs -U 51f7e9a4-5154-4e29-a7a6-208417290b85 /dev/sda1更改设备为指定的uuid
  11. tune2fs -U random /dev/sda1 ;-U 的参数如果为 random 表示直接产生一个随意的新 UUID:
  12. tune2fs -U time /dev/sda1 ;-U 的参数如果为 time 表示直接依当前时间产生一个新的 UUID:
  13. tune2fs -U clear /dev/sda1 ;-U 的参数如果为 clear 表示清除档案系统的 UUID:

其次ext3–>ext4升级:

lsmod |grep ext4 ##先检查一下系统是否支持ext4文件系统
uname -a  ##查看一下系统内核版本建议在2.6.18以上
umount partition ##卸载要升级的分区,如果是系统或重要分区,可以进入系统单用户模式进行操作;如果分区正在使用,可以用lsof和fuser消除关联!
tune2fs -l /dev/sda1 | grep extent ##查看一下分区是否有激活的ext4分区特征
tune2fs -O has_journal,extents,huge_file,flex_bg,uninit_bg,dir_nlink,extra_isize ##给分区添加ext4特性
e2fsck -fDC0 /dev/sdb1 -y  ##检查文件系统错误
mount partition ##重新挂载分区!或重启即可!
注意

vi /etc/fstab  ##切记一定要给这个在这个文件中,给对应的分区type修改为ext4,否则重启会重新回到ext3!

可以使用命令“df -Th 、fsck -N 、lsblk -f 、mount | grep “^/” 、blkid 、file -sL partition ”等命令,来获取分区的文件系统类型!

最后ext3–>ext2(因为某种特殊需求降级处理):

tune2fs -O ^has_journal parition ##给这个分区取消ext3类型特性! 
e2fsck -pf partition ##检查分区错误 
rm -rf .journey ##moung挂载后,cd进入挂载目录,删除目录下“.journey”文件 
vi /etc/fstab ##一定不要忘了修改对应分区的类型为ext3

二、新建分区并创建文件系统:fdisk、parted、mkfs.ext4  

了解以上的文件系统后,我们要知道如何创建和使用它们,首先是创建分区,常用的命令即fdisk:

[root@Moni ~]# fdisk -l  ##查看磁盘设备相关信息;
<--可以看到新添加的磁盘和磁盘剩余未分配的空间,如“Disk /dev/sdb doesn't contain a valid partition table”表示磁盘未分区-->
[root@Moni ~]#fdisk /dev/sdb
command (m for help):p ##"p"显示磁盘和分区信息
command (m for help):n ##新建磁盘
command action 
    e   extended
    p   primary partition (1-4)
p ##这里键入“p”,创建主分区,“e”是创建扩展分区
partitionnumber (1-4):1 ##选择“1”就好,如果已经有主分区1,则键入“2”,可用“p”查看分区信息
first cylinder (1-130),default 1):1 ##其实柱面,默认即可,也可手动选择,如“1”
last cylinder or +size or +sizeM or +sizek (1-130,default 130):130
<--这里默认是分配到最后一个柱面,当然前提是后面没有别的分区,也可以自定义,如“+20G” 即给20G的空间-->
command (m for help):w ##保存并退出,“q”不保存退出
the partition table has been altered!
calling ioctl() to re-read partition table.
syncing disk.
[root@Moni ~]#mkfs.ext4 /dev/sdb1 ##格式化分区,过程需要数分钟不等!

以上是fdisk命令分区,但是fdisk有个限制,就单个是分区不能超过2TB,为什么?因为fdisk的分区结构采用的MBR!

如此对于大于两个TB的分区,我们需要采用GPT分区结构,so,请参考下面本站文章:
【系统集成】linux使用parted划分大于2TB分区

三、挂载磁盘分区:mount、fstab  

创建了磁盘分区后,还需要挂载才能使用,就好比windows上要分配个盘符才能使用(win上最多可支持24个分区),linux中则需要挂载到目录,如此理论上linux上的挂载点很多咯!

首先说一下mount命令,即linux系统挂载分区的工具:

[root@Moni ~]# mkdir /mnt/disk1 <--新建挂载点-->
[root@Moni ~]# mount /dev/sdb1 /mnt/disk1
[root@Moni ~]# mount <--显示所有挂载-->
/dev/mapper/VolGroup-lv_root on / type ext4 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
devpts on /dev/pts type devpts (rw,gid=5,mode=620)
tmpfs on /dev/shm type tmpfs (rw,size=80%)
/dev/sda1 on /boot type ext4 (rw)
/dev/sdb1 on /mnt/disk1 type ext4 (rw)
[root@Moni ~]# df -Th | grep sda1 <--显示分区信息和使用情况-->
/dev/sdb1 ext4 477M 33M 419M 8% /mnt/disk1
<--"477"总空间,"33"已使用,"419"可用空间,"8%"已使用百分比-->

mount是我们手动挂载分区,重启后失效,那么如何设置随系统启动自动挂载磁盘呢?

/etc/fstab文件,便可使得系统在重启后自动挂载的配置文件;

[root@Moni ~]# echo "/dev/sdb1 /mnt/disk1 ext4 defaults 0 0" >> /etc/fstab

“”之内的字符串,第一部分即挂载的分区设备文件,第二部分即分区的挂载点,第三部分即分区的文件系统格式,第四部分使用系统默认的挂载参数(defaults),第五部分即决定dump命令在进行备份时是否要将这个分区存档,有三个值,默认设置为“0”不存档,“1”代表每天进行dump的操作,“2”代表不定日期的dump操作,第六部分即设定系统启动时是否对设备进行fsck,数值也有三种“1”保留给根分区,其它分区使用“2”,表示检查跟分区后检查,“0”表示不检查;

当然其中挂载分区的设备文件,大多情况下我们并不这么配置,而是配置成磁盘分区的UUID:

[root@Moni ~]# blkid /dev/sdb1 <--获取UUID-->
/dev/sdb1: UUID="74d0f4e9-a559-458f-8bce-307cd21ab895" TYPE="ext4" 
[root@Moni ~]# vim /etc/fstab
UUID=74d0f4e9-a559-458f-8bce-307cd21ab895 /mnt/disk1 ext4 defaults  0 0
[root@moni ~]#mount -a <--重新加载fstab文件-->

  

扩展

上面第四部分讲到挂载文件系统的parameters参数

其中defaults即同时具备rw、suid、dev、exec、auto、nouser、async等默认参数设置:

  • async、sync:设置是否为同步方式运行,默认为async
  • aoto、noauto:当执行命令“mount -a”时,此文件系统是否被主动挂载,默认为auto
  • rw、ro:是否以只读或者读写模式挂载
  • exec、noexec:限制此文件系统内是否能够进行“执行”的操作
  • user、nouser:是否允许用户使用mount命令挂载
  • suid、nosuid:是否允许suid的存在
  • usrquota:启动文件系统支持配额模式
  • Grpquota:启动文件系统对群组磁盘配置模式的支持

以上参数都是针对一般文件系统参数,多个参数用“,”隔开,除此之外,如tmpfs文件系统:

tmpfs,临时文件系统,基于系统内存的文件系统,类似于虚拟磁盘ramdisk,但不完全相同,tmpfs可以使用RAM,但它也可以使用swap分区来存储,而且传统的ramdisk是个块设备,要用mkfs来格式化它,才能真正地使用它;而tmpfs是一个文件系统,并不是块设备,只是安装它,就可以使用了。当然tmpfs是最好的基于RAM的文件系统。

当然说这么多,tmpfs,博主知道的就是oracle的sga的使用;有的时候报错“SGA size can not be greater than maximum shared memeory segment size”,便可以通过调tmpfs的大小来解决

tmpfs /dev/shm tmpfs defaults,size=80%  0 0  
<--调整“size”参数,使用的是RAM物理内存空间-->

另外还有常见的挂载iso镜像文件系统使用的“-o loop”l参数,用来把一个文件当作一个设备挂载

linux中常见的几种虚拟文件系统,即一般基于ram内存的文件系统:

proc虚拟文件系统,向用户提供了内核的大量信息,如进程相关信息,boot向内核传的参数及一些内核模块相关的信息:

proc /proc  proc defaults  0 0

stsfs虚拟文件系统,用于管理设备的属性,通过sysfs可以访问到所有挂载在系统当中的设备的属性,如设备id、总线号、插槽号;

sysfs /sys  sysfs defaults 0 0

devpts虚拟文件系统,为远程虚拟终端提供支持,pts即远程虚拟终端,devpts就是虚机终端文件系统文件设备咯,

devpts /dev/pts devpts gid=5,mode=620  0 0

tmpfs虚拟文件系统,存储操作过程中的的中间文件,如解压一个文件,中间产生的临时文件放在这里;上面说的oracle运行的地方;

linux中挂载windows文件共享和nfs文件共享:

windows网络共享的核心是smb/cifs,所以linux要想挂载,即必须安装samba软件包,安装好即可直接挂载咯!

[root@Moni ~]# mkdir /mnt/samba
[root@Moni ~]# mount -t smbfs -o username=administrator,password=123456  //192.168.1.1/d$    /mnt/samba

nfs文件共享,不多说,首先检查有无nfs软件包,然后配置服务端,即可在客户端直接挂载使用咯:

①、修改 /etc/exports,增加共享目录

/export/home/work1 192.168.1.2(rw)

/export/home/work2 *(rw)

/export/home/work3 nfs-client(rw)

注:/export/home/目录下的work1、work2、work3是准备共享的目录,192.168.1.2、*、 nfs-client是被允许链接此共享linux客户机的IP地址或主机名。如果要使用主机名nfs-client必须在服务端主机 /etc/hosts文件里增加nfs-client主机名解析。格式如下:

192.168.1.3 nfs-client

②、启动与停止NFS服务

/etc/rc.d/init.d/portmap start (在REDHAT中PORTMAP是默认启动的)

/etc/rc.d/init.d/nfs start 启动NFS服务

/etc/rc.d/init.d/nfs stop 停止NFS服务

注:若修改/etc/export文件增加新的共享,应先停止NFS服务,再启动NFS服务方能使新增加的共享起作用。使用命令exportfs -rv也可以达到同样的效果。

3、linux客户端挂接(mount)其他linux系统或UNIX系统的NFS共享

# mkdir –p /mnt/nfs

注:建立一个目录用来作挂接点(mount point)

#mount -t nfs -o rw 192.168.1.1:/export/home/work1 /mnt/nfs

注:这里我们假设192.168.1.1是NFS服务端的主机IP地址,当然这里也可以使用主机名,但必须在本机/etc/hosts文件里增加服务端ip定义。/export/home/work1为服务端共享的目录。

当然这里重点,我们要了解客户端mount、fstab中,关于nfs挂载的文件系统参数:

  • hard:配置之后client会不断尝试与server连接知道mount为止;
  • rsize和wsize:配置文件传输尺寸,
  • bg :后台进程jobs管理里想必应该见到过,这里也一样,当mount无法成功时,系统将操作转移到后台继续mount,从而不影响系统的正常启动和速度;
  • fg:和bg相反,默认参数之一;
  • nfsvers=n:设定nfs版本,默认使用“2”;
  • mountport:设定mount的端口;
  • port:配置server端nfs服务的监听端口;
  • timeo=n:设置超时时间,超时则尝试重新传输,默认是7/10秒,即0.7s;
  • intr:允许通知终端一个nfs调用;
  • udp:是哦有那个udp作为nfs的传输协议;
  • tcp:使用tcp协议;
  • namlen=n:设定远程服务所允许的最长文件名,默认255;
  • acregmin=n:设定最小的在文件更新之前cache时间,默认是3;
  • acregmax=n:设定最大的在文件更新之前cache时间,默认是60;
  • acdirmin=n:设定最小的在目录更新之前的cache时间,默认是30;
  • acdirmax=n:设定最大的在目录更新之前的cache时间,默认是60;
  • actimeo=n:将上面四个值设为同一个数值,默认没有启用;
  • retry=n:当网络传输出现故障时,尝试重新连接多少时间后不在尝试,默认是10000 minutes;
  • noac:关闭cache机制;
[root@Moni ~]# vim /etc/fstab
192.168.1.1:/export/home/work1 /mnt/nfs  nfs  rw,tcp,intr   0  0

(如果“mount -a”无法挂载,尝试去掉最后“0 0”的dump和fsck参数,或是使用“mount -a -t nfs”命令)

磁盘检查:fsck、badblocks:

当磁盘出现逻辑错误时,可以使用fsck来尝试恢复;比如突然断电或宕机强制关机引起的故障;

[root@Moni ~]# fsck -t ext4 /dev/sdb1

(注意:fsck检查磁盘是,磁盘分区需是未挂载使用状态)

思考

如果umount卸载报错提示busy,怎么办?上面说可以用lsof和fuser两种方法消除关联,具体操作如下:

[root@Moni ~]# umount /home/work/work3
umount: /home/work/work3: device is busy.
 (In some cases useful info about processes that use
 the device is found by lsof(8) or fuser(1))
[root@Moni ~]# lsof /home/work/work3
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
lsof 14873 root cwd DIR 253,3 4096 2 /home/work/work3
[root@Moni work3]# kill -9 14873
[root@Moni ~]# fuser -k /home/work/work3

(前置是通过杀死占用的进程,后者是取消文件的关联)

最后再思考一下,如果是系统根分区,如何fsck呢?我们没有办法在系统中把根分区卸载!

事实上,我们只要重启计算机即可,如果真是根分区文件系统出现问题,系统在重启的时候会检测到这个问题,,我们根据提示,进入单用户模式,即可食用fsck来修复文件系统了!

此外,和fsck不同,“badblocks”是用来检测磁盘的物理坏道的!但一般只用它来确认磁盘是否有坏道!  

[root@Moni ~]# badblocks -s -v -o diskbad.log /dev/sda1
正在检查从 0 到 511999的块
Checking for bad blocks (read-only test): 完成 
Pass completed, 0 bad blocks found.
<--或是直接检测怀疑有坏道的块,用编号检测范围-->
[root@Moni ~]#badblocks -s -v -o diskbad.log /dev/sda1 END-blocks START-blocks

(如果发现了坏道,我们可以直接使用badblocks命令的写入扫描修复有坏道的扇区块,但一般不这么做,最后一定不要忘记备份)

[root@Moni ~]#badblocks -w -s /dev/sdb END-bad-blocks START-bad-blocks

(当然,如此我们扫描了坏道,如40000-45000这5000个块都是损坏的,更好的办法修复呢?)

[root@Moni ~]#e2fsck -l ./diskbad.log /dev/sda1
注意

diskbad.log就是上面检测输出有坏道的块的编号,“e2fsck -l” Add to badblocks list,意思就是添加坏道扇区块列表,提示并强迫操作系统不使用这些损坏的区块存储数据。

最后有童鞋可能会怀疑,到底是扇区编号还是区块编号,这里说的是区块编号,我们知道磁盘是由一个个扇区sectors组成,但是存储数据时,却不是以扇区为单位的,而是一个个块区block,超级快,不然数据读写是很慢的。简单的说,就是块可以包含若干页,页可以包含若干簇,簇可以包含若干扇区

(好的就分享到这里,如果您有高见或好的分享,记得留言哦!)


原创文章,转载请注明:转自于公牛博客

本文链接地址:【linux系统命令④】、文件系统

5
祝福我们的祖国繁荣昌盛
  • 请尽情挥洒您的笔墨!

    欢迎来到公牛博客更多分享更多精彩记录美丽点亮生活

    公牛博客·统计碑运行:2841 D
    博文:213 P
    评论:1872 S