9
"labix.org/v2/mgo/bson"
12
// Initiate sets up a replica set with the given replica set name with the
13
// single given member. It need be called only once for a given mongo replica
16
// Note that you must set DialWithInfo and set Direct = true when dialing into a
17
// specific non-initiated mongo server. The session will be set to Monotonic
20
// See http://docs.mongodb.org/manual/reference/method/rs.initiate/ for more
22
func Initiate(session *mgo.Session, address, name string) error {
23
session.SetMode(mgo.Monotonic, true)
27
Members: []Member{{Id: 1, Address: address}},
29
return session.Run(bson.D{{"replSetInitiate", cfg}}, nil)
32
// Member holds configuration information for a replica set member.
34
// See http://docs.mongodb.org/manual/reference/replica-configuration/
37
// Id is a unique id for a member in a set.
40
// Address holds the network address of the member,
41
// in the form hostname:port.
42
Address string `bson:"host"`
44
// Arbiter holds whether the member is an arbiter only.
45
// This value is optional; it defaults to false.
46
Arbiter *bool `bson:"arbiterOnly,omitempty"`
48
// BuildIndexes determines whether the mongod builds indexes on this member.
49
// This value is optional; it defaults to true.
50
BuildIndexes *bool `bson:"buildIndexes,omitempty"`
52
// Hidden determines whether the replica set hides this member from
53
// the output of IsMaster.
54
// This value is optional; it defaults to false.
55
Hidden *bool `bson:"hidden,omitempty"`
57
// Priority determines eligibility of a member to become primary.
58
// This value is optional; it defaults to 1.
59
Priority *float64 `bson:"priority,omitempty"`
61
// Tags store additional information about a replica member, often used for
62
// customizing read preferences and write concern.
63
Tags map[string]string `bson:"tags,omitempty"`
65
// SlaveDelay describes the number of seconds behind the master that this
66
// replica set member should lag rounded up to the nearest second.
67
// This value is optional; it defaults to 0.
68
SlaveDelay *time.Duration `bson:"slaveDelay,omitempty"`
70
// Votes controls the number of votes a server has in a replica set election.
71
// This value is optional; it defaults to 1.
72
Votes *int `bson:"votes,omitempty"`
75
// Add adds the given members to the session's replica set. Duplicates of
76
// existing replicas will be ignored.
78
// Members will have their Ids set automatically if they are not already > 0
79
func Add(session *mgo.Session, members ...Member) error {
80
config, err := CurrentConfig(session)
87
for _, member := range config.Members {
94
for _, newMember := range members {
95
for _, member := range config.Members {
96
if member.Address == newMember.Address {
97
// already exists, skip it
101
// let the caller specify an id if they want, treat zero as unspecified
102
if newMember.Id < 1 {
106
config.Members = append(config.Members, newMember)
108
return session.Run(bson.D{{"replSetReconfig", config}}, nil)
111
// Remove removes members with the given addresses from the replica set. It is
112
// not an error to remove addresses of non-existent replica set members.
113
func Remove(session *mgo.Session, addrs ...string) error {
114
config, err := CurrentConfig(session)
119
for _, rem := range addrs {
120
for n, repl := range config.Members {
121
if repl.Address == rem {
122
config.Members = append(config.Members[:n], config.Members[n+1:]...)
127
err = session.Run(bson.D{{"replSetReconfig", config}}, nil)
129
// EOF means we got disconnected due to the Remove... this is normal.
130
// Refreshing should fix us up.
137
// Set changes the current set of replica set members. Members will have their
138
// ids set automatically if their ids are not already > 0.
139
func Set(session *mgo.Session, members []Member) error {
140
config, err := CurrentConfig(session)
147
// Assign ids to members that did not previously exist, starting above the
148
// value of the highest id that already existed
149
ids := map[string]int{}
151
for _, m := range config.Members {
152
ids[m.Address] = m.Id
158
for x, m := range members {
159
if id, ok := ids[m.Address]; ok {
168
config.Members = members
170
err = session.Run(bson.D{{"replSetReconfig", config}}, nil)
172
// EOF means we got disconnected due to a Remove... this is normal.
173
// Refreshing should fix us up.
180
// Config reports information about the configuration of a given mongo node
181
type IsMasterResults struct {
182
// The following fields hold information about the specific mongodb node.
183
IsMaster bool `bson:"ismaster"`
184
Secondary bool `bson:"secondary"`
185
Arbiter bool `bson:"arbiterOnly"`
186
Address string `bson:"me"`
187
LocalTime time.Time `bson:"localTime"`
189
// The following fields hold information about the replica set.
190
ReplicaSetName string `bson:"setName"`
191
Addresses []string `bson:"hosts"`
192
Arbiters []string `bson:"arbiters"`
193
PrimaryAddress string `bson:"primary"`
196
// IsMaster returns information about the configuration of the node that
197
// the given session is connected to.
198
func IsMaster(session *mgo.Session) (*IsMasterResults, error) {
199
results := &IsMasterResults{}
200
err := session.Run("isMaster", results)
207
// CurrentMembers returns the current members of the replica set.
208
func CurrentMembers(session *mgo.Session) ([]Member, error) {
209
cfg, err := CurrentConfig(session)
213
return cfg.Members, nil
216
// CurrentConfig returns the Config for the given session's replica set.
217
func CurrentConfig(session *mgo.Session) (*Config, error) {
219
err := session.DB("local").C("system.replset").Find(nil).One(cfg)
221
return nil, fmt.Errorf("Error getting replset config : %s", err.Error())
226
// Config is the document stored in mongodb that defines the servers in the
229
Name string `bson:"_id"`
230
Version int `bson:"version"`
231
Members []Member `bson:"members"`
234
// CurrentStatus returns the status of the replica set for the given session.
235
func CurrentStatus(session *mgo.Session) (*Status, error) {
237
err := session.Run("replSetGetStatus", status)
239
return nil, fmt.Errorf("Error from replSetGetStatus: %v", err)
244
// Status holds data about the status of members of the replica set returned
245
// from replSetGetStatus
247
// See http://docs.mongodb.org/manual/reference/command/replSetGetStatus/#dbcmd.replSetGetStatus
249
Name string `bson:"set"`
250
Members []MemberStatus `bson:"members"`
253
// Status holds the status of a replica set member returned from
255
type MemberStatus struct {
256
// Id holds the replica set id of the member that the status is describing.
259
// Address holds address of the member that the status is describing.
260
Address string `bson:"name"`
262
// Self holds whether this is the status for the member that
263
// the session is connected to.
264
Self bool `bson:"self"`
266
// ErrMsg holds the most recent error or status message received
268
ErrMsg string `bson:"errmsg"`
270
// Healthy reports whether the member is up. It is true for the
271
// member that the request was made to.
272
Healthy bool `bson:"health"`
274
// State describes the current state of the member.
275
State MemberState `bson:"state"`
277
// Uptime describes how long the member has been online.
278
Uptime time.Duration `bson:"uptime"`
280
// Ping describes the length of time a round-trip packet takes to travel
281
// between the remote member and the local instance. It is zero for the
282
// member that the session is connected to.
283
Ping time.Duration `bson:"pingMS"`
286
// MemberState represents the state of a replica set member.
287
// See http://docs.mongodb.org/manual/reference/replica-states/
304
var memberStateStrings = []string{
305
StartupState: "STARTUP",
306
PrimaryState: "PRIMARY",
307
SecondaryState: "SECONDARY",
308
RecoveringState: "RECOVERING",
310
Startup2State: "STARTUP2",
311
UnknownState: "UNKNOWN",
312
ArbiterState: "ARBITER",
314
RollbackState: "ROLLBACK",
315
ShunnedState: "SHUNNED",
318
// String returns a string describing the state.
319
func (state MemberState) String() string {
320
if state < 0 || int(state) >= len(memberStateStrings) {
321
return "INVALID_MEMBER_STATE"
323
return memberStateStrings[state]