๐Ÿƒ MongoDB Debugging & Troubleshooting Guide

โ† Back to Home Elasticsearch โ†’ PostgreSQL โ†’ Kubernetes โ†’

A comprehensive guide for diagnosing and troubleshooting MongoDB database issues.

๐Ÿ“‹ Table of Contents


๐Ÿ”Œ Connection & Status

Connect to MongoDB

# Connect to local instance
mongosh

# Connect to remote instance
mongosh "mongodb://<USERNAME>:<PASSWORD>@<HOST>:<PORT>/<DATABASE>"

# Connect with authentication database
mongosh --host <HOST> --port 27017 -u <USERNAME> -p <PASSWORD> --authenticationDatabase admin

Check MongoDB Version

db.version()

// Or more detailed
db.serverStatus().version

Check Server Status

// Comprehensive server status
db.serverStatus()

// Specific sections
db.serverStatus().connections
db.serverStatus().network
db.serverStatus().opcounters
db.serverStatus().mem

Check Current Operations

// All current operations
db.currentOp()

// Only active operations
db.currentOp({ "active": true })

// Long-running queries (> 5 seconds)
db.currentOp({ 
    "active": true, 
    "secs_running": { "$gt": 5 } 
})

๐Ÿ“Š Database & Collection Info

List All Databases

show dbs

// Or with detailed info
db.adminCommand({ listDatabases: 1 })

// Databases with sizes
db.adminCommand({ listDatabases: 1, nameOnly: false })

Database Statistics

// Current database
db.stats()

// Specific database
use <DATABASE_NAME>
db.stats()

// Human-readable sizes
db.stats(1024*1024) // In MB

List All Collections

show collections

// Or with details
db.getCollectionNames()

// Collection info with stats
db.getCollectionInfos()

Collection Statistics

// Basic stats
db.<COLLECTION_NAME>.stats()

// Detailed stats with index details
db.<COLLECTION_NAME>.stats({ indexDetails: true })

// Size information
db.<COLLECTION_NAME>.totalSize()
db.<COLLECTION_NAME>.storageSize()
db.<COLLECTION_NAME>.totalIndexSize()

Document Count

// Fast count (uses metadata)
db.<COLLECTION_NAME>.estimatedDocumentCount()

// Accurate count (slower)
db.<COLLECTION_NAME>.countDocuments()

// Count with filter
db.<COLLECTION_NAME>.countDocuments({ status: "active" })

โšก Performance Diagnostics

Check Database Profiler

// Enable profiler (level 2 = all operations)
db.setProfilingLevel(2)

// Level 1 = slow operations only (> 100ms)
db.setProfilingLevel(1, { slowms: 100 })

// Check current profiling level
db.getProfilingStatus()

// View profiler data
db.system.profile.find().limit(10).sort({ ts: -1 }).pretty()

// Find slow queries
db.system.profile.find({ 
    millis: { $gt: 1000 } 
}).sort({ ts: -1 }).pretty()

// Disable profiler
db.setProfilingLevel(0)

Monitor Database Operations

// Real-time stats
db.serverStatus().opcounters

// Monitor specific operations
db.currentOp({
    "$or": [
        { "op": "query" },
        { "op": "getmore" },
        { "op": "insert" },
        { "op": "update" },
        { "op": "remove" }
    ]
})

Memory Usage

// Memory statistics
db.serverStatus().mem

// WiredTiger cache statistics
db.serverStatus().wiredTiger.cache

// Connection statistics
db.serverStatus().connections

Check Lock Statistics

// Global lock information
db.serverStatus().globalLock

// Current locks
db.currentOp({ "waitingForLock": true })

// Lock statistics
db.serverStatus().locks

๐Ÿ”„ Replication & Replica Sets

Replica Set Status

// Full replica set status
rs.status()

// Replica set configuration
rs.conf()

// Check if node is primary
db.isMaster()

// Simpler primary check
rs.isMaster()

Replication Lag

// Check replication lag for all members
rs.printReplicationInfo()

// Detailed secondary status
rs.printSecondaryReplicationInfo()

// Check oplog window
db.getReplicationInfo()

Monitor Oplog

// Switch to local database
use local

// Oplog statistics
db.oplog.rs.stats()

// First and last oplog entries
db.oplog.rs.find().sort({ $natural: 1 }).limit(1).pretty()
db.oplog.rs.find().sort({ $natural: -1 }).limit(1).pretty()

// Oplog size
db.oplog.rs.stats().maxSize / (1024*1024*1024) // In GB

Replica Set Management

// Add member to replica set
rs.add("<HOSTNAME>:<PORT>")

