1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-04-18 21:44:02 +03:00
mariadb-columnstore-engine/versioning/BRM/load_brm_from_file.cpp
drrtuy dd8fac35ae
fix(syscat): MCOL-5816 23.02 -> 23.10 upgrade issues (#3346) (#3374)
* feat(BRM,tools): couple utilities to watch/operate shared memory locks and extent map

* feat(BRM,tools): merged two utilities and added some extra dbbuilder output in case of upgrade

* fix(dbbuilder): extra output to log upgrade detection.
2024-12-26 16:26:34 +00:00

174 lines
5.3 KiB
C++

/* Copyright (C) 2024 MariaDB Corporation, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; version 2 of
the License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. */
/*
* A tool that can take a csv file of extent map entires and produce a BRM_saves_em-compatible file.
* If you re-compile extentmap.cpp to dump the extent map as it loads, you'll get a csv file on stdout.
* Save this to a file and edit it as needed (remove the cruft at the top & bottom for sure). Then use
* this tool to create a binary BRM_saves_em file.
*/
#include <iostream>
#include <stdint.h>
#include <fstream>
#include <cerrno>
#include <string>
#include <cstdlib>
#include <cassert>
#include <limits>
using namespace std;
#include "CLI11.hpp"
#include "extentmap.h"
static const char* BIN_NAME = "mcs-load-brm-from-file";
template <typename T>
T parseField(std::stringstream& ss, const char delimiter)
{
std::string field;
std::getline(ss, field, delimiter);
return std::stoll(field);
}
BRM::EMEntry parseLine(const std::string& line, char delimiter = '|')
{
std::stringstream ss(line);
std::string field;
auto rangeStart = parseField<int64_t>(ss, delimiter);
auto rangeSize = parseField<uint32_t>(ss, delimiter);
BRM::InlineLBIDRange range{rangeStart, rangeSize};
auto fileID = parseField<int>(ss, delimiter);
auto blockOffset = parseField<uint32_t>(ss, delimiter);
auto hwm = parseField<BRM::HWM_t>(ss, delimiter);
auto partitionNum = parseField<BRM::PartitionNumberT>(ss, delimiter);
auto segmentNum = parseField<uint16_t>(ss, delimiter);
auto dbRoot = parseField<BRM::DBRootT>(ss, delimiter);
auto colWid = parseField<uint16_t>(ss, delimiter);
auto status = parseField<int16_t>(ss, delimiter);
auto hiVal = parseField<int64_t>(ss, delimiter);
auto loVal = parseField<int64_t>(ss, delimiter);
auto sequenceNum = parseField<int32_t>(ss, delimiter);
auto isValid = parseField<char>(ss, delimiter);
auto partition = BRM::EMCasualPartition_t{loVal, hiVal, sequenceNum, isValid};
return BRM::EMEntry{range, fileID, blockOffset, hwm, partitionNum,
segmentNum, dbRoot, colWid, status, {partition}};
}
int main(int argc, char** argv)
{
CLI::App app{BIN_NAME};
app.description(
"A tool to build Extent Map image file from its text representation. A text representation can be obtained using 'editem -i'"
"display the lock state.");
std::string srcFilename;
std::string dstFilename;
bool debug = false;
app.add_option("-i,--input-filename", srcFilename,
"Extent Map as its text representation.")
->required();
app.add_option("-o,--output-filename", dstFilename,
"Extent Map output image file, default as input-filename.out")
->default_val("");
app.add_option("-d,--debug", debug, "Print extra output")->default_val(false);
CLI11_PARSE(app, argc, argv);
ifstream in(srcFilename);
int e = errno;
if (!in)
{
cerr << "file read error: " << strerror(e) << endl;
return 1;
}
// Brute force count the number of lines
int numEMEntries = 0;
{
string line;
getline(in, line);
while (!in.eof())
{
numEMEntries++;
getline(in, line);
}
}
std::cout << "Number of entries: " << numEMEntries << std::endl;
if (dstFilename.empty())
{
dstFilename = srcFilename + ".out";
}
ofstream outFile(dstFilename);
BRM::InlineLBIDRange maxLBIDinUse{0, 0};
std::ifstream infile(srcFilename);
if (!infile.is_open())
{
std::cerr << "Can not open file " << srcFilename << std::endl;
return 1;
}
int loadSize[3];
loadSize[0] = EM_MAGIC_V5;
loadSize[1] = numEMEntries;
loadSize[2] = 1; // one free list entry
outFile.write((char*)&loadSize, (3 * sizeof(int)));
string line;
while (std::getline(infile, line))
{
BRM::EMEntry em = parseLine(line);
if (em.range.start > maxLBIDinUse.start)
{
maxLBIDinUse.start = em.range.start;
maxLBIDinUse.size = em.range.size;
}
if (debug)
{
std::cout << em.range.start << '\t' << em.range.size << '\t' << em.fileID << '\t' << em.blockOffset
<< '\t' << em.HWM << '\t' << em.partitionNum << '\t' << em.segmentNum << '\t' << em.dbRoot
<< '\t' << em.colWid << '\t' << em.status << '\t' << em.partition.cprange.hiVal << '\t'
<< em.partition.cprange.loVal << '\t' << em.partition.cprange.sequenceNum << '\t'
<< (short int)(em.partition.cprange.isValid) << std::endl;
}
outFile.write((char*)&em, sizeof(em));
}
infile.close();
auto flStart = maxLBIDinUse.start + maxLBIDinUse.size * 1024;
assert(flStart / 1024 <= numeric_limits<uint32_t>::max());
uint32_t flEnd = numeric_limits<uint32_t>::max() - flStart / 1024;
BRM::InlineLBIDRange fl{flStart, flEnd};
outFile.write((char*)&fl, sizeof(fl));
outFile.close();
return 0;
}