gsutil rsync 尝试在将源迁移到新存储后重新上传所有内容

Posted

技术标签:

【中文标题】gsutil rsync 尝试在将源迁移到新存储后重新上传所有内容【英文标题】:gsutil rsync tries to re-upload everything after migrating source to new storage 【发布时间】:2021-03-14 22:07:19 【问题描述】:

我有一个相当大的 (~1 TB) 目录,该目录已经在 google 存档存储上进行了备份。由于本地计算机上的空间原因,我不得不将目录迁移到其他地方,但是现在当我尝试运行将其同步到云的脚本(使用新目录作为源)时,它会尝试上传所有内容。我猜问题出在迁移文件的时间戳上,因为当我尝试使用“-c”(CRC 比较)时,它可以正常工作,但速度太慢而无法使用(即使使用已编译的 CRC)。

通过手动检查时间戳,它们似乎被很好地复制了(使用robocopy /mir 进行迁移),那么究竟是什么时间戳让 gsutil.. 感到不安/困惑?

我看到了几种解决方法:

    找到一种方法在副本中保留原始时间戳(我仍然有原始文件夹,所以这是一个选项) 以某种方式说服 gsutil 仅修补云文件的时间戳或退回到仅大小 咬紧牙关重新上传所有内容

将不胜感激任何建议。

用于迁移的命令:

robocopy SOURCE TARGET /mir /unilog+:robocopy.log /tee

也试过了:

robocopy SOURCE TARGET /mir /COPY:DAT /DCOPY:T /unilog+:robocopy.log /tee

用于与 google 同步的命令:

gsutil -m rsync -r "source" "gs://MYBUCKET/target"

【问题讨论】:

【参考方案1】:

事实证明,即使您尝试同步时间戳,它们最终也会有所不同:

>>> os.stat(r'file.copy')
nt.stat_result(st_mode=33206, ... st_size=1220431L, st_atime=1606987626L, st_mtime=1257521848L, st_ctime=1512570325L)
>>> os.stat(r'file.original')
nt.stat_result(st_mode=33206, ... st_size=1220431L, st_atime=1606987624L, st_mtime=1257521847L, st_ctime=1512570325L)

可以清楚地看到 mtime 和 atime 只是略微偏离(稍后)

尝试同步它们:

>>> os.utime(r'file.copy', (1606987626, 1257521847))
>>> os.stat(r'file.copy')
nt.stat_result(st_mode=33206, ... st_size=1220431L, st_atime=1606987626L, st_mtime=1257521848L, st_ctime=1512570325L)

导致 mtime 仍然关闭,但如果我再往前一点:

>>> os.utime(r'file.copy', (1606987626, 1257521845))
>>> os.stat(r'file.copy')
nt.stat_result(st_mode=33206, ... st_size=1220431L, st_atime=1606987626L, st_mtime=1257521846L, st_ctime=1512570325L)

它改变了,但仍然不准确。

但是,现在在及时收回后,我可以使用“-u”开关忽略目标中较新的文件:

gsutil -m rsync -u -r "source" "gs://MYBUCKET/target"

修复目标中所有文件的时间戳的脚本:

import os

SOURCE = r'source'
TARGET = r'target'

file_count = 0
diff_count = 0

for root, dirs, files in os.walk(SOURCE):
    for name in files:
        file_count += 1
        source_filename = os.path.join(root, name)
        target_filename = source_filename.replace(SOURCE, TARGET)
        try:
            source_stat = os.stat(source_filename)
            target_stat = os.stat(target_filename)
        except WindowsError:
            continue

        delta = 0
        while source_stat.st_mtime < target_stat.st_mtime:
            diff_count += 1
            #print source_filename, source_stat
            #print target_filename, target_stat
            print 'patching', target_filename
            os.utime(target_filename, (source_stat.st_atime, source_stat.st_mtime-delta))
            target_stat = os.stat(target_filename)
            delta += 1

print file_count, diff_count

它远非完美,但运行该命令不再导致所有内容都尝试同步。希望有人会觉得有用,仍然欢迎其他解决方案。

【讨论】:

以上是关于gsutil rsync 尝试在将源迁移到新存储后重新上传所有内容的主要内容,如果未能解决你的问题,请参考以下文章

GSUtil rsync 在 S3 存储桶上给出 400 不可​​重试异常

从谷歌云存储到 s3 的 gsutil rsync 挂在大文件上

gsutil - 使用联合用户 AWS 密钥时 cp、rsync 的问题

gsutil rsync Google Store 与 AWS S3 400 ExcessHeaderValues

如何跳过 gsutil rsync 中的现有文件

使用 gsutil rsync 更新从 Google 存储桶提供的静态网站的内容