// Remove member
rs.remove("<HOSTNAME>:<PORT>")

// Step down primary
rs.stepDown(60) // seconds

// Force reconfiguration
rs.reconfig(<NEW_CONFIG>, { force: true })

๐Ÿ” Query Analysis

Explain Query Plan

// Explain query execution
db.<COLLECTION_NAME>.find({ field: value }).explain("executionStats")

// Detailed explanation
db.<COLLECTION_NAME>.find({ field: value }).explain("allPlansExecution")

// Check if index is used
db.<COLLECTION_NAME>.find({ field: value }).explain("queryPlanner")

Find Slow Queries

// From profiler
db.system.profile.find({
    millis: { $gt: 100 }
}).sort({ millis: -1 }).limit(10).pretty()

// Queries with collection scans (COLLSCAN)
db.system.profile.find({
    "planSummary": { $eq: "COLLSCAN" }
}).sort({ millis: -1 }).pretty()

Query Performance

// Time query execution
var start = new Date()
db.<COLLECTION_NAME>.find({ field: value }).toArray()
var end = new Date()
print("Query took: " + (end - start) + "ms")

// Or use explain with execution stats
db.<COLLECTION_NAME>.find({ field: value })
    .explain("executionStats").executionStats.executionTimeMillis

๐Ÿ“‡ Indexing

List All Indexes

// For a collection
db.<COLLECTION_NAME>.getIndexes()

// All indexes in database
db.getCollectionNames().forEach(function(collection) {
    print("\n=== Indexes for: " + collection + " ===");
    printjson(db[collection].getIndexes());
});

Create Indexes

// Single field index
db.<COLLECTION_NAME>.createIndex({ field: 1 })

// Compound index
db.<COLLECTION_NAME>.createIndex({ field1: 1, field2: -1 })

// Text index
db.<COLLECTION_NAME>.createIndex({ field: "text" })

// Create index in background
db.<COLLECTION_NAME>.createIndex({ field: 1 }, { background: true })

// Unique index
db.<COLLECTION_NAME>.createIndex({ field: 1 }, { unique: true })

// TTL index (auto-delete after time)
db.<COLLECTION_NAME>.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })

Index Usage Statistics

// Index stats
db.<COLLECTION_NAME>.aggregate([
    { $indexStats: {} }
])

// Find unused indexes
db.<COLLECTION_NAME>.aggregate([
    { $indexStats: {} },
    { $match: { "accesses.ops": 0 } }
])

Drop Indexes

// Drop specific index
db.<COLLECTION_NAME>.dropIndex("index_name")

// Drop all indexes except _id
db.<COLLECTION_NAME>.dropIndexes()

// Drop specific index by specification
db.<COLLECTION_NAME>.dropIndex({ field: 1 })

๐Ÿ—‚๏ธ Sharding

Sharding Status

// Overall sharding status
sh.status()

// Check if sharding is enabled for database
use <DATABASE_NAME>
db.stats()

// List all shards
use config
db.shards.find().pretty()

Shard Distribution

// Check chunk distribution
use config
db.chunks.aggregate([
    { $group: { _id: "$shard", count: { $sum: 1 } } }
])

// Check collection sharding info
db.<COLLECTION_NAME>.getShardDistribution()

Enable Sharding

// Enable sharding for database
sh.enableSharding("<DATABASE_NAME>")

// Shard a collection
sh.shardCollection("<DATABASE_NAME>.<COLLECTION_NAME>", { shardKey: 1 })

Balancer Status

// Check balancer status
sh.getBalancerState()

// Start/stop balancer
sh.startBalancer()
sh.stopBalancer()

// Check if balancer is running
sh.isBalancerRunning()

๐Ÿ› ๏ธ Operations & Maintenance

Kill Operation

// Find operation ID
db.currentOp()

// Kill specific operation
db.killOp(<OPERATION_ID>)

Compact Collection

// Reclaim disk space
db.runCommand({ compact: "<COLLECTION_NAME>" })

// Compact with force
db.runCommand({ compact: "<COLLECTION_NAME>", force: true })

Validate Collection

// Validate collection integrity
db.<COLLECTION_NAME>.validate()

// Full validation (slower but thorough)
db.<COLLECTION_NAME>.validate({ full: true })

Repair Database

# Stop MongoDB and run repair
mongod --repair --dbpath /path/to/data

# Or from inside MongoDB (requires space)
db.repairDatabase()

Backup & Restore

# Backup entire database
mongodump --host <HOST> --port <PORT> -u <USERNAME> -p <PASSWORD> --out /backup/path

# Backup specific database
mongodump --host <HOST> --port <PORT> -u <USERNAME> -p <PASSWORD> -d <DATABASE> --out /backup/path

