bool MMAPV1DatabaseCatalogEntry::isOlderThan24(OperationContext* opCtx) const { if (_extentManager->numFiles() == 0) return false; const DataFileVersion version = _extentManager->getFileFormat(opCtx); fassert(40109, version.isCompatibleWithCurrentCode()); return !version.is24IndexClean(); }
void MMAPV1DatabaseCatalogEntry::markCollationFeatureAsInUse(OperationContext* opCtx) { if (_extentManager->numFiles() == 0) return; DataFileVersion version = _extentManager->getFileFormat(opCtx); fassert(40150, version.isCompatibleWithCurrentCode()); if (version.getMayHaveCollationMetadata()) return; version.setMayHaveCollationMetadata(); _extentManager->setFileFormat(opCtx, version); }
void MMAPV1DatabaseCatalogEntry::markIndexSafe24AndUp(OperationContext* opCtx) { if (_extentManager->numFiles() == 0) return; DataFileVersion version = _extentManager->getFileFormat(opCtx); fassert(40110, version.isCompatibleWithCurrentCode()); if (version.is24IndexClean()) return; // nothing to do version.setIs24IndexClean(); _extentManager->setFileFormat(opCtx, version); }
void MMAPV1DatabaseCatalogEntry::_init(OperationContext* txn) { WriteUnitOfWork wunit(txn); // Upgrade freelist const NamespaceString oldFreeList(name(), "$freelist"); NamespaceDetails* freeListDetails = _namespaceIndex.details(oldFreeList.ns()); if (freeListDetails) { if (!freeListDetails->firstExtent.isNull()) { _extentManager.freeExtents( txn, freeListDetails->firstExtent, freeListDetails->lastExtent); } _namespaceIndex.kill_ns(txn, oldFreeList.ns()); } DataFileVersion version = _extentManager.getFileFormat(txn); if (version.isCompatibleWithCurrentCode() && !version.mayHave28Freelist()) { // Any DB that can be opened and written to gets this flag set. version.setMayHave28Freelist(); _extentManager.setFileFormat(txn, version); } const NamespaceString nsi(name(), "system.indexes"); const NamespaceString nsn(name(), "system.namespaces"); bool isSystemNamespacesGoingToBeNew = _namespaceIndex.details(nsn.toString()) == NULL; bool isSystemIndexesGoingToBeNew = _namespaceIndex.details(nsi.toString()) == NULL; _ensureSystemCollection(txn, nsn.toString()); _ensureSystemCollection(txn, nsi.toString()); if (isSystemNamespacesGoingToBeNew) { txn->recoveryUnit()->registerChange(new EntryInsertion(nsn.toString(), this)); } if (isSystemIndexesGoingToBeNew) { txn->recoveryUnit()->registerChange(new EntryInsertion(nsi.toString(), this)); } Entry*& indexEntry = _collections[nsi.toString()]; Entry*& nsEntry = _collections[nsn.toString()]; NamespaceDetails* const indexDetails = _namespaceIndex.details(nsi.toString()); NamespaceDetails* const nsDetails = _namespaceIndex.details(nsn.toString()); // order has to be: // 1) ns rs // 2) i rs // 3) catalog entries if (!nsEntry) { nsEntry = new Entry(); NamespaceDetailsRSV1MetaData* md = new NamespaceDetailsRSV1MetaData(nsn.toString(), nsDetails); nsEntry->recordStore.reset( new SimpleRecordStoreV1(txn, nsn.toString(), md, &_extentManager, false)); } if (!indexEntry) { indexEntry = new Entry(); NamespaceDetailsRSV1MetaData* md = new NamespaceDetailsRSV1MetaData(nsi.toString(), indexDetails); indexEntry->recordStore.reset( new SimpleRecordStoreV1(txn, nsi.toString(), md, &_extentManager, true)); } RecordId indexNamespaceId; if (isSystemIndexesGoingToBeNew) { indexNamespaceId = _addNamespaceToNamespaceCollection(txn, nsi.toString(), NULL); } if (!nsEntry->catalogEntry) { nsEntry->catalogEntry.reset( new NamespaceDetailsCollectionCatalogEntry(nsn.toString(), nsDetails, nsEntry->recordStore.get(), RecordId(), indexEntry->recordStore.get(), this)); } if (!indexEntry->catalogEntry) { indexEntry->catalogEntry.reset( new NamespaceDetailsCollectionCatalogEntry(nsi.toString(), indexDetails, nsEntry->recordStore.get(), indexNamespaceId, indexEntry->recordStore.get(), this)); } wunit.commit(); // Now put everything in the cache of namespaces. None of the operations below do any // transactional operations. RecordStoreV1Base* rs = _getNamespaceRecordStore(); invariant(rs); auto cursor = rs->getCursor(txn); while (auto record = cursor->next()) { auto ns = record->data.releaseToBson()["name"].String(); Entry*& entry = _collections[ns]; // The two cases where entry is not null is for system.indexes and system.namespaces, // which we manually instantiated above. It is OK to skip these two collections, // because they don't have indexes on them anyway. if (entry) { if (entry->catalogEntry->getNamespacesRecordId().isNull()) { entry->catalogEntry->setNamespacesRecordId(record->id); } else { invariant(entry->catalogEntry->getNamespacesRecordId() == record->id); } continue; } entry = new Entry(); _insertInCache(txn, ns, record->id, entry); } }