2017-05-26 04:48:44 +08:00
/*
* DatabaseContext . h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013 - 2018 Apple Inc . and the FoundationDB project authors
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* Licensed under the Apache License , Version 2.0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* http : //www.apache.org/licenses/LICENSE-2.0
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
# ifndef DatabaseContext_h
# define DatabaseContext_h
# pragma once
2019-02-18 07:41:16 +08:00
# include "fdbclient/NativeAPI.actor.h"
2018-10-20 01:30:13 +08:00
# include "fdbclient/KeyRangeMap.h"
# include "fdbclient/MasterProxyInterface.h"
2017-05-26 04:48:44 +08:00
# include "fdbrpc/QueueModel.h"
# include "fdbrpc/MultiInterface.h"
# include "flow/TDMetric.actor.h"
2018-10-20 01:30:13 +08:00
# include "fdbclient/EventTypes.actor.h"
2017-05-26 04:48:44 +08:00
# include "fdbrpc/ContinuousSample.h"
2018-11-03 04:15:09 +08:00
class StorageServerInfo : public ReferencedInterface < StorageServerInterface > {
2017-05-26 04:48:44 +08:00
public :
2018-11-03 04:15:09 +08:00
static Reference < StorageServerInfo > getInterface ( DatabaseContext * cx , StorageServerInterface const & interf , LocalityData const & locality ) ;
2017-05-26 04:48:44 +08:00
void notifyContextDestroyed ( ) ;
2018-11-03 04:15:09 +08:00
virtual ~ StorageServerInfo ( ) ;
2017-05-26 04:48:44 +08:00
private :
DatabaseContext * cx ;
2018-11-03 04:15:09 +08:00
StorageServerInfo ( DatabaseContext * cx , StorageServerInterface const & interf , LocalityData const & locality ) : cx ( cx ) , ReferencedInterface < StorageServerInterface > ( interf , locality ) { }
2017-05-26 04:48:44 +08:00
} ;
2018-11-03 04:15:09 +08:00
typedef MultiInterface < ReferencedInterface < StorageServerInterface > > LocationInfo ;
typedef MultiInterface < MasterProxyInterface > ProxyInfo ;
2017-05-26 04:48:44 +08:00
2019-03-15 01:26:22 +08:00
class DatabaseContext : public ReferenceCounted < DatabaseContext > , public FastAllocated < DatabaseContext > , NonCopyable {
2017-05-26 04:48:44 +08:00
public :
2019-03-15 01:26:22 +08:00
static DatabaseContext * allocateOnForeignThread ( ) {
return ( DatabaseContext * ) DatabaseContext : : operator new ( sizeof ( DatabaseContext ) ) ;
}
2018-09-26 06:06:19 +08:00
// For internal (fdbserver) use only
2019-05-25 01:51:08 +08:00
static Database create ( Reference < AsyncVar < ClientDBInfo > > clientInfo , Future < Void > clientInfoMonitor ,
LocalityData clientLocality , bool enableLocalityLoadBalance ,
2019-07-10 04:41:54 +08:00
TaskPriority taskID = TaskPriority : : DefaultEndpoint , bool lockAware = false ,
2019-05-25 01:51:08 +08:00
int apiVersion = Database : : API_VERSION_LATEST , bool switchable = false ) ;
2017-05-26 04:48:44 +08:00
~ DatabaseContext ( ) ;
2019-07-27 06:05:02 +08:00
Database clone ( ) const { return Database ( new DatabaseContext ( connectionFile , clientInfo , clientInfoMonitor , taskID , clientLocality , enableLocalityLoadBalance , lockAware , internal , apiVersion , switchable ) ) ; }
2017-05-26 04:48:44 +08:00
2019-05-17 04:54:06 +08:00
std : : pair < KeyRange , Reference < LocationInfo > > getCachedLocation ( const KeyRef & , bool isBackward = false ) ;
2017-05-26 04:48:44 +08:00
bool getCachedLocations ( const KeyRangeRef & , vector < std : : pair < KeyRange , Reference < LocationInfo > > > & , int limit , bool reverse ) ;
Reference < LocationInfo > setCachedLocation ( const KeyRangeRef & , const vector < struct StorageServerInterface > & ) ;
void invalidateCache ( const KeyRef & , bool isBackward = false ) ;
void invalidateCache ( const KeyRangeRef & ) ;
2019-03-20 09:44:37 +08:00
Reference < ProxyInfo > getMasterProxies ( bool useProvisionalProxies ) ;
Future < Reference < ProxyInfo > > getMasterProxiesFuture ( bool useProvisionalProxies ) ;
2017-05-26 04:48:44 +08:00
Future < Void > onMasterProxiesChanged ( ) ;
2019-03-05 06:16:39 +08:00
Future < HealthMetrics > getHealthMetrics ( bool detailed ) ;
2017-05-26 04:48:44 +08:00
// Update the watch counter for the database
void addWatch ( ) ;
void removeWatch ( ) ;
void setOption ( FDBDatabaseOptions : : Option option , Optional < StringRef > value ) ;
2018-09-22 06:58:14 +08:00
Error deferredError ;
2017-05-26 04:48:44 +08:00
bool lockAware ;
2018-10-03 06:28:46 +08:00
bool isError ( ) {
return deferredError . code ( ) ! = invalid_error_code ;
}
2017-05-26 04:48:44 +08:00
void checkDeferredError ( ) {
2018-10-03 06:28:46 +08:00
if ( isError ( ) ) {
2018-09-22 06:58:14 +08:00
throw deferredError ;
}
2017-05-26 04:48:44 +08:00
}
2018-09-22 06:58:14 +08:00
int apiVersionAtLeast ( int minVersion ) { return apiVersion < 0 | | apiVersion > = minVersion ; }
2017-05-26 04:48:44 +08:00
2018-09-22 06:58:14 +08:00
Future < Void > onConnected ( ) ; // Returns after a majority of coordination servers are available and have reported a leader. The cluster file therefore is valid, but the database might be unavailable.
Reference < ClusterConnectionFile > getConnectionFile ( ) ;
2019-05-25 00:24:23 +08:00
// Switch the database to use the new connection file, and recreate all pending watches for committed transactions.
2019-04-23 06:48:47 +08:00
//
// Meant to be used as part of a 'hot standby' solution to switch to the standby. A correct switch will involve
// advancing the version on the new cluster sufficiently far that any transaction begun with a read version from the
// old cluster will fail to commit. Assuming the above version-advancing is done properly, a call to
2019-05-25 00:24:23 +08:00
// switchConnectionFile guarantees that any read with a version from the old cluster will not be attempted on the
2019-04-23 06:48:47 +08:00
// new cluster.
2019-05-25 00:24:23 +08:00
Future < Void > switchConnectionFile ( Reference < ClusterConnectionFile > standby ) ;
2019-06-20 07:53:14 +08:00
Future < Void > connectionFileChanged ( ) ;
2019-05-25 01:51:08 +08:00
bool switchable = false ;
2019-04-23 06:48:47 +08:00
2018-09-22 06:58:14 +08:00
//private:
2019-07-27 06:05:02 +08:00
explicit DatabaseContext ( Reference < AsyncVar < Reference < ClusterConnectionFile > > > connectionFile , Reference < AsyncVar < ClientDBInfo > > clientDBInfo ,
2019-07-09 05:01:04 +08:00
Future < Void > clientInfoMonitor , TaskPriority taskID , LocalityData const & clientLocality ,
2019-07-13 02:39:19 +08:00
bool enableLocalityLoadBalance , bool lockAware , bool internal = true , int apiVersion = Database : : API_VERSION_LATEST , bool switchable = false ) ;
2017-05-26 04:48:44 +08:00
2018-10-03 06:28:46 +08:00
explicit DatabaseContext ( const Error & err ) ;
2019-03-15 04:42:03 +08:00
2017-05-26 04:48:44 +08:00
// Key DB-specific information
2019-07-27 06:05:02 +08:00
Reference < AsyncVar < Reference < ClusterConnectionFile > > > connectionFile ;
2017-11-02 09:29:56 +08:00
AsyncTrigger masterProxiesChangeTrigger ;
Future < Void > monitorMasterProxiesInfoChange ;
2017-05-26 04:48:44 +08:00
Reference < ProxyInfo > masterProxies ;
2019-03-20 09:44:37 +08:00
bool provisional ;
2017-05-26 04:48:44 +08:00
UID masterProxiesLastChange ;
LocalityData clientLocality ;
QueueModel queueModel ;
bool enableLocalityLoadBalance ;
// Transaction start request batching
struct VersionBatcher {
PromiseStream < std : : pair < Promise < GetReadVersionReply > , Optional < UID > > > stream ;
Future < Void > actor ;
} ;
std : : map < uint32_t , VersionBatcher > versionBatcher ;
2019-06-20 07:53:14 +08:00
AsyncTrigger connectionFileChangedTrigger ;
2019-04-23 06:48:47 +08:00
// Disallow any reads at a read version lower than minAcceptableReadVersion. This way the client does not have to
// trust that the read version (possibly set manually by the application) is actually from the correct cluster.
// Updated everytime we get a GRV response
Version minAcceptableReadVersion = std : : numeric_limits < Version > : : max ( ) ;
void validateVersion ( Version ) ;
2017-05-26 04:48:44 +08:00
// Client status updater
struct ClientStatusUpdater {
2019-02-13 05:54:24 +08:00
std : : vector < std : : pair < std : : string , BinaryWriter > > inStatusQ ;
std : : vector < std : : pair < std : : string , BinaryWriter > > outStatusQ ;
2017-05-26 04:48:44 +08:00
Future < Void > actor ;
} ;
ClientStatusUpdater clientStatusUpdater ;
// Cache of location information
int locationCacheSize ;
CoalescedKeyRangeMap < Reference < LocationInfo > > locationCache ;
2018-11-03 04:15:09 +08:00
std : : map < UID , StorageServerInfo * > server_interf ;
2017-05-26 04:48:44 +08:00
2019-07-09 05:01:04 +08:00
UID dbId ;
2019-07-10 05:17:26 +08:00
bool internal ; // Only contexts created through the C client and fdbcli are non-internal
2019-07-09 05:01:04 +08:00
CounterCollection cc ;
Counter transactionReadVersions ;
Counter transactionLogicalReads ;
Counter transactionPhysicalReads ;
Counter transactionCommittedMutations ;
Counter transactionCommittedMutationBytes ;
Counter transactionsCommitStarted ;
Counter transactionsCommitCompleted ;
Counter transactionsTooOld ;
Counter transactionsFutureVersions ;
Counter transactionsNotCommitted ;
Counter transactionsMaybeCommitted ;
Counter transactionsResourceConstrained ;
Counter transactionsProcessBehind ;
2017-05-26 04:48:44 +08:00
ContinuousSample < double > latencies , readLatencies , commitLatencies , GRVLatencies , mutationsPerCommit , bytesPerCommit ;
int outstandingWatches ;
int maxOutstandingWatches ;
2019-03-20 00:15:41 +08:00
int snapshotRywEnabled ;
2017-05-26 04:48:44 +08:00
Future < Void > logger ;
2019-06-25 17:47:35 +08:00
TaskPriority taskID ;
2017-05-26 04:48:44 +08:00
Int64MetricHandle getValueSubmitted ;
EventMetricHandle < GetValueComplete > getValueCompleted ;
2018-09-22 06:58:14 +08:00
Reference < AsyncVar < ClientDBInfo > > clientInfo ;
Future < Void > clientInfoMonitor ;
2019-07-24 10:22:44 +08:00
Future < Void > connected ;
2018-09-22 06:58:14 +08:00
int apiVersion ;
2019-03-01 09:45:00 +08:00
2019-03-03 05:55:41 +08:00
int mvCacheInsertLocation ;
2019-03-01 09:45:00 +08:00
std : : vector < std : : pair < Version , Optional < Value > > > metadataVersionCache ;
2019-03-04 14:58:45 +08:00
2019-02-02 05:23:10 +08:00
HealthMetrics healthMetrics ;
2019-03-05 06:16:39 +08:00
double healthMetricsLastUpdated ;
double detailedHealthMetricsLastUpdated ;
2019-06-29 04:24:32 +08:00
UniqueOrderedOptionList < FDBTransactionOptions > transactionDefaults ;
2017-05-26 04:48:44 +08:00
} ;
# endif