Permalink
Browse files

make preallocation of data files more atomic

  • Loading branch information...
1 parent 697c7b3 commit 3d38c57b93d0690a79fdead41d7a2d17452aa182 @dwight dwight committed Mar 17, 2011
Showing with 29 additions and 9 deletions.
  1. +29 −9 util/file_allocator.cpp
View
@@ -38,7 +38,7 @@ namespace mongo {
void ensureParentDirCreated(const boost::filesystem::path& p){
const boost::filesystem::path parent = p.branch_path();
-
+
if (! boost::filesystem::exists(parent)){
ensureParentDirCreated(parent);
log() << "creating directory " << parent.string() << endl;
@@ -199,6 +199,19 @@ namespace mongo {
return false;
}
+ string makeTempFileName() {
+ while( 1 ) {
+ path p = path(dbpath) / "_tmp";
+ stringstream ss;
+ ss << (unsigned) rand();
+ p /= ss.str();
+ string fn = p.string();
+ if( !boost::filesystem::exists(p) )
+ return fn;
+ }
+ return "";
+ }
+
void FileAllocator::run( FileAllocator * fa ) {
setThreadName( "FileAllocator" );
while( 1 ) {
@@ -217,21 +230,20 @@ namespace mongo {
name = fa->_pending.front();
size = fa->_pendingSize[ name ];
}
+ string tmp = makeTempFileName();
try {
log() << "allocating new datafile " << name << ", filling with zeroes..." << endl;
ensureParentDirCreated(name);
- long fd = open(name.c_str(), O_CREAT | O_RDWR | O_NOATIME, S_IRUSR | S_IWUSR);
+ ensureParentDirCreated(tmp);
+ long fd = open(tmp.c_str(), O_CREAT | O_RDWR | O_NOATIME, S_IRUSR | S_IWUSR);
if ( fd <= 0 ) {
- stringstream ss;
- ss << "FileAllocator: couldn't open " << name << ' ' << errnoWithDescription();
- uassert( 10439 , ss.str(), fd <= 0 );
+ log() << "FileAllocator: couldn't create " << name << " (" << tmp << ") " << errnoWithDescription() << endl;
+ uasserted(10439, "");
}
- flushMyDirectory(name); // done before ensureLength to avoid flushing data on some filesystems
-
#if defined(POSIX_FADV_DONTNEED)
if( posix_fadvise(fd, 0, size, POSIX_FADV_DONTNEED) ) {
- log() << "warning: posix_fadvise fails " << name << ' ' << errnoWithDescription() << endl;
+ log() << "warning: posix_fadvise fails " << name << " (" << tmp << ") " << errnoWithDescription() << endl;
}
#endif
@@ -240,18 +252,26 @@ namespace mongo {
/* make sure the file is the full desired length */
ensureLength( fd , size );
+ close( fd );
+
+ if( rename(tmp.c_str(), name.c_str()) ) {
+ log() << "error: couldn't rename " << tmp << " to " << name << ' ' << errnoWithDescription() << endl;
+ uasserted(13653, "");
+ }
+ flushMyDirectory(name);
+
log() << "done allocating datafile " << name << ", "
<< "size: " << size/1024/1024 << "MB, "
<< " took " << ((double)t.millis())/1000.0 << " secs"
<< endl;
- close( fd );
}
catch ( ... ) {
log() << "error failed to allocate new file: " << name
<< " size: " << size << ' ' << errnoWithDescription() << endl;
try {
+ BOOST_CHECK_EXCEPTION( boost::filesystem::remove( tmp ) );
BOOST_CHECK_EXCEPTION( boost::filesystem::remove( name ) );
}
catch ( ... ) {

0 comments on commit 3d38c57

Please sign in to comment.