strengthened the protections related to changing regions

This commit is contained in:
Evan Tschannen 2018-11-12 17:40:40 -08:00
parent 26c49f21be
commit 6353a6724b
4 changed files with 38 additions and 19 deletions

View File

@ -1610,12 +1610,17 @@ ACTOR Future<bool> configure( Database db, std::vector<StringRef> tokens, Refere
ret=false;
break;
case ConfigurationResult::REGION_NOT_FULLY_REPLICATED:
printf("ERROR: When usable_regions=2, all regions with priority >= 0 must be fully replicated before changing the configuration\n");
printf("ERROR: When usable_regions > 1, all regions with priority >= 0 must be fully replicated before changing the configuration\n");
printf("Type `configure FORCE <TOKEN>*' to configure without this check\n");
ret=false;
break;
case ConfigurationResult::MULTIPLE_ACTIVE_REGIONS:
printf("ERROR: When changing from usable_regions=1 to usable_regions=2, only one region can have priority >= 0\n");
printf("ERROR: When changing usable_regions, only one region can have priority >= 0\n");
printf("Type `configure FORCE <TOKEN>*' to configure without this check\n");
ret=false;
break;
case ConfigurationResult::REGIONS_CHANGED:
printf("ERROR: The region configuration cannot be changed while simultaneously reducing usable_regions\n");
printf("Type `configure FORCE <TOKEN>*' to configure without this check\n");
ret=false;
break;
@ -1714,15 +1719,20 @@ ACTOR Future<bool> fileConfigure(Database db, std::string filePath, bool isNewDa
ret=false;
break;
case ConfigurationResult::REGION_NOT_FULLY_REPLICATED:
printf("ERROR: When usable_regions=2, all regions with priority >= 0 must be fully replicated before changing the configuration\n");
printf("ERROR: When usable_regions > 1, All regions with priority >= 0 must be fully replicated before changing the configuration\n");
printf("Type `fileconfigure FORCE <FILENAME>' to configure without this check\n");
ret=false;
break;
case ConfigurationResult::MULTIPLE_ACTIVE_REGIONS:
printf("ERROR: When changing from usable_regions=1 to usable_regions=2, only one region can have priority >= 0\n");
printf("ERROR: When changing usable_regions, only one region can have priority >= 0\n");
printf("Type `fileconfigure FORCE <FILENAME>' to configure without this check\n");
ret=false;
break;
case ConfigurationResult::REGIONS_CHANGED:
printf("ERROR: The region configuration cannot be changed while simultaneously reducing usable_regions\n");
printf("Type `fileconfigure FORCE <TOKEN>*' to configure without this check\n");
ret=false;
break;
case ConfigurationResult::SUCCESS:
printf("Configuration changed\n");
ret=false;

View File

@ -311,7 +311,20 @@ ACTOR Future<ConfigurationResult::Type> changeConfig( Database cx, std::map<std:
return ConfigurationResult::INVALID_CONFIGURATION;
}
if(oldConfig.usableRegions==1 && newConfig.usableRegions==2) {
if(oldConfig.usableRegions==2 && newConfig.usableRegions==1) {
//cannot change region configuration
std::map<Key,int32_t> dcId_priority;
for(auto& it : newConfig.regions) {
dcId_priority[it.dcId] = it.priority;
}
for(auto& it : oldConfig.regions) {
if(!dcId_priority.count(it.dcId) || dcId_priority[it.dcId] != it.priority) {
return ConfigurationResult::REGIONS_CHANGED;
}
}
}
if(oldConfig.usableRegions != newConfig.usableRegions) {
//must only have one region with priority >= 0
int activeRegionCount = 0;
for(auto& it : newConfig.regions) {

View File

@ -53,6 +53,7 @@ public:
STORAGE_IN_UNKNOWN_DCID,
REGION_NOT_FULLY_REPLICATED,
MULTIPLE_ACTIVE_REGIONS,
REGIONS_CHANGED,
SUCCESS
};
};

View File

@ -29,13 +29,16 @@
static const char* storeTypes[] = { "ssd", "ssd-1", "ssd-2", "memory" };
static const char* redundancies[] = { "single", "double", "triple" };
std::string generateRegions(int& regions) {
std::string generateRegions() {
std::string result;
if(g_simulator.physicalDatacenters == 1 || (g_simulator.physicalDatacenters == 2 && g_random->random01() < 0.25) || g_simulator.physicalDatacenters == 3) {
regions = 1;
return " usable_regions=1 regions=\"\"";
}
if(g_random->random01() < 0.25) {
return format(" usable_regions=%d", g_random->randomInt(1,3));
}
int primaryPriority = 1;
int remotePriority = -1;
double priorityType = g_random->random01();
@ -180,16 +183,9 @@ std::string generateRegions(int& regions) {
if(g_random->random01() < 0.8) {
regionArr.push_back(remoteObj);
if(g_random->random01() < 0.8) {
regions = 2;
result += " usable_regions=2";
} else {
regions = 1;
result += " usable_regions=1";
if(g_random->random01() < 0.25) {
result += format(" usable_regions=%d", g_random->randomInt(1,3));
}
} else {
regions = 1;
result += " usable_regions=1";
}
result += " regions=" + json_spirit::write_string(json_spirit::mValue(regionArr), json_spirit::Output_options::none);
@ -320,15 +316,14 @@ struct ConfigureDatabaseWorkload : TestWorkload {
if(g_simulator.physicalDatacenters == 2 || g_simulator.physicalDatacenters > 3) {
maxRedundancies--; //There are not enough machines for triple replication in fearless configurations
}
int redundancy = g_random->randomInt( 0, maxRedundancies);
int redundancy = g_random->randomInt(0, maxRedundancies);
std::string config = redundancies[redundancy];
if(config == "triple" && g_simulator.physicalDatacenters == 3) {
config = "three_data_hall ";
}
state int regions = 1;
config += generateRegions(regions);
config += generateRegions();
if (g_random->random01() < 0.5) config += " logs=" + format("%d", randomRoleNumber());
if (g_random->random01() < 0.5) config += " proxies=" + format("%d", randomRoleNumber());