MCPcopy Create free account
hub / github.com/apple/foundationdb / getDurableVersion

Method getDurableVersion

fdbserver/TagPartitionedLogSystem.actor.cpp:1885–1981  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1883}
1884
1885Optional<std::tuple<Version, Version, std::vector<TLogLockResult>>> TagPartitionedLogSystem::getDurableVersion(
1886 UID dbgid,
1887 LogLockInfo lockInfo,
1888 std::vector<Reference<AsyncVar<bool>>> failed,
1889 Optional<Version> lastEnd) {
1890
1891 Reference<LogSet> logSet = lockInfo.logSet;
1892 // To ensure consistent recovery, the number of servers NOT in the write quorum plus the number of servers NOT
1893 // in the read quorum have to be strictly less than the replication factor. Otherwise there could be a replica
1894 // set consistent entirely of servers that are out of date due to not being in the write quorum or unavailable
1895 // due to not being in the read quorum. So with N = # of tlogs, W = antiquorum, R = required count, F =
1896 // replication factor, W + (N - R) < F, and optimally (N-W)+(N-R)=F-1. Thus R=N+1-F+W.
1897 int requiredCount =
1898 (int)logSet->logServers.size() + 1 - logSet->tLogReplicationFactor + logSet->tLogWriteAntiQuorum;
1899 ASSERT(requiredCount > 0 && requiredCount <= logSet->logServers.size());
1900 ASSERT(logSet->tLogReplicationFactor >= 1 && logSet->tLogReplicationFactor <= logSet->logServers.size());
1901 ASSERT(logSet->tLogWriteAntiQuorum >= 0 && logSet->tLogWriteAntiQuorum < logSet->logServers.size());
1902
1903 std::vector<LocalityData> availableItems, badCombo;
1904 std::vector<TLogLockResult> results;
1905 std::string sServerState;
1906 LocalityGroup unResponsiveSet;
1907 for (int t = 0; t < logSet->logServers.size(); t++) {
1908 if (lockInfo.replies[t].isReady() && !lockInfo.replies[t].isError() && (!failed.size() || !failed[t]->get())) {
1909 results.push_back(lockInfo.replies[t].get());
1910 availableItems.push_back(logSet->tLogLocalities[t]);
1911 sServerState += 'a';
1912 } else {
1913 unResponsiveSet.add(logSet->tLogLocalities[t]);
1914 sServerState += 'f';
1915 }
1916 }
1917
1918 // Check if the list of results is not larger than the anti quorum
1919 bool bTooManyFailures = (results.size() <= logSet->tLogWriteAntiQuorum);
1920
1921 // Check if failed logs complete the policy
1922 bTooManyFailures = bTooManyFailures || ((unResponsiveSet.size() >= logSet->tLogReplicationFactor) &&
1923 (unResponsiveSet.validate(logSet->tLogPolicy)));
1924
1925 // Check all combinations of the AntiQuorum within the failed
1926 if (!bTooManyFailures && (logSet->tLogWriteAntiQuorum) &&
1927 (!validateAllCombinations(
1928 badCombo, unResponsiveSet, logSet->tLogPolicy, availableItems, logSet->tLogWriteAntiQuorum, false))) {
1929 TraceEvent("EpochEndBadCombo", dbgid)
1930 .detail("Required", requiredCount)
1931 .detail("Present", results.size())
1932 .detail("ServerState", sServerState);
1933 bTooManyFailures = true;
1934 }
1935
1936 ASSERT(logSet->logServers.size() == lockInfo.replies.size());
1937 if (!bTooManyFailures) {
1938 std::sort(results.begin(), results.end(), [](const TLogLockResult& a, const TLogLockResult& b) -> bool {
1939 return a.end < b.end;
1940 });
1941 int absent = logSet->logServers.size() - results.size();
1942 int safe_range_begin = logSet->tLogWriteAntiQuorum;

Callers

nothing calls this directly

Calls 13

validateAllCombinationsFunction · 0.85
TraceEventClass · 0.85
detailMethod · 0.80
getMethod · 0.65
sizeMethod · 0.45
isReadyMethod · 0.45
isErrorMethod · 0.45
push_backMethod · 0.45
addMethod · 0.45
validateMethod · 0.45
beginMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected