summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
authorunknown <heikki@hundin.mysql.fi>2003-10-13 11:20:19 +0300
committerunknown <heikki@hundin.mysql.fi>2003-10-13 11:20:19 +0300
commitd212ba604b22f8fad80489319a7ddc09d126ba67 (patch)
tree5d5b7191e57ae4eafdff3f6a259ba37729217404 /sql
parent1862f671606e086c68228903abb64d9727f95b72 (diff)
downloadmariadb-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.cc51
-rw-r--r--sql/ha_innodb.h1
-rw-r--r--sql/handler.h1
-rw-r--r--sql/lex.h3
-rw-r--r--sql/mysql_priv.h1
-rw-r--r--sql/sql_class.cc1
-rw-r--r--sql/sql_class.h1
-rw-r--r--sql/sql_lex.h6
-rw-r--r--sql/sql_parse.cc4
-rw-r--r--sql/sql_table.cc77
-rw-r--r--sql/sql_yacc.yy6
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;