BareOS的增量备份大小过大

我有一个BareOS安装,对默认configuration文件的修改很less。 有正在执行的完整,增量和差异备份。 大多数客户似乎正在按预期备份。

但是,我的一个客户似乎在每个增量周期中多次备份整个文件系统的10%以上。

如何查找正在重复备份的最大文件和文件夹?

BAT在这里看起来不是很有用,因为它只列出了文件节点本身的大小,而不是整个文件夹的大小。 我正在有效地寻找一个在BareOS框架内工作的du命令来进行特定的备份尝试。

请注意,在第一部分的最后添加了一个重要的更新


不幸的是,即使很容易检查一个特定的备份发生了什么事情,获取备份文件的文件大小并不是那么容易。

让我们深入一些例子。

在我的情况,从bconsole我可以得到最后的工作列表:

 *list jobs Automatically selected Catalog: CatalogoBareos Using Catalog "CatalogoBareos" +-------+------------------------+---------------------+------+-------+------------+-------------------+-----------+ | JobId | Name | StartTime | Type | Level | JobFiles | JobBytes | JobStatus | +-------+------------------------+---------------------+------+-------+------------+-------------------+-----------+ [...] | 7,060 | backup-XXXXXXXX | 2016-01-02 16:00:50 | B | I | 2 | 74,225,116 | T | | 7,062 | backup-YYY | 2016-01-02 16:04:47 | B | F | 890,482 | 181,800,839,481 | T | [...] +-------+------------------------+---------------------+------+-------+------------+-------------------+-----------+ 

从上面,你可以看到两个工作:

  • 作业7060:一个“I”增量备份,有趣的2个文件共74MB的数据;
  • 作业7062:一个“F”ull备份,有趣的890492文件,总共181GB的数据;

让我们专注于Job 7060,因为它是一个渐进的。 让我们来看看哪些文件是备份的:

 *list files jobid=7060 c:/allXXX_Backup/PLONE/Backup_Plone.bkf c:/allXXX_Backup/PLONE/ +-------+-----------------+---------------------+------+-------+----------+------------+-----------+ | JobId | Name | StartTime | Type | Level | JobFiles | JobBytes | JobStatus | +-------+-----------------+---------------------+------+-------+----------+------------+-----------+ | 7,060 | backup-XXXXXXXX | 2016-01-02 16:00:50 | B | I | 2 | 74,225,116 | T | +-------+-----------------+---------------------+------+-------+----------+------------+-----------+ * 

所以Job 7060感兴趣的是一个文件(Backup_Plone.bkf)和一个目录(包含的文件夹)。

不幸的是,正如你所看到的, list files jobid=7060的输出不会显示你需要的文件大小,所以…..希望这很有用,但是不能解决你的问题。

让我们继续前进。

我已经走过了这个系统的官方文档 ,无法find从bconsole中获取“filesize”的正确方法。 所以我决定采取沉重的方式:直接对目录进行SQL访问。

注意:在处理直接访问目录时请特别小心,因为每一个不合适的操作都可能导致严重的损坏,并造成相关的数据丢失!

一旦连接到数据库引擎(MySQL,在我的情况….但这是一个细节,因为与PostgreSQL是一样的),我看到备份文件元数据存储(…等)在:

  • File表:它主要存储所有的元数据,除了…
  • Filename名表:它存储备份文件的文件名
  • Path表:它存储备份文件的完整path

有一个很大的惊喜,我发现File表不包含size字段。 所以用一个简单的查询就不可能得到我们需要的东西。 无论如何,我发现了一个有趣的LStat字段(稍后更多)。

所以我启动了下面的SQL查询:

 select f.JobId,f.LStat,f.MD5, fn.Name, p.Path from Filename fn, File f, Path p where f.JobId=7060 and fn.FilenameId = f.FilenameId and p.PathId = f.PathId 

