The blog of Jafar Aliyev


Home :: Programming :: Developer tips :: Database

Creation date:

MongoDB administration tips

Set authentication for MongoDB

By default MongoDB runs without authentication. To set authentication, first create at least one credential per database, while you’re running an instance without authentication.

> db.addUser("user1", "pwd1")

This command adds user1 with password pwd1 to the current database. To see created user run this command and list all users of current database.

> db.system.users.find()

You can also remove user1 from users collection.

> db.removeUser("user1")

Now stop/restart database with --auth option

Create Mongo service on Windows

The following command will create Windows service for MongoDB and enable web console, because of --rest option.

sc create MongoService binPath= "c:\mongodb-2.2.2\bin\mongod.exe --service --rest --dbpath \"c:\mongodb-2.2.2\db\" --logpath \"d:\mongodb-2.2.2\log\"" DisplayName= "Mongo DB Standalone"

Your web admin console URL will be http://hostname:28017/

To enable authentication set --auth option too.

sc create MongoAuth binPath= "c:\mongodb-2.2.2\bin\mongod.exe --service --auth --rest --dbpath \"c:\mongodb-2.2.2\db\" --logpath \"c:\mongodb-2.2.2\log\"" DisplayName= "Mongo DB with Authentication"

Create Replica sets in Windows 2008 server

I’ll create here replica set with 4 MongoDB servers in one server. Therefore I’ll use different ports of the same server. Say you have a standalone Mongo server on port 27017. Stop it and start with --replSet option

mongod --dbpath "c:\mongodb-2.2.2\db" --logpath "c:\mongodb-2.2.2\log" --port 27017 --replSet rs0

rs0 is your replica set name. Create three more MongoDB servers and add to this set. First create three folders. I name then with the names of used ports.

> md db-27018
> md db-27019
> md db-27020

Now open three consoles and start  three more servers

> mongod --dbpath "c:\mongodb-2.2.2\db-27018" --port 27018 --replSet rs0
> mongod --dbpath "c:\mongodb-2.2.2\db-27019" --port 27019 --replSet rs0
> mongod --dbpath "c:\mongodb-2.2.2\db-27020" --port 27020 --replSet rs0

Note, that I did not specify --logpath for these servers, if you want enable logging in all servers create the different log catalogs. In production you will start all MongoDB servers in different servers and will have separate log paths for all nodes. But this is a demo server.
Then run mongo.exe and connect to first server on port 27017, and initiate your replica set.
Note, that during initiation it'll create oplog journal space and fill it with zeroes. In x64 platform it will occupy 5% of your free space and must be at least 1GB. But in x86 it is just 50MB. If you have a big free space on your hard drive it'll take quite a long time. Therefore I recommend to set the size of oplog journal file explicitly. You can do it with --oplogSize parameter, for example --oplogSize 1024 will occupy 1GB space.

> mongo --host localhost --port 27017
> rs.initiate()

This server will be the PRIMARY node. Now add secondary nodes and an arbiter.

> rs.add("myhost:27018")
> rs.add("myhost:27019")
> rs.add("myhost:27020", {arbiterOnly: true})

First two nodes are added as SECONDARY nodes, the third one is only arbiter. Arbiter is used during election in case of failure of primary server.
To use authentication in replica sets, first create a plain file to keep passphrase. This passphrase is used for mutual authentication between nodes. Say we create file named secret, with any word inside, for example write p@ss inside of secret file. Then place this file anywhere and set during mongo startup as parameter of --keyFile.

> mongod --dbpath "c:\mongodb-2.2.2\db-27018" --port 27018 --replSet rs0 –-keyFile c:\mongodb-2.2.2\secret
> mongod --dbpath "c:\mongodb-2.2.2\db-27019" --port 27019 --replSet rs0 –-keyFile c:\mongodb-2.2.2\secret
> mongod --dbpath "c:\mongodb-2.2.2\db-27020" --port 27020 --replSet rs0 –-keyFile c:\mongodb-2.2.2\secret

Now you don’t need --auth parameter. MongoDB will already start with authentication. Note, that the passphrase inside of file is not used for user authentication. The authentication is done as before, in case of standalone server.

Restore from crash in Replication mode

