~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/kernel/blocks/dbtup/DbtupAbort.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
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 as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
#define DBTUP_C
 
17
#define DBTUP_ABORT_CPP
 
18
#include "Dbtup.hpp"
 
19
#include <RefConvert.hpp>
 
20
#include <ndb_limits.h>
 
21
#include <pc.hpp>
 
22
 
 
23
void Dbtup::freeAllAttrBuffers(Operationrec*  const regOperPtr)
 
24
{
 
25
  if (regOperPtr->storedProcedureId == RNIL) {
 
26
    jam();
 
27
    freeAttrinbufrec(regOperPtr->firstAttrinbufrec);
 
28
  } else {
 
29
    jam();
 
30
    StoredProcPtr storedPtr;
 
31
    c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->storedProcedureId);
 
32
    ndbrequire(storedPtr.p->storedCode == ZSCAN_PROCEDURE);
 
33
    storedPtr.p->storedCounter--;
 
34
    regOperPtr->storedProcedureId = ZNIL;
 
35
  }//if
 
36
  regOperPtr->firstAttrinbufrec = RNIL;
 
37
  regOperPtr->lastAttrinbufrec = RNIL;
 
38
  regOperPtr->m_any_value = 0;
 
39
}//Dbtup::freeAllAttrBuffers()
 
40
 
 
41
void Dbtup::freeAttrinbufrec(Uint32 anAttrBuf) 
 
42
{
 
43
  Uint32 Ttemp;
 
44
  AttrbufrecPtr localAttrBufPtr;
 
45
  Uint32 RnoFree = cnoFreeAttrbufrec;
 
46
  localAttrBufPtr.i = anAttrBuf;
 
47
  while (localAttrBufPtr.i != RNIL) {
 
48
    jam();
 
49
    ptrCheckGuard(localAttrBufPtr, cnoOfAttrbufrec, attrbufrec);
 
50
    Ttemp = localAttrBufPtr.p->attrbuf[ZBUF_NEXT];
 
51
    localAttrBufPtr.p->attrbuf[ZBUF_NEXT] = cfirstfreeAttrbufrec;
 
52
    cfirstfreeAttrbufrec = localAttrBufPtr.i;
 
53
    localAttrBufPtr.i = Ttemp;
 
54
    RnoFree++;
 
55
  }//if
 
56
  cnoFreeAttrbufrec = RnoFree;
 
57
}//Dbtup::freeAttrinbufrec()
 
58
 
 
59
/**
 
60
 * Abort abort this operation and all after (nextActiveOp's)
 
61
 */
 
62
void Dbtup::execTUP_ABORTREQ(Signal* signal) 
 
63
{
 
64
  jamEntry();
 
65
  do_tup_abortreq(signal, 0);
 
66
}
 
67
 
 
68
void Dbtup::do_tup_abortreq(Signal* signal, Uint32 flags)
 
