~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge initial InnoDB+ import.

This was applied by generating a patch between MySQL 5.1.50 InnoDB plugin and
the just-merged innodb+ from mysql-trunk revision-id: vasil.dimov@oracle.com-20100422110752-1zowoqxel5xx3z2e

Then, some manual merge resolving and it worked. This should make it much
easier to merge the rest of InnoDB 1.1 and 1.2 from the mysql tree using
my bzr-reapply script.

This takes us to InnoDB 1.1.1(ish).

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
/*=============================*/
241
231
 
242
232
        ut_ad(node && thr);
243
233
 
244
 
        log_free_check();
245
 
 
246
234
        /* Check if also the previous version of the clustered index record
247
235
        should be undone in this same rollback operation */
248
236
 
326
314
        ulint           mode)   /*!< in: latch mode BTR_MODIFY_LEAF or
327
315
                                BTR_MODIFY_TREE */
328
316
{
329
 
        ibool           found;
330
 
        btr_pcur_t      pcur;
331
 
        btr_cur_t*      btr_cur;
332
 
        ibool           success;
333
 
        ibool           old_has;
334
 
        ulint           err;
335
 
        mtr_t           mtr;
336
 
        mtr_t           mtr_vers;
 
317
        btr_pcur_t              pcur;
 
318
        btr_cur_t*              btr_cur;
 
319
        ibool                   success;
 
320
        ibool                   old_has;
 
321
        ulint                   err;
 
322
        mtr_t                   mtr;
 
323
        mtr_t                   mtr_vers;
 
324
        enum row_search_result  search_result;
337
325
 
338
326
        log_free_check();
339
327
        mtr_start(&mtr);
340
328
 
341
 
        found = row_search_index_entry(index, entry, mode, &pcur, &mtr);
342
 
 
343
329
        btr_cur = btr_pcur_get_btr_cur(&pcur);
344
330
 
345
 
        if (!found) {
 
331
        ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
 
332
 
 
333
        search_result = row_search_index_entry(index, entry, mode,
 
334
                                               &pcur, &mtr);
 
335
 
 
336
        switch (UNIV_EXPECT(search_result, ROW_FOUND)) {
 
337
        case ROW_NOT_FOUND:
346
338
                /* In crash recovery, the secondary index record may
347
339
                be missing if the UPDATE did not have time to insert
348
340
                the secondary index records before the crash.  When we
353
345
                before it has inserted all updated secondary index
354
346
                records, then the undo will not find those records. */
355
347
 
356
 
                btr_pcur_close(&pcur);
357
 
                mtr_commit(&mtr);
358
 
 
359
 
                return(DB_SUCCESS);
 
348
                err = DB_SUCCESS;
 
349
                goto func_exit;
 
350
        case ROW_FOUND:
 
351
                break;
 
352
        case ROW_BUFFERED:
 
353
        case ROW_NOT_DELETED_REF:
 
354
                /* These are invalid outcomes, because the mode passed
 
355
                to row_search_index_entry() did not include any of the
 
356
                flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
 
357
                ut_error;
360
358
        }
361
359
 
362
360
        /* We should remove the index record if no prior version of the row,
406
404
        }
407
405
 
408
406
        btr_pcur_commit_specify_mtr(&(node->pcur), &mtr_vers);
 
407
 
 
408
func_exit:
409
409
        btr_pcur_close(&pcur);
410
410
        mtr_commit(&mtr);
411
411
 
460
460
        dict_index_t*   index,  /*!< in: index */
461
461
        const dtuple_t* entry)  /*!< in: index entry */
462
462
{
463
 
        mem_heap_t*     heap;
464
 
        btr_pcur_t      pcur;
465
 
        upd_t*          update;
466
 
        ulint           err             = DB_SUCCESS;
467
 
        big_rec_t*      dummy_big_rec;
468
 
        mtr_t           mtr;
469
 
        trx_t*          trx             = thr_get_trx(thr);
 
463
        mem_heap_t*             heap;
 
464
        btr_pcur_t              pcur;
 
465
        btr_cur_t*              btr_cur;
 
466
        upd_t*                  update;
 
467
        ulint                   err             = DB_SUCCESS;
 
468
        big_rec_t*              dummy_big_rec;
 
469
        mtr_t                   mtr;
 
470
        trx_t*                  trx             = thr_get_trx(thr);
 
471
        enum row_search_result  search_result;
470
472
 
471
473
        /* Ignore indexes that are being created. */
472
474
        if (UNIV_UNLIKELY(*index->name == TEMP_INDEX_PREFIX)) {
477
479
        log_free_check();
478
480
        mtr_start(&mtr);
479
481
 
480
 
        if (UNIV_UNLIKELY(!row_search_index_entry(index, entry,
481
 
                                                  mode, &pcur, &mtr))) {
 
482
        ut_ad(mode == BTR_MODIFY_TREE || mode == BTR_MODIFY_LEAF);
 
483
 
 
484
        search_result = row_search_index_entry(index, entry, mode,
 
485
                                               &pcur, &mtr);
 
486
 
 
487
        switch (search_result) {
 
488
        case ROW_BUFFERED:
 
489
        case ROW_NOT_DELETED_REF:
 
490
                /* These are invalid outcomes, because the mode passed
 
491
                to row_search_index_entry() did not include any of the
 
492
                flags BTR_INSERT, BTR_DELETE, or BTR_DELETE_MARK. */
 
493
                ut_error;
 
494
        case ROW_NOT_FOUND:
482
495
                fputs("InnoDB: error in sec index entry del undo in\n"
483
496
                      "InnoDB: ", stderr);
484
497
                dict_index_name_print(stderr, trx, index);
493
506
                fputs("\n"
494
507
                      "InnoDB: Submit a detailed bug report"
495
508
                      " to http://bugs.mysql.com\n", stderr);
496
 
        } else {
497
 
                btr_cur_t*      btr_cur = btr_pcur_get_btr_cur(&pcur);
498
 
 
 
509
                break;
 
510
        case ROW_FOUND:
 
511
                btr_cur = btr_pcur_get_btr_cur(&pcur);
499
512
                err = btr_cur_del_mark_set_sec_rec(BTR_NO_LOCKING_FLAG,
500
513
                                                   btr_cur, FALSE, thr, &mtr);
501
514
                ut_a(err == DB_SUCCESS);
669
682
                        /* Build the newest version of the index entry */
670
683
                        entry = row_build_index_entry(node->row, node->ext,
671
684
                                                      index, heap);
672
 
                        if (UNIV_UNLIKELY(!entry)) {
673
 
                                /* The server must have crashed in
674
 
                                row_upd_clust_rec_by_insert(), in
675
 
                                row_ins_index_entry_low() before
676
 
                                btr_store_big_rec_extern_fields()
677
 
                                has written the externally stored columns
678
 
                                (BLOBs) of the new clustered index entry. */
679
 
 
680
 
                                /* The table must be in DYNAMIC or COMPRESSED
681
 
                                format.  REDUNDANT and COMPACT formats
682
 
                                store a local 768-byte prefix of each
683
 
                                externally stored column. */
684
 
                                ut_a(dict_table_get_format(index->table)
685
 
                                     >= DICT_TF_FORMAT_ZIP);
686
 
 
687
 
                                /* This is only legitimate when
688
 
                                rolling back an incomplete transaction
689
 
                                after crash recovery. */
690
 
                                ut_a(thr_get_trx(thr)->is_recovered);
691
 
 
692
 
                                /* The server must have crashed before
693
 
                                completing the insert of the new
694
 
                                clustered index entry and before
695
 
                                inserting to the secondary indexes.
696
 
                                Because node->row was not yet written
697
 
                                to this index, we can ignore it.  But
698
 
                                we must restore node->undo_row. */
699
 
                        } else {
700
 
                                /* NOTE that if we updated the fields of a
701
 
                                delete-marked secondary index record so that
702
 
                                alphabetically they stayed the same, e.g.,
703
 
                                'abc' -> 'aBc', we cannot return to the
704
 
                                original values because we do not know them.
705
 
                                But this should not cause problems because
706
 
                                in row0sel.c, in queries we always retrieve
707
 
                                the clustered index record or an earlier
708
 
                                version of it, if the secondary index record
709
 
                                through which we do the search is
710
 
                                delete-marked. */
711
 
 
712
 
                                err = row_undo_mod_del_mark_or_remove_sec(
713
 
                                        node, thr, index, entry);
714
 
                                if (err != DB_SUCCESS) {
715
 
                                        mem_heap_free(heap);
716
 
 
717
 
                                        return(err);
718
 
                                }
719
 
 
720
 
                                mem_heap_empty(heap);
 
685
                        ut_a(entry);
 
686
                        /* NOTE that if we updated the fields of a
 
687
                        delete-marked secondary index record so that
 
688
                        alphabetically they stayed the same, e.g.,
 
689
                        'abc' -> 'aBc', we cannot return to the original
 
690
                        values because we do not know them. But this should
 
691
                        not cause problems because in row0sel.c, in queries
 
692
                        we always retrieve the clustered index record or an
 
693
                        earlier version of it, if the secondary index record
 
694
                        through which we do the search is delete-marked. */
 
695
 
 
696
                        err = row_undo_mod_del_mark_or_remove_sec(node, thr,
 
697
                                                                  index,
 
698
                                                                  entry);
 
699
                        if (err != DB_SUCCESS) {
 
700
                                mem_heap_free(heap);
 
701
 
 
702
                                return(err);
721
703
                        }
722
704
 
723
705
                        /* We may have to update the delete mark in the
726
708
                        the secondary index record if we updated its fields
727
709
                        but alphabetically they stayed the same, e.g.,
728
710
                        'abc' -> 'aBc'. */
 
711
                        mem_heap_empty(heap);
729
712
                        entry = row_build_index_entry(node->undo_row,
730
713
                                                      node->undo_ext,
731
714
                                                      index, heap);