diff options
author | Tor Egge <Tor.Egge@broadpark.no> | 2018-08-01 15:32:17 +0200 |
---|---|---|
committer | Tor Egge <Tor.Egge@oath.com> | 2018-08-02 10:08:27 +0000 |
commit | f450c9c1302a6fbc93cd0cfaf524b1137b8eca07 (patch) | |
tree | 21bc63c94ff99d23553cc6078e8d3780efb7610d /searchlib | |
parent | 553aa395b40c5fb49abef5a10efb86bbb084fea0 (diff) |
Add fsync calls to reduce probability of unexpected state after a crash.
Diffstat (limited to 'searchlib')
3 files changed, 36 insertions, 11 deletions
diff --git a/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp b/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp index 10015bb658a..837c38eb340 100644 --- a/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp +++ b/searchlib/src/vespa/searchlib/common/indexmetainfo.cpp @@ -1,6 +1,7 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. #include "indexmetainfo.h" +#include <vespa/vespalib/io/fileutil.h> #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/guard.h> #include <cassert> @@ -310,6 +311,7 @@ IndexMetaInfo::save(const vespalib::string &baseName) { vespalib::string fileName = makeFileName(baseName); vespalib::string newName = fileName + ".new"; + vespalib::unlink(newName); vespalib::FilePointer f(fopen(newName.c_str(), "w")); if (!f.valid()) { LOG(warning, "could not open file for writing: %s", newName.c_str()); @@ -350,6 +352,7 @@ IndexMetaInfo::save(const vespalib::string &baseName) newName.c_str(), fileName.c_str()); return false; } + vespalib::File::sync(vespalib::dirname(fileName)); return true; } diff --git a/searchlib/src/vespa/searchlib/transactionlog/domain.cpp b/searchlib/src/vespa/searchlib/transactionlog/domain.cpp index 88c2dd9ecc3..1caff132779 100644 --- a/searchlib/src/vespa/searchlib/transactionlog/domain.cpp +++ b/searchlib/src/vespa/searchlib/transactionlog/domain.cpp @@ -3,6 +3,7 @@ #include "domain.h" #include <vespa/vespalib/util/stringfmt.h> #include <vespa/vespalib/util/closuretask.h> +#include <vespa/vespalib/io/fileutil.h> #include <vespa/fastos/file.h> #include <algorithm> #include <thread> @@ -60,6 +61,7 @@ Domain::Domain(const string &domainName, const string & baseDir, Executor & comm _sessionExecutor.sync(); if (_parts.empty() || _parts.crbegin()->second->isClosed()) { _parts[lastPart].reset(new DomainPart(_name, dir(), lastPart, _defaultCrcType, _fileHeaderContext, false)); + vespalib::File::sync(dir()); } } @@ -294,6 +296,7 @@ void Domain::commit(const Packet & packet) _parts[entry.serial()] = dp; } dp = _parts.rbegin()->second; + vespalib::File::sync(dir()); } dp->commit(entry.serial(), packet); cleanSessions(); @@ -310,6 +313,7 @@ bool Domain::erase(SerialNum to) _parts.erase(it); } retval = retval && dp->erase(to); + vespalib::File::sync(dir()); } if (_parts.begin()->second->range().to() >= to) { _parts.begin()->second->erase(to); diff --git a/searchlib/src/vespa/searchlib/transactionlog/translogserver.cpp b/searchlib/src/vespa/searchlib/transactionlog/translogserver.cpp index 4c3c5609a93..bfca137ba06 100644 --- a/searchlib/src/vespa/searchlib/transactionlog/translogserver.cpp +++ b/searchlib/src/vespa/searchlib/transactionlog/translogserver.cpp @@ -336,6 +336,29 @@ void TransLogServer::exportRPC(FRT_Supervisor & supervisor) rb.ReturnDesc("syncedto", "Entry synced to"); } +namespace { + +void +writeDomainDir(std::lock_guard<std::mutex> &guard, + vespalib::string dir, + vespalib::string domainList, + std::map<vespalib::string, std::shared_ptr<Domain>> &domains) +{ + (void) guard; + vespalib::string domainListTmp(domainList + ".tmp"); + vespalib::unlink(domainListTmp); + std::ofstream domainDir(domainListTmp.c_str(), std::ios::trunc); + for (const auto &domainEntry : domains) { + domainDir << domainEntry.first << std::endl; + } + domainDir.close(); + vespalib::File::sync(domainListTmp); + vespalib::rename(domainListTmp, domainList, false, false); + vespalib::File::sync(dir); +} + +} + void TransLogServer::createDomain(FRT_RPCRequest *req) { uint32_t retval(0); @@ -351,12 +374,9 @@ void TransLogServer::createDomain(FRT_RPCRequest *req) try { domain = std::make_shared<Domain>(domainName, dir(), _commitExecutor, _sessionExecutor, _domainPartSize, _defaultCrcType, _fileHeaderContext); - { - Guard domainGuard(_lock); - _domains[domain->name()] = domain; - } - std::ofstream domainDir(domainList().c_str(), std::ios::app); - domainDir << domain->name() << std::endl; + Guard domainGuard(_lock); + _domains[domain->name()] = domain; + writeDomainDir(domainGuard, dir(), domainList(), _domains); } catch (const std::exception & e) { LOG(warning, "Failed creating %s domain. Exception = %s", domainName, e.what()); retval = uint32_t(-1); @@ -385,12 +405,10 @@ void TransLogServer::deleteDomain(FRT_RPCRequest *req) Guard domainGuard(_lock); _domains.erase(domainName); } - vespalib::rmdir(Domain::getDir(dir(), domainName).c_str(), true); - std::ofstream domainDir(domainList().c_str(), std::ios::trunc); + vespalib::rmdir(Domain::getDir(dir(), domainName), true); + vespalib::File::sync(dir()); Guard domainGuard(_lock); - for (DomainList::const_iterator it(_domains.begin()), mt(_domains.end()); it != mt; it++) { - domainDir << it->first << std::endl; - } + writeDomainDir(domainGuard, dir(), domainList(), _domains); } catch (const std::exception & e) { msg = make_string("Failed deleting %s domain. Exception = %s", domainName, e.what()); retval = -1; |