我有一个内置在Node / Meteor中的文件存储服务,它使用GridFS,并且它被复制到多个容器中。我目前正在努力寻找的是,这段代码是否真正意识到读/写的一致性
db.command({
filemd5: someFileId,
root: 'fs'
}, function callback(err, results) {
...
})
我以块的形式上传文件,并在将所有块合并到单个文件中后执行该命令。而且我感觉它使用的是辅助成员(我有几个md5值是空文件 - d41d8cd98f00b204e9800998ecf8427e
)。是否有任何文档或其他设置?
这两个参数是文档中描述的唯一选项.. https://docs.mongodb.com/manual/reference/command/filemd5/
UPDATE
合并块的确切代码在第三方包中:
cursor = files.find(
{
'metadata._Resumable.resumableIdentifier': file.metadata._Resumable.resumableIdentifier
length:
$ne: 0
},
{
fields:
length: 1
metadata: 1
sort:
'metadata._Resumable.resumableChunkNumber': 1
}
)
https://github.com/vsivsi/meteor-file-collection/blob/master/src/resumable_server.coffee#L26
然后有第111-119行首先执行filemd5,并在文件上运行更新
@db.command md5Command, (err, results) ->
if err
lock.releaseLock()
return callback err
# Update the size and md5 to the file data
files.update { _id: fileId }, { $set: { length: file.metadata._Resumable.resumableTotalSize, md5: results.md5 }},
(err, res) =>
lock.releaseLock()
callback err
https://github.com/vsivsi/meteor-file-collection/blob/master/src/resumable_server.coffee#L111-L119
在写完最后一个块后,cursor = files.find()
会启动所有合并内容,因此如果读取首选项为secondaryPreferred
,那么它们可能仍然不在那里?该代码是否应重构为仅使用主要代码?
答案 0 :(得分:1)
GridFS创建了2个集合:files
和chunks
。
典型的files
条目如下所示:
{
"_id" : ObjectId("58cfbc8b6900bb31c7b1b8d9"),
"length" : 4,
"chunkSize" : 261120,
"uploadDate" : ISODate("2017-03-20T11:27:07.812Z"),
"md5" : "d3b07384d113edec49eaa6238ad5ff00",
"filename" : "foo.txt"
}
filemd5
管理命令应该只返回相关文件文档的md5
字段(以及块数)。
<强> files.md5 强>
filemd5命令返回的完整文件的MD5哈希值。该值具有String类型。来源:GridFS docs
它应该代表完整文件的哈希值,或至少代表最初保存的哈希值。
文件收集文档的'md5'字段是什么?如何使用?
'md5'保存MD5校验和,该校验和是根据用户文件的原始内容计算的。从历史上看,GridFS不使用已确认的写入,因此必须使用此校验和来确保写入正确完成。通过已确认的写入,MD5校验和仍可用于确保GridFS中的文件未被破坏。第三方直接访问&#39;文件&#39; GridFS下的“块”集合可能会无意或恶意地对文档进行更改,使GridFS无法使用它们。将文件集合文档中的MD5与重新计算的MD5进行比较可以检测到此类错误和损坏。但是,驱动程序现在假定存储的文件未损坏,并且想要使用MD5值检查损坏的应用程序必须自己执行此操作。来源:GridFS spec
如果以不使用驱动程序mongoc_gridfs_file_save
的方式更新(例如,流式传输),则md5
字段将不会更新。
实际上,进一步阅读规范:
为什么要存储MD5校验和而不是根据需要创建哈希? 当文件最初上传到GridFS时,必须计算MD5校验和,因为这是我们唯一一次保证拥有整个未损坏的文件。从GridFS读取文件时即时计算它将确保我们的读取成功,但不保证系统中文件的状态。对存储的MD5校验和进行成功检查可确保存储的文件与原始文件匹配,并且没有发生损坏。
这就是我们正在做的事情。只有mongoc_gridfs_file_save才会计算文件的md5总和并存储它。任何其他入口点,例如流,都希望用户创建所有支持mongoc_gridfs_file_opt_t并正确计算md5
来源:JIRA issue