Aws-cli: AWS S3 同步不会同步所有文件

创建于 2018-04-18  ·  44评论  ·  资料来源: aws/aws-cli

我们有几十万个文件,S3 可以可靠地同步文件。 但是,我们注意到大约一年前有几个文件发生了变化,这些文件不同但不同步或更新。

源和目标时间戳也不同,但同步从未发生。 S3 有更新的文件。

命令如下
aws s3 s3://source /local-folder --delete

所有不同步的文件都具有相同的日期,但分布在多个不同的文件夹中。

是否有 S3 touch 命令来更改时间戳并可能使文件再次同步?

feature-request s3 s3sync s3syncstrategy

最有用的评论

我不敢相信这张票前一段时间没有关闭。 据我所知,它按设计工作,但用户(包括我)对它应该如何工作做出假设,然后当它表现得不像他们预期的那样时感到惊讶。

  • 当文件被同步或复制到 s3 时,它在存储桶上收到的时间戳是它被复制的日期,它_总是_比源文件的日期新。 这就是 s3 的工作方式。
  • 文件仅在大小更改或目标上的时间戳比源 _older_ 时才同步。
  • 这意味着如果源文件已更新但文件的大小保持不变,并且这些更改文件的日期早于上次复制时的日期,则 s3 同步将不会再次同步它们。
  • 从 s3 复制到本地时,使用--exact-timestamps _only_ 有效。 故意不为本地到 s3 启用它,因为时间戳 _never_ 相等。 所以在从本地同步到 s3 时设置它没有效果。
  • 我不认为 s3 计算上传文件的哈希值,因此无法避免文件大小和上次上传日期作为检查。

最重要的是,它可以按预期工作,但在各种用例中这是不可取的。 如上所述我使用s3 cp --recursive解决了它

所有44条评论

您可以使用--exact-timestamps来解决这个问题,但如果您正在上传,这可能会导致上传过多。

为了帮助复制,您能给我一些有关未同步文件之一的信息吗?

  • 本地的确切文件大小是多少?
  • S3 中的确切文件大小是多少?
  • 本地最后修改时间是几点?
  • S3中的最后修改时间是什么时候?
  • 本地文件是符号链接/在符号链接后面吗?

示例命令运行
aws s3 同步 s3://bucket/ /var/www/folder/ --delete

几个文件丢失
确切的本地大小:2625
确切的 s3:2625
当地的确切时间戳:06-Jan-2017 9:32:31
确切的时间戳 s3:20-Jun-2017 10:14:57
S3 和本地中的普通文件

在大约 50,000 个文件的列表中,有几个类似的情况。 然而,所有同步丢失的时间都是 2017 年 6 月 20 日的不同时间。

使用 --exact-timestamps 会显示更多要下载的文件,尽管它们的内容完全相同。 但是,他们仍然缺少上面示例中的那些。

同样的问题在这里。
aws s3 sync dist/ s3://bucket --delete没有使用 dist/index.html 上传 s3://bucket/index.html

dist/index.html 和 s3://bucket/index.html 文件大小相同,但修改时间不同。

实际上,有时 awscli 确实上传了文件,但有时却没有

同样在这里, --exact-timestamps没有帮助 - index.html不会被覆盖。

我们今天/上周遇到了这个问题。 再次 index.html 文件大小相同,但内容和修改次数不同。

有人知道解决方法吗?

我刚遇到这个。 与@icymind@samdammers报告的问题相同:我的(本地) index.html文件的内容已更改,但其文件大小与 S3 中的早期副本相同。 {{aws s3 sync}} 命令没有上传它。 我的“解决方法”是从 S3 中删除index.html ,然后再次运行同步(然后将它上传为一个新文件,我猜)。

服务器: EC2 linux
版本: aws-cli/1.16.108 Python/2.7.15 Linux/4.9.62-21.56.amzn1.x86_64 botocore/1.12.98


aws s3 sync运行超过 270T 的数据后,我丢失了几 GB 的文件。 同步根本不复制带有特殊字符的文件。

文件示例/data/company/storage/projects/1013815/3.Company Estimates/B. Estimates

不得不使用cp -R -n

同样的问题,相同大小但不同时间戳的 xml 文件没有正确同步

我能够重现这个问题

错误.tar.gz
下载附加的 tar 文件,然后

