卷影复制服务(VSS)的原理与实务 ── 使用中文件为何能够备份

· · Windows, VSS, 备份, 文件, NTFS, 业务应用, 故障排查, 信息系统

「想复制其他应用正打开的文件,结果被『进程无法访问该文件』这句错误挡了下来」「被要求在不停止核心系统的情况下备份数据文件夹」「备份软件为什么能若无其事地复制正在使用中的数据库文件」── 无论是开发业务应用,还是运维文件服务器,这都是迟早会撞上的问题。

答案的核心就是卷影复制服务(VSS: Volume Shadow Copy Service)。这是二十多年前就已内置在 Windows 中的机制,无论是 Windows Server Backup、系统还原,还是市面上几乎所有的备份软件,都建立在这个基础之上。1

本文面向需要「使用中文件复制功能」的业务应用开发者,以及负责文件服务器・业务电脑备份运维的信息系统人员,基于截至 2026 年 8 月的一手资料,梳理 VSS 的登场角色与原理、vssadmin 的运维实务,以及「开发者应该在多大程度上涉入 VSS」的判断标准。我们在《Windows I/O 的深层》系列中已经看过缓存管理器与 NTFS 的内部结构,本文作为其续篇,将讨论紧贴在卷之上、插入其间的「快照」这一层。

1. 先说结论

  • VSS 是一套 COM 接口群与协调服务,用于让「应用持续写入中的卷」也能被备份。它从 Windows XP 起就已内置。2
  • 登场角色共有 3 种,加上一个协调角色。它们是请求卷影副本的请求者(备份软件)、在应用一侧保证数据一致性的编写器(SQL Server 等),以及实际创建快照的提供程序,三者由 VSS 服务从中协调。1
  • Windows 标准系统提供程序采用写时复制方式。它不会复制整个卷,而是只把快照之后被改写的数据块,在改写前转移到差异区域(diff area)。差异区域必须位于 NTFS 卷上。1
  • 静止点通过「冻结编写器(最长 60 秒)→创建快照(10 秒以内)→解冻」这一流程完成。一旦超过限制时间,创建就会被中止,由请求者重新来过。1
  • 有无编写器的配合,会直接影响复制品质。没有配合创建的快照,等同于「断电瞬间的磁盘状态」(崩溃一致);有配合的快照,则已完成日志滚动或缓存刷新,是应用自身可以保证能够恢复的一致状态(应用程序一致)。31
  • 运维确认使用 vssadmin。用 list shadows / list writers / list shadowstorage 确认现状,用 resize shadowstorage 调整差异区域的上限。差异区域一旦耗尽,就会从最旧的卷影副本开始被悄悄删除。451
  • 在自制应用中嵌入 VSS 请求者是一项大工程。它是基于 COM 的原生 API,官方并未提供面向 .NET 的封装。多数情况下用重试・调整共享模式・短时间停止就足够了,真正需要 VSS 时,把 DiskShadow 写成脚本才是现实的解法(仅限 Windows Server)。67
  • 卷影副本本身并不是备份。写时复制的差异数据依赖于原卷上未受损的数据块,因此对磁盘故障、被盗这类连原卷一起丢失的故障无能为力。面对勒索软件,也会因卷影副本本身被删除(7.3)或大量改写导致差异区域耗尽(7.4)而变得靠不住。只有与保存到其他介质的备份组合起来,卷影副本才真正有意义。1

2. 问题设定 ── 使用中文件为什么无法直接复制

出发点在于 Windows 的文件共享模式。在 Windows 中打开文件(CreateFile)时,需要以共享模式(dwShareMode)声明「自己打开期间,允许其他进程做什么」。当已有进程以不允许读取共享的方式打开文件时,随后尝试以读取方式打开该文件的进程,就会因共享冲突(ERROR_SHARING_VIOLATION,错误代码 32)而失败。8 在 .NET 中,这会表现为大家熟悉的 IOException(「该进程无法访问文件,因为该文件正被另一进程使用」)。

