globalsign / mgo

The MongoDB driver for Go
Other
1.97k stars 232 forks source link

DropDatabase returns not master when seesion mode is Secondary #396

Closed catundercar closed 3 years ago

catundercar commented 3 years ago

We use the issue tracker to track bugs with mgo - if you have a usage question, it's best to try Stack Overflow :)

Replace this text with your description, and please answer the questions below before submitting your issue to help us out. Thanks!


What version of MongoDB are you using (mongod --version)?

<3.2.7>

What version of Go are you using (go version)?

<1.14>

What operating system and processor architecture are you using (go env)?

<linux amd64>

What did you do?

There is a weird thing when I use mongodb that is working on master-slave status. The mongodb repl config is

var config = {
    _id: 'xbrother',
    members:[
        {
            _id: 0,
            host: 'master:27017',
            priority:1
        },
        {
            _id: 1,
            host: 'slave:27017',
            priority: 0,
            votes: 0
        }
    ]
}

When I set the session to Secondary mode, then I use DropDatabase(), mongodb will return a error: not master.First, I think the mongodb is working wrong status, but the weird thing is I used session.LiveServers(), it returned all servers.And when I use Insert or Find ,it works ok.

The rs.status() returns this:

{
    "set" : "xbrother",
    "date" : ISODate("2020-10-19T10:02:47.805Z"),
    "myState" : 1,
    "term" : NumberLong(1),
    "heartbeatIntervalMillis" : NumberLong(2000),
    "members" : [
        {
            "_id" : 0,
            "name" : "master:27017",
            "health" : 1,
            "state" : 1,
            "stateStr" : "PRIMARY",
            "uptime" : 3437,
            "optime" : {
                "ts" : Timestamp(1603101004, 2),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-10-19T09:50:04Z"),
            "electionTime" : Timestamp(1603098673, 1),
            "electionDate" : ISODate("2020-10-19T09:11:13Z"),
            "configVersion" : 1,
            "self" : true
        },
        {
            "_id" : 1,
            "name" : "slave:27017",
            "health" : 1,
            "state" : 2,
            "stateStr" : "SECONDARY",
            "uptime" : 3105,
            "optime" : {
                "ts" : Timestamp(1603101004, 2),
                "t" : NumberLong(1)
            },
            "optimeDate" : ISODate("2020-10-19T09:50:04Z"),
            "lastHeartbeat" : ISODate("2020-10-19T10:02:47.654Z"),
            "lastHeartbeatRecv" : ISODate("2020-10-19T10:02:47.654Z"),
            "pingMs" : NumberLong(0),
            "syncingTo" : "master:27017",
            "configVersion" : 1
        }
    ],
    "ok" : 1
}

And there are some of my codes:

func (e *Engine) DialWithFailFast() (*mgo.Session, error) {
    info, err := mgo.ParseURL(e.getURL())
    if err != nil {
        return nil, err
    }

    info.Timeout = 10 * time.Second
    info.FailFast = true

    return mgo.DialWithInfo(info)
}

func (e *Engine) getURL() string {
    return fmt.Sprintf("mongodb://%s:%s/admin?connect=direct", e.conf.Host, e.conf.Port)
}

func (e *Engine) Init() error {
    s, err := e.DialWithFailFast()
    if err != nil {
        log.Fatalf("Dial error: %s", err.Error())
        return err
    }
    s.SetMode(mgo.Secondary, true)
    if err := s.Ping(); err != nil {
        return err
    }
    e.conn = s

    return nil
}

func (e *Engine) getDB() (*mgo.Session, *mgo.Database) {
    s := e.conn.Copy()
    return s, s.DB(e.conf.DbName)
}

func (e *Engine) DbInit() error {
    s, db := e.getDB()
    defer s.Close()
    fmt.Println("live servers: ", s.LiveServers())

    return db.DropDatabase()
}

func TestDbInit(t *testing.T) {
    config := &Config{
        Host:   "192.168.123.200,192.168.123.201",
        Port:   "27017",
        DbName: "study",
    }
    e := NewEngine(config)
    if err := e.Init(); err != nil {
        log.Fatalf("Init error: %s", err.Error())
        return
    }

    err := e.DbInit()
    if err != nil {
        t.Error(err)
    }
}

The following is the test execution result:

$ go test -run=TestDb
live servers:  [192.168.123.200:27017 192.168.123.201:27017]
--- FAIL: TestDbInit (0.00s)
    engine_test.go:22: not master

By the way, it drop ok when I use mongo shell. I hope you can give me some suggestions, thank you very much!

If possible, provide a recipe for reproducing the error. A runnable program is great and really helps!

Can you reproduce the issue on the latest development branch?

Yes