Data Domain:如何列出 Data Domain 文件系统上的文件,sfs-dump

摘要: 本文介绍如何使用 Data Domain CLI 转储单个 MTree 或整个文件系统 (FS) 的文件和目录列表。这使用户能够通过备份应用程序了解 Data Domain 中存储的数据。

本文章適用於 本文章不適用於 本文無關於任何特定產品。 本文未識別所有產品版本。

症狀

Data Domain 是被动后端存储设备。它仅存储备份应用程序告诉它要存储的内容,并且仅在备份应用程序告诉它删除文件时才删除数据。Data Domain 从不自行创建或删除任何文件。

无论接收的协议是什么,Data Domain FS 都只包含以 MTree 形式组织的文件(在目录中)。所有文件(包括活动层和任何云单元中的文件)共享相同的根和命名空间;存在单个命名空间,这意味着文件和目录列表不加区分地包括活动层和云单元中的文件。

由于以下原因,获取详细的文件转储会非常有用:
  • 与备份应用程序管理的文件列表进行比较,以检查该备份应用程序中是否有孤立的文件。
  • 列出超过特定存储时长阈值的所有文件,以确定备份应用程序是否正常执行备份保留
由于最近在 DDOS 中所做的更改,用于从 Data Domain 系统收集文件列表的命令已逐渐更改。这些命令仅在 DD CLI 中提供,并且根据版本,将为:
  • 对于低于 7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 的 DDOS
se sfs_dump
  • 对于等于或高于 7.13.0.0、7.10.1.15、7.7.5.25、6.2.1.110 的任何 DDOS
filesys sfs-dump

原因

DDOS 版本 7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 及更高版本不再支持在 SE 模式中访问以下命令:
sfs_dump
访问此功能所需的 SE 模式已被弃用,详见 DSA-2023-412:针对多个安全漏洞的 Dell Technologies PowerProtect 安全更新

在过渡期间,旧的 SE 模式 sfs_dump 命令中的一些功能不可用,但在稍后阶段重新引入。因此,本知识库文章尝试解释其中的差异以及如何处理每种情况下的命令输出。

解析度

要从 CLI 获取 Data Domain 中文件的详细列表,以及有关获取存储在 Data Domain 中的文件的情报的过程,取决于正在运行的 DDOS 版本。收集包含文件详细信息的文本输出文件后,将输出处理为更方便使用的格式的过程始终是相同的,因为所有 DDOS 版本的输出格式都是相同的(或者可以使用脚本转换为通用格式)。

所有 DDOS 版本的共同点是要求以管理员用户身份登录到 Data Domain,并使用支持将控制台输出记录到客户端上的文本文件的 SSH 客户端执行此操作(PuTTY 非常适合)。用户必须配置 SSH 客户端,以便它将输出记录到客户端计算机上的文本文件中(确保记录的行数或单个行长度没有限制)。SSH 会话日志文件(以及 DD 文件列表)不会写入 Data Domain,而是会写入发起 SSH 连接的(通常是)台式计算机。

在收集 SSH 会话输出时,确保为文件指定一个有意义的名称(例如添加 Data Domain 主机名和要转储的 MTree 名称),并确保有足够的空间用于存储日志文件(对于具有 100 万个文件的系统,此空间大约为 200 MB)。

从 DD CLI 运行以收集文件列表的确切命令取决于使用的 DDOS 版本,总结如下。
 

7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 之前的 DDOS 版本:

这些版本仍支持 se sfs_dump 命令(以及 -c 选项,将文件详细信息直接输出为 CSV,不进行任何进一步处理),但出于安全原因不建议进入 SE 模式,请升级到可用的最新 LTS DDOS 版本。

确保您以管理员用户身份登录 Data Domain,并将 SSH 客户端配置为将输出写入磁盘,更改为 SE 权限模式,然后针对需要获取文件详细信息的每个 MTree 运行以下命令:
#### To produce the output directly as CSV
# se sfs_dump -c <mtree-path>

#### To produce the output as default format
# se sfs_dump <mtree-path>
这些变体的命令还可以一次生成 FS 中所有文件的列表(而不是一次生成一个 MTree)。要转储 FS 中所有文件的文件信息详细信息,请去掉 MTree 路径:
# se sfs_dump -c
完成后,确保停止将 SSH 客户端记录到磁盘,并将文件放在一边等待进一步处理。

命令输出的格式为每个文件一行。如果不使用 -c ,格式与上面显示的更高版本的格式相同。如果使用了 -c(对于 CSV 输出),格式如下所示(输出中的第一行为标头):
name    mtime   fileid  size    seg_bytes       seg_count       redun_seg_count pre_lc_size     post_lc_size
/data/col1/backup/file       1656995350000000000     78      33554431        33668007        4016    0       33668007        34208564


DDOS 版本 7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 或更高版本:

