Skip to content

Commit 9b84368

Browse files
committed
storage analyze
1 parent 48c386a commit 9b84368

14 files changed

+233
-12
lines changed

mongo/src/mongo/db/catalog/index_catalog_entry_impl.cpp

+2-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ MultikeyPaths IndexCatalogEntryImpl::getMultikeyPaths(OperationContext* opCtx) c
184184
}
185185

186186
// ---
187-
187+
//索引创建成功,标记一下
188188
void IndexCatalogEntryImpl::setIsReady(bool newIsReady) {
189189
_isReady = newIsReady;
190190
}
@@ -348,6 +348,7 @@ RecordId IndexCatalogEntryImpl::_catalogHead(OperationContext* opCtx) const {
348348

349349
bool IndexCatalogEntryImpl::_catalogIsMultikey(OperationContext* opCtx,
350350
MultikeyPaths* multikeyPaths) const {
351+
//KVCollectionCatalogEntry::isIndexMultikey
351352
return _collection->isIndexMultikey(opCtx, _descriptor->indexName(), multikeyPaths);
352353
}
353354

mongo/src/mongo/db/catalog/index_catalog_impl.cpp

+13-6
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,7 @@ IndexCatalogImpl::~IndexCatalogImpl() {
133133

134134
//CollectionImpl::init中调用
135135
//例如mongod实例重启得时候会调用
136+
//从元数据文件"_mdb_catalog.wt"中获取索引信息,并构造索引对应的IndexCatalogEntryImpl
136137
Status IndexCatalogImpl::init(OperationContext* opCtx) {
137138
vector<string> indexNames;
138139
//BSONCollectionCatalogEntry::getAllIndexes
@@ -161,7 +162,7 @@ Status IndexCatalogImpl::init(OperationContext* opCtx) {
161162
auto descriptor = stdx::make_unique<IndexDescriptor>(
162163
_collection, _getAccessMethodName(opCtx, keyPattern), spec);
163164
const bool initFromDisk = true;
164-
//获取descriptor该索引对应的IndexCatalogEntryImpl添加到_entries数组
165+
//获取descriptor该索引对应的IndexCatalogEntryImpl添加到IndexCatalogImpl._entries数组
165166
//一个索引对应一个IndexCatalogEntry
166167
IndexCatalogEntry* entry =
167168
_setupInMemoryStructures(opCtx, std::move(descriptor), initFromDisk);
@@ -407,7 +408,7 @@ StatusWith<BSONObj> IndexCatalogImpl::createIndexOnEmptyCollection(OperationCont
407408
// now going to touch disk
408409
IndexBuildBlock indexBuildBlock(opCtx, _collection, spec);
409410
//IndexCatalogImpl::IndexBuildBlock::init
410-
//该索引初始化
411+
//对IndexBuildBlock对应的索引进行初始化,创建索引对应的存储引擎底层索引文件
411412
status = indexBuildBlock.init();
412413
if (!status.isOK())
413414
return status;
@@ -459,7 +460,7 @@ IndexCatalogImpl::IndexBuildBlock::IndexBuildBlock(OperationContext* opCtx,
459460
//CmdCreateIndex::errmsgRun->MultiIndexBlockImpl::init调用(收到createIndex建索引)
460461

461462
////获取descriptor该索引对应的IndexCatalogEntryImpl添加到_entries数组
462-
//对IndexBuildBlock对应的索引进行初始化
463+
//对IndexBuildBlock对应的索引进行初始化,创建索引对应的存储引擎底层索引文件
463464
Status IndexCatalogImpl::IndexBuildBlock::init() {
464465
// need this first for names, etc...
465466
//获取所有信息的key,可以db.collection.getIndexes()获取
@@ -478,7 +479,7 @@ Status IndexCatalogImpl::IndexBuildBlock::init() {
478479
/// ---------- setup on disk structures ----------------
479480

480481
//KVCollectionCatalogEntry::prepareForIndexBuild
481-
//准备工作
482+
//创建索引的准备工作,并创建存储引擎对应索引目录文件
482483
Status status = _collection->getCatalogEntry()->prepareForIndexBuild(_opCtx, descriptor.get());
483484
if (!status.isOK())
484485
return status;
@@ -505,14 +506,16 @@ IndexCatalogImpl::IndexBuildBlock::~IndexBuildBlock() {
505506
// Don't need to call fail() here, as rollback will clean everything up for us.
506507
}
507508

508-
//失败处理
509+
//MultiIndexBlockImpl::~MultiIndexBlockImpl()调用
509510
void IndexCatalogImpl::IndexBuildBlock::fail() {
510511
fassert(17204, _catalog->_getCollection()->ok()); // defensive
511512

513+
512514
IndexCatalogEntry* entry = IndexCatalog::_getEntries(_catalog).find(_indexName);
513515
invariant(entry == _entry);
514516

515517
if (entry) {
518+
//同时删除内存缓存的entry,并从磁盘删除
516519
IndexCatalogImpl::_dropIndex(_catalog, _opCtx, entry).transitional_ignore();
517520
} else {
518521
IndexCatalog::_deleteIndexFromDisk(_catalog, _opCtx, _indexName, _indexNamespace);
@@ -557,6 +560,7 @@ void IndexCatalogImpl::IndexBuildBlock::success() {
557560
collection->setMinimumVisibleSnapshot(snapshotName);
558561
});
559562

563+
//索引创建成功,标记一下
560564
entry->setIsReady(true);
561565
}
562566

@@ -958,6 +962,7 @@ Status IndexCatalogImpl::_doesSpecConflictWithExisting(OperationContext* opCtx,
958962
return Status::OK();
959963
}
960964

965+
//
961966
BSONObj IndexCatalogImpl::getDefaultIdIndexSpec(
962967
ServerGlobalParams::FeatureCompatibility::Version featureCompatibilityVersion) const {
963968
dassert(_idObj["_id"].type() == NumberInt);
@@ -1209,12 +1214,14 @@ vector<BSONObj> IndexCatalogImpl::getAndClearUnfinishedIndexes(OperationContext*
12091214
return toReturn;
12101215
}
12111216

1217+
//判断指定索引是否是Multikey类型
12121218
bool IndexCatalogImpl::isMultikey(OperationContext* opCtx, const IndexDescriptor* idx) {
12131219
IndexCatalogEntry* entry = _entries.find(idx);
12141220
invariant(entry);
12151221
return entry->isMultikey();
12161222
}
12171223

1224+
//获取指定索引对应的MultikeyPaths
12181225
MultikeyPaths IndexCatalogImpl::getMultikeyPaths(OperationContext* opCtx,
12191226
const IndexDescriptor* idx) {
12201227
IndexCatalogEntry* entry = _entries.find(idx);
@@ -1223,7 +1230,7 @@ MultikeyPaths IndexCatalogImpl::getMultikeyPaths(OperationContext* opCtx,
12231230
}
12241231

12251232
// ---------------------------
1226-
1233+
//该表是否有至少有一个索引
12271234
bool IndexCatalogImpl::haveAnyIndexes() const {
12281235
return _entries.size() != 0;
12291236
}

mongo/src/mongo/db/catalog/index_catalog_impl.h

+1
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ class IndexCatalogImpl : public IndexCatalog::Impl {
179179
*/
180180
Status checkUnfinished() const override;
181181

182+
//迭代器
182183
class IndexIteratorImpl : public IndexCatalog::IndexIterator::Impl {
183184
public:
184185
IndexIteratorImpl(OperationContext* opCtx,

mongo/src/mongo/db/catalog/index_create_impl.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ MultiIndexBlockImpl::MultiIndexBlockImpl(OperationContext* opCtx, Collection* co
165165
_ignoreUnique(false),
166166
_needToCleanup(true) {}
167167

168+
//清除所有索引
168169
MultiIndexBlockImpl::~MultiIndexBlockImpl() {
169170
if (!_needToCleanup || _indexes.empty())
170171
return;
@@ -175,6 +176,7 @@ MultiIndexBlockImpl::~MultiIndexBlockImpl() {
175176
// Because that may need to write, it is done inside
176177
// of a WUOW. Nothing inside this block can fail, and it is made fatal if it does.
177178
for (size_t i = 0; i < _indexes.size(); i++) {
179+
//IndexCatalogImpl::IndexBuildBlock::fail()
178180
_indexes[i].block->fail();
179181
}
180182
wunit.commit();

mongo/src/mongo/db/index/multikey_paths.h

+75
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,81 @@ namespace mongo {
220220
ns: "test.user",
221221
ident: "test/collection/1--8777216180098127804"
222222
}
223+
224+
225+
226+
> db.user.getIndexes()
227+
[
228+
{
229+
"v" : 2,
230+
"key" : {
231+
"_id" : 1
232+
},
233+
"name" : "_id_",
234+
"ns" : "test.user"
235+
},
236+
{
237+
"v" : 2,
238+
"key" : {
239+
"name" : 1,
240+
"aihao.aa" : 1,
241+
"aihao.bb" : -1,
242+
"aihao.aa.cc" : 1,
243+
"aihao.bb.cc" : -1
244+
},
245+
"name" : "name_1_aihao.aa_1_aihao.bb_-1_aihao.aa.cc_1_aihao.bb.cc_-1",
246+
"ns" : "test.user"
247+
},
248+
{
249+
"v" : 2,
250+
"key" : {
251+
"yangtest1" : 1
252+
},
253+
"name" : "yangtest1_1",
254+
"ns" : "test.user",
255+
"background" : true
256+
}
257+
]
258+
>
259+
> db.user.find()
260+
{ "_id" : ObjectId("6051d0eadc66165aba0feb51"), "name" : "yangyazhou", "aihao" : [ { "aa" : "aaa", "bb" : "bbb" }, { "aa" : "aaa2", "bb" : "bbb2" }, { "aa" : "aaa3", "bb" : "bbb3" } ] }
261+
{ "_id" : ObjectId("6052cf588a685826f0daf714"), "name" : "yangyazhou", "aihao" : [ { "aa" : [ { "cc" : "ccc1" }, { "cc" : "ccc2" } ], "bb" : "bbb3" } ] }
262+
>
263+
>
264+
> db.user.find({"name" : "yangyazhou", "aihao.aa":"aaa"})
265+
{ "_id" : ObjectId("6051d0eadc66165aba0feb51"), "name" : "yangyazhou", "aihao" : [ { "aa" : "aaa", "bb" : "bbb" }, { "aa" : "aaa2", "bb" : "bbb2" }, { "aa" : "aaa3", "bb" : "bbb3" } ] }
266+
>
267+
> 参考appendMultikeyPaths
268+
db.user.find({"name" : "yangyazhou", "aihao.aa":"aaa"})对应.explain("allPlansExecution")输出如下:
269+
270+
271+
"keyPattern" : {
272+
"name" : 1,
273+
"aihao.aa" : 1,
274+
"aihao.bb" : -1,
275+
"aihao.aa.cc" : 1,
276+
"aihao.bb.cc" : -1
277+
},
278+
"indexName" : "name_1_aihao.aa_1_aihao.bb_-1_aihao.aa.cc_1_aihao.bb.cc_-1",
279+
"isMultiKey" : true,
280+
"multiKeyPaths" : {
281+
"name" : [ ],
282+
"aihao.aa" : [
283+
"aihao",
284+
"aihao.aa"
285+
],
286+
"aihao.bb" : [
287+
"aihao"
288+
],
289+
"aihao.aa.cc" : [
290+
"aihao",
291+
"aihao.aa"
292+
],
293+
"aihao.bb.cc" : [
294+
"aihao"
295+
]
296+
},
297+
223298
*/
224299

225300

mongo/src/mongo/db/query/explain.cpp

+72
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,78 @@ void addStageSummaryStr(const PlanStage* stage, StringBuilder& sb) {
216216
*
217217
* This function should only be called if the associated index supports path-level multikey
218218
* tracking.
219+
220+
> db.user.getIndexes()
221+
[
222+
{
223+
"v" : 2,
224+
"key" : {
225+
"_id" : 1
226+
},
227+
"name" : "_id_",
228+
"ns" : "test.user"
229+
},
230+
{
231+
"v" : 2,
232+
"key" : {
233+
"name" : 1,
234+
"aihao.aa" : 1,
235+
"aihao.bb" : -1,
236+
"aihao.aa.cc" : 1,
237+
"aihao.bb.cc" : -1
238+
},
239+
"name" : "name_1_aihao.aa_1_aihao.bb_-1_aihao.aa.cc_1_aihao.bb.cc_-1",
240+
"ns" : "test.user"
241+
},
242+
{
243+
"v" : 2,
244+
"key" : {
245+
"yangtest1" : 1
246+
},
247+
"name" : "yangtest1_1",
248+
"ns" : "test.user",
249+
"background" : true
250+
}
251+
]
252+
>
253+
> db.user.find()
254+
{ "_id" : ObjectId("6051d0eadc66165aba0feb51"), "name" : "yangyazhou", "aihao" : [ { "aa" : "aaa", "bb" : "bbb" }, { "aa" : "aaa2", "bb" : "bbb2" }, { "aa" : "aaa3", "bb" : "bbb3" } ] }
255+
{ "_id" : ObjectId("6052cf588a685826f0daf714"), "name" : "yangyazhou", "aihao" : [ { "aa" : [ { "cc" : "ccc1" }, { "cc" : "ccc2" } ], "bb" : "bbb3" } ] }
256+
>
257+
>
258+
> db.user.find({"name" : "yangyazhou", "aihao.aa":"aaa"})
259+
{ "_id" : ObjectId("6051d0eadc66165aba0feb51"), "name" : "yangyazhou", "aihao" : [ { "aa" : "aaa", "bb" : "bbb" }, { "aa" : "aaa2", "bb" : "bbb2" }, { "aa" : "aaa3", "bb" : "bbb3" } ] }
260+
>
261+
>
262+
db.user.find({"name" : "yangyazhou", "aihao.aa":"aaa"})¶ÔÓ¦.explain("allPlansExecution")Êä³öÈçÏÂ:
263+
264+
265+
"keyPattern" : {
266+
"name" : 1,
267+
"aihao.aa" : 1,
268+
"aihao.bb" : -1,
269+
"aihao.aa.cc" : 1,
270+
"aihao.bb.cc" : -1
271+
},
272+
"indexName" : "name_1_aihao.aa_1_aihao.bb_-1_aihao.aa.cc_1_aihao.bb.cc_-1",
273+
"isMultiKey" : true,
274+
"multiKeyPaths" : {
275+
"name" : [ ],
276+
"aihao.aa" : [
277+
"aihao",
278+
"aihao.aa"
279+
],
280+
"aihao.bb" : [
281+
"aihao"
282+
],
283+
"aihao.aa.cc" : [
284+
"aihao",
285+
"aihao.aa"
286+
],
287+
"aihao.bb.cc" : [
288+
"aihao"
289+
]
290+
},
219291
*/
220292
void appendMultikeyPaths(const BSONObj& keyPattern,
221293
const MultikeyPaths& multikeyPaths,

mongo/src/mongo/db/service_context_d.cpp

+50
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,56 @@ void ServiceContextMongoD::shutdownGlobalStorageEngineCleanly() {
245245
}
246246
}
247247

248+
/*
249+
存储引擎注册识别区分流程:
250+
ServiceContextMongoD._storageFactories
251+
252+
void ServiceContextMongoD::registerStorageEngine(const std::string& name,
253+
const StorageEngine::Factory* factory) {
254+
// No double-registering.
255+
invariant(0 == _storageFactories.count(name));
256+
257+
// Some sanity checks: the factory must exist,
258+
invariant(factory);
259+
260+
// and all factories should be added before we pick a storage engine.
261+
invariant(NULL == _storageEngine);
262+
263+
_storageFactories[name] = factory;
264+
}
265+
266+
267+
MONGO_INITIALIZER_WITH_PREREQUISITES(DevNullEngineInit, ("SetGlobalEnvironment"))
268+
(InitializerContext* context) {
269+
getGlobalServiceContext()->registerStorageEngine("devnull", new DevNullStorageEngineFactory());------对应DevNullKVEngine
270+
return Status::OK();
271+
}
272+
}
273+
274+
275+
MONGO_INITIALIZER_WITH_PREREQUISITES(MMAPV1EngineInit, ("SetGlobalEnvironment"))
276+
(InitializerContext* context) {
277+
getGlobalServiceContext()->registerStorageEngine("mmapv1", new MMAPV1Factory()); --------对应MMAPV1Engine
278+
return Status::OK();
279+
}
280+
281+
MONGO_INITIALIZER_WITH_PREREQUISITES(WiredTigerEngineInit, ("SetGlobalEnvironment")) ---------WiredTigerKVEngine
282+
(InitializerContext* context) {
283+
getGlobalServiceContext()->registerStorageEngine(kWiredTigerEngineName,
284+
new WiredTigerFactory());
285+
286+
return Status::OK();
287+
}
288+
289+
ServiceContextMongoD::initializeGlobalStorageEngine() {
290+
//获取存储引擎,默认的WiredTiger存储引擎对应WiredTigerFactory
291+
const StorageEngine::Factory* factory = _storageFactories[storageGlobalParams.engine];
292+
//WiredTigerFactory::create //根据params参数构造KVStorageEngine类
293+
_storageEngine = factory->create(storageGlobalParams, _lockFile.get());
294+
_storageEngine->finishInit(); //void KVStorageEngine::finishInit() {}
295+
}
296+
*/
297+
248298
void ServiceContextMongoD::registerStorageEngine(const std::string& name,
249299
const StorageEngine::Factory* factory) {
250300
// No double-registering.

mongo/src/mongo/db/storage/kv/kv_catalog.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,7 @@ std::string KVCatalog::getCollectionIdent(StringData ns) const {
584584
}
585585

586586
//KVCollectionCatalogEntry::prepareForIndexBuild调用
587+
//获取索引对应文件目录数据
587588
std::string KVCatalog::getIndexIdent(OperationContext* opCtx,
588589
StringData ns,
589590
StringData idxName) const {

mongo/src/mongo/db/storage/kv/kv_collection_catalog_entry.cpp

+3-2
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,7 @@ Status KVCollectionCatalogEntry::removeIndex(OperationContext* opCtx, StringData
211211
//DatabaseImpl::createCollection->IndexCatalogImpl::createIndexOnEmptyCollection->IndexCatalogImpl::IndexBuildBlock::init
212212
//->KVCollectionCatalogEntry::prepareForIndexBuild
213213

214-
//非backgroud阻塞方式创建索引的准备工作
214+
//非backgroud阻塞方式创建索引的准备工作,并创建存储引擎对应索引目录文件
215215
Status KVCollectionCatalogEntry::prepareForIndexBuild(OperationContext* opCtx,
216216
const IndexDescriptor* spec) {
217217
//BSONCollectionCatalogEntry::MetaData
@@ -242,7 +242,8 @@ Status KVCollectionCatalogEntry::prepareForIndexBuild(OperationContext* opCtx,
242242
//KVCatalog::putMetaData
243243
_catalog->putMetaData(opCtx, ns().toString(), md);
244244

245-
//KVCatalog::getIndexIdent 从元数据中获取表索引信息
245+
//KVCatalog::getIndexIdent
246+
//获取索引对应文件目录数据
246247
string ident = _catalog->getIndexIdent(opCtx, ns().ns(), spec->indexName());
247248

248249
//WiredTigerKVEngine::createGroupedSortedDataInterface

0 commit comments

Comments
 (0)