重要的是,这不是缺陷,而是保护数据的正确机制。如果正在写入的文件在写到一半时被读取,读取方拿到的就会是「写了一半的中途状态」。排他控制的设计正如《文件集成互斥控制基础知识》中详细讨论的那样,是应用间协作的基础。

然而,这套正确的机制却与备份从根本上相冲突。

  • 共享冲突这道墙:数据库或业务应用一直开着的文件,本身就有可能连作为复制源打开都做不到。
  • 一致性这道墙:即便能打开(即对方允许读取共享),复制也需要时间。由于复制期间应用仍在持续写入,文件的前半部分与后半部分可能来自不同的时间点,多个文件之间(数据本体与日志等)也可能出现前后矛盾。而且正如《缓存管理器》一篇所述,写入首先会落到内存中的缓存上,因此只看磁盘上的文件,未必是最新内容。
  • 运维这道墙:「那就在复制时把应用停掉」听起来很有道理,但对于全天候运行的业务系统或文件服务器来说是无法接受的。

也就是说,真正的需求是「在不停止应用的前提下,得到某一瞬间的一致状态副本」。这件事靠各个应用自行解决过于沉重,于是作为 OS 层级的机制被准备出来的,正是 VSS。VSS 作为一套基于 COM 接口的框架提供,使得即便应用正在持续向卷写入数据,也能够对该卷执行备份。2

3. VSS 的登场角色 ── 请求者・编写器・提供程序

VSS 的构成,被整理为 3 种角色,加上从中协调的服务。1

角色 承担的工作 具体示例
VSS 服务 协调各角色之间的关系,是 Windows 的一部分 VSS 本体
请求者 请求创建(以及导入・删除)卷影副本的软件 各类备份软件。Windows Server Backup、DiskShadow 也属于请求者
编写器 在应用一侧保证待备份数据一致性的组件 由 SQL Server、Exchange Server 等提供。注册表等 Windows 组成部分的编写器随 OS 一同附带
提供程序 实际创建并维护卷影副本的组件 Windows 标准的系统提供程序(写时复制方式)。存储设备一侧也存在硬件提供程序

这套角色分工的妙处在于,互不了解内部结构的产品之间也能够协作。备份软件(请求者)并不了解 SQL Server 的内部结构,但 SQL Server 的编写器会以元数据的形式申报「应当备份的文件群(组件)」,并在静止点创建前后整理好自身的数据,因此请求者只需照办,就能得到一致的备份。19 在 Windows 上运行的第三方备份软件,几乎全部都是 VSS 请求者。1

信息系统实务中需要意识到这 3 种角色的场景,正是故障排查。备份软件失败到底是请求者(软件一侧)的问题、特定编写器(应用一侧)的问题,还是提供程序・差异区域(基础设施一侧)的问题,会导致排查的方向完全不同(详见第 5、7 章)。

4. 快照的原理 ── 写时复制与「静止点」

4.1. 写时复制 ── 不复制整个卷,只保存「那一瞬间」

一听到「快照」,很容易联想到整个卷的复制,但 Windows 标准系统提供程序采用的其实是写时复制(copy-on-write)方式。在创建快照的那一刻,几乎不会复制任何东西。此后,当原卷上的某个数据块即将被改写时,系统会在改写完成之前,先把改写前的数据块转移到差异区域(diff area,卷影副本存储),再放行这次写入。1 只有在每个数据块第一次被改写时才需要转移,对已转移过的数据块再次覆盖写入并不会增加差异区域的消耗。

时间点 原卷 差异区域
T0:创建快照 1 2 3 4 5 (空)
T1:改写数据块 3 1 2 3’ 4 5 3(转移改写前的内容)
T2:读取卷影副本 数据块 1 2 4 5 从这里读取 数据块 3 从这里读取

想要读取「那一瞬间的卷」时,未变化的数据块从原卷读取,发生变化的数据块从差异区域读取,二者合成即可。由于只复制发生变化的部分,创建过程一瞬间就能完成,占用的容量也只是差异部分而已。反过来说,写入越频繁的卷,差异区域消耗得也越快(这正是第 7 章的伏笔),而差异区域必须位于与原数据同一台机器的 NTFS 卷上。1 支撑这套机制的,是系统提供程序的组成文件 swprv.dll,以及插入卷 I/O 的驱动程序 volsnap.sys1 如果对「如何插入 I/O 栈」这个话题感兴趣,也可以参阅《过滤器驱动程序与迷你过滤器》一文。

