summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2015-08-11 14:51:41 -0400
committerMathias Stearn <mathias@10gen.com>2015-08-12 17:01:00 -0400
commitf20b07fbd4447aa415a639c124c74d5b69dbcf1b (patch)
tree7c37166b7c3d928576ab6825c4a3bc6dece8efd8
parent7c7487b3e0c98739249de33e84dbc76f50bd5717 (diff)
downloadmongo-f20b07fbd4447aa415a639c124c74d5b69dbcf1b.tar.gz
SERVER-19213 Move old snapshot cleanup out of the repl mutex
-rw-r--r--src/mongo/db/repl/oplog.cpp3
-rw-r--r--src/mongo/db/storage/snapshot_manager.h16
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp10
-rw-r--r--src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h1
4 files changed, 27 insertions, 3 deletions
diff --git a/src/mongo/db/repl/oplog.cpp b/src/mongo/db/repl/oplog.cpp
index 7be8430c56a..2c08adab0a7 100644
--- a/src/mongo/db/repl/oplog.cpp
+++ b/src/mongo/db/repl/oplog.cpp
@@ -1019,6 +1019,9 @@ void SnapshotThread::run() {
log() << "skipping storage snapshot pass due to write conflict";
continue;
}
+
+ // Called outside of all locks.
+ _manager->cleanupUnneededSnapshots();
}
}
diff --git a/src/mongo/db/storage/snapshot_manager.h b/src/mongo/db/storage/snapshot_manager.h
index e4a30199525..8d4b81fd5c3 100644
--- a/src/mongo/db/storage/snapshot_manager.h
+++ b/src/mongo/db/storage/snapshot_manager.h
@@ -71,15 +71,27 @@ public:
virtual Status createSnapshot(OperationContext* txn, const SnapshotName& name) = 0;
/**
- * Sets the snapshot to be used for committed reads. Once set, all older snapshots that are
- * not currently in use by any RecoveryUnit can be deleted.
+ * Sets the snapshot to be used for committed reads.
*
* Implementations are allowed to assume that all older snapshots have names that compare
* less than the passed in name, and newer ones compare greater.
+ *
+ * This is called while holding a very hot mutex. Therefore it should avoid doing any work that
+ * can be done later. In particular, cleaning up of old snapshots should be deferred until
+ * cleanupUnneededSnapshots is called.
*/
virtual void setCommittedSnapshot(const SnapshotName& name) = 0;
/**
+ * Cleans up all snapshots older than the current committed snapshot.
+ *
+ * Operations that have already begun using an older snapshot must continue to work using that
+ * snapshot until they would normally start using a newer one. Any implementation that allows
+ * that without an unbounded growth of snapshots is permitted.
+ */
+ virtual void cleanupUnneededSnapshots() = 0;
+
+ /**
* Drops all snapshots and clears the "committed" snapshot.
*/
virtual void dropAllSnapshots() = 0;
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp
index 56be58ffdf3..a56f4827f59 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.cpp
@@ -57,8 +57,16 @@ void WiredTigerSnapshotManager::setCommittedSnapshot(const SnapshotName& name) {
invariant(!_committedSnapshot || *_committedSnapshot <= name);
_committedSnapshot = name;
+}
+
+void WiredTigerSnapshotManager::cleanupUnneededSnapshots() {
+ stdx::lock_guard<stdx::mutex> lock(_mutex);
+
+ if (!_committedSnapshot)
+ return;
- const std::string config = str::stream() << "drop=(before=" << name.asU64() << ')';
+ const std::string config = str::stream() << "drop=(before=" << _committedSnapshot->asU64()
+ << ')';
invariantWTOK(_session->snapshot(_session, config.c_str()));
}
diff --git a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h
index 956f581bded..912f0fb13d4 100644
--- a/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h
+++ b/src/mongo/db/storage/wiredtiger/wiredtiger_snapshot_manager.h
@@ -54,6 +54,7 @@ public:
Status prepareForCreateSnapshot(OperationContext* txn) final;
Status createSnapshot(OperationContext* ru, const SnapshotName& name) final;
void setCommittedSnapshot(const SnapshotName& name) final;
+ void cleanupUnneededSnapshots() final;
void dropAllSnapshots() final;
//