Data Domain:如何使用 sfs-dump 列出 Data Domain 文件系统上的文件
Summary: 本文介绍如何使用 Data Domain 命令行界面 (CLI) 转储单个 MTree 或整个文件系统 (FS) 的文件和目录列表。
Symptoms
无论接收的协议是什么,Data Domain FS 都只包含以 MTree 形式组织的文件(在目录中)。所有文件(包括活动层和任何云单元中的文件)共享相同的根和命名空间;存在单个命名空间,这意味着文件和目录列表不加区分地包括活动层和云单元中的文件。
由于以下原因,获取详细的文件转储会非常有用:
-
与备份应用程序管理的文件列表进行比较,以检查该备份应用程序中是否有孤立的文件。
-
列出超过特定存储时长阈值的所有文件,以确定备份应用程序是否正常执行备份保留
Cause
用于创建文件列表的 CLI 工具是 sfs_dump.
Resolution
使用 SSH 会话日志记录收集列表输出。从 DD CLI 运行以收集文件列表的确切命令取决于正在使用的 Data Domain 操作系统 (DDOS) 版本。
快速链接
- 为 7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 之前的 DDOS 版本创建列表
- 为 DDOS 版本 7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 或更高版本创建列表
- 为 DDOS 版本 8.1.0.0、7.13.1.10、7.10.1.30 和 7.7.5.40 或更高版本创建列表
- 将列表转换为 CSV 文件
- 将 CSV 格式的sfs_dump输出导入电子表格
要从 CLI 获取 Data Domain 中文件的详细列表,并最终获取有关存储在 Data Domain 中的文件的 情报 的过程取决于正在运行的 DDOS 版本。
收集包含文件详细信息的文本输出文件后,将输出处理为更可用的格式始终相同,因为所有 DDOS 版本的输出格式都相同(或者可以使用脚本转换为通用格式)。
SSH 会话日志记录:
所有 DDOS 版本的共同点是要求以管理员用户身份登录到 Data Domain,并使用 SSH 客户端执行此操作,该客户端支持将控制台输出记录到客户端上的文本文件(PuTTY 适用于此情况)。配置 SSH 客户端,使其将输出记录到客户端上的文本文件(确保记录的行数或单个行长度没有限制)。SSH 会话日志文件(以及 DD 文件列表)不会写入 Data Domain,而是写入(通常)启动 SSH 连接的(通常)桌面客户端上。
收集 SSH 会话输出时,确保为文件指定一个有意义的名称(例如添加 Data Domain 主机名和要转储的 MTree 名称),并确保日志文件有足够的空间(对于具有 100 万个文件的 Data Domain,此空间大约为 200 MB)。
7.13.0.0、7.10.1.15、7.7.5.25 和 6.2.1.110 之前的 DDOS 版本:
这些版本仍支持 se sfs_dump 命令(以及 -c 选项,将文件详细信息直接输出为 CSV,而不进行任何进一步处理),但出于安全原因不建议进入支持工程师 (SE) 模式,而是应升级到可用的最新 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 或更高版本:
要列出的 MTree 位于关键字“MTree”之后:
# filesys sfs-dump mtree <mtree-path>
filesys sfs_dum 命令(与 se sfs_dump管理此进程:
- 新命令不支持使用
-c选项将文件信息转储为 CSV(列)格式 - 新命令一次只能运行一个 MTree,不支持在一次调用中针对整个 FS 运行
如果需要将所有 MTree 的文件详细信息转储到文件,请循环访问 Data Domain FS 中的整个 MTree 列表,并为每个 MTree 运行一次命令。用户可以通过运行以下命令来获取系统中的 MTree 列表:
# mtree list
以管理员用户身份登录 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 或更高版本:
filesys fs-dump管理此进程:
- 可以添加
-c选项,以类似 CSV 的格式版本打印输出(字段由列分隔) - 可以针对 FS 中的所有文件同时运行文件转储信息
- 使用 ssh 会话日志记录 来收集输出。
命令仍然与之前的版本相同,但具有所提及的增强功能,总结如下:
#### 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_dump 或 filesys sfs-dump 数据处理成有用的东西:
使用 filesys sfs-dump 或 sfs_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 字节) - 文件本地压缩(也称为“l
comp“是系数 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 选项示例显示的文件相比,这个示例没有实现重复数据消除(无冗余数据段),也没有实现任何本地压缩。这表示该文件是压缩文件。
post_lc_size 是一个指定的值,并不意味着该文件使用的磁盘空间等于该容量,因为在单个文件级别上没有考虑许多 FS 级别的开销。其限制与以下命令的已知限制相同:
mtree show compression利用上述输出文件中的信息包括以适合用户目标的方式处理数值数据。应用场景的一些示例包括:
- 确定
gcomp和lcomp与特定路径对应的文件(如果路径可以匹配到某个特定的备份服务器、客户端、策略、作业等) - 计算多少数据 (
pre-comp) 存储在早于给定时间的给定位置(以确定孤立项或解决备份应用程序未使备份过期过期的问题) - 可能有用的任何其他类型的统计数据
sfs_dump -c 选项 在较新的版本中,我们的建议是将输出数据转换为上面的CSV格式,然后使用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
超出此时间点的所有内容均按原样提供给用户。对于下面分享的说明,戴尔方面不作任何保证,也不承担任何义务。从文件列表详细信息中获取情报是用户的任务,如何实现这一目标完全取决于用于挖掘文件转储输出中的数据的工具集、要实现的目标以及用户自己在处理上述命令输出中的数据方面的专业知识。一个用户可能会选择使用文本文件的 Linux 命令行处理来转储一些聚合,其他用户可能会选择使用“gnuplot”为图表值生成输入,而大多数用户被认为寻求一种更简单(但有限)的方法,从 CSV 文件构建电子表格进行分析。
戴尔已努力确保以下说明正确、可行且对用户有用,但不能保证它们有效,也无法保证提供支持,因为它们不在支持范围之内。
将 CSV 格式的sfs_dump输出导入电子表格(Excel 示例):
获得 CSV 版本的文件详细信息列表后,从数据中获取情报的一种方法是将数据加载到电子表格软件中。这里使用 Microsoft Excel 作为示例,其他软件的说明应该与此类似。要将 CSV 文本文件作为 CSV 导入到 Excel 中,请执行以下步骤:
- 打开 Excel 并创建一个新的空白电子表格
- 单击顶部的数据菜单,然后单击名为从文本/CSV 的图标
- 使用对话框找到 CSV 格式的文件数据(
sfs-dump-CSV.csv,如非 CSV 格式的转换脚本示例中所示),选择该文件,然后单击导入 - 如果输入文件格式正确,并且 Excel 可以从前 200 行生成格式(它应该这样做),则对话框应显示要生成的电子表格的预览。查看信息以确保它看起来正常,包括将第一行检测为标头
- 如果预览看起来一切正常,请单击对话框底部的 “加载 ”按钮,新的电子表格将以漂亮的格式显示,并且字段标题变成了搜索和过滤器启用的标题。
电子表格中的数据已经很有用,例如对大小等数值字段应用数字筛选器(仅显示给定大小以上的文件),或在名称字段上应用文本筛选器,以便仅显示 Data Domain 文件中与给定模式匹配的文件详细信息输出(仅以特定 MTree 的路径开头的文件)。 并根据该数据进行其他派生计算。
正确导入的 Excel 电子表格应在 A-I 列中包含数据。如果数据仅存在于 A 列中,但在整个屏幕上延伸,则关闭 Excel 并重试上述步骤 1 至 5。
添加额外的计算字段:
用户可以根据需要,使用任意数量的计算字段扩展电子表格。例如,添加与文件的 mtime(上次修改时间,通常是写入 DD 的时间)相对应的人类可读日期和时间字段。此外,根据数据的用途,计算并显示每个文件的一些压缩值可能会很有用。新列将使用 Excel 公式自动填充,如下所述。
时间戳转换:
要将 UNIX 格式的时间戳转换为人类可读的日期和时间,请执行以下操作:
- 右键单击单元格 J2,选择设置单元格格式
- 在左侧的分类列表中,选择自定义。
- 如果其中没有人类可读的日期时间格式,则创建该格式(示例在末尾包含 EST 字符串。它可以替换为您的文本时区定义,或者如果不感兴趣,则完全删除“EST”):yyyy-mm-dd hh:mm:ss “EST”
- 完成后单击“确定”。现在,单元格 J2 具有自定义数据格式。
- 将以下公式添加到单元格 J2。在公式中,将 (-6*3600) 替换为在获取“sfs-dump”数据时与 Data Domain 中配置的时区的 UTC 对应的正确时区差异。例如,在夏季,美国东部时间比 UTC 晚 6 小时,因此替换为“-6”。
(((B2/1000000000+(-6*3600))/86400)+25569) (((B2/1000000000)/86400)+25569)
- 将公式粘贴到单元格 J2 以及电子表格中其余行的每个单元格
- 针对整个电子表格计算公式,并以配置的格式显示日期和时间值
- 将列的格式设置为现有列,并将标题配置为可以应用日期筛选器的日期,唯一要做的就是为列设置适当的名称(日期)
压缩信息:
可以通过执行上述操作,为每个文件的压缩信息添加列。这一次,公式显示包括 “=”,因此必须复制整个文本,然后选择 “选择性粘贴”作为文本:
- 复制以下公式并将 “Paste Special as Text”粘贴到单元格 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 天的文件:
- 单击名称标题中的向下箭头,选择文本筛选,然后选择开头是并在文本框中键入
/data/col1/backup/。不要遗漏尾部斜杠。单击确定 - 单击最后写入日期标题中的向下箭头,选择日期筛选,然后选择之前。使用对话框右侧的日期选择器选择 30 天前的日期。单击确定。
Additional Information
转储文件位置的命令(活动和云)
有一种方法可以转储文件列表并显示哪些文件位于活动层,哪些文件位于云单元中,即:
#### 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 来说,输出可能太大,在这种情况下,可以使用 拆分 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.n.n.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 数据,这些更改对于其他脚本也是相同的。但是,由于脚本本身也是如此,上述更改由戴尔提供,不提供任何保证,希望它们有用。