diff options
Diffstat (limited to 'storage/innobase/row/row0mysql.cc')
-rw-r--r-- | storage/innobase/row/row0mysql.cc | 176 |
1 files changed, 76 insertions, 100 deletions
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 2717d39b4c0..6184bcddcb5 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 2000, 2014, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2000, 2015, Oracle and/or its affiliates. All Rights Reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -610,6 +610,7 @@ handle_new_error: case DB_DUPLICATE_KEY: case DB_FOREIGN_DUPLICATE_KEY: case DB_TOO_BIG_RECORD: + case DB_TOO_BIG_FOR_REDO: case DB_UNDO_RECORD_TOO_BIG: case DB_ROW_IS_REFERENCED: case DB_NO_REFERENCED_ROW: @@ -1324,18 +1325,14 @@ row_insert_for_mysql( mem_analyze_corruption(prebuilt); ut_error; - } else if (srv_created_new_raw || srv_force_recovery) { - fputs("InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" + } else if (srv_force_recovery) { + fputs("InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" "InnoDB: mysqld and edit my.cnf so that" - " newraw is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", + "InnoDB: innodb_force_... is removed.\n", stderr); - if(srv_force_recovery) { - return(DB_READ_ONLY); - } - return(DB_ERROR); + + return(DB_READ_ONLY); } trx->op_info = "inserting"; @@ -1460,6 +1457,11 @@ error_exit: with a latch. */ dict_table_n_rows_inc(table); + if (prebuilt->clust_index_was_generated) { + /* set row id to prebuilt */ + ut_memcpy(prebuilt->row_id, node->row_id_buf, DATA_ROW_ID_LEN); + } + row_update_statistics_if_needed(table); trx->op_info = ""; @@ -1721,18 +1723,14 @@ row_update_for_mysql( ut_error; } - if (UNIV_UNLIKELY(srv_created_new_raw || srv_force_recovery)) { - fputs("InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" + if (UNIV_UNLIKELY(srv_force_recovery)) { + fputs("InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw" - " is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", + "InnoDB: mysqld and edit my.cnf so that" + "InnoDB: innodb_force_... is removed.\n", stderr); - if(srv_force_recovery) { - return(DB_READ_ONLY); - } - return(DB_ERROR); + + return(DB_READ_ONLY); } DEBUG_SYNC_C("innodb_row_update_for_mysql_begin"); @@ -2231,22 +2229,6 @@ row_create_table_for_mysql( goto err_exit; ); - if (srv_created_new_raw) { - fputs("InnoDB: A new raw disk partition was initialized:\n" - "InnoDB: we do not allow database modifications" - " by the user.\n" - "InnoDB: Shut down mysqld and edit my.cnf so that newraw" - " is replaced with raw.\n", stderr); -err_exit: - dict_mem_table_free(table); - - if (commit) { - trx_commit_for_mysql(trx); - } - - return(DB_ERROR); - } - trx->op_info = "creating table"; if (row_mysql_is_system_table(table->name)) { @@ -2257,7 +2239,19 @@ err_exit: "InnoDB: MySQL system tables must be" " of the MyISAM type!\n", table->name); - goto err_exit; + +#ifndef DBUG_OFF +err_exit: +#endif /* !DBUG_OFF */ + dict_mem_table_free(table); + + if (commit) { + trx_commit_for_mysql(trx); + } + + trx->op_info = ""; + + return(DB_ERROR); } trx_start_if_not_started_xa(trx); @@ -3307,16 +3301,6 @@ row_truncate_table_for_mysql( ut_ad(table); - if (srv_created_new_raw) { - fputs("InnoDB: A new raw disk partition was initialized:\n" - "InnoDB: we do not allow database modifications" - " by the user.\n" - "InnoDB: Shut down mysqld and edit my.cnf so that newraw" - " is replaced with raw.\n", stderr); - - return(DB_ERROR); - } - if (dict_table_is_discarded(table)) { return(DB_TABLESPACE_DELETED); } else if (table->ibd_file_missing) { @@ -3438,13 +3422,11 @@ row_truncate_table_for_mysql( goto funct_exit; } - if (table->space && !table->dir_path_of_temp_table) { + if (table->space && !DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) { /* Discard and create the single-table tablespace. */ ulint space = table->space; ulint flags = fil_space_get_flags(space); - ut_a(!DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)); - dict_get_and_save_data_dir_path(table, true); if (flags != ULINT_UNDEFINED @@ -3798,16 +3780,6 @@ row_drop_table_for_mysql( ut_a(name != NULL); - if (srv_created_new_raw) { - fputs("InnoDB: A new raw disk partition was initialized:\n" - "InnoDB: we do not allow database modifications" - " by the user.\n" - "InnoDB: Shut down mysqld and edit my.cnf so that newraw" - " is replaced with raw.\n", stderr); - - DBUG_RETURN(DB_ERROR); - } - /* The table name is prefixed with the database name and a '/'. Certain table names starting with 'innodb_' have their special meaning regardless of the database name. Thus, we need to @@ -4244,8 +4216,9 @@ row_drop_table_for_mysql( is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY); /* If there is a temp path then the temp flag is set. - However, during recovery, we might have a temp flag but - not know the temp path */ + However, during recovery or reloading the table object + after eviction from data dictionary cache, we might + have a temp flag but not know the temp path */ ut_a(table->dir_path_of_temp_table == NULL || is_temp); if (dict_table_is_discarded(table) || table->ibd_file_missing) { @@ -4373,7 +4346,7 @@ row_drop_table_for_mysql( case DB_OUT_OF_FILE_SPACE: err = DB_MUST_GET_MORE_FILE_SPACE; - + trx->error_state = err; row_mysql_handle_errors(&err, trx, NULL, NULL); /* raise error */ @@ -4813,24 +4786,22 @@ row_rename_table_for_mysql( ibool old_is_tmp, new_is_tmp; pars_info_t* info = NULL; int retry; + bool aux_fts_rename = false; ut_a(old_name != NULL); ut_a(new_name != NULL); ut_ad(trx->state == TRX_STATE_ACTIVE); - if (srv_created_new_raw || srv_force_recovery) { - fputs("InnoDB: A new raw disk partition was initialized or\n" - "InnoDB: innodb_force_recovery is on: we do not allow\n" + if (srv_force_recovery) { + fputs("InnoDB: innodb_force_recovery is on: we do not allow\n" "InnoDB: database modifications by the user. Shut down\n" - "InnoDB: mysqld and edit my.cnf so that newraw" - " is replaced\n" - "InnoDB: with raw, and innodb_force_... is removed.\n", + "InnoDB: mysqld and edit my.cnf so that" + "InnoDB: innodb_force_... is removed.\n", stderr); - if(srv_force_recovery) { - err = DB_READ_ONLY; - } + err = DB_READ_ONLY; goto funct_exit; + } else if (row_mysql_is_system_table(new_name)) { fprintf(stderr, @@ -5099,34 +5070,8 @@ row_rename_table_for_mysql( if (dict_table_has_fts_index(table) && !dict_tables_have_same_db(old_name, new_name)) { err = fts_rename_aux_tables(table, new_name, trx); - - if (err != DB_SUCCESS && (table->space != 0)) { - char* orig_name = table->name; - trx_t* trx_bg = trx_allocate_for_background(); - - /* If the first fts_rename fails, the trx would - be rolled back and committed, we can't use it any more, - so we have to start a new background trx here. */ - ut_a(trx_state_eq(trx, TRX_STATE_NOT_STARTED)); - trx_bg->op_info = "Revert the failing rename " - "for fts aux tables"; - trx_bg->dict_operation_lock_mode = RW_X_LATCH; - trx_start_for_ddl(trx_bg, TRX_DICT_OP_TABLE); - - /* If rename fails and table has its own tablespace, - we need to call fts_rename_aux_tables again to - revert the ibd file rename, which is not under the - control of trx. Also notice the parent table name - in cache is not changed yet. If the reverting fails, - the ibd data may be left in the new database, which - can be fixed only manually. */ - table->name = const_cast<char*>(new_name); - fts_rename_aux_tables(table, old_name, trx_bg); - table->name = orig_name; - - trx_bg->dict_operation_lock_mode = 0; - trx_commit_for_mysql(trx_bg); - trx_free_for_background(trx_bg); + if (err != DB_TABLE_NOT_FOUND) { + aux_fts_rename = true; } } @@ -5239,6 +5184,37 @@ end: } funct_exit: + if (aux_fts_rename && err != DB_SUCCESS + && table != NULL && (table->space != 0)) { + + char* orig_name = table->name; + trx_t* trx_bg = trx_allocate_for_background(); + + /* If the first fts_rename fails, the trx would + be rolled back and committed, we can't use it any more, + so we have to start a new background trx here. */ + ut_a(trx_state_eq(trx_bg, TRX_STATE_NOT_STARTED)); + trx_bg->op_info = "Revert the failing rename " + "for fts aux tables"; + trx_bg->dict_operation_lock_mode = RW_X_LATCH; + trx_start_for_ddl(trx_bg, TRX_DICT_OP_TABLE); + + /* If rename fails and table has its own tablespace, + we need to call fts_rename_aux_tables again to + revert the ibd file rename, which is not under the + control of trx. Also notice the parent table name + in cache is not changed yet. If the reverting fails, + the ibd data may be left in the new database, which + can be fixed only manually. */ + table->name = const_cast<char*>(new_name); + fts_rename_aux_tables(table, old_name, trx_bg); + table->name = orig_name; + + trx_bg->dict_operation_lock_mode = 0; + trx_commit_for_mysql(trx_bg); + trx_free_for_background(trx_bg); + } + if (table != NULL) { dict_table_close(table, dict_locked, FALSE); } |