From 24ae3989aa0f5d7458526a4dc5b1037f12e4bd89 Mon Sep 17 00:00:00 2001 From: Salim Date: Wed, 10 Jan 2018 23:07:57 +0000 Subject: [PATCH 1/2] Replica Set Compatibility --- config.json | 11 +++++++---- docker-entrypoint.sh | 13 +++++++++++++ lib/metadata/mongoclient/backend.js | 10 ++++++++-- 3 files changed, 28 insertions(+), 6 deletions(-) diff --git a/config.json b/config.json index f1662e9572..68f4df0ada 100644 --- a/config.json +++ b/config.json @@ -74,8 +74,11 @@ "recordLogName": "s3-recordlog" }, "mongodb": { - "host": "localhost", - "port": 27018, - "database": "metadata" + "host": "localhost", + "port": 27018, + "writeConcern": "majority", + "replicaSet": "", + "readPreference": "primary", + "database": "metadata" } -} +} \ No newline at end of file diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh index 2f18d65d51..6fcdaca799 100755 --- a/docker-entrypoint.sh +++ b/docker-entrypoint.sh @@ -81,6 +81,19 @@ if [[ "$METADATA_HOST" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .metadataClient.host=\"$METADATA_HOST\"" fi +if [[ "$MONGODB_HOST" ]]; then + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .mongodb.host=\"$MONGODB_HOST\"" + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .mongodb.port=27017" +fi + +if [[ "$MONGODB_PORT" ]]; then + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .mongodb.port=$MONGODB_PORT" +fi + +if [[ "$MONGODB_RS" ]]; then + JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .mongodb.replicaSet=\"$MONGODB_RS\"" +fi + if [[ "$REDIS_HOST" ]]; then JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.host=\"$REDIS_HOST\"" JQ_FILTERS_CONFIG="$JQ_FILTERS_CONFIG | .localCache.port=6379" diff --git a/lib/metadata/mongoclient/backend.js b/lib/metadata/mongoclient/backend.js index 9264048455..bd07ec4447 100644 --- a/lib/metadata/mongoclient/backend.js +++ b/lib/metadata/mongoclient/backend.js @@ -39,6 +39,7 @@ const ASYNC_REPAIR_TIMEOUT = 15000; let uidCounter = 0; const VID_SEP = versioning.VersioningConstants.VersionId.Separator; +const format = require('util').format; function generateVersionId() { // generate a unique number for each member of the nodejs cluster @@ -66,8 +67,13 @@ function generatePHDVersion(versionId) { class MongoClientInterface { constructor() { - const mongoUrl = - `mongodb://${config.mongodb.host}:${config.mongodb.port}`; + const mongoUrl = format( + 'mongodb://%s:%s/w=%s&replicaSet=%s&readPreference=%s', + config.mongodb.host, + config.mongodb.port, + config.mongodb.writeConcern, + config.mongodb.replicaSet, + config.mongodb.readPreference); this.logger = logger; this.client = null; this.db = null; From d195267f5fcc178cbcfbaa6182f0ac8a42c898a6 Mon Sep 17 00:00:00 2001 From: Salim Date: Wed, 31 Jan 2018 16:06:34 -0800 Subject: [PATCH 2/2] Improved Mongo Loggging --- lib/metadata/mongoclient/backend.js | 73 +++++++++++++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/lib/metadata/mongoclient/backend.js b/lib/metadata/mongoclient/backend.js index bd07ec4447..40931c2a5b 100644 --- a/lib/metadata/mongoclient/backend.js +++ b/lib/metadata/mongoclient/backend.js @@ -41,6 +41,7 @@ let uidCounter = 0; const VID_SEP = versioning.VersioningConstants.VersionId.Separator; const format = require('util').format; + function generateVersionId() { // generate a unique number for each member of the nodejs cluster return genVID(`${process.pid}.${uidCounter++}`, @@ -66,6 +67,7 @@ function generatePHDVersion(versionId) { } class MongoClientInterface { + constructor() { const mongoUrl = format( 'mongodb://%s:%s/w=%s&replicaSet=%s&readPreference=%s', @@ -83,6 +85,8 @@ class MongoClientInterface { // initialize this backend MongoClient.connect(mongoUrl, (err, client) => { if (err) { + this.logger.error('error connecting to mongo server', + { error: err.message }); throw (errors.InternalError); } this.logger.debug('connected to mongodb'); @@ -146,6 +150,9 @@ class MongoClientInterface { _id: bucketName, }, {}, (err, doc) => { if (err) { + log.error( + 'getBucketAttributes: error getting bucket attributes', + { error: err.message }); return cb(errors.InternalError); } if (!doc) { @@ -162,6 +169,9 @@ class MongoClientInterface { getBucketAndObject(bucketName, objName, params, log, cb) { this.getBucketAttributes(bucketName, log, (err, bucket) => { if (err) { + log.error( + 'getBucketAttributes: error getting bucket attributes', + { error: err.message }); return cb(err); } this.getObject(bucketName, objName, params, log, (err, obj) => { @@ -172,6 +182,8 @@ class MongoClientInterface { BucketInfo.fromObj(bucket).serialize(), }); } + log.error('getObject: error getting object', + { error: err.message }); return cb(err); } return cb(null, { @@ -209,9 +221,13 @@ class MongoClientInterface { _id: bucketName, }, {}, (err, result) => { if (err) { + log.error('deleteBucketStep2: error deleting bucket', + { error: err.message }); return cb(errors.InternalError); } if (result.ok !== 1) { + log.error('deleteBucketStep2: failed deleting bucket', + { error: err.message }); return cb(errors.InternalError); } return cb(null); @@ -235,6 +251,8 @@ class MongoClientInterface { if (err.codeName === 'NamespaceNotFound') { return this.deleteBucketStep2(bucketName, log, cb); } + log.error('deleteBucket: error deleting bucket', + { error: err.message }); return cb(errors.InternalError); } return this.deleteBucketStep2(bucketName, log, cb); @@ -340,7 +358,15 @@ class MongoClientInterface { value: objVal, }, { upsert: true, - }, () => cb()); + }, err => { + if (err) { + log.error( + 'putObjectNoVer: error putting obect with no versioning', + { error: err.message }); + return cb(errors.InternalError); + } + return cb(); + }); } putObject(bucketName, objName, objVal, params, log, cb) { @@ -370,6 +396,8 @@ class MongoClientInterface { _id: objName, }, {}, (err, doc) => { if (err) { + log.error('findOne: error getting object', + { error: err.message }); return cb(errors.InternalError); } if (!doc) { @@ -378,7 +406,8 @@ class MongoClientInterface { if (doc.value.isPHD) { this.getLatestVersion(c, objName, log, (err, value) => { if (err) { - log.error('getting latest version', err); + log.error('getLatestVersion: getting latest version', + { error: err.message }); return cb(err); } return cb(null, value); @@ -407,6 +436,9 @@ class MongoClientInterface { toArray( (err, keys) => { if (err) { + log.error( + 'getLatestVersion: error getting latest version', + { error: err.message }); return cb(errors.InternalError); } if (keys.length === 0) { @@ -436,9 +468,13 @@ class MongoClientInterface { upsert: true, }, (err, result) => { if (err) { + log.error('repair: error trying to repair value', + { error: err.message }); return cb(errors.InternalError); } if (result.ok !== 1) { + log.error('repair: failed trying to repair value', + { error: err.message }); return cb(errors.InternalError); } return cb(null); @@ -452,12 +488,13 @@ class MongoClientInterface { asyncRepair(c, objName, mst, log) { this.getLatestVersion(c, objName, log, (err, value) => { if (err) { - log.error('async-repair: getting latest version', err); + log.error('async-repair: getting latest version', + { error: err.message }); return undefined; } this.repair(c, objName, value, mst, log, err => { if (err) { - log.error('async-repair failed', err); + log.error('async-repair failed', { error: err.message }); return undefined; } log.debug('async-repair success'); @@ -488,6 +525,9 @@ class MongoClientInterface { 'value.versionId': mst.versionId, }, {}, err => { if (err) { + log.error( + 'findOneAndDelete: error finding and deleting', + { error: err.message }); return cb(errors.InternalError); } // do not test result.ok === 1 because @@ -496,6 +536,8 @@ class MongoClientInterface { }); return undefined; } + log.error('getLatestVersion: error getting latest version', + { error: err.message }); return cb(err); } // We have other versions available so repair: @@ -548,9 +590,15 @@ class MongoClientInterface { _id: vObjName, }, {}, (err, result) => { if (err) { + log.error( + 'findOneAndDelete: error when version is not master', + { error: err.message }); return cb(errors.InternalError); } if (result.ok !== 1) { + log.error( + 'findOneAndDelete: failed when version is not master', + { error: err.message }); return cb(errors.InternalError); } return cb(null); @@ -568,6 +616,8 @@ class MongoClientInterface { _id: objName, }, {}, (err, mst) => { if (err) { + log.error('deleteObjectVer: error deleting versioned object', + { error: err.message }); return cb(errors.InternalError); } if (!mst) { @@ -591,9 +641,15 @@ class MongoClientInterface { _id: objName, }, {}, (err, result) => { if (err) { + log.error( + 'deleteObjectNoVer: error deleting object with no version', + { error: err.message }); return cb(errors.InternalError); } if (result.ok !== 1) { + log.error( + 'deleteObjectNoVer: failed deleting object with no version', + { error: err.message }); return cb(errors.InternalError); } return cb(null); @@ -632,7 +688,8 @@ class MongoClientInterface { error: err.message, errorStack: err.stack, }; - log.error('error listing objects', logObj); + log.error( + 'internalListObject: error listing objects', logObj); cb(errors.InternalError); } }) @@ -660,6 +717,8 @@ class MongoClientInterface { _id: __UUID, }, {}, (err, doc) => { if (err) { + log.error('readUUID: error reading UUID', + { error: err.message }); return cb(errors.InternalError); } if (!doc) { @@ -681,6 +740,8 @@ class MongoClientInterface { // FIXME: define a KeyAlreadyExists error in Arsenal return cb(errors.EntityAlreadyExists); } + log.error('writeUUIDIfNotExists: error writing UUID', + { error: err.message }); return cb(errors.InternalError); } // FIXME: shoud we check for result.ok === 1 ? @@ -697,6 +758,8 @@ class MongoClientInterface { this.writeUUIDIfNotExists(uuid, log, err => { if (err) { if (err === errors.InternalError) { + log.error('getUUID: error getting UUID', + { error: err.message }); return cb(err); } return this.readUUID(log, cb);