顺带一提,除此之外还有把镜像分离出来的完整复制方式,以及把变化写入另一个卷的重定向写入方式,硬件提供程序会根据存储设备一侧的情况使用最优的方式。1

4.2. 创建静止点的流程 ── 冻结 60 秒・创建 10 秒的协作

如果说写时复制回答的是「如何保存」,那么 VSS 真正的核心在于「保存哪个时刻的状态」,也就是静止点的创建方式。卷影副本按以下流程创建。1

请求者请求创建卷影副本枚举编写器并收集元数据各编写器将备份对象以组件形式通过 XML 申报各编写器准备数据滚动日志・刷新缓存等整理为可恢复的一致状态冻结编写器的写入 I/O读取仍可进行,最长 60 秒VSS 刷新文件系统缓冲区并冻结文件系统提供程序创建卷影副本10 秒以内,此期间写入 I/O 保持冻结释放文件系统 → 解冻编写器应用恢复写入请求者从卷影副本耗费时间执行备份

图1:卷影副本创建流程。真正停止的只有数秒到数十秒,备份本体是针对快照执行的

要点有 3 个。

  1. 应用停止的时间,只有创建静止点的一瞬间。冻结被限定在 60 秒以内,提供程序的创建(提交)被限定在 10 秒以内,一旦超时,创建就会被中止,由请求者重新来过。1 耗时数小时的备份本体,是在应用照常运行的情况下,针对已经完成的只读卷影副本执行的。
  2. 冻结期间仍然可以读取。被停止的只有写入 I/O。1
  3. 文件系统也会被冻结。由于 VSS 会先刷新文件系统缓冲区再冻结,缓存中尚未落盘的写入以及文件系统元数据,都会以一致的顺序反映到快照中。1

4.3. 崩溃一致与应用程序一致

这里出现了区分备份品质的一个重要区别。

没有编写器配合创建的卷影副本,处于 Microsoft 术语中所说的崩溃一致(crash consistent)状态。官方定义为「与系统遭遇突然关机这一灾难性故障之后所处的磁盘状态相当」,从中恢复则「相当于突然关机后重新启动」。3 从文件系统角度看并没有损坏,但从应用的角度看,就相当于「写入过程中被拔掉了电源」。对于具备事务日志恢复机制的数据库来说,多数情况下能够恢复,但恢复处理是前提条件。

有编写器配合时,则会在静止点之前,由各编写器滚动事务日志、刷新缓存,整理为应用自身能够保证「从这里可以正确恢复」的一致状态1 这就是应用程序一致,也是编写器这套机制存在的意义。需要注意的是,编写器所保证的是「作为应用而言一致・可恢复的状态」,并不会擅自把正在执行的事务提交完成。未提交的操作会在恢复时被回滚(这与数据库常规的恢复行为相同)。编写器实现这份品质保证的方式,是在不停止应用的前提下,仅用数十秒的冻结完成。

备份软件的设置项中之所以会出现「使用 VSS」「保证应用程序一致性」这类选项,正是这一区别的体现。对于文件服务器上单纯的一批文件而言,崩溃一致基本不会造成问题;但对于承载着数据库或邮件存储的服务器来说,对应编写器是否正常,本身就直接决定了备份的品质。

5. 运维命令实务 ── vssadmin 与「以前的版本」

信息系统人员在实务中确认 VSS 状态所用的工具是 vssadmin(需在具有管理员权限的命令提示符中执行)。按照现行的命令参考,list shadows / list writers / delete shadows / resize shadowstorage 在客户端与服务器两侧都可以使用。4 Windows Server 系列的参考文档中,还额外记载了 create shadow / list shadowstorage / list providers 等命令。5 另外需要注意,vssadmin 能够管理的,仅限于系统提供程序创建的卷影副本。1

