Storage Engine API
mmap.h
Go to the documentation of this file.
1 /* Copyright 2009 10gen Inc.
2  *
3  * This program is free software: you can redistribute it and/or modify
4  * it under the terms of the GNU Affero General Public License, version 3,
5  * as published by the Free Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU Affero General Public License for more details.
11  *
12  * You should have received a copy of the GNU Affero General Public License
13  * along with this program. If not, see <http://www.gnu.org/licenses/>.
14  *
15  * As a special exception, the copyright holders give permission to link the
16  * code of portions of this program with the OpenSSL library under certain
17  * conditions as described in each individual source file and distribute
18  * linked combinations including the program with the OpenSSL library. You
19  * must comply with the GNU Affero General Public License in all respects
20  * for all of the code used other than as permitted herein. If you modify
21  * file(s) with this exception, you may extend this exception to your
22  * version of the file(s), but you are not obligated to do so. If you do not
23  * wish to do so, delete this exception statement from your version. If you
24  * delete this exception statement from all source files in the program,
25  * then also delete it in the license file.
26  */
27 
28 #pragma once
29 
30 #include <set>
31 #include <sstream>
32 #include <vector>
33 
34 #include "mongo/base/disallow_copying.h"
35 #include "mongo/db/client.h"
37 #include "mongo/db/operation_context.h"
38 
39 namespace mongo {
40 
41 #if !defined(_WIN32)
42 typedef int HANDLE;
43 #endif
44 
45 extern std::size_t getMinOSPageSizeBytes();
46 void minOSPageSizeBytesTest(size_t minOSPageSizeBytes); // lame-o
47 
48 // call this if syncing data fails
50 
51 class MAdvise {
53 
54 public:
55  enum Advice { Sequential = 1, Random = 2 };
56  MAdvise(void* p, unsigned len, Advice a);
57  ~MAdvise(); // destructor resets the range to MADV_NORMAL
58 private:
59  void* _p;
60  unsigned _len;
61 };
62 
63 // lock order: lock dbMutex before this if you lock both
67  static unsigned era;
68 
70 
71 public:
72  explicit LockMongoFilesShared(OperationContext* opCtx) : lk(opCtx->lockState(), mmmutex) {
73  // JS worker threads may not have cc() setup, as they work on behalf of other clients
74  dassert(opCtx == cc().getOperationContext() || !cc().getOperationContext());
75  }
76 
77  static void assertExclusivelyLocked(OperationContext* opCtx) {
78  invariant(mmmutex.isExclusivelyLocked(opCtx->lockState()));
79  }
80 
81  static void assertAtLeastReadLocked(OperationContext* opCtx) {
82  invariant(mmmutex.isAtLeastReadLocked(opCtx->lockState()));
83  }
84 
91  static unsigned getEra() {
92  return era;
93  }
94 };
95 
98 
99 public:
100  explicit LockMongoFilesExclusive(OperationContext* opCtx)
101  : lk(opCtx->lockState(), LockMongoFilesShared::mmmutex) {
102  // JS worker threads may not have cc() setup, as they work on behalf of other clients
103  dassert(opCtx == cc().getOperationContext() || !cc().getOperationContext());
105  }
106 };
107 
108 /* the administrative-ish stuff here */
109 class MongoFile {
111 
112 public:
114  class Flushable {
115  public:
116  virtual ~Flushable() {}
117  virtual void flush(OperationContext* opCtx) = 0;
118  };
119 
120  enum Options {
121  NONE = 0,
122  SEQUENTIAL = 1 << 0, // hint - e.g. FILE_FLAG_SEQUENTIAL_SCAN on windows.
123  READONLY = 1 << 1 // if true, writing to the mapped file will crash the process.
124  };
125 
126  // Integral type used as a BitSet of Options.
127  using OptionSet = std::underlying_type<Options>::type;
128 
130  virtual ~MongoFile() = default;
131 
135  template <class F>
136  static void forEach(OperationContext* opCtx, F fun);
137 
142  static std::set<MongoFile*>& getAllFiles();
143 
144  static int flushAll(OperationContext* opCtx, bool sync); // returns n flushed
145  static void closeAllFiles(OperationContext* opCtx, std::stringstream& message);
146 
147  virtual bool isDurableMappedFile() {
148  return false;
149  }
150 
151  std::string filename() const {
152  return _filename;
153  }
154  void setFilename(OperationContext* opCtx, const std::string& fn);
155 
156  virtual uint64_t getUniqueId() const = 0;
157 
158 private:
159  std::string _filename;
160  static int _flushAll(OperationContext* opCtx, bool sync); // returns n flushed
162 
163 protected:
167  virtual void close(OperationContext* opCtx) = 0;
168  virtual void flush(bool sync) = 0;
173  virtual Flushable* prepareFlush() = 0;
174 
178  virtual bool isClosed() = 0;
179 
180  void created(OperationContext* opCtx); /* subclass must call after create */
181 
190  void destroyed(OperationContext* opCtx);
191 
192  virtual unsigned long long length() const = 0;
193 
194  bool isOptionSet(Options option) const {
195  return _options & option;
196  }
197 };
198 
207 
208 public:
209  MongoFileFinder(OperationContext* opCtx) : _lk(opCtx) {}
210 
214  MongoFile* findByPath(const std::string& path) const;
215 
216 private:
218 };
219 
220 class MemoryMappedFile : public MongoFile {
221 protected:
222  virtual void* viewForFlushing() {
223  if (views.size() == 0)
224  return 0;
225  verify(views.size() == 1);
226  return views[0];
227  }
228 
229 public:
230  MemoryMappedFile(OperationContext* opCtx, OptionSet options = NONE);
231 
232  virtual ~MemoryMappedFile();
233 
237  virtual void close(OperationContext* opCtx);
238 
242  void* map(OperationContext* opCtx, const char* filename);
243 
248  void* create(OperationContext* opCtx,
249  const std::string& filename,
250  unsigned long long len,
251  bool zero);
252 
253  void flush(bool sync);
254 
255  virtual bool isClosed();
256 
257  virtual Flushable* prepareFlush();
258 
259  long shortLength() const {
260  return (long)len;
261  }
262  unsigned long long length() const {
263  return len;
264  }
265  HANDLE getFd() const {
266  return fd;
267  }
268 
273  void* createPrivateMap();
274 
275  virtual uint64_t getUniqueId() const {
276  return _uniqueId;
277  }
278 
279  static int totalMappedLengthInMB() {
280  return static_cast<int>(totalMappedLength.load() / 1024 / 1024);
281  }
282 
283 private:
284  static void updateLength(const char* filename, unsigned long long& length);
285 
286  HANDLE fd = 0;
287  HANDLE maphandle = 0;
288  std::vector<void*> views;
289  unsigned long long len = 0u;
290  static AtomicUInt64 totalMappedLength;
291  const uint64_t _uniqueId;
292 #ifdef _WIN32
293  // flush Mutex
294  //
295  // Protects:
296  // Prevent flush() and close() from concurrently running.
297  // It ensures close() cannot complete while flush() is running
298  // Lock Ordering:
299  // LockMongoFilesShared must be taken before _flushMutex if both are taken
300  stdx::mutex _flushMutex;
301 #endif
302 
303 protected:
308  void* map(OperationContext* opCtx, const char* filename, unsigned long long& length);
309 
313  void* remapPrivateView(OperationContext* opCtx, void* oldPrivateAddr);
314 };
315 
317 template <class F>
318 inline void MongoFile::forEach(OperationContext* opCtx, F p) {
319  LockMongoFilesShared lklk(opCtx);
320  const std::set<MongoFile*>& mmfiles = MongoFile::getAllFiles();
321  for (std::set<MongoFile*>::const_iterator i = mmfiles.begin(); i != mmfiles.end(); i++)
322  p(*i);
323 }
324 
325 } // namespace mongo
Advice
Definition: mmap.h:55
look up a MMF by filename.
Definition: mmap.h:205
std::vector< void * > views
Definition: mmap.h:288
unsigned long long length() const
Definition: mmap.h:262
static unsigned getEra()
era changes anytime memory maps come and go.
Definition: mmap.h:91
static void forEach(OperationContext *opCtx, F fun)
p is called from within a mutex that MongoFile uses.
Definition: mmap.h:318
Definition: mmap.h:220
MongoFileFinder(OperationContext *opCtx)
Definition: mmap.h:209
bool isExclusivelyLocked(Locker *locker)
Definition: d_concurrency.cpp:131
size_t length
Definition: record_store_v1_base.cpp:852
Options
Definition: mmap.h:120
~MAdvise()
Definition: mmap_posix.cpp:158
virtual uint64_t getUniqueId() const
Definition: mmap.h:275
Copyright (C) 2014 MongoDB Inc.
Definition: bson_collection_catalog_entry.cpp:38
std::string _filename
Definition: mmap.h:159
static void assertExclusivelyLocked(OperationContext *opCtx)
Definition: mmap.h:77
static int totalMappedLengthInMB()
Definition: mmap.h:279
static AtomicUInt64 totalMappedLength
Definition: mmap.h:290
static void assertAtLeastReadLocked(OperationContext *opCtx)
Definition: mmap.h:81
Definition: mmap.h:51
HANDLE getFd() const
Definition: mmap.h:265
virtual bool isDurableMappedFile()
Definition: mmap.h:147
virtual ~Flushable()
Definition: mmap.h:116
virtual void * viewForFlushing()
Definition: mmap.h:222
std::underlying_type< Options >::type OptionSet
Definition: mmap.h:127
int HANDLE
Definition: mmap.h:42
Definition: mmap.h:64
bool isAtLeastReadLocked(Locker *locker)
Definition: d_concurrency.cpp:135
const uint64_t _uniqueId
Definition: mmap.h:291
LockMongoFilesExclusive(OperationContext *opCtx)
Definition: mmap.h:100
Lock::ExclusiveLock lk
Definition: mmap.h:97
const OptionSet _options
Definition: mmap.h:161
bool isOptionSet(Options option) const
Definition: mmap.h:194
void minOSPageSizeBytesTest(size_t minOSPageSizeBytes)
Definition: mmap.cpp:59
MONGO_DISALLOW_COPYING(MAdvise)
Obtains a ResourceMutex for shared/non-exclusive use.
Definition: d_concurrency.h:163
unsigned _len
Definition: mmap.h:60
static void remapPrivateView(OperationContext *opCtx, double fraction)
Remaps the private view from the shared view so that it does not consume too much copy-on-write/swap ...
Definition: dur.cpp:631
static Lock::ResourceMutex mmmutex
Definition: mmap.h:66
Flushable has to fail nicely if the underlying object gets killed.
Definition: mmap.h:114
void * _p
Definition: mmap.h:59
std::size_t getMinOSPageSizeBytes()
Definition: mmap_posix.cpp:72
static unsigned era
Definition: mmap.h:67
OperationContext Database StringData BSONObj options
Definition: database_impl.cpp:949
void dataSyncFailedHandler()
Definition: mmap.cpp:246
Definition: mmap.h:96
For use as general mutex or readers/writers lock, outside the general multi-granularity model...
Definition: d_concurrency.h:121
Definition: mmap.h:109
LockMongoFilesShared(OperationContext *opCtx)
Definition: mmap.h:72
Lock::SharedLock lk
Definition: mmap.h:69
LockMongoFilesShared _lk
Definition: mmap.h:217
long shortLength() const
Definition: mmap.h:259
std::string filename() const
Definition: mmap.h:151
Collection *const OperationContext *const opCtx
Definition: collection_impl.cpp:80
static std::set< MongoFile * > & getAllFiles()
note: you need to be in mmmutex when using this.
Definition: mmap.cpp:144
Definition: mmap.h:55
Definition: mmap.h:55
MAdvise(void *p, unsigned len, Advice a)
Definition: mmap_posix.cpp:139
Obtains a ResourceMutex for exclusive use.
Definition: d_concurrency.h:152