summaryrefslogtreecommitdiff
path: root/src/mongo/db/range_deleter.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/range_deleter.h')
-rw-r--r--src/mongo/db/range_deleter.h515
1 files changed, 256 insertions, 259 deletions
diff --git a/src/mongo/db/range_deleter.h b/src/mongo/db/range_deleter.h
index eaf8fa35e1d..f58625f8083 100644
--- a/src/mongo/db/range_deleter.h
+++ b/src/mongo/db/range_deleter.h
@@ -47,289 +47,286 @@
namespace mongo {
- class OperationContext;
- struct DeleteJobStats;
- struct RangeDeleteEntry;
- struct RangeDeleterEnv;
- struct RangeDeleterOptions;
+class OperationContext;
+struct DeleteJobStats;
+struct RangeDeleteEntry;
+struct RangeDeleterEnv;
+struct RangeDeleterOptions;
+
+/**
+ * Class for deleting documents for a given namespace and range. It contains a queue of
+ * jobs to be deleted. Deletions can be "immediate", in which case they are going to be put
+ * in front of the queue and acted on promptly, or "lazy", in which they would be acted
+ * upon when they get to the head of the queue.
+ *
+ * Threading assumptions:
+ *
+ * This class has (currently) one worker thread attacking the queue, one
+ * job at a time. If we want an immediate deletion, that job is going to
+ * be performed on the thread that is requesting it.
+ *
+ * All calls regarding deletion are synchronized.
+ *
+ * Life cycle:
+ * RangeDeleter* deleter = new RangeDeleter(new ...);
+ * deleter->startWorkers();
+ * ...
+ * getGlobalServiceContext()->killAllOperations(); // stop all deletes
+ * deleter->stopWorkers();
+ * delete deleter;
+ */
+class RangeDeleter {
+ MONGO_DISALLOW_COPYING(RangeDeleter);
+
+public:
+ /**
+ * Creates a new deleter and uses an environment object to delegate external logic like
+ * data deletion. Takes ownership of the environment.
+ */
+ explicit RangeDeleter(RangeDeleterEnv* env);
+
+ /**
+ * Destroys this deleter. Must make sure that no threads are working on this queue. Use
+ * stopWorkers to stop the internal workers, it is an error not to do so.
+ */
+ ~RangeDeleter();
+
+ //
+ // Thread management methods
+ //
+
+ /**
+ * Starts the background thread to work on this queue. Does nothing if the worker
+ * thread is already active.
+ *
+ * This call is _not_ thread safe and must be issued before any other call.
+ */
+ void startWorkers();
/**
- * Class for deleting documents for a given namespace and range. It contains a queue of
- * jobs to be deleted. Deletions can be "immediate", in which case they are going to be put
- * in front of the queue and acted on promptly, or "lazy", in which they would be acted
- * upon when they get to the head of the queue.
+ * Stops the background thread working on this queue. This will block if there are
+ * tasks that are being deleted, but will leave the pending tasks in the queue.
*
- * Threading assumptions:
+ * Steps:
+ * 1. Stop accepting new queued deletes.
+ * 2. Stop all idle workers.
+ * 3. Waits for all threads to finish any task that is in progress (but see note
+ * below).
*
- * This class has (currently) one worker thread attacking the queue, one
- * job at a time. If we want an immediate deletion, that job is going to
- * be performed on the thread that is requesting it.
+ * Note:
*
- * All calls regarding deletion are synchronized.
+ * + restarting this deleter with startWorkers after stopping it is not supported.
*
- * Life cycle:
- * RangeDeleter* deleter = new RangeDeleter(new ...);
- * deleter->startWorkers();
- * ...
- * getGlobalServiceContext()->killAllOperations(); // stop all deletes
- * deleter->stopWorkers();
- * delete deleter;
+ * + the worker thread could be running a call in the environment. The thread is
+ * only going to be returned when the environment decides so. In production,
+ * KillCurrentOp::killAll can be used to get the thread back from the environment.
*/
- class RangeDeleter {
- MONGO_DISALLOW_COPYING(RangeDeleter);
- public:
-
- /**
- * Creates a new deleter and uses an environment object to delegate external logic like
- * data deletion. Takes ownership of the environment.
- */
- explicit RangeDeleter(RangeDeleterEnv* env);
-
- /**
- * Destroys this deleter. Must make sure that no threads are working on this queue. Use
- * stopWorkers to stop the internal workers, it is an error not to do so.
- */
- ~RangeDeleter();
-
- //
- // Thread management methods
- //
-
- /**
- * Starts the background thread to work on this queue. Does nothing if the worker
- * thread is already active.
- *
- * This call is _not_ thread safe and must be issued before any other call.
- */
- void startWorkers();
-
- /**
- * Stops the background thread working on this queue. This will block if there are
- * tasks that are being deleted, but will leave the pending tasks in the queue.
- *
- * Steps:
- * 1. Stop accepting new queued deletes.
- * 2. Stop all idle workers.
- * 3. Waits for all threads to finish any task that is in progress (but see note
- * below).
- *
- * Note:
- *
- * + restarting this deleter with startWorkers after stopping it is not supported.
- *
- * + the worker thread could be running a call in the environment. The thread is
- * only going to be returned when the environment decides so. In production,
- * KillCurrentOp::killAll can be used to get the thread back from the environment.
- */
- void stopWorkers();
-
- //
- // Queue manipulation methods - can be called by anyone.
- //
-
- /**
- * Adds a new delete to the queue.
- *
- * If notifyDone is not NULL, it will be signaled after the delete is completed.
- * Note that this will happen only if the delete was actually queued.
- *
- * Returns true if the task is queued and false If the given range is blacklisted,
- * is already queued, or stopWorkers() was called.
- */
- bool queueDelete(OperationContext* txn,
- const RangeDeleterOptions& options,
- Notification* notifyDone,
- std::string* errMsg);
-
- /**
- * Removes the documents specified by the range. Unlike queueTask, this call
- * blocks and the deletion is performed by the current thread.
- *
- * Returns true if the deletion was performed. False if the range is blacklisted,
- * was already queued, or stopWorkers() was called.
- */
- bool deleteNow(OperationContext* txn,
- const RangeDeleterOptions& options,
- std::string* errMsg);
-
- //
- // Introspection methods
- //
-
- // Note: original contents of stats will be cleared. Caller owns the returned stats.
- void getStatsHistory(std::vector<DeleteJobStats*>* stats) const;
-
- size_t getTotalDeletes() const;
- size_t getPendingDeletes() const;
- size_t getDeletesInProgress() const;
-
- //
- // Methods meant to be only used for testing. Should be treated like private
- // methods.
- //
-
- /** Returns a BSON representation of the queue contents. For debugging only. */
- BSONObj toBSON() const;
-
- private:
- // Ownership is transferred to here.
- void recordDelStats(DeleteJobStats* newStat);
-
-
- struct NSMinMax;
-
- struct NSMinMaxCmp {
- bool operator()(const NSMinMax* lhs, const NSMinMax* rhs) const;
- };
-
- typedef std::deque<RangeDeleteEntry*> TaskList; // owned here
-
- typedef std::set<NSMinMax*, NSMinMaxCmp> NSMinMaxSet; // owned here
-
- /** Body of the worker thread */
- void doWork();
-
- /** Returns true if the range doesn't intersect with one other range */
- bool canEnqueue_inlock(StringData ns,
- const BSONObj& min,
- const BSONObj& max,
- std::string* errMsg) const;
-
- /** Returns true if stopWorkers() was called. This call is synchronized. */
- bool stopRequested() const;
-
- std::unique_ptr<RangeDeleterEnv> _env;
-
- // Initially not active. Must be started explicitly.
- std::unique_ptr<stdx::thread> _worker;
-
- // Protects _stopRequested.
- mutable stdx::mutex _stopMutex;
-
- // If set, no other delete taks should be accepted.
- bool _stopRequested;
-
- // No delete is in progress. Used to make sure that there is no activity
- // in this deleter, and therefore is safe to destroy it. Must be used in
- // conjunction with _stopRequested.
- stdx::condition_variable _nothingInProgressCV;
-
- // Protects all the data structure below this.
- mutable stdx::mutex _queueMutex;
-
- // _taskQueue has a task ready to work on.
- stdx::condition_variable _taskQueueNotEmptyCV;
-
- // Queue for storing the list of ranges that have cursors pending on it.
- //
- // Note: pointer life cycle is not handled here.
- TaskList _notReadyQueue;
-
- // Queue for storing the list of ranges that are ready to be removed.
- //
- // Note: pointer life cycle is not handled here.
- TaskList _taskQueue;
-
- // Set of all deletes - deletes waiting for cursors, waiting to be acted upon
- // and in progress. Includes both queued and immediate deletes.
- //
- // queued delete life cycle: new @ queuedDelete, delete @ doWork
- // deleteNow life cycle: deleteNow stack variable
- NSMinMaxSet _deleteSet;
+ void stopWorkers();
- // Keeps track of number of tasks that are in progress, including the inline deletes.
- size_t _deletesInProgress;
-
- // Protects _statsHistory
- mutable stdx::mutex _statsHistoryMutex;
- std::deque<DeleteJobStats*> _statsHistory;
- };
+ //
+ // Queue manipulation methods - can be called by anyone.
+ //
+ /**
+ * Adds a new delete to the queue.
+ *
+ * If notifyDone is not NULL, it will be signaled after the delete is completed.
+ * Note that this will happen only if the delete was actually queued.
+ *
+ * Returns true if the task is queued and false If the given range is blacklisted,
+ * is already queued, or stopWorkers() was called.
+ */
+ bool queueDelete(OperationContext* txn,
+ const RangeDeleterOptions& options,
+ Notification* notifyDone,
+ std::string* errMsg);
/**
- * Simple class for storing statistics for the RangeDeleter.
+ * Removes the documents specified by the range. Unlike queueTask, this call
+ * blocks and the deletion is performed by the current thread.
+ *
+ * Returns true if the deletion was performed. False if the range is blacklisted,
+ * was already queued, or stopWorkers() was called.
*/
- struct DeleteJobStats {
- Date_t queueStartTS;
- Date_t queueEndTS;
- Date_t deleteStartTS;
- Date_t deleteEndTS;
- Date_t waitForReplStartTS;
- Date_t waitForReplEndTS;
-
- long long int deletedDocCount;
-
- DeleteJobStats(): deletedDocCount(0) {
- }
- };
+ bool deleteNow(OperationContext* txn, const RangeDeleterOptions& options, std::string* errMsg);
+
+ //
+ // Introspection methods
+ //
- struct RangeDeleterOptions {
- RangeDeleterOptions(const KeyRange& range);
+ // Note: original contents of stats will be cleared. Caller owns the returned stats.
+ void getStatsHistory(std::vector<DeleteJobStats*>* stats) const;
- const KeyRange range;
+ size_t getTotalDeletes() const;
+ size_t getPendingDeletes() const;
+ size_t getDeletesInProgress() const;
- WriteConcernOptions writeConcern;
- std::string removeSaverReason;
- bool fromMigrate;
- bool onlyRemoveOrphanedDocs;
- bool waitForOpenCursors;
+ //
+ // Methods meant to be only used for testing. Should be treated like private
+ // methods.
+ //
+
+ /** Returns a BSON representation of the queue contents. For debugging only. */
+ BSONObj toBSON() const;
+
+private:
+ // Ownership is transferred to here.
+ void recordDelStats(DeleteJobStats* newStat);
+
+
+ struct NSMinMax;
+
+ struct NSMinMaxCmp {
+ bool operator()(const NSMinMax* lhs, const NSMinMax* rhs) const;
};
- /**
- * For internal use only.
- */
- struct RangeDeleteEntry {
- RangeDeleteEntry(const RangeDeleterOptions& options);
+ typedef std::deque<RangeDeleteEntry*> TaskList; // owned here
- const RangeDeleterOptions options;
+ typedef std::set<NSMinMax*, NSMinMaxCmp> NSMinMaxSet; // owned here
- // Sets of cursors to wait to close until this can be ready
- // for deletion.
- std::set<CursorId> cursorsToWait;
+ /** Body of the worker thread */
+ void doWork();
- // Not owned here.
- // Important invariant: Can only be set and used by one thread.
- Notification* notifyDone;
+ /** Returns true if the range doesn't intersect with one other range */
+ bool canEnqueue_inlock(StringData ns,
+ const BSONObj& min,
+ const BSONObj& max,
+ std::string* errMsg) const;
- // Time since the last time we reported this object.
- Date_t lastLoggedTS;
+ /** Returns true if stopWorkers() was called. This call is synchronized. */
+ bool stopRequested() const;
- DeleteJobStats stats;
+ std::unique_ptr<RangeDeleterEnv> _env;
- // For debugging only
- BSONObj toBSON() const;
- };
+ // Initially not active. Must be started explicitly.
+ std::unique_ptr<stdx::thread> _worker;
+
+ // Protects _stopRequested.
+ mutable stdx::mutex _stopMutex;
+
+ // If set, no other delete taks should be accepted.
+ bool _stopRequested;
+
+ // No delete is in progress. Used to make sure that there is no activity
+ // in this deleter, and therefore is safe to destroy it. Must be used in
+ // conjunction with _stopRequested.
+ stdx::condition_variable _nothingInProgressCV;
+
+ // Protects all the data structure below this.
+ mutable stdx::mutex _queueMutex;
+
+ // _taskQueue has a task ready to work on.
+ stdx::condition_variable _taskQueueNotEmptyCV;
+
+ // Queue for storing the list of ranges that have cursors pending on it.
+ //
+ // Note: pointer life cycle is not handled here.
+ TaskList _notReadyQueue;
+
+ // Queue for storing the list of ranges that are ready to be removed.
+ //
+ // Note: pointer life cycle is not handled here.
+ TaskList _taskQueue;
+
+ // Set of all deletes - deletes waiting for cursors, waiting to be acted upon
+ // and in progress. Includes both queued and immediate deletes.
+ //
+ // queued delete life cycle: new @ queuedDelete, delete @ doWork
+ // deleteNow life cycle: deleteNow stack variable
+ NSMinMaxSet _deleteSet;
+
+ // Keeps track of number of tasks that are in progress, including the inline deletes.
+ size_t _deletesInProgress;
+
+ // Protects _statsHistory
+ mutable stdx::mutex _statsHistoryMutex;
+ std::deque<DeleteJobStats*> _statsHistory;
+};
+
+
+/**
+ * Simple class for storing statistics for the RangeDeleter.
+ */
+struct DeleteJobStats {
+ Date_t queueStartTS;
+ Date_t queueEndTS;
+ Date_t deleteStartTS;
+ Date_t deleteEndTS;
+ Date_t waitForReplStartTS;
+ Date_t waitForReplEndTS;
+
+ long long int deletedDocCount;
+
+ DeleteJobStats() : deletedDocCount(0) {}
+};
+
+struct RangeDeleterOptions {
+ RangeDeleterOptions(const KeyRange& range);
+
+ const KeyRange range;
+
+ WriteConcernOptions writeConcern;
+ std::string removeSaverReason;
+ bool fromMigrate;
+ bool onlyRemoveOrphanedDocs;
+ bool waitForOpenCursors;
+};
+
+/**
+ * For internal use only.
+ */
+struct RangeDeleteEntry {
+ RangeDeleteEntry(const RangeDeleterOptions& options);
+
+ const RangeDeleterOptions options;
+
+ // Sets of cursors to wait to close until this can be ready
+ // for deletion.
+ std::set<CursorId> cursorsToWait;
+
+ // Not owned here.
+ // Important invariant: Can only be set and used by one thread.
+ Notification* notifyDone;
+
+ // Time since the last time we reported this object.
+ Date_t lastLoggedTS;
+
+ DeleteJobStats stats;
+
+ // For debugging only
+ BSONObj toBSON() const;
+};
+
+/**
+ * Class for encapsulating logic used by the RangeDeleter class to perform its tasks.
+ */
+struct RangeDeleterEnv {
+ virtual ~RangeDeleterEnv() {}
/**
- * Class for encapsulating logic used by the RangeDeleter class to perform its tasks.
+ * Deletes the documents from the given range. This method should be
+ * responsible for making sure that the proper contexts are setup
+ * to be able to perform deletions.
+ *
+ * Must be a synchronous call. Docs should be deleted after call ends.
+ * Must not throw Exceptions.
*/
- struct RangeDeleterEnv {
- virtual ~RangeDeleterEnv() {}
-
- /**
- * Deletes the documents from the given range. This method should be
- * responsible for making sure that the proper contexts are setup
- * to be able to perform deletions.
- *
- * Must be a synchronous call. Docs should be deleted after call ends.
- * Must not throw Exceptions.
- */
- virtual bool deleteRange(OperationContext* txn,
- const RangeDeleteEntry& taskDetails,
- long long int* deletedDocs,
- std::string* errMsg) = 0;
-
- /**
- * Gets the list of open cursors on a given namespace. The openCursors is an
- * output parameter that will contain all the cursors open after this is called.
- * Assume that openCursors is empty when passed in.
- *
- * Must be a synchronous call. CursorIds should be populated after call.
- * Must not throw exception.
- */
- virtual void getCursorIds(OperationContext* txn,
- StringData ns,
- std::set<CursorId>* openCursors) = 0;
- };
+ virtual bool deleteRange(OperationContext* txn,
+ const RangeDeleteEntry& taskDetails,
+ long long int* deletedDocs,
+ std::string* errMsg) = 0;
+
+ /**
+ * Gets the list of open cursors on a given namespace. The openCursors is an
+ * output parameter that will contain all the cursors open after this is called.
+ * Assume that openCursors is empty when passed in.
+ *
+ * Must be a synchronous call. CursorIds should be populated after call.
+ * Must not throw exception.
+ */
+ virtual void getCursorIds(OperationContext* txn,
+ StringData ns,
+ std::set<CursorId>* openCursors) = 0;
+};
-} // namespace mongo
+} // namespace mongo