命令 可以看到什么 实务中的使用场景
vssadmin list shadows 已存在的卷影副本列表(创建时间、目标卷、卷影副本卷名) 确认「可用于恢复的静止点最早到什么时候」。检查备份后是否有残留
vssadmin list writers 已注册编写器的列表及其状态 备份软件因 VSS 错误而失败时的初步排查,确定是哪个编写器(即哪个应用)出了问题
vssadmin list shadowstorage 卷影副本存储(差异区域)的使用量、分配量、上限 调查「以前的版本消失了」的问题,检查是否已顶到上限
vssadmin resize shadowstorage ─(变更差异区域的上限) 当差异区域不足以保留期望的世代数时进行扩容10

如果 list writers 的结果显示某个编写器处于错误状态,应当怀疑的不是 VSS 本体,而是提供该编写器的应用一侧。请确认负责该应用的服务状态,以及应用程序/系统事件日志(详见第 7 章)。

resize shadowstorage/maxsize 参数可以用 KB/MB/GB 等带单位的方式指定上限,不指定时则不设上限。需要注意的是,官方明确指出,存储上限的变更(尤其是缩小)本身就有可能导致卷影副本消失10 对于希望保留世代的卷,不能随意缩小其上限。

5.1. 与「以前的版本」的关系

在文件服务器上启用「共享文件夹的卷影副本(Shadow Copies of Shared Folders)」后,共享上文件在某个时间点的副本会被定期保留,用户可以不借助管理员之手,从「以前的版本」中恢复被误删除・误覆盖的文件。1 这是 VSS 最贴近日常的应用,能够切实减少帮助台的工作量。

不过这也有上限。系统提供程序的卷影副本,每个卷最多可保留 512 个,其中共享文件夹的卷影副本功能默认维持的数量是 64 个(可通过注册表 MaxShadowCopies 更改)。1 并且正如下文所述,一旦差异区域不足,就会从旧的世代开始被自动删除。稳妥的理解方式是:「能保留多少个世代」并不取决于设置的世代数,而是由写入量和差异区域的大小决定的。

6. 开发者应如何参与 ── 自制应用是否需要 VSS

从这里开始转向开发者的视角。当被要求「希望加入一个连使用中文件也能复制的备份功能」时,应该如何与 VSS 打交道?

6.1. 自行实现请求者是一项大工程

VSS 的 API,无论请求者还是编写器,都以COM 及 C++ 接口的形式提供(请求者的核心是 IVssBackupComponents)。6 官方并未提供面向 .NET 的封装,需要从编写器的元数据收集,到快照集的管理,再到出错时的善后处理,全部正确实现,因此并不是可以作为业务应用的一个功能随意加入的东西。在我们承接开发项目的报价中,「自行实现 VSS 请求者」也会作为独立的开发项目单独列出。

现实的解法有两种。第一,交给现有的支持 VSS 的备份软件;第二,如果是 Windows Server,可以通过脚本使用 DiskShadow。DiskShadow 是 OS 自带的 VSS 请求者,除交互模式外还具备脚本模式(diskshadow /s script.txt),可以用一份脚本描述从创建卷影副本、公开到驱动器号(expose)、执行复制处理的批处理(exec),直到收尾的整个流程。71 也就是说,「创建卷影副本 → 用自制的复制处理从中取出文件 → 删除」这一整套流程,可以完全不写一行 COM 代码就搭建出来。不过DiskShadow 仅限 Windows Server,客户端 OS 中并不包含1 如果需求也覆盖客户端电脑,这一点就会让天平倾向于采用现有的备份软件。

6.2. 是否真的需要 VSS ── 判断表

根据经验,关于「复制使用中文件」的咨询,大多数无需 VSS 也能解决。请先判断需求的层级,再选择工具。

