summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2014-09-23 17:09:50 -0400
committerMathias Stearn <mathias@10gen.com>2014-10-17 20:34:36 -0400
commit7e7439bab78da9c993fcf566e4ea8d5c0570ad8d (patch)
treea15b63212eee126a383fee111c098a24d21b6282 /src/mongo/db
parent4d34532dbf749fe2c9df9ed7421db196eaf93632 (diff)
downloadmongo-7e7439bab78da9c993fcf566e4ea8d5c0570ad8d.tar.gz
SERVER-15319 Bump file versions for 2.8-style freelist
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/db.cpp1
-rw-r--r--src/mongo/db/index_names.h4
-rw-r--r--src/mongo/db/pdfile_version.h43
-rw-r--r--src/mongo/db/storage/mmap_v1/data_file.cpp3
-rw-r--r--src/mongo/db/storage/mmap_v1/data_file.h74
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp44
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp21
-rw-r--r--src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h5
8 files changed, 97 insertions, 98 deletions
diff --git a/src/mongo/db/db.cpp b/src/mongo/db/db.cpp
index f2c64765098..2f82a287043 100644
--- a/src/mongo/db/db.cpp
+++ b/src/mongo/db/db.cpp
@@ -65,7 +65,6 @@
#include "mongo/db/log_process_details.h"
#include "mongo/db/mongod_options.h"
#include "mongo/db/operation_context_impl.h"
-#include "mongo/db/pdfile_version.h"
#include "mongo/db/query/internal_plans.h"
#include "mongo/db/range_deleter_service.h"
#include "mongo/db/repl/repl_coordinator_global.h"
diff --git a/src/mongo/db/index_names.h b/src/mongo/db/index_names.h
index 658ddd8459b..728906ed701 100644
--- a/src/mongo/db/index_names.h
+++ b/src/mongo/db/index_names.h
@@ -71,8 +71,8 @@ namespace mongo {
/**
* True if is a regular (non-plugin) index or uses a plugin that existed before 2.4.
- * These plugins are grandfathered in and allowed to exist in DBs with
- * PDFILE_MINOR_VERSION_22_AND_OLDER
+ * These plugins are grandfathered in and allowed to exist in DBs where
+ * DataFileVersion::is24IndexClean() returns false.
*/
static bool existedBefore24(const std::string& name);
diff --git a/src/mongo/db/pdfile_version.h b/src/mongo/db/pdfile_version.h
deleted file mode 100644
index a83b24cf493..00000000000
--- a/src/mongo/db/pdfile_version.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/**
-* Copyright (C) 2013 10gen Inc.
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU Affero General Public License, version 3,
-* as published by the Free Software Foundation.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU Affero General Public License for more details.
-*
-* You should have received a copy of the GNU Affero General Public License
-* along with this program. If not, see <http://www.gnu.org/licenses/>.
-*
-* As a special exception, the copyright holders give permission to link the
-* code of portions of this program with the OpenSSL library under certain
-* conditions as described in each individual source file and distribute
-* linked combinations including the program with the OpenSSL library. You
-* must comply with the GNU Affero General Public License in all respects for
-* all of the code used other than as permitted herein. If you modify file(s)
-* with this exception, you may extend this exception to your version of the
-* file(s), but you are not obligated to do so. If you do not wish to do so,
-* delete this exception statement from your version. If you delete this
-* exception statement from all source files in the program, then also delete
-* it in the license file.
-*/
-
-#pragma once
-
-namespace mongo {
-
- // pdfile versions
- const int PDFILE_VERSION = 4;
- const int PDFILE_VERSION_MINOR_22_AND_OLDER = 5;
- const int PDFILE_VERSION_MINOR_24_AND_NEWER = 6;
-
- // For backward compatibility with versions before 2.4.0 all new DBs start
- // with PDFILE_VERSION_MINOR_22_AND_OLDER and are converted when the first
- // index using a new plugin is created. See the logic in
- // IndexCatalog::_upgradeDatabaseMinorVersionIfNeeded for details
-
-} // namespace mongo
diff --git a/src/mongo/db/storage/mmap_v1/data_file.cpp b/src/mongo/db/storage/mmap_v1/data_file.cpp
index c08f00ece21..d8941c341fe 100644
--- a/src/mongo/db/storage/mmap_v1/data_file.cpp
+++ b/src/mongo/db/storage/mmap_v1/data_file.cpp
@@ -202,8 +202,7 @@ namespace mongo {
verify( HeaderSize == 8192 );
DataFileHeader *h = getDur().writing(this);
h->fileLength = filelength;
- h->version = PDFILE_VERSION;
- h->versionMinor = PDFILE_VERSION_MINOR_22_AND_OLDER; // All dbs start like this
+ h->version = DataFileVersion::defaultForNewFiles();
h->unused.set( fileno, HeaderSize );
verify( (data-(char*)this) == HeaderSize );
h->unusedLength = fileLength - HeaderSize - 16;
diff --git a/src/mongo/db/storage/mmap_v1/data_file.h b/src/mongo/db/storage/mmap_v1/data_file.h
index b8aa7f4f379..ce5f0b34549 100644
--- a/src/mongo/db/storage/mmap_v1/data_file.h
+++ b/src/mongo/db/storage/mmap_v1/data_file.h
@@ -31,7 +31,6 @@
#pragma once
#include "mongo/db/diskloc.h"
-#include "mongo/db/pdfile_version.h"
#include "mongo/db/storage/mmap_v1/durable_mapped_file.h"
namespace mongo {
@@ -39,6 +38,67 @@ namespace mongo {
class ExtentManager;
class OperationContext;
+#pragma pack(1)
+ class DataFileVersion {
+ public:
+ DataFileVersion(uint32_t major, uint32_t minor) :_major(major), _minor(minor) {}
+
+ static DataFileVersion defaultForNewFiles() {
+ return DataFileVersion(kCurrentMajor, kIndexes24AndNewer
+ | kMayHave28Freelist
+ );
+ }
+
+ bool isCompatibleWithCurrentCode() const {
+ if (_major != kCurrentMajor)
+ return false;
+
+ if (_minor & ~kUsedMinorFlagsMask)
+ return false;
+
+ const uint32_t indexCleanliness = _minor & kIndexPluginMask;
+ if (indexCleanliness != kIndexes24AndNewer && indexCleanliness != kIndexes22AndOlder)
+ return false;
+
+ // We are compatible with either setting of kMayHave28Freelist.
+
+ return true;
+ }
+
+ bool is24IndexClean() const { return (_minor & kIndexPluginMask) == kIndexes24AndNewer; }
+ void setIs24IndexClean() { _minor = ((_minor & ~kIndexPluginMask) | kIndexes24AndNewer); }
+
+ bool mayHave28Freelist() const { return _minor & kMayHave28Freelist; }
+ void setMayHave28Freelist() { _minor |= kMayHave28Freelist; }
+
+ uint32_t major() const { return _major; }
+ uint32_t minorRaw() const { return _minor; }
+
+ private:
+ static const uint32_t kCurrentMajor = 4;
+
+ // minor layout:
+ // first 4 bits - index plugin cleanliness.
+ // see IndexCatalog::_upgradeDatabaseMinorVersionIfNeeded for details
+ // 5th bit - 1 if started with 2.8-style freelist implementation (SERVER-14081)
+ // 6th through 31st bit - reserved and must be set to 0.
+ static const uint32_t kIndexPluginMask = 0xf;
+ static const uint32_t kIndexes22AndOlder = 5;
+ static const uint32_t kIndexes24AndNewer = 6;
+
+ static const uint32_t kMayHave28Freelist = (1 << 4);
+
+ // All set bits we know about are covered by this mask.
+ static const uint32_t kUsedMinorFlagsMask = 0x1f;
+
+ uint32_t _major;
+ uint32_t _minor;
+ };
+
+ // Note: Intentionally not defining relational operators for DataFileVersion as there is no
+ // total ordering of all versions now that '_minor' is used as a bit vector.
+#pragma pack()
+
/* a datafile - i.e. the "dbname.<#>" files :
----------------------
@@ -55,8 +115,7 @@ namespace mongo {
#pragma pack(1)
class DataFileHeader {
public:
- int version;
- int versionMinor;
+ DataFileVersion version;
int fileLength;
DiskLoc unused; /* unused is the portion of the file that doesn't belong to any allocated extents. -1 = no more */
int unusedLength;
@@ -68,14 +127,7 @@ namespace mongo {
enum { HeaderSize = 8192 };
- // all of this should move up to the database level
- bool isCurrentVersion() const {
- return version == PDFILE_VERSION && ( versionMinor == PDFILE_VERSION_MINOR_22_AND_OLDER
- || versionMinor == PDFILE_VERSION_MINOR_24_AND_NEWER
- );
- }
-
- bool uninitialized() const { return version == 0; }
+ bool uninitialized() const { return version.major() == 0; }
void init(OperationContext* txn, int fileno, int filelength, const char* filename);
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp
index e219c5cf765..d9872b170b2 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_database_catalog_entry.cpp
@@ -43,12 +43,12 @@
#include "mongo/db/index/hash_access_method.h"
#include "mongo/db/index/haystack_access_method.h"
#include "mongo/db/index/s2_access_method.h"
-#include "mongo/db/pdfile_version.h"
#include "mongo/db/server_parameters.h"
#include "mongo/db/storage/mmap_v1/btree/btree_interface.h"
#include "mongo/db/storage/mmap_v1/catalog/namespace_details.h"
#include "mongo/db/storage/mmap_v1/catalog/namespace_details_collection_entry.h"
#include "mongo/db/storage/mmap_v1/catalog/namespace_details_rsv1_metadata.h"
+#include "mongo/db/storage/mmap_v1/dur.h"
#include "mongo/db/storage/mmap_v1/data_file.h"
#include "mongo/db/storage/mmap_v1/dur_recovery_unit.h"
#include "mongo/db/storage/mmap_v1/record_store_v1_capped.h"
@@ -170,6 +170,13 @@ namespace mongo {
}
}
}
+
+ DataFileVersion version = _extentManager.getFileFormat(txn);
+ if (version.isCompatibleWithCurrentCode() && !version.mayHave28Freelist()) {
+ // Any DB that can be opened and written to gets this flag set.
+ version.setMayHave28Freelist();
+ _extentManager.setFileFormat(txn, version);
+ }
}
wunit.commit();
@@ -435,13 +442,11 @@ namespace mongo {
{
- int major = 0;
- int minor = 0;
- _extentManager.getFileFormat( opCtx, &major, &minor );
+ const DataFileVersion version = _extentManager.getFileFormat(opCtx);
BSONObjBuilder dataFileVersion( output->subobjStart( "dataFileVersion" ) );
- dataFileVersion.append( "major", major );
- dataFileVersion.append( "minor", minor );
+ dataFileVersion.append( "major", version.major() );
+ dataFileVersion.append( "minor", version.minorRaw() );
dataFileVersion.done();
}
}
@@ -452,40 +457,33 @@ namespace mongo {
if ( _extentManager.numFiles() == 0 )
return false;
- int major = 0;
- int minor = 0;
-
- _extentManager.getFileFormat( opCtx, &major, &minor );
+ const DataFileVersion version = _extentManager.getFileFormat(opCtx);
- invariant( major == PDFILE_VERSION );
+ invariant(version.isCompatibleWithCurrentCode());
- return minor == PDFILE_VERSION_MINOR_22_AND_OLDER;
+ return !version.is24IndexClean();
}
void MMAPV1DatabaseCatalogEntry::markIndexSafe24AndUp( OperationContext* opCtx ) {
if ( _extentManager.numFiles() == 0 )
return;
- int major = 0;
- int minor = 0;
+ DataFileVersion version = _extentManager.getFileFormat(opCtx);
- _extentManager.getFileFormat( opCtx, &major, &minor );
-
- invariant( major == PDFILE_VERSION );
-
- if ( minor == PDFILE_VERSION_MINOR_24_AND_NEWER )
- return;
+ invariant(version.isCompatibleWithCurrentCode());
- invariant( minor == PDFILE_VERSION_MINOR_22_AND_OLDER );
+ if (version.is24IndexClean())
+ return; // nothing to do
- _extentManager.setFileFormat(opCtx, major, PDFILE_VERSION_MINOR_24_AND_NEWER);
+ version.setIs24IndexClean();
+ _extentManager.setFileFormat(opCtx, version);
}
bool MMAPV1DatabaseCatalogEntry::currentFilesCompatible( OperationContext* opCtx ) const {
if ( _extentManager.numFiles() == 0 )
return true;
- return _extentManager.getOpenFile( 0 )->getHeader()->isCurrentVersion();
+ return _extentManager.getOpenFile( 0 )->getHeader()->version.isCompatibleWithCurrentCode();
}
void MMAPV1DatabaseCatalogEntry::getCollectionNamespaces( std::list<std::string>* tofill ) const {
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp
index f6d18f3090d..ccf903cf035 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.cpp
@@ -563,27 +563,20 @@ namespace mongo {
_size.store(n + 1);
}
- void MmapV1ExtentManager::getFileFormat( OperationContext* txn, int* major, int* minor ) const {
+ DataFileVersion MmapV1ExtentManager::getFileFormat(OperationContext* txn) const {
if ( numFiles() == 0 )
- return;
- const DataFile* df = _getOpenFile( 0 );
- *major = df->getHeader()->version;
- *minor = df->getHeader()->versionMinor;
-
- if ( *major <= 0 || *major >= 100 ||
- *minor <= 0 || *minor >= 100 ) {
- error() << "corrupt pdfile version? major: " << *major << " minor: " << *minor;
- fassertFailed( 14026 );
- }
+ return DataFileVersion(0, 0);
+
+ // We explicitly only look at the first file.
+ return _getOpenFile(0)->getHeader()->version;
}
- void MmapV1ExtentManager::setFileFormat(OperationContext* txn, int major, int minor) {
+ void MmapV1ExtentManager::setFileFormat(OperationContext* txn, DataFileVersion newVersion) {
invariant(numFiles() > 0);
DataFile* df = _getOpenFile(0);
invariant(df);
- txn->recoveryUnit()->writingInt(df->getHeader()->version) = major;
- txn->recoveryUnit()->writingInt(df->getHeader()->versionMinor) = minor;
+ *txn->recoveryUnit()->writing(&df->getHeader()->version) = newVersion;
}
}
diff --git a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h
index e1857db726c..61d2f1cfcb7 100644
--- a/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h
+++ b/src/mongo/db/storage/mmap_v1/mmap_v1_extent_manager.h
@@ -45,6 +45,7 @@
namespace mongo {
class DataFile;
+ class DataFileVersion;
class Record;
class OperationContext;
@@ -142,8 +143,8 @@ namespace mongo {
/**
* Not thread safe, requires a database exclusive lock
*/
- void getFileFormat(OperationContext* txn, int* major, int* minor) const;
- void setFileFormat(OperationContext* txn, int major, int minor);
+ DataFileVersion getFileFormat(OperationContext* txn) const;
+ void setFileFormat(OperationContext* txn, DataFileVersion newVersion);
const DataFile* getOpenFile( int n ) const { return _getOpenFile( n ); }