当前位置: 首页 > news >正文

mongodb源代码分析创建db流程分析

mongo/db/catalog/create_collection.cpp中reateCollection构建元数据文档:将集合信息(命名空间、选项、键前缀等)序列化为 BSON 格式,{ ns: "db.conca", ident: "collection-0--8262702921578327518", md: };
_rs->insertRecord将元数据文档插入到Catalog的记录存储(RecordStore)中,写入到系统表_uri:table:_mdb_catalog中。_mdb_catalog存储集合和索引的元数据信息,_mdb_catalog.wt在数据库文件夹下面:

数据库的信息在哪个文件存储呢?

/mongo/db/catalog/create_collection.cpp是创建集合的核心代码,后面重点分析其中获取数据库的代码。

mongo/db/catalog/create_collection.cpp中_createCollection是命令db.createCollection('conca', { })核心方法。AutoGetOrCreateDb autoDb先获取到对应的数据库。

Status _createCollection(OperationContext* opCtx,const NamespaceString& nss,const CollectionOptions& collectionOptions,const BSONObj& idIndex) {...AutoGetOrCreateDb autoDb(opCtx, nss.db(), MODE_IX);Lock::CollectionLock collLock(opCtx, nss, MODE_X);...});
}

/mongo/db/catalog_raii.cpp中AutoGetOrCreateDb代码,_autoDb.getDb()获取数据库,如果没有获取到db,openDb则进行打开对应的数据库。

AutoGetOrCreateDb::AutoGetOrCreateDb(OperationContext* opCtx,StringData dbName,LockMode mode,Date_t deadline): _autoDb(opCtx, dbName, mode, deadline) {invariant(mode == MODE_IX || mode == MODE_X);_db = _autoDb.getDb();if (!_db) {auto databaseHolder = DatabaseHolder::get(opCtx);_db = databaseHolder->openDb(opCtx, dbName, &_justCreated);}auto dss = DatabaseShardingState::get(opCtx, dbName);auto dssLock = DatabaseShardingState::DSSLock::lockShared(opCtx, dss);dss->checkDbVersion(opCtx, dssLock);
}

 /mongo/db/catalog/database_holder_impl.cpp中openDb代码:

 std::make_unique<DatabaseImpl>(dbname, ++_epoch)创建数据库实现类DatabaseImpl, newDb->init初始化数据库实现类。auto it = _dbs.find(dbname);再次获取是否存在相同名称的数据库,如果存在则返回,如果不存在则设置进去。

Database* DatabaseHolderImpl::openDb(OperationContext* opCtx, StringData ns, bool* justCreated) {const StringData dbname = _todb(ns);invariant(opCtx->lockState()->isDbLockedForMode(dbname, MODE_IX));if (justCreated)*justCreated = false;  // Until proven otherwise.stdx::unique_lock<SimpleMutex> lk(_m);// The following will insert a nullptr for dbname, which will treated the same as a non-// existant database by the get method, yet still counts in getNamesWithConflictingCasing.if (auto db = _dbs[dbname])return db;// We've inserted a nullptr entry for dbname: make sure to remove it on unsuccessful exit.auto removeDbGuard = makeGuard([this, &lk, dbname] {if (!lk.owns_lock())lk.lock();_dbs.erase(dbname);});// Check casing in lock to avoid transient duplicates.auto duplicates = _getNamesWithConflictingCasing_inlock(dbname);uassert(ErrorCodes::DatabaseDifferCase,str::stream() << "db already exists with different case already have: ["<< *duplicates.cbegin() << "] trying to create [" << dbname.toString()<< "]",duplicates.empty());// Do the catalog lookup and database creation outside of the scoped lock, because these may// block.lk.unlock();if (CollectionCatalog::get(opCtx).getAllCollectionUUIDsFromDb(dbname).empty()) {audit::logCreateDatabase(opCtx->getClient(), dbname);if (justCreated)*justCreated = true;}auto newDb = std::make_unique<DatabaseImpl>(dbname, ++_epoch);newDb->init(opCtx);// Finally replace our nullptr entry with the new Database pointer.removeDbGuard.dismiss();lk.lock();auto it = _dbs.find(dbname);// Dropping a database requires a MODE_X lock, so the entry in the `_dbs` map cannot disappear.invariant(it != _dbs.end());if (it->second) {// Creating databases only requires a DB lock in MODE_IX. Thus databases can concurrently// created. If this thread "lost the race", return the database object that was persisted in// the `_dbs` map.return it->second;}it->second = newDb.release();invariant(_getNamesWithConflictingCasing_inlock(dbname.toString()).empty());return it->second;
}

