Skip to content

Commit

Permalink
SERVER-4345 Add support processing fifo files in mongorestore
Browse files Browse the repository at this point in the history
Example : `./mongorestore -d test -c foo_dupl <(mongodump -d test -c foo -out - 2>/dev/null | tail -n+2)`
Example (after pull mongodb#204) : `./mongorestore -d test -c foo_dupl <(mongodump -d test -c foo -out - 2>/dev/null)`

This closes mongodb#205

Signed-off-by: Benety Goh <benety@mongodb.com>
  • Loading branch information
azat authored and Jed Estep committed Aug 1, 2014
1 parent a42bc8b commit bc9c573
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 18 deletions.
8 changes: 6 additions & 2 deletions src/mongo/tools/restore.cpp
Expand Up @@ -410,8 +410,10 @@ class Restore : public BSONTool {
return;
}

boost::filesystem::file_status fileStatus = boost::filesystem::status(root);
if ( ! ( endsWith( root.string().c_str() , ".bson" ) ||
endsWith( root.string().c_str() , ".bin" ) ) ) {
endsWith( root.string().c_str() , ".bin" ) ) &&
! ( fileStatus.type() == boost::filesystem::fifo_file ) ) {
toolError() << "don't know what to do with file [" << root.string() << "]" << std::endl;
return;
}
Expand Down Expand Up @@ -492,7 +494,9 @@ class Restore : public BSONTool {

// 2) Create collection with options from metadata file if present
BSONObj metadataObject;
if (mongoRestoreGlobalParams.restoreOptions || mongoRestoreGlobalParams.restoreIndexes) {
boost::filesystem::file_status fileStatus = boost::filesystem::status(root);
if (fileStatus.type() != boost::filesystem::fifo_file &&
(mongoRestoreGlobalParams.restoreOptions || mongoRestoreGlobalParams.restoreIndexes)) {
string oldCollName = root.leaf().string(); // Name of collection that was dumped from
oldCollName = oldCollName.substr( 0 , oldCollName.find_last_of( "." ) );
boost::filesystem::path metadataFile = (root.branch_path() / (oldCollName + ".metadata.json"));
Expand Down
47 changes: 31 additions & 16 deletions src/mongo/tools/tool.cpp
Expand Up @@ -294,13 +294,18 @@ namespace mongo {
}

long long BSONTool::processFile( const boost::filesystem::path& root ) {
bool isFifoFile = boost::filesystem::status(root).type() == boost::filesystem::fifo_file;

std::string fileName = root.string();

unsigned long long fileLength = file_size( root );
unsigned long long fileLength = 0;
if (!isFifoFile) {
fileLength = file_size( root );

if ( fileLength == 0 ) {
toolInfoOutput() << "file " << fileName << " empty, skipping" << std::endl;
return 0;
if ( fileLength == 0 ) {
toolInfoOutput() << "file " << fileName << " empty, skipping" << std::endl;
return 0;
}
}


Expand All @@ -311,29 +316,38 @@ namespace mongo {
return 0;
}

if (!isFifoFile) {
#ifdef POSIX_FADV_SEQUENTIAL
posix_fadvise(fileno(file), 0, fileLength, POSIX_FADV_SEQUENTIAL);
posix_fadvise(fileno(file), 0, fileLength, POSIX_FADV_SEQUENTIAL);
#endif

if (logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1))) {
toolInfoOutput() << "\t file size: " << fileLength << std::endl;
if (logger::globalLogDomain()->shouldLog(logger::LogSeverity::Debug(1))) {
toolInfoOutput() << "\t file size: " << fileLength << std::endl;
}
}

unsigned long long read = 0;
unsigned long long num = 0;
unsigned long long processed = 0;

const int BUF_SIZE = BSONObjMaxUserSize + ( 1024 * 1024 );
boost::scoped_array<char> buf_holder(new char[BUF_SIZE]);
char * buf = buf_holder.get();

ProgressMeter m(fileLength);
if (!toolGlobalParams.quiet) {
m.setUnits( "bytes" );
// no progress is available for FIFO
// only for regular files
boost::scoped_ptr<ProgressMeter> m;
if (!toolGlobalParams.quiet && !isFifoFile) {
m.reset(new ProgressMeter( fileLength ));
// boost::scoped_ptr<ProgressMeter> m( fileLength );
m->setUnits( "bytes" );
}

while ( read < fileLength ) {
while ( true ) {
size_t amt = fread(buf, 1, 4, file);
// end of fifo/file
if ( feof(file) ) {
break;
}
verify( amt == 4 );

int size = ((int*)buf)[0];
Expand Down Expand Up @@ -368,17 +382,18 @@ namespace mongo {
processed++;
}

read += o.objsize();
num++;

if (!toolGlobalParams.quiet) {
m.hit(o.objsize());
if (m.get()) {
m->hit(o.objsize());
}
}

fclose( file );

uassert(10265, "counts don't match", read == fileLength);
if (m.get()) {
uassert(10265, "counts don't match", m->done() == fileLength);
}
toolInfoOutput() << num << ((num == 1) ? " document" : " documents")
<< " found" << std::endl;
if (bsonToolGlobalParams.hasFilter) {
Expand Down

0 comments on commit bc9c573

Please sign in to comment.