diff options
author | unknown <heikki@hundin.mysql.fi> | 2003-10-13 11:20:19 +0300 |
---|---|---|
committer | unknown <heikki@hundin.mysql.fi> | 2003-10-13 11:20:19 +0300 |
commit | d212ba604b22f8fad80489319a7ddc09d126ba67 (patch) | |
tree | 5d5b7191e57ae4eafdff3f6a259ba37729217404 /sql | |
parent | 1862f671606e086c68228903abb64d9727f95b72 (diff) | |
download | mariadb-git-d212ba604b22f8fad80489319a7ddc09d126ba67.tar.gz |
Many files:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
sql/ha_innodb.cc:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/sql_class.cc:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/sql_parse.cc:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/sql_table.cc:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/ha_innodb.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/handler.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/lex.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/mysql_priv.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/sql_class.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/sql_lex.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
sql/sql_yacc.yy:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/ha/ha0ha.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/ha/hash0hash.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/buf/buf0buf.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/buf/buf0flu.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/buf/buf0lru.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/buf/buf0rea.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/btr/btr0btr.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/btr/btr0sea.c:
Track crash in buf_LRU_block_remove_hashed_page + 1807 reported in MySQL-3.23.5x
innobase/fil/fil0fil.c:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/buf0buf.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/ha0ha.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/hash0hash.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/row0mysql.h:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/buf0buf.ic:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/ha0ha.ic:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/include/ibuf0ibuf.ic:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/page/page0page.c:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/row/row0mysql.c:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/row/row0purge.c:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/row/row0uins.c:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
innobase/row/row0umod.c:
ALTER TABLE ... DISCARD/IMPORT TABLESPACE
Diffstat (limited to 'sql')
-rw-r--r-- | sql/ha_innodb.cc | 51 | ||||
-rw-r--r-- | sql/ha_innodb.h | 1 | ||||
-rw-r--r-- | sql/handler.h | 1 | ||||
-rw-r--r-- | sql/lex.h | 3 | ||||
-rw-r--r-- | sql/mysql_priv.h | 1 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_lex.h | 6 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_table.cc | 77 | ||||
-rw-r--r-- | sql/sql_yacc.yy | 6 |
11 files changed, 140 insertions, 12 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index f1072c3137a..d07b166d9e2 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -1451,7 +1451,7 @@ ha_innobase::open( DBUG_RETURN(1); } - if (ib_table->ibd_file_missing) { + if (ib_table->ibd_file_missing && !current_thd->tablespace_op) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to open a table handle but the .ibd file for\n" @@ -3629,6 +3629,42 @@ ha_innobase::create( } /********************************************************************* +Discards or imports an InnoDB tablespace. */ + +int +ha_innobase::discard_or_import_tablespace( +/*======================================*/ + /* out: 0 == success, -1 == error */ + my_bool discard) /* in: TRUE if discard, else import */ +{ + row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt; + dict_table_t* table; + trx_t* trx; + int err; + + DBUG_ENTER("ha_innobase::discard_or_import_tablespace"); + + ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N); + ut_a(prebuilt->trx == + (trx_t*) current_thd->transaction.all.innobase_tid); + + table = prebuilt->table; + trx = prebuilt->trx; + + if (discard) { + err = row_discard_tablespace_for_mysql(table->name, trx); + } else { + err = row_import_tablespace_for_mysql(table->name, trx); + } + + if (err == DB_SUCCESS) { + DBUG_RETURN(0); + } + + DBUG_RETURN(-1); +} + +/********************************************************************* Drops a table from an InnoDB database. Before calling this function, MySQL calls innobase_commit to commit the transaction of the current user. Then the current user cannot have locks set on the table. Drop table @@ -3647,7 +3683,7 @@ ha_innobase::delete_table( trx_t* trx; char norm_name[1000]; - DBUG_ENTER("ha_innobase::delete_table"); + DBUG_ENTER("ha_innobase::delete_table"); /* Get the transaction associated with the current thd, or create one if not yet created */ @@ -4536,7 +4572,8 @@ ha_innobase::external_lock( update_thd(thd); - if (lock_type != F_UNLCK && prebuilt->table->ibd_file_missing) { + if (lock_type != F_UNLCK && prebuilt->table->ibd_file_missing + && !current_thd->tablespace_op) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB error:\n" "MySQL is trying to use a table handle but the .ibd file for\n" @@ -4546,6 +4583,7 @@ ha_innobase::external_lock( "Look from section 15.1 of http://www.innodb.com/ibman.html\n" "how you can resolve the problem.\n", prebuilt->table->name); + DBUG_RETURN(HA_ERR_CRASHED); } trx = prebuilt->trx; @@ -4793,11 +4831,12 @@ ha_innobase::store_lock( if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) { - /* If we are not doing a LOCK TABLE, then allow multiple - writers */ + /* If we are not doing a LOCK TABLE or DISCARD/IMPORT + TABLESPACE, then allow multiple writers */ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT && - lock_type <= TL_WRITE) && !thd->in_lock_tables) { + lock_type <= TL_WRITE) && !thd->in_lock_tables + && !thd->tablespace_op) { lock_type = TL_WRITE_ALLOW_WRITE; } diff --git a/sql/ha_innodb.h b/sql/ha_innodb.h index b17097b3c57..0c89a9d29ce 100644 --- a/sql/ha_innodb.h +++ b/sql/ha_innodb.h @@ -160,6 +160,7 @@ class ha_innobase: public handler void info(uint); int analyze(THD* thd,HA_CHECK_OPT* check_opt); int optimize(THD* thd,HA_CHECK_OPT* check_opt); + int discard_or_import_tablespace(my_bool discard); int extra(enum ha_extra_function operation); int reset(void); int external_lock(THD *thd, int lock_type); diff --git a/sql/handler.h b/sql/handler.h index b74e06c6edf..b756d9a09fb 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -317,6 +317,7 @@ public: virtual int dump(THD* thd, int fd = -1) { return ER_DUMP_NOT_IMPLEMENTED; } virtual void deactivate_non_unique_index(ha_rows rows) {} virtual bool activate_all_index(THD *thd) {return 0;} + virtual int discard_or_import_tablespace(my_bool discard) {return -1;} // not implemented by default virtual int net_read_dump(NET* net) { return ER_DUMP_NOT_IMPLEMENTED; } diff --git a/sql/lex.h b/sql/lex.h index e11b50ed16d..859f92dd752 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -130,6 +130,7 @@ static SYMBOL symbols[] = { { "DESCRIBE", SYM(DESCRIBE),0,0}, { "DIRECTORY", SYM(DIRECTORY_SYM),0,0}, { "DISABLE", SYM(DISABLE_SYM),0,0}, + { "DISCARD", SYM(DISCARD),0,0}, { "DISTINCT", SYM(DISTINCT),0,0}, { "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */ { "DIV", SYM(DIV_SYM),0,0}, @@ -200,6 +201,7 @@ static SYMBOL symbols[] = { { "INNER", SYM(INNER_SYM),0,0}, { "INNOBASE", SYM(INNOBASE_SYM),0,0}, { "INNODB", SYM(INNOBASE_SYM),0,0}, + { "IMPORT", SYM(IMPORT),0,0}, { "INSERT", SYM(INSERT),0,0}, { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, { "INT", SYM(INT_SYM),0,0}, @@ -387,6 +389,7 @@ static SYMBOL symbols[] = { { "SUPER", SYM(SUPER_SYM),0,0}, { "TABLE", SYM(TABLE_SYM),0,0}, { "TABLES", SYM(TABLES),0,0}, + { "TABLESPACE", SYM(TABLESPACE),0,0}, { "TEMPORARY", SYM(TEMPORARY),0,0}, { "TERMINATED", SYM(TERMINATED),0,0}, { "TEXT", SYM(TEXT_SYM),0,0}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index afbda2b4ad1..a1919bf1a0e 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -486,6 +486,7 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name, bool drop_primary, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS, + enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP, bool simple_alter=0); int mysql_create_like_table(THD *thd, TABLE_LIST *table, HA_CREATE_INFO *create_info, diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cdca7454698..c7d77c67236 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -173,6 +173,7 @@ THD::THD():user_time(0), is_fatal_error(0), protocol_simple.init(this); protocol_prep.init(this); + tablespace_op=FALSE; #ifdef USING_TRANSACTIONS bzero((char*) &transaction,sizeof(transaction)); if (opt_using_transactions) diff --git a/sql/sql_class.h b/sql/sql_class.h index 5e5d0335e9d..146ee18e3e2 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -502,6 +502,7 @@ public: time_t connect_time,thr_create_time; // track down slow pthread_create thr_lock_type update_lock_default; delayed_insert *di; + my_bool tablespace_op; /* This is TRUE in DISCARD/IMPORT TABLESPACE */ struct st_transactions { IO_CACHE trans_log; THD_TRANS all; // Trans since BEGIN WORK diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 8ce028020c2..0166951ab9d 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -110,6 +110,11 @@ enum olap_type UNSPECIFIED_OLAP_TYPE, CUBE_TYPE, ROLLUP_TYPE }; +enum tablespace_op_type +{ + NO_TABLESPACE_OP, DISCARD_TABLESPACE, IMPORT_TABLESPACE +}; + /* The state of the lex parsing for selects @@ -530,6 +535,7 @@ typedef struct st_lex enum ha_rkey_function ha_rkey_mode; enum enum_enable_or_disable alter_keys_onoff; enum enum_var_type option_type; + enum tablespace_op_type tablespace_op; uint uint_geom_type; uint grant, grant_tot_col, which_columns; uint fk_delete_opt, fk_update_opt, fk_match_option; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index e30fd0acfae..248dfc0e47a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2207,7 +2207,9 @@ mysql_execute_command(THD *thd) select_lex->order_list.elements, (ORDER *) select_lex->order_list.first, lex->drop_primary, lex->duplicates, - lex->alter_keys_onoff, lex->simple_alter); + lex->alter_keys_onoff, + lex->tablespace_op, + lex->simple_alter); } break; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 16afd592e59..3840e29f04a 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1748,6 +1748,70 @@ int mysql_check_table(THD* thd, TABLE_LIST* tables,HA_CHECK_OPT* check_opt) &handler::check)); } +/* table_list should contain just one table */ +int mysql_discard_or_import_tablespace(THD *thd, + TABLE_LIST *table_list, + enum tablespace_op_type tablespace_op) +{ + TABLE *table; + my_bool discard; + int error; + DBUG_ENTER("mysql_discard_or_import_tablespace"); + + /* Note that DISCARD/IMPORT TABLESPACE always is the only operation in an + ALTER TABLE */ + + thd->proc_info="discard_or_import_tablespace"; + + if (tablespace_op == DISCARD_TABLESPACE) + discard = TRUE; + else + discard = FALSE; + + thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open + and ::external_lock() do not complain when we + lock the table */ + mysql_ha_closeall(thd, table_list); + + if (!(table=open_ltable(thd,table_list,TL_WRITE))) + { + thd->tablespace_op=FALSE; + DBUG_RETURN(-1); + } + + thd->tablespace_op=FALSE; + + error=table->file->discard_or_import_tablespace(discard); + + thd->proc_info="end"; + + if (error) + goto err; + + /* The 0 in the call below means 'not in a transaction', which means + immediate invalidation; that is probably what we wish here */ + query_cache_invalidate3(thd, table_list, 0); + + /* The ALTER TABLE is always in its own transaction */ + error = ha_commit_stmt(thd); + if (ha_commit(thd)) + error=1; + if (error) + goto err; + mysql_update_log.write(thd, thd->query,thd->query_length); + if (mysql_bin_log.is_open()) + { + Query_log_event qinfo(thd, thd->query, thd->query_length, 0); + mysql_bin_log.write(&qinfo); + } +err: + close_thread_tables(thd); + if (error == 0) { + send_ok(thd); + DBUG_RETURN(0); + } + DBUG_RETURN(error); +} int mysql_alter_table(THD *thd,char *new_db, char *new_name, HA_CREATE_INFO *create_info, @@ -1759,6 +1823,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, bool drop_primary, enum enum_duplicates handle_duplicates, enum enum_enable_or_disable keys_onoff, + enum tablespace_op_type tablespace_op, bool simple_alter) { TABLE *table,*new_table; @@ -1771,6 +1836,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, ulonglong next_insert_id; uint save_time_stamp,db_create_options, used_fields; enum db_type old_db_type,new_db_type; + thr_lock_type lock_type; DBUG_ENTER("mysql_alter_table"); thd->proc_info="init"; @@ -1781,6 +1847,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, used_fields=create_info->used_fields; mysql_ha_closeall(thd, table_list); + + if (tablespace_op != NO_TABLESPACE_OP) + DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list, + tablespace_op)); if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); @@ -1834,8 +1904,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type=table->row_type; - /* In some simple cases we need not to recreate the table */ - thd->proc_info="setup"; if (simple_alter && !table->tmp_table) { @@ -1860,6 +1928,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, } VOID(pthread_mutex_unlock(&LOCK_open)); } + if (!error) { switch (keys_onoff) { @@ -2395,8 +2464,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } } - - /* The ALTER TABLE is always in it's own transaction */ + /* The ALTER TABLE is always in its own transaction */ error = ha_commit_stmt(thd); if (ha_commit(thd)) error=1; @@ -2695,4 +2763,3 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt) table->table=0; DBUG_RETURN(-1); } - diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 81a59196e3c..f917e4ec027 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -211,6 +211,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token DESCRIBE %token DES_KEY_FILE %token DISABLE_SYM +%token DISCARD %token DISTINCT %token DUPLICATE_SYM %token DYNAMIC_SYM @@ -244,6 +245,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token HOSTS_SYM %token IDENT %token IGNORE_SYM +%token IMPORT %token INDEX %token INDEXES %token INFILE @@ -360,6 +362,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SUBJECT_SYM %token TABLES %token TABLE_SYM +%token TABLESPACE %token TEMPORARY %token TERMINATED %token TEXT_STRING @@ -1635,6 +1638,7 @@ alter: lex->create_info.table_charset= thd->variables.collation_database; lex->create_info.row_type= ROW_TYPE_NOT_USED; lex->alter_keys_onoff=LEAVE_AS_IS; + lex->tablespace_op=NO_TABLESPACE_OP; lex->simple_alter=1; } alter_list @@ -1648,6 +1652,8 @@ alter: alter_list: + | DISCARD TABLESPACE { Lex->tablespace_op=DISCARD_TABLESPACE; } + | IMPORT TABLESPACE { Lex->tablespace_op=IMPORT_TABLESPACE; } | alter_list_item | alter_list ',' alter_list_item; |