需求 现实解法 是否需要 VSS
只要能读到其他应用正在写入的文件即可,稍等一会儿也没关系 重试(重试+等待)。共享冲突多数是暂时性状态 不需要
对方应用允许读取共享 把共享模式对齐后打开(.NET 下指定 FileShare.ReadWrite)。但读到写了一半的内容这一风险需要自行管理 不需要
可以在业务的空档期(夜间・休息时段)停止应用 停止期间复制。最简单也最可靠 不需要
可以与对方应用达成协作约定 改为原子性的协作设计,例如完成后用重命名交付等方式(参见排他控制相关文章) 不需要
想把无法停止的应用的一整套数据,以一致状态复制出来 VSS。先考虑现有备份软件,其次是 DiskShadow 脚本(仅限 Server),最后才是自行实现请求者 需要

6.3. 自制应用是否应该注册编写器

也来整理一下反方向的问题:「自制的业务应用是否应该提供 VSS 编写器」。如果编写了编写器,无论客户使用哪一款备份软件,都能以应用程序一致的方式获取自身应用的数据。另外,还有一种比普通编写器更简易的快捷编写器(IVssExpressWriter)机制,但它只是登记「哪些文件应作为对象/排除对象」这一元数据声明而已。6 由于它不会接收冻结/解冻等通知,因此无法做到在创建快照时让应用的写入随之静止。快捷编写器只适用于那些保存设计上「即便在写入过程中被抓取也不会损坏(崩溃一致即可)」的场合;如果需要在静止点上进行协调,就必须实现普通的编写器。

不过,判断的基准其实很简单。

  • 如果数据保存在 SQL Server 等数据库中,就不需要。数据库一侧的编写器会保证一致性。1
  • 如果只是单纯的文件保存,首先应从保存处理本身的设计入手解决。只要采用「先把内容完整写入临时文件,再通过重命名替换」这种原子性的保存方式,即便是崩溃一致的快照,也不会留下「损坏的保存文件」。
  • 值得考虑注册编写器的,仅限于拥有跨多个文件的自有数据存储、且需要在静止点上保证相互一致的应用。而这种规模的数据是否值得用自定义格式来承载,或许才是更应该先重新审视的问题。

7. 落坑点 ── 运维中真正会踩到的 4 处

7.1. VSS 本身并不是备份

这是最重要的落坑点。系统提供程序的卷影副本,本质上是位于与原数据同一台机器磁盘上的差异数据。一旦差异区域丢失就无法合成出原状,因此对磁盘故障・主机被盗或丢失・整卷加密之类的情况,起不到任何保护作用。Microsoft 的文档也明确区分了卷影副本与备份:「从卷影副本复制到磁带等介质上的内容才是备份,复制完成后卷影副本本身是可以删除的」。1 卷影副本是静止点,是从误操作中快速恢复的手段,并不能替代保存到其他介质、其他场所的备份。

7.2. 编写器的错误属于应用一侧的问题

如果备份软件因「VSS 错误」而失败,首先应通过 vssadmin list writers 确定是哪个编写器失败了。编写器的实体是应用程序(或 Windows 组成部分)一侧的组件1,因此排查原因的主战场是负责该应用的服务状态与事件日志。如果被「备份软件报错」这一表象牵着走,只在备份软件一侧持续调查,就会绕远路。这种「从可观测的事实中缩小嫌疑范围」的排查思路,在《接手了没有源代码也没有文档的系统》一文中也有涉及。

7.3. 勒索软件会主动来删除卷影副本

这是防御方需要了解的一个事实。也许会有人期待:既然「以前的版本」可以恢复,那被勒索软件加密后,是不是也能靠它恢复?但众所周知,许多勒索软件会在加密前后删除卷影副本,主动堵死这条恢复通路。由于删除卷影副本只需具备管理员权限,用正规命令即可执行,因此它无法成为阻止入侵后攻击者的最后一道防线。据此,防御的重心应放在:(1) 把卷影副本定位为「有则更快」的辅助手段,而不是「恢复计划的一部分」;(2) 另外准备攻击者无法触及的离线・异地备份;(3) 不给日常运维账户授予管理员权限。涵盖从备份到加密・报废在内的整个 PC 生命周期防御,也可以参阅《BitLocker实务指南》《报废 Windows 电脑前的核对清单》。

