From a372c7cf186386ff390f5dc8a8bfbaad2a76ec38 Mon Sep 17 00:00:00 2001 From: Evan Tschannen Date: Sat, 16 Mar 2019 22:48:24 -0700 Subject: [PATCH] configure memory now selects the ssd engine for transaction log spilling. Transaction log spilling is only used when the transaction logs cannot keep all of the unpopped mutations it has in memory. If we are only using this data structure because we do not have enough memory, it is much less safe to use the memory storage engine for this purpose. --- fdbcli/fdbcli.actor.cpp | 29 +++++++++++++++++++++++++++++ fdbclient/DatabaseConfiguration.cpp | 2 ++ fdbclient/ManagementAPI.actor.cpp | 3 ++- fdbclient/Schemas.cpp | 3 ++- 4 files changed, 35 insertions(+), 2 deletions(-) diff --git a/fdbcli/fdbcli.actor.cpp b/fdbcli/fdbcli.actor.cpp index 9f7a0c851c..d72e07a0e8 100644 --- a/fdbcli/fdbcli.actor.cpp +++ b/fdbcli/fdbcli.actor.cpp @@ -900,6 +900,7 @@ void printStatus(StatusObjectReader statusObj, StatusClient::StatusLevel level, // If there is a configuration message then there is no configuration information to display outputString += "\nConfiguration:"; std::string outputStringCache = outputString; + bool isOldMemory = false; try { // Configuration section // FIXME: Should we suppress this if there are cluster messages implying that the database has no configuration? @@ -914,6 +915,9 @@ void printStatus(StatusObjectReader statusObj, StatusClient::StatusLevel level, outputString += "\n Storage engine - "; if (statusObjConfig.get("storage_engine", strVal)){ + if(strVal == "old_memory") { + isOldMemory = true; + } outputString += strVal; } else outputString += "unknown"; @@ -1173,6 +1177,7 @@ void printStatus(StatusObjectReader statusObj, StatusClient::StatusLevel level, // Workload section outputString += "\n\nWorkload:"; outputStringCache = outputString; + bool foundLogAndStorage = false; try { // Determine which rates are unknown StatusObjectReader statusObjWorkload; @@ -1225,6 +1230,22 @@ void printStatus(StatusObjectReader statusObj, StatusClient::StatusLevel level, std::vector messagesAddrs; for (auto proc : processesMap.obj()){ StatusObjectReader process(proc.second); + if(process.has("roles")) { + StatusArray rolesArray = proc.second.get_obj()["roles"].get_array(); + bool storageRole = false; + bool logRole = false; + for (StatusObjectReader role : rolesArray) { + if (role["role"].get_str() == "storage") { + storageRole = true; + } + else if (role["role"].get_str() == "log") { + logRole = true; + } + } + if(storageRole && logRole) { + foundLogAndStorage = true; + } + } if (process.has("messages")) { StatusArray processMessagesArr = process.last().get_array(); if (processMessagesArr.size()){ @@ -1408,6 +1429,14 @@ void printStatus(StatusObjectReader statusObj, StatusClient::StatusLevel level, if (clientTime != ""){ outputString += "\n\nClient time: " + clientTime; } + + if(processesMap.obj().size() > 1 && isOldMemory) { + outputString += "\n\nWARNING: type `configure memory' to switch to a safer method of persisting data on the transaction logs."; + } + if(processesMap.obj().size() > 9 && foundLogAndStorage) { + outputString += "\n\nWARNING: A single process is both a transaction log and a storage server.\n For best performance use dedicated disks for the transaction logs by setting process classes."; + } + printf("%s\n", outputString.c_str()); } diff --git a/fdbclient/DatabaseConfiguration.cpp b/fdbclient/DatabaseConfiguration.cpp index 1bc518e0e4..d6bd3d93c5 100644 --- a/fdbclient/DatabaseConfiguration.cpp +++ b/fdbclient/DatabaseConfiguration.cpp @@ -262,6 +262,8 @@ StatusObject DatabaseConfiguration::toJSON(bool noPolicies) const { } else if( tLogDataStoreType == KeyValueStoreType::SSD_BTREE_V2 && storageServerStoreType == KeyValueStoreType::SSD_REDWOOD_V1 ) { result["storage_engine"] = "ssd-redwood-experimental"; } else if( tLogDataStoreType == KeyValueStoreType::MEMORY && storageServerStoreType == KeyValueStoreType::MEMORY ) { + result["storage_engine"] = "old_memory"; + } else if( tLogDataStoreType == KeyValueStoreType::SSD_BTREE_V2 && storageServerStoreType == KeyValueStoreType::MEMORY ) { result["storage_engine"] = "memory"; } else { result["storage_engine"] = "custom"; diff --git a/fdbclient/ManagementAPI.actor.cpp b/fdbclient/ManagementAPI.actor.cpp index 04cbbeb45e..3d879260be 100644 --- a/fdbclient/ManagementAPI.actor.cpp +++ b/fdbclient/ManagementAPI.actor.cpp @@ -94,7 +94,8 @@ std::map configForToken( std::string const& mode ) { // Add any new store types to fdbserver/workloads/ConfigureDatabase, too if (storeType.present()) { - out[p+"log_engine"] = out[p+"storage_engine"] = format("%d", storeType.get()); + out[p+"log_engine"] = format("%d", KeyValueStoreType::SSD_BTREE_V2); + out[p+"storage_engine"] = format("%d", storeType.get()); return out; } diff --git a/fdbclient/Schemas.cpp b/fdbclient/Schemas.cpp index e9c2f97f8b..64b3b156dc 100644 --- a/fdbclient/Schemas.cpp +++ b/fdbclient/Schemas.cpp @@ -501,7 +501,8 @@ const KeyRef JSONSchemas::statusSchema = LiteralStringRef(R"statusSchema( "ssd-1", "ssd-2", "ssd-redwood-experimental", - "memory" + "memory", + "old_memory" ]}, "coordinators_count":1, "excluded_servers":[