~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/trx/trx0roll.c

Replacing all bzero() calls with memset() calls and removing the bzero.c file.
Also removing check for bzero from the 'configure.ac' autoconf file.

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#define TRX_ROLL_TRUNC_THRESHOLD        1
32
32
 
33
33
/* In crash recovery, the current trx to be rolled back */
34
 
static trx_t*           trx_roll_crash_recv_trx = NULL;
 
34
trx_t*          trx_roll_crash_recv_trx = NULL;
35
35
 
36
36
/* In crash recovery we set this to the undo n:o of the current trx to be
37
37
rolled back. Then we can print how many % the rollback has progressed. */
38
 
static ib_int64_t       trx_roll_max_undo_no;
 
38
ib_longlong     trx_roll_max_undo_no;
39
39
 
40
40
/* Auxiliary variable which tells the previous progress % we printed */
41
 
static ulint            trx_roll_progress_printed_pct;
 
41
ulint           trx_roll_progress_printed_pct;
42
42
 
43
43
/***********************************************************************
44
44
Rollback a transaction used in MySQL. */
45
 
UNIV_INTERN
 
45
 
46
46
int
47
47
trx_general_rollback_for_mysql(
48
48
/*===========================*/
115
115
 
116
116
/***********************************************************************
117
117
Rollback a transaction used in MySQL. */
118
 
UNIV_INTERN
 
118
 
119
119
int
120
120
trx_rollback_for_mysql(
121
121
/*===================*/
135
135
        the transaction object does not have an InnoDB session object, and we
136
136
        set a dummy session that we use for all MySQL transactions. */
137
137
 
 
138
        mutex_enter(&kernel_mutex);
 
139
 
 
140
        if (trx->sess == NULL) {
 
141
                /* Open a dummy session */
 
142
 
 
143
                if (!trx_dummy_sess) {
 
144
                        trx_dummy_sess = sess_open();
 
145
                }
 
146
 
 
147
                trx->sess = trx_dummy_sess;
 
148
        }
 
149
 
 
150
        mutex_exit(&kernel_mutex);
 
151
 
138
152
        err = trx_general_rollback_for_mysql(trx, FALSE, NULL);
139
 
 
 
153
        
140
154
        trx->op_info = "";
141
155
 
142
156
        return(err);
144
158
 
145
159
/***********************************************************************
146
160
Rollback the latest SQL statement for MySQL. */
147
 
UNIV_INTERN
 
161
 
148
162
int
149
163
trx_rollback_last_sql_stat_for_mysql(
150
164
/*=================================*/
172
186
 
173
187
/***********************************************************************
174
188
Frees savepoint structs. */
175
 
UNIV_INTERN
 
189
 
176
190
void
177
191
trx_roll_savepoints_free(
178
192
/*=====================*/
207
221
row holds a lock where the lock information is carried by the trx id stored in
208
222
the row, these locks are naturally released in the rollback. Savepoints which
209
223
were set after this savepoint are deleted. */
210
 
UNIV_INTERN
 
224
 
211
225
ulint
212
226
trx_rollback_to_savepoint_for_mysql(
213
227
/*================================*/
217
231
                                                otherwise DB_SUCCESS */
218
232
        trx_t*          trx,                    /* in: transaction handle */
219
233
        const char*     savepoint_name,         /* in: savepoint name */
220
 
        ib_int64_t*     mysql_binlog_cache_pos) /* out: the MySQL binlog cache
 
234
        ib_longlong*    mysql_binlog_cache_pos) /* out: the MySQL binlog cache
221
235
                                                position corresponding to this
222
236
                                                savepoint; MySQL needs this
223
237
                                                information to remove the
275
289
If there is already a savepoint of the same name, this call erases that old
276
290
savepoint and replaces it with a new. Savepoints are deleted in a transaction
277
291
commit or rollback. */
278
 
UNIV_INTERN
 
292
 
279
293
ulint
280
294
trx_savepoint_for_mysql(
281
295
/*====================*/
282
296
                                                /* out: always DB_SUCCESS */
283
297
        trx_t*          trx,                    /* in: transaction handle */
284
298
        const char*     savepoint_name,         /* in: savepoint name */
285
 
        ib_int64_t      binlog_cache_pos)       /* in: MySQL binlog cache
 
299
        ib_longlong     binlog_cache_pos)       /* in: MySQL binlog cache
286
300
                                                position corresponding to this
287
301
                                                connection at the time of the
288
302
                                                savepoint */
331
345
/***********************************************************************
332
346
Releases a named savepoint. Savepoints which
333
347
were set after this savepoint are deleted. */
334
 
UNIV_INTERN
 
348
 
335
349
ulint
336
350
trx_release_savepoint_for_mysql(
337
351
/*============================*/
375
389
 
376
390
/***********************************************************************
377
391
Returns a transaction savepoint taken at this point in time. */
378
 
UNIV_INTERN
 
392
 
379
393
trx_savept_t
380
394
trx_savept_take(
381
395
/*============*/
390
404
}
391
405
 
392
406
/***********************************************************************
393
 
Roll back an active transaction. */
394
 
static
395
 
void
396
 
trx_rollback_active(
397
 
/*================*/
398
 
        trx_t*  trx)    /* in/out: transaction */
 
407
Rollback or clean up transactions which have no user session. If the
 
408
transaction already was committed, then we clean up a possible insert
 
409
undo log. If the transaction was not yet committed, then we roll it back.
 
410
Note: this is done in a background thread. */
 
411
 
 
412
os_thread_ret_t
 
413
trx_rollback_or_clean_all_without_sess(
 
414
/*===================================*/
 
415
                        /* out: a dummy parameter */
 
416
        void*   arg __attribute__((unused)))
 
417
                        /* in: a dummy parameter required by
 
418
                        os_thread_create */
399
419
{
400
420
        mem_heap_t*     heap;
401
421
        que_fork_t*     fork;
402
422
        que_thr_t*      thr;
403
423
        roll_node_t*    roll_node;
 
424
        trx_t*          trx;
404
425
        dict_table_t*   table;
405
 
        ib_int64_t      rows_to_undo;
 
426
        ib_longlong     rows_to_undo;
406
427
        const char*     unit            = "";
407
 
        ibool           dictionary_locked = FALSE;
408
 
 
 
428
        int             err;
 
429
 
 
430
        mutex_enter(&kernel_mutex);
 
431
 
 
432
        /* Open a dummy session */
 
433
 
 
434
        if (!trx_dummy_sess) {
 
435
                trx_dummy_sess = sess_open();
 
436
        }
 
437
 
 
438
        mutex_exit(&kernel_mutex);
 
439
 
 
440
        if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
 
441
 
 
442
                fprintf(stderr,
 
443
                        "InnoDB: Starting in background the rollback"
 
444
                        " of uncommitted transactions\n");
 
445
        } else {
 
446
                goto leave_function;
 
447
        }
 
448
loop:
409
449
        heap = mem_heap_create(512);
410
450
 
 
451
        mutex_enter(&kernel_mutex);
 
452
 
 
453
        trx = UT_LIST_GET_FIRST(trx_sys->trx_list);
 
454
 
 
455
        while (trx) {
 
456
                if ((trx->sess || (trx->conc_state == TRX_NOT_STARTED))) {
 
457
                        trx = UT_LIST_GET_NEXT(trx_list, trx);
 
458
                } else if (trx->conc_state == TRX_PREPARED) {
 
459
 
 
460
                        trx->sess = trx_dummy_sess;
 
461
                        trx = UT_LIST_GET_NEXT(trx_list, trx);
 
462
                } else {
 
463
                        break;
 
464
                }
 
465
        }
 
466
 
 
467
        mutex_exit(&kernel_mutex);
 
468
 
 
469
        if (trx == NULL) {
 
470
                ut_print_timestamp(stderr);
 
471
                fprintf(stderr,
 
472
                        "  InnoDB: Rollback of non-prepared transactions"
 
473
                        " completed\n");
 
474
 
 
475
                mem_heap_free(heap);
 
476
 
 
477
                goto leave_function;
 
478
        }
 
479
 
 
480
        trx->sess = trx_dummy_sess;
 
481
 
 
482
        if (trx->conc_state == TRX_COMMITTED_IN_MEMORY) {
 
483
                fprintf(stderr, "InnoDB: Cleaning up trx with id %lu %lu\n",
 
484
                        (ulong) ut_dulint_get_high(trx->id),
 
485
                        (ulong) ut_dulint_get_low(trx->id));
 
486
 
 
487
                trx_cleanup_at_db_startup(trx);
 
488
 
 
489
                mem_heap_free(heap);
 
490
 
 
491
                goto loop;
 
492
        }
 
493
 
411
494
        fork = que_fork_create(NULL, NULL, QUE_FORK_RECOVERY, heap);
412
495
        fork->trx = trx;
413
496
 
436
519
 
437
520
        ut_print_timestamp(stderr);
438
521
        fprintf(stderr,
439
 
                "  InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s"
 
522
                "  InnoDB: Rolling back trx with id %lu %lu, %lu%s"
440
523
                " rows to undo\n",
441
 
                TRX_ID_PREP_PRINTF(trx->id),
 
524
                (ulong) ut_dulint_get_high(trx->id),
 
525
                (ulong) ut_dulint_get_low(trx->id),
442
526
                (ulong) rows_to_undo, unit);
443
527
        mutex_exit(&kernel_mutex);
444
528
 
446
530
 
447
531
        trx->mysql_process_no = os_proc_get_number();
448
532
 
449
 
        if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
 
533
        if (trx->dict_operation) {
450
534
                row_mysql_lock_data_dictionary(trx);
451
 
                dictionary_locked = TRUE;
452
535
        }
453
536
 
454
537
        que_run_threads(thr);
469
552
 
470
553
        mutex_exit(&kernel_mutex);
471
554
 
472
 
        if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE
473
 
            && !ut_dulint_is_zero(trx->table_id)) {
474
 
 
 
555
        if (trx->dict_operation) {
475
556
                /* If the transaction was for a dictionary operation, we
476
557
                drop the relevant table, if it still exists */
477
558
 
484
565
                table = dict_table_get_on_id_low(trx->table_id);
485
566
 
486
567
                if (table) {
487
 
                        ulint   err;
488
 
 
489
568
                        fputs("InnoDB: Table found: dropping table ", stderr);
490
569
                        ut_print_name(stderr, trx, TRUE, table->name);
491
570
                        fputs(" in recovery\n", stderr);
496
575
                }
497
576
        }
498
577
 
499
 
        if (dictionary_locked) {
 
578
        if (trx->dict_operation) {
500
579
                row_mysql_unlock_data_dictionary(trx);
501
580
        }
502
581
 
503
 
        fprintf(stderr, "\nInnoDB: Rolling back of trx id " TRX_ID_FMT
504
 
                " completed\n",
505
 
                TRX_ID_PREP_PRINTF(trx->id));
 
582
        fprintf(stderr, "\nInnoDB: Rolling back of trx id %lu %lu completed\n",
 
583
                (ulong) ut_dulint_get_high(trx->id),
 
584
                (ulong) ut_dulint_get_low(trx->id));
506
585
        mem_heap_free(heap);
507
586
 
508
587
        trx_roll_crash_recv_trx = NULL;
509
 
}
510
 
 
511
 
/***********************************************************************
512
 
Rollback or clean up any incomplete transactions which were
513
 
encountered in crash recovery.  If the transaction already was
514
 
committed, then we clean up a possible insert undo log. If the
515
 
transaction was not yet committed, then we roll it back.
516
 
Note: this is done in a background thread. */
517
 
UNIV_INTERN
518
 
os_thread_ret_t
519
 
trx_rollback_or_clean_all_recovered(
520
 
/*================================*/
521
 
                        /* out: a dummy parameter */
522
 
        void*   arg __attribute__((unused)))
523
 
                        /* in: a dummy parameter required by
524
 
                        os_thread_create */
525
 
{
526
 
        trx_t*  trx;
527
 
 
528
 
        mutex_enter(&kernel_mutex);
529
 
 
530
 
        if (UT_LIST_GET_FIRST(trx_sys->trx_list)) {
531
 
 
532
 
                fprintf(stderr,
533
 
                        "InnoDB: Starting in background the rollback"
534
 
                        " of uncommitted transactions\n");
535
 
        } else {
536
 
                goto leave_function;
537
 
        }
538
 
 
539
 
        mutex_exit(&kernel_mutex);
540
 
 
541
 
loop:
542
 
        mutex_enter(&kernel_mutex);
543
 
 
544
 
        for (trx = UT_LIST_GET_FIRST(trx_sys->trx_list); trx;
545
 
             trx = UT_LIST_GET_NEXT(trx_list, trx)) {
546
 
                if (!trx->is_recovered) {
547
 
                        continue;
548
 
                }
549
 
 
550
 
                switch (trx->conc_state) {
551
 
                case TRX_NOT_STARTED:
552
 
                case TRX_PREPARED:
553
 
                        continue;
554
 
 
555
 
                case TRX_COMMITTED_IN_MEMORY:
556
 
                        mutex_exit(&kernel_mutex);
557
 
                        fprintf(stderr,
558
 
                                "InnoDB: Cleaning up trx with id "
559
 
                                TRX_ID_FMT "\n",
560
 
                                TRX_ID_PREP_PRINTF(trx->id));
561
 
                        trx_cleanup_at_db_startup(trx);
562
 
                        goto loop;
563
 
 
564
 
                case TRX_ACTIVE:
565
 
                        mutex_exit(&kernel_mutex);
566
 
                        trx_rollback_active(trx);
567
 
                        goto loop;
568
 
                }
569
 
        }
570
 
 
571
 
        ut_print_timestamp(stderr);
572
 
        fprintf(stderr,
573
 
                "  InnoDB: Rollback of non-prepared transactions completed\n");
 
588
 
 
589
        goto loop;
574
590
 
575
591
leave_function:
576
 
        mutex_exit(&kernel_mutex);
577
 
 
578
592
        /* We count the number of threads in os_thread_exit(). A created
579
593
        thread should always use that to exit and not use return() to exit. */
580
594
 
585
599
 
586
600
/***********************************************************************
587
601
Creates an undo number array. */
588
 
UNIV_INTERN
 
602
 
589
603
trx_undo_arr_t*
590
604
trx_undo_arr_create(void)
591
605
/*=====================*/
615
629
 
616
630
/***********************************************************************
617
631
Frees an undo number array. */
618
 
UNIV_INTERN
 
632
 
619
633
void
620
634
trx_undo_arr_free(
621
635
/*==============*/
761
775
 
762
776
/***************************************************************************
763
777
Tries truncate the undo logs. */
764
 
UNIV_INTERN
 
778
 
765
779
void
766
780
trx_roll_try_truncate(
767
781
/*==================*/
817
831
 
818
832
        ut_ad(mutex_own(&(trx->undo_mutex)));
819
833
 
820
 
        undo_page = trx_undo_page_get_s_latched(undo->space, undo->zip_size,
 
834
        undo_page = trx_undo_page_get_s_latched(undo->space,
821
835
                                                undo->top_page_no, mtr);
822
836
        offset = undo->top_offset;
823
837
 
832
846
 
833
847
                undo->empty = TRUE;
834
848
        } else {
835
 
                prev_rec_page = page_align(prev_rec);
 
849
                prev_rec_page = buf_frame_align(prev_rec);
836
850
 
837
851
                if (prev_rec_page != undo_page) {
838
852
 
839
853
                        trx->pages_undone++;
840
854
                }
841
855
 
842
 
                undo->top_page_no = page_get_page_no(prev_rec_page);
 
856
                undo->top_page_no = buf_frame_get_page_no(prev_rec_page);
843
857
                undo->top_offset  = prev_rec - prev_rec_page;
844
858
                undo->top_undo_no = trx_undo_rec_get_undo_no(prev_rec);
845
859
        }
853
867
undo number of the popped undo record to the array of currently processed
854
868
undo numbers in the transaction. When the query thread finishes processing
855
869
of this undo record, it must be released with trx_undo_rec_release. */
856
 
UNIV_INTERN
 
870
 
857
871
trx_undo_rec_t*
858
872
trx_roll_pop_top_rec_of_trx(
859
873
/*========================*/
984
998
Reserves an undo log record for a query thread to undo. This should be
985
999
called if the query thread gets the undo log record not using the pop
986
1000
function above. */
987
 
UNIV_INTERN
 
1001
 
988
1002
ibool
989
1003
trx_undo_rec_reserve(
990
1004
/*=================*/
1005
1019
 
1006
1020
/***********************************************************************
1007
1021
Releases a reserved undo record. */
1008
 
UNIV_INTERN
 
1022
 
1009
1023
void
1010
1024
trx_undo_rec_release(
1011
1025
/*=================*/
1025
1039
 
1026
1040
/*************************************************************************
1027
1041
Starts a rollback operation. */
1028
 
UNIV_INTERN
 
1042
 
1029
1043
void
1030
1044
trx_rollback(
1031
1045
/*=========*/
1099
1113
performed by executing this query graph like a query subprocedure call.
1100
1114
The reply about the completion of the rollback will be sent by this
1101
1115
graph. */
1102
 
UNIV_INTERN
 
1116
 
1103
1117
que_t*
1104
1118
trx_roll_graph_build(
1105
1119
/*=================*/
1186
1200
 
1187
1201
/********************************************************************
1188
1202
Finishes a transaction rollback. */
1189
 
UNIV_INTERN
 
1203
 
1190
1204
void
1191
1205
trx_finish_rollback_off_kernel(
1192
1206
/*===========================*/
1254
1268
 
1255
1269
/*************************************************************************
1256
1270
Creates a rollback command node struct. */
1257
 
UNIV_INTERN
 
1271
 
1258
1272
roll_node_t*
1259
1273
roll_node_create(
1260
1274
/*=============*/
1274
1288
 
1275
1289
/***************************************************************
1276
1290
Performs an execution step for a rollback command node in a query graph. */
1277
 
UNIV_INTERN
 
1291
 
1278
1292
que_thr_t*
1279
1293
trx_rollback_step(
1280
1294
/*==============*/