[GODRIVER-2317] ListCollections failed Created: 18/Feb/22  Updated: 16/Mar/22  Resolved: 16/Mar/22

Status: Closed
Project: Go Driver
Component/s: None
Affects Version/s: 1.8.3
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: du liu Assignee: Benji Rewis (Inactive)
Resolution: Won't Fix Votes: 0
Labels: Bug
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Attachments: PNG File image-2022-02-18-13-03-18-737.png    
Issue Links:
Related
related to DRIVERS-1186 Allow db/collection/index enumeration... Closed

 Description   

Summary

MongoDB server version and topology: 4.4 / master+ a slave node replica set

driver version: master

 

How to Reproduce

  1.  Down the master node.Now only a slave node is on lived.
  2. use uri mongodb://[username]:[password]@master_ip,slave_ip/db_name
  3. Set the client option readPreference to primaryPreferred
  4. Then NewClient and ListCollections.

The code like:

package main
 
import (
   "context"
   "go.mongodb.org/mongo-driver/bson"
   "go.mongodb.org/mongo-driver/mongo"
   "go.mongodb.org/mongo-driver/mongo/options"
   "go.mongodb.org/mongo-driver/mongo/readpref"
   "log"
)
 
func main() {
   opts := options.Client().SetReadPreference(readpref.PrimaryPreferred())
   client, err := mongo.NewClient(options.Client().ApplyURI(""), opts)
   if err != nil {
      log.Fatal(err)
   }
   
   if err := client.Connect(context.Background()); err != nil {
      log.Fatal(err)
   }
   
   _, err = client.Database("dbName").ListCollections(context.Background(), bson.D{})
   if err != nil {
      log.Fatal(err)
   }
}

It will return error like:

server selection error: server selection timeout, current topology: {Type: ReplicaSetNoPrimary}

By reading source code of mongo-go-driver,I think the problem be here:

 



 Comments   
Comment by Benji Rewis (Inactive) [ 16/Mar/22 ]

Perfect, and happy to help out! Closing this ticket for now, but feel free to comment here again or open a new GODRIVER ticket if we can help with anything else.

Comment by du liu [ 16/Mar/22 ]

Yep,it looks like it can do what I want. I can get the replSetStatus first, and then connect to a secondary node in Single topology directly.

Thanks, you saved a man who was struggling with the company's old replecation set deployment.

Comment by Benji Rewis (Inactive) [ 16/Mar/22 ]

I would use something like replSetGetStatus with our RunCommand function. Like so:

db := client.Database("admin")
res := db.RunCommand(context.TODO(), bson.D{{"replSetGetStatus", 1}})
if res.Err() != nil {
	panic(res.Err())
}
 
var status bson.D
if err := res.Decode(&status); err != nil {
	panic(err)
}
fmt.Println(status)

Comment by du liu [ 16/Mar/22 ]

Emm,Are there any method to get repleca set information?  Now it seems that only the error message contains node information.

Comment by Benji Rewis (Inactive) [ 15/Mar/22 ]

Hello again, mrliuxiansen8023@gmail.com! Unfortunately the cross-drivers ticket has been closed as “won’t do”. We recognize that it might be helpful to respect read preference for enumerative, administrative helpers like listCollections, but it seems like the underlying issue here is the lack of availability of your replica set’s primary. Is there anything we can do to help with your availability issues? Are you seeing consistent, long-running shutdowns of your primary node?

Comment by du liu [ 11/Mar/22 ]

Thanks

Comment by Benji Rewis (Inactive) [ 11/Mar/22 ]

Apologies for the delay in response, mrliuxiansen8023@gmail.com! Those are some fair points, and I've re-opened a cross-drivers ticket to consider honoring the user's readPreference for enumerative, administrative commands such as listCollections. I've linked DRIVERS-1186 to this ticket.

Comment by du liu [ 03/Mar/22 ]

Yes,because mongodump was written by golang, so I call the `dump` method.

Recently, I wanted to implement a way to have the backup function work when the host is down.When use uri like this ` uri mongodb://[username]:[password]@master_ip,slave_ip/db_name`, It's not work ok.

Although it is possible to connect directly to the backup machine, I have to write very ugly logic to get the address of the backup machine.

To be honest, I am puzzled by this design. What is the advantage of connecting directly to the slave and leaving the choice of setting read mode to the client?

It will make the user wonder why it still times out even though I set PrimaryPreferred.

Hope you will discuss this draft again QAQ.

Best wishes,

Liu

Comment by Benji Rewis (Inactive) [ 02/Mar/22 ]

Sometimes we do need this feature when the primary node is down.

Are retryable reads useful in this case? It seems like the operation could retry and potentially succeed once the primary is back up. Or, in your case, is the primary expected to be down for an extended period of time?

this feature directly affects mongodump.

To clarify, are you using the mongodump tool, and an internal call to the Go driver's ListCollections is failing?

Comment by du liu [ 02/Mar/22 ]

`primaryPreferred` might be a better choise.

Comment by du liu [ 02/Mar/22 ]

You are right, but would it be better to leave this parameter to the client, or set it to primaryPreferred. Sometimes we do need to use this feature when the primary node is down. And this feature directly affects mongodump.

Comment by Benji Rewis (Inactive) [ 01/Mar/22 ]

Hello again, mrliuxiansen8023@gmail.com! Thanks for your bug report. As you discovered in the ListCollections code, we do force a read preference of primary for the command. While the listCollections command can be run on primary or secondary nodes (see the server manual here), our cross-drivers specifications say:

Drivers MUST run listCollections on the primary node when in a replica set topology, unless directly connected to a secondary node in Single topology.

We enforce the primary read preference as a call to listCollections on a secondary node may return inaccurate (not up-to-date) information. For example, if you created a collection (a write operation that will always be routed to the primary) and immediately ran listCollections on the secondary, that new collection may not be present in the returned list.

Comment by Kevin Albertson [ 22/Feb/22 ]

Hello mrliuxiansen8023@gmail.com, thank you for the report. We will look into this soon.

Generated at Thu Feb 08 08:38:18 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.