1 /* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License, version 2.0,
5 as published by the Free Software Foundation.
6
7 This program is also distributed with certain software (including
8 but not limited to OpenSSL) that is licensed under separate terms,
9 as designated in a particular file or component or in included license
10 documentation. The authors of MySQL hereby grant you an additional
11 permission to link the program and your derivative works with the
12 separately licensed software that they have included with MySQL.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License, version 2.0, for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22
23 #include "DbtuxProxy.hpp"
24 #include "Dbtux.hpp"
25 #include "../dblqh/DblqhCommon.hpp"
26
DbtuxProxy(Block_context & ctx)27 DbtuxProxy::DbtuxProxy(Block_context& ctx) :
28 LocalProxy(DBTUX, ctx)
29 {
30 // GSN_ALTER_INDX_IMPL_REQ
31 addRecSignal(GSN_ALTER_INDX_IMPL_REQ, &DbtuxProxy::execALTER_INDX_IMPL_REQ);
32 addRecSignal(GSN_ALTER_INDX_IMPL_CONF, &DbtuxProxy::execALTER_INDX_IMPL_CONF);
33 addRecSignal(GSN_ALTER_INDX_IMPL_REF, &DbtuxProxy::execALTER_INDX_IMPL_REF);
34
35 // GSN_INDEX_STAT_IMPL_REQ
36 addRecSignal(GSN_INDEX_STAT_IMPL_REQ, &DbtuxProxy::execINDEX_STAT_IMPL_REQ);
37 addRecSignal(GSN_INDEX_STAT_IMPL_CONF, &DbtuxProxy::execINDEX_STAT_IMPL_CONF);
38 addRecSignal(GSN_INDEX_STAT_IMPL_REF, &DbtuxProxy::execINDEX_STAT_IMPL_REF);
39
40 // GSN_INDEX_STAT_REP
41 addRecSignal(GSN_INDEX_STAT_REP, &DbtuxProxy::execINDEX_STAT_REP);
42 }
43
~DbtuxProxy()44 DbtuxProxy::~DbtuxProxy()
45 {
46 }
47
48 SimulatedBlock*
newWorker(Uint32 instanceNo)49 DbtuxProxy::newWorker(Uint32 instanceNo)
50 {
51 return new Dbtux(m_ctx, instanceNo);
52 }
53
54 // GSN_ALTER_INDX_IMPL_REQ
55
56 void
execALTER_INDX_IMPL_REQ(Signal * signal)57 DbtuxProxy::execALTER_INDX_IMPL_REQ(Signal* signal)
58 {
59 const AlterIndxImplReq* req = (const AlterIndxImplReq*)signal->getDataPtr();
60 Ss_ALTER_INDX_IMPL_REQ& ss = ssSeize<Ss_ALTER_INDX_IMPL_REQ>();
61 ss.m_req = *req;
62 ndbrequire(signal->getLength() == AlterIndxImplReq::SignalLength);
63 sendREQ(signal, ss);
64 }
65
66 void
sendALTER_INDX_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle * handle)67 DbtuxProxy::sendALTER_INDX_IMPL_REQ(Signal* signal, Uint32 ssId,
68 SectionHandle * handle)
69 {
70 Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
71
72 AlterIndxImplReq* req = (AlterIndxImplReq*)signal->getDataPtrSend();
73 *req = ss.m_req;
74 req->senderRef = reference();
75 req->senderData = ssId;
76 sendSignalNoRelease(workerRef(ss.m_worker), GSN_ALTER_INDX_IMPL_REQ,
77 signal, AlterIndxImplReq::SignalLength, JBB, handle);
78 }
79
80 void
execALTER_INDX_IMPL_CONF(Signal * signal)81 DbtuxProxy::execALTER_INDX_IMPL_CONF(Signal* signal)
82 {
83 const AlterIndxImplConf* conf = (const AlterIndxImplConf*)signal->getDataPtr();
84 Uint32 ssId = conf->senderData;
85 Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
86 recvCONF(signal, ss);
87 }
88
89 void
execALTER_INDX_IMPL_REF(Signal * signal)90 DbtuxProxy::execALTER_INDX_IMPL_REF(Signal* signal)
91 {
92 const AlterIndxImplRef* ref = (const AlterIndxImplRef*)signal->getDataPtr();
93 Uint32 ssId = ref->senderData;
94 Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
95 recvREF(signal, ss, ref->errorCode);
96 }
97
98 void
sendALTER_INDX_IMPL_CONF(Signal * signal,Uint32 ssId)99 DbtuxProxy::sendALTER_INDX_IMPL_CONF(Signal* signal, Uint32 ssId)
100 {
101 Ss_ALTER_INDX_IMPL_REQ& ss = ssFind<Ss_ALTER_INDX_IMPL_REQ>(ssId);
102 BlockReference dictRef = ss.m_req.senderRef;
103
104 if (!lastReply(ss))
105 return;
106
107 if (ss.m_error == 0) {
108 jam();
109 AlterIndxImplConf* conf = (AlterIndxImplConf*)signal->getDataPtrSend();
110 conf->senderRef = reference();
111 conf->senderData = ss.m_req.senderData;
112 sendSignal(dictRef, GSN_ALTER_INDX_IMPL_CONF,
113 signal, AlterIndxImplConf::SignalLength, JBB);
114 } else {
115 AlterIndxImplRef* ref = (AlterIndxImplRef*)signal->getDataPtrSend();
116 ref->senderRef = reference();
117 ref->senderData = ss.m_req.senderData;
118 ref->errorCode = ss.m_error;
119 sendSignal(dictRef, GSN_ALTER_INDX_IMPL_REF,
120 signal, AlterIndxImplRef::SignalLength, JBB);
121 }
122
123 ssRelease<Ss_ALTER_INDX_IMPL_REQ>(ssId);
124 }
125
126 // GSN_INDEX_STAT_IMPL_REQ
127
128 void
execINDEX_STAT_IMPL_REQ(Signal * signal)129 DbtuxProxy::execINDEX_STAT_IMPL_REQ(Signal* signal)
130 {
131 jamEntry();
132 const IndexStatImplReq* req =
133 (const IndexStatImplReq*)signal->getDataPtr();
134 Ss_INDEX_STAT_IMPL_REQ& ss = ssSeize<Ss_INDEX_STAT_IMPL_REQ>();
135 ss.m_req = *req;
136 ndbrequire(signal->getLength() == IndexStatImplReq::SignalLength);
137 sendREQ(signal, ss);
138 }
139
140 void
sendINDEX_STAT_IMPL_REQ(Signal * signal,Uint32 ssId,SectionHandle *)141 DbtuxProxy::sendINDEX_STAT_IMPL_REQ(Signal* signal, Uint32 ssId,
142 SectionHandle*)
143 {
144 Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
145
146 IndexStatImplReq* req = (IndexStatImplReq*)signal->getDataPtrSend();
147 *req = ss.m_req;
148 req->senderRef = reference();
149 req->senderData = ssId;
150
151 const Uint32 instance = workerInstance(ss.m_worker);
152 NdbLogPartInfo lpinfo(instance);
153
154 //XXX remove unused
155 switch (req->requestType) {
156 case IndexStatReq::RT_START_MON:
157 /*
158 * DICT sets fragId if assigned frag is on this node, or else ZNIL
159 * to turn off any possible old assignment. In MT-LQH we also have
160 * to check which worker owns the frag.
161 */
162 if (req->fragId != ZNIL
163 && !lpinfo.partNoOwner(req->indexId, req->fragId)) {
164 jam();
165 req->fragId = ZNIL;
166 }
167 break;
168 case IndexStatReq::RT_STOP_MON:
169 /*
170 * DICT sets fragId to ZNIL always. There is no (pointless) check
171 * to see if the frag was ever assigned.
172 */
173 ndbrequire(req->fragId == ZNIL);
174 break;
175 case IndexStatReq::RT_SCAN_FRAG:
176 ndbrequire(req->fragId != ZNIL);
177 if (!lpinfo.partNoOwner(req->indexId, req->fragId)) {
178 jam();
179 skipReq(ss);
180 return;
181 }
182 break;
183 case IndexStatReq::RT_CLEAN_NEW:
184 case IndexStatReq::RT_CLEAN_OLD:
185 case IndexStatReq::RT_CLEAN_ALL:
186 ndbrequire(req->fragId == ZNIL);
187 break;
188 case IndexStatReq::RT_DROP_HEAD:
189 /*
190 * Only one client can do the PK-delete of the head record. We use
191 * of course the worker which owns the assigned fragment.
192 */
193 ndbrequire(req->fragId != ZNIL);
194 if (!lpinfo.partNoOwner(req->indexId, req->fragId)) {
195 jam();
196 skipReq(ss);
197 return;
198 }
199 break;
200 default:
201 ndbrequire(false);
202 break;
203 }
204
205 sendSignal(workerRef(ss.m_worker), GSN_INDEX_STAT_IMPL_REQ,
206 signal, IndexStatImplReq::SignalLength, JBB);
207 }
208
209 void
execINDEX_STAT_IMPL_CONF(Signal * signal)210 DbtuxProxy::execINDEX_STAT_IMPL_CONF(Signal* signal)
211 {
212 jamEntry();
213 const IndexStatImplConf* conf =
214 (const IndexStatImplConf*)signal->getDataPtr();
215 Uint32 ssId = conf->senderData;
216 Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
217 recvCONF(signal, ss);
218 }
219
220 void
execINDEX_STAT_IMPL_REF(Signal * signal)221 DbtuxProxy::execINDEX_STAT_IMPL_REF(Signal* signal)
222 {
223 jamEntry();
224 const IndexStatImplRef* ref = (const IndexStatImplRef*)signal->getDataPtr();
225 Uint32 ssId = ref->senderData;
226 Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
227 recvREF(signal, ss, ref->errorCode);
228 }
229
230 void
sendINDEX_STAT_IMPL_CONF(Signal * signal,Uint32 ssId)231 DbtuxProxy::sendINDEX_STAT_IMPL_CONF(Signal* signal, Uint32 ssId)
232 {
233 Ss_INDEX_STAT_IMPL_REQ& ss = ssFind<Ss_INDEX_STAT_IMPL_REQ>(ssId);
234 BlockReference dictRef = ss.m_req.senderRef;
235
236 if (!lastReply(ss))
237 return;
238
239 if (ss.m_error == 0) {
240 jam();
241 IndexStatImplConf* conf = (IndexStatImplConf*)signal->getDataPtrSend();
242 conf->senderRef = reference();
243 conf->senderData = ss.m_req.senderData;
244 sendSignal(dictRef, GSN_INDEX_STAT_IMPL_CONF,
245 signal, IndexStatImplConf::SignalLength, JBB);
246 } else {
247 IndexStatImplRef* ref = (IndexStatImplRef*)signal->getDataPtrSend();
248 ref->senderRef = reference();
249 ref->senderData = ss.m_req.senderData;
250 ref->errorCode = ss.m_error;
251 sendSignal(dictRef, GSN_INDEX_STAT_IMPL_REF,
252 signal, IndexStatImplRef::SignalLength, JBB);
253 }
254
255 ssRelease<Ss_INDEX_STAT_IMPL_REQ>(ssId);
256 }
257
258 // GSN_INDEX_STAT_REP
259
260 void
execINDEX_STAT_REP(Signal * signal)261 DbtuxProxy::execINDEX_STAT_REP(Signal* signal)
262 {
263 jamEntry();
264 const IndexStatRep* rep =
265 (const IndexStatRep*)signal->getDataPtr();
266 Ss_INDEX_STAT_REP& ss = ssSeize<Ss_INDEX_STAT_REP>();
267 ss.m_rep = *rep;
268 ndbrequire(signal->getLength() == IndexStatRep::SignalLength);
269 sendREQ(signal, ss);
270 ssRelease<Ss_INDEX_STAT_REP>(ss);
271 }
272
273 void
sendINDEX_STAT_REP(Signal * signal,Uint32 ssId,SectionHandle *)274 DbtuxProxy::sendINDEX_STAT_REP(Signal* signal, Uint32 ssId,
275 SectionHandle*)
276 {
277 Ss_INDEX_STAT_REP& ss = ssFind<Ss_INDEX_STAT_REP>(ssId);
278
279 IndexStatRep* rep = (IndexStatRep*)signal->getDataPtrSend();
280 *rep = ss.m_rep;
281 rep->senderData = reference();
282 rep->senderData = ssId;
283
284 const Uint32 instance = workerInstance(ss.m_worker);
285 NdbLogPartInfo lpinfo(instance);
286
287 ndbrequire(rep->fragId != ZNIL);
288 if (!lpinfo.partNoOwner(rep->indexId, rep->fragId)) {
289 jam();
290 skipReq(ss);
291 return;
292 }
293
294 sendSignal(workerRef(ss.m_worker), GSN_INDEX_STAT_REP,
295 signal, IndexStatRep::SignalLength, JBB);
296 }
297
298 BLOCK_FUNCTIONS(DbtuxProxy)
299