# Backup specific collection
mongodump --host <HOST> --port <PORT> -u <USERNAME> -p <PASSWORD> -d <DATABASE> -c <COLLECTION> --out /backup/path

# Restore database
mongorestore --host <HOST> --port <PORT> -u <USERNAME> -p <PASSWORD> /backup/path

# Restore specific database
mongorestore --host <HOST> --port <PORT> -u <USERNAME> -p <PASSWORD> -d <DATABASE> /backup/path/<DATABASE>

User Management

// Create user
use admin
db.createUser({
    user: "<USERNAME>",
    pwd: "<PASSWORD>",
    roles: [ { role: "readWrite", db: "<DATABASE>" } ]
})

// List all users
use admin
db.system.users.find().pretty()

// Drop user
db.dropUser("<USERNAME>")

// Change user password
db.changeUserPassword("<USERNAME>", "<NEW_PASSWORD>")

๐Ÿ“ˆ Monitoring & Metrics

Connection Statistics

// Current connections
db.serverStatus().connections

// Connection pool stats
db.serverStatus().network

Operation Counters

// Operations per second
db.serverStatus().opcounters

// Network metrics
db.serverStatus().network

Storage Engine Statistics (WiredTiger)

// Cache statistics
db.serverStatus().wiredTiger.cache

// Transaction statistics
db.serverStatus().wiredTiger.transaction

// Cursor statistics
db.serverStatus().wiredTiger.cursor

Collection Scan Statistics

// Find collections with high scan ratios
db.getCollectionNames().forEach(function(collection) {
    var stats = db[collection].stats();
    if (stats.count > 0) {
        print(collection + ": " + stats.totalIndexSize + " index size, " + 
              stats.size + " collection size");
    }
});

๐Ÿšจ Common Issues & Solutions

Issue: High Memory Usage

// Check cache usage
db.serverStatus().wiredTiger.cache

// Solution: Adjust cache size in mongod.conf
// storage.wiredTiger.engineConfig.cacheSizeGB

Issue: Slow Queries

// Enable profiler
db.setProfilingLevel(1, { slowms: 100 })

// Check slow queries
db.system.profile.find({ millis: { $gt: 100 } }).sort({ ts: -1 })

// Solutions:
// 1. Add appropriate indexes
// 2. Optimize query patterns
// 3. Use projection to limit fields

Issue: Connection Limit Reached

// Check current connections
db.serverStatus().connections

// Kill idle connections
db.currentOp({ "active": false }).inprog.forEach(function(op) {
    if (op.secs_running > 300) { // 5 minutes
        db.killOp(op.opid);
    }
});

// Solution: Increase maxIncomingConnections in mongod.conf

Issue: Replica Lag

// Check lag
rs.printSecondaryReplicationInfo()

// Solutions:
// 1. Check network latency
// 2. Increase oplog size
// 3. Check secondary hardware resources
// 4. Reduce write load on primary

Issue: Lock Contention

// Check current locks
db.currentOp({ "waitingForLock": true })

// Solutions:
// 1. Optimize queries
// 2. Use appropriate indexes
// 3. Batch writes
// 4. Consider sharding

๐Ÿ”ง Configuration Check

View Current Configuration

// Get all parameters
db.adminCommand({ getParameter: '*' })

// Specific parameters
db.adminCommand({ getParameter: 1, maxConnections: 1 })

Check Data Directory

db.serverCmdLineOpts()

๐Ÿ“ Best Practices

  1. Always use indexes for frequently queried fields
  2. Monitor replica lag in production environments
  3. Enable profiling only when debugging (impacts performance)
  4. Regular backups using mongodump or file system snapshots
  5. Use projection to limit returned fields
  6. Batch operations when possible to reduce network overhead
  7. Monitor oplog size to ensure sufficient replication window
  8. Use connection pooling in applications
  9. Set appropriate TTL indexes for time-series data
  10. Regular compaction to reclaim disk space

๐Ÿ”— Useful Tools


๐Ÿ“š Additional Resources

Check Logs

# Typical log location
tail -f /var/log/mongodb/mongod.log

# Search for errors
grep -i error /var/log/mongodb/mongod.log

# Search for slow queries
grep -i "slow query" /var/log/mongodb/mongod.log

System Resource Usage

# Check MongoDB process
ps aux | grep mongod

# Monitor with top
top -p $(pgrep mongod)

# Check disk usage
df -h /path/to/mongodb/data

# Check I/O statistics
iostat -x 2

โš ๏ธ Security Notes


โ† Back to Home Elasticsearch โ†’ PostgreSQL โ†’ Kubernetes โ†’