mirror of https://gitee.com/bigwinds/arangodb
First set of changes, not yet activated.
This commit is contained in:
parent
f47329f3c0
commit
e9630b7aca
|
@ -1,7 +1,7 @@
|
|||
/* global ArangoServerState, ArangoClusterInfo */
|
||||
'use strict';
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief JavaScript cluster functionality
|
||||
// /
|
||||
// / @file
|
||||
|
@ -26,7 +26,7 @@
|
|||
// /
|
||||
// / @author Jan Steemann
|
||||
// / @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var console = require('console');
|
||||
var arangodb = require('@arangodb');
|
||||
|
@ -133,9 +133,9 @@ function cancelReadLockOnLeader (endpoint, database, lockJobId) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief cancel barrier from sync
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function cancelBarrier (endpoint, database, barrierId) {
|
||||
if (barrierId <= 0) {
|
||||
|
@ -152,9 +152,9 @@ function cancelBarrier (endpoint, database, barrierId) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief tell leader that we are in sync
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function addShardFollower (endpoint, database, shard) {
|
||||
console.debug('addShardFollower: tell the leader to put us into the follower list...');
|
||||
|
@ -169,9 +169,9 @@ function addShardFollower (endpoint, database, shard) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief tell leader that we are stop following
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function removeShardFollower (endpoint, database, shard) {
|
||||
console.debug('removeShardFollower: tell the leader to take us off the follower list...');
|
||||
|
@ -186,9 +186,9 @@ function removeShardFollower (endpoint, database, shard) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief lookup for 4-dimensional nested dictionary data
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function lookup4d (data, a, b, c) {
|
||||
if (!data.hasOwnProperty(a)) {
|
||||
|
@ -203,9 +203,9 @@ function lookup4d (data, a, b, c) {
|
|||
return data[a][b][c];
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief return a shardId => server map
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getShardMap (plannedCollections) {
|
||||
var shardMap = { };
|
||||
|
@ -235,9 +235,9 @@ function getShardMap (plannedCollections) {
|
|||
return shardMap;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief return the indexes of a collection as a map
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getIndexMap (shard) {
|
||||
var indexes = { }, i;
|
||||
|
@ -254,24 +254,28 @@ function getIndexMap (shard) {
|
|||
return indexes;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief return a hash with the local databases
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getLocalDatabases () {
|
||||
var result = { };
|
||||
var db = require('internal').db;
|
||||
|
||||
db._databases().forEach(function (database) {
|
||||
result[database] = { name: database };
|
||||
});
|
||||
|
||||
let result = { };
|
||||
let db = require('internal').db;
|
||||
let curDb = db._name();
|
||||
try {
|
||||
db._databases().forEach(function (database) {
|
||||
db._useDatabase(database);
|
||||
result[database] = { name: database, id: db._id() };
|
||||
});
|
||||
} finally {
|
||||
db._useDatabase(curDb);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief return a hash with the local collections
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function getLocalCollections () {
|
||||
var result = { };
|
||||
|
@ -305,9 +309,9 @@ function getLocalCollections () {
|
|||
return result;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief create databases if they exist in the plan but not locally
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function createLocalDatabases (plannedDatabases, currentDatabases) {
|
||||
var ourselves = global.ArangoServerState.id();
|
||||
|
@ -360,9 +364,9 @@ function createLocalDatabases (plannedDatabases, currentDatabases) {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief drop databases if they do exist locally but not in the plan
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function dropLocalDatabases (plannedDatabases) {
|
||||
var ourselves = global.ArangoServerState.id();
|
||||
|
@ -415,9 +419,9 @@ function dropLocalDatabases (plannedDatabases) {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief clean up what's in Current/Databases for ourselves
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function cleanupCurrentDatabases (currentDatabases) {
|
||||
var ourselves = global.ArangoServerState.id();
|
||||
|
@ -455,9 +459,9 @@ function cleanupCurrentDatabases (currentDatabases) {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief handle database changes
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function handleDatabaseChanges (plan, current) {
|
||||
var plannedDatabases = plan.Databases;
|
||||
|
@ -468,9 +472,9 @@ function handleDatabaseChanges (plan, current) {
|
|||
cleanupCurrentDatabases(currentDatabases);
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief create collections if they exist in the plan but not locally
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function createLocalCollections (plannedCollections, planVersion,
|
||||
currentCollections, takeOverResponsibility) {
|
||||
|
@ -785,9 +789,9 @@ function leaderResign (database, collId, shardName, ourselves) {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief drop collections if they exist locally but not in the plan
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function dropLocalCollections (plannedCollections, currentCollections) {
|
||||
var ourselves = global.ArangoServerState.id();
|
||||
|
@ -898,9 +902,9 @@ function dropLocalCollections (plannedCollections, currentCollections) {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief clean up what's in Current/Collections for ourselves
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function cleanupCurrentCollections (plannedCollections, currentCollections) {
|
||||
var dropCollectionAgency = function (database, collection, shardID) {
|
||||
|
@ -955,9 +959,9 @@ function cleanupCurrentCollections (plannedCollections, currentCollections) {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief lock key space
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function lockSyncKeyspace () {
|
||||
while (!global.KEY_SET_CAS('shardSynchronization', 'lock', 1, null)) {
|
||||
|
@ -965,17 +969,17 @@ function lockSyncKeyspace () {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief unlock key space
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function unlockSyncKeyspace () {
|
||||
global.KEY_SET('shardSynchronization', 'lock', null);
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief launch a scheduled job if needed
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function tryLaunchJob () {
|
||||
const registerTask = require('internal').registerTask;
|
||||
|
@ -1033,9 +1037,9 @@ function tryLaunchJob () {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief synchronize one shard, this is run as a V8 task
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function synchronizeOneShard (database, shard, planId, leader) {
|
||||
// synchronize this shard from the leader
|
||||
|
@ -1183,9 +1187,9 @@ function synchronizeOneShard (database, shard, planId, leader) {
|
|||
database, shard, database, planId);
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief schedule a shard synchronization
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function scheduleOneShardSynchronization (database, shard, planId, leader) {
|
||||
console.debug('scheduleOneShardSynchronization:', database, shard, planId,
|
||||
|
@ -1222,10 +1226,10 @@ function scheduleOneShardSynchronization (database, shard, planId, leader) {
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief synchronize collections for which we are followers (synchronously
|
||||
// / replicated shards)
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function synchronizeLocalFollowerCollections (plannedCollections,
|
||||
currentCollections) {
|
||||
|
@ -1299,9 +1303,9 @@ function synchronizeLocalFollowerCollections (plannedCollections,
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief handle collection changes
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function handleCollectionChanges (plan, current, takeOverResponsibility) {
|
||||
var plannedCollections = plan.Collections;
|
||||
|
@ -1335,7 +1339,7 @@ function handleCollectionChanges (plan, current, takeOverResponsibility) {
|
|||
function migratePrimary(plan, current) {
|
||||
// will analyze local state and then issue db._create(),
|
||||
// db._drop() etc. to sync plan and local state for shards
|
||||
let localErrors = executePlanForDatabases(plan);
|
||||
let localErrors = executePlanForCollections(plan);
|
||||
|
||||
// will do a diff between plan and current to find out
|
||||
// the shards for which this db server is a planned
|
||||
|
@ -1350,9 +1354,139 @@ function migratePrimary(plan, current) {
|
|||
|
||||
// diff current and local and prepare agency transactions or whatever
|
||||
// to update current. Will report the errors created locally to the agency
|
||||
updateCurrentForDatabases(localErrors, current);
|
||||
updateCurrentForCollections(localErrors, current);
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief executePlanForDatabases
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function executePlanForDatabases(plan) {
|
||||
let plannedDatabases = plan.Databases;
|
||||
let localErrors = {};
|
||||
|
||||
let db = require('internal').db;
|
||||
db._useDatabase('_system');
|
||||
|
||||
let localDatabases = getLocalDatabases();
|
||||
let name;
|
||||
|
||||
// check which databases need to be created locally:
|
||||
for (name in plannedDatabases) {
|
||||
if (plannedDatabases.hasOwnProperty(name)) {
|
||||
if (!localDatabases.hasOwnProperty(name)) {
|
||||
// must create database
|
||||
|
||||
// TODO: handle options and user information
|
||||
|
||||
console.debug("creating local database '%s'", name);
|
||||
|
||||
try {
|
||||
db._createDatabase(name);
|
||||
} catch (err) {
|
||||
localErrors[name] = { error: true, errorNum: err.errorNum,
|
||||
errorMessage: err.errorMessage, name: name };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// check which databases need to be deleted locally
|
||||
localDatabases = getLocalDatabases();
|
||||
for (name in localDatabases) {
|
||||
if (localDatabases.hasOwnProperty(name)) {
|
||||
if (!plannedDatabases.hasOwnProperty(name) && name.substr(0, 1) !== '_') {
|
||||
// must drop database
|
||||
|
||||
console.info("dropping local database '%s'", name);
|
||||
|
||||
// Do we have to stop a replication applier first?
|
||||
if (ArangoServerState.role() === 'SECONDARY') {
|
||||
try {
|
||||
db._useDatabase(name);
|
||||
var rep = require('@arangodb/replication');
|
||||
var state = rep.applier.state();
|
||||
if (state.state.running === true) {
|
||||
console.info('stopping replication applier first');
|
||||
rep.applier.stop();
|
||||
}
|
||||
}
|
||||
finally {
|
||||
db._useDatabase('_system');
|
||||
}
|
||||
}
|
||||
db._dropDatabase(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return localErrors;
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief updateCurrentForDatabases
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function updateCurrentForDatabases(localErrors, current) {
|
||||
let ourselves = global.ArangoServerState.id();
|
||||
|
||||
function makeAddDatabaseAgencyOperation(payload, trx) {
|
||||
trx[0][curDatabases + payload.name + '/' + ourselves] =
|
||||
{op: 'set', new: payload};
|
||||
};
|
||||
|
||||
function makeDropDatabaseAgencyOperation(name, trx) {
|
||||
trx[0][curDatabases + name + '/' + ourselves] = {'op':'delete'};
|
||||
};
|
||||
|
||||
let db = require('internal').db;
|
||||
db._useDatabase('_system');
|
||||
|
||||
let localDatabases = getLocalDatabases();
|
||||
let currentDatabases = current.Databases;
|
||||
let name;
|
||||
let trx = [{}]; // Here we collect all write operations
|
||||
|
||||
// Add entries that we have but that are not in Current:
|
||||
for (name in localDatabases) {
|
||||
if (localDatabases.hasOwnProperty(name) && name.substr(0, 1) !== '_') {
|
||||
if (!currentDatabases.hasOwnProperty(name) ||
|
||||
!currentDatabases[name].hasOwnProperty(ourselves)) {
|
||||
console.debug("adding entry in Current for database '%s'", name);
|
||||
makeAddDatabaseAgencyOperation({error: false, errorNum: 0, name: name,
|
||||
id: localDatabases[name].id,
|
||||
errorMessage: ""}, trx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove entries from current that no longer exist locally:
|
||||
for (name in currentDatabases) {
|
||||
if (currentDatabases.hasOwnProperty(name) && name.substr(0, 1) !== '_') {
|
||||
if (!localDatabases.hasOwnProperty(name)) {
|
||||
// we found a database we don't have locally
|
||||
|
||||
if (currentDatabases[name].hasOwnProperty(ourselves)) {
|
||||
// we are entered for a database that we don't have locally
|
||||
console.debug("cleaning up entry for unknown database '%s'", name);
|
||||
makeDropDatabaseAgencyOperation(name, trx);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, report any errors that might have been produced earlier when
|
||||
// we were trying to execute the Plan:
|
||||
for (name in localErrors) {
|
||||
if (localErrors.hasOwnProperty(name)) {
|
||||
console.debug("reporting error to Current about database '%s'", name);
|
||||
makeAddDatabaseAgencyOperation(localErrors[name], trx);
|
||||
}
|
||||
}
|
||||
|
||||
return trx;
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief take care of databases on any type of server according to Plan
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1360,10 +1494,22 @@ function migratePrimary(plan, current) {
|
|||
function migrateAnyServer(plan, current) {
|
||||
// will analyze local state and then issue db._createDatabase(),
|
||||
// db._dropDatabase() etc. to sync plan and local state for databases
|
||||
let localErrors = executePlanForCollections(plan);
|
||||
let localErrors = executePlanForDatabases(plan);
|
||||
// diff current and local and prepare agency transactions or whatever
|
||||
// to update current. will report the errors created locally to the agency
|
||||
updateCurrentForCollections(localErrors, current);
|
||||
let trx = updateCurrentForDatabases(localErrors, current);
|
||||
if (Object.keys().length !== 0) {
|
||||
trx[0][curVersion] = {op: 'increment'};
|
||||
// TODO: reduce timeout when we can:
|
||||
try {
|
||||
let res = global.ArangoAgency.write([trx]);
|
||||
if (typeof res !== 'object' || res.length !== 1 || res[0] === 0) {
|
||||
console.error('migrateAnyServer: could not send transaction for Current to agency, result:', res);
|
||||
}
|
||||
} catch (err) {
|
||||
console.error('migrateAnyServer: caught exception when sending transaction for Current to agency:', err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -1408,9 +1554,9 @@ function setupReplication () {
|
|||
return ok;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief role change from secondary to primary
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function secondaryToPrimary () {
|
||||
console.info('Switching role from secondary to primary...');
|
||||
|
@ -1440,49 +1586,49 @@ function secondaryToPrimary () {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief role change from primary to secondary
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function primaryToSecondary () {
|
||||
console.info('Switching role from primary to secondary...');
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief change handling trampoline function
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function handleChanges (plan, current) {
|
||||
// Note: This is never called with role === 'COORDINATOR' or on a single
|
||||
// server.
|
||||
var changed = false;
|
||||
var role = ArangoServerState.role();
|
||||
if (role === 'PRIMARY' || role === 'SECONDARY') {
|
||||
// Need to check role change for automatic failover:
|
||||
var myId = ArangoServerState.id();
|
||||
if (role === 'PRIMARY') {
|
||||
if (!plan.DBServers[myId]) {
|
||||
// Ooops! We do not seem to be a primary any more!
|
||||
changed = ArangoServerState.redetermineRole();
|
||||
// Need to check role change for automatic failover:
|
||||
var myId = ArangoServerState.id();
|
||||
if (role === 'PRIMARY') {
|
||||
if (!plan.DBServers[myId]) {
|
||||
// Ooops! We do not seem to be a primary any more!
|
||||
changed = ArangoServerState.redetermineRole();
|
||||
}
|
||||
} else { // role === "SECONDARY"
|
||||
if (plan.DBServers[myId]) {
|
||||
changed = ArangoServerState.redetermineRole();
|
||||
if (!changed) {
|
||||
// mop: oops...changing role has failed. retry next time.
|
||||
return false;
|
||||
}
|
||||
} else { // role === "SECONDARY"
|
||||
if (plan.DBServers[myId]) {
|
||||
} else {
|
||||
var found = null;
|
||||
var p;
|
||||
for (p in plan) {
|
||||
if (plan.hasOwnProperty(p) && plan[p] === myId) {
|
||||
found = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found !== ArangoServerState.idOfPrimary()) {
|
||||
// Note this includes the case that we are not found at all!
|
||||
changed = ArangoServerState.redetermineRole();
|
||||
if (!changed) {
|
||||
// mop: oops...changing role has failed. retry next time.
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
var found = null;
|
||||
var p;
|
||||
for (p in plan) {
|
||||
if (plan.hasOwnProperty(p) && plan[p] === myId) {
|
||||
found = p;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found !== ArangoServerState.idOfPrimary()) {
|
||||
// Note this includes the case that we are not found at all!
|
||||
changed = ArangoServerState.redetermineRole();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1501,7 +1647,7 @@ function handleChanges (plan, current) {
|
|||
// migrateAnyServer(plan, current)
|
||||
// if (role === 'PRIMARY') {
|
||||
// migratePrimary(plan, current);
|
||||
// } else if (role == 'SECONDARY') {
|
||||
// } else { // if (role == 'SECONDARY') {
|
||||
// setupReplication();
|
||||
// }
|
||||
|
||||
|
@ -1519,9 +1665,9 @@ function handleChanges (plan, current) {
|
|||
return success;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief throw an ArangoError
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var raiseError = function (code, msg) {
|
||||
var err = new ArangoError();
|
||||
|
@ -1531,9 +1677,9 @@ var raiseError = function (code, msg) {
|
|||
throw err;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief retrieve a list of shards for a collection
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var shardList = function (dbName, collectionName) {
|
||||
let ci = global.ArangoClusterInfo.getCollectionInfo(dbName, collectionName);
|
||||
|
@ -1561,9 +1707,9 @@ var shardList = function (dbName, collectionName) {
|
|||
return shards;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief wait for a distributed response
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var waitForDistributedResponse = function (data, numberOfRequests) {
|
||||
var received = [];
|
||||
|
@ -1612,9 +1758,9 @@ var waitForDistributedResponse = function (data, numberOfRequests) {
|
|||
return received;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief whether or not clustering is enabled
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isCluster = function () {
|
||||
var role = global.ArangoServerState.role();
|
||||
|
@ -1622,17 +1768,17 @@ var isCluster = function () {
|
|||
return (role !== undefined && role !== 'SINGLE' && role !== 'AGENT');
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief whether or not we are a coordinator
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isCoordinator = function () {
|
||||
return global.ArangoServerState.isCoordinator();
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief role
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var role = function () {
|
||||
var role = global.ArangoServerState.role();
|
||||
|
@ -1643,9 +1789,9 @@ var role = function () {
|
|||
return undefined;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief status
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var status = function () {
|
||||
if (!isCluster() || !global.ArangoServerState.initialized()) {
|
||||
|
@ -1655,9 +1801,9 @@ var status = function () {
|
|||
return global.ArangoServerState.status();
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief isCoordinatorRequest
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var isCoordinatorRequest = function (req) {
|
||||
if (!req || !req.hasOwnProperty('headers')) {
|
||||
|
@ -1667,11 +1813,13 @@ var isCoordinatorRequest = function (req) {
|
|||
return req.headers.hasOwnProperty('x-arango-coordinator');
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief handlePlanChange
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var handlePlanChange = function (plan, current) {
|
||||
// This is never called on a coordinator, we still make sure that it
|
||||
// is not executed on a single server or coordinator, just to be sure:
|
||||
if (!isCluster() || isCoordinator() || !global.ArangoServerState.initialized()) {
|
||||
return true;
|
||||
}
|
||||
|
@ -1681,43 +1829,8 @@ var handlePlanChange = function (plan, current) {
|
|||
current: current.Version
|
||||
};
|
||||
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief execute an action under a write-lock
|
||||
// ////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function writeLocked (lockInfo, cb, args) {
|
||||
var timeout = lockInfo.timeout;
|
||||
if (timeout === undefined) {
|
||||
timeout = 60;
|
||||
}
|
||||
|
||||
var ttl = lockInfo.ttl;
|
||||
if (ttl === undefined) {
|
||||
ttl = 120;
|
||||
}
|
||||
if (require('internal').coverage || require('internal').valgrind) {
|
||||
ttl *= 10;
|
||||
timeout *= 10;
|
||||
}
|
||||
|
||||
global.ArangoAgency.lockWrite(lockInfo.part, ttl, timeout);
|
||||
|
||||
try {
|
||||
cb.apply(null, args);
|
||||
global.ArangoAgency.increaseVersion(lockInfo.part + '/Version');
|
||||
|
||||
let version = global.ArangoAgency.get(lockInfo.part + '/Version');
|
||||
versions[lockInfo.part.toLowerCase()] = version.arango[lockInfo.part].Version;
|
||||
|
||||
global.ArangoAgency.unlockWrite(lockInfo.part, timeout);
|
||||
} catch (err) {
|
||||
global.ArangoAgency.unlockWrite(lockInfo.part, timeout);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
versions.success = handleChanges(plan, current, writeLocked);
|
||||
versions.success = handleChanges(plan, current);
|
||||
|
||||
console.debug('plan change handling successful');
|
||||
} catch (err) {
|
||||
|
@ -1729,9 +1842,9 @@ var handlePlanChange = function (plan, current) {
|
|||
return versions;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief coordinatorId
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var coordinatorId = function () {
|
||||
if (!isCoordinator()) {
|
||||
|
@ -1740,9 +1853,9 @@ var coordinatorId = function () {
|
|||
return global.ArangoServerState.id();
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief bootstrap db servers
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var bootstrapDbServers = function (isRelaunch) {
|
||||
global.ArangoClusterInfo.reloadDBServers();
|
||||
|
@ -1790,9 +1903,9 @@ var bootstrapDbServers = function (isRelaunch) {
|
|||
return result;
|
||||
};
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief shard distribution
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function format (x) {
|
||||
var r = {};
|
||||
|
@ -1830,9 +1943,9 @@ function shardDistribution () {
|
|||
};
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief move shard
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function moveShard (info) {
|
||||
var isLeader;
|
||||
|
@ -1874,9 +1987,9 @@ function moveShard (info) {
|
|||
return {error: false, id: id};
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief rebalance shards
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function rebalanceShards () {
|
||||
var dbServers = global.ArangoClusterInfo.getDBServers();
|
||||
|
@ -1982,9 +2095,9 @@ function rebalanceShards () {
|
|||
return true;
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief supervision state
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function supervisionState () {
|
||||
try {
|
||||
|
@ -2000,9 +2113,9 @@ function supervisionState () {
|
|||
}
|
||||
}
|
||||
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
// / @brief wait for synchronous replication to settle
|
||||
// //////////////////////////////////////////////////////////////////////////////
|
||||
// /////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function waitForSyncReplOneCollection (dbName, collName) {
|
||||
console.debug('waitForSyncRepl:', dbName, collName);
|
||||
|
|
Loading…
Reference in New Issue