1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
/** @file touch.cpp
compaction of deleted space in pdfiles (datafiles)
*/
/**
* Copyright (C) 2012 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,b
* 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/>.
*/
#include "mongo/pch.h"
#include <string>
#include <vector>
#include "mongo/db/auth/action_set.h"
#include "mongo/db/auth/action_type.h"
#include "mongo/db/auth/authorization_manager.h"
#include "mongo/db/auth/privilege.h"
#include "mongo/db/commands.h"
#include "mongo/db/d_concurrency.h"
#include "mongo/db/curop-inl.h"
#include "mongo/db/index.h"
#include "mongo/db/jsobj.h"
#include "mongo/db/pdfile.h"
#include "mongo/util/timer.h"
#include "mongo/util/touch_pages.h"
namespace mongo {
class TouchCmd : public Command {
public:
virtual LockType locktype() const { return NONE; }
virtual bool adminOnly() const { return false; }
virtual bool slaveOk() const { return true; }
virtual bool maintenanceMode() const { return true; }
virtual bool logTheOp() { return false; }
virtual void help( stringstream& help ) const {
help << "touch collection\n"
"Page in all pages of memory containing every extent for the given collection\n"
"{ touch : <collection_name>, [data : true] , [index : true] }\n"
" at least one of data or index must be true; default is both are false\n";
}
virtual void addRequiredPrivileges(const std::string& dbname,
const BSONObj& cmdObj,
std::vector<Privilege>* out) {
ActionSet actions;
actions.addAction(ActionType::touch);
out->push_back(Privilege(AuthorizationManager::SERVER_RESOURCE_NAME, actions));
}
TouchCmd() : Command("touch") { }
virtual bool run(const string& db,
BSONObj& cmdObj,
int,
string& errmsg,
BSONObjBuilder& result,
bool fromRepl) {
string coll = cmdObj.firstElement().valuestr();
if( coll.empty() || db.empty() ) {
errmsg = "no collection name specified";
return false;
}
string ns = db + '.' + coll;
if ( ! NamespaceString::normal(ns.c_str()) ) {
errmsg = "bad namespace name";
return false;
}
bool touch_indexes( cmdObj["index"].trueValue() );
bool touch_data( cmdObj["data"].trueValue() );
if ( ! (touch_indexes || touch_data) ) {
errmsg = "must specify at least one of (data:true, index:true)";
return false;
}
bool ok = touch( ns, errmsg, touch_data, touch_indexes, result );
return ok;
}
bool touch( std::string& ns,
std::string& errmsg,
bool touch_data,
bool touch_indexes,
BSONObjBuilder& result ) {
if (touch_data) {
log() << "touching namespace " << ns << endl;
touchNs( ns );
log() << "touching namespace " << ns << " complete" << endl;
}
if (touch_indexes) {
// enumerate indexes
std::vector< std::string > indexes;
{
Client::ReadContext ctx(ns);
NamespaceDetails *nsd = nsdetails(ns);
massert( 16153, "namespace does not exist", nsd );
NamespaceDetails::IndexIterator ii = nsd->ii();
while ( ii.more() ) {
IndexDetails& idx = ii.next();
indexes.push_back( idx.indexNamespace() );
}
}
for ( std::vector<std::string>::const_iterator it = indexes.begin();
it != indexes.end();
it++ ) {
touchNs( *it );
}
}
return true;
}
};
static TouchCmd touchCmd;
}
|