了解Linux默认文件系统的发展历史目前的大部份Linux文件系统都默认采用ext4文件系统,正如先前的Linux发行版默认使用ext3、ext2以及更久前的ext。对于不熟悉Linux或文件系统的同事而言,你可能不清楚ext4相对于上一版本ext3带来了哪些变化。你可能还想晓得在一连串关于取代的文件系统比如Btrfs、XFSZFS不断被发布的情况下,ext4是否依然能得到进一步的发在一篇文章中,我们不可能述说文件系统的所有方面,但我们尝试让你早日了解Linux默认文件系统的发展历史,包括它的诞生以及未来发展。我仔细研究了维基百科里的各类关于ext文件系统文章、wiki中关于ext4的条目以及结合自己的经验写下这篇文章。ext导论MINIX文件系统在有ext之前,使用的是MINIX文件系统。假如你不熟悉Linux历史,这么可以理解为MINIX是用于IBMPC/AT微型计算机的一个特别小的类Unix系统。AndrewTannenbaum为了教学的目的而开发了它,并于1987IBM1980中期的PC/AT,MBlairMartin,CCBY-SA4.0其实你可以通读MINIX的源代码,但实际上它并不是自由开源软件(FOSS)。
出版Tannebaum专著的出版商要求你花69港元的许可费来运行MINIX,而这笔费用包含在书籍的费用中。虽然这么,在那时来说十分实惠,但是MINIX的使用得到迅速发展,很快超过了Tannebaum曾经使用它来院长操作系统编码的意图。在整个20世纪90代,你可以发觉MINIX的安装在世界各个学院上面十分流行。而此时,年青的LinusTorvalds使用MINIX来开发原Linux内核,并于1991年首次公布,而后在1992GPL开源合同下发布。并且等等,这是一篇以文件系统为主题的文章不是吗?是的,MINIX有自己的文件系统,初期的Linux版本依赖于它。跟MINIX一样,Linux的文件系统也就像玩具那般小MINIX文件系统最多能处理14个字符的文件名,而且只能处理64MB的储存空间。到了1991通常的硬碟规格已然达到了40-140MB。很其实,LinuxLinus开发出刚起步的Linux内核时,RémyCard从事第一代的ext文件系统的开发工作。ext文件系统在1992年首次实现并发布仅在Linux首次发布后的一年!——ext解决了MINIX文件系统中最糟糕的问题。ext使用在Linux内核中的新虚拟文件系统(VFS)具象层。
与之前的MINIX文件系统不同的是,ext可以处理高达GB储存空间并处理255个字符的文ext并没有长时间占统治地位,主要是因为它原始的时间戳(每位文件仅有一个时间戳,而不是明天我们所熟inode、最近文件访问时间和最新文件更改时间的时间戳。)仅仅一年后,ext2就取代了它。Rmy很快就意识到ext的局限性,所以一年后他设ext2取代它。当ext一直根植于“玩具”操作系统时,ext2从一开始就被设计为一个商业级文件系统,承袭BSDBerkeley文件系统的设计原理。ext2提供了GB级别的最大文件大小和TB级别的文件系统大小,使其在20世纪90年代的地位牢牢巩固在文件系统大联盟中。很快它被广泛地使用,无论是在Linux内核中还是最终在MINIX中,且借助第三方模块可以使其应用于MacOS但这儿仍旧有一些问题须要解决:ext2文件系统与20世纪90年代的大多数文件系统一样,假如在将数据写入到c盘的时侯,系统发生崩溃或断电,则容易发生灾难性的数据损毁。随着时间的推移,因为碎片(单个文件储存在多个位置,数学上其分散在旋转的c盘上),它们也遭到了严重的性能损失。虽然存在这种问题,但明天ext2还是用在个别特殊的情况下最常见的是,作为便携式USB驱动器的文件系统格式。
ext2被采用后的年后,StephenTweedie宣布他正在旨在于改进ext2。这成了ext3,并于20012.4.15内核版本中被采用到Linux内核主线中。20世纪90年代中期的PackardBell计算机,Spacekid,CC0Linux发行版中工作得很FAT、FAT32、HFS和当时的其它文件系统一样在断电时容易发生灾难性的破坏。假如在将数据写入文件系统时侯发生断电,则可能会将其留在所谓不一致的状事情只完成一半而另一半未完成。这可能造成大量文件遗失或破损,这种文件与正在保存的文件无关甚至造成整个文件系统未能卸载。20世纪90年代后期的其它文件系统,如微NTFS,使用日志来解决这个问题。日志是c盘上的一种特殊的分配区域,其写入被储存在事务中;假如该事务完成c盘写入,则日志中的数据将递交给文件系统自身。假如系统在该操作递交前崩溃,则重新启动的系统辨识其为未完成的事务而将其进行回滚,如同未曾发生过一样。这意味着正在处理的文件可能仍然会遗失,但文件系统本身保持一致,且其它所有数据都是安全的。在使用ext3文件系统的Linux内核中实现了三个级别的日志记录方法:日记journal、顺序ordered日记是最低风险模式,在将数据和元数据递交给文件系统之前将其写入日志。
这可以保证正在写入的文件与整个文件系统的一致性,但其明显增加了性能。次序是大多数Linux发行版默认模式;次序模式将元数据写入日志而直接将数据递交到文件系统。顾名思义,这儿的操作次序是固定的:首先,元数据递交到日志;其次,数据写入文件系统,之后才将日志中关联的元数据更新到文件系统。这确保了在发生崩溃时,这些与未完整写入相关联的元数据仍在日志中,且文件系统可以在回滚日志时清除这些不完整的写入事务。在次序模式下,系统崩溃可能造成在崩溃期间文件的错误被主动写入,但文件系统它本身也是最不安全的日志模式。在回写模式下,像次序模式一样,元数据会被记录到日志,但数据不会。与次序模式不同,元数据和数据都可以以任何有利于获得最佳性能的次序写入。这可以明显增强性能,但安全性低好多。虽然回写模式一直保证文件系统本身的安全性,但在崩溃或崩溃之前写入的文件很容易遗失或破损。跟之前的ext2类似,ext3使用16位内部主存。这意味着对于有着4K块大小的ext3在最大尺寸为16TiB的文件系统中可以处理的最大文件大小为TheodoreTs’o(是当时ext3主要开发人员)在2006年发表的ext4,于五年后在2.6.28内核版本中被加入到了Linux主线。
ext4描述为一个明显扩充ext3但依然依赖于旧技术的临时技术。他预计ext4终将会被真正的下一代文件系统所替代。DellPrecision380工作站,LanceFisher,CCBY-SA2.0ext4在功能上与ext3在功能上十分相像,但支持大文件系统,提升了对碎片的抵抗力,有更高的性能以及更好的时间戳。ext4vsext3ext4有一些特别明晰的差异,在这儿集中讨ext4特地设计为尽可能地向后兼容ext3。这除了容许ext3文件系统原地升级到ext4;也容许ext4驱动程序以ext3模式手动挂载ext3文件系统,因而使它无需单独维护两个代码库。ext3文件系统使用32位轮询,这限制它仅支持TiB文件大小和16TiB文件系统系统大小(这是假定在块大小为KiB的情况下,一些ext3文件系统使用更小的块大小,因而对其进一步被限制)。ext4使用48位的内部主存,理论上可以在文件系统上分配高达16TiB大小的文件,其中文件系统大小最高可1000000TiB(1EiB)。在初期ext4的实现中有些用户空间的程序一直将其限制为最大大小为16TiB的文件系统,但截止2011年,e2fsprogs早已直接支持小于16TiB大小ext4文件系统。
比如,红帽企业Linux在其协议上仅支持最高50TiBext4文件系统,并建议ext4卷不超过100TiB。ext4在将储存块写入c盘之前对储存块的分配方法进行了大量改进,这可以明显增强读写性能。区段extent是一系列连续的化学块(最多达128MiB,假定块大小为KiB),可以一次性保留和主存。使用区段可以降低给定文件所需的inode数目,并明显降低碎片并提升写入大文件时的性能。ext3为每一个新分配的块调用一次块分配器。当多个写入同时打开分配器时,很容易造成严重的碎片。但是,ext4使用延后分配,这容许它合并写入并更好地决定怎样为仍未递交的写入分配块。在为文件预分配c盘空间时,大部份文件系统必须在创建时将零写入该文件的块中。ext4容许取代使用fallocate(),它保证了空间的可用性(并企图为它找到连续的空间),而不须要先写入它。这明显增强了写入和将来读取流和数据库应用程序的写入数据的性能。这是一个耐人寻味而有争议性的功能。延后分配容许ext4等待分配将写入数据的实际块,直至它打算好将数据提交到c盘。(相比之下,虽然数据仍旧在往写入缓存中写入,ext3也会立刻分配块。
)当缓存中的数据累积时,延后分配块容许文件系统对怎样分配块作出更好的选择,增加碎片(写入,以及稍后的读)并明显提高性能。但是不幸的是,它降低了还没有专门调用fsync()方式(当程序员想确保数据完全刷新到c盘时)的程序的数据遗失的可能性。fd=open(“file”,O_TRUNC);write(fd,data);close(fd);使用旧的文件系统,close(fd);足以保证file中的内容刷新到c盘。虽然严格来说,写不是事务性的,但若果文件关掉后发生崩溃,则遗失数据的风险很小。假如写入不成功(因为程序上的错误、磁盘上的错误、断电等),文件的原始版本和较新版本都可能遗失数据或损坏。假如其它进程在写入文件时访问文件,则会看见受损的版本。假如其它进程打开文件而且不希望其内容发生修改诸如,映射到多个正在运行的程序的共享库。这种进程可能会崩溃。为了防止这种问题,一些程序员完全避开使用O_TRUNC。相反,她们可能会写入一个新文件,关掉它,之后将其重命名为旧文件名:fd=open(“newfile”);write(fd,data);close(fd);rename(“newfile”,“file”);没有延后分配的文件系统下,这足以防止里面列出的潜在的毁坏和崩溃问题:由于rename()是原子操作,所以它不会被崩溃中断;而且运行的程序将继续引用旧的文件。
如今file的未链接版本只要有一个打开的文件文件句柄即可。并且由于ext4的延后分配会造成写入被延后和重新排序,rename(“newfile”,“file”)可以在newfile的内容实际写入c盘内容之前执行,这出现了并行进行再度获得file为了减轻这些情况,Linux内核(自版本2.6.30)尝试检查那些常见代码情况并强制立刻分配。这会降低但不能避免数据遗失的可能性而且它对新文件没有任何帮助。假如你是一位开发人员,请注意:保证数据立刻写入磁盘的惟一方式是正确调用fsync()。ext3仅限于32000个子目录;ext4容许无限数目的子目录。从2.6.23内核版本开始,ext4使用HTree索引来降低大量子目录的性能损失。ext3没有对日志进行校准,这给处于内核直接控制之外的c盘或自带缓存的控制器设备带来了问题。假如控制器或具自带缓存的c盘脱离了写入次序,则可能会破坏ext3的日记事务次序,因而可能破坏在崩溃期间(或之前一段时间)写入的文件。装文件系统时,你在挂载选项设置barrier=1,之后设备都会忠实地执行fsync仍然向上到底层硬件。
通过实践,可以发现储存设备和控制器常常不遵循写入障碍提升性能(和跟竞争对手比较的性能基准),但降低了本应当避免数据受损的可能性。对日志进行校准和容许文件系统崩溃后第一次挂载时意识到其个别条目是无效或无序的。因而,这防止了回滚部分条目或无序日志条目的错误,并进一步受损的文件系统fsck被调用时会检测整个文件系统包括已删掉或空文件。相比之下,ext4标记了inode未分配的块和磁道linux命令详解词典,因而容许fsck完全跳过它们。这大大减低了在大多数文件系统上运行fsck的时间,它实现于内ext3提供细度为1秒的时间戳。其实足以满足大多数用途,但任务关键型应用程序常常须要更严格的时间控制。ext4通过提供毫秒级的时间戳,使其可用于这些企业、科学以及任务关键型的应用程序。ext3文件系统也没有提供足够的位来储存203818日之后的日期。ext4在这儿降低了两个位,将Unix纪元扩充了408年。假如你在公元2446年读到这篇文章,你很有可能早已转移到一个更好的文件系统假如你还在检测自197000:00(UTC)以来的时间,这会让我死后得以安眠。ext3都不直接支持在线碎片整理即在挂载时会对文件系统进行碎片整理。
ext2有一个包含的实用程序e2defrag,它的名子暗示它须要在文件系统未挂载时脱机运行。(其实,这对于根文件系统来说十分有问题。)ext3中的情况甚至更糟糕其实ext3不容易遭到严重碎片的影响,但ext3文件系统运行e2defrag可能会造成灾难性受损和数据遗失。虽然ext3最初被觉得“不受碎片影响”,但对同一文件(比如BitTorrent)采用大规模并行写入过程的过程清楚地表明情况并非完全这么。一些用户空间的手段和解决方式,比如Shake,以这样或那样形式解决了这个问题但它们比真正的、文件系统感知的、内核级碎片整理过程更慢并且在各方面都不太令人满意。ext4通过e4defrag解决了这个问题,且是一个在线、内核模式、文件系统感知、块和区段级别的碎片整理实用程正在进行的ext4开发ext4,正如MontyPython中瘟疫感染者以前说过的那样,“我还没死呢!”虽然它的主要开发人员觉得它只是一个真正的下一代文件系统的权宜之计,然而在一段时间内,没有任何可能的候选人打算好(因为技术或许可问题)布署为根文件系统。在未来的ext4版本中依然有一些关键功能要开发linux命令tar,包括元数据校准和、一流的配额支持和大分配块。
因为ext4具有冗余超级块,因而为文件系统校准其中的元数据提供了一种方式,可以自行确定主超级块是否已损毁并须要使用备用块。可以在没有校准和的情况下,从损坏的超级块恢复并且用户首先须要意识到它已损毁,之后尝试使用备用方式自动挂载文件系统。因为在个别情况下,使用受损的主超级块安装文件系统读写可能会导致进一步的毁坏,虽然是经验丰富的用户也难以防止,这也不是一个完美的解决方案!ZFS等下一代文件系统提供的极度强悍的每块校准和相比,ext4的元数据校准和的功能十分弱。但它总比没有好。其实校准所有的事情都听上去很简单!事实上,将校准和与文件系统联接到一起有一些重大的挑战;请参阅设计文档了解详尽信息。等等,配额?!从ext2出现的这天开始我们就有了这种!是的,但它们仍然都是事后的添加的东西,但是它们总是逞能。这儿可能不值得详尽介绍,但设计文档列举了配额将从用户空间联通到内核中的形式,但是才能愈发正确和高效地执行。随着时间的推移,这些厌恶的储存系统不断显得越来越大。因为一些固态硬碟早已使用8K硬件块大小,因而ext44K模块的当前限制越来越遭到限制。
较大的储存块可以明显降低碎片并提升性能,代价是降低“松弛”空间(当你只须要块的一部份来储存文件或文件的最后一块时留下的空间)。ext4的实际限制ext4是一个强壮、稳定的文件系统。现在大多数人都应当在用它作为根文件系统,但它未能处理所有需求。让我们简单地说说你不应当期盼的一些事情现今或可能在未来:尽管ext4可以处理高达EiB大小(相当于1,000,000TiB)大小的数据,但你真的不应当尝试这样做。不仅还能记住更多块的地址之外,还存在规模上的问题。并且现今ext4不会处理(但是可能永远不会)超过50-100TiB的数据。ext4也不足以保证数据的完整性。随着日志记录的重大进展又回到了ext3的那种时侯,它并未囊括数据受损的许多常见诱因。假如数据早已在c盘上被破坏因为故障硬件,宇宙射线的影响(是的,真的),或则只是数据随时间衰减ext4未能测量或修补这些受损。基于前面两点,ext4只是一个纯文件系统,而不是储存卷管理器。这意味着,虽然你有多个c盘也就是奇偶校准或冗余,理论上你可以从ext4中恢复受损的数据,但未能晓得使用它是否对你有利。
尽管理论上可以在不同的层中分离文件系统和储存卷管理系统而不会遗失手动受损检查和修补功能,但这不是当前储存系统的设计方法,但是它将给新设计带来重大挑战。在我们开始之前,提醒一句:要特别当心,没有任何备用的文件系统作为主线内核的一部份而外置和直接支持!虽然一个文件系统是安全的,假如在内核升级期间出现问题,使用它作为根文件系统也是十分可怕的。假如你没有充分的理由通过一个chroot去使用取代介质引导,耐心地操作内核模块、grub配置和DKMS……不要在一个很重要的系统中去除预留的根文件。可能有充分的理由使用你的发行版不直接支持的文件系统但若果你这样做,我强烈建议你在系统启动并可用后再安装它。(比如,你可能有一个ext4根文件系统,但是将大部份数据储存在ZFSBtrfs池中。)ext文件系统在Linux中的主线中的地位一样。它是一个64位的日志文件系统,自2001年以来内放在Linux内核中,为小型文件系统和高度并发性提供了高性能(即大量的进程就会立刻写入文件系统)。开始,XFS成为RedHatEnterpriseLinux的默认文件系统。
对于家庭或大型企业用户来说,它依然有一些缺点最值得注意的是,重新调整现有XFS文件系统是一件十分苦闷的事情,不如创建另一个并复制数据更有意义。其实XFS是稳定的且是高性能的,但它和ext4之间没有足够具体的最终用途差别,以值得推荐在非默认(如RHEL7)的任何地方使用它,除非它解决了对ext4的特定问题,比如小于50TiB容量的文件系统。XFS在任何方面都不是ZFS、Btrfs甚至WAFL(一个专有的SAN文件系统)的“下一代”文件系统。如同ext4一样,它应当被视为一种更好的方法的权宜之计。SunMicrosystems开发,以zettabyte命名万亿GB由于它理论上可以解决小型储存系统。作为真正的下一代文件系统,ZFS提供卷管理(才能在单个文件系统中处理多个单独的储存设备),块级加密校验和(容许以极高的确切率测量数据受损),手动受损修补(其中冗余或奇偶校准储存可用),快速异步增量复制,内联压缩等,以及更多。Linux用户的角度来看,ZFS的最大问题是许可证问题。ZFS许可证是CDDL许可证linux 默认 文件不缓存,这是一种与GPL突的半许可的许可证。
关于在Linux内核中使用ZFS义存在好多争议,其争议范围从“它是GPL违法”到“它是CDDL违法”到“它完全没问题linux 默认 文件不缓存,它还没有在法院上进行过测试。”最值得注意的是,自2016年以来Canonical已将ZFS代码内联在其默认内核中,并且目前尚未能律挑战。此时,虽然我作为一个特别狂热于ZFS的用户,我也不建议将ZFS作为Linux的根文件系统。假如你想在Linux上借助ZFS的优势,用ext4设置一个小的根文件系统,之后将ZFS用在你剩余的储存上,把数据、应用程序以及你喜欢的东西置于它里面root分区保留在ext4上,直至你的发行版明晰支持ZFS根目录。B-TreeFilesystem的简称,一般发音为“butter”ChrisMason2007年在Oracle任职期间发布。Btrfs致力跟ZFS有大部份相同的目标,提供多种设备管理、每块校准、异步复制、直列压缩等,还有更多。截止2018年,Btrfs相当稳定,可用作标准的单c盘文件系统,但可能不应当依赖于卷管理器。与许多常见用例ZFS相比,它存在严重的性能问题,其下一代功能可能十分多,其结果可能是从灾难性地性能增加到实际数据的丢Btrfs的维持状态是有争议的;SUSEEnterpriseLinux2015年采用它作为默认文件系统,而RedHat2017年宣布它从RHEL7.4开始不再支持Btrfs。可能值得注意的是,该产品支持Btrfs布署用作单c盘文件系统,而不是ZFS中的多c盘卷管理器,甚至Synology在它的储存设备使用Btrfs,并且它在传统Linux内核RAID(mdraid)之上分层来管理c盘。