mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
ALTER TABLE ... DISABLE KEYS / ALTER TABLE ... ENABLE KEYS
This commit is contained in:
parent
8e882bcafa
commit
8b2a9517a6
9 changed files with 119 additions and 53 deletions
|
@ -19022,6 +19022,8 @@ alter_specification:
|
|||
or DROP [COLUMN] col_name
|
||||
or DROP PRIMARY KEY
|
||||
or DROP INDEX index_name
|
||||
or DISABLE KEYS
|
||||
or ENABLE KEYS
|
||||
or RENAME [TO] new_tbl_name
|
||||
or ORDER BY col
|
||||
or table_options
|
||||
|
@ -19183,6 +19185,15 @@ If you use @code{ALTER TABLE} on a @code{MyISAM} table, all non-unique
|
|||
indexes are created in a separate batch (like in @code{REPAIR}).
|
||||
This should make @code{ALTER TABLE} much faster when you have many indexes.
|
||||
|
||||
@item
|
||||
Since @strong{MySQL 4.0} this feature could be activated explicitly.
|
||||
@code{ALTER TABLE ... DISABLE KEYS} makes @strong{MySQL} to stop updating
|
||||
non-unique indexes for @code{MyISAM} table.
|
||||
@code{ALTER TABLE ... ENABLE KEYS} then should be used to recreate missing
|
||||
indexes. As @strong{MySQL} does it with special algorithm which is much
|
||||
faster then inserting keys one by one, disabling keys could give a
|
||||
considerable speedup on bulk inserts.
|
||||
|
||||
@item
|
||||
@findex mysql_info()
|
||||
With the C API function @code{mysql_info()}, you can find out how many
|
||||
|
@ -24645,14 +24656,11 @@ InnoDB: Database physically writes the file full: wait...
|
|||
InnoDB: Data file /home/heikki/data/ibdata2 did not exist: new to be created
|
||||
InnoDB: Setting file /home/heikki/data/ibdata2 size to 262144000
|
||||
InnoDB: Database physically writes the file full: wait...
|
||||
InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist: new to be c
|
||||
reated
|
||||
InnoDB: Log file /home/heikki/data/logs/ib_logfile0 did not exist: new to be created
|
||||
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile0 size to 5242880
|
||||
InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist: new to be c
|
||||
reated
|
||||
InnoDB: Log file /home/heikki/data/logs/ib_logfile1 did not exist: new to be created
|
||||
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile1 size to 5242880
|
||||
InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist: new to be c
|
||||
reated
|
||||
InnoDB: Log file /home/heikki/data/logs/ib_logfile2 did not exist: new to be created
|
||||
InnoDB: Setting log file /home/heikki/data/logs/ib_logfile2 size to 5242880
|
||||
InnoDB: Started
|
||||
mysqld: ready for connections
|
||||
|
@ -30936,8 +30944,13 @@ Execute a @code{FLUSH TABLES} statement or the shell command @code{mysqladmin
|
|||
flush-tables}.
|
||||
@end enumerate
|
||||
|
||||
This procedure will be built into @code{LOAD DATA INFILE} in some future
|
||||
version of @strong{MySQL}.
|
||||
Since @strong{MySQL 4.0} you can also use
|
||||
@code{ALTER TABLE tbl_name DISABLE KEYS} instead of
|
||||
@code{myisamchk --keys-used=0 -rq /path/to/db/tbl_name} and
|
||||
@code{ALTER TABLE tbl_name ENABLE KEYS} instead of
|
||||
@code{myisamchk -r -q /path/to/db/tbl_name}. This way you can also skip
|
||||
@code{FLUSH TABLES} steps.
|
||||
|
||||
@item
|
||||
You can speed up insertions by locking your tables:
|
||||
|
||||
|
@ -43868,6 +43881,9 @@ Our TODO section contains what we plan to have in 4.0. @xref{TODO MySQL 4.0}.
|
|||
|
||||
@itemize @bullet
|
||||
@item
|
||||
Added @code{ALTER TABLE table_name DISABLE KEYS} and
|
||||
@code{ALTER TABLE table_name ENABLE KEYS} commands.
|
||||
@item
|
||||
Added @code{HANDLER} command.
|
||||
@item
|
||||
Added @code{SQL_CALC_FOUND_ROWS} and @code{FOUND_ROWS()}. This make it
|
||||
|
|
|
@ -71,3 +71,23 @@ ALTER TABLE t1 ADD Column new_col int not null;
|
|||
UNLOCK TABLES;
|
||||
OPTIMIZE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
drop table if exists t1;
|
||||
|
||||
#
|
||||
# ALTER TABLE ... ENABLE/DISABLE KEYS
|
||||
|
||||
create table t1 (n1 int not null, n2 int, n3 int, n4 float,
|
||||
unique(n1),
|
||||
key (n1, n2, n3, n4),
|
||||
key (n2, n3, n4, n1),
|
||||
key (n3, n4, n1, n2),
|
||||
key (n4, n1, n2, n3) );
|
||||
alter table t1 disable keys;
|
||||
let $1=10000;
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 values($1,RAND()*1000,RAND()*1000,RAND());
|
||||
dec $1;
|
||||
}
|
||||
alter table t1 enable keys;
|
||||
drop table t1;
|
||||
|
|
|
@ -112,6 +112,7 @@ static SYMBOL symbols[] = {
|
|||
{ "DELETE", SYM(DELETE_SYM),0,0},
|
||||
{ "DESC", SYM(DESC),0,0},
|
||||
{ "DESCRIBE", SYM(DESCRIBE),0,0},
|
||||
{ "DISABLE", SYM(DISABLE_SYM),0,0},
|
||||
{ "DISTINCT", SYM(DISTINCT),0,0},
|
||||
{ "DISTINCTROW", SYM(DISTINCT),0,0}, /* Access likes this */
|
||||
{ "DOUBLE", SYM(DOUBLE_SYM),0,0},
|
||||
|
@ -122,6 +123,7 @@ static SYMBOL symbols[] = {
|
|||
{ "ELSE", SYM(ELSE),0,0},
|
||||
{ "ESCAPE", SYM(ESCAPE_SYM),0,0},
|
||||
{ "ESCAPED", SYM(ESCAPED),0,0},
|
||||
{ "ENABLE", SYM(ENABLE_SYM),0,0},
|
||||
{ "ENCLOSED", SYM(ENCLOSED),0,0},
|
||||
{ "ENUM", SYM(ENUM),0,0},
|
||||
{ "EXPLAIN", SYM(DESCRIBE),0,0},
|
||||
|
|
|
@ -328,7 +328,9 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
|||
List<Alter_column> &alter_list,
|
||||
ORDER *order,
|
||||
bool drop_primary,
|
||||
enum enum_duplicates handle_duplicates);
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
|
||||
bool simple_alter=0);
|
||||
bool mysql_rename_table(enum db_type base,
|
||||
const char *old_db,
|
||||
const char * old_name,
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
class Query_log_event;
|
||||
class Load_log_event;
|
||||
|
||||
enum enum_enable_or_disable { LEAVE_AS_IS, ENABLE, DISABLE };
|
||||
enum enum_ha_read_modes { RFIRST, RNEXT, RPREV, RLAST, RKEY };
|
||||
enum enum_duplicates { DUP_ERROR, DUP_REPLACE, DUP_IGNORE };
|
||||
enum enum_log_type { LOG_CLOSED, LOG_NORMAL, LOG_NEW, LOG_BIN };
|
||||
|
|
|
@ -144,10 +144,11 @@ typedef struct st_lex {
|
|||
enum enum_tx_isolation tx_isolation;
|
||||
enum enum_ha_read_modes ha_read_mode;
|
||||
enum ha_rkey_function ha_rkey_mode;
|
||||
enum enum_enable_or_disable alter_keys_onoff;
|
||||
uint in_sum_expr,grant,grant_tot_col,which_columns, sort_default;
|
||||
thr_lock_type lock_option;
|
||||
bool create_refs,drop_primary,drop_if_exists,local_file;
|
||||
bool in_comment,ignore_space,verbose;
|
||||
bool in_comment,ignore_space,verbose,simple_alter;
|
||||
|
||||
} LEX;
|
||||
|
||||
|
|
|
@ -1393,7 +1393,8 @@ mysql_execute_command(void)
|
|||
tables, lex->create_list,
|
||||
lex->key_list, lex->drop_list, lex->alter_list,
|
||||
(ORDER *) lex->order_list.first,
|
||||
lex->drop_primary, lex->duplicates);
|
||||
lex->drop_primary, lex->duplicates,
|
||||
lex->alter_keys_onoff, lex->simple_alter);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1080,7 +1080,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
List<Alter_column> &alter_list,
|
||||
ORDER *order,
|
||||
bool drop_primary,
|
||||
enum enum_duplicates handle_duplicates)
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff,
|
||||
bool simple_alter)
|
||||
{
|
||||
TABLE *table,*new_table;
|
||||
int error;
|
||||
|
@ -1145,39 +1147,50 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
if (create_info->row_type == ROW_TYPE_DEFAULT)
|
||||
create_info->row_type=table->row_type;
|
||||
|
||||
/* Check if the user only wants to do a simple RENAME */
|
||||
/* In some simple cases we need not to recreate the table */
|
||||
|
||||
thd->proc_info="setup";
|
||||
if (new_name != table_name &&
|
||||
!fields.elements && !keys.elements && ! drop_list.elements &&
|
||||
!alter_list.elements && !drop_primary &&
|
||||
new_db_type == old_db_type && create_info->max_rows == 0 &&
|
||||
create_info->auto_increment_value == 0 && !table->tmp_table)
|
||||
if (simple_alter)
|
||||
{
|
||||
thd->proc_info="rename";
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
/* Then do a 'simple' rename of the table */
|
||||
error=0;
|
||||
if (!access(new_name_buff,F_OK))
|
||||
if (new_name != table_name)
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
|
||||
error= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fn_ext(new_name)=0;
|
||||
close_cached_table(thd,table);
|
||||
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
|
||||
error= -1;
|
||||
}
|
||||
if (!error && (error=ha_commit_rename(thd)))
|
||||
{
|
||||
my_error(ER_GET_ERRNO,MYF(0),error);
|
||||
error=1;
|
||||
}
|
||||
thd->proc_info="rename";
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
/* Then do a 'simple' rename of the table */
|
||||
error=0;
|
||||
if (!access(new_name_buff,F_OK))
|
||||
{
|
||||
my_error(ER_TABLE_EXISTS_ERROR,MYF(0),new_name);
|
||||
error= -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
*fn_ext(new_name)=0;
|
||||
close_cached_table(thd,table);
|
||||
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
|
||||
error= -1;
|
||||
}
|
||||
if (!error && (error=ha_commit_rename(thd)))
|
||||
{
|
||||
my_error(ER_GET_ERRNO,MYF(0),error);
|
||||
error=1;
|
||||
}
|
||||
|
||||
VOID(pthread_cond_broadcast(&COND_refresh));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
VOID(pthread_cond_broadcast(&COND_refresh));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
}
|
||||
if (!error)
|
||||
{
|
||||
switch (keys_onoff)
|
||||
{
|
||||
case LEAVE_AS_IS: break;
|
||||
case ENABLE: error=table->file->activate_all_index(thd); break;
|
||||
case DISABLE:
|
||||
table->file->deactivate_non_unique_index(table->file->records);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!error)
|
||||
{
|
||||
mysql_update_log.write(thd, thd->query, thd->query_length);
|
||||
|
@ -1188,7 +1201,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||
}
|
||||
send_ok(&thd->net);
|
||||
}
|
||||
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,12 +145,14 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize);
|
|||
%token DESC
|
||||
%token DESCRIBE
|
||||
%token DISTINCT
|
||||
%token DISABLE_SYM
|
||||
%token DOUBLE_SYM
|
||||
%token DROP
|
||||
%token DUMPFILE
|
||||
%token DYNAMIC_SYM
|
||||
%token ELSE
|
||||
%token ELT_FUNC
|
||||
%token ENABLE_SYM
|
||||
%token ENCLOSED
|
||||
%token ENCODE_SYM
|
||||
%token ENCRYPT
|
||||
|
@ -1110,6 +1112,8 @@ alter:
|
|||
lex->db=lex->name=0;
|
||||
bzero((char*) &lex->create_info,sizeof(lex->create_info));
|
||||
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
||||
lex->alter_keys_onoff=LEAVE_AS_IS;
|
||||
lex->simple_alter=1;
|
||||
}
|
||||
alter_list
|
||||
|
||||
|
@ -1118,16 +1122,18 @@ alter_list:
|
|||
| alter_list ',' alter_list_item
|
||||
|
||||
add_column:
|
||||
ADD opt_column { Lex->change=0;}
|
||||
ADD opt_column { Lex->change=0; }
|
||||
|
||||
alter_list_item:
|
||||
add_column field_list_item opt_place
|
||||
| add_column '(' field_list ')'
|
||||
| CHANGE opt_column field_ident { Lex->change= $3.str; } field_spec
|
||||
add_column field_list_item opt_place { Lex->simple_alter=0; }
|
||||
| add_column '(' field_list ')' { Lex->simple_alter=0; }
|
||||
| CHANGE opt_column field_ident { Lex->change= $3.str; Lex->simple_alter=0; }
|
||||
field_spec
|
||||
| MODIFY_SYM opt_column field_ident
|
||||
{
|
||||
Lex->length=Lex->dec=0; Lex->type=0; Lex->interval=0;
|
||||
Lex->default_value=0;
|
||||
Lex->simple_alter=0;
|
||||
}
|
||||
type opt_attribute
|
||||
{
|
||||
|
@ -1137,23 +1143,26 @@ alter_list_item:
|
|||
Lex->default_value, $3.str,
|
||||
Lex->interval))
|
||||
YYABORT;
|
||||
Lex->simple_alter=0;
|
||||
}
|
||||
| DROP opt_column field_ident opt_restrict
|
||||
{ Lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
|
||||
$3.str)); }
|
||||
| DROP PRIMARY_SYM KEY_SYM { Lex->drop_primary=1; }
|
||||
| DROP FOREIGN KEY_SYM opt_ident {}
|
||||
$3.str)); Lex->simple_alter=0; }
|
||||
| DROP PRIMARY_SYM KEY_SYM { Lex->drop_primary=1; Lex->simple_alter=0; }
|
||||
| DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; }
|
||||
| DROP key_or_index field_ident
|
||||
{ Lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||
$3.str)); }
|
||||
$3.str)); Lex->simple_alter=0; }
|
||||
| DISABLE_SYM KEYS { Lex->alter_keys_onoff=DISABLE; }
|
||||
| ENABLE_SYM KEYS { Lex->alter_keys_onoff=ENABLE; }
|
||||
| ALTER opt_column field_ident SET DEFAULT literal
|
||||
{ Lex->alter_list.push_back(new Alter_column($3.str,$6)); }
|
||||
{ Lex->alter_list.push_back(new Alter_column($3.str,$6)); Lex->simple_alter=0; }
|
||||
| ALTER opt_column field_ident DROP DEFAULT
|
||||
{ Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); }
|
||||
{ Lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0)); Lex->simple_alter=0; }
|
||||
| RENAME opt_to table_alias table_ident
|
||||
{ Lex->db=$4->db.str ; Lex->name= $4->table.str; }
|
||||
| create_table_options
|
||||
| order_clause
|
||||
{ Lex->db=$4->db.str ; Lex->name= $4->table.str; Lex->simple_alter=0; }
|
||||
| create_table_options { Lex->simple_alter=0; }
|
||||
| order_clause { Lex->simple_alter=0; }
|
||||
|
||||
opt_column:
|
||||
/* empty */ {}
|
||||
|
@ -2604,8 +2613,10 @@ keyword:
|
|||
| DATE_SYM {}
|
||||
| DAY_SYM {}
|
||||
| DELAY_KEY_WRITE_SYM {}
|
||||
| DISABLE_SYM {}
|
||||
| DUMPFILE {}
|
||||
| DYNAMIC_SYM {}
|
||||
| ENABLE_SYM {}
|
||||
| END {}
|
||||
| ENUM {}
|
||||
| ESCAPE_SYM {}
|
||||
|
|
Loading…
Reference in a new issue