/mongo/db/catalog/database_impl.cpp中DatabaseImpl::init代码:

void DatabaseImpl::init(OperationContext* const opCtx) const {Status status = validateDBName(_name);if (!status.isOK()) {warning() << "tried to open invalid db: " << _name;uasserted(10028, status.toString());}auto& catalog = CollectionCatalog::get(opCtx);for (const auto& uuid : catalog.getAllCollectionUUIDsFromDb(_name)) {auto collection = catalog.lookupCollectionByUUID(uuid);invariant(collection);// If this is called from the repair path, the collection is already initialized.if (!collection->isInitialized())collection->init(opCtx);}// At construction time of the viewCatalog, the CollectionCatalog map wasn't initialized yet,// so no system.views collection would be found. Now that we're sufficiently initialized, reload// the viewCatalog to populate its in-memory state. If there are problems with the catalog// contents as might be caused by incorrect mongod versions or similar, they are found right// away.auto views = ViewCatalog::get(this);Status reloadStatus = views->reload(opCtx, ViewCatalogLookupBehavior::kValidateDurableViews);if (!reloadStatus.isOK()) {warning() << "Unable to parse views: " << redact(reloadStatus)<< "; remove any invalid views from the " << _viewsName<< " collection to restore server functionality." << startupWarningsLog;}
}

DatabaseImpl::init这段代码是 MongoDB 中DatabaseImpl类的init方法实现,主要功能是完成数据库的初始化工作,包括验证数据库名合法性、初始化集合以及加载视图目录等。

http://www.dtcms.com/a/314065.html

相关文章:

  • 芯脑觉醒:Deepoc如何让送餐机器人“活”起来?
  • 手搓TCP服务器实现基础IO
  • Go语言高并发价格监控系统设计
  • TCP 协议的“无消息边界”(No Message Boundaries)特性
  • sqli-labs-master/Less-31~Less-40
  • 内联函数:提升效率的空间换时间艺术
  • 移动端 WebView 视频无法播放怎么办 媒体控件错误排查与修复指南
  • 官宣!多功能DC-DC数字电源控制器重磅首发
  • 应用药品GSP证书识别技术,提升药品流通各环节的合规管理效率和风控水平
  • 数据工程与处理:AI时代的数据基石与智能化管道
  • java~final关键字
  • doris `unicode` 是多语言混合类型分词与elasticsearch分词差异
  • Java从入门到精通 - 算法、正则、异常
  • MQTT:安装部署
  • 【AI 加持下的 Python 编程实战 2_13】第九章:繁琐任务的自动化(中)——自动批量合并 PDF 文档
  • CMake进阶: 使用FetchContent方法基于gTest的C++单元测试
  • Docker-07.Docker基础-数据卷挂载
  • 在CAPL自动化脚本中巧用panel函数
  • 关键领域软件研发如何构建智能知识管理体系?从文档自动化到安全协同的全面升级
  • 实现Trie(前缀和)C++
  • 【REACT18.x】封装react-rouer实现多级路由嵌套,封装登录态权限拦截
  • PyTorch :三角函数与特殊运算
  • python:讲懂决策树,为理解随机森林算法做准备,以示例带学习,通俗易懂,容易理解和掌握
  • 张 事实关注增强模型:提升AI准确率新方法
  • 设备电机状态监测中的故障诊断与定位策略
  • 【AI论文】VL-Cogito:面向高级多模态推理的渐进式课程强化学习
  • Redis之Hash和List类型常用命令
  • [特殊字符] Ubuntu 下 MySQL 离线部署教学(含手动步骤与一键脚本)
  • 小鹏汽车前端面经
  • 笔记本电脑联想T14重启后无法识别外置红米屏幕