If we stop the auditor database all nodes stand SECONDARY.  After starting auditor the former PRIMARY server stands PRIMARY again.
If we stop any other SECONDARY node, it is restored after start, if oplog is not rewrited yet, because oplog is a capped collection, and if any node will stay offline for a long time it could not be restored automatically.
If we stop the PRIMARY server one of SECONDARY servers will stand PRIMARY and after starting the former PRIMARY it’ll no longer stay PRIMARY. Administrator must manually make it primary again, if needed.
If we stop the PRIMARY server during update, the updates, which were not replicated to other nodes, will stay only in this server. After starting this former PRIMARY server, it’ll try to restore itself from new PRIMARY server, it’ll do two things:

  • Roll back the state of server to the point, where all nodes have the same data. All not replicated information of this server will be rolled back and placed in rollback catalog in format <database>.<collection>.<timestamp>.bson
    For example: pcat.products.2011-05-09T18-10-04.0.bson
  • Apply all changes made since the time of last crash from the new PRIMARY server

But the former PRIMARY still will stay in SECONDARY state.

First method: Let’s start to apply these updates into new PRIMARY node with mongorestore utility.

> mongorestore.exe --host myhost --port 27019 C:\mongodb-2.2.2\db\rollback\pcat.products.2013-02-05T11-28-56.0.bson

It’ll create the new database named by rollback and place all data into collection : pcat.products.2011-05-09T18-10-04.0 inside of database. It’s not what we wanted. Therefore we’ll show the database and collection names:

> mongorestore.exe --host myhost --port 27019 -d pcat -c products C:\mongodb-2.2.2\db\rollback\pcat.products.2013-02-05T11-28-56.0.bson

Second method: We convert this bson file into json using bsondump, and use import utility to import it into the new PRIMARY server node

C:\mongodb-2.2.2\bin>bsondump C:\mongodb-2.2.2\db\rollback\pcat.products.2013-02 -05T11-28-56.0.bson > c:\mongodb-2.2.2\rollback.json

It’ll create json file with converted rollback data inside of rollback.json. This is the sample of our rollback file. Our collection here has only one fields named by key:

{ "_id" : ObjectId( "5110eb89ca0c3055ad849f30" ), "key" : 14403 }
{ "_id" : ObjectId( "5110eb89ca0c3055ad849f31" ), "key" : 14404 }
> mongoimport --host jaf-test --port 27019 -d pcat -c products --journal C:\mongodb-2.2.2\rollback.json

Now we have both data in products collection:

rs0:PRIMARY> db.products.find({"key":14404})
{ "_id" : ObjectId("5110eb89ca0c3055ad849f31"), "key" : 14404 }
rs0:PRIMARY> db.products.find({"key":14403})
{ "_id" : ObjectId("5110eb89ca0c3055ad849f30"), "key" : 14403 }

Now we’ll try to switch back our node on port 27017 into PRIMARY. We’re still on our new PRIMARY server on port 27019. We want to make primary server the node on port 27017.

rs0:PRIMARY> cfg=rs.config()
 "_id" : "rs0",
  "version" : 8,
  "members" : [
    "_id" : 0,
    "host" : "jaf-test:27017"
    "_id" : 1,
    "host" : "jaf-test:27019"
    "_id" : 3,
    "host" : "jaf-test:27018"
    "_id" : 4,
    "host" : "jaf-test:27020",
    "arbiterOnly" : true

You see we don’t have “_id”:2. It does not matter we refer to array by index therefore use 0,1,2,3 to refer to server nodes.

rs0:PRIMARY> cfg.members[0].priority = 1
rs0:PRIMARY> cfg.members[1].priority = 0.5
rs0:PRIMARY> cfg.members[2].priority = 0.5
rs0:PRIMARY> cfg.members[3].priority = 0.5
rs0:PRIMARY> rs.reconfig(cfg)

After 10 seconds the node with priority 1 will become PRIMARY. You issued this command from 27019 (PRIMARY) console and your current console will reconnect into 27019 as SECONDARY.  You have to exit and connect into node on port 27017. This node is PRIMARY again.

© Copyright

All articles in this site are written by Jafar N.Aliyev. Reproducing of any article must be followed by the author name and link to the site of origin(this site). This site also keeps the same rules relative to the articles of other authors.