@@ -252,6 +252,7 @@ Status IndexCatalogImpl::checkUnfinished() const {
252
252
<< _collection->ns ().ns ());
253
253
}
254
254
255
+ // 版本兼容相关,IndexCatalogImpl::_getAccessMethodName中调用,先忽略
255
256
bool IndexCatalogImpl::_shouldOverridePlugin (OperationContext* opCtx,
256
257
const BSONObj& keyPattern) const {
257
258
string pluginName = IndexNames::findPluginName (keyPattern);
@@ -298,6 +299,7 @@ string IndexCatalogImpl::_getAccessMethodName(OperationContext* opCtx,
298
299
299
300
// ---------------------------
300
301
302
+ // 忽略,版本兼容性相关的
301
303
Status IndexCatalogImpl::_upgradeDatabaseMinorVersionIfNeeded (OperationContext* opCtx,
302
304
const string& newPluginName) {
303
305
// first check if requested index requires pdfile minor version to be bumped
@@ -307,6 +309,7 @@ Status IndexCatalogImpl::_upgradeDatabaseMinorVersionIfNeeded(OperationContext*
307
309
308
310
DatabaseCatalogEntry* dbce = _collection->dbce ();
309
311
312
+ //
310
313
if (!dbce->isOlderThan24 (opCtx)) {
311
314
return Status::OK (); // these checks have already been done
312
315
}
@@ -373,7 +376,7 @@ db/catalog/database_impl.cpp: fullIdIndexSpec = uassertStatusOK(i
373
376
374
377
*/
375
378
// DatabaseImpl::createCollection createSystemIndexes CollectionImpl::truncate中调用执行
376
- // 空表上面建索引
379
+ // 空表上面建索引,一般是手动创建索引或者第一次给某个表写数据的时候调用
377
380
StatusWith<BSONObj> IndexCatalogImpl::createIndexOnEmptyCollection (OperationContext* opCtx,
378
381
BSONObj spec) {
379
382
invariant (opCtx->lockState ()->isCollectionLockedForMode (_collection->ns ().toString (), MODE_X));
@@ -386,6 +389,7 @@ StatusWith<BSONObj> IndexCatalogImpl::createIndexOnEmptyCollection(OperationCont
386
389
return status;
387
390
388
391
// 索引个数 索引冲突 索引名冲突等检查失败,例如索引名有冲突 索引达到上限等
392
+ // 然后返回对应的索引spec
389
393
StatusWith<BSONObj> statusWithSpec = prepareSpecForCreate (opCtx, spec);
390
394
status = statusWithSpec.getStatus ();
391
395
if (!status.isOK ())
@@ -403,20 +407,26 @@ StatusWith<BSONObj> IndexCatalogImpl::createIndexOnEmptyCollection(OperationCont
403
407
// now going to touch disk
404
408
IndexBuildBlock indexBuildBlock (opCtx, _collection, spec);
405
409
// IndexCatalogImpl::IndexBuildBlock::init
406
- status = indexBuildBlock.init (); // 建索引
410
+ // 该索引初始化
411
+ status = indexBuildBlock.init ();
407
412
if (!status.isOK ())
408
413
return status;
409
414
410
415
// sanity checks, etc...
416
+ // 获取该索引对应IndexCatalogEntryImpl
411
417
IndexCatalogEntry* entry = indexBuildBlock.getEntry ();
412
418
invariant (entry);
419
+ // 获取该索引descriptor
413
420
IndexDescriptor* descriptor = entry->descriptor ();
414
421
invariant (descriptor);
415
422
invariant (entry == _entries.find (descriptor));
416
423
424
+ // 啥也没做IndexAccessMethod::initializeAsEmpty->WiredTigerIndex::initAsEmpty
417
425
status = entry->accessMethod ()->initializeAsEmpty (opCtx);
418
426
if (!status.isOK ())
419
427
return status;
428
+
429
+ // IndexBuildBlock::success
420
430
indexBuildBlock.success ();
421
431
422
432
// sanity check
@@ -425,14 +435,17 @@ StatusWith<BSONObj> IndexCatalogImpl::createIndexOnEmptyCollection(OperationCont
425
435
return spec;
426
436
}
427
437
428
- // index_create_impl.cpp中的MultiIndexBlockImpl::init new该类
438
+ // IndexCatalogImpl::createIndexOnEmptyCollection中第一次使用空表的时候(第一次写数据或者手动建表)
439
+ // index_create_impl.cpp中的MultiIndexBlockImpl::init new该类,也就是建索引的时候
429
440
IndexCatalogImpl::IndexBuildBlock::IndexBuildBlock (OperationContext* opCtx,
430
441
Collection* collection,
431
442
const BSONObj& spec)
432
443
: _collection(collection),
433
444
_catalog (collection->getIndexCatalog ()),
434
445
_ns(_catalog->_getCollection ()->ns().ns()),
435
446
_spec(spec.getOwned()),
447
+ // 真正赋值见IndexCatalogImpl::_setupInMemoryStructures
448
+ // 对应IndexCatalogEntryImpl
436
449
_entry(nullptr ),
437
450
_opCtx(opCtx) {
438
451
invariant (collection);
@@ -442,10 +455,11 @@ IndexCatalogImpl::IndexBuildBlock::IndexBuildBlock(OperationContext* opCtx,
442
455
// 创建集合的时候或者程序重启的时候建索引:DatabaseImpl::createCollection->IndexCatalogImpl::createIndexOnEmptyCollection->IndexCatalogImpl::IndexBuildBlock::init
443
456
// MultiIndexBlockImpl::init->IndexCatalogImpl::IndexBuildBlock::init 程序运行过程中,并且集合已经存在的时候建索引
444
457
445
- // IndexCatalogImpl::createIndexOnEmptyCollection 调用
446
- // CmdCreateIndex::errmsgRun->MultiIndexBlockImpl::init调用
458
+ // IndexCatalogImpl::createIndexOnEmptyCollection 调用(第一次创建空表或者第一次往空表写入数据)
459
+ // CmdCreateIndex::errmsgRun->MultiIndexBlockImpl::init调用(收到createIndex建索引)
447
460
448
461
// //获取descriptor该索引对应的IndexCatalogEntryImpl添加到_entries数组
462
+ // 对IndexBuildBlock对应的索引进行初始化
449
463
Status IndexCatalogImpl::IndexBuildBlock::init () {
450
464
// need this first for names, etc...
451
465
// 获取所有信息的key,可以db.collection.getIndexes()获取
@@ -474,7 +488,7 @@ Status IndexCatalogImpl::IndexBuildBlock::init() {
474
488
// / ---------- setup in memory structures ----------------
475
489
const bool initFromDisk = false ;
476
490
// 获取descriptor该索引对应的IndexCatalogEntryImpl添加到_entries数组
477
- // 一个索引对应一个IndexCatalogImpl
491
+ // 一个索引对应一个IndexCatalogEntryImpl
478
492
_entry = IndexCatalogImpl::_setupInMemoryStructures (
479
493
_catalog, _opCtx, std::move (descriptor), initFromDisk);
480
494
@@ -491,6 +505,7 @@ IndexCatalogImpl::IndexBuildBlock::~IndexBuildBlock() {
491
505
// Don't need to call fail() here, as rollback will clean everything up for us.
492
506
}
493
507
508
+ // 失败处理
494
509
void IndexCatalogImpl::IndexBuildBlock::fail () {
495
510
fassert (17204 , _catalog->_getCollection ()->ok ()); // defensive
496
511
@@ -506,19 +521,26 @@ void IndexCatalogImpl::IndexBuildBlock::fail() {
506
521
507
522
// IndexCatalogImpl::createIndexOnEmptyCollection调用 检查索引是否创建成功
508
523
void IndexCatalogImpl::IndexBuildBlock::success () {
524
+ // 获取该索引对应的表信息
509
525
Collection* collection = _catalog->_getCollection ();
510
526
fassert (17207 , collection->ok ());
511
527
NamespaceString ns (_indexNamespace);
512
528
invariant (_opCtx->lockState ()->isDbLockedForMode (ns.db (), MODE_X));
513
529
530
+ // KVCollectionCatalogEntry::indexBuildSuccess
531
+ // 更新元数据"_mdb_catalog.wt"信息中的索引
514
532
collection->getCatalogEntry ()->indexBuildSuccess (_opCtx, _indexName);
515
533
534
+ // IndexCatalogImpl::findIndexByName
535
+ // 查找该索引desc
516
536
IndexDescriptor* desc = _catalog->findIndexByName (_opCtx, _indexName, true );
517
537
fassert (17330 , desc);
538
+ // IndexCatalogImpl::_getEntries从数组中查找内存中是否有该索引desc
518
539
IndexCatalogEntry* entry = _catalog->_getEntries ().find (desc);
519
540
fassert (17331 , entry && entry == _entry);
520
541
521
542
OperationContext* opCtx = _opCtx;
543
+ // 例如id索引对应打印marking index _id_ as ready in snapshot id 85053
522
544
LOG (2 ) << " marking index " << _indexName << " as ready in snapshot id "
523
545
<< opCtx->recoveryUnit ()->getSnapshotId ();
524
546
_opCtx->recoveryUnit ()->onCommit ([opCtx, entry, collection] {
@@ -1170,6 +1192,9 @@ void IndexCatalogImpl::_deleteIndexFromDisk(OperationContext* opCtx,
1170
1192
// "Leftover" means they were unfinished when a mongod shut down.
1171
1193
// Certain operations are prohibited until someone fixes.
1172
1194
// Retrieve by calling getAndClearUnfinishedIndexes().
1195
+
1196
+ // restartInProgressIndexesFromLastShutdown->checkNS调用
1197
+ // 当真正运行添加某个索引得时候,如果这时候实例挂掉,当实例重启后需要调用该接口先删除索引,然后再checkNS重构索引
1173
1198
vector<BSONObj> IndexCatalogImpl::getAndClearUnfinishedIndexes (OperationContext* opCtx) {
1174
1199
vector<BSONObj> toReturn = _unfinishedIndexes;
1175
1200
_unfinishedIndexes.clear ();
@@ -1453,7 +1478,15 @@ const IndexCatalogEntry* IndexCatalogImpl::getEntry(const IndexDescriptor* desc)
1453
1478
return entry;
1454
1479
}
1455
1480
1481
+ /*
1482
+ 该方法给集合添加一个标识,来修改集合的行为。 标识包含usePowerOf2Sizes和index。
1483
+
1484
+ 命令格式为:
1485
+
1486
+ db.runCommand({"collMod":<collection>,"<flag>":<value>})
1456
1487
1488
+ */
1489
+ // _collModInternal中调用, 先跳过
1457
1490
const IndexDescriptor* IndexCatalogImpl::refreshEntry (OperationContext* opCtx,
1458
1491
const IndexDescriptor* oldDesc) {
1459
1492
invariant (opCtx->lockState ()->isCollectionLockedForMode (_collection->ns ().ns (), MODE_X));
@@ -1471,6 +1504,7 @@ const IndexDescriptor* IndexCatalogImpl::refreshEntry(OperationContext* opCtx,
1471
1504
1472
1505
// Delete the IndexCatalogEntry that owns this descriptor. After deletion, 'oldDesc' is
1473
1506
// invalid and should not be dereferenced.
1507
+ // 从_entries数组清除oldDesc
1474
1508
IndexCatalogEntry* oldEntry = _entries.release (oldDesc);
1475
1509
opCtx->recoveryUnit ()->registerChange (
1476
1510
new IndexRemoveChange (opCtx, _collection, &_entries, oldEntry));
@@ -1492,7 +1526,8 @@ const IndexDescriptor* IndexCatalogImpl::refreshEntry(OperationContext* opCtx,
1492
1526
}
1493
1527
1494
1528
// ---------------------------
1495
- // IndexCatalogImpl::_indexRecords
1529
+ // IndexCatalogImpl::_indexRecords调用,
1530
+ // 把bsonRecords对应的索引KV数据写入存储引擎
1496
1531
Status IndexCatalogImpl::_indexFilteredRecords (OperationContext* opCtx,
1497
1532
IndexCatalogEntry* index,
1498
1533
const std::vector<BsonRecord>& bsonRecords,
@@ -1518,23 +1553,29 @@ Status IndexCatalogImpl::_indexFilteredRecords(OperationContext* opCtx,
1518
1553
}
1519
1554
1520
1555
// IndexCatalogImpl::indexRecords
1556
+ // 把bsonRecords对应的索引KV(如果需要过滤,则提前过滤)数据写入存储引擎
1521
1557
Status IndexCatalogImpl::_indexRecords (OperationContext* opCtx,
1522
1558
IndexCatalogEntry* index,
1523
1559
const std::vector<BsonRecord>& bsonRecords,
1524
1560
int64_t * keysInsertedOut) {
1525
- const MatchExpression* filter = index ->getFilterExpression ();
1526
- if (!filter)
1561
+ // 基于age列创建大于25岁的部分索引 db.persons.createIndex({country:1},{partialFilterExpression: {age: {$gt:25}}})
1562
+ const MatchExpression* filter = index ->getFilterExpression ();
1563
+ if (!filter) // 普通索引,也就是不带partialFilterExpression
1527
1564
return _indexFilteredRecords (opCtx, index , bsonRecords, keysInsertedOut);
1528
1565
1566
+ // 携带有partialFilterExpression参数的索引
1529
1567
std::vector<BsonRecord> filteredBsonRecords;
1530
1568
for (auto bsonRecord : bsonRecords) {
1569
+ // 只把满足partialFilterExpression条件的doc添加到filteredBsonRecords,然后写入存储引擎
1531
1570
if (filter->matchesBSON (*(bsonRecord.docPtr )))
1532
1571
filteredBsonRecords.push_back (bsonRecord);
1533
1572
}
1534
1573
1535
1574
return _indexFilteredRecords (opCtx, index , filteredBsonRecords, keysInsertedOut);
1536
1575
}
1537
1576
1577
+ // 删除loc对应的index索引数据
1578
+ // IndexCatalogImpl::unindexRecord调用
1538
1579
Status IndexCatalogImpl::_unindexRecord (OperationContext* opCtx,
1539
1580
IndexCatalogEntry* index,
1540
1581
const BSONObj& obj,
@@ -1588,6 +1629,7 @@ Status IndexCatalogImpl::indexRecords(OperationContext* opCtx,
1588
1629
return Status::OK ();
1589
1630
}
1590
1631
1632
+ // CollectionImpl::deleteDocument调用,删除数据loc对应的索引KV数据
1591
1633
void IndexCatalogImpl::unindexRecord (OperationContext* opCtx,
1592
1634
const BSONObj& obj,
1593
1635
const RecordId& loc,
@@ -1597,16 +1639,19 @@ void IndexCatalogImpl::unindexRecord(OperationContext* opCtx,
1597
1639
*keysDeletedOut = 0 ;
1598
1640
}
1599
1641
1642
+ // 删除该数据对应的所有索引KV
1600
1643
for (IndexCatalogEntryContainer::const_iterator i = _entries.begin (); i != _entries.end ();
1601
1644
++i) {
1602
1645
IndexCatalogEntry* entry = i->get ();
1603
1646
1604
1647
// If it's a background index, we DO NOT want to log anything.
1605
1648
bool logIfError = entry->isReady (opCtx) ? !noWarn : false ;
1649
+ // 删除loc对应的index索引数据
1606
1650
_unindexRecord (opCtx, entry, obj, loc, logIfError, keysDeletedOut).transitional_ignore ();
1607
1651
}
1608
1652
}
1609
1653
1654
+ // IndexCatalogImpl::_fixIndexSpec中调用
1610
1655
BSONObj IndexCatalogImpl::fixIndexKey (const BSONObj& key) {
1611
1656
if (IndexDescriptor::isIdIndexPattern (key)) {
1612
1657
return _idObj;
@@ -1639,7 +1684,7 @@ void IndexCatalogImpl::prepareInsertDeleteOptions(OperationContext* opCtx,
1639
1684
}
1640
1685
}
1641
1686
1642
- //
1687
+ // 从spec中获取索引信息,然后以bson格式返回
1643
1688
StatusWith<BSONObj> IndexCatalogImpl::_fixIndexSpec (OperationContext* opCtx,
1644
1689
Collection* collection,
1645
1690
const BSONObj& spec) {
0 commit comments