[CXX-1284] aggregate on secondary fails plus max_staleness assertion heisenbug Created: 23/Mar/17  Updated: 11/Sep/19  Resolved: 03/Apr/17

Status: Closed
Project: C++ Driver
Component/s: Implementation
Affects Version/s: 3.1.1
Fix Version/s: None

Type: Task Priority: Minor - P4
Reporter: Denis Bip Assignee: Unassigned
Resolution: Cannot Reproduce Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified
Environment:

Linux/debian 8.6


Issue Links:
Related
related to CDRIVER-2098 mongoc_collection_aggregate fails aga... Closed
related to CXX-1285 aggregate sets read preference option... Closed

 Description   

Hi! I'm trying to read from a secondary of replicaSet and get "Not master and slaveOk=false". Can you help me?



 Comments   
Comment by David Golden [ 03/Apr/17 ]

I'm going to close this ticket, as I can't reproduce the max_time_ms bug in over 400,000 iterations. It's possible the bug fixes for read preferences to secondaries fixed some uninitialized memory bug that was causing the assertion failure.

Thanks for the initial report and your patience and the aggregation to secondaries fixes will be in our 3.2.0-rc0 targeted around the end of April.

Comment by Denis Bip [ 24/Mar/17 ]

Hi, if still actual - I've checked all servers version, its 3.4.2, maxWireVersion is 5. Thank you for help, I'll wait for a new version of drivers

Comment by David Golden [ 23/Mar/17 ]

The "aggregate from secondary" problem is a bug in libmongoc and has been filed as CDRIVER-2098.

It works in mongocxx with an explicit read preference option due to a side effect of a bug, which has been filed as CXX-1285.

The max_staleness assertion is currently a stumper, so I'm going to leave this question open but retitle it.

Comment by David Golden [ 23/Mar/17 ]

Hi, again. I can see where (with assertions off), the same bug that triggered my assertion could also put you in the code path that could report "Not all servers support maxStalenessSeconds", but only if one member of your topology is not running MongoDB 3.4. Could you please confirm the versions of everything in your production deployment? (e.g. get your replica set status output and for each node, run 'ismaster' – the maxWireVersion field should be '5' for all of them.)

Comment by David Golden [ 23/Mar/17 ]

Does the other one look anything like this?

src/mongoc/mongoc-server-description.c:752 mongoc_server_description_filter_stale(): precondition failed: max_staleness_seconds > 0

Comment by David Golden [ 23/Mar/17 ]

I can replicate the "Not master" error and am trying to determine if it's a bug in mongocxx or upstream in libmongoc.

If you want to video the other problem, please feel free, but I'm not sure there's much we can do unless we have a way to replicate it.

Comment by Denis Bip [ 23/Mar/17 ]

I can make video or screenshots if it may help to understand

Comment by Denis Bip [ 23/Mar/17 ]

libmongoc is 1.5.3. Yes all servers are the same version. It is just a replica set, not sharded. Something strange is going on tests...If I include some other undepended of mongo files (logs for example) code throw an error again, like in real project...so only primary read works

Comment by David Golden [ 23/Mar/17 ]

What version of libmongoc are you using?

For the main project, all your servers are the same version? Is it just a replica set or is it sharded?

Comment by Denis Bip [ 23/Mar/17 ]

I wrote special test, so, fisrt way does not work (error "Not master and slaveOk=false"), second way (option pass) start to work, but only in test project, main project continue throw an error "Not all servers support maxStalenessSeconds".
Here is a test code:

#include <iostream>
 
#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
 
#include <mongocxx/client.hpp>
#include <mongocxx/options/find.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/uri.hpp>
#include <mongocxx/pipeline.hpp>
#include <bsoncxx/stdx/optional.hpp>
#include <mongocxx/pool.hpp>
#include <mongocxx/stdx.hpp>
 
 
using bsoncxx::builder::stream::document;
using bsoncxx::builder::stream::open_document;
using bsoncxx::builder::stream::close_document;
using bsoncxx::builder::stream::open_array;
using bsoncxx::builder::stream::close_array;
using bsoncxx::builder::stream::finalize;
using bsoncxx::type;
 