并得到以下结果:

 mysql> select f.JobId,f.LStat,f.MD5, fn.Name, p.Path -> from -> Filename fn, -> File f, -> Path p -> where -> f.JobId=7060 and -> fn.FilenameId = f.FilenameId and -> p.PathId = f.PathId -> ; +-------+------------------------------------------------------+------------------------+------------------+-------------------------+ | JobId | LStat | MD5 | Name | Path | +-------+------------------------------------------------------+------------------------+------------------+-------------------------+ | 7060 | AA IH/ BAAA EbJQA AA BWheFw BWheFw BTD/En AAL | 8ZuPGwdo9JYJileo+sVlfg | Backup_Plone.bkf | c:/all***_Backup/PLONE/ | | 7060 | AA EH/ BAAAAAA BWhRjY BWgz4o BTD/En AAL | 0 | | c:/all***_Backup/PLONE/ | +-------+------------------------------------------------------+------------------------+------------------+-------------------------+ 2 rows in set (0.00 sec) 

至于LStat字段,在官方的BareOS开发者指南中我看到:

 > Column Name Data Type Remark > [...] > LStat tinyblob File attributes in base64 encoding 

所以,现在的问题是:

  • LStat是否包含文件大小?

而且,我敢打赌“是的!绝对!”:

  • 如何从LStatstring中检索FileSize?

快速search“BareOS LStat”使我得到了几个结果。 几秒钟后,我得到了这个线程,包括几个有关LStat字段的评论,包括一个小PERL脚本来正确解码它。 在这里( * Brian McDonald ,2005 *提供 ),稍作修改以更好地满足您的需求:

 #!/usr/bin/perl my $base64_digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; my $base64_values = { }; my $val = 0; foreach my $letter ( split(//, $base64_digits ) ) { $base64_values->{ $letter } = $val++; } print "Please, enter your LSTAT string:"; my $lstat = <STDIN>; my $vals = decode_stats($lstat); print "Here are the results:\n"; foreach my $key (keys %{$vals}) { printf("%15s: %s\n",$key, $$vals{$key}) ; } exit; sub decode_stats { my $stats = shift; my $hash = { }; # The stats data is in base64 format. Yuck! - I mean Yay! # Each value is base64 encoded incorrectly, a deficiency we have # to correct here. In particular, some values are encoded with a single # base64 character. This results in a 6 bit value, and you have to # understand how bacula padded and manipulated those values before storing # them in the DB. # the fields are, in order: my @fields = qw( st_dev st_ino st_mode st_nlink st_uid st_gid st_rdev st_size st_blksize st_blocks st_atime st_mtime st_ctime LinkFI st_flags data ); # Decoding this mess is based on reading src/lib/base64.c in bacula, in # particular the to_base64 function, which is how these got in the DB in # the first place. my $field_idx = 0; foreach my $element ( split( /\s+/, $stats ) ) { my $result = 0; for ( my $i = 0; $i<length($element); $i++ ) { if ($i) { $result <<= 6; } my $r = substr($element, $i, 1 ); $result += $base64_values->{$r}; } $hash->{ $fields[$field_idx] } = $result; $field_idx++; } return $hash; } 

在启动并给定LSTATstring时,会报告大量数据, 包括文件大小 (st_size,输出的最后一个字段):

 verzulli@iMac-Chiara:/tmp$ perl pp.pl Please, enter your LSTAT string:AA IH/ BAAA EbJQA AA BWheFw BWheFw BTD/En AAL Here are the results: LinkFI: 0 st_atime: 1451614576 st_ino: 0 st_flags: 0 st_mtime: 1451614576 st_dev: 0 st_nlink: 1 st_blksize: 0 st_blocks: 0 data: 11 st_gid: 0 st_mode: 33279 st_uid: 0 st_rdev: 0 st_ctime: 1393553703 st_size: 74224640 

所以,现在我们有了文件大小,但不幸的是,在单个查询中找不到单个备份作业的最大文件是容易的。

有几个解决scheme:

  • 如果您正在运行MySQL 5.6.1或更高版本,或者支持BASE_64编译/解码的DBMS引擎,则可以查询LSTAT的SUBSTR,然后让DB引擎将其解码为Base64值。 例如,看到这里

  • 你可以写一个存储过程。 实际上它应该已经存在于PostgreSQL中,至于这个 (谁声明:“ …为lstat字段添加了示例postgresql存储过程…. ”);

  • 你可以写一个小的PERL脚本,查询目录,并通过解码的东西