tar -zxvf bug.tar.gz
aws s3 sync a/ s3://<some-bucket-name>/<some_dir>/ --delete
aws s3 sync b/ s3://<some-bucket-name>/<some_dir>/ --delete

你会看到,即使目录 a 和 b 中的 repomd.xml 的内容和时间戳不同
尝试同步 b 没有任何作用

经过测试
aws-cli/1.16.88 Python/2.7.15 Darwin/16.7.0 botocore/1.12.78
aws-cli/1.16.109 Python/2.7.5 Linux/3.10.0-693.17.1.el7.x86_64 botocore/1.12.99

我看到了同样的问题。 尝试从 s3 同步文件目录,其中一个文件已更新到本地目录。 该文件未在本地目录中更新

我也在看这个。 就我而言,它是一个带有 index.html 的 React 应用程序,它指的是生成的 .js 文件。 我将它们与 --delete 选项同步以删除不再引用的旧文件。 index.html 有时不会上传,导致旧的 index.html 指向不再存在的 .js 文件。

因此我的网站停止工作!!!

我目前不知道为什么会发生这种情况。

有没有人有任何想法或解决方法?

我们有同样的问题,但刚刚找到了一个解决方法。 我知道,这不是最好的方法,但它有效:

aws s3 cp s3://SRC s3://DEST ...
aws s3 sync s3://SRC s3://DEST ... --delete

在我们看来,副本工作正常,所以首先我们复制,然后我们使用同步命令删除不再存在的文件。
希望问题能尽快得到解决。

我在我的管道中添加了--exact-timestamps并且问题没有再次出现。 但是,它首先是间歇性的,所以我不能确定它是否修复了它。 如果它再次发生,我会接受@marns93的建议。

我们遇到了这个问题, --exact-timestamps解决了我们的问题。 我不确定这是否完全相同的问题。

我看到了这个问题,这很明显,因为每次调用只需要复制少数(十几个)文件。

它发生的情况就像上面报告的一样:如果被sync编入的文件夹包含一个文件内容不同但文件大小相同的文件, sync将跳过从S3.

我们最终将脚本更改为aws s3 cp --recursive来修复它,但这是一个令人讨厌的错误——很长一段时间我们认为我们自己的应用程序中存在某种竞争条件,没有意识到 aws-cli 只是选择不复制更新的文件。

我在一个 html 文件中也看到了这一点

aws-cli/1.16.168 Python/3.6.0 Windows/2012ServerR2 botocore/1.12.158

我从 GitHub gist 复制粘贴了s3 sync命令,并在上面设置了--size-only 。 删除它解决了问题!

刚刚在将构建工件上传到存储桶时遇到了这个问题。 我们的 HTML 往往只更改资产链接的哈希码,因此大小始终相同。 如果构建在前一个构建之后过早,则 S3 同步会跳过这些。 例子:

10:01 - 构建 1 运行
10:05 - 构建 2 次运行
10:06 - Build 1 上传到 s3
10:10 - Build 2 上传到 s3

构建 2 具有时间戳为 10:05 的 HTML 文件,但是构建 1 上传到 s3 的 HTML 文件的时间戳为 10:06,因为这是创建对象的时间。 这导致它们被 s3 同步忽略,因为远程文件比本地文件“更新”。

我现在使用s3 cp --recursive后跟s3 sync --delete之前的建议。

希望这可能对某人有所帮助。