69
{
 
70
  OperationrecPtr regOperPtr;
 
71
  FragrecordPtr regFragPtr;
 
72
  TablerecPtr regTabPtr;
 
73
 
 
74
  regOperPtr.i = signal->theData[0];
 
75
  c_operation_pool.getPtr(regOperPtr);
 
76
  TransState trans_state= get_trans_state(regOperPtr.p);
 
77
  ndbrequire((trans_state == TRANS_STARTED) ||
 
78
             (trans_state == TRANS_TOO_MUCH_AI) ||
 
79
             (trans_state == TRANS_ERROR_WAIT_TUPKEYREQ) ||
 
80
             (trans_state == TRANS_IDLE));
 
81
  if (regOperPtr.p->op_struct.op_type == ZREAD) {
 
82
    jam();
 
83
    freeAllAttrBuffers(regOperPtr.p);
 
84
    initOpConnection(regOperPtr.p);
 
85
    return;
 
86
  }//if
 
87
 
 
88
  regFragPtr.i = regOperPtr.p->fragmentPtr;
 
89
  ptrCheckGuard(regFragPtr, cnoOfFragrec, fragrecord);
 
90
 
 
91
  regTabPtr.i = regFragPtr.p->fragTableId;
 
92
  ptrCheckGuard(regTabPtr, cnoOfTablerec, tablerec);
 
93
 
 
94
  if (get_tuple_state(regOperPtr.p) == TUPLE_PREPARED)
 
95
  {
 
96
    jam();
 
97
    if (!regTabPtr.p->tuxCustomTriggers.isEmpty() &&
 
98
        (flags & ZSKIP_TUX_TRIGGERS) == 0)
 
99
      executeTuxAbortTriggers(signal,
 
100
                              regOperPtr.p,
 
101
                              regFragPtr.p,
 
102
                              regTabPtr.p);
 
103
    
 
104
    OperationrecPtr loopOpPtr;
 
105
    loopOpPtr.i = regOperPtr.p->nextActiveOp;
 
106
    while (loopOpPtr.i != RNIL) {
 
107
      jam();
 
108
      c_operation_pool.getPtr(loopOpPtr);
 
109
      if (get_tuple_state(loopOpPtr.p) != TUPLE_ALREADY_ABORTED &&
 
110
          !regTabPtr.p->tuxCustomTriggers.isEmpty() &&
 
111
          (flags & ZSKIP_TUX_TRIGGERS) == 0) {
 
112
        jam();
 
113
        executeTuxAbortTriggers(signal,
 
114
                                loopOpPtr.p,
 
115
                                regFragPtr.p,
 
116
                                regTabPtr.p);
 
117
      }
 
118
      set_tuple_state(loopOpPtr.p, TUPLE_ALREADY_ABORTED);      
 
119
      loopOpPtr.i = loopOpPtr.p->nextActiveOp;
 
120
    }
 
121
  }
 
122
 
 
123
  PagePtr page;
 
124
  Tuple_header *tuple_ptr= (Tuple_header*)
 
125
    get_ptr(&page, &regOperPtr.p->m_tuple_location, regTabPtr.p);
 
126
 
 
127
  Uint32 bits= tuple_ptr->m_header_bits;  
 
128
  if(regOperPtr.p->op_struct.op_type != ZDELETE)
 
129
  {
 
130
    Tuple_header *copy= (Tuple_header*)
 
131
      c_undo_buffer.get_ptr(&regOperPtr.p->m_copy_tuple_location);
 
132
    
 
133
    if(regOperPtr.p->op_struct.m_disk_preallocated)
 
134
    {
 
135
      jam();
 
136
      Local_key key;
 
137
      memcpy(&key, copy->get_disk_ref_ptr(regTabPtr.p), sizeof(key));
 
138
      disk_page_abort_prealloc(signal, regFragPtr.p, &key, key.m_page_idx);
 
139
    }
 
140
    
 
141
 
 
142
    Uint32 copy_bits= copy->m_header_bits;
 
143
    if(! (bits & Tuple_header::ALLOC))
 
144
    {
 
145
      if(copy_bits & Tuple_header::MM_GROWN)
 
146
      {
 
147
        if (0) ndbout_c("abort grow");
 
148
        Ptr<Page> vpage;
 
149
        Uint32 idx= regOperPtr.p->m_tuple_location.m_page_idx;
 
150
        Uint32 mm_vars= regTabPtr.p->m_attributes[MM].m_no_of_varsize;
 
151
        Uint32 *var_part;
 
152
 
 
153
        ndbassert(tuple_ptr->m_header_bits & Tuple_header::CHAINED_ROW);
 
154
        
 
155
        Var_part_ref *ref = tuple_ptr->get_var_part_ref_ptr(regTabPtr.p);
 
156
 
 
157
        Local_key tmp; 
 
158
        ref->copyout(&tmp);
 
159
        
 
160
        idx= tmp.m_page_idx;
 
161
        var_part= get_ptr(&vpage, *ref);
 
162
        Var_page* pageP = (Var_page*)vpage.p;
 
163
        Uint32 len= pageP->get_entry_len(idx) & ~Var_page::CHAIN;
 
164
        Uint32 sz = ((((mm_vars + 1) << 1) + (((Uint16*)var_part)[mm_vars]) + 3)>> 2);
 
165
        ndbassert(sz <= len);
 
166
        pageP->shrink_entry(idx, sz);
 
167
        update_free_page_list(regFragPtr.p, vpage);
 
168
      } 
 
169
      else if(bits & Tuple_header::MM_SHRINK)
 
170
      {
 
171
        if (0) ndbout_c("abort shrink");
 
172
      }
 
173
    }
 
174
    else if (regOperPtr.p->is_first_operation() && 
 
175
             regOperPtr.p->is_last_operation())
 
176
    {
 
177
      /**
 
178
       * Aborting last operation that performed ALLOC
 
179
       */
 
180
      tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
 
181
      tuple_ptr->m_header_bits |= Tuple_header::FREED;
 
182
    }
 
183
  }
 
184
  else if (regOperPtr.p->is_first_operation() && 
 
185
           regOperPtr.p->is_last_operation())
 
186
  {
 
187
    if (bits & Tuple_header::ALLOC)
 
188
    {
 
189
      tuple_ptr->m_header_bits &= ~(Uint32)Tuple_header::ALLOC;
 
190
      tuple_ptr->m_header_bits |= Tuple_header::FREED;
 
191
    }
 
192
  }
 
193
  
 
194
  if(regOperPtr.p->is_first_operation() && regOperPtr.p->is_last_operation())
 
195
  {
 
196
    if (regOperPtr.p->m_undo_buffer_space)
 
197
      c_lgman->free_log_space(regFragPtr.p->m_logfile_group_id, 
 
198
                              regOperPtr.p->m_undo_buffer_space);
 
199
  }
 
200
 
 
201
  removeActiveOpList(regOperPtr.p, tuple_ptr);
 
202
  initOpConnection(regOperPtr.p);
 
203
}
 
