How to check if a database exists on MongoDB

Why do you need this?

Just suppose you want to backup a Mongo database using mongodump.

As backups for individual databases don’t support –oplog, you may want to make sure you get a consistent database and therefore you may decide to use fsyncLock() to flush any pending write operation, and to lock new writes until your task is finished (do this only over secondary nodes on replica sets)

But then you launch mongodump against the MongoDB node… and the task keeps waiting for something…

Guess what? Most probably the database you want to backup doesn’t exist.  But as mongodump will try to extract data, this will trigger the database autocreation.

Look to the following example:

> show dbs
> use testdb
switched to db testdb
> show dbs
> db.testcol.find()
> show dbs
testdb (empty)

As you used fsyncLock(), mongodump will keep waiting until it can create the new database. But that never will happen unless you run fsyncUnlock().

So the key is to check if the database exists before running mongodump.

Unfortunately mongoDB has a function to check if a collection exists (db.collection.exists), but not to check if a database exists.

Sure, you should only try to backup existing databases. But what will happen if something or somebody removes a database by mistake? Youur backup job will get stuck!

So this small piece of code will do the trick:

var found=new Boolean(false);var dbs = db.getMongo().getDBNames();
for(var i in dbs) {
if (dbs[i].toString == ‘<database_name>’) 
found = 1;
}
if (found.valueOf()) print(true); else print(false);
 
 
Download code
 
You only need to change <database_name> to the database name you want to check.

Of course you can use this as a function. Or you can use it inside a Bash Script used to a single database:

# Function to create a gzipped backup for a database
# Syntax: dbbackup node db_name directory
function dbbackup {
local js=”
var found = 0;
var dbs = db.getMongo().getDBNames();
for(var i in dbs) {
if (dbs[i].toString() == ‘”${2}”‘)
found = 1;
}
if (found.valueOf()) print(true); else print(false);
if [ $(mongo –host $1 –eval “$js” –quiet) == “true” ]; then
# Flush and lock node
mongo –host $1 –eval ‘db.fsyncLock()’ –quiet
# Dump, compress and remove dump folder
mongodump –host $1 –db $2 –out $3
tar -C $3 -czf $3/$2.tar.gz $2
rm -rf $3/$2
# Unlock node
mongo –host $1 –eval ‘db.fsyncUnlock()’ –quiet
echo “Database backed up correctly!”
else
echo “Database $2 doesn’t exist!”
fi
}
 
Download code

And yes, I know making block level snapshots will be better. But sometimes you simply can’t use them.

2 Comments

    • If you mean, at the first snippet, this:

      Then I that’s not a variable. You need to replace it with the database you want to check.

      Of course you can also define a variable at the Javascript code as regular Javascript variable.

      If you mean the second snippet, then just add the function to your bash script and use it as a regular function. The only argument is the database name you want to check.

Leave a Reply

Your email address will not be published.


*


This site uses Akismet to reduce spam. Learn how your comment data is processed.