Why do I get Error resulting in state DEAD in MongoDB?

痴心易碎 提交于 2020-02-06 15:07:39

问题


I’m working with multidocument mongodb transactions, and I’m getting an unexpected error.

In my c++ app, using mongocxx driver, the steps I’m performing are the following:

  1. create session
  2. start transaction
  3. create a bulk_write 1 for this session, where I have multiple updates (~1000) to colletion 1
  4. create another bulk_write 2 for this session, where I have multiple inserts (~1000) to collection 2
  5. execute bulk_write 1
  6. execute bulk write 2
  7. commit transaction

This is the code snippet for the algorithm:

#include <iostream>
#include <vector>

#include <bsoncxx/builder/stream/document.hpp>
#include <bsoncxx/json.hpp>
#include <bsoncxx/exception/exception.hpp>
#include <mongocxx/client.hpp>
#include <mongocxx/instance.hpp>
#include <mongocxx/exception/exception.hpp>
#include <mongocxx/exception/logic_error.hpp>
#include <mongocxx/exception/operation_exception.hpp>



int main(int argc, char** argv)
{
    /* Parameters */

    std::string db_uri = "<PROVIDE URI TO CONNECT WITH A MONGO DB WITH REPLICA SETS>";
    std::string db_name = "db_0";
    std::string collection0_name = "coll_0";
    std::string collection1_name = "coll_1";
    int N_UPDATES = 100000;
    int N_INSERTS = 100000;

    /* Init connection */

    static mongocxx::instance inst{};
    mongocxx::uri client_uri = mongocxx::uri(db_uri);
    mongocxx::options::client client_options;
    mongocxx::options::ssl ssl_options;
    ssl_options.allow_invalid_certificates(true);
    client_options.ssl_opts(ssl_options);
    mongocxx::client client = mongocxx::client(client_uri, client_options);

    /* Reinit collections */

    mongocxx::database db = client[db_name];        
    auto builder = bsoncxx::builder::stream::document{};
    bsoncxx::document::value doc_value = builder
    << "Hello" << "MongoDB"
    << bsoncxx::builder::stream::finalize;    
    db[collection0_name].insert_one(doc_value.view()); /* insert a dummy doc */    
    db[collection0_name].delete_many({}); /* delete all docs */
    db[collection1_name].insert_one(doc_value.view()); /* insert a dummy doc */    
    db[collection1_name].delete_many({}); /* delete all docs */

    /* Create session */

    mongocxx::client_session session = client.start_session();

    /* Start transaction */

    session.start_transaction();

    /* Create bulk operations */

    mongocxx::bulk_write op0 = db[collection0_name].create_bulk_write(session);
    mongocxx::bulk_write op1 = db[collection1_name].create_bulk_write(session);
    std::vector<mongocxx::bulk_write*> bulk_operations;
    bulk_operations.push_back(&op0);
    bulk_operations.push_back(&op1);

    /* Fill update bulk operations */

    for (int i = 0; i < N_UPDATES; i++){

        mongocxx::model::update_one upsert_one{
            bsoncxx::builder::basic::make_document(
                bsoncxx::builder::basic::kvp("field0", i),
                bsoncxx::builder::basic::kvp("field1", i)
            ),
            bsoncxx::builder::basic::make_document(
                bsoncxx::builder::basic::kvp("$set", bsoncxx::builder::basic::make_document(
                    bsoncxx::builder::basic::kvp("field0", i),
                    bsoncxx::builder::basic::kvp("field1", i),
                    bsoncxx::builder::basic::kvp("field2", i),
                    bsoncxx::builder::basic::kvp("field3", i))
                )
            )
        };

        upsert_one.upsert(true); // Set upsert to true: if no document matches {"a": 1}, insert {"a": 2}.
        op0.append(upsert_one);
    }

    /* Fill insert bulk operations */

    for (int i = 0; i < N_INSERTS; i++){

        mongocxx::model::insert_one insert_one{
            bsoncxx::builder::basic::make_document(
                bsoncxx::builder::basic::kvp("field0", i),
                bsoncxx::builder::basic::kvp("field1", i),
                bsoncxx::builder::basic::kvp("field2", i)
            )
        };

        op1.append(insert_one);
    }

    /* Execute transaction */

    for( auto bulk_op : bulk_operations){
        try {
            bulk_op->execute();
        }
        catch (std::exception& e){     
            std::cerr << "Bulk write exception: " << e.what() << std::endl;
            session.abort_transaction();
        }
    }

    session.commit_transaction();   

    return 0;
}

which you can compile using the following command in a linux system with mongocxx installed:

c++ --std=c++11 test.cpp -o test -I/usr/local/include/mongocxx/v_noabi -I/usr/local/include/bsoncxx/v_noabi -L/usr/local/lib -lmongocxx -lbsoncxx

While executing I get the following error:

Bulk write exception: Exec error resulting in state DEAD :: caused by :: operation was interrupted: generic server error
terminate called after throwing an instance of 'mongocxx::v_noabi::operation_exception'
  what():  No transaction started: generic server error
Aborted (core dumped)

Also, I got different errors changing the parameters N_INSERTS and N_UPDATES:

https://docs.google.com/spreadsheets/d/1xZZs5Vb8FCXpvjL2o2fEyujWrDzCTAWCvF49IerZqHw/edit?usp=sharing

Thanks!

来源:https://stackoverflow.com/questions/57384733/why-do-i-get-error-resulting-in-state-dead-in-mongodb

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!