Skip to content

Commit

Permalink
MB-6770 Add the recreate option to KVStore::delVBucket()
Browse files Browse the repository at this point in the history
VBucket reset operation should delete a vbucket database file
and then recreate the empty database file. As the vbucket reset
operation internally invokes KVStore::delVBucket API, this API
should support the recreate option.

Change-Id: I70f429038a9ed572ddc5cc4e9ad046a257a27f66
Reviewed-on: http://review.couchbase.org/21189
Reviewed-by: Jin Lim <jin@couchbase.com>
Reviewed-by: Michael Wiederhold <mike@couchbase.com>
Tested-by: Karan Kumar <karan@couchbase.com>
  • Loading branch information
chiyoung authored and Peter Wansch committed Sep 28, 2012
1 parent 274f6bd commit d369500
Show file tree
Hide file tree
Showing 7 changed files with 41 additions and 20 deletions.
2 changes: 1 addition & 1 deletion src/blackhole-kvstore/blackhole.cc
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ void BlackholeKVStore::del(const Item &,
cb.callback(val); cb.callback(val);
} }


bool BlackholeKVStore::delVBucket(uint16_t) bool BlackholeKVStore::delVBucket(uint16_t, bool)
{ {
return true; return true;
} }
Expand Down
2 changes: 1 addition & 1 deletion src/blackhole-kvstore/blackhole.hh
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ public:
void del(const Item &itm, uint64_t rowid, void del(const Item &itm, uint64_t rowid,
Callback<int> &cb); Callback<int> &cb);


bool delVBucket(uint16_t vbucket); bool delVBucket(uint16_t vbucket, bool recreate);


vbucket_map_t listPersistedVbuckets(void); vbucket_map_t listPersistedVbuckets(void);


Expand Down
16 changes: 13 additions & 3 deletions src/couch-kvstore/couch-kvstore.cc
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -511,7 +511,7 @@ void CouchKVStore::del(const Item &itm,
} }
} }


bool CouchKVStore::delVBucket(uint16_t vbucket) bool CouchKVStore::delVBucket(uint16_t vbucket, bool recreate)
{ {
assert(!isReadOnly()); assert(!isReadOnly());
assert(couchNotifier); assert(couchNotifier);
Expand All @@ -520,7 +520,17 @@ bool CouchKVStore::delVBucket(uint16_t vbucket)
couchNotifier->delVBucket(vbucket, cb); couchNotifier->delVBucket(vbucket, cb);
cb.waitForValue(); cb.waitForValue();


cachedVBStates.erase(vbucket); if (recreate) {
vbucket_state vbstate(vbucket_state_dead, 0, 0);
vbucket_map_t::iterator it = cachedVBStates.find(vbucket);
if (it != cachedVBStates.end()) {
vbstate.state = it->second.state;
}
cachedVBStates[vbucket] = vbstate;
resetVBucket(vbucket, vbstate);
} else {
cachedVBStates.erase(vbucket);
}
updateDbFileMap(vbucket, 1, false); updateDbFileMap(vbucket, 1, false);
return cb.val; return cb.val;
} }
Expand Down Expand Up @@ -726,7 +736,7 @@ bool CouchKVStore::snapshotStats(const std::map<std::string, std::string> &stats
return rv; return rv;
} }


