Example #1
0
 void rollbackTransactionFromOplog(BSONObj entry, bool purgeEntry) {
     bool transactionAlreadyApplied = entry["a"].Bool();
     Client::Transaction transaction(DB_SERIALIZABLE);
     if (transactionAlreadyApplied) {
         if (entry.hasElement("ref")) {
             rollbackRefOp(entry);
         } else if (entry.hasElement("ops")) {
             rollbackOps(entry["ops"].Array());
         } else {
             verify(0);
         }
     }
     {
         LOCK_REASON(lockReason, "repl: purging entry from oplog");
         Lock::DBRead lk1("local", lockReason);
         if (purgeEntry) {
             purgeEntryFromOplog(entry);
         }
         else {
             // set the applied bool to false, to let the oplog know that
             // this entry has not been applied to collections
             BSONElementManipulator(entry["a"]).setBool(false);
             writeEntryToOplog(entry, false);
         }
     }
     transaction.commit(DB_TXN_NOSYNC);
 }
Example #2
0
 // takes an entry that was written _logTransactionOps
 // and applies them to collections
 //
 // TODO: possibly improve performance of this. We create and destroy a
 // context for each operation. Find a way to amortize it out if necessary
 //
 void applyTransactionFromOplog(BSONObj entry) {
     bool transactionAlreadyApplied = entry["a"].Bool();
     if (!transactionAlreadyApplied) {
         Client::Transaction transaction(DB_SERIALIZABLE);
         if (entry.hasElement("ref")) {
             applyRefOp(entry);
         } else if (entry.hasElement("ops")) {
             applyOps(entry["ops"].Array());
         } else {
             verify(0);
         }
         // set the applied bool to true, to let the oplog know that
         // this entry has been applied to collections
         BSONElementManipulator(entry["a"]).setBool(true);
         {
             LOCK_REASON(lockReason, "repl: setting oplog entry's applied bit");
             Lock::DBRead lk1("local", lockReason);
             writeEntryToOplog(entry, false);
         }
         // If this code fails, it is impossible to recover from
         // because we don't know if the transaction successfully committed
         // so we might as well crash
         // There is currently no known way this code can throw an exception
         try {
             // we are operating as a secondary. We don't have to fsync
             transaction.commit(DB_TXN_NOSYNC);
         }
         catch (std::exception &e) {
             log() << "exception during commit of applyTransactionFromOplog, aborting system: " << e.what() << endl;
             printStackTrace();
             logflush();
             ::abort();
         }
     }
 }
Example #3
0
 void logTransactionOpsRef(GTID gtid, uint64_t timestamp, uint64_t hash, OID& oid) {
     Lock::DBRead lk1("local");
     BSONObjBuilder b;
     addGTIDToBSON("_id", gtid, b);
     b.appendDate("ts", timestamp);
     b.append("h", (long long)hash);
     b.append("a", true);
     b.append("ref", oid);
     BSONObj bb = b.done();
     writeEntryToOplog(bb, true);
 }
Example #4
0
    static void _logTransactionOps(GTID gtid, uint64_t timestamp, uint64_t hash, BSONArray& opInfo) {
        Lock::DBRead lk1("local");

        BSONObjBuilder b;
        addGTIDToBSON("_id", gtid, b);
        b.appendDate("ts", timestamp);
        b.append("h", (long long)hash);
        b.append("a", true);
        b.append("ops", opInfo);

        BSONObj bb = b.done();
        // write it to oplog
        LOG(3) << "writing " << bb.toString(false, true) << " to master " << endl;
        writeEntryToOplog(bb, true);
    }
Example #5
0
 // assumes oplog is read locked on entry
 void replicateTransactionToOplog(BSONObj& op) {
     // set the applied bool to false, to let the oplog know that
     // this entry has not been applied to collections
     BSONElementManipulator(op["a"]).setBool(false);
     writeEntryToOplog(op, true);
 }