MongoDB master slave replication example

  • 2020-06-07 05:30:11
  • OfStack

Master-slave replication can be used for database backup, failover, and read-write separation.

Mongodb 3.2 was used in this experiment. Let's first look at the help of mongod under 1


[root@localhost mongodb]# mongod --help
..... omit 
Master/slave options (old; use replica sets instead):
 --master               master mode
 --slave                slave mode
 --source arg             when slave: specify master as 
                    <server:port>
 --only arg              when slave: specify a single database 
                    to replicate
 --slavedelay arg           specify delay (in seconds) to be used 
                    when applying master ops to slave
 --autoresync             automatically resync if slave data is 
                    stale
..... omit 

Master-slave replication is out of date and is currently being replaced by replicas. The difference between master-slave replication and replicas can be simply understood as that master-slave replication cannot fail over automatically. The cluster in replicas can select a new master node using the elected policy after the master node is down. Realize automatic failover.

The slave nodes can be one or more.

Now let's implement master-slave replication with two instances on one machine.

Create a database directory

[root@localhost data]# mkdir -p /application/mongodb/data/{master,slave}

2. Start the master instance

[root@localhost data]# mongod --dbpath=/application/mongodb/data/master/ --port 27017 --master

--master specifies that this instance is the primary server.

3. Start the slave instance

[root@localhost ~]# mongod --dbpath=/application/mongodb/data/slave/ --port 27018 --slave --source 127.0.0.1:27017

--slave specifies the instance as a slave server
source Who specifies the primary server?

After the slave server is started, the master server is continuously requested to synchronize the data


2016-01-16T10:30:10.208+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:11.210+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:12.211+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:14.196+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:15.197+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:16.199+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:17.202+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:18.204+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:19.207+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:30:20.209+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017

At this point, master-slave replication is configured, as simple as that.

For the slave server, there are 3 parameters that need to be explained 1 more time.

--only arg

Specify that only a specific database is replicated from the node (all databases are replicated by default)

--slavedelay arg

Specifies how long to delay the slave server to resynchronize, which is useful in the event of a human error on the master server. The slave server did not synchronize the error when the error was found. This can avoid mistakes.

--autoresync

If the slave node's data is broken from the master node (the data in some oplog is not synchronized, that is, overwritten), then this option automatically synchronizes the database from the node from scratch.

Let's verify that the data synchronization is valid under 1.
Insert data into the main library.


[root@localhost ~]# mongo 127.0.0.1:27017
MongoDB shell version: 3.2.1
connecting to: 127.0.0.1:27017/test
> db.user.insert({"name":"jack","age":40,"job":"moive star"})
WriteResult({ "nInserted" : 1 })
> db.user.insert({"name":"vicent","age":25,"job":"teacher"})
WriteResult({ "nInserted" : 1 })

Log in from the database and check that the data is synchronized


[root@localhost ~]# mongo 127.0.0.1:27018
MongoDB shell version: 3.2.1
connecting to: 127.0.0.1:27018/test
> > db.user.find()
{ "_id" : ObjectId("5699af720102a61caffb76e8"), "name" : "jack", "age" : 40, "job" : "moive star" }
{ "_id" : ObjectId("5699af920102a61caffb76e9"), "name" : "vicent", "age" : 25, "job" : "teacher" }

You can see that the data has been synchronized

By default, to enable queries in the slave library, you must tell the server that you accept data from the slave server (there may be synchronization delays, the data is not 1, you can accept such a mismatch).


> show collections
2016-01-16T10:52:04.363+0800 E QUERY  [thread1] Error: listCollections failed: { "ok" : 0, "errmsg" : "not master and slaveOk=false", "code" : 13435 } :
_getErrorWithCode@src/mongo/shell/utils.js:23:13
DB.prototype._getCollectionInfosCommand@src/mongo/shell/db.js:746:1
DB.prototype.getCollectionInfos@src/mongo/shell/db.js:758:15
DB.prototype.getCollectionNames@src/mongo/shell/db.js:769:12
shellHelper.show@src/mongo/shell/utils.js:695:9
shellHelper@src/mongo/shell/utils.js:594:15
@(shellhelp2):1:1

Perform rs slaveOK


> rs.slaveOk()
> show collections
user
>

There is an sources collection in the local database for the slave service that records information about the master service


> use local
switched to db local
> show collections
me
sources
startup_log
> db.sources.find().pretty()
{
  "_id" : ObjectId("5699aaafa33311c25ab793df"),
  "host" : "127.0.0.1:27017",
  "source" : "main",
  "syncedTo" : Timestamp(1452913003, 1)
}

We don't need to specify the source parameter when we start the slave library again.


