mirror of
https://github.com/MariaDB/server.git
synced 2025-08-01 03:47:19 +03:00
Automatic merge
This commit is contained in:
@ -1143,3 +1143,4 @@ sql/db.opt
|
||||
./_CPack_Packages
|
||||
./install_manifest_*.txt
|
||||
typescript
|
||||
mysql-test/collections/default.release.done
|
||||
|
12
mysql-test/r/myisam-metadata.result
Normal file
12
mysql-test/r/myisam-metadata.result
Normal file
@ -0,0 +1,12 @@
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (
|
||||
id INT PRIMARY KEY,
|
||||
a VARCHAR(100),
|
||||
INDEX(a)
|
||||
) ENGINE=MyISAM;
|
||||
ALTER TABLE t1 DISABLE KEYS;
|
||||
ALTER TABLE t1 ENABLE KEYS;
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
|
||||
t1 MyISAM 10 Dynamic 100000 27 # # # 0 NULL # # # latin1_swedish_ci NULL
|
||||
DROP TABLE t1;
|
22
mysql-test/suite/rpl/r/replace.result
Normal file
22
mysql-test/suite/rpl/r/replace.result
Normal file
@ -0,0 +1,22 @@
|
||||
include/master-slave.inc
|
||||
[connection master]
|
||||
drop table if exists t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (pr_id int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, pr_page int(11) NOT NULL, pr_type varbinary(60) NOT NULL, test int, UNIQUE KEY pr_pagetype (pr_page,pr_type)) ENGINE=myisam AUTO_INCREMENT=136;
|
||||
insert into t1 (pr_page, pr_type, test) values(1,"one",0),(2,"two",0);
|
||||
select * from t1;
|
||||
pr_id pr_page pr_type test
|
||||
136 1 one 0
|
||||
137 2 two 0
|
||||
replace into t1 (pr_page, pr_type,test) values(1,"one",2);
|
||||
select * from t1;
|
||||
pr_id pr_page pr_type test
|
||||
138 1 one 2
|
||||
137 2 two 0
|
||||
select * from t1;
|
||||
pr_id pr_page pr_type test
|
||||
138 1 one 2
|
||||
137 2 two 0
|
||||
drop table t1;
|
||||
include/rpl_end.inc
|
24
mysql-test/suite/rpl/t/replace.test
Normal file
24
mysql-test/suite/rpl/t/replace.test
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# Test of REPLACE with replication
|
||||
#
|
||||
|
||||
source include/master-slave.inc;
|
||||
|
||||
#
|
||||
# Test of doing replace on unique key on table with auto_increment
|
||||
#
|
||||
|
||||
drop table if exists t1;
|
||||
CREATE TABLE t1 (pr_id int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY, pr_page int(11) NOT NULL, pr_type varbinary(60) NOT NULL, test int, UNIQUE KEY pr_pagetype (pr_page,pr_type)) ENGINE=myisam AUTO_INCREMENT=136;
|
||||
insert into t1 (pr_page, pr_type, test) values(1,"one",0),(2,"two",0);
|
||||
select * from t1;
|
||||
replace into t1 (pr_page, pr_type,test) values(1,"one",2);
|
||||
select * from t1;
|
||||
sync_slave_with_master;
|
||||
connection slave;
|
||||
select * from t1;
|
||||
connection master;
|
||||
drop table t1;
|
||||
|
||||
# End of 5.5 tests
|
||||
--source include/rpl_end.inc
|
49
mysql-test/t/myisam-metadata.test
Normal file
49
mysql-test/t/myisam-metadata.test
Normal file
@ -0,0 +1,49 @@
|
||||
#
|
||||
# Test bugs in MyISAM that may cause problems for metadata
|
||||
#
|
||||
|
||||
--source include/big_test.inc
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
#
|
||||
# LP:989055 - Querying myisam table metadata may corrupt the table
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
id INT PRIMARY KEY,
|
||||
a VARCHAR(100),
|
||||
INDEX(a)
|
||||
) ENGINE=MyISAM;
|
||||
ALTER TABLE t1 DISABLE KEYS;
|
||||
|
||||
let $1=100000;
|
||||
--disable_query_log
|
||||
while ($1)
|
||||
{
|
||||
eval insert into t1 values($1, "line number $1");
|
||||
dec $1;
|
||||
}
|
||||
--enable_query_log
|
||||
|
||||
--connect(con1,localhost,root,,)
|
||||
--send
|
||||
ALTER TABLE t1 ENABLE KEYS;
|
||||
|
||||
--connection default
|
||||
--let $wait_timeout=10
|
||||
--let $show_statement= SHOW PROCESSLIST
|
||||
--let $field= State
|
||||
--let $condition= = 'Repair by sorting'
|
||||
--source include/wait_show_condition.inc
|
||||
|
||||
--replace_column 7 # 8 # 9 # 12 # 13 # 14 #
|
||||
SHOW TABLE STATUS LIKE 't1';
|
||||
|
||||
--connection con1
|
||||
--reap
|
||||
--connection default
|
||||
--disconnect con1
|
||||
DROP TABLE t1;
|
@ -71,6 +71,7 @@ Usage: $0 [OPTIONS]
|
||||
--defaults-extra-file=FILE Also use defaults from the specified file
|
||||
--ledir=DIRECTORY Look for mysqld in the specified directory
|
||||
--open-files-limit=LIMIT Limit the number of open files
|
||||
--crash-script=FILE Script to call when mysqld crashes
|
||||
--timezone=TZ Set the system timezone
|
||||
--malloc-lib=LIB Preload shared library LIB if available
|
||||
--mysqld=FILE Use the specified file as mysqld
|
||||
@ -202,6 +203,7 @@ parse_arguments() {
|
||||
optname_subst=`echo "$optname" | sed 's/_/-/g'`
|
||||
arg=`echo $arg | sed "s/^$optname/$optname_subst/"`
|
||||
case "$arg" in
|
||||
--crash-script=*) CRASH_SCRIPT="$val" ;;
|
||||
# these get passed explicitly to mysqld
|
||||
--basedir=*) MY_BASEDIR_VERSION="$val" ;;
|
||||
--datadir=*|--data=*) DATADIR="$val" ;;
|
||||
@ -799,7 +801,7 @@ have_sleep=1
|
||||
|
||||
while true
|
||||
do
|
||||
rm -f $safe_mysql_unix_port "$pid_file" # Some extra safety
|
||||
rm -f "$pid_file" # Some extra safety
|
||||
|
||||
start_time=`date +%M%S`
|
||||
|
||||
@ -874,6 +876,11 @@ do
|
||||
done
|
||||
fi
|
||||
log_notice "mysqld restarted"
|
||||
if test -n "$CRASH_SCRIPT"
|
||||
then
|
||||
crash_script_output=`$CRASH_SCRIPT 2>&1`
|
||||
log_error "$crash_script_output"
|
||||
fi
|
||||
done
|
||||
|
||||
log_notice "mysqld from pid file $pid_file ended"
|
||||
|
@ -7298,7 +7298,7 @@ static int mysql_init_variables(void)
|
||||
log_error_file_ptr= log_error_file;
|
||||
protocol_version= PROTOCOL_VERSION;
|
||||
what_to_log= ~ (1L << (uint) COM_TIME);
|
||||
refresh_version= 1L; /* Increments on each reload */
|
||||
refresh_version= 2L; /* Increments on each reload. 0 and 1 are reserved */
|
||||
executed_events= 0;
|
||||
global_query_id= thread_id= 1L;
|
||||
my_atomic_rwlock_init(&global_query_id_lock);
|
||||
|
@ -87,6 +87,7 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
const char **ext;
|
||||
MY_STAT stat_info;
|
||||
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
|
||||
MYSQL_OPEN_FOR_REPAIR |
|
||||
MYSQL_OPEN_HAS_MDL_LOCK |
|
||||
MYSQL_LOCK_IGNORE_TIMEOUT));
|
||||
DBUG_ENTER("prepare_for_repair");
|
||||
@ -197,7 +198,8 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list,
|
||||
*/
|
||||
pos_in_locked_tables= table->pos_in_locked_tables;
|
||||
if (wait_while_table_is_used(thd, table,
|
||||
HA_EXTRA_PREPARE_FOR_FORCED_CLOSE))
|
||||
HA_EXTRA_PREPARE_FOR_FORCED_CLOSE,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
goto end;
|
||||
/* Close table but don't remove from locked list */
|
||||
close_all_tables_for_name(thd, table_list->table->s,
|
||||
@ -589,8 +591,10 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
*/
|
||||
if (lock_type == TL_WRITE && !table->table->s->tmp_table)
|
||||
{
|
||||
table->table->s->protect_against_usage();
|
||||
if (wait_while_table_is_used(thd, table->table,
|
||||
HA_EXTRA_PREPARE_FOR_RENAME))
|
||||
HA_EXTRA_PREPARE_FOR_RENAME,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
goto err;
|
||||
DEBUG_SYNC(thd, "after_admin_flush");
|
||||
/* Flush entries in the query cache involving this table. */
|
||||
|
@ -1068,7 +1068,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables,
|
||||
if (share)
|
||||
{
|
||||
kill_delayed_threads_for_table(share);
|
||||
/* tdc_remove_table() also sets TABLE_SHARE::version to 0. */
|
||||
/* tdc_remove_table() calls share->remove_from_cache_at_close() */
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_UNUSED, table->db,
|
||||
table->table_name, TRUE);
|
||||
found=1;
|
||||
@ -2327,7 +2327,8 @@ bool rename_temporary_table(THD* thd, TABLE *table, const char *db,
|
||||
*/
|
||||
|
||||
bool wait_while_table_is_used(THD *thd, TABLE *table,
|
||||
enum ha_extra_function function)
|
||||
enum ha_extra_function function,
|
||||
enum_tdc_remove_table_type remove_type)
|
||||
{
|
||||
DBUG_ENTER("wait_while_table_is_used");
|
||||
DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
|
||||
@ -2338,7 +2339,7 @@ bool wait_while_table_is_used(THD *thd, TABLE *table,
|
||||
table->mdl_ticket, thd->variables.lock_wait_timeout))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
tdc_remove_table(thd, TDC_RT_REMOVE_NOT_OWN,
|
||||
tdc_remove_table(thd, remove_type,
|
||||
table->s->db.str, table->s->table_name.str,
|
||||
FALSE);
|
||||
/* extra() call must come only after all instances above are closed */
|
||||
@ -3084,7 +3085,9 @@ retry_share:
|
||||
goto err_unlock;
|
||||
}
|
||||
|
||||
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH))
|
||||
if (!(flags & MYSQL_OPEN_IGNORE_FLUSH) ||
|
||||
(share->protected_against_usage() &&
|
||||
!(flags & MYSQL_OPEN_FOR_REPAIR)))
|
||||
{
|
||||
if (share->has_old_version())
|
||||
{
|
||||
@ -9376,6 +9379,7 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||
TABLE *table;
|
||||
TABLE_SHARE *share;
|
||||
DBUG_ENTER("tdc_remove_table");
|
||||
DBUG_PRINT("enter",("name: %s remove_type: %d", table_name, remove_type));
|
||||
|
||||
if (! has_lock)
|
||||
mysql_mutex_lock(&LOCK_open);
|
||||
@ -9401,7 +9405,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||
{
|
||||
DBUG_ASSERT(share->used_tables.is_empty());
|
||||
}
|
||||
else if (remove_type == TDC_RT_REMOVE_NOT_OWN)
|
||||
else if (remove_type == TDC_RT_REMOVE_NOT_OWN ||
|
||||
remove_type == TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE)
|
||||
{
|
||||
I_P_List_iterator<TABLE, TABLE_share> it2(share->used_tables);
|
||||
while ((table= it2++))
|
||||
@ -9412,8 +9417,8 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||
}
|
||||
#endif
|
||||
/*
|
||||
Set share's version to zero in order to ensure that it gets
|
||||
automatically deleted once it is no longer referenced.
|
||||
Mark share to ensure that it gets automatically deleted once
|
||||
it is no longer referenced.
|
||||
|
||||
Note that code in TABLE_SHARE::wait_for_old_version() assumes
|
||||
that marking share as old and removal of its unused tables
|
||||
@ -9422,7 +9427,13 @@ void tdc_remove_table(THD *thd, enum_tdc_remove_table_type remove_type,
|
||||
TDC does not contain old shares which don't have any tables
|
||||
used.
|
||||
*/
|
||||
share->version= 0;
|
||||
if (remove_type == TDC_RT_REMOVE_NOT_OWN)
|
||||
share->remove_from_cache_at_close();
|
||||
else
|
||||
{
|
||||
/* Ensure that no can open the table while it's used */
|
||||
share->protect_against_usage();
|
||||
}
|
||||
|
||||
while ((table= it++))
|
||||
free_cache_entry(table);
|
||||
|
@ -60,7 +60,8 @@ enum find_item_error_report_type {REPORT_ALL_ERRORS, REPORT_EXCEPT_NOT_FOUND,
|
||||
IGNORE_EXCEPT_NON_UNIQUE};
|
||||
|
||||
enum enum_tdc_remove_table_type {TDC_RT_REMOVE_ALL, TDC_RT_REMOVE_NOT_OWN,
|
||||
TDC_RT_REMOVE_UNUSED};
|
||||
TDC_RT_REMOVE_UNUSED,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE};
|
||||
|
||||
/* bits for last argument to remove_table_from_cache() */
|
||||
#define RTFC_NO_FLAG 0x0000
|
||||
@ -153,6 +154,7 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update,
|
||||
*/
|
||||
#define MYSQL_OPEN_SKIP_SCOPED_MDL_LOCK 0x1000
|
||||
#define MYSQL_LOCK_NOT_TEMPORARY 0x2000
|
||||
#define MYSQL_OPEN_FOR_REPAIR 0x4000
|
||||
|
||||
/** Please refer to the internals manual. */
|
||||
#define MYSQL_OPEN_REOPEN (MYSQL_OPEN_IGNORE_FLUSH |\
|
||||
@ -254,7 +256,9 @@ bool setup_tables_and_check_access(THD *thd,
|
||||
ulong want_access,
|
||||
bool full_table_list);
|
||||
bool wait_while_table_is_used(THD *thd, TABLE *table,
|
||||
enum ha_extra_function function);
|
||||
enum ha_extra_function function,
|
||||
enum_tdc_remove_table_type remove_type=
|
||||
TDC_RT_REMOVE_NOT_OWN);
|
||||
|
||||
void drop_open_table(THD *thd, TABLE *table, const char *db_name,
|
||||
const char *table_name);
|
||||
|
@ -2211,7 +2211,8 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
|
||||
if (thd->locked_tables_mode)
|
||||
{
|
||||
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED))
|
||||
if (wait_while_table_is_used(thd, table->table, HA_EXTRA_NOT_USED,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
{
|
||||
error= -1;
|
||||
goto err;
|
||||
@ -6258,13 +6259,15 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
case LEAVE_AS_IS:
|
||||
break;
|
||||
case ENABLE:
|
||||
if (wait_while_table_is_used(thd, table, extra_func))
|
||||
if (wait_while_table_is_used(thd, table, extra_func,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
goto err;
|
||||
DEBUG_SYNC(thd,"alter_table_enable_indexes");
|
||||
error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
|
||||
break;
|
||||
case DISABLE:
|
||||
if (wait_while_table_is_used(thd, table, extra_func))
|
||||
if (wait_while_table_is_used(thd, table, extra_func,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
goto err;
|
||||
error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
|
||||
break;
|
||||
@ -6292,7 +6295,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
simple rename did nothing and therefore we can safely return
|
||||
without additional clean-up.
|
||||
*/
|
||||
if (wait_while_table_is_used(thd, table, extra_func))
|
||||
if (wait_while_table_is_used(thd, table, extra_func,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
goto err;
|
||||
close_all_tables_for_name(thd, table->s, HA_EXTRA_PREPARE_FOR_RENAME);
|
||||
/*
|
||||
@ -6725,6 +6729,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (table->s->tmp_table)
|
||||
{
|
||||
Open_table_context ot_ctx(thd, (MYSQL_OPEN_IGNORE_FLUSH |
|
||||
MYSQL_OPEN_FOR_REPAIR |
|
||||
MYSQL_LOCK_IGNORE_TIMEOUT));
|
||||
TABLE_LIST tbl;
|
||||
bzero((void*) &tbl, sizeof(tbl));
|
||||
@ -6797,7 +6802,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
table->file->indexes_are_disabled())
|
||||
need_lock_for_indexes= true;
|
||||
if (!table->s->tmp_table && need_lock_for_indexes &&
|
||||
wait_while_table_is_used(thd, table, extra_func))
|
||||
wait_while_table_is_used(thd, table, extra_func,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
goto err_new_table_cleanup;
|
||||
thd_proc_info(thd, "manage keys");
|
||||
DEBUG_SYNC(thd, "alter_table_manage_keys");
|
||||
@ -7017,7 +7023,8 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (lower_case_table_names)
|
||||
my_casedn_str(files_charset_info, old_name);
|
||||
|
||||
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME))
|
||||
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_RENAME,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
{
|
||||
if (pending_inplace_add_index)
|
||||
{
|
||||
|
@ -364,7 +364,8 @@ bool Truncate_statement::lock_table(THD *thd, TABLE_LIST *table_ref,
|
||||
{
|
||||
DEBUG_SYNC(thd, "upgrade_lock_for_truncate");
|
||||
/* To remove the table from the cache we need an exclusive lock. */
|
||||
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP))
|
||||
if (wait_while_table_is_used(thd, table, HA_EXTRA_PREPARE_FOR_DROP,
|
||||
TDC_RT_REMOVE_NOT_OWN_AND_MARK_NOT_USABLE))
|
||||
DBUG_RETURN(TRUE);
|
||||
m_ticket_downgrade= table->mdl_ticket;
|
||||
/* Close if table is going to be recreated. */
|
||||
|
@ -323,7 +323,7 @@ TABLE_SHARE *alloc_table_share(TABLE_LIST *table_list, char *key,
|
||||
share->normalized_path.str= share->path.str;
|
||||
share->normalized_path.length= path_length;
|
||||
|
||||
share->version= refresh_version;
|
||||
share->set_refresh_version();
|
||||
|
||||
/*
|
||||
Since alloc_table_share() can be called without any locking (for
|
||||
|
23
sql/table.h
23
sql/table.h
@ -793,12 +793,33 @@ struct TABLE_SHARE
|
||||
return table_map_id;
|
||||
}
|
||||
|
||||
|
||||
/** Is this table share being expelled from the table definition cache? */
|
||||
inline bool has_old_version() const
|
||||
{
|
||||
return version != refresh_version;
|
||||
}
|
||||
inline bool protected_against_usage() const
|
||||
{
|
||||
return version == 0;
|
||||
}
|
||||
inline void protect_against_usage()
|
||||
{
|
||||
version= 0;
|
||||
}
|
||||
/*
|
||||
Remove from table definition cache at close.
|
||||
Table can still be opened by SHOW
|
||||
*/
|
||||
inline void remove_from_cache_at_close()
|
||||
{
|
||||
if (version != 0) /* Don't remove protection */
|
||||
version= 1;
|
||||
}
|
||||
inline void set_refresh_version()
|
||||
{
|
||||
version= refresh_version;
|
||||
}
|
||||
|
||||
/**
|
||||
Convert unrelated members of TABLE_SHARE to one enum
|
||||
representing its type.
|
||||
|
@ -35,7 +35,6 @@ C_MODE_START
|
||||
ICP_RESULT index_cond_func_maria(void *arg);
|
||||
C_MODE_END
|
||||
|
||||
extern ulong maria_sort_buffer_size;
|
||||
extern TYPELIB maria_recover_typelib;
|
||||
extern ulonglong maria_recover_options;
|
||||
|
||||
|
Reference in New Issue
Block a user