Files
poco/MongoDB/samples/ReplicaSet
Matej Kenda 51f3749fa0 MongoDB replica set support (#5068)
* feature(MongoDB): Initial implementation of support for replica sets.

* enh(MongoDB): Add parsing of mongodb replica set URI.

* enh(MongoDB): Treat single-server as primary, fix parsing of URI.

* fix(MongoDB): Add missing example for parsing the URI.

* enh(MongoDB): simplified and modernised code.

* fix(MongoDB): Fixes based on static analysis report.

* enh(MongoDB): Remove unused includes.

* fix(MongoDB): ReplicaSetMonitor: handle wrong arguments more gracefully.

* enh(MongoDB) Use string literals and char constants where possible.

* enh(MongoDB) More tests.

* fix(MongoDB): Prevent duplicate entries in MongoDB::Document.

* enh(MongoDB): Update RS tests, remove support for pre 5.1 MongoDB.

* enh(MongoDB): Use C++ std mutex primitives instead of Poco.

* fix(MongoDB): correct replica set compile errors.

* fix(MongoDB): fix replica set tests to work with IPv6 addresses.

* enh(MongoDB): Remove confusing hosts from ServerDescription and use hosts from "hello" only to discover replica set hosts.

* enh(MongoDB): fix unused variables in tests.

* enh(MongoDB): Add read-preference validation to replica set connection and pool.

* chore(MongoDB): Add reserve to Document.

* enh(MongoDB): connect to server in pool activateObject.

* chore(MongoDB): use tried servers set only locally inside executeWithRetry.

* enh(MongoDB): Add support for ReplicaSetConnection to OpMsgCursor.

* enh(MongoDB): Replica set: More robust retry of failed MongoDB commands.

* enh(MongoDB): ReplicaSet remove redundant function, update documentation.

* enh(MongoDB): Update handling of URL parameters.

* enh(MongoDB): Updates to use SSL socket factory.

* enh(MongoDB): Log topology change when detected.

* enh(MongoDB): Move function to wait for the server availability to ReplicaSet.

* enh(MongoDB): Replica set: send notification on topology change.

* enh(MongoDB): Replica set: Remove internal logger for

* enh(MongoDB): Replica set: Remove internal logger for topology change. Use notification instead.

* enh(MongoDB): Update samples and replica set readme.

* enh(MongoDB): Fix parsing replica set URI.

* enh(MongoDB): Introduce ReplicaSetURI for handling custom URI.

* fix(MongoDB): heartbeatFrequency --> heartbeatFrequencyMS to match standard URL

* enh(MongoDB): Introduce constants in ReplicaSetURI.

* chore(MongoDB): Minor enhancements.

* enh(MongoDB): Correct logic to determine replica set topology from discovered servers.

* enh(MongoDB): Remove redundant code when parsing hello response.

* enh(MongoDB): Prevent servers from different replica set to be used in the topology.

* enh(MongoDB): Mark topology with incompatible servers as Unknown.

* enh(CI): Speed-up build by using cmake --build --parallel 4

* enh(CI): Upgrade codeql from v3 to v4

https://github.blog/changelog/2025-10-28-upcoming-deprecation-of-codeql-action-v3/

* enh(modules): Update MongoDB module to reflect latest state.

enh(MongoDB): Remove dead code and mark Message as implementation detail.

enh(CI): Fix build of C++ modules

* fix(C++ modules): Use C++20 features in samples, not C++23.

* docs(MongoDB): Clarify RTT limitation in Nearest read preference
2025-12-16 07:49:36 +01:00
..
2025-12-16 07:49:36 +01:00
2025-12-16 07:49:36 +01:00

MongoDB Replica Set Examples

This directory contains comprehensive examples demonstrating Poco::MongoDB replica set support with automatic failover, read preferences, and connection pooling.

Minimum MongoDB Version: MongoDB 5.1 or later (for replica set features)

Examples Overview

Sample Description
ReplicaSetMonitor Production-ready monitoring tool for deployment verification and continuous health monitoring
ReplicaSet Feature demonstrations with multiple commands (basic, readpref, failover, pool, topology)
URIExample MongoDB URI parsing and connection demonstration

ReplicaSetMonitor - Deployment Health Check Tool

A continuous monitoring tool that performs regular read/write operations and displays replica set topology status. Ideal for deployment verification and health monitoring.

Features

  • Continuous Health Checks: Performs writes to primary and reads from replica set at configurable intervals
  • Real-time Topology Display: Shows current replica set status, server roles, and round-trip times
  • Statistics Tracking: Monitors success rates for read and write operations
  • Deployment Verification: Quickly verify replica set is functioning correctly
  • Automatic Failover Testing: Continues working even during primary elections

Usage

# Basic usage with defaults
./ReplicaSetMonitor

# Using MongoDB URI (recommended)
./ReplicaSetMonitor -u 'mongodb://mongo1:27017,mongo2:27017/?replicaSet=rs0'

# Specify replica set and hosts (traditional method)
./ReplicaSetMonitor -s rs0 -H mongo1:27017,mongo2:27017,mongo3:27017

# Run with 10-second intervals for 100 iterations
./ReplicaSetMonitor -i 10 -n 100

# Verbose mode for detailed operation output
./ReplicaSetMonitor -v

# Full example with URI
./ReplicaSetMonitor \
    --uri 'mongodb://mongo1:27017,mongo2:27017,mongo3:27017/?replicaSet=rs0&readPreference=primaryPreferred' \
    --interval 5 \
    --database test \
    --collection health_check \
    --verbose

# Full example with traditional options
./ReplicaSetMonitor \
    --set rs0 \
    --hosts mongo1:27017,mongo2:27017,mongo3:27017 \
    --interval 5 \
    --database test \
    --collection health_check \
    --verbose

Command-Line Options

Option Description Default
-h, --help Show help message -
-u, --uri URI MongoDB connection URI (takes precedence) -
-s, --set NAME Replica set name rs0
-H, --hosts HOSTS Comma-separated host:port list localhost:27017,localhost:27018,localhost:27019
-i, --interval SECONDS Check interval in seconds 5
-d, --database NAME Database name test
-c, --collection NAME Collection name poco_monitor
-v, --verbose Verbose output false
-n, --iterations N Number of iterations unlimited

Note: The --uri option takes precedence over --set and --hosts options.

Environment Variables

  • MONGODB_URI: MongoDB connection URI (takes precedence)
  • MONGODB_REPLICA_SET: Replica set name
  • MONGODB_HOSTS: Comma-separated host:port list

Example Output

Connecting to replica set: rs0
Seed servers: mongo1:27017, mongo2:27017, mongo3:27017
Check interval: 5 seconds

Replica set connected successfully!
Background monitoring active.

================================================================================
TOPOLOGY STATUS
================================================================================
Replica Set: rs0
Type:        Replica Set (with Primary)
Has Primary: Yes

Servers: 3
--------------------------------------------------------------------------------
Address                        Type        RTT (ms)  Status
--------------------------------------------------------------------------------
mongo1:27017                   PRIMARY     2.34      OK
mongo2:27017                   SECONDARY   3.12      OK
mongo3:27017                   SECONDARY   2.89      OK
================================================================================

[2025-11-26T21:15:00Z] Check #1
Write (Primary): ✓ OK (12 ms)
Read (PrimaryPreferred): ✓ OK (8 ms)
Statistics: Writes: 1/1 (100.0%), Reads: 1/1 (100.0%)
--------------------------------------------------------------------------------
[2025-11-26T21:15:05Z] Check #2
Write (Primary): ✓ OK (9 ms)
Read (PrimaryPreferred): ✓ OK (7 ms)
Statistics: Writes: 2/2 (100.0%), Reads: 2/2 (100.0%)
--------------------------------------------------------------------------------

Use Cases

1. Deployment Verification

Run the monitor immediately after deploying a replica set:

# Run for 60 iterations (5 minutes with 5-second intervals)
./ReplicaSetMonitor -s production-rs -H prod1:27017,prod2:27017,prod3:27017 -n 60

2. Load Testing

Combine with multiple instances to generate load:

# Run multiple monitors in parallel
for i in {1..10}; do
    ./ReplicaSetMonitor -i 1 &
done

3. Failover Testing

Run the monitor while performing failover operations:

# Start monitor
./ReplicaSetMonitor -v

# In another terminal, step down the primary:
# mongo --eval "rs.stepDown()"

# Monitor will automatically failover and continue operations

4. Continuous Monitoring

Run as a long-term health check:

# Run indefinitely with 30-second intervals
./ReplicaSetMonitor -i 30 > replica_set_health.log 2>&1

Docker Compose Testing

Create a local replica set for testing:

# docker-compose.yml
version: '3'
services:
  mongo1:
    image: mongo:7.0
    command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"]
    ports: ["27017:27017"]

  mongo2:
    image: mongo:7.0
    command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"]
    ports: ["27018:27017"]

  mongo3:
    image: mongo:7.0
    command: ["--replSet", "rs0", "--bind_ip_all", "--port", "27017"]
    ports: ["27019:27017"]

Initialize the replica set:

docker-compose up -d
docker exec -it $(docker ps -q -f name=mongo1) mongosh --eval "
rs.initiate({
  _id: 'rs0',
  members: [
    { _id: 0, host: 'localhost:27017' },
    { _id: 1, host: 'localhost:27018' },
    { _id: 2, host: 'localhost:27019' }
  ]
})"

# Wait a few seconds for election
sleep 5

# Run the monitor
./ReplicaSetMonitor -s rs0 -H localhost:27017,localhost:27018,localhost:27019

ReplicaSet - Feature Examples

Demonstrates various replica set features with multiple commands.

Usage

./ReplicaSet <command>

Commands

Command Description
basic Basic replica set connection and operations
readpref Read preference examples (primary, secondary, nearest)
failover Automatic failover demonstration
pool Connection pooling example
topology Topology discovery and monitoring

Examples

# Basic connection
./ReplicaSet basic

# Try different read preferences
./ReplicaSet readpref

# Demonstrate automatic failover
./ReplicaSet failover

# Show connection pooling
./ReplicaSet pool

# Display topology information
./ReplicaSet topology

URIExample - URI Parsing Demonstration

Demonstrates MongoDB URI parsing and connection to replica sets.

Features

  • Parse MongoDB connection URIs
  • Display parsed configuration (hosts, replica set name, read preference, timeouts)
  • Connect to replica set and show topology
  • Query server information
  • Validate URI format

Usage

./URIExample <uri>

Examples

# Basic replica set URI
./URIExample 'mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0'

# With read preference
./URIExample 'mongodb://mongo1:27017,mongo2:27017/?replicaSet=rs0&readPreference=primaryPreferred'

# With custom timeouts and heartbeat
./URIExample 'mongodb://host1:27017,host2:27017/?replicaSet=rs0&connectTimeoutMS=5000&socketTimeoutMS=30000&heartbeatFrequencyMS=5000'

Supported URI Options

  • replicaSet=name - Replica set name
  • readPreference=mode - Read preference (primary|primaryPreferred|secondary|secondaryPreferred|nearest)
  • connectTimeoutMS=ms - Connection timeout in milliseconds (for custom SocketFactory implementations)
  • socketTimeoutMS=ms - Socket timeout in milliseconds (for custom SocketFactory implementations)
  • heartbeatFrequencyMS=milliseconds - Heartbeat frequency in milliseconds (default: 10000)
  • reconnectRetries=n - Number of reconnection retries (default: 10)
  • reconnectDelay=seconds - Delay between reconnection attempts in seconds (default: 1)

Example Output

Parsing MongoDB Replica Set URI
================================================================================
URI: mongodb://localhost:27017,localhost:27018,localhost:27019/?replicaSet=rs0

✓ URI parsed successfully!

Configuration:
--------------------------------------------------------------------------------
Replica Set Name: rs0
Read Preference:  primary
Seed Servers:     localhost:27017, localhost:27018, localhost:27019
Monitoring:       Active

Connecting to replica set...
✓ Connected to primary: localhost:27017

Server Information:
--------------------------------------------------------------------------------
MongoDB Version: 7.0.5
Git Version:     7809d71e84e314b497f282ea52598668b08b84dd

Replica Set Topology:
--------------------------------------------------------------------------------
Set Name:    rs0
Has Primary: Yes
Servers:     3

  localhost:27017 [PRIMARY] RTT: 2.34 ms
  localhost:27018 [SECONDARY] RTT: 3.12 ms
  localhost:27019 [SECONDARY] RTT: 2.89 ms

✓ Success!

Building the Examples

With CMake

cd poco
mkdir build && cd build
cmake .. -DENABLE_MONGODB=ON -DENABLE_SAMPLES=ON
cmake --build . --target ReplicaSetMonitor
cmake --build . --target ReplicaSet
cmake --build . --target URIExample

# Executables are in bin/
./bin/ReplicaSetMonitor --help
./bin/ReplicaSet basic
./bin/URIExample 'mongodb://localhost:27017/?replicaSet=rs0'

With Make

cd MongoDB/samples/ReplicaSet
make
./ReplicaSetMonitor --help

Troubleshooting

"No suitable server found in replica set"

  • Verify MongoDB servers are running: nc -zv localhost 27017
  • Check replica set is initialized: mongosh --eval "rs.status()"
  • Verify network connectivity between hosts
  • Check replica set name matches: -s option should match rs.status()._id

"Connection failed" errors

  • Ensure MongoDB is binding to the correct interface (--bind_ip_all)
  • Check firewall rules allow connections to MongoDB ports
  • Verify authentication is disabled or credentials are provided

High latency or timeouts

  • Check network conditions between client and MongoDB servers
  • Increase timeout values in replica set configuration
  • Verify MongoDB servers are not overloaded

Advanced Configuration

Custom Read Preference with Tags

// Target servers in specific datacenter
Document tags;
tags.add("dc", "east");
tags.add("rack", "1");
ReadPreference pref(ReadPreference::Nearest, tags);

Custom Heartbeat Frequency

ReplicaSet::Config config;
config.heartbeatFrequencySeconds = 30;  // 30 seconds (default: 10)

Disable Background Monitoring

ReplicaSet::Config config;
config.enableMonitoring = false;  // Manual topology refresh only

Custom Reconnection Settings

ReplicaSet::Config config;
config.serverReconnectRetries = 5;         // Number of retries (default: 10)
config.serverReconnectDelaySeconds = 2;    // Delay between retries in seconds (default: 1)

Additional Resources