MongoDB installation and upgradation in Ubuntu

Installation of MongoDB is not my goal, while installation mongodb on ubuntu we need to remember that, It should be easily upgraded to its latest version. In this article,
1. How do you easily install mongodb in your ubuntu and how do you upgrade it.
2. Later part of the article includes best practice to start and stop mongodb service.

Installing mongodb enterprise to ubuntu

Before anything, you need to create mongodb user and group to your ubuntu system.

>sudo -i
>adduser mongodb  // adding an user it will promted for password, do the steps, it will automatically create mongodb user and group too

>su mongodb  // Rest of the process should be control by 'mongodb' user and group only
 

Download/copy the link mongodb latest binary tarball from the this link and follow the steps below. Here I am first installing mongodb 4.0 version, after installation I will upgrade it to 4.4 version.

> sudo apt-get install libcurl4 libgssapi-krb5-2 libldap-2.4-2 libwrap0 libsasl2-2 snmp openssl liblzma5  // first you need to install this package

> wget https://downloads.mongodb.com/linux/mongodb-linux-x86_64-enterprise-ubuntu1804-4.0.20.tgz       
// Downloading the tarball

> tar -zxvf mongodb-linux-x86_64-enterprise-ubuntu1804-4.0.20.tgz  // Making it unter
> cp mongodb-linux-x86_64-enterprise-ubuntu1804-4.0.20/bin/* /usr/local/bin/     // now copy the whole directory content to /usr/local/bin directory

> which mongod  // it should return /usr/local/bin/mongod

if required, change ownership and permission, it should be owned by mongodb user and group with 744 permission 
sudo chown -R mongodb:mongodb /usr/local/bin/mongo*
chmod -R 744 /usr/local/bin/mongo* //this time do not use sudo

> ls -lh /usr/local/bin/mongo*   // Check this directory, it is full of mongodb packages like, mongod, mongos, mongoexport etc.

-rwxr--r-- 1 mongodb mongodb 51M Sep  9 14:27 /usr/local/bin/mongo
-rwxr--r-- 1 mongodb mongodb 32M Sep  9 14:27 /usr/local/bin/mongocryptd
-rwxr--r-- 1 mongodb mongodb 72M Sep  9 14:27 /usr/local/bin/mongod
-rwxr--r-- 1 mongodb mongodb 25M Sep  9 14:27 /usr/local/bin/mongodecrypt
-rwxr--r-- 1 mongodb mongodb 17M Sep  9 14:27 /usr/local/bin/mongodump
-rwxr--r-- 1 mongodb mongodb 17M Sep  9 14:27 /usr/local/bin/mongoexport
-rwxr--r-- 1 mongodb mongodb 17M Sep  9 14:27 /usr/local/bin/mongofiles
-rwxr--r-- 1 mongodb mongodb 17M Sep  9 14:27 /usr/local/bin/mongoimport
-rwxr--r-- 1 mongodb mongodb 26M Sep  9 14:27 /usr/local/bin/mongoldap
-rwxr--r-- 1 mongodb mongodb 18M Sep  9 14:27 /usr/local/bin/mongoreplay
-rwxr--r-- 1 mongodb mongodb 18M Sep  9 14:27 /usr/local/bin/mongorestore
-rwxr--r-- 1 mongodb mongodb 40M Sep  9 14:27 /usr/local/bin/mongos
-rwxr--r-- 1 mongodb mongodb 17M Sep  9 14:27 /usr/local/bin/mongostat
-rwxr--r-- 1 mongodb mongodb 16M Sep  9 14:27 /usr/local/bin/mongotop


> mongod --version  // it will return mongodb 4.0 enterprise module.

Your installation of mongodb on Ubuntu has done. Now the question is how to upgrade this mongodb to its latest release.

Upgrade mongodb binaries to latest

Before starting this process, first you need to stop your existing database gracefully by following commands.

use admin;
db.shutdownServer();

You probably know that our mongodb binaries are inside /usr/local/bin directory, so we need to down load new binaries from the tarball and replace files of this directory, and it will work. The same way after downloading tarball you just copy its /bin directory content to /usr/local/bin location, mongodb version will be upgraded.

Best practice to start and stop mongod process

Now, you have two choice to start and stop mongod process, but both the cases you need to define a mongod.conf file, which retain all the mongodb configuration. It can be located at /etc/mongod.conf , I am sharing a demo mongodb config file, for more info you can visit this link.

sudo nano /etc/mongod.conf // creating config file and paste below configuration into that file and save it.


storage:
  dbPath: "/data/db"
systemLog:
  path: "/data/log/mongod.log"
  destination: "file"
#replication:
  #replSetName: rs-one
net:
  bindIp : "127.0.0.1,localhost"
  port : 27017
#tls:
  #mode: "requireTLS"
  #certificateKeyFile: "/etc/tls/tls.pem"
  #CAFile: "/etc/tls/TLSCA.pem"
security:
  authorization: "enabled"
  #keyFile: "/data/keyfile"
processManagement:
  fork: true

In above file, I made commented out few lines of code by #, because those points may be required for replica set environment and tls authentication, which I do not need for this demo.
We need to create data directory where mongodb data file will store.

mkdir -p /data/db
mkdir -p /data/log/
chmod -R 744 /data

Now we can start / stop mongod process by this following method.

1. Direct start with mongod -f method

mongod -f /etc/mongod.conf    // Starting the mongodb process, it will show successfully forked the process

ps -ef | grep mongod   // If process started successfully, then you can able to see the process. do not kill the process.

You should not kill the mongod process, it may corrupt your entire database file. After staring process you can create an user inside mongodb leveraging localhost exception by following method.

> mongo --port 27017 //it will looks like

Mongodb Enterprise>

use admin

db.createUser(
{ 
     user:'username',
     pwd:'password',
     roles:[{role:"root",db:"admin"}]
}
)

// This is how you just created an user for mongodb.

Gracefully shutdown mongod process

In any case you have to shut down gracefully the mongodb process to avoid data corruption. The following method is recommended under any circumstances.

> mongo --port 27017
authenticate db with creds
use admin;
db.auth('username','password') //it should return 1

db.shutdownServer()  // this is the command which gracefully shut down the database process. 

Always run db.shutdownServer() before stopping mongod process.

2. Auto Start mongodb.service on system start

Create mongodb.service file in this directory /lib/systemd/system/mongodb.service

sudo nano /lib/systemd/system/mongodb.service

in this file paste this below configuration
-----------------------------------------------------------------------
[Install]
WantedBy=multi-user.target

[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target

[Service]
User=mongodb
Group=mongodb
Environment="OPTIONS=-f /etc/mongod.conf" "MONGOSHUT=--shutdown --config /etc/mongod.conf"
#EnvironmentFile=-/etc/sysconfig/mongod
ExecStart=/usr/local/bin/mongod $OPTIONS
ExecStop=/usr/local/bin/mongod $MONGOSHUT
ExecReload=/bin/kill -HUP $MAINPID
Restart=always
#ExecStartPre=/usr/bin/mkdir -p /var/run/mongodb
#ExecStartPre=/usr/bin/chown mongod:mongod /var/run/mongodb
#ExecStartPre=/usr/bin/chmod 0755 /var/run/mongodb
PermissionsStartOnly=true
#PIDFile=/var/run/mongodb/mongod.pid
Type=forking
# file size
LimitFSIZE=infinity
# cpu time
LimitCPU=infinity
# virtual memory size
LimitAS=infinity
# open files
LimitNOFILE=64000
# processes/threads
LimitNPROC=64000
# locked memory
LimitMEMLOCK=infinity
# total threads (user+kernel)
TasksMax=infinity
TasksAccounting=false
# Recommended limits for mongod as specified in
# https://docs.mongodb.com/manual/reference/ulimit/#recommended-ulimit-settings

Now you can start with below mention command, only positive point of this process, when you just boot up the VM it will automatically start the mongod process.

sudo systemctl enable mongodb.service // This will start mongodb service autometically when VM boot up.


sudo systemctl daemon-reload
sudo systemctl start mongodb // this will start the process manually
sudo systemctl status mongodb  // It will show the status


sudo systemctl stop mongodb  // DO NOT USE THIS TO STOP MONGOD, USE GRACEFUL SHUTDOWN PROCEDURE

But when you stop the process, then please follow mongodb gracefully shutdown procedure.

Update some ubuntu settings that can helps MongoDB to perform better

sudo -i
nano /etc/fstab
defaults,noatime,nodiratime,nofail

grep -q 'vm.zone_reclaim_mode' /etc/sysctl.conf || echo "vm.zone_reclaim_mode=0" | sudo tee --append /etc/sysctl.conf

sudo sysctl -w vm.zone_reclaim_mode=0

grep -q 'vm.swappiness' /etc/sysctl.conf || echo "vm.swappiness=1" | sudo tee --append /etc/sysctl.conf
sudo sysctl -w vm.swappiness=1

sudo grep -q 'kernel.pid_max' /etc/sysctl.conf || echo "kernel.pid_max=64000" | sudo tee --append /etc/sysctl.conf
sysctl -w kernel.pid_max=64000

sudo grep -q 'net.ipv4.tcp_keepalive_time' /etc/sysctl.conf || echo "net.ipv4.tcp_keepalive_time=120" | sudo tee --append /etc/sysctl.conf
sysctl -w net.ipv4.tcp_keepalive_time=120

sudo grep -q 'fs.file-max' /etc/sysctl.conf || echo "fs.file-max=1616055" | sudo tee --append /etc/sysctl.conf
sudo sysctl -w fs.file-max=98000

sudo grep -q 'kernel.threads-max' /etc/sysctl.conf || echo "kernel.threads-max=126557" | sudo tee --append /etc/sysctl.conf
sudo sysctl -w kernel.threads-max=64000

sudo grep -q 'vm.max_map_count' /etc/sysctl.conf || echo "vm.max_map_count=128000" | sudo tee --append /etc/sysctl.conf
sudo sysctl -w vm.max_map_count=128000

============================================================
nano disable-transparent-huge-pages.service
------------------------------------------------------------
[Unit]
Description=Disable Transparent Huge Pages (THP)
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongodb.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/enabled > /dev/null'
ExecStart=/bin/sh -c 'echo never | tee /sys/kernel/mm/transparent_hugepage/defrag > /dev/null'
ExecStart=/bin/sh -c 'echo 0 | tee /sys/kernel/mm/transparent_hugepage/khugepaged/defrag > /dev/null'
[Install]
WantedBy=basic.target

============================================================
nano set-readahead-for-disks.service
------------------------------------------------------------
[Unit]
Description=Set Readahead to 8
DefaultDependencies=no
After=sysinit.target local-fs.target
Before=mongodb.service
[Service]
Type=oneshot
ExecStart=/bin/sh -c 'blockdev --setra 8 /dev/sdc1 > /dev/null'
[Install]
WantedBy=basic.target




sudo mv disable-transparent-huge-pages.service /etc/systemd/system/disable-transparent-huge-pages.service
sudo mv set-readahead-for-disks.service /etc/systemd/system/set-readahead-for-disks.service
sudo systemctl daemon-reload
sudo systemctl start disable-transparent-huge-pages
sudo systemctl start set-readahead-for-disks.service
sudo systemctl enable disable-transparent-huge-pages
sudo systemctl enable set-readahead-for-disks.service


--------------------------Back to mongodb user-----------------------------------

sudo cp /lib/systemd/system/mongodb.service /etc/systemd/system/
sudo nano /etc/systemd/system/mongodb.service
ExecStart=/usr/bin/numactl --interleave=all /usr/bin/mongod --config /etc/mongod.conf
apt-get -y install numactl

sudo init 6
sudo systemctl daemon-reload
sudo systemctl stop mongodb.service
sudo systemctl start mongodb.service