mongoError: Topology was destroyed

≡放荡痞女 提交于 2019-11-26 15:10:24
Jason Nichols

It seems to mean your node server's connection to your MongoDB instance was interrupted while it was trying to write to it.

Take a look at the Mongo source code that generates that error

Mongos.prototype.insert = function(ns, ops, options, callback) {
    if(typeof options == 'function') callback = options, options = {};
    if(this.s.state == DESTROYED) return callback(new MongoError(f('topology was destroyed')));
    // Topology is not connected, save the call in the provided store to be
    // Executed at some point when the handler deems it's reconnected
    if(!this.isConnected() && this.s.disconnectHandler != null) {
      callback = bindToCurrentDomain(callback);
      return this.s.disconnectHandler.add('insert', ns, ops, options, callback);
    }

    executeWriteOperation(this.s, 'insert', ns, ops, options, callback);
}

This does not appear to be related to the Sails issue cited in the comments, as no upgrades were installed to precipitate the crash or the "fix"

I know that Jason's answer was accepted, but I had the same problem with Mongoose and found that the service hosting my database recommended to apply the following settings in order to keep Mongodb's connection alive in production:

var options = {
  server: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } },
  replset: { socketOptions: { keepAlive: 1, connectTimeoutMS: 30000 } }
};
mongoose.connect(secrets.db, options);

I hope that this reply may help other people having "Topology was destroyed" errors.

This error is due to mongo driver dropping the connection for any reason (server was down for example).

By default mongoose will try to reconnect for 30 seconds then stop retrying and throw errors forever until restarted.

You can change this by editing these 2 fields in the connection options

mongoose.connect(uri, 
    { server: { 
        // sets how many times to try reconnecting
        reconnectTries: Number.MAX_VALUE,
        // sets the delay between every retry (milliseconds)
        reconnectInterval: 1000 
        } 
    }
);

connection options documentation

In my case, this error was caused by a db.close(); out of a 'await' section inside of 'async'

MongoClient.connect(url, {poolSize: 10, reconnectTries: Number.MAX_VALUE, reconnectInterval: 1000}, function(err, db) {
    // Validate the connection to Mongo
    assert.equal(null, err);    
    // Query the SQL table 
    querySQL()
    .then(function (result) {
        console.log('Print results SQL');
        console.log(result);
        if(result.length > 0){

            processArray(db, result)
            .then(function (result) {
                console.log('Res');
                console.log(result);
            })
            .catch(function (err) {
                console.log('Err');
                console.log(err);
            })
        } else {
            console.log('Nothing to show in MySQL');
        }
    })
    .catch(function (err) {
        console.log(err);
    });
    db.close(); // <--------------------------------THIS LINE
});
codeinaire

Just a minor addition to Gaafar's answer, it gave me a deprecation warning. Instead of on the server object, like this:

MongoClient.connect(MONGO_URL, {
    server: {
        reconnectTries: Number.MAX_VALUE,
        reconnectInterval: 1000
    }
});

It can go on the top level object. Basically, just take it out of the server object and put it in the options object like this:

MongoClient.connect(MONGO_URL, {
    reconnectTries: Number.MAX_VALUE,
    reconnectInterval: 1000
});

"Topology was destroyed" might be caused by mongoose disconnecting before mongo document indexes are created, per this comment

In order to make sure all models have their indexes built before disconnecting, you can:

await Promise.all(mongoose.modelNames().map(model => mongoose.model(model).ensureIndexes()));

await mongoose.disconnect();

I alse had the same error. Finally, I found that I have some error on my code. I use load balance for two nodejs server, but I just update the code of one server.

I change my mongod server from standalone to replication, but I forget to do the corresponding update for the connection string, so I met this error.

standalone connection string: mongodb://server-1:27017/mydb replication connection string: mongodb://server-1:27017,server-2:27017,server-3:27017/mydb?replicaSet=myReplSet

details here:[mongo doc for connection string]

I met this in kubernetes/minikube + nodejs + mongoose environment. The problem was that DNS service was up with a kind of latency. Checking DNS is ready solved my problem.

const dns = require('dns');

var dnsTimer = setInterval(() => {
	dns.lookup('mongo-0.mongo', (err, address, family) => {
		if (err) {
			console.log('DNS LOOKUP ERR', err.code ? err.code : err);
		} else {
			console.log('DNS LOOKUP: %j family: IPv%s', address, family);
			clearTimeout(dnsTimer);
			mongoose.connect(mongoURL, db_options);
		}
	});
}, 3000);


var db = mongoose.connection;
var db_options = {
	autoReconnect:true,

	poolSize: 20,
	socketTimeoutMS: 480000,
	keepAlive: 300000,

	keepAliveInitialDelay : 300000,
	connectTimeoutMS: 30000,
	reconnectTries: Number.MAX_VALUE,
	reconnectInterval: 1000,
	useNewUrlParser: true
};

(the numbers in db_options are arbitrary found on stackoverflow and similar like sites)

I got this error, while I was creating a new database on my MongoDb Compass Community. The issue was with my Mongod, it was not running. So as a fix, I had to run the Mongod command as preceding.

C:\Program Files\MongoDB\Server\3.6\bin>mongod

I was able to create a database after running that command.

Hope it helps.

In my case, this error was caused by an identical server instance already running background.

The weird thing is when I started my server without notice there's one running already, the console didn't show anything like 'something is using port xxx'. I could even upload something to the server. So, it took me quite long to locate this problem.

What's more, after closing all the applications I can imagine, I still could not find the process which is using this port in my Mac's activity monitor. I have to use lsof to trace. The culprit was not surprising - it's a node process. However, with the PID shown in the terminal, I found the port number in the monitor is different from the one used by my server.

All in all, kill all the node processes may solve this problem directly.

Sebastian comment on Adrien's answer needs more attention it helped me but it being a comment might be ignore sometime so here's a solution:

var options =  { useMongoClient: true, keepAlive: 1, connectTimeoutMS: 30000, reconnectTries: 30, reconnectInterval: 5000 }
mongoose.connect(config.mongoConnectionString, options, (err) => {
    if(err) {
        console.error("Error while connecting", err);
    }
});

I was struggling with this for some time - As you can see from other answers, the issue can be very different.

The easiest way to find out whats causing is this is to turn on loggingLevel: info in the options

I solved this issue by:

  1. ensuring mongo is running
  2. restarting my server

You need to go to the "Connect" menu and click on the "Connect to ..." submenu. This will open a new MongoDB Compass Community window, through which you can connect again.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!