204
 
 
205
/* **************************************************************** */
 
206
/* ********************** TRANSACTION ERROR MODULE **************** */
 
207
/* **************************************************************** */
 
208
int Dbtup::TUPKEY_abort(Signal* signal, int error_type)
 
209
{
 
210
  switch(error_type) {
 
211
  case 1:
 
212
//tmupdate_alloc_error:
 
213
    terrorCode= ZMEM_NOMEM_ERROR;
 
214
    jam();
 
215
    break;
 
216
 
 
217
  case 15:
 
218
    jam();
 
219
    terrorCode = ZREGISTER_INIT_ERROR;
 
220
    break;
 
221
 
 
222
  case 16:
 
223
    jam();
 
224
    terrorCode = ZTRY_TO_UPDATE_ERROR;
 
225
    break;
 
226
 
 
227
  case 17:
 
228
    jam();
 
229
    terrorCode = ZNO_ILLEGAL_NULL_ATTR;
 
230
    break;
 
231
 
 
232
  case 19:
 
233
    jam();
 
234
    terrorCode = ZTRY_TO_UPDATE_ERROR;
 
235
    break;
 
236
 
 
237
  case 20:
 
238
    jam();
 
239
    terrorCode = ZREGISTER_INIT_ERROR;
 
240
    break;
 
241
 
 
242
  case 22:
 
243
    jam();
 
244
    terrorCode = ZTOTAL_LEN_ERROR;
 
245
    break;
 
246
 
 
247
  case 23:
 
248
    jam();
 
249
    terrorCode = ZREGISTER_INIT_ERROR;
 
250
    break;
 
251
 
 
252
  case 24:
 
253
    jam();
 
254
    terrorCode = ZREGISTER_INIT_ERROR;
 
255
    break;
 
256
 
 
257
  case 26:
 
258
    jam();
 
259
    terrorCode = ZREGISTER_INIT_ERROR;
 
260
    break;
 
261
 
 
262
  case 27:
 
263
    jam();
 
264
    terrorCode = ZREGISTER_INIT_ERROR;
 
265
    break;
 
266
 
 
267
  case 28:
 
268
    jam();
 
269
    terrorCode = ZREGISTER_INIT_ERROR;
 
270
    break;
 
271
 
 
272
  case 29:
 
273
    jam();
 
274
    break;
 
275
 
 
276
  case 30:
 
277
    jam();
 
278
    terrorCode = ZCALL_ERROR;
 
279
    break;
 
280
 
 
281
  case 31:
 
282
    jam();
 
283
    terrorCode = ZSTACK_OVERFLOW_ERROR;
 
284
    break;
 
285
 
 
286
  case 32:
 
287
    jam();
 
288
    terrorCode = ZSTACK_UNDERFLOW_ERROR;
 
289
    break;
 
290
 
 
291
  case 33:
 
292
    jam();
 
293
    terrorCode = ZNO_INSTRUCTION_ERROR;
 
294
    break;
 
295
 
 
296
  case 34:
 
297
    jam();
 
298
    terrorCode = ZOUTSIDE_OF_PROGRAM_ERROR;
 
299
    break;
 
300
 
 
301
  case 35:
 
302
    jam();
 
303
    terrorCode = ZTOO_MANY_INSTRUCTIONS_ERROR;
 
304
    break;
 
305
 
 
306
  case 38:
 
307
    jam();
 
308
    terrorCode = ZTEMPORARY_RESOURCE_FAILURE;
 
309
    break;
 
310
 
 
311
  case 39:
 
312
    if (get_trans_state(operPtr.p) == TRANS_TOO_MUCH_AI) {
 
313
      jam();
 
314
      terrorCode = ZTOO_MUCH_ATTRINFO_ERROR;
 
315
    } else if (get_trans_state(operPtr.p) == TRANS_ERROR_WAIT_TUPKEYREQ) {
 
316
      jam();
 
317
      terrorCode = ZSEIZE_ATTRINBUFREC_ERROR;
 
318
    } else {
 
319
      ndbrequire(false);
 
320
    }//if
 
321
    break;
 
322
  case 40:
 
323
    jam();
 
324
    terrorCode = ZUNSUPPORTED_BRANCH;
 
325
    break;
 
326
  default:
 
327
    ndbrequire(false);
 
328
    break;
 
329
  }//switch
 
330
  tupkeyErrorLab(signal);
 
331
  return -1;
 
332
}
 
