MCPcopy Create free account
hub / github.com/LadybugDB/ladybug / replayShadowPageRecords

Method replayShadowPageRecords

src/storage/shadow_file.cpp:93–141  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

91}
92
93void ShadowFile::replayShadowPageRecords(ClientContext& context) {
94 if (context.getDBConfig()->readOnly) {
95 throw RuntimeException("Couldn't replay shadow pages under read-only mode. Please re-open "
96 "the database with read-write mode to replay shadow pages.");
97 }
98 auto vfs = VirtualFileSystem::GetUnsafe(context);
99 auto shadowFilePath = StorageUtils::getShadowFilePath(context.getDatabasePath());
100 auto shadowFileInfo = vfs->openFile(shadowFilePath, FileOpenFlags(FileFlags::READ_ONLY));
101
102 std::unique_ptr<FileInfo> dataFileInfo;
103 try {
104 dataFileInfo = vfs->openFile(context.getDatabasePath(),
105 FileOpenFlags{FileFlags::WRITE | FileFlags::READ_ONLY, FileLockType::WRITE_LOCK});
106 } catch (IOException& e) {
107 throw RuntimeException(std::format(
108 "Found shadow file {} but no corresponding database file. This file "
109 "may have been left behind from a previous database with the same name. If it is safe "
110 "to do so, please delete this file and restart the database.",
111 shadowFilePath));
112 }
113
114 ShadowFileHeader header;
115 const auto headerBuffer = std::make_unique<uint8_t[]>(LBUG_PAGE_SIZE);
116 shadowFileInfo->readFromFile(headerBuffer.get(), LBUG_PAGE_SIZE, 0);
117 memcpy(&header, headerBuffer.get(), sizeof(ShadowFileHeader));
118
119 // When replaying the shadow file we haven't read the database ID from the database
120 // header yet
121 // So we need to do it separately here to verify the shadow file matches the database
122 auto oldDatabaseID = getOldDatabaseID(*dataFileInfo);
123 FileDBIDUtils::verifyDatabaseID(*shadowFileInfo, oldDatabaseID, header.databaseID);
124
125 std::vector<ShadowPageRecord> shadowPageRecords;
126 shadowPageRecords.reserve(header.numShadowPages);
127 auto reader = std::make_unique<BufferedFileReader>(*shadowFileInfo);
128 reader->resetReadOffset((header.numShadowPages + 1) * LBUG_PAGE_SIZE);
129 Deserializer deSer(std::move(reader));
130 deSer.deserializeVector(shadowPageRecords);
131
132 const auto pageBuffer = std::make_unique<uint8_t[]>(LBUG_PAGE_SIZE);
133 page_idx_t shadowPageIdx = 1;
134 for (const auto& record : shadowPageRecords) {
135 shadowFileInfo->readFromFile(pageBuffer.get(), LBUG_PAGE_SIZE,
136 shadowPageIdx * LBUG_PAGE_SIZE);
137 dataFileInfo->writeFile(pageBuffer.get(), LBUG_PAGE_SIZE,
138 record.originalPageIdx * LBUG_PAGE_SIZE);
139 shadowPageIdx++;
140 }
141}
142
143void ShadowFile::flushAll(main::ClientContext& context) const {
144 // Write header page to file.

Callers

nothing calls this directly

Calls 10

FileOpenFlagsClass · 0.85
getOldDatabaseIDFunction · 0.85
getDBConfigMethod · 0.80
resetReadOffsetMethod · 0.80
getDatabasePathMethod · 0.45
openFileMethod · 0.45
readFromFileMethod · 0.45
getMethod · 0.45
reserveMethod · 0.45
writeFileMethod · 0.45

Tested by

no test coverage detected