1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #define MONGO_LOG_DEFAULT_COMPONENT ::mongo::logger::LogComponent::kSharding
32 
33 #include "mongo/platform/basic.h"
34 
35 #include "mongo/db/s/move_timing_helper.h"
36 
37 #include "mongo/db/client.h"
38 #include "mongo/db/curop.h"
39 #include "mongo/s/grid.h"
40 #include "mongo/util/log.h"
41 
42 namespace mongo {
43 
MoveTimingHelper(OperationContext * opCtx,const std::string & where,const std::string & ns,const BSONObj & min,const BSONObj & max,int totalNumSteps,std::string * cmdErrmsg,const ShardId & toShard,const ShardId & fromShard)44 MoveTimingHelper::MoveTimingHelper(OperationContext* opCtx,
45                                    const std::string& where,
46                                    const std::string& ns,
47                                    const BSONObj& min,
48                                    const BSONObj& max,
49                                    int totalNumSteps,
50                                    std::string* cmdErrmsg,
51                                    const ShardId& toShard,
52                                    const ShardId& fromShard)
53     : _opCtx(opCtx),
54       _where(where),
55       _ns(ns),
56       _to(toShard),
57       _from(fromShard),
58       _totalNumSteps(totalNumSteps),
59       _cmdErrmsg(cmdErrmsg),
60       _nextStep(0) {
61     _b.append("min", min);
62     _b.append("max", max);
63 }
64 
~MoveTimingHelper()65 MoveTimingHelper::~MoveTimingHelper() {
66     // even if logChange doesn't throw, bson does
67     // sigh
68     try {
69         if (_to.isValid()) {
70             _b.append("to", _to.toString());
71         }
72 
73         if (_from.isValid()) {
74             _b.append("from", _from.toString());
75         }
76 
77         if (_nextStep != _totalNumSteps) {
78             _b.append("note", "aborted");
79         } else {
80             _b.append("note", "success");
81         }
82 
83         if (!_cmdErrmsg->empty()) {
84             _b.append("errmsg", *_cmdErrmsg);
85         }
86 
87         Grid::get(_opCtx)
88             ->catalogClient()
89             ->logChange(_opCtx,
90                         str::stream() << "moveChunk." << _where,
91                         _ns,
92                         _b.obj(),
93                         ShardingCatalogClient::kMajorityWriteConcern)
94             .transitional_ignore();
95     } catch (const std::exception& e) {
96         warning() << "couldn't record timing for moveChunk '" << _where
97                   << "': " << redact(e.what());
98     }
99 }
100 
done(int step)101 void MoveTimingHelper::done(int step) {
102     invariant(step == ++_nextStep);
103     invariant(step <= _totalNumSteps);
104 
105     const std::string s = str::stream() << "step " << step << " of " << _totalNumSteps;
106 
107     CurOp* op = CurOp::get(_opCtx);
108 
109     {
110         stdx::lock_guard<Client> lk(*_opCtx->getClient());
111         op->setMessage_inlock(s.c_str());
112     }
113 
114     _b.appendNumber(s, _t.millis());
115     _t.reset();
116 }
117 
118 }  // namespace mongo
119