summaryrefslogtreecommitdiffstats
path: root/searchlib/src
diff options
context:
space:
mode:
authorTor Egge <Tor.Egge@broadpark.no>2018-08-01 15:32:17 +0200
committerTor Egge <Tor.Egge@oath.com>2018-08-02 10:08:27 +0000
commitf450c9c1302a6fbc93cd0cfaf524b1137b8eca07 (patch)
tree21bc63c94ff99d23553cc6078e8d3780efb7610d /searchlib/src
parent553aa395b40c5fb49abef5a10efb86bbb084fea0 (diff)
Add fsync calls to reduce probability of unexpected state after a crash.
Diffstat (limited to 'searchlib/src')
-rw-r--r--searchlib/src/vespa/searchlib/common/indexmetainfo.cpp3
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/domain.cpp4
-rw-r--r--searchlib/src/vespa/searchlib/transactionlog/translogserver.cpp40
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;