7.4. 差异区域一旦耗尽,就会从旧世代开始悄悄消失

正如第 4 章所述,写时复制消耗差异区域的时机,是快照获取之后各数据块第一次被改写的时候。已转移过的数据块无论被覆写多少次,消耗量都不会增加,因此消耗量并非由「写入次数」决定,而是由「保留中的快照之后,被改写的数据块范围有多广」决定。而一旦差异区域达到上限,该卷的卷影副本就会从最旧的开始依次被删除1 由于不会对交互中的用户发出任何通知,往往是在「本以为能恢复到上周的版本」结果却做不到的时候才被察觉。不过这并非完全无声——System 日志中会记录 volsnap 来源的事件(因无法确保差异区域而被删除时记录 25,因扩展失败或达到上限而中止时记录 35/36 等)。除了定期检查外,把这些 volsnap 事件也纳入监控与告警范围,就能第一时间察觉数据丢失。大量文件更新・批量转换・碎片整理这类「大范围扫过整个卷」的处理,之所以会一口气吃光差异区域,正是因为这套「由改写范围决定消耗量」的特性。请定期用 vssadmin list shadowstorage 检查使用量,确认保留的世代数是否满足业务要求(「最长多少天后才会发现误删除」),必要时扩大上限。510

8. 总结

  • 使用中文件之所以不能直接复制,源于共享冲突与一致性这两个问题,而这正是保护数据的正确机制。「不停止应用也想要一致的副本」这一需求,VSS 就是 OS 层级给出的答案。
  • VSS 是由 VSS 服务从中协调请求者(提出请求)・编写器(保证一致性)・提供程序(执行创建)这 3 种角色的框架,使得互不了解彼此的备份软件与业务应用能够协作。
  • 系统提供程序采用写时复制方式,静止点通过「冻结编写器(最长 60 秒)→创建(10 秒以内)→解冻」完成。没有编写器配合是崩溃一致,有配合则是应用程序一致。
  • 运维确认使用 vssadmin(list shadows / list writers / list shadowstorage)。编写器的错误应怀疑应用一侧,差异区域的使用量需要定期查看。
  • 开发者应先用判断表确认能否通过重试・共享模式・停止时段・协作设计解决问题,只有真正需要时才转向 VSS。相比自行实现,DiskShadow 脚本(仅限 Server)或现有软件才是现实的解法。
  • 卷影副本不是备份。它只是依赖原卷未受损数据块的差异数据,对磁盘故障之类原卷本身丢失的情况无能为力,对勒索软件也会因卷影副本被删除或差异区域耗尽而变得不可靠。请务必与离线・异地的备份组合使用。

相关文章

相关咨询领域

合同会社小村软件承接包括「使用中文件复制・备份功能」在内的业务应用设计与开发、文件协作相关共享冲突与备份失败(VSS 编写器错误)的原因调查,以及文件服务器备份・世代管理的运维梳理。即便还处于「这件事究竟是否需要 VSS」的判断阶段,也欢迎咨询。

