MongoDB current operations and profiling

Current operations

db.currentOp()

Operations running for over 5 seconds…

db.currentOp().inprog.forEach(function(op) {
    if (op.secs_running > 5) printjson(op);
})

Write operations waiting for a lock

db.currentOp(
  {
    "waitingForLock" : true,
    $or: [
      { "op" : { "$in" : [ "insert", "update", "remove" ] } },
      { "query.findandmodify": { $exists: true } }
    ]
  }
)

Operations that have never yielded

db.currentOp(
   {
     "active" : true,
     "numYields" : 0,
     "waitingForLock" : false
   }
)

Index creation operations

db.currentOp(
    {
      $or: [
        { op: "query", "query.createIndexes": { $exists: true } },
        { op: "insert", ns: /\.system\.indexes\b/ }
      ]
    }
)

Profiling Levels

  • 0 – the profiler is off, does not collect any data.
  • 1 – collects profiling data for slow operations only.
  • 2 – collects profiling data for all database operations.

Checking profiling level

db.getProfilingStatus()

Turn on profiling for operations taking more than 1 second (1000 milliseconds)

db.setProfilingLevel(1,1000)

Turn profiling off

db.setProfilingLevel(0)

5 most recent operations logged in the system.profile table

db.system.profile.find().limit(5).sort( { ts : -1 } ).pretty()

Recent operations that took longer than 5 seconds

db.system.profile.find( { millis : { $gt : 5000 } } ).pretty()

Ten recent operations that took over 15 seconds. Print only important fields.

db.system.profile.find({
 millis: {
 $gt: 15000
 }
}, {
 ns: 1,
 query: 1,
 numYield: 1,
 millis: 1
}).limit(10).pretty();

More examples:

db.system.profile.find({
 millis: {
 $gt: 5000
 },
 ts: {
 $gt: new Date(ISODate().getTime() - 1000 * 60 * 10)
 }
}).limit(5).pretty();

db.system.profile.find({
 millis: {
 $gt: 5000
 },
 ts: {
 $gt: new Date(ISODate().getTime() - 1000 * 60 * 10)
 }
}, {
 op: 1,
 ns: 1,
 query: 1,
 numYield: 1,
 millis: 1,
 ts: 1
}).limit(5).pretty();

To change the size of the system.profile collection, you must:

  1. Disable profiling.
  2. Drop the system.profile collection.
  3. Create a new system.profile collection.
  4. Re-enable profiling.

To create a new system.profile collections that’s 4000000 bytes, use the following sequence of operations

db.setProfilingLevel(0)
db.system.profile.drop()
db.createCollection( "system.profile", { capped: true, size:4000000 } )
db.setProfilingLevel(1)

Running MongoDB 2 and 3 on the same computer

Manually install (untar) MongoDB 2 and 3 into two different folders, for example

.../mongodb2
.../mongodb3

Create log and data folders for each version

.../mongodb2/log
.../mongodb2/data 
.../mongodb3/log
.../mongodb3/data

Create a conf file for each version.

.../mongodb2/data/mongod.conf
.../mongodb3/data/mongod.conf

Contents of these files can be something like

logpath=.../mongodb2/log/mongod.log
port=27017
dbpath=.../mongodb2/data
pidfilepath=.../mongodb2/mongod.pid

logpath=.../mongodb3/log/mongod.log
port=37017
dbpath=.../mongodb3/data
pidfilepath=.../mongodb3/mongod.pid

As you can see here, MongoDB 2 will be running on port 27017 and MongoDB 3 will be running on port 37017

No start each server with the following commands

.../mongodb2/bin/mongod  --config .../mongodb2/mongod.conf
.../mongodb3/bin/mongod  --config .../mongodb3/mongod.conf

That’s it 🙂

Two different command line clients can be run as follows

.../mongodb2/bin/mongo --port 27017
.../mongodb3/bin/mongo --port 37017

Cassandra DBA – Tricks and tips

Change replication factor for an existing keyspace

ALTER KEYSPACE acme WITH REPLICATION =  { 'class' : 'SimpleStrategy', 'replication_factor' : 2 };

Drop a keyspace

DROP KEYSPACE acme;

Drop a column

ALTER TABLE person DROP mail;

Add a column

ALTER TABLE person ADD email text;

Counting keys (rows) in column. Here is a quick way to get an “estimated” count

nodetool cfstats acme.person

Command to check cluster / node status

nodetool status

Force restart of datastax agent

service datastax-agent force-reload

How to insert current date-time into a table using CQL?

This can be done using the now and dateof functions.

The now function takes no arguments and generates a new unique timeuuid (at the time where the statement using it is executed).

The dateof function takes a timeuuid argument and extracts the embedded timestamp.

INSERT INTO account (name, created) VALUES ('acme', dateof(now()));

Java and Cassandra setup on an AWS Linux server

Java 7 Setup

# First verify the version of Java being used is not Oracle JDK.
java -version

# Get the latest JDK 7 from Oracle http://www.oracle.com/technetwork/java/javase/downloads/
wget http://download.oracle.com/otn-pub/java/jdk/XXXXXX/jdk-7u71-linux-x64.rpm
# Install Java
sudo rpm -i jdk-7u71-linux-x64.rpm
# Check if the default java version is set to Oracle jdk
java -version

# If not then lets create one more alternative for Java for Oracle JDK
sudo /usr/sbin/alternatives --install /usr/bin/java java /usr/java/jdk1.7.0_71/bin/java 20000
# Set the Oracle JDK as the default java
sudo /usr/sbin/alternatives --config java

# Verify if change in SDK was done.
java -version

Cassandra Setup

Download Cassandra from http://cassandra.apache.org/download/

  • Unzip/Untar the file apache-cassandra-2.1.0-bin.tar.gz
    • Copy the Cassandra folder apache-cassandra-2.1.0 to /usr/share
  • Edit the file /usr/share/apache-cassandra-2.1.0/conf/cassandra.yaml if necessary
  • Make sure /var/lib/cassandra has sufficient space

Start cassandra using the command:

/usr/share/apache-cassandra-2.1.o/bin/cassandra