1
0
mirror of https://github.com/mariadb-corporation/mariadb-columnstore-engine.git synced 2025-12-17 01:02:23 +03:00

Fixed a few random things.

This commit is contained in:
Patrick LeBlanc
2019-04-05 14:10:59 -05:00
parent 0d7556811a
commit 1879499ad3
5 changed files with 60 additions and 43 deletions

View File

@@ -384,7 +384,12 @@ void Cache::rename(const string &oldKey, const string &newKey, ssize_t sizediff)
{ {
boost::unique_lock<boost::mutex> s(lru_mutex); boost::unique_lock<boost::mutex> s(lru_mutex);
auto it = m_lru.find(oldKey); auto it = m_lru.find(oldKey);
assert(it != m_lru.end()); //assert(it != m_lru.end());
if (it == m_lru.end())
{
logger->log(LOG_ERR, "Cache: was told to rename %s, but it does not exist", oldKey.string().c_str());
assert(0);
}
auto lit = it->lit; auto lit = it->lit;
m_lru.erase(it); m_lru.erase(it);

View File

@@ -578,7 +578,12 @@ void IOCoordinator::deleteMetaFile(const bf::path &file)
*/ */
Synchronizer *synchronizer = Synchronizer::get(); Synchronizer *synchronizer = Synchronizer::get();
ScopedWriteLock lock(this, file.string());
// this is kind of ugly. We need to lock on file relative to metaPath
string lockKey = file.string().substr(metaPath.string().length() + 1);
cout << "Deletemetafile locking on " << lockKey << endl;
ScopedWriteLock lock(this, lockKey);
MetadataFile meta(file); MetadataFile meta(file);
replicator->remove(file); replicator->remove(file);
@@ -809,26 +814,6 @@ int IOCoordinator::copyFile(const char *filename1, const char *filename2)
for (auto &jEntry : newJournalEntries) for (auto &jEntry : newJournalEntries)
sync->newJournalEntry(jEntry); sync->newJournalEntry(jEntry);
return 0; return 0;
#if 0
SMLogging* logger = SMLogging::get();
int err = 0, l_errno;
try {
bf::copy_file(filename1, filename2);
}
catch (bf::filesystem_error &e) {
err = -1;
l_errno = e.code().value(); // why not.
// eh, not going to translate all of boost's errors into our errors for this.
// log the error
logger->log(LOG_ERR,"IOCoordinator::copy(): got %s",e.what());
}
catch (...) {
err = -1;
l_errno = EIO;
}
return err;
#endif
} }
const bf::path &IOCoordinator::getCachePath() const const bf::path &IOCoordinator::getCachePath() const
@@ -1003,7 +988,7 @@ int IOCoordinator::mergeJournalInMem(boost::shared_array<uint8_t> &objData, size
ss << headertxt.get(); ss << headertxt.get();
boost::property_tree::ptree header; boost::property_tree::ptree header;
boost::property_tree::json_parser::read_json(ss, header); boost::property_tree::json_parser::read_json(ss, header);
assert(header.get<int>("version") == "1"); assert(header.get<int>("version") == 1);
size_t maxJournalOffset = header.get<size_t>("max_offset"); size_t maxJournalOffset = header.get<size_t>("max_offset");
if (maxJournalOffset > *len) if (maxJournalOffset > *len)

View File

@@ -187,6 +187,9 @@ int Replicator::remove(const boost::filesystem::path &filename, Flags flags)
{ {
int ret = 0; int ret = 0;
if (flags & NO_LOCAL)
return 0; // not implemented yet
try try
{ {
boost::filesystem::remove_all(filename); boost::filesystem::remove_all(filename);
@@ -202,6 +205,9 @@ int Replicator::remove(const boost::filesystem::path &filename, Flags flags)
int Replicator::remove(const char *filename, Flags flags) int Replicator::remove(const char *filename, Flags flags)
{ {
if (flags & NO_LOCAL)
return 0; // not implemented yet
boost::filesystem::path p(filename); boost::filesystem::path p(filename);
return remove(p); return remove(p);
} }

View File

@@ -229,13 +229,17 @@ void Synchronizer::process(list<string>::iterator name, bool callerHoldsLock)
mutex.unlock(); mutex.unlock();
bool success = false; bool success = false;
// in testing, this seems to only run once when an exception is caught. Not obvious why yet.... ??
while (!success) while (!success)
{ {
try { try {
/* Exceptions should only happen b/c of cloud service errors. Rather than retry here endlessly, // Exceptions should only happen b/c of cloud service errors that can't be retried.
probably a better idea to have cloudstorage classes do the retrying */ // This code is intentionally racy to avoid having to grab big locks.
// In particular, it's possible that by the time synchronize() runs,
// the file to sync has already been deleted. When one of these functions
// encounters a state that doesn't make sense, such as being told to upload a file
// that doesn't exist, it will return silently under the assumption that
// things are working as they should upstream, and a syncDelete() call will be coming
// shortly.
if (pending->opFlags & DELETE) if (pending->opFlags & DELETE)
synchronizeDelete(sourceFile, name); synchronizeDelete(sourceFile, name);
else if (pending->opFlags & JOURNAL) else if (pending->opFlags & JOURNAL)
@@ -283,23 +287,25 @@ void Synchronizer::synchronize(const string &sourceFile, list<string>::iterator
if (exists) if (exists)
return; return;
// can this run after a delete op?
exists = bf::exists(cachePath / key); exists = bf::exists(cachePath / key);
if (!exists) if (!exists)
{ {
logger->log(LOG_WARNING, "synchronize(): was told to upload %s but it does not exist locally", key.c_str()); logger->log(LOG_DEBUG, "synchronize(): was told to upload %s but it does not exist locally", key.c_str());
return; return;
} }
err = cs->putObject((cachePath / key).string(), key); err = cs->putObject((cachePath / key).string(), key);
if (err) if (err)
throw runtime_error(string("synchronize(): uploading ") + key + ", got " + strerror_r(errno, buf, 80)); throw runtime_error(string("synchronize(): uploading ") + key + ", got " + strerror_r(errno, buf, 80));
replicator->remove(key.c_str(), Replicator::NO_LOCAL); replicator->remove((cachePath/key).string().c_str(), Replicator::NO_LOCAL);
} }
void Synchronizer::synchronizeDelete(const string &sourceFile, list<string>::iterator &it) void Synchronizer::synchronizeDelete(const string &sourceFile, list<string>::iterator &it)
{ {
ScopedWriteLock s(ioc, sourceFile); /* Don't think it's necessary to lock here. Sync is being told to delete a file on cloud storage.
Presumably the caller has removed it from metadata & the cache, so it is no longer referencable.
*/
//ScopedWriteLock s(ioc, sourceFile);
cs->deleteObject(*it); cs->deleteObject(*it);
} }
@@ -313,8 +319,9 @@ void Synchronizer::synchronizeWithJournal(const string &sourceFile, list<string>
if (!bf::exists(journalName)) if (!bf::exists(journalName))
{ {
logger->log(LOG_WARNING, "synchronizeWithJournal(): no journal file found for %s", key.c_str()); logger->log(LOG_DEBUG, "synchronizeWithJournal(): no journal file found for %s", key.c_str());
// I don't think this should happen, maybe throw a logic_error here // I don't think this should happen, maybe throw a logic_error here.
// Revision ^^. It can happen if the object was deleted after the op was latched but before it runs.
return; return;
} }
@@ -330,7 +337,14 @@ void Synchronizer::synchronizeWithJournal(const string &sourceFile, list<string>
{ {
err = cs->getObject(key, &data, &size); err = cs->getObject(key, &data, &size);
if (err) if (err)
{
if (errno == ENOENT)
{
logger->log(LOG_DEBUG, "synchronizeWithJournal(): %s does not exist in cache nor in cloud storage", key.c_str());
return;
}
throw runtime_error(string("Synchronizer: getObject() failed: ") + strerror_r(errno, buf, 80)); throw runtime_error(string("Synchronizer: getObject() failed: ") + strerror_r(errno, buf, 80));
}
err = ioc->mergeJournalInMem(data, &size, journalName.c_str()); err = ioc->mergeJournalInMem(data, &size, journalName.c_str());
assert(!err); assert(!err);
} }
@@ -342,7 +356,12 @@ void Synchronizer::synchronizeWithJournal(const string &sourceFile, list<string>
string newKey = MetadataFile::getNewKeyFromOldKey(key, size); string newKey = MetadataFile::getNewKeyFromOldKey(key, size);
err = cs->putObject(data, size, newKey); err = cs->putObject(data, size, newKey);
if (err) if (err)
{
// try to delete it in cloud storage... unlikely it is there in the first place, and if it is
// this probably won't work
cs->deleteObject(newKey);
throw runtime_error(string("Synchronizer: putObject() failed: ") + strerror_r(errno, buf, 80)); throw runtime_error(string("Synchronizer: putObject() failed: ") + strerror_r(errno, buf, 80));
}
// if the object was cached... // if the object was cached...
// write the new data to disk, // write the new data to disk,
@@ -364,13 +383,15 @@ void Synchronizer::synchronizeWithJournal(const string &sourceFile, list<string>
{ {
err = ::write(newFD, data.get(), size - count); err = ::write(newFD, data.get(), size - count);
if (err < 0) if (err < 0)
{
::unlink(newCachePath.string().c_str());
throw runtime_error(string("Synchronizer: Failed to write to a new object in local storage! Got ") throw runtime_error(string("Synchronizer: Failed to write to a new object in local storage! Got ")
+ strerror_r(errno, buf, 80)); + strerror_r(errno, buf, 80));
}
count += err; count += err;
} }
cache->rename(key, newKey, size - bf::file_size(oldCachePath)); cache->rename(key, newKey, size - bf::file_size(oldCachePath));
replicator->remove(key.c_str()); // should this be the file to remove, or the key? replicator->remove(oldCachePath.string().c_str());
} }
// update the metadata for the source file // update the metadata for the source file

View File

@@ -1367,10 +1367,10 @@ void IOCCopyFile3()
bf::path metaPath = ioc->getMetadataPath(); bf::path metaPath = ioc->getMetadataPath();
bf::path journalPath = ioc->getJournalPath(); bf::path journalPath = ioc->getJournalPath();
bf::path cachePath = ioc->getCachePath(); bf::path cachePath = ioc->getCachePath();
bf::path sourcePath = metaPath/"copyfile1"/"source.meta"; bf::path sourcePath = metaPath/"copyfile3"/"source.meta";
bf::path destPath = metaPath/"copyfile2"/"dest.meta"; bf::path destPath = metaPath/"copyfile4"/"dest.meta";
const char *l_sourceFile = "copyfile1/source"; const char *l_sourceFile = "copyfile3/source";
const char *l_destFile = "copyfile2/dest"; const char *l_destFile = "copyfile4/dest";
cache->reset(); cache->reset();
@@ -1381,7 +1381,7 @@ void IOCCopyFile3()
cache->newObject(testObjKey, bf::file_size(cachePath/testObjKey)); cache->newObject(testObjKey, bf::file_size(cachePath/testObjKey));
cache->newJournalEntry(bf::file_size(journalPath/(string(testObjKey) + ".journal"))); cache->newJournalEntry(bf::file_size(journalPath/(string(testObjKey) + ".journal")));
int err = ioc->copyFile("copyfile1/source", "copyfile2/dest"); int err = ioc->copyFile("copyfile3/source", "copyfile4/dest");
assert(!err); assert(!err);
uint8_t buf1[8192], buf2[8192]; uint8_t buf1[8192], buf2[8192];
err = ioc->read(l_sourceFile, buf1, 0, 8192); err = ioc->read(l_sourceFile, buf1, 0, 8192);
@@ -1390,8 +1390,8 @@ void IOCCopyFile3()
assert(err == 8192); assert(err == 8192);
assert(memcmp(buf1, buf2, 8192) == 0); assert(memcmp(buf1, buf2, 8192) == 0);
ioc->unlink("copyfile1"); ioc->unlink("copyfile3");
ioc->unlink("copyfile2"); ioc->unlink("copyfile4");
assert(cache->getCurrentCacheSize() == 0); assert(cache->getCurrentCacheSize() == 0);
cout << "IOC copy file 3 OK" << endl; cout << "IOC copy file 3 OK" << endl;
} }