参考链接

  1. Microsoft Learn, Volume Shadow Copy Service (Windows Server)。关于 VSS 服务・请求者(备份软件,Windows Server Backup 与 DPM 均属此类,Windows 上几乎所有备份软件都是请求者)・编写器(由 SQL Server、Exchange Server 等提供,注册表等 Windows 组成部分的编写器随 OS 一同附带)・提供程序的角色分工;卷影副本创建的流程(收集编写器元数据 → 通过完成事务・滚动日志・刷新缓存进行准备 → 冻结写入 I/O,限时 60 秒以内且读取仍可进行 → 刷新并冻结文件系统缓冲区 → 提供程序在 10 秒以内完成创建 → 解冻,超时则中止并由请求者重试);完整复制・写时复制・重定向写入这 3 种方式;系统提供程序采用写时复制方式,差异区域(diff area)必须位于 NTFS 卷上;组成文件为 swprv.dll 与 volsnap.sys;差异区域空间耗尽时该卷的卷影副本会从最旧的开始被删除;软件卷影副本每个卷最多 512 个,共享文件夹的卷影副本默认维持 64 个(可通过 MaxShadowCopies 更改);共享文件夹的卷影副本使用户无需管理员协助即可恢复被删除・修改的文件;卷影副本与备份的区别(复制到介质上的内容才是备份,卷影副本可以删除);DiskShadow 是仅限 Windows Server 的 VSS 请求者;vssadmin 只能管理系统提供程序创建的卷影副本等内容。  2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

  2. Microsoft Learn, Volume Shadow Copy Service (Win32)。关于 VSS 是一套 COM 接口群,实现了一套框架,使得系统上的应用程序在持续向卷写入数据的同时,也能够对该卷执行备份,以及该框架自 Windows XP 起获得支持等内容。  2

  3. Microsoft Learn, VSS Glossary: crash consistent state。关于崩溃一致状态是「与系统遭遇突然关机这一灾难性故障之后所处的磁盘状态相当」的状态;从这类卷影副本集恢复相当于「突然关机后重新启动」;这是在没有编写器支持的情况下被创建为卷影副本的数据的默认状态等内容。  2

  4. Microsoft Learn, vssadmin。关于 vssadmin 是用于显示当前卷影副本,以及已安装的全部卷影副本编写器・提供程序的命令;delete shadows / list shadows / list writers / resize shadowstorage 各子命令被整理为客户端与服务器均可使用等内容。  2

  5. Microsoft Learn, Vssadmin (Windows Server 2012 R2 and 2012)。关于 Windows Server 系列参考文档中记载的 vssadmin 子命令列表,包括 add shadowstorage / create shadow / delete shadows / delete shadowstorage / list providers / list shadows / list shadowstorage(列出系统上全部卷影副本存储关联)/ list volumes / list writers / resize shadowstorage 等内容。  2 3

  6. Microsoft Learn, Volume Shadow Copy API Interfaces。关于 VSS API 以支持创建请求者与编写器的 COM 及 C++ 接口形式提供;定义了面向请求者的 IVssBackupComponents 系列接口,面向编写器的 IVssCreateWriterMetadata 系列接口,以及面向简易快捷编写器的 IVssExpressWriter 等内容。  2 3

  7. Microsoft Learn, Diskshadow。关于 DiskShadow 是一款公开 VSS 功能的工具,具备交互式命令解释器与脚本模式(diskshadow /s script.txt);执行时需要具备本地 Administrators 组成员身份;通过 add・create・expose(将持久卷影副本公开为驱动器号等)・exec(执行本地文件)・delete shadows 等命令,可以把从创建卷影副本到公开・执行备份脚本的整个流程写入一份脚本等内容。  2

  8. Microsoft Learn, CreateFileW function。关于打开文件时通过 dwShareMode 指定允许后续打开操作的共享访问(读取・写入・删除);请求的访问与既有句柄的共享模式冲突时,打开操作会因共享冲突(ERROR_SHARING_VIOLATION)而失败等内容。 

  9. Microsoft Learn, Overview of Processing a Backup Under VSS。关于备份处理中请求者与编写器如何协作;编写器通过只读元数据(Writer Metadata Document)申报自己负责的文件群(组件),请求者据此解读并选择备份对象,记录到自身的元数据(Backup Components Document)中;编写器在卷影副本创建前暂停 I/O,完成后恢复正常运行等内容。 

  10. Microsoft Learn, Vssadmin resize shadowstorage。关于该命令用于变更可用作卷影副本存储的最大容量;不指定 /maxsize 时存储用量不受限制;数值可以用 KB/MB/GB/TB/PB/EB 为单位指定;存储关联的容量变更有可能导致卷影副本消失,官方对此有明确警告等内容。  2 3

共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。

与本文相近的主题页面。以本文为起点,可以进一步了解相关服务和其他文章。

本文与以下服务页面相关联,欢迎从最接近的入口查看。

常见问题

汇总了咨询这一主题时常见的问题。