333
 
 
334
void Dbtup::early_tupkey_error(Signal* signal)
 
335
{
 
336
  Operationrec * const regOperPtr = operPtr.p;
 
337
  ndbrequire(!regOperPtr->op_struct.in_active_list);
 
338
  set_trans_state(regOperPtr, TRANS_IDLE);
 
339
  set_tuple_state(regOperPtr, TUPLE_PREPARED);
 
340
  initOpConnection(regOperPtr);
 
341
  send_TUPKEYREF(signal, regOperPtr);
 
342
}
 
343
 
 
344
void Dbtup::tupkeyErrorLab(Signal* signal) 
 
345
{
 
346
  Operationrec * const regOperPtr = operPtr.p;
 
347
  set_trans_state(regOperPtr, TRANS_IDLE);
 
348
  set_tuple_state(regOperPtr, TUPLE_PREPARED);
 
349
 
 
350
  FragrecordPtr fragPtr;
 
351
  fragPtr.i= regOperPtr->fragmentPtr;
 
352
  ptrCheckGuard(fragPtr, cnoOfFragrec, fragrecord);
 
353
 
 
354
  TablerecPtr tabPtr;
 
355
  tabPtr.i= fragPtr.p->fragTableId;
 
356
  ptrCheckGuard(tabPtr, cnoOfTablerec, tablerec);
 
357
 
 
358
  if (regOperPtr->m_undo_buffer_space &&
 
359
      (regOperPtr->is_first_operation() && regOperPtr->is_last_operation()))
 
360
  {
 
361
    c_lgman->free_log_space(fragPtr.p->m_logfile_group_id, 
 
362
                            regOperPtr->m_undo_buffer_space);
 
363
  }
 
364
 
 
365
  Uint32 *ptr = 0;
 
366
  if (!regOperPtr->m_tuple_location.isNull())
 
367
  {
 
368
    PagePtr tmp;
 
369
    ptr= get_ptr(&tmp, &regOperPtr->m_tuple_location, tabPtr.p);
 
370
  }
 
371
 
 
372
 
 
373
  removeActiveOpList(regOperPtr, (Tuple_header*)ptr);
 
374
  initOpConnection(regOperPtr);
 
375
  send_TUPKEYREF(signal, regOperPtr);
 
376
}
 
377
 
 
378
void Dbtup::send_TUPKEYREF(Signal* signal,
 
379
                           Operationrec* const regOperPtr)
 
380
{
 
381
  TupKeyRef * const tupKeyRef = (TupKeyRef *)signal->getDataPtrSend();  
 
382
  tupKeyRef->userRef = regOperPtr->userpointer;
 
383
  tupKeyRef->errorCode = terrorCode;
 
384
  sendSignal(DBLQH_REF, GSN_TUPKEYREF, signal, 
 
385
             TupKeyRef::SignalLength, JBB);
 
386
}
 
387
 
 
388
/**
 
389
 * Unlink one operation from the m_operation_ptr_i list in the tuple.
 
390
 */
 
391
void Dbtup::removeActiveOpList(Operationrec*  const regOperPtr,
 
392
                               Tuple_header *tuple_ptr)
 
393
{
 
394
  OperationrecPtr raoOperPtr;
 
395
 
 
396
  if(!regOperPtr->m_copy_tuple_location.isNull())
 
397
  {
 
398
    jam();
 
399
    c_undo_buffer.free_copy_tuple(&regOperPtr->m_copy_tuple_location);
 
400
  }
 
401
 
 
402
  if (regOperPtr->op_struct.in_active_list) {
 
403
    regOperPtr->op_struct.in_active_list= false;
 
404
    if (regOperPtr->nextActiveOp != RNIL) {
 
405
      jam();
 
406
      raoOperPtr.i= regOperPtr->nextActiveOp;
 
407
      c_operation_pool.getPtr(raoOperPtr);
 
408
      raoOperPtr.p->prevActiveOp= regOperPtr->prevActiveOp;
 
409
    } else {
 
410
      jam();
 
411
      tuple_ptr->m_operation_ptr_i = regOperPtr->prevActiveOp;
 
412
    }
 
413
    if (regOperPtr->prevActiveOp != RNIL) {
 
414
      jam();
 
415
      raoOperPtr.i= regOperPtr->prevActiveOp;
 
416
      c_operation_pool.getPtr(raoOperPtr);
 
417
      raoOperPtr.p->nextActiveOp= regOperPtr->nextActiveOp;
 
418
    }
 
419
    regOperPtr->prevActiveOp= RNIL;
 
420
    regOperPtr->nextActiveOp= RNIL;
 
421
  }
 
422
}