enum class TYPE_TEST
{
    PRIMARY,
    URI_STRING_SECONDARY_PREFRRED,
    OPT_SECONDARY_PREFERRED
};
 
void h()
{
    std::cout << "To run test type: ./mcxx [p,u,o]" << std::endl;
    std::cout << "    p - primary" << std::endl;
    std::cout << "    u - uri string preferred secondary" << std::endl;
    std::cout << "    o - option passed to preferred secondary" << std::endl;
}
 
int main(int argc, char **argv)
{
    TYPE_TEST t = TYPE_TEST::PRIMARY;
 
    if (argc != 2)
    {
        h();
        return 0;
    }
 
    if (!strcmp(argv[1], "p")) {}
    else if (!strcmp(argv[1], "u")) t = TYPE_TEST::URI_STRING_SECONDARY_PREFRRED;
    else if (!strcmp(argv[1], "o")) t = TYPE_TEST::OPT_SECONDARY_PREFERRED;
    else
    {
        h();
        return 0;
    }
 
    std::cout << (int) t << std::endl;
 
    std::string uri = "mongodb://";
    if (t == TYPE_TEST::URI_STRING_SECONDARY_PREFRRED) uri += "&readPreference=secondaryPreferred";
 
    mongocxx::instance inst{};
 
    mongocxx::pool pool(mongocxx::uri{ uri });
    mongocxx::stdx::optional<mongocxx::pool::entry> en_ = pool.try_acquire();
    if (en_ == mongocxx::stdx::nullopt)
    {
        std::cout << "cant_find_an_a_free_connection" << std::endl;
        return 0;
    }
 
    mongocxx::client* conn = en_->get();
 
    try
    {
        auto db_ = (*conn)["test"];
 
        mongocxx::pipeline stages;
 
        mongocxx::options::aggregate opt;
        if (t == TYPE_TEST::OPT_SECONDARY_PREFERRED)
        {
            mongocxx::read_preference rp;
            rp.mode(mongocxx::read_preference::read_mode::k_secondary_preferred);
            opt.read_preference(rp);
        }
 
        auto cursor = db_["test"].aggregate(stages, opt);
 
        for (auto&& doc : cursor)
        {
            std::cout << bsoncxx::to_json(doc) << std::endl;
        }
    }
    catch(std::exception& ex)
    {
       std::cout << ex.what() << std::endl;
    }
 
    return 0;
}
 

Comment by David Golden [ 23/Mar/17 ]

Could you please provide a complete, minimal example, per SSCCE? Ideally it should be something I can download, compile and run to see the error. Please include the connection string you use, though replace any host names with "foo.example.com" or similar, and I'll fix that before I compile.

Comment by Denis Bip [ 23/Mar/17 ]

part code looks like (for second way):

mongocxx::options::aggregate opt;
mongocxx::read_preference rp;
rp.mode(mongocxx::read_preference::read_mode::k_secondary_preferred);
opt.read_preference(rp);
 
auto cursor = db_[collection].aggregate(stages, opt);
 
for (auto&& doc : cursor) //error here

Comment by Denis Bip [ 23/Mar/17 ]

Two ways I've tried to do:
1) Add "&readPreference=secondaryPreferred" to string connection, after I get error "Not master and slaveOk=false"
2) Add an option to method: set mode object of read_preference to k_secondary_preferred and pass to opt which pass to aggregate method (connection string does not contain "&readPreference=secondaryPreferred"), after I get error "Not all servers support maxStalenessSeconds" (all servers version = 3.4.2). Next queries get error "Not master and slaveOk=false".

Both errors fires in try/catch block when trying to fetch after call aggregate method

Comment by David Golden [ 23/Mar/17 ]

Sure, we can help. Could you please put together an SSCCE? I.e. assume I have a replica set running, how exactly do I see what you're seeing?

Generated at Wed Feb 07 22:02:03 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.