[root@localhost ~]# mongod --dbpath=/application/mongodb/data/slave/ --port 27018 --slave
2016-01-16T10:57:45.965+0800 I CONTROL [initandlisten] MongoDB starting : pid=21820 port=27018 dbpath=/application/mongodb/data/slave/ slave=1 64-bit host=localhost.localdomain
2016-01-16T10:57:45.967+0800 I CONTROL [initandlisten] db version v3.2.1
2016-01-16T10:57:45.968+0800 I CONTROL [initandlisten] git version: a14d55980c2cdc565d4704a7e3ad37e4e535c1b2
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten] OpenSSL version: OpenSSL 1.0.1e-fips 11 Feb 2013
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten] allocator: tcmalloc
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten] modules: none
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten] build environment:
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten]   distmod: rhel62
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten]   distarch: x86_64
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten]   target_arch: x86_64
2016-01-16T10:57:45.969+0800 I CONTROL [initandlisten] options: { net: { port: 27018 }, slave: true, storage: { dbPath: "/application/mongodb/data/slave/" } }
2016-01-16T10:57:46.010+0800 I -    [initandlisten] Detected data files in /application/mongodb/data/slave/ created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2016-01-16T10:57:46.011+0800 I STORAGE [initandlisten] wiredtiger_open config: create,cache_size=1G,session_max=20000,eviction=(threads_max=4),config_base=false,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics_log=(wait=0),
2016-01-16T10:57:48.485+0800 I CONTROL [initandlisten] ** WARNING: You are running this process as the root user, which is not recommended.
2016-01-16T10:57:48.486+0800 I CONTROL [initandlisten] 
2016-01-16T10:57:48.488+0800 I CONTROL [initandlisten] 
2016-01-16T10:57:48.490+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/enabled is 'always'.
2016-01-16T10:57:48.490+0800 I CONTROL [initandlisten] **    We suggest setting it to 'never'
2016-01-16T10:57:48.490+0800 I CONTROL [initandlisten] 
2016-01-16T10:57:48.490+0800 I CONTROL [initandlisten] ** WARNING: /sys/kernel/mm/transparent_hugepage/defrag is 'always'.
2016-01-16T10:57:48.490+0800 I CONTROL [initandlisten] **    We suggest setting it to 'never'
2016-01-16T10:57:48.490+0800 I CONTROL [initandlisten] 
2016-01-16T10:57:48.493+0800 I FTDC   [initandlisten] Initializing full-time diagnostic data capture with directory '/application/mongodb/data/slave/diagnostic.data'
2016-01-16T10:57:48.494+0800 I NETWORK [initandlisten] waiting for connections on port 27018
2016-01-16T10:57:48.495+0800 I NETWORK [HostnameCanonicalizationWorker] Starting hostname canonicalization worker
2016-01-16T10:57:49.497+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:57:50.503+0800 I REPL   [replslave] sleep 1 sec before next pass
2016-01-16T10:57:51.504+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:57:52.505+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:57:54.295+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017
2016-01-16T10:57:55.296+0800 I REPL   [replslave] syncing from host:127.0.0.1:27017

The oplog logs are synchronized between master and slave libraries. oplog exists in the local database of the main library, oplog.$main collection.


> use local
switched to db local
> db.oplog.$main.find({"op":"i"}).sort({"ts":-1}).pretty()
{
  "ts" : Timestamp(1452916694, 1),
  "h" : NumberLong(0),
  "v" : 2,
  "op" : "i",
  "ns" : "test.user",
  "o" : {
    "_id" : ObjectId("5699bfd6647c735cb3a50e0c"),
    "name" : "zhangcong"
  }
}
{
  "ts" : Timestamp(1452913156, 1),
  "h" : NumberLong(0),
  "v" : 2,
  "op" : "i",
  "ns" : "test.user",
  "o" : {
    "_id" : ObjectId("5699b204358c4672cad1cc6e"),
    "name" : "zhangdd",
    "age" : 30,
    "job" : "teacher"
  }
}
{
  "ts" : Timestamp(1452912530, 1),
  "h" : NumberLong(0),
  "v" : 2,
  "op" : "i",
  "ns" : "test.user",
  "o" : {
    "_id" : ObjectId("5699af920102a61caffb76e9"),
    "name" : "vicent",
    "age" : 25,
    "job" : "teacher"
  }
}
{
  "ts" : Timestamp(1452912498, 2),
  "h" : NumberLong(0),
  "v" : 2,
  "op" : "i",
  "ns" : "test.user",
  "o" : {
    "_id" : ObjectId("5699af720102a61caffb76e8"),
    "name" : "jack",
    "age" : 40,
    "job" : "moive star"
  }
}

The set belongs to a fixed set. After a fixed time of 1, the old log will be overwritten. If the log has been overwritten, it has not come from the library and is synchronized. The data can no longer be synchronized from the library. Only use --autoresync to resynchronize the data.

Note: The value of the parameter specified by the command line parameter can be written to the config file and used at startup

mongod --config /path/to/file.conf

Later versions of mongod 2.4 use the YAML format to write configuration files. The official file does not give a method for how the configuration of master-slave replication is declared in the configuration file. I've tried several ways of writing it, but none of them are correct. Because mongodb replaces master-slave replication with replicas, it is possible that the configuration file no longer supports master-slave replication.

Thank you for reading, I hope to help you, thank you for your support to this site!


Related articles: