~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/row/row0umod.c

  • Committer: Brian Aker
  • Date: 2010-11-06 15:43:10 UTC
  • mfrom: (1908.1.1 merge)
  • Revision ID: brian@tangent.org-20101106154310-g1jpjzwbc53pfc4f
Filesort encapsulation, plus modification to copy contructor

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
58
58
some of its fields were changed. Now, it is possible that the delete marked
59
59
version has become obsolete at the time the undo is started. */
60
60
 
61
 
/*************************************************************************
62
 
IMPORTANT NOTE: Any operation that generates redo MUST check that there
63
 
is enough space in the redo log before for that operation. This is
64
 
done by calling log_free_check(). The reason for checking the
65
 
availability of the redo log space before the start of the operation is
66
 
that we MUST not hold any synchonization objects when performing the
67
 
check.
68
 
If you make a change in this module make sure that no codepath is
69
 
introduced where a call to log_free_check() is bypassed. */
70
 
 
71
61
/***********************************************************//**
72
62
Checks if also the previous version of the clustered index record was
73
63
modified or inserted by the same transaction, and its undo number is such
74
64
that it should be undone in the same rollback.
75
65
@return TRUE if also previous modify or insert of this row should be undone */
76
 
static
 
66
UNIV_INLINE
77
67
ibool
78
68
row_undo_mod_undo_also_prev_vers(
79
69
/*=============================*/
85
75
 
86
76
        trx = node->trx;
87
77
 
88
 
        if (node->new_trx_id != trx->id) {
 
78
        if (0 != ut_dulint_cmp(node->new_trx_id, trx->id)) {
89
79
 
90
 
                *undo_no = 0;
 
80
                *undo_no = ut_dulint_zero;
91
81
                return(FALSE);
92
82
        }
93
83
 
95
85
 
96
86
        *undo_no = trx_undo_rec_get_undo_no(undo_rec);
97
87
 
98
 
        return(trx->roll_limit <= *undo_no);
 
88
        return(ut_dulint_cmp(trx->roll_limit, *undo_no) <= 0);
99
89
}
100
90
 
101
91
/***********************************************************//**
114
104
        btr_pcur_t*     pcur;
115
105
        btr_cur_t*      btr_cur;
116
106
        ulint           err;
117
 
#ifdef UNIV_DEBUG
118
107
        ibool           success;
119
 
#endif /* UNIV_DEBUG */
120
108
 
121
109
        pcur = &(node->pcur);
122
110
        btr_cur = btr_pcur_get_btr_cur(pcur);
123
111
 
124
 
#ifdef UNIV_DEBUG
125
 
        success =
126
 
#endif /* UNIV_DEBUG */
127
 
        btr_pcur_restore_position(mode, pcur, mtr);
 
112
        success = btr_pcur_restore_position(mode, pcur, mtr);
128
113
 
129
114
        ut_ad(success);
130
115
 
159
144
 
160
145
/***********************************************************//**
161
146
Removes a clustered index record after undo if possible.
162
 
This is attempted when the record was inserted by updating a
163
 
delete-marked record and there no longer exist transactions
164
 
that would see the delete-marked record.  In other words, we
165
 
roll back the insert by purging the record.
166
147
@return DB_SUCCESS, DB_FAIL, or error code: we may run out of file space */
167
148
static
168
149
ulint
169
150
row_undo_mod_remove_clust_low(
170
151
/*==========================*/
171
152
        undo_node_t*    node,   /*!< in: row undo node */
172
 
        que_thr_t*      thr,    /*!< in: query thread */
 
153
        que_thr_t*      thr __attribute__((unused)), /*!< in: query thread */
173
154
        mtr_t*          mtr,    /*!< in: mtr */
174
155
        ulint           mode)   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE */
175
156
{
178
159
        ulint           err;
179
160
        ibool           success;
180
161
 
181
 
        ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
182
162
        pcur = &(node->pcur);
183
163
        btr_cur = btr_pcur_get_btr_cur(pcur);
184
164
 
210
190
        } else {
211
191
                ut_ad(mode == BTR_MODIFY_TREE);
212
192
 
213
 
                /* This operation is analogous to purge, we can free also
214
 
                inherited externally stored fields */
 
193
                /* Note that since this operation is analogous to purge,
 
194
                we can free also inherited externally stored fields:
 
195
                hence the RB_NONE in the call below */
215
196
 
216
 
                btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
217
 
                                           thr_is_recv(thr)
218
 
                                           ? RB_RECOVERY_PURGE_REC
219
 
                                           : RB_NONE, mtr);
 
197
                btr_cur_pessimistic_delete(&err, FALSE, btr_cur, RB_NONE, mtr);
220
198
 
221
199
                /* The delete operation may fail if we have little
222
200
                file space left: TODO: easiest to crash the database
246
224
 
247
225
        ut_ad(node && thr);
248
226
 
249
 
        log_free_check();
250
 
 
251
227
        /* Check if also the previous version of the clustered index record
252
228
        should be undone in this same rollback operation */
253
229
 
331
307
        ulint           mode)   /*!< in: latch mode BTR_MODIFY_LEAF or
332
308
                                BTR_MODIFY_TREE */
333
309
{
334
 
        btr_pcur_t              pcur;
335
 
        btr_cur_t*              btr_cur;
336
 
        ibool                   success;
337
 
        ibool                   old_has;
338
 
        ulint                   err;
339
 
        mtr_t                   mtr;
340
 
        mtr_t                   mtr_vers;
341
 
        enum row_search_result  search_result;
 
310
        ibool           found;
 
311
        btr_pcur_t      pcur;
 
312
        btr_cur_t*      btr_cur;
 
313
        ibool           success;
 
314
        ibool           old_has;
 
315
        ulint           err;
 
316
        mtr_t           mtr;
 
317
        mtr_t           mtr_vers;
342
318
 
343
319
        log_free_check();
344
320
        mtr_start(&mtr);
345
321
 
 
322
        found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
 
323
 
346
324
        btr_cur = btr_pcur_get_btr_cur(&pcur);
347
325
 
348
 
        ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
349
 
 
350
 
        search_result = row_search_index_entry(index, entry, mode,
351
 
                                               &pcur, &mtr);
352
 
 
353
 
        switch (UNIV_EXPECT(search_result, ROW_FOUND)) {
354
 
        case ROW_NOT_FOUND:
 
326
        if (!found) {
355
327
                /* In crash recovery, the secondary index record may
356
328
                be missing if the UPDATE did not have time to insert
357
329
                the secondary index records before the crash.  When we
362
334
                before it has inserted all updated secondary index
363
335
                records, then the undo will not find those records. */
364
336
 
365
 
                err = DB_SUCCESS;
366
 
                goto func_exit;
367
 
        case ROW_FOUND:
368
 
                break;
369
 
        case ROW_BUFFERED:
370
 
        case ROW_NOT_DELETED_REF:
371
 
                /* These are invalid outcomes, because the mode passed
372
 
                to row_search_index_entry() did not include any of the
373
 
                flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
374
 
                ut_error;
 
337
                btr_pcur_close(&pcur);
 
338
                mtr_commit(&mtr);
 
339
 
 
340
                return(DB_SUCCESS);
375
341
        }
376
342
 
377
343
        /* We should remove the index record if no prior version of the row,
404
370
                } else {
405
371
                        ut_ad(mode == BTR_MODIFY_TREE);
406
372
 
407
 
                        /* No need to distinguish RB_RECOVERY_PURGE here,
408
 
                        because we are deleting a secondary index record:
409
 
                        the distinction between RB_NORMAL and
410
 
                        RB_RECOVERY_PURGE only matters when deleting a
411
 
                        record that contains externally stored
 
373
                        /* No need to distinguish RB_RECOVERY here, because we
 
374
                        are deleting a secondary index record: the distinction
 
375
                        between RB_NORMAL and RB_RECOVERY only matters when
 
376
                        deleting a record that contains externally stored
412
377
                        columns. */
413
378
                        ut_ad(!dict_index_is_clust(index));
414
379
                        btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
421
386
        }
422
387
 
423
388
        btr_pcur_commit_specify_mtr(&(node->pcur), &mtr_vers);
424
 
 
425
 
func_exit:
426
389
        btr_pcur_close(&pcur);
427
390
        mtr_commit(&mtr);
428
391
 
475
438
                                BTR_MODIFY_TREE */
476
439
        que_thr_t*      thr,    /*!< in: query thread */
477
440
        dict_index_t*   index,  /*!< in: index */
478
 
        const dtuple_t* entry)  /*!< in: index entry */
 
441
        dtuple_t*       entry)  /*!< in: index entry */