有了卷影副本,是不是就不需要备份了?
不需要这个说法并不成立。Windows 标准系统提供程序创建的卷影副本是写时复制方式的差异数据,并不会另外持有「那一时刻的完整副本」,而是依赖原卷上尚未被改写的数据块。即便把差异区域(diff area)配置在另一个卷上,一旦原卷丢失依然无法还原,对磁盘故障、电脑被盗或丢失这类连原卷一起失去的情况完全无能为力。对于勒索软件也是如此——加密写入本身确实会把改写前的数据块转移到差异区域,但在实际攻击中,卷影副本常常因被主动删除,或因大量改写导致差异区域耗尽而随之丢失,因此不能指望它。Microsoft 的文档也明确区分了两者:把卷影副本中的数据复制到磁带等介质上才是备份,复制完成后卷影副本本身是可以删除的。卷影副本只是「用于制作备份的静止点」以及「从轻微误操作中快速恢复的手段」,并不能替代保存在其他介质、其他场所的备份。
我想在自己开发的业务应用中复制使用中的文件,应该使用 VSS 吗?
现实的做法是先找一条不需要用 VSS 就能解决问题的路。VSS 的请求者必须用基于 COM 的原生 API(IVssBackupComponents 等)编写,官方并未提供面向 .NET 的封装,因此把它嵌入自制应用是相当大的工程。如果需求只是「只要迟早能读到其他进程正在写入的文件就行」,用重试就够了;如果「对方允许读取共享」,那么把共享模式对齐后打开即可。如果能让应用短暂停止,在业务的空档期复制是最简单也最可靠的做法。只有「要把无法停止的应用的一整套数据以一致状态复制出来」这一需求才轮到 VSS 出场,而即便到了这一步,也应优先考虑支持 VSS 的备份软件或把 DiskShadow 写成脚本,而不是自行实现。
vssadmin list writers 显示编写器处于错误状态,该怎么办?
基本原则是把它当作负责该编写器的应用程序一侧的问题来调查。vssadmin list writers 会列出已注册的编写器及其状态,因此首先要确定是哪个编写器失败了。编写器是由 SQL Server 之类的应用程序,或注册表等 Windows 组成部分提供的,所以出错的原因大多不在 VSS 本体,而在于负责该编写器的应用的服务状态,或记录在应用程序/系统事件日志中的错误。可以重启相应服务、排查复现条件,如果仍未解决,就去确认该应用的支持信息。备份软件因 VSS 错误而失败时,这一套排查步骤同样适用于初步定位。
卷影副本在不知不觉中消失了,这是为什么?
最常见的原因是差异区域(卷影副本存储)容量不足。在写时复制方式下,快照生成之后,每个数据块第一次被改写时,改写前的内容都会被转移到差异区域,因此被改写的范围越大,消耗的差异区域就越多。一旦达到分配的上限,Windows 就会从最旧的卷影副本开始依次删除以腾出空间。由于这个过程不会通知交互中的用户,是悄无声息地发生的,所以往往是在「以为能用以前的版本恢复到上周的版本,结果却发现没有了」的时候才被发现(System 日志中会记录 volsnap 来源的事件 25 等,把它纳入监控对象就能及时察觉)。可以用 vssadmin list shadowstorage 确认使用量与上限,需要时用 vssadmin resize shadowstorage 扩大上限。不过也要注意,上限的变更(尤其是缩小)本身就可能导致卷影副本消失。
资源管理器中的「以前的版本」和 VSS 是什么关系?
「以前的版本」是从 VSS 创建的卷影副本中取出过去文件内容的入口之一。在文件服务器上启用「共享文件夹的卷影副本」(Shadow Copies of Shared Folders)后,系统会定期创建卷影副本,用户只需右键点击共享文件夹上的文件,就能自行从以前的版本中恢复,不需要借助管理员之手。这正是它的优点:能够自行修正误删除、误覆盖。但由于其实体就是卷影副本,可保留的世代数存在上限,一旦差异区域不足,也会从旧的世代开始消失。正如正文所述,「有以前的版本,就不需要备份」这个说法并不成立。

作者简介

本文作者的个人简介页面。

Go Komura

小村软件有限公司 代表

以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。

返回博客列表