此版本不再支持在 SE 模式下访问 sfs_dump (以下命令不可用):
se sfs_dump
由于发现安全问题,SE 模式已被弃用。要使用的备用命令如下。请注意命令名称略有不同,并且在本例中,要列出的 MTree 位于关键字“MTree”之后:
# filesys sfs-dump mtree <mtree-path>
对于标题中的版本,此 sfs-dump 命令(相较于 se sfsa_dump):
  • 新命令不支持使用 -c 选项将文件信息转储为 CSV(列)格式
  • 新命令一次只能运行一个 MTree,不支持在一次调用中针对整个 FS 运行
对于使用这些版本的客户,如果需要将所有 MTree 的文件详细信息转储到文件,则必须遍历 Data Domain FS 中的整个 MTree 列表,并为每个 MTree 运行一次命令。用户可以通过运行以下命令来获取系统中的 MTree 列表:
# mtree list
以下命令的输出与之前的 se sfs_dump 命令(不含 -c 选项。
filesys sfs-dump
确保您以管理员用户身份登录到 Data Domain,并将 SSH 客户端配置为将输出写入磁盘,然后针对您想要获取文件详细信息的每个 MTree 运行以下命令:
# filesys sfs-dump mtree <mtree-path>

如果您要获取多个 MTree 的文件详细信息,请选择将所有内容转储到同一输出文件,或者在针对每个 MTree 运行命令之前,在 SSH 客户端配置中切换到不同的文件。

或者,您可以通过 SSH 运行命令,以无人值守的方式收集输出,如下所示:

#### Releases 7.13.0.0, 7.10.1.15, 7.7.5.25 and 6.2.1.110 onwards only
# ssh sysadmin@DD-HOSTNAME "filesys sfs-dump mtree /data/col1/backup" > sfs-dump-DD-backup.txt

对于任一情况,在输出信息中每个文件占一行,格式如下:

/data/col1/backup/file: mtime: 1580211658000000000 fileid: 175 size: 136794 type: 9 seg_bytes: 138282 seg_count: 18 redun_seg_count: 14 (78%) pre_lc_size: 15045 post_lc_size: 8760 (58%) mode: 02000100644 start_offset: 0 end_offset: 18446744073709551615

DDOS 版本 8.1.0.0、7.13.1.10、7.10.1.30 和 7.7.5.40 或更高版本:

由于客户需求,旧的 se sfs_dump 命令中的一些功能已重新引入,现在可用于 filesys sfs-dump 命令,即:
  • 可以添加 -c 选项,以类似 CSV 的格式版本打印输出(字段由列分隔)
  • 可以针对 FS 中的所有文件同时运行文件转储信息
命令仍然与之前的版本相同,但具有所提及的增强功能,总结如下:
 
#### File listing for all the files in a given MTree path
# filesys sfs-dump mtree <mtree-path>

#### File listing for all the files in a given MTree path, with CSV-like output
# filesys sfs-dump -c mtree <mtree-path>

#### File listing for all the files in the FS
# filesys sfs-dump

#### File listing for all the files in the FS, with CSV-like output
# filesys sfs-dump -c

此命令继续被“隐藏”,因此它不会出现在 CLI 交互式帮助或文档中。
 

如何将 sfs_dumpfilesys sfs-dump 数据转化为有用的洞见:

使用 filesys sfs-dumpsfs_dump (不含 -c 选项)时,输出中报告的单个文件的格式总结如下:
/data/col1/backup/file: mtime: 1580211658000000000 fileid: 175 size: 136794 type: 9 seg_bytes: 138282 seg_count: 18 redun_seg_count: 14 (78%) pre_lc_size: 15045 post_lc_size: 8760 (58%) mode: 02000100644 start_offset: 0 end_offset: 18446744073709551615

Field 01 : filename with full path (/data/col1/backup/file)
Field 03 : file last modification time as UNIX epoch in nanoseconds (nanoseconds since January 1st 1970 at midnight)
Field 05 : file (inode) ID, inode numbers are per MTree (175)
Field 07 : pre-comp size for the file in bytes (136794)
Field 09 : type of file (9)
Field 11 : segment store bytes (this is NOT the file size), please ignore (138282)
Field 13 : segment count, or the number of segments the file consists of (18)
Field 15 : number of file segments which are redundant, or not unique (14)
Field 16 : percentage of non-unique segments to total segments (78%)
Field 18 : combined size of the file's unique segments after deduplication (15045)
Field 20 : combined size of the file's unique segments after deduplication and local compression (8760)
Field 21 : ratio of post-deduplicated + post-compressed unique segments size to post-deduplicated unique segment size (58%), shows how well local compression worked
Field 23 : file mode, please ignore
在上面的示例中,我们有一个原始大小为 136,794 字节的文件,该文件在通过 Data Domain FS 接收管道传递后,经计算,在进行重复数据消除后使用 15,045 字节,在写入磁盘之前文件的唯一数据段压缩后使用 8,760 字节。因此:
  • 文件重复数据消除(我们称之为“gcomp”或全局压缩)的系数为 x9.09(136,794 到 15,045 字节)
  • 文件本地压缩(我们称之为“lcomp”,表示本地压缩)的系数为 x1.72(15,045 到 8760 字节)
  • 估计的总文件大小缩减(称为“压缩比”)的系数为 x15.62(136,794 到 8760 字节)
或者, sfs_dump -c 输出是类似的,但更简洁:
/data/col1/backup/file       1656995350000000000     78      33554431        33668007        4016    0       33668007        34208564

Field 01 : filename with full path (/data/col1/backup/file)
Field 02 : file last modification time as UNIX epoch in nanoseconds (nanoseconds since January 1st 1970 at midnight)
Field 03 : file (inode) ID, inode numbers are per MTree
Field 04 : pre-comp size for the file in bytes (33554431)
Filed 05 : segment store bytes (this is NOT the file size), please ignore (33668007)
Field 06 : segment count, or the number of segments the file consists of (4016)
Field 07 : number of file segments which are redundant, or not unique (0)
Field 08 : combined size of the file's unique segments after deduplication (33668007)
Field 09 : combined size of the file's unique segments after deduplication and local compression (34208564)
对于这个例子,我们可以进行与上一个例子相同的计算:
  • 文件重复数据消除(我们称之为“gcomp”或全局压缩)的系数为 x0.99(33,554,431 到 33,668,007 字节)
  • 文件本地压缩(我们称之为“lcomp”,表示本地压缩)的系数为 x0.98(33,668,007 到 34,208,564 字节)
  • 估计的总文件大小缩减(称为“压缩比”)的系数为 x0.98(33,554,431 到 34,208,564 字节)
与不含 -c 选项示例显示的文件相比,这个示例没有实现重复数据消除(无冗余数据段),也没有实现任何本地压缩。这表示该文件是压缩文件。
 
注意:输出文件中有关大小的数据(“pre-comp size for the file in bytes”除外)应视为近似值,不可完全依赖这些数据。文件的元数据是在文件接收时创建的,在当时是正确的,但之后不会进行任何更新,因此会随着时间的推移而过时。此外,文件的 post_lc_size 是一个指定的值,并不意味着该文件使用的磁盘空间等于该容量,因为在单个文件级别上没有考虑许多 FS 级别的开销。其限制与以下命令的已知限制相同:
mtree show compression
利用上述输出文件中的信息包括以适合用户目标的方式处理数值数据。应用场景的一些示例包括:
  • 确定与特定路径对应的文件的 gcomp 和 lcomp(如果路径可以匹配到某个特定的备份服务器、客户端、策略、作业等)
  • 计算指定位置中存储的早于指定时间的数据量(压缩前)(以确定孤立数据或排查备份应用程序未按时使到期备份过期的问题)
  • 可能有用的任何其他类型的统计数据
要获得一套说明,并弥补在较新版本中无法使用 sfs_dump -c 选项的损失,我们的建议是将输出数据转换为上面的 CSV 格式,然后使用 CSV 格式的文件进行进一步处理,但是,根据您的技能,您也可以直接处理非 CSV 输出。

要将非 CSV sfs_dump 输出转换为与 sfs_dump -c 打印的输出相同的格式,您可以使用以下 Linux 命令行:
# cat sfs-dump-noCSV.txt | grep ^/ | awk '
BEGIN {print "name\tmtime\tfileid\tsize\tseg_bytes\tseg_count\tredun_seg_count\tpre_lc_size\tpost_lc_size"}
{
    colon_index = index($0, ":")
    filename = substr($0, 1, colon_index - 1)
    gsub(/^[[:space:]]+|[[:space:]]+$/, "", filename)
    n = split(substr($0, colon_index + 1), fields, " ")
    print filename "\t" fields[2] "\t" fields[4] "\t" fields[6] "\t" fields[10] "\t" fields[12] "\t" fields[14] "\t" fields[17] "\t" fields[19]
}' > sfs-dump-CSV.csv
 
提醒:上面的命令会忽略输入文件 (sfs-dump-noCSV.txt) 中不以斜杠开头的所有内容,因为只有以“/data”开头的行才包含要处理的文件详细信息。输出文件将第一行作为标头,并使用制表符 (\t) 作为字段分隔符。

超出此时间点的所有内容均按原样提供给用户。对于下面分享的说明,戴尔方面不作任何保证,也不承担任何义务。从文件列表详细信息中获取情报是用户的任务,如何实现这一目标完全取决于用于挖掘文件转储输出中的数据的工具集、要实现的目标以及用户自己在处理上述命令输出中的数据方面的专业知识。一些用户可能会选择使用文本文件的 Linux 命令行处理来转储一些聚合数据,其他用户可能会选择使用“gnuplot”为图表值生成输入,而大多数用户则会采用一种更简单(但有限)的方法,从 CSV 文件构建电子表格进行分析。

戴尔尽力确保以下说明正确、有效且对用户有用,但我们无法保证它们适用于您,也不会为这些说明提供支持,因为它们不在支持范围之内。


将 CSV 格式的 sfs_dump 输出导入到电子表格(Excel 示例):

获得 CSV 版本的文件详细信息列表后,从数据中获取情报的一种方法是将数据加载到电子表格软件中。这里使用 Microsoft Excel 作为示例,其他软件的说明应该与此类似。要将 CSV 文本文件作为 CSV 导入到 Excel 中,请执行以下步骤:
  1. 打开 Excel 并创建一个新的空白电子表格
  2. 单击顶部的数据菜单,然后单击名为从文本/CSV 的图标
  3. 使用对话框找到 CSV 格式的文件数据(sfs-dump-CSV.csv ,如非 CSV 格式的转换脚本示例中所示),选择该文件,然后单击导入
  4. 如果输入文件格式正确,并且 Excel 可以从前 200 行生成格式(它应该这样做),则对话框应显示要生成的电子表格的预览。检查信息以确保一切看起来正常,包括将第一行检测为标头
  5. 如果预览没问题,请单击对话框底部的加载按钮,您将获得格式正确的新电子表格,并且字段标题行启用搜索和筛选。
电子表格中的数据已经很有用,您可以执行一些操作,例如在数值字段中应用数字筛选(如大小)以仅显示大于指定大小的文件,或在名称字段中应用文本筛选,以仅显示 Data Domain 文件详细信息输出中与指定模式匹配的文件(仅以特定 MTree 路径开头的文件),并根据该数据进行其他推导计算。

正确导入的 Excel 电子表格应在 A 到 I 列中包含数据。如果数据仅存在于 A 列中,但布满整个屏幕,请关闭 Excel 并重试上述步骤 1 至 5。

添加额外的计算字段

用户可以根据需要,使用任意数量的计算字段扩展电子表格。例如,添加与文件的 mtime(上次修改时间,通常是写入 DD 的时间)相对应的人类可读日期和时间字段。此外,根据数据的用途,计算并显示每个文件的一些压缩值可能会很有用。新列将使用 Excel 公式自动填充,如下所述。

时间戳转换:

要将 UNIX 格式的时间戳转换为人类可读的日期和时间,请执行以下操作:
  1. 右键单击单元格 J2,选择设置单元格格式
  2. 在左侧的分类列表中,选择自定义
  3. 如果其中没有人类可读的日期时间格式,则创建该格式(示例在末尾包含 EST 字符串。您可以用您的文本时区定义替换它,或者如果不感兴趣,则完全删除“EST”):yyyy-mm-dd hh:mm:ss "EST"
  4. 完成后单击“确定”。现在,单元格 J2 具有自定义数据格式。
  5. 将以下公式添加到单元格 J2。在公式中,将 (-6*3600) 替换为在获取“sfs-dump”数据时与 Data Domain 中配置的时区的 UTC 对应的正确时区差异。例如,在夏季,美国东部时间比 UTC 晚 6 小时,因此替换为“-6”。
如果您对如此精确的时间调整不感兴趣,则可以改用公式的缩略形式。添加公式并避免覆盖日期和时间格式的最简单方法是复制以下两个版本之一,在单元格 J2 中键入“等于”字符 = 以开始编辑单元格,然后粘贴复制的公式:
(((B2/1000000000+(-6*3600))/86400)+25569)
(((B2/1000000000)/86400)+25569)
提醒:如果在未先将单元格置于编辑模式的情况下将文本粘贴到 J2 中,则会覆盖单元格的格式。或者,您可以在公式前面加上 =,复制整条文本,右键单击单元格 J2 选择选择性粘贴,选择文本,然后单击确定。效果应该是一样的。在正确执行上述步骤的情况下,Excel 会自动执行以下几项操作:
  • 将公式粘贴到单元格 J2 以及电子表格中其余行的每个单元格 
  • 针对整个电子表格计算公式,并以配置的格式显示日期和时间值
  • 对列应用美观格式,并将标题配置为可以应用日期筛选日期格式,您唯一需要做的就是为列设置适当的名称(日期

压缩信息

您可以按照上述方式添加每个文件的压缩信息列。这次我们显示的公式包含 =,因此您必须复制整条文本,然后选择性粘贴为文本:
  • 复制以下公式并在单元格 K2 中选择性粘贴为文本,以创建一个列,用于显示每个文件的重复数据消除或 gcomp 信息:
    =IF(H2=0,0,D2/H2)
  • 复制以下公式并在单元格 L2 中选择性粘贴为文本,以创建一个列,用于显示每个文件的本地压缩或 lcomp 信息:
    =IF(I2=0,0,H2/I2)
  • 复制以下公式并在单元格 M2 中选择性粘贴为文本,以创建一个列,用于显示每个文件的总文件压缩率:
    =K2*L2
为新列指定适当的名称。如果您希望更改压缩值的格式(例如,限制小数位数),请按照日期和时间示例操作,并在粘贴公式之前提前设置单元格数值格式。

请务必转到文件菜单并执行另存为,确保已保存文件的类型设置为 Excel 工作簿 (*.xlsx),以便保留格式设置和筛选。

完成所述操作后,电子表格将包含以下(相关)列:
  • A 包含文件名
  • B 包含上次写入文件的日期戳(UNIX 时间戳,以纳秒为单位)
  • D 是文件的原始大小
  • H 是全局压缩后的大小
  • I 是全局和本地压缩后的大小
  • J 包含上次写入文件的日期戳,采用人类可读格式
  • K 包含文件的全局压缩(重复数据消除)
  • L 包含文件的本地压缩
  • M 包含文件的总压缩
所有文件大小均以字节为单位。
您现在可以使用 Excel 根据需要进行筛选或排序,以报告您的数据。
  • 例如,如需仅显示 MTree /data/col1/backup 中超过 30 天的文件:
  1. 单击名称标题中的向下箭头,选择文本筛选,然后选择开头是并在文本框中键入 /data/col1/backup/ 。不要遗漏尾部斜杠。单击确定
  2. 单击最后写入日期标题中的向下箭头选择日期筛选,然后选择之前。使用对话框右侧的日期选择器选择 30 天前的日期。单击确定
底部的状态栏会显示与此选择匹配的行数。

其他資訊

转储文件位置的命令(活动和云)

有一种方法可以转储文件列表并显示哪些文件位于活动层,哪些文件位于云单元中,即:
#### For the DD FS as a whole
# filesys report generate file-location

#### For an individual MTree or subdirectory
# filesys report generate file-location path /data/col1/test

这两种情况的输出为以下类型:

-------------------------      ----------------------      ----------------------      ---------------------------
File Name                      Location(Unit Name)         Size                        Placement Time
-------------------------      ----------------------      ----------------------      ---------------------------
/data/col1/test/file1.bin                  Cloud-Unit                  200.00 GiB      Sat Mar  5 13:24:10 2022
/data/col1/test/file2.bin                      Active                   10.00 TiB      Sat May 14 00:48:17 2022
-------------------------      ----------------------      ----------------------      ---------------------------
但是,上述命令往往不适用于大多数意图,例如,大小为人类可读的单位(而不是字节、MiB 或任何设置的乘数),并且放置时间与活动层文件备份到 Data Domain 的时间相匹配,但与云中的文件不匹配(云中文件的“放置时间”是文件移动到云单元的日期和时间)。

此外,请注意以下命令(以及从非 CSV sfs_dump转换而来的脚本)在以制表符分隔的列中输出数据。输出中存在的制表符必须保存在日志记录文件中,否则上面所述的将 CSV 导入 Excel 的步骤无法正确分隔字段。
sfs_dump -c
提供的说明假定您具有一定的 Excel 知识,但在其他电子表格软件中也适用。

新式版本的 Excel 允许多行,但请记住, sfs_dump 输出中的每个文件占一行,因此 Excel 必须能够快速处理和更新行数与数据集中的文件数一样多的电子表格。硬性限制是略高于 100 万行,但即使文件数量远低于此值,Excel 也可能不适合该作业(速度太慢)。

如果您的 sfs_dump 输出中包含的文件对于您的 Excel 版本来说太多,或者您想要处理较小的文件以提高性能,您可以尝试为每个 MTree 运行一次该过程,这样系统就有多个电子表格。

即使是单个 MTree sfs_dump 输出对于 Excel 也可能太大,在这种情况下,您可以使用 split Linux 命令(或任何其他类似工具来拆分大型文本文件在线结束边界)以一次处理多个较小的 CSV 文件,例如:
# split  -b <size> <filename> <new filename prefix>  (splits by file size)
# split  -l <size> <filename> <new filename prefix>  (splits by number of lines)
# split  -n <size> <filename> <new filename prefix>  (splits by number of pieces)

例如,要将输入文本文件拆分为每个大小为 200 MiB 的数据块,并为每个块命名,运行:

"sfs_dump.out.split"

然后运行:

# split -b 200M sfs_dump.out sfs_dump.out.split


使用 "filesys sfs-dump" 进行整个 FS 文件数据转储

对于少数无法以 CSV 格式转储文件详细信息的版本,戴尔按原样(不作任何保证)向用户提供下面的脚本,以便通过处理非 CSV sfs_dump 输出来获得类似的结果。

由于不支持 CSV 输出的版本也不允许将 FS 中的所有文件的信息作为一个整体转储,因此该脚本使用 SSH 连接到目标 Data Domain 以遍历 MTree 列表(一次运行一个 MTree 的文件转储以收集所有 MTree 的文件列表),然后转换为可以进一步处理的 CSV 格式:
#!/bin/bash

#### WARNING
####     This script is provided to you by Dell Technologies with NO GUARANTEE, as best-effort sample code to get a full FS sfs-dump collected
####     for DDOS releases which do not support "se sfs-dump", or as an alternative to it, in releases which support "filesys fs-dump"
####     That this script does not work for you, or if you need help setting it up, extending it, or resolving any issues, is not entitled to support
####     This script is not part of Dell PowerProtect / Data Domain, and hence it is not supported

#### Replace values below to suit your needs
USERNAME="sysadmin"
DD_HOSTNAME="10.60.36.172"
#### NO CHANGES NEEDED BEYOND THIS POINT

clear
echo "Script collects a full FS sfs-dump from \"${DD_HOSTNAME}\", using the command \"filesys sfs-dump\", one MTree at a time"
echo "    * Script has to be configured by settting the \"USERNAME\" and \"DD_HOSTNAME\" variables within the top of the script"
echo "    * Script expects passwordless SSH connection as \"USERNAME\" to the \"DD_HOSTNAME\" configured"
echo "    * To configure passwordless SSH login to a DataDomain, check KB at https://www.dell.com/support/kbdoc/000004033 "
echo "    * Test passwordless login is configured and working prior to going ahead with this script"
echo "    * If passwordless login is not configured, script will ask for the \"${USERNAME}\" password "
echo "          - Once for getting the MTree list"
echo "          - And once for each one of the MTrees in \"${DD_HOSTNAME}\" "
echo
echo -n "Are you sure you want to continue? (y/n) : "
read -n 1 answer
echo
if [ "${answer}" = "y" ]; then
    echo "Going ahead with the script."
    echo
else
    echo "Stopping script now. Re-run when passwordless login to \"${DD_HOSTNAME}\" as \"${USERNAME}\" works. Bye."
    exit 1
fi

echo -n "1/6 : Collecting list of MTrees from DD..."
ssh ${USERNAME}@${DD_HOSTNAME} "mtree list" 2>/dev/null | grep ^/ | awk '{print $(NF-3)}' > mtree-list.txt
echo "Done."

n_mtrees=$( wc -l mtree-list.txt | cut -d" "  -f1 )
echo -n "2/6 : Collecting per-Mtree sfs-dump information for ${n_mtrees} MTrees ..."
for mtree in `cat mtree-list.txt`; do
    name=$(echo $mtree | cut -d/ -f4)
    ssh ${USERNAME}@${DD_HOSTNAME} "filesys sfs-dump mtree ${mtree}" 2>/dev/null | grep ^/ > sfs-dump-${name}.txt
    echo -n "."
done
echo "Done."

echo -n "3/6 : Putting all the files together..."
for file in `ls sfs-dump-*.txt`; do 
    if [ -s "${file}" ]; then cat ${file} >> sfs-dump-noCSV.txt; fi
done
echo "Done."

echo -n "4/6 : Converting sfs-dump output to CSV format..."
cat sfs-dump-noCSV.txt | grep ^/ | grep -v ^$ | awk '
BEGIN {print "name\tmtime\tfileid\tsize\tseg_bytes\tseg_count\tredun_seg_count\tpre_lc_size\tpost_lc_size"}
{
    colon_index = index($0, ":")
    filename = substr($0, 1, colon_index - 1)
    gsub(/^[[:space:]]+|[[:space:]]+$/, "", filename)
    n = split(substr($0, colon_index + 1), fields, " ")
    print filename "\t" fields[2] "\t" fields[4] "\t" fields[6] "\t" fields[10] "\t" fields[12] "\t" fields[14] "\t" fields[17] "\t" fields[19]
}' > sfs-dump-CSV.csv
echo "Done."

echo -n "5/6 : Cleaning up..."
for mtree in `cat mtree-list.txt`; do name=$(echo $mtree | cut -d/ -f4); rm -f sfs-dump-${name}.txt ; done
rm sfs-dump-noCSV.txt
rm mtree-list.txt
echo "Done."


echo -n "6/6 : Summary"
echo
n_files=$( wc -l sfs-dump-CSV.csv | cut -d" "  -f1 )
echo
echo "Collecting whole FS sfs-dump data from ${HOSTNAME} completed"
echo "File includes output for ${n_mtrees} MTrees, with a combined $(( ${n_files} - 1 )) files across Active and Cloud Tiers (if applicable)"
echo "Start of file shown below for your convenience :"
echo "===================="
head -5 sfs-dump-CSV.csv
echo "===================="
echo
echo "Done."

exit 0

用于将非 CSV“sfs-dump”和“filesys report generate file-location”的输出合并为 CSV 文件的脚本,该文件包含与上文脚本相同的所有信息以及每个文件层和放置时间信息

以下脚本由戴尔按原样(不作任何保证)提供给用户,以期为上面的 sfs_dump 和 filesys report generate file-location 命令的输出增加价值。用户可以基于层(活动或上面两个配置的云单元中的任何一个)筛选文件,以便通过将层位置和放置时间信息添加到输出 CSV 中的每个文件条目来更精确地了解每层的文件分布情况。

脚本需要使用 sfs-dump(不是 sfs_dump -c)输出作为第一个参数,filesys report generate file-location 输出作为第二个参数。输出写入硬编码文件名“sfs-dump-output-tiers.csv”,可以在脚本本身内更改。

可以使用 Excel,通过上文所述的相同方式处理输出。
#!/bin/bash

#### WARNING
####     This script is provided to you by Dell Technologies with NO GUARANTEE, as best-effort sample code to match the output from commands :
####       * sfs-dump (in non CSV format)
####       * filesys report generate file-location
####     So that a new CSV with the file paths appearing on both is created for all the data in sfs-dump file with the added tier and placement time information from location report
####
####     This script is not part of Dell PowerProtect / Data Domain, and hence it is not supported
####
####     Usage : extend-sfs-dump-with-tier.sh sfs-dump-output.csv file-location-output.log
####     Output : static "sfs-dump-output-tiers.csv" file name (may be changed below)

#### Replace values below to suit your needs
OUTPUT_FILENAME="sfs-dump-output-tiers.csv"
#### NO CHANGES NEEDED BEYOND THIS POINT

clear

if [ ! $# == 2 ]; then
    echo "Combine output from sfs-dump and tier location report into a CSV file with tier and placement time information"
    echo
    echo "Usage : $0 SFS-DUMP-OUTPUT-FILE    REPORT-FILE-LOCATION-FILE"
    echo "NOTE : SFS-DUMP-OUTPUT-FILE has to be in non-CSV format"
    exit 1
fi

INPUT_SFSDUMP="$1"
INPUT_LOCATION="$2"


echo -n "1/6 : Sanity checking input files..."
if [ ! -s "${INPUT_SFSDUMP}" ]; then
    echo "Input file ${INPUT_SFSDUMP} does not exist"
    exit 1
fi
if [ ! -s "${INPUT_LOCATION}" ]; then
    echo "Input file ${INPUT_LOCATION} does not exist"
    exit 1
fi
n_files_sfsdump=`grep ^/ ${INPUT_SFSDUMP} | wc -l`
n_files_location=`grep ^/ ${INPUT_LOCATION} | wc -l`
if [ ${n_files_sfsdump} -eq ${n_files_location} ]; then
    echo -n "both have the same amount of files (${n_files_location}). "
else
    echo -n "sfs-dump has ${n_files_sfsdump} files whereas location report has ${n_files_location} files, this may be normal if the difference is small. "
fi
echo "Done."


echo -n "2/6 : Sanitize \"file-location\" input..."
cat ${INPUT_LOCATION} | awk 'BEGIN {rejected="temp-location-rejected.log"; accepted="temp-location-accepted.log"} { if ( $0 ~ "Missing -unit") { gsub(/Missing -unit/, "Missing-Cloud-Unit", $0); print $0 > rejected } else { if ($0 ~ "^/" ) print $0 > accepted } }'
if [ -s "temp-location-rejected.log" ]; then
    REJECTS_EXIST="yes"
    echo -n "Some files in location report sit in unavailable or deleted cloud units, you may need to re-run this script after fixing the issue and gathering a new location report. "
    cat temp-location-rejected.log temp-location-accepted.log | sed -e 's/\t/:\t/' | sort > temp-location-report-sorted.log
    rm temp-location-rejected.log
else
    cat temp-location-accepted.log | sed -e 's/\t/:\t/' | sort > temp-location-report-sorted.log
    REJECTS_EXIST="no"
fi
rm temp-location-accepted.log
echo "Done."


echo -n "3/6 : Sanitize \"sfs-dump\" input..."
cat ${INPUT_SFSDUMP} | grep ^/ | sort > temp-sfs-dump.log
echo "Done."


echo -n "4/6 : Merging information for sfs-dump and location report..."
join -1 1 -2 1 temp-sfs-dump.log temp-location-report-sorted.log > temp-merged-information.log
rm temp-sfs-dump.log
rm temp-location-report-sorted.log
n_files_combined=`grep ^/ temp-merged-information.log | wc -l`
if [ ${n_files_combined} -eq 0 ]; then
    echo "No files matched from input files. sfs-dump output must NOT be in CSV format. Exiting."
    rm temp-merged-information.log
    exit 1
fi
echo -n "Input files matched on ${n_files_combined} files. "
echo "Done."


echo -n "5/6 : Converting merged sfs-dump / location-report output to CSV format..."
cat temp-merged-information.log | grep ^/ | grep -v ^$ | awk '
BEGIN {print "name\tmtime\tfileid\tsize\tseg_bytes\tseg_count\tredun_seg_count\tpre_lc_size\tpost_lc_size\ttier\tplacement_time"}
{
    colon_index = index($0, ":")
    filename = substr($0, 1, colon_index - 1)
    gsub(/^[[:space:]]+|[[:space:]]+$/, "", filename)
    n = split(substr($0, colon_index + 1), fields, " ")
    print filename "\t" fields[2] "\t" fields[4] "\t" fields[6] "\t" fields[10] "\t" fields[12] "\t" fields[14] "\t" fields[17] "\t" fields[19] "\t" fields[27] \
        "\t" fields[length(fields)-4] " " fields[length(fields)-3] " " fields[length(fields)-2] " " fields[length(fields)-1] " " fields[length(fields)]
}' > ${OUTPUT_FILENAME}
rm temp-merged-information.log
echo "Done."


echo -n "6/6 : Summary"
echo
echo
echo "Merging information from sfs-dump (${INPUT_SFSDUMP}) and location-report ${INPUT_LOCATION} output completed."
echo "Output file (${OUTPUT_FILENAME}) includes information for a total ${n_files_combined} files, out of ${n_files_sfsdump} in input sfs-dump, and ${n_files_location} in input location report."
if [ "${REJECTS_EXIST}" == "yes" ]; then
    echo "Note there are some files in disconnected or deleted cloud units, for which the \"tier\" field has been replaced with \"Missing-Cloud-Unit\"."
fi
echo
echo "Start of file shown below for your convenience :"
echo "===================="
head -5 ${OUTPUT_FILENAME}
echo "===================="
echo
echo "You may follow the instructions in https://www.dell.com/support/kbdoc/000081345 to process this CSV file in an spreadhseet"
echo
echo "Done."

exit 0


对于 Veritas NetBackup 用户:

在 Data Domain 中创建文件时,Veritas NetBackup (NBU) 在文件名中使用冒号字符。例如,当 Data Domain 用作 NBU 的后端存储时,以下是有效的 NBU 文件名路径:
/data/col1/MTREE_NAME/POLICY-NAME_1400502741_C1_F1:1400502741:VM_PRD-02:4:1::
/data/col1/MTREE_NAME/POLICY-NAME_1400502741_C1_F2:1400502741:VM_PRD-02:4:1::
/data/col1/MTREE_NAME/POLICY-NAME_1400502741_C1_HDR:1400502741:VM_PRD-02:4:1::
这给上面的示例脚本带来了问题,因为冒号字符用作 sfs_dump 命令输出的分隔符,运行上面的脚本将产生错误的结果。

对于此类情况,您必须采用如下方式编辑脚本:
--- iterate-dd-for-fs-sfs-dump.sh       2024-01-23 06:32:16.521409000 -0500
+++ iterate-dd-for-fs-sfs-dump-NBU.sh   2024-02-27 03:26:42.808246000 -0500
@@ -55,11 +55,11 @@
 cat sfs-dump-noCSV.txt | grep ^/ | grep -v ^$ | awk '
 BEGIN {print "name\tmtime\tfileid\tsize\tseg_bytes\tseg_count\tredun_seg_count\tpre_lc_size\tpost_lc_size"}
 {
-    colon_index = index($0, ":")
-    filename = substr($0, 1, colon_index - 1)
+    colon_index = index($0, ":::")
+    filename = substr($0, 1, colon_index + 1)
     gsub(/^[[:space:]]+|[[:space:]]+$/, "", filename)
     n = split(substr($0, colon_index + 1), fields, " ")
-    print filename "\t" fields[2] "\t" fields[4] "\t" fields[6] "\t" fields[10] "\t" fields[12] "\t" fields[14] "\t" fields[17] "\t" fields[19]
+    print filename "\t" fields[3] "\t" fields[5] "\t" fields[7] "\t" fields[11] "\t" fields[13] "\t" fields[15] "\t" fields[18] "\t" fields[20] "\t"
 }' > sfs-dump-CSV.csv
 echo "Done."
更改会共享以便脚本遍历 Data Domain 中的所有 MTree 以拉取每个 MTree 的 sfs_dump 数据,这些更改对于其他脚本也是相同的。但是,由于对于脚本本身也是如此,上述更改由戴尔为您提供(不作任何保证),希望它们对您有用。

受影響的產品

Data Domain

產品

Data Domain
文章屬性
文章編號: 000081345
文章類型: Solution
上次修改時間: 27 5月 2025
版本:  21
向其他 Dell 使用者尋求您問題的答案
支援服務
檢查您的裝置是否在支援服務的涵蓋範圍內。