479
442
{
480
 
        mem_heap_t*             heap;
481
 
        btr_pcur_t              pcur;
482
 
        btr_cur_t*              btr_cur;
483
 
        upd_t*                  update;
484
 
        ulint                   err             = DB_SUCCESS;
485
 
        big_rec_t*              dummy_big_rec;
486
 
        mtr_t                   mtr;
487
 
        trx_t*                  trx             = thr_get_trx(thr);
488
 
        enum row_search_result  search_result;
 
443
        mem_heap_t*     heap;
 
444
        btr_pcur_t      pcur;
 
445
        upd_t*          update;
 
446
        ulint           err             = DB_SUCCESS;
 
447
        big_rec_t*      dummy_big_rec;
 
448
        mtr_t           mtr;
 
449
        trx_t*          trx             = thr_get_trx(thr);
489
450
 
490
451
        /* Ignore indexes that are being created. */
491
452
        if (UNIV_UNLIKELY(*index->name == TEMP_INDEX_PREFIX)) {
496
457
        log_free_check();
497
458
        mtr_start(&mtr);
498
459
 
499
 
        ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
500
 
 
501
 
        search_result = row_search_index_entry(index, entry, mode,
502
 
                                               &pcur, &mtr);
503
 
 
504
 
        switch (search_result) {
505
 
        case ROW_BUFFERED:
506
 
        case ROW_NOT_DELETED_REF:
507
 
                /* These are invalid outcomes, because the mode passed
508
 
                to row_search_index_entry() did not include any of the
509
 
                flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
510
 
                ut_error;
511
 
        case ROW_NOT_FOUND:
 
460
        if (UNIV_UNLIKELY(!row_search_index_entry(index, entry,
 
461
                                                  mode, &pcur, &mtr))) {
512
462
                fputs("InnoDB: error in sec index entry del undo in\n"
513
463
                      "InnoDB: ", stderr);
514
464
                dict_index_name_print(stderr, trx, index);
523
473
                fputs("\n"
524
474
                      "InnoDB: Submit a detailed bug report"
525
475
                      " to http://bugs.mysql.com\n", stderr);
526
 
                break;
527
 
        case ROW_FOUND:
528
 
                btr_cur = btr_pcur_get_btr_cur(&pcur);
 
476
        } else {
 
477
                btr_cur_t*      btr_cur = btr_pcur_get_btr_cur(&pcur);
 
478
 
529
479
                err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
530
480
                                                   btr_cur, FALSE, thr, &mtr);
531
481
                ut_a(err == DB_SUCCESS);
583
533
        dict_index_t*   index;
584
534
        ulint           err     = DB_SUCCESS;
585
535
 
586
 
        ut_ad(node->rec_type == TRX_UNDO_UPD_DEL_REC);
587
536
        heap = mem_heap_create(1024);
588
537
 
589
538
        while (node->index != NULL) {
601
550
                        does not exist.  However, this situation may
602
551
                        only occur during the rollback of incomplete
603
552
                        transactions. */
604
 
                        ut_a(thr_is_recv(thr));
 
553
                        ut_a(trx_is_recv(thr_get_trx(thr)));
605
554
                } else {
606
555
                        err = row_undo_mod_del_mark_or_remove_sec(
607
556
                                node, thr, index, entry);
699
648
                        /* Build the newest version of the index entry */
700
649
                        entry = row_build_index_entry(node->row, node->ext,
701
650
                                                      index, heap);
702
 
                        if (UNIV_UNLIKELY(!entry)) {
703
 
                                /* The server must have crashed in
704
 
                                row_upd_clust_rec_by_insert(), in
705
 
                                row_ins_index_entry_low() before
706
 
                                btr_store_big_rec_extern_fields()
707
 
                                has written the externally stored columns
708
 
                                (BLOBs) of the new clustered index entry. */
709
 
 
710
 
                                /* The table must be in DYNAMIC or COMPRESSED
711
 
                                format.  REDUNDANT and COMPACT formats
712
 
                                store a local 768-byte prefix of each
713
 
                                externally stored column. */
714
 
                                ut_a(dict_table_get_format(index->table)
715
 
                                     >= DICT_TF_FORMAT_ZIP);
716
 
 
717
 
                                /* This is only legitimate when
718
 
                                rolling back an incomplete transaction
719
 
                                after crash recovery. */
720
 
                                ut_a(thr_get_trx(thr)->is_recovered);
721
 
 
722
 
                                /* The server must have crashed before
723
 
                                completing the insert of the new
724
 
                                clustered index entry and before
725
 
                                inserting to the secondary indexes.
726
 
                                Because node->row was not yet written
727
 
                                to this index, we can ignore it.  But
728
 
                                we must restore node->undo_row. */
729
 
                        } else {
730
 
                                /* NOTE that if we updated the fields of a
731
 
                                delete-marked secondary index record so that
732
 
                                alphabetically they stayed the same, e.g.,
733
 
                                'abc' -> 'aBc', we cannot return to the
734
 
                                original values because we do not know them.
735
 
                                But this should not cause problems because
736
 
                                in row0sel.c, in queries we always retrieve
737
 
                                the clustered index record or an earlier
738
 
                                version of it, if the secondary index record
739
 
                                through which we do the search is
740
 
                                delete-marked. */
741
 
 
742
 
                                err = row_undo_mod_del_mark_or_remove_sec(
743
 
                                        node, thr, index, entry);
744
 
                                if (err != DB_SUCCESS) {
745
 
                                        mem_heap_free(heap);
746
 
 
747
 
                                        return(err);
748
 
                                }
749
 
 
750
 
                                mem_heap_empty(heap);
 
651
                        ut_a(entry);
 
652
                        /* NOTE that if we updated the fields of a
 
653
                        delete-marked secondary index record so that
 
654
                        alphabetically they stayed the same, e.g.,
 
655
                        'abc' -> 'aBc', we cannot return to the original
 
656
                        values because we do not know them. But this should
 
657
                        not cause problems because in row0sel.c, in queries
 
658
                        we always retrieve the clustered index record or an
 
659
                        earlier version of it, if the secondary index record
 
660
                        through which we do the search is delete-marked. */
 
661
 
 
662
                        err = row_undo_mod_del_mark_or_remove_sec(node, thr,
 
663
                                                                  index,
 
664
                                                                  entry);
 
665
                        if (err != DB_SUCCESS) {
 
666
                                mem_heap_free(heap);
 
667
 
 
668
                                return(err);
751
669
                        }
752
670
 
753
671
                        /* We may have to update the delete mark in the
756
674
                        the secondary index record if we updated its fields
757
675
                        but alphabetically they stayed the same, e.g.,
758
676
                        'abc' -> 'aBc'. */
 
677
                        mem_heap_empty(heap);
759
678
                        entry = row_build_index_entry(node->undo_row,
760
679
                                                      node->undo_ext,
761
680
                                                      index, heap);
795
714
        dict_index_t*   clust_index;
796
715
        byte*           ptr;
797
716
        undo_no_t       undo_no;
798
 
        table_id_t      table_id;
 
717
        dulint          table_id;
799
718
        trx_id_t        trx_id;
800
719
        roll_ptr_t      roll_ptr;
801
720
        ulint           info_bits;