bool CouchKVStore::setVBucketState(uint16_t vbucketId, vbucket_state vbstate, bool CouchKVStore::setVBucketState(uint16_t vbucketId, vbucket_state &vbstate,
uint32_t vb_change_type, bool newfile, uint32_t vb_change_type, bool newfile,
bool notify) bool notify)
{ {
Expand Down
7 changes: 4 additions & 3 deletions src/couch-kvstore/couch-kvstore.hh
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -326,9 +326,10 @@ public:
* Delete a given vbucket database instance from the underlying storage system * Delete a given vbucket database instance from the underlying storage system
* *
* @param vbucket vbucket id * @param vbucket vbucket id
* @param recreate true if we need to create an empty vbucket after deletion
* @return true if the vbucket deletion is completed successfully. * @return true if the vbucket deletion is completed successfully.
*/ */
bool delVBucket(uint16_t vbucket); bool delVBucket(uint16_t vbucket, bool recreate);


/** /**
* Retrieve the list of persisted vbucket states * Retrieve the list of persisted vbucket states
Expand Down Expand Up @@ -475,10 +476,10 @@ protected:
void loadDB(shared_ptr<Callback<GetValue> > cb, bool keysOnly, void loadDB(shared_ptr<Callback<GetValue> > cb, bool keysOnly,
std::vector<uint16_t> *vbids, std::vector<uint16_t> *vbids,
couchstore_docinfos_options options=COUCHSTORE_NO_OPTIONS); couchstore_docinfos_options options=COUCHSTORE_NO_OPTIONS);
bool setVBucketState(uint16_t vbucketId, vbucket_state vbstate, bool setVBucketState(uint16_t vbucketId, vbucket_state &vbstate,
uint32_t vb_change_type, bool newfile = false, uint32_t vb_change_type, bool newfile = false,
bool notify = true); bool notify = true);
bool resetVBucket(uint16_t vbucketId, vbucket_state vbstate) { bool resetVBucket(uint16_t vbucketId, vbucket_state &vbstate) {
return setVBucketState(vbucketId, vbstate, VB_NO_CHANGE, true, false); return setVBucketState(vbucketId, vbstate, VB_NO_CHANGE, true, false);
} }


Expand Down
22 changes: 13 additions & 9 deletions src/ep.cc
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -249,13 +249,13 @@ class VBucketMemoryDeletionCallback : public DispatcherCallback {
class VBucketDeletionCallback : public DispatcherCallback { class VBucketDeletionCallback : public DispatcherCallback {
public: public:
VBucketDeletionCallback(EventuallyPersistentStore *e, RCPtr<VBucket> &vb, VBucketDeletionCallback(EventuallyPersistentStore *e, RCPtr<VBucket> &vb,
EPStats &st, const void* c = NULL) : EPStats &st, const void* c = NULL, bool rc = false) :
ep(e), vbucket(vb->getId()), ep(e), vbucket(vb->getId()),
stats(st), cookie(c) {} stats(st), cookie(c), recreate(rc) {}


bool callback(Dispatcher &, TaskId &) { bool callback(Dispatcher &, TaskId &) {
hrtime_t start_time(gethrtime()); hrtime_t start_time(gethrtime());
vbucket_del_result result = ep->completeVBucketDeletion(vbucket); vbucket_del_result result = ep->completeVBucketDeletion(vbucket, recreate);
if (result == vbucket_del_success || result == vbucket_del_invalid) { if (result == vbucket_del_success || result == vbucket_del_invalid) {
hrtime_t spent(gethrtime() - start_time); hrtime_t spent(gethrtime() - start_time);
hrtime_t wall_time = spent / 1000; hrtime_t wall_time = spent / 1000;
Expand Down Expand Up @@ -283,6 +283,7 @@ class VBucketDeletionCallback : public DispatcherCallback {
uint16_t vbucket; uint16_t vbucket;
EPStats &stats; EPStats &stats;
const void* cookie; const void* cookie;
bool recreate;
}; };


EventuallyPersistentStore::EventuallyPersistentStore(EventuallyPersistentEngine &theEngine, EventuallyPersistentStore::EventuallyPersistentStore(EventuallyPersistentEngine &theEngine,
Expand Down Expand Up @@ -958,13 +959,13 @@ void EventuallyPersistentStore::scheduleVBSnapshot(const Priority &p) {
} }


vbucket_del_result vbucket_del_result
EventuallyPersistentStore::completeVBucketDeletion(uint16_t vbid) { EventuallyPersistentStore::completeVBucketDeletion(uint16_t vbid, bool recreate) {
LockHolder lh(vbsetMutex); LockHolder lh(vbsetMutex);


RCPtr<VBucket> vb = vbuckets.getBucket(vbid); RCPtr<VBucket> vb = vbuckets.getBucket(vbid);
if (!vb || vb->getState() == vbucket_state_dead || vbuckets.isBucketDeletion(vbid)) { if (!vb || vb->getState() == vbucket_state_dead || vbuckets.isBucketDeletion(vbid)) {
lh.unlock(); lh.unlock();
if (rwUnderlying->delVBucket(vbid)) { if (rwUnderlying->delVBucket(vbid, recreate)) {
vbuckets.setBucketDeletion(vbid, false); vbuckets.setBucketDeletion(vbid, false);
mutationLog.deleteAll(vbid); mutationLog.deleteAll(vbid);
// This is happening in an independent transaction, so // This is happening in an independent transaction, so
Expand All @@ -982,14 +983,17 @@ EventuallyPersistentStore::completeVBucketDeletion(uint16_t vbid) {
} }


void EventuallyPersistentStore::scheduleVBDeletion(RCPtr<VBucket> &vb, void EventuallyPersistentStore::scheduleVBDeletion(RCPtr<VBucket> &vb,
const void* cookie=NULL, double delay=0) { const void* cookie,
double delay,
bool recreate) {
shared_ptr<DispatcherCallback> mem_cb(new VBucketMemoryDeletionCallback(this, vb)); shared_ptr<DispatcherCallback> mem_cb(new VBucketMemoryDeletionCallback(this, vb));
nonIODispatcher->schedule(mem_cb, NULL, Priority::VBMemoryDeletionPriority, delay, false); nonIODispatcher->schedule(mem_cb, NULL, Priority::VBMemoryDeletionPriority, delay, false);


if (vbuckets.setBucketDeletion(vb->getId(), true)) { if (vbuckets.setBucketDeletion(vb->getId(), true)) {
shared_ptr<DispatcherCallback> cb(new VBucketDeletionCallback(this, vb, shared_ptr<DispatcherCallback> cb(new VBucketDeletionCallback(this, vb,
stats, stats,
cookie)); cookie,
recreate));
dispatcher->schedule(cb, dispatcher->schedule(cb,
NULL, Priority::VBucketDeletionPriority, NULL, Priority::VBucketDeletionPriority,
delay, false); delay, false);
Expand Down Expand Up @@ -1037,8 +1041,8 @@ bool EventuallyPersistentStore::resetVBucket(uint16_t vbid) {
RCPtr<VBucket> newvb = vbuckets.getBucket(vbid); RCPtr<VBucket> newvb = vbuckets.getBucket(vbid);
newvb->checkpointManager.resetTAPCursors(vb->checkpointManager.getTAPCursorNames()); newvb->checkpointManager.resetTAPCursors(vb->checkpointManager.getTAPCursorNames());


// Clear all the items from the vbucket kv table on disk. // Delete the vbucket database file and recreate the empty file
scheduleVBDeletion(vb); scheduleVBDeletion(vb, NULL, 0, true);
rv = true; rv = true;
} }
return rv; return rv;
Expand Down
6 changes: 4 additions & 2 deletions src/ep.hh
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -540,7 +540,7 @@ public:
/** /**
* Perform a fast vbucket deletion. * Perform a fast vbucket deletion.
*/ */
vbucket_del_result completeVBucketDeletion(uint16_t vbid); vbucket_del_result completeVBucketDeletion(uint16_t vbid, bool recreate);


/** /**
* Deletes a vbucket * Deletes a vbucket
Expand Down Expand Up @@ -732,7 +732,9 @@ protected:
private: private:


void scheduleVBDeletion(RCPtr<VBucket> &vb, void scheduleVBDeletion(RCPtr<VBucket> &vb,
const void* cookie, double delay); const void* cookie,
double delay = 0,
bool recreate = false);


RCPtr<VBucket> getVBucket(uint16_t vbid, vbucket_state_t wanted_state); RCPtr<VBucket> getVBucket(uint16_t vbid, vbucket_state_t wanted_state);


Expand Down
6 changes: 5 additions & 1 deletion src/kvstore.hh
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@
typedef std::pair<int, int64_t> mutation_result; typedef std::pair<int, int64_t> mutation_result;


struct vbucket_state { struct vbucket_state {
vbucket_state() { }
vbucket_state(vbucket_state_t _state, uint64_t _chkid, uint64_t _maxDelSeqNum) :
state(_state), checkpointId(_chkid), maxDeletedSeqno(_maxDelSeqNum) { }

vbucket_state_t state; vbucket_state_t state;
uint64_t checkpointId; uint64_t checkpointId;
uint64_t maxDeletedSeqno; uint64_t maxDeletedSeqno;
Expand Down Expand Up @@ -195,7 +199,7 @@ public:
/** /**
* Delete a given vbucket database. * Delete a given vbucket database.
*/ */
virtual bool delVBucket(uint16_t vbucket) = 0; virtual bool delVBucket(uint16_t vbucket, bool recreate = false) = 0;


/** /**
* Get a list of all persisted vbuckets (with their states). * Get a list of all persisted vbuckets (with their states).
Expand Down

0 comments on commit d369500

Please sign in to comment.