希望这将是足够的;-)


更新1

我刚刚发现了BVFS API的存在,明确地说“ …主要针对希望为Bareos开发新的GUI界面的开发人员… ”。

这些API提供了一组新的命令(所谓的“ 点命令 ”),包括一个有趣的.bvfs_lsfiles ,它在控制台上显示一些元数据, 包括LSTAT字段。 所以:

  1. 无需直接访问底层数据库/目录就可以获得LSTAT字段

另外,在BareOS 15.2中引入了新的“API模式2”,增加了对JSON输出的支持。 我刚刚testing过:

  1. 启用V.2 API后,由.bvfs_lsfiles返回的JSON对象包含正确解码的文件大小字段

这里举一个例子:

 *.bvfs_update Using Catalog "MyCatalog" *.bvfs_lsfiles path=/var/log/2016/01/06/ jobid=79 107131 34080 3614785 79 P0A CCMR IGA BAAA H1V BAA BI BWjIkK BWjJAx BWjJAx AAC shorewall.log 107131 34081 3614786 79 P0A CCMQ IGA BAAA BT1 BAA Q BWjIkK BWjI7p BWjI7p AAC system.log *.api 2 { "jsonrpc": "2.0", "id": null, "result": { "api": 2 } }* *.bvfs_lsfiles path=/var/log/2016/01/06/ jobid=79 { "jsonrpc": "2.0", "id": null, "result": { "files": [ { "type": "F", "stat": { "dev": 64768, "nlink": 1, "mode": 33152, "ino": 533265, "rdev": 0, "user": "root", "group": "root", "atime": 1452050698, "size": 32085, "mtime": 1452052529, "ctime": 1452052529 }, "pathid": 107131, "name": "shorewall.log", "fileid": 3614785, "filenameid": 34080, "jobid": 79, "lstat": "P0A CCMR IGA BAAA H1V BAA BI BWjIkK BWjJAx BWjJAx AAC", "linkfileindex": 0 }, { "type": "F", "stat": { "dev": 64768, "nlink": 1, "mode": 33152, "ino": 533264, "rdev": 0, "user": "root", "group": "root", "atime": 1452050698, "size": 5365, "mtime": 1452052201, "ctime": 1452052201 }, "pathid": 107131, "name": "system.log", "fileid": 3614786, "filenameid": 34081, "jobid": 79, "lstat": "P0A CCMQ IGA BAAA BT1 BAA Q BWjIkK BWjI7p BWjI7p AAC", "linkfileindex": 0 } ] } }* 

所以,最后,最近的版本是BareOS,原来的问题似乎是可以解决的, 而不需要直接访问目录。

当我欣赏@ damiano-verzulli的努力时,在FreeNode的BareOS IRC频道上的讨论避开了这个回应:

事实certificate,Kjetil Torgrim Homme已经写了一个脚本来做这个,叫做bacula-du 。 (还有其他一些有用的脚本!)

他们都从这里列出和获得:

http://heim.ifi.uio.no/kjetilho/hacks/

特别是bacula-du被解释为:

 Usage: bacula-du [OPTIONS] -j JOBID Summarize disk usage of directories included in the backup JOBID Main options are: -a, --all write counts for all files, not just directories -S, --separate-dirs do not include size of subdirectories -t, --threshold=SIZE skip output for files or directories with usage below SIZE. default is 1 octet. -L, --largest=NUM only print NUM largest directories/files There is also an alternate mode which can be useful as a faster alternative to a verify job. Usage: bacula-du --md5sum -j JOBID --md5sum output list of all files in job in md5sum format 

bacula-du (版本1.4)

有一个小笔记,我不得不在这里添加。 为了这个工作,它必须有访问数据库(显然)。 在默认configuration中,它使用基于用户的安全机制,因此您必须以bareos用户的身份运行该命令才能工作,例如

 $ sudo -u bareos ./bacula-du -j 1429 done reading database. 807160 /log/ 6372 /var/openldap-data/ 6372 /var/ 813532 /admin/ ... 119983392 /