Skip to content

Commit 0e4ef6a

Browse files
SERVER-16749: handle per index exceptions and continue
1 parent e339dbf commit 0e4ef6a

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed

jstests/noPassthrough/ttl_capped.js

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* Test that a capped collection ttl index doesn't cause the server to shut down,
3+
* nor stop processing collections in the db
4+
* TODO: Change this test to show that you can't create capped collection ttl index
5+
* Will need to figure out how to test that failed index ttl processing doesn't block others
6+
*/
7+
(function() {
8+
"use strict";
9+
var baseDir = "jstests_ttl_capped";
10+
var port = allocatePorts( 1 )[ 0 ];
11+
var dbpath = MongoRunner.dataPath + baseDir + "/";
12+
13+
var m = MongoRunner.runMongod({
14+
dbpath: dbpath,
15+
port: port,
16+
setParameter:"ttlMonitorSleepSecs=1"});
17+
var db = m.getDB( "test" );
18+
19+
// Make sure we have collections before and after the capped one, so we can check they work.
20+
var bc = db.ttl_before;
21+
var t = db.ttl_capped;
22+
var ac = db.ttl_zafter;
23+
24+
t.drop();
25+
bc.drop();
26+
ac.drop();
27+
var dt = (new Date()).getTime();
28+
jsTest.log("using date on inserted docs: " + tojson(new Date(dt)));
29+
30+
// increase logging
31+
assert.commandWorked(db.adminCommand({setParameter:1, logLevel:1}));
32+
33+
bc.ensureIndex( { x : 1 } , { expireAfterSeconds : -1 } );
34+
assert.commandWorked(t.runCommand( "create", { capped:true, size:100, maxCount:100} ));
35+
t.ensureIndex( { x : 1 } , { expireAfterSeconds : -1 } );
36+
ac.ensureIndex( { x : 1 } , { expireAfterSeconds : -1 } );
37+
38+
assert.writeOK(bc.insert({x: new Date(dt)}));
39+
assert.writeOK(t.insert({x: new Date(dt)}));
40+
assert.writeOK(ac.insert({x: new Date(dt)}));
41+
42+
assert.eq(bc.count(), 1);
43+
assert.eq(t.count(), 1);
44+
assert.eq(ac.count(), 1);
45+
46+
sleep(1.1 * 1000); // 2 second sleep
47+
jsTest.log("TTL work should be done.")
48+
assert.eq(bc.count(), 0);
49+
assert.eq(t.count(), 1);
50+
assert.eq(ac.count(), 0);
51+
52+
MongoRunner.stopMongod(port);
53+
})();

src/mongo/db/ttl.cpp

+14-6
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ namespace mongo {
6969
ServerStatusMetricField<Counter64> ttlDeletedDocumentsDisplay("ttl.deletedDocuments", &ttlDeletedDocuments);
7070

7171
MONGO_EXPORT_SERVER_PARAMETER( ttlMonitorEnabled, bool, true );
72+
MONGO_EXPORT_SERVER_PARAMETER( ttlMonitorSleepSecs, int, 60 ); //used for testing
7273

7374
class TTLMonitor : public BackgroundJob {
7475
public:
@@ -84,7 +85,7 @@ namespace mongo {
8485
cc().getAuthorizationSession()->grantInternalAuthorization();
8586

8687
while ( ! inShutdown() ) {
87-
sleepsecs( 60 );
88+
sleepsecs( ttlMonitorSleepSecs );
8889

8990
LOG(3) << "TTLMonitor thread awake" << endl;
9091

@@ -123,8 +124,16 @@ namespace mongo {
123124
for ( vector<BSONObj>::const_iterator it = indexes.begin();
124125
it != indexes.end(); ++it ) {
125126

126-
if ( !doTTLForIndex( &txn, db, *it ) ) {
127-
break; // stop processing TTL indexes on this database
127+
BSONObj idx = *it;
128+
try {
129+
if ( !doTTLForIndex( &txn, db, idx ) ) {
130+
break; // stop processing TTL indexes on this database
131+
}
132+
} catch (const DBException& dbex) {
133+
error() << "Error processing ttl index: " << idx
134+
<< " -- " << dbex.toString();
135+
// continue on to the next index
136+
continue;
128137
}
129138
}
130139
}
@@ -191,6 +200,7 @@ namespace mongo {
191200
*/
192201
bool doTTLForIndex( OperationContext* txn, const string& dbName, const BSONObj& idx ) {
193202
BSONObj key = idx["key"].Obj();
203+
const string ns = idx["ns"].String();
194204
if ( key.nFields() != 1 ) {
195205
error() << "key for ttl index can only have 1 field" << endl;
196206
return true;
@@ -210,13 +220,11 @@ namespace mongo {
210220
query = BSON( key.firstElement().fieldName() << b.obj() );
211221
}
212222

213-
LOG(1) << "TTL: " << key << " \t " << query << endl;
223+
LOG(1) << "TTL -- ns: " << ns << "key:" << key << " query: " << query << endl;
214224

215225
long long numDeleted = 0;
216226
int attempt = 1;
217227
while (1) {
218-
const string ns = idx["ns"].String();
219-
220228
ScopedTransaction scopedXact(txn, MODE_IX);
221229
AutoGetDb autoDb(txn, dbName, MODE_IX);
222230
Database* db = autoDb.getDb();

0 commit comments

Comments
 (0)