本周早些时候我遇到了同样的问题; 我没有使用--size-only 。 我们的 index.html 相差一个字符( .# ),所以大小是一样的,但是 s3 上的时间戳比新索引的时间戳早了 40 分钟.html。 我删除了 index.html 作为临时解决方法,但无法对每个部署进行双重检查。

此处相同,名称相同但时间戳和内容不同的文件不会从 S3 同步到本地,并且 --delete 没有帮助

我们遇到了同样的问题。 不会复制大小相同但时间戳较新的 index.html。

这个问题是一年多前报道的。 为什么不固定?

实际上它使 snyc 命令无用。

确切时间

--exact-timestamps 解决了这个问题

我也受到这个问题的影响。 我添加了 --exact-timestamps ,问题似乎修复了我正在查看的文件。 我没有进行详尽的搜索。 我有大约 100k 个文件和 20gb,比这里的其他人少得多。

我遇到了同样的问题, aws s3 sync跳过一些文件,即使内容和日期不同。 日志显示那些跳过的文件已同步但实际上并未同步。
但是当我再次运行aws s3 sync时,这些文件被同步了。 很奇怪!

我在使用 Hugo 构建网站时遇到了这个问题,我终于想通了。 我将子模块用于我的 Hugo 主题,并没有将它们拉到 CI 上。 这会在 Hugo 中引起警告,但不会导致失败。

# On local
                   | EN
-------------------+-----
  Pages            | 16
  Paginator pages  |  0
  Non-page files   |  0
  Static files     |  7
  Processed images |  0
  Aliases          |  7
  Sitemaps         |  1
  Cleaned          |  0

# On CI
                   | EN  
-------------------+-----
  Pages            |  7  
  Paginator pages  |  0  
  Non-page files   |  0  
  Static files     |  2  
  Processed images |  0  
  Aliases          |  0  
  Sitemaps         |  1  
  Cleaned          |  0  

一旦我更新了子模块,一切都按预期工作。

我们也受到了这个问题的影响,以至于在一个新的vendor/autoload.php文件没有同步后平台宕机了大约 18 小时,并且与vendor/composer/autoload_real.php过时了整个应用程序无法加载。

这是一个_非常_奇怪的问题,我不敢相信这个问题已经开放了这么久。

为什么同步不使用哈希而不是上次修改? 0 有意义。

对于未来的 Google 员工,我收到了一个经过编辑的错误:

PHP message: PHP Fatal error:  Uncaught Error: Class 'ComposerAutoloaderInitXXXXXXXXXXXXX' not found in /xxx/xxx/vendor/autoload.php:7
Stack trace:
#0 /xxx/xxx/bootstrap/app.php(3): require_once()
#1 /xxx/xxx/public/index.php(14): require('/xxx/xxx...')
#2 {main}
  thrown in /xxx/xxx/vendor/autoload.php on line 7" while reading response header from upstream: ...
---

同样的问题,并非所有文件都同步, --exact-timestamps没有帮助。

aws --version
aws-cli/1.18.22 Python/2.7.13 Linux/4.14.152-127.182.amzn2.x86_64 botocore/1.15.22

我不敢相信这张票开了这么久……同样的问题,亚马逊的客户痴迷在哪里?

我不敢相信这张票前一段时间没有关闭。 据我所知,它按设计工作,但用户(包括我)对它应该如何工作做出假设,然后当它表现得不像他们预期的那样时感到惊讶。

  • 当文件被同步或复制到 s3 时,它在存储桶上收到的时间戳是它被复制的日期,它_总是_比源文件的日期新。 这就是 s3 的工作方式。
  • 文件仅在大小更改或目标上的时间戳比源 _older_ 时才同步。
  • 这意味着如果源文件已更新但文件的大小保持不变,并且这些更改文件的日期早于上次复制时的日期,则 s3 同步将不会再次同步它们。
  • 从 s3 复制到本地时,使用--exact-timestamps _only_ 有效。 故意不为本地到 s3 启用它,因为时间戳 _never_ 相等。 所以在从本地同步到 s3 时设置它没有效果。
  • 我不认为 s3 计算上传文件的哈希值,因此无法避免文件大小和上次上传日期作为检查。

最重要的是,它可以按预期工作,但在各种用例中这是不可取的。 如上所述我使用s3 cp --recursive解决了它

@jam13感谢您的解释,现在事后看来这一切都是有道理的!

尽管如此,我认为它目前的记录很差(我原以为文档中会有一个红色警告,说明--exact-timestamps仅适用于 _from s3 到 local_ 并且 s3 cli 只是退出而不是静默忽略参数)和可选的基于哈希的比较模式是实现可靠工作同步模式所必需的。

是的,文档不是很好,默默地忽略选项是非常无益的。 在过去的 2 年中,AWS 没有对这张票进行任何管理甚至官方评论,这也说明了问题。

@jam13我深入研究了一些文档,发现我需要 --exact-timestamps 来规避从 s3 到本地的一些问题。 谢谢!

@kyleknap @KaibaLopez @stealthycoin关于这个有什么更新吗?

我不敢相信这张票前一段时间没有关闭。 据我所知,它按设计工作,但用户(包括我)对它应该如何工作做出假设,然后当它表现得不像他们预期的那样时感到惊讶。

* When a file is synced or copied _to_ s3, the timestamp it receives on the bucket is the date it was copied, which is _always_ newer than the date of the source file. This is just how s3 works.

* Files are only synced if the size changes, or the timestamp on the target is _older_ than the source.

* This means that if source files are updated but the size of the files remains unchanged and the dates on those changed files pre-date when they were last copied, s3 sync will not sync them again.

* Using `--exact-timestamps` _only_ works when copying from s3 to local. It is deliberately not enabled for local to s3 because the timestamps are _never_ equal. So setting it when syncing from local to s3 has no effect.

* I don't think s3 calculates hashes for uploaded files, so there's no way of avoiding file size and last uploaded date as checks.

最重要的是,它可以按预期工作,但在各种用例中这是不可取的。 如上所述我使用s3 cp --recursive解决了它

s3 确实对对象进行哈希处理,但如果您不是上传者ETag 。 问题在于 ETag 取决于上传文件时使用的块数和块大小。 如果您不是上传者,您可能不知道块大小(但可以从 ETag 获取块数)。 我不知道为什么要这样做。

这可能按预期工作,但没有按预期工作。 检查文件是否已更改应该很简单

这只是人们意外体验不同步的一个巨大问题
数据。 有 100 种不同的解决方法可以拯救这里的每个人
阅读这张票的时间,以及发现这个票所花费的时间
是他们源代码中的一个问题。 为什么他们不能做其中之一?

2020 年 4 月 14 日,星期二,下午 1:57,Keith Kelly通知@github.com
写道:

我不敢相信这张票前一段时间没有关闭。 尽我所能
告诉,它按设计工作,但用户(包括我)对
它应该如何工作,然后当它不像他们那样表现时感到惊讶
预期的。

  • 当文件被同步或复制到 s3 时,它在存储桶上收到的时间戳是它被复制的日期,它_总是_比源文件的日期新。 这就是 s3 的工作方式。

  • 文件仅在大小更改或目标上的时间戳比源 _older_ 时才同步。

  • 这意味着如果源文件已更新但文件的大小保持不变,并且这些更改文件的日期早于上次复制时的日期,则 s3 同步将不会再次同步它们。

  • 从 s3 复制到本地时,使用--exact-timestamps _only_ 有效。 故意不为本地到 s3 启用它,因为时间戳 _never_ 相等。 所以在从本地同步到 s3 时设置它没有效果。

  • 我不认为 s3 计算上传文件的哈希值,因此无法避免文件大小和上次上传日期作为检查。

底线是它按预期工作,但有各种用例
这是不可取的。 正如刚才提到的
<#m_8540343689970969812_issuecomment-534061850> 我已经解决了
使用 s3 cp --recursive

s3 确实会散列对象,但不是以完全可知的方式
https://teppen.io/2018/10/23/aws_s3_verify_etags/ ,并将其存储为
熟悉的 ETag https://en.wikipedia.org/wiki/HTTP_ETag 。 问题
是 ETag 取决于块的数量和块大小
文件已上传。如果您不是上传者,您可能不会
知道块大小(但可以从 ETag 中获取块数)。 一世
不知道为什么这样做。


您收到此消息是因为您发表了评论。
直接回复本邮件,在GitHub上查看
https://github.com/aws/aws-cli/issues/3273#issuecomment-613677369 ,或
退订
https://github.com/notifications/unsubscribe-auth/ADUA4NKJMCUSGTNAAITGPXTRMTE2NANCNFSM4E3JNHPQ
.

>

...汤姆

有同样的问题。 通过将源存储桶策略更改为:

 "Action": [
                "s3:*"
            ],

我有cp --recursivesync
这一切都解决了。 我有两个应该可以正常工作的动作,但没有。 试一试,让我知道它是否解决了你的问题。

在这里说我也遇到了sync 。 我注意到的唯一原因是因为我正在密封和验证两端的MHLsync不起作用,我在 890 GB 中丢失了大约 60 GB,试图逐个文件夹浏览。 然后我找到了这个线程并尝试了cp --recursive并且数据再次开始流动。 一旦我获得其余数据,将最后一次验证 MHL。

我写了一个脚本来重现这个问题,我使用:
aws-cli/1.18.34 Python/2.7.17 Darwin/19.4.0 botocore/1.13.50

如果您执行该脚本,您将看到在上传更改后,不再下载相同的更改。 这是脚本:

#!/bin/bash
PROFILE=foobar #PUT YOUR PROFILE HERE
BUCKET=baz123  #PUT YOUR BUCKET HERE

mkdir -p test/local
mkdir -p test/s3

cat >test/s3/test.json <<EOF
{
  "__comment_logging": "set cookie expiration time of aws split, examples '+1 hour', '+5 days', '+100 days'",
  "splitCookieExpiration": "+3 hours"
}
EOF

#UPLOAD
aws --profile=$PROFILE s3 sync --delete test/s3 s3://$BUCKET/ 
#DOWNLOAD
aws --profile=$PROFILE s3 sync --delete s3://$BUCKET/ test/local


#CHANGE 
cat >test/s3/test.json <<EOF
{
  "__comment_logging": "set cookie expiration time of aws split, examples '+1 hour', '+5 days', '+100 days'",
  "splitCookieExpiration": "+2 hours"
}
EOF


#UPLOAD
aws --profile=$PROFILE s3 sync --delete test/s3 s3://$BUCKET/ 
#DOWNLOAD
aws --profile=$PROFILE s3 sync --delete s3://$BUCKET/ test/local

@htrappmann请先阅读@jam13 的回答https://github.com/aws/aws-cli/issues/3273#issuecomment -602514439 - 这不是错误,而是功能!

感谢@applerom的提示,但我真的无法理解@jam13如何将

此外,如果文件大小不变但源时间戳较新,也不会发生同步,就像在我的示例脚本中一样。

感谢@applerom的提示,但我真的无法理解@jam13如何将

此外,如果文件大小不变但源时间戳较新,也不会发生同步,就像在我的示例脚本中一样。

这看起来确实是在做错事,不是吗。

我进行了一些其他测试,以查看我实际需要做什么才能进行下载:

ls -l test/local/test.json
aws s3 sync --delete s3://$BUCKET/ test/local
touch -m -t 201901010000 test/local/test.json
ls -l test/local/test.json
aws s3 sync --delete s3://$BUCKET/ test/local
touch test/local/test.json
ls -l test/local/test.json
aws s3 sync --delete s3://$BUCKET/ test/local

把文件修改时间改成去年,s3同步还是没有下载文件,所以不是简单的时区问题。

当将修改时间更改为现在(因此本地文件比远程文件新)时,s3 同步_确实_下载文件!

我无法理解,所以我检查了文档,其中状态(在描述--exact-timestamps选项时):

默认行为是忽略相同尺寸的物品,除非当地版本比S3版本更新

使用--exact-timestamps进行下载确实按预期工作(时间戳中的任何差异都会导致副本),但这个默认值在我看来确实是倒退。

也许与其说“按设计工作”,不如说“按文档工作”。

@jam13哇,太奇怪了,我认为这是文档中的混乱!
但是,如果这是修复错误的新方法,只需将它们明确地放在文档中......

@jam13

我不确定我们是否可以排除时区问题。
每天,当我在 s3 控制台中进行第一次更改并同步aws s3 sync s3://$BUCKET . ,它就会同步。 如果我对该文件进行另一次更改,然后进行同步,则它不会同步。
但是第二天就可以用了。

这让我重新思考是否可能是因为时区。

因此,请多检查一下您上面提到的touch -m命令。

touch -m -t 201901010000 test/local/test.json
把文件修改时间改成去年,s3同步还是没有下载文件,所以不是简单的时区问题。

上面的 touch 命令只回溯 mtime。 它不会(也不能)回溯 ctime。
S3 cli 是否可能使用 ctime?

$ touch file
$ stat -x file
  File: "file"
  Size: 0            FileType: Regular File
  ...
  ...
Access: Mon Jul 20 21:59:11 2020
Modify: Mon Jul 20 21:59:11 2020
Change: Mon Jul 20 21:59:11 2020

$ touch -m -t 201901010000 file
$ stat -x file
  File: "file"
  Size: 0            FileType: Regular File
  ...
  ...
Access: Mon Jul 20 21:59:11 2020
Modify: Tue Jan  1 00:00:00 2019
Change: Mon Jul 20 22:01:48 2020

我认为文件同步应该保证本地文件和远程文件是一样的。 我不认为我这样说是不公平的。 我认为aws s3 sync更像是一个update ,而不是同步。 我现在要将aws s3 sync每个实现更改为aws s3 cp --recursive

感谢@jam13https://github.com/aws/aws-cli/issues/3273#issuecomment -602514439 的解释

此页面是否有帮助?
0 / 5 - 0 等级