Source code implementation of replica set
1. Start the process
DB. cpp
Main
Mongodbmain
Initandlisten
_ Initandlisten
Listen
Createserver (options, new mymessagehandler ());
Startreplication
The startreplication function is analyzed here.
2. startreplication
Boost: thread t (boost: BIND (& startreplsets, replsetcmdline); start a thread
Startreplsets
Replset: Make (* replsetcmdline)-> go ();
Make
Init
Loadconfig ();
This function is mainly used to wait for the member (port) on which the replica set depends to start and wait for initialization.
Start a thread after initialization and regularly connect to other nodes for heartbeat detection,
_ Go
Loadlastoptimewritten: Obtain the last synchronization time of the oplog. RS table
{Ts: Timestamp 1373520206000 | 1, h: 0, V: 2, OP: "N", NS: "", O: {MSG: "initiating set "}}
Startthreads (); the following key Analysis
Newreplup (); bind a function as the _ logop function pointer. cud will use this function to lock the local database first.
The main part of the startthreads function is as follows:
Void replsetimpl: startthreads (){
Task: fork (MGR );
Mgr-> send (boost: BIND (& MANAGER: msgchecknewstate, thereplset-> MGR ));
If (myconfig (). arbiteronly ){
Return;
}
Boost: thread t (startsyncthread );
Replset: backgroundsync * Sync = replset: backgroundsync: Get ();
Boost: thread producer (boost: BIND (& replset: backgroundsync: producerthread, sync ));
Boost: thread Notifier (boost: BIND (& replset: backgroundsync: notifierthread, sync ));
Task: fork (ghost );
// Member heartbeats are started in replsetimpl: initfromconfig
}
There are three threads and one function, startsyncthread, producerthread, notifierthread, and msgchecknewstate. Next, let's take a look at the respective functions of these three threads and the functions of msgchecknewstate.
(1) msgchecknewstate node status switching, voting election, etc., which will not be analyzed in detail here
(2) producerthread thread analysis (this thread is started only from the node)
_ Producerthread
Produce
Getoplogreader obtains a synchronization Data Node
Tailingquerygte
{Store the synchronized oplog data to the buffer.
Bsonobj o = R. nextsafe (). getowned ();
_ Buffer. Push (O );
}
(3) startsyncthread Analysis
While (1)
_ Syncthread
Void replsetimpl: _ syncthread (){
// Check criteria for doing an Initial sync:
// 1. If the oplog is empty, do an Initial sync
// 2. If minvalid has _ initialsyncflag set, do an Initial sync
If (lastoptimewritten. isnull () | getinitialsyncflag ()){
Syncdoinitialsync ();
Return; // _ syncthread will be recalled, starts from top again in case sync failed.
}
/* We have some data. Continue tailing .*/
Replset: synctail tail (replset: backgroundsync: Get ());
Tail. oplogapplication ();
}
The function bold section describes the function's function. It is used to obtain the oplog from the master node.
Tail. oplogapplication ();
Multiapply this function writes logs read by the previous producerthread to its own database
Applyopstooplog updates the latest timestamp of Synchronization
(3) notifierthread (not easy to understand) means to notify the server. We have successfully synchronized data.
Summary: The principle of replica set implementation is that a thread continuously performs heartbeat detection and node status change voting.
A thread obtains oplog data from the service node (not necessarily the master node) and puts it in its own buffer.
A thread synchronizes data from its own buffer to its own database.
One thread notifies the service node that data synchronization is complete.
The wait and Y mechanisms are used for coordination between threads.