trx_t* trx_allocate_for_mysql(void) /*========================*/ /* out, own: transaction object */ { trx_t* trx; mutex_enter(&kernel_mutex); /* Open a dummy session */ if (!trx_dummy_sess) { trx_dummy_sess = sess_open(); } trx = trx_create(trx_dummy_sess); trx_n_mysql_transactions++; UT_LIST_ADD_FIRST(mysql_trx_list, trx_sys->mysql_trx_list, trx); mutex_exit(&kernel_mutex); trx->mysql_thread_id = os_thread_get_curr_id(); trx->mysql_process_no = os_proc_get_number(); return(trx); }
/**********************************************************//** Prints a timestamp to a file. */ UNIV_INTERN void ut_print_timestamp( /*===============*/ FILE* file) /*!< in: file where to print */ { ulint proc_number = os_proc_get_number(); #ifdef __WIN__ SYSTEMTIME cal_tm; GetLocalTime(&cal_tm); fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %lu", (int)cal_tm.wYear, (int)cal_tm.wMonth, (int)cal_tm.wDay, (int)cal_tm.wHour, (int)cal_tm.wMinute, (int)cal_tm.wSecond, proc_number); #else #ifdef HAVE_LOCALTIME_R struct tm cal_tm; #endif struct tm* cal_tm_ptr; time_t tm; time(&tm); #ifdef HAVE_LOCALTIME_R localtime_r(&tm, &cal_tm); cal_tm_ptr = &cal_tm; #else cal_tm_ptr = localtime(&tm); #endif fprintf(file, "%d-%02d-%02d %02d:%02d:%02d %lu", cal_tm_ptr->tm_year + 1900, cal_tm_ptr->tm_mon + 1, cal_tm_ptr->tm_mday, cal_tm_ptr->tm_hour, cal_tm_ptr->tm_min, cal_tm_ptr->tm_sec, proc_number); #endif }
/********************************************************************//** Creates a transaction object for MySQL. @return own: transaction object */ UNIV_INTERN trx_t* trx_allocate_for_mysql(void) /*========================*/ { trx_t* trx; mutex_enter(&kernel_mutex); trx = trx_create(trx_dummy_sess); trx_n_mysql_transactions++; UT_LIST_ADD_FIRST(mysql_trx_list, trx_sys->mysql_trx_list, trx); mutex_exit(&kernel_mutex); trx->mysql_thread_id = os_thread_get_curr_id(); trx->mysql_process_no = os_proc_get_number(); return(trx); }
/*******************************************************************//** Roll back an active transaction. */ static void trx_rollback_active( /*================*/ trx_t* trx) /*!< in/out: transaction */ { mem_heap_t* heap; que_fork_t* fork; que_thr_t* thr; roll_node_t* roll_node; dict_table_t* table; ib_int64_t rows_to_undo; const char* unit = ""; ibool dictionary_locked = FALSE; heap = mem_heap_create(512); fork = que_fork_create(NULL, NULL, QUE_FORK_RECOVERY, heap); fork->trx = trx; thr = que_thr_create(fork, heap); roll_node = roll_node_create(heap); thr->child = roll_node; roll_node->common.parent = thr; mutex_enter(&kernel_mutex); trx->graph = fork; ut_a(thr == que_fork_start_command(fork)); trx_roll_crash_recv_trx = trx; trx_roll_max_undo_no = trx->undo_no; trx_roll_progress_printed_pct = 0; rows_to_undo = trx_roll_max_undo_no; if (rows_to_undo > 1000000000) { rows_to_undo = rows_to_undo / 1000000; unit = "M"; } ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: Rolling back trx with id " TRX_ID_FMT ", %lu%s" " rows to undo\n", (ullint) trx->id, (ulong) rows_to_undo, unit); mutex_exit(&kernel_mutex); trx->mysql_thread_id = os_thread_get_curr_id(); trx->mysql_process_no = os_proc_get_number(); if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) { row_mysql_lock_data_dictionary(trx); dictionary_locked = TRUE; } que_run_threads(thr); mutex_enter(&kernel_mutex); while (trx->que_state != TRX_QUE_RUNNING) { mutex_exit(&kernel_mutex); fprintf(stderr, "InnoDB: Waiting for rollback of trx id " TRX_ID_FMT " to end\n", (ullint) trx->id); os_thread_sleep(100000); mutex_enter(&kernel_mutex); } mutex_exit(&kernel_mutex); if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE && trx->table_id != 0) { /* If the transaction was for a dictionary operation, we drop the relevant table, if it still exists */ fprintf(stderr, "InnoDB: Dropping table with id %llu" " in recovery if it exists\n", (ullint) trx->table_id); table = dict_table_get_on_id_low(trx->table_id); if (table) { ulint err; fputs("InnoDB: Table found: dropping table ", stderr); ut_print_name(stderr, trx, TRUE, table->name); fputs(" in recovery\n", stderr); err = row_drop_table_for_mysql(table->name, trx, TRUE); trx_commit_for_mysql(trx); ut_a(err == (int) DB_SUCCESS); } } if (dictionary_locked) { row_mysql_unlock_data_dictionary(trx); } fprintf(stderr, "\nInnoDB: Rolling back of trx id " TRX_ID_FMT " completed\n", (ullint) trx->id); mem_heap_free(heap); trx_roll_crash_recv_trx = NULL; }