Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
mariadb
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
b6d36087
Commit
b6d36087
authored
Feb 16, 2010
by
Sergey Glukhov
Browse files
Options
Browse Files
Download
Plain Diff
automerge
parents
82e2d858
e32414df
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
191 additions
and
27 deletions
+191
-27
mysql-test/r/partition_debug_sync.result
mysql-test/r/partition_debug_sync.result
+57
-0
mysql-test/t/partition_debug_sync.test
mysql-test/t/partition_debug_sync.test
+81
-0
sql/ha_partition.cc
sql/ha_partition.cc
+27
-6
sql/sql_base.cc
sql/sql_base.cc
+1
-0
sql/sql_table.cc
sql/sql_table.cc
+25
-21
No files found.
mysql-test/r/partition_debug_sync.result
0 → 100644
View file @
b6d36087
DROP TABLE IF EXISTS t1, t2;
SET DEBUG_SYNC= 'RESET';
#
# Bug#42438: Crash ha_partition::change_table_ptr
# Test when remove partitioning is done while drop table is waiting
# for the table.
# Con 1
SET DEBUG_SYNC= 'RESET';
CREATE TABLE t1
(a INTEGER,
b INTEGER NOT NULL,
KEY (b))
ENGINE = MYISAM
/*!50100 PARTITION BY RANGE (a)
(PARTITION p0 VALUES LESS THAN (2),
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */;
SET DEBUG_SYNC= 'alter_table_before_create_table_no_lock SIGNAL removing_partitioning WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_main_binlog SIGNAL partitioning_removed';
ALTER TABLE t1 REMOVE PARTITIONING;
# Con default
SET DEBUG_SYNC= 'now WAIT_FOR removing_partitioning';
SET DEBUG_SYNC= 'waiting_for_table SIGNAL waiting_for_alter';
SET DEBUG_SYNC= 'rm_table_part2_before_delete_table WAIT_FOR partitioning_removed';
DROP TABLE IF EXISTS t1;
# Con 1
SET DEBUG_SYNC= 'RESET';
SET DEBUG_SYNC= 'RESET';
#
# Bug#42438: Crash ha_partition::change_table_ptr
# Test when remove partitioning is failing due to drop table is already
# in progress.
CREATE TABLE t2
(a INTEGER,
b INTEGER NOT NULL,
KEY (b))
ENGINE = MYISAM
/*!50100 PARTITION BY RANGE (a)
(PARTITION p0 VALUES LESS THAN (2),
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */;
SET DEBUG_SYNC= 'before_lock_tables_takes_lock SIGNAL removing_partitions WAIT_FOR waiting_for_alter';
SET DEBUG_SYNC= 'alter_table_before_rename_result_table WAIT_FOR delete_done';
ALTER TABLE t2 REMOVE PARTITIONING;
# Con default
SET DEBUG_SYNC= 'now WAIT_FOR removing_partitions';
SET DEBUG_SYNC= 'waiting_for_table SIGNAL waiting_for_alter';
SET DEBUG_SYNC= 'rm_table_part2_before_binlog SIGNAL delete_done';
DROP TABLE IF EXISTS t2;
# Con 1
ERROR 42S02: Table 'test.t2' doesn't exist
SET DEBUG_SYNC= 'RESET';
# Con default
SET DEBUG_SYNC= 'RESET';
End of 5.1 tests
mysql-test/t/partition_debug_sync.test
0 → 100644
View file @
b6d36087
#--disable_abort_on_error
#
# Test for the partition storage engine which require DEBUG_SYNC feature to
# Created by Mattias Jonsson
#
--
source
include
/
have_partition
.
inc
--
source
include
/
have_debug_sync
.
inc
--
disable_warnings
DROP
TABLE
IF
EXISTS
t1
,
t2
;
SET
DEBUG_SYNC
=
'RESET'
;
--
enable_warnings
--
echo
#
--
echo
# Bug#42438: Crash ha_partition::change_table_ptr
--
echo
# Test when remove partitioning is done while drop table is waiting
--
echo
# for the table.
connect
(
con1
,
localhost
,
root
,,);
--
echo
# Con 1
SET
DEBUG_SYNC
=
'RESET'
;
CREATE
TABLE
t1
(
a
INTEGER
,
b
INTEGER
NOT
NULL
,
KEY
(
b
))
ENGINE
=
MYISAM
/*!50100 PARTITION BY RANGE (a)
(PARTITION p0 VALUES LESS THAN (2),
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */
;
SET
DEBUG_SYNC
=
'alter_table_before_create_table_no_lock SIGNAL removing_partitioning WAIT_FOR waiting_for_alter'
;
SET
DEBUG_SYNC
=
'alter_table_before_main_binlog SIGNAL partitioning_removed'
;
--
send
ALTER
TABLE
t1
REMOVE
PARTITIONING
connection
default
;
--
echo
# Con default
SET
DEBUG_SYNC
=
'now WAIT_FOR removing_partitioning'
;
SET
DEBUG_SYNC
=
'waiting_for_table SIGNAL waiting_for_alter'
;
SET
DEBUG_SYNC
=
'rm_table_part2_before_delete_table WAIT_FOR partitioning_removed'
;
DROP
TABLE
IF
EXISTS
t1
;
--
echo
# Con 1
connection
con1
;
--
reap
connection
default
;
SET
DEBUG_SYNC
=
'RESET'
;
connection
con1
;
SET
DEBUG_SYNC
=
'RESET'
;
--
echo
#
--
echo
# Bug#42438: Crash ha_partition::change_table_ptr
--
echo
# Test when remove partitioning is failing due to drop table is already
--
echo
# in progress.
CREATE
TABLE
t2
(
a
INTEGER
,
b
INTEGER
NOT
NULL
,
KEY
(
b
))
ENGINE
=
MYISAM
/*!50100 PARTITION BY RANGE (a)
(PARTITION p0 VALUES LESS THAN (2),
PARTITION p1 VALUES LESS THAN (20),
PARTITION p2 VALUES LESS THAN (100),
PARTITION p3 VALUES LESS THAN MAXVALUE ) */
;
SET
DEBUG_SYNC
=
'before_lock_tables_takes_lock SIGNAL removing_partitions WAIT_FOR waiting_for_alter'
;
SET
DEBUG_SYNC
=
'alter_table_before_rename_result_table WAIT_FOR delete_done'
;
--
send
ALTER
TABLE
t2
REMOVE
PARTITIONING
connection
default
;
--
echo
# Con default
SET
DEBUG_SYNC
=
'now WAIT_FOR removing_partitions'
;
SET
DEBUG_SYNC
=
'waiting_for_table SIGNAL waiting_for_alter'
;
SET
DEBUG_SYNC
=
'rm_table_part2_before_binlog SIGNAL delete_done'
;
DROP
TABLE
IF
EXISTS
t2
;
--
echo
# Con 1
connection
con1
;
--
error
ER_NO_SUCH_TABLE
--
reap
SET
DEBUG_SYNC
=
'RESET'
;
disconnect
con1
;
connection
default
;
--
echo
# Con default
SET
DEBUG_SYNC
=
'RESET'
;
--
echo
End
of
5.1
tests
sql/ha_partition.cc
View file @
b6d36087
...
@@ -1746,13 +1746,23 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
...
@@ -1746,13 +1746,23 @@ void ha_partition::update_create_info(HA_CREATE_INFO *create_info)
void
ha_partition
::
change_table_ptr
(
TABLE
*
table_arg
,
TABLE_SHARE
*
share
)
void
ha_partition
::
change_table_ptr
(
TABLE
*
table_arg
,
TABLE_SHARE
*
share
)
{
{
handler
**
file_array
=
m_file
;
handler
**
file_array
;
table
=
table_arg
;
table
=
table_arg
;
table_share
=
share
;
table_share
=
share
;
do
/*
m_file can be NULL when using an old cached table in DROP TABLE, when the
table just has REMOVED PARTITIONING, see Bug#42438
*/
if
(
m_file
)
{
{
(
*
file_array
)
->
change_table_ptr
(
table_arg
,
share
);
file_array
=
m_file
;
}
while
(
*
(
++
file_array
));
DBUG_ASSERT
(
*
file_array
);
do
{
(
*
file_array
)
->
change_table_ptr
(
table_arg
,
share
);
}
while
(
*
(
++
file_array
));
}
if
(
m_added_file
&&
m_added_file
[
0
])
if
(
m_added_file
&&
m_added_file
[
0
])
{
{
/* if in middle of a drop/rename etc */
/* if in middle of a drop/rename etc */
...
@@ -6055,7 +6065,13 @@ void ha_partition::print_error(int error, myf errflag)
...
@@ -6055,7 +6065,13 @@ void ha_partition::print_error(int error, myf errflag)
if
(
error
==
HA_ERR_NO_PARTITION_FOUND
)
if
(
error
==
HA_ERR_NO_PARTITION_FOUND
)
m_part_info
->
print_no_partition_found
(
table
);
m_part_info
->
print_no_partition_found
(
table
);
else
else
m_file
[
m_last_part
]
->
print_error
(
error
,
errflag
);
{
/* In case m_file has not been initialized, like in bug#42438 */
if
(
m_file
)
m_file
[
m_last_part
]
->
print_error
(
error
,
errflag
);
else
handler
::
print_error
(
error
,
errflag
);
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -6065,7 +6081,12 @@ bool ha_partition::get_error_message(int error, String *buf)
...
@@ -6065,7 +6081,12 @@ bool ha_partition::get_error_message(int error, String *buf)
DBUG_ENTER
(
"ha_partition::get_error_message"
);
DBUG_ENTER
(
"ha_partition::get_error_message"
);
/* Should probably look for my own errors first */
/* Should probably look for my own errors first */
DBUG_RETURN
(
m_file
[
m_last_part
]
->
get_error_message
(
error
,
buf
));
/* In case m_file has not been initialized, like in bug#42438 */
if
(
m_file
)
DBUG_RETURN
(
m_file
[
m_last_part
]
->
get_error_message
(
error
,
buf
));
DBUG_RETURN
(
handler
::
get_error_message
(
error
,
buf
));
}
}
...
...
sql/sql_base.cc
View file @
b6d36087
...
@@ -2169,6 +2169,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
...
@@ -2169,6 +2169,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond)
proc_info
=
thd
->
proc_info
;
proc_info
=
thd
->
proc_info
;
thd_proc_info
(
thd
,
"Waiting for table"
);
thd_proc_info
(
thd
,
"Waiting for table"
);
DBUG_ENTER
(
"wait_for_condition"
);
DBUG_ENTER
(
"wait_for_condition"
);
DEBUG_SYNC
(
thd
,
"waiting_for_table"
);
if
(
!
thd
->
killed
)
if
(
!
thd
->
killed
)
(
void
)
pthread_cond_wait
(
cond
,
mutex
);
(
void
)
pthread_cond_wait
(
cond
,
mutex
);
...
...
sql/sql_table.cc
View file @
b6d36087
...
@@ -22,6 +22,9 @@
...
@@ -22,6 +22,9 @@
#include "sp_head.h"
#include "sp_head.h"
#include "sql_trigger.h"
#include "sql_trigger.h"
#include "sql_show.h"
#include "sql_show.h"
#if defined(ENABLED_DEBUG_SYNC)
#include "debug_sync.h"
#endif
#ifdef __WIN__
#ifdef __WIN__
#include <io.h>
#include <io.h>
...
@@ -1889,22 +1892,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -1889,22 +1892,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
pthread_mutex_lock
(
&
LOCK_open
);
pthread_mutex_lock
(
&
LOCK_open
);
/*
/* Disable drop of enabled log tables, must be done before name locking */
If we have the table in the definition cache, we don't have to check the
.frm file to find if the table is a normal table (not view) and what
engine to use.
*/
for
(
table
=
tables
;
table
;
table
=
table
->
next_local
)
for
(
table
=
tables
;
table
;
table
=
table
->
next_local
)
{
{
TABLE_SHARE
*
share
;
if
(
check_if_log_table
(
table
->
db_length
,
table
->
db
,
table
->
db_type
=
NULL
;
if
((
share
=
get_cached_table_share
(
table
->
db
,
table
->
table_name
)))
table
->
db_type
=
share
->
db_type
();
/* Disable drop of enabled log tables */
if
(
share
&&
(
share
->
table_category
==
TABLE_CATEGORY_PERFORMANCE
)
&&
check_if_log_table
(
table
->
db_length
,
table
->
db
,
table
->
table_name_length
,
table
->
table_name
,
1
))
table
->
table_name_length
,
table
->
table_name
,
1
))
{
{
my_error
(
ER_BAD_LOG_STATEMENT
,
MYF
(
0
),
"DROP"
);
my_error
(
ER_BAD_LOG_STATEMENT
,
MYF
(
0
),
"DROP"
);
...
@@ -1923,7 +1914,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -1923,7 +1914,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
{
{
char
*
db
=
table
->
db
;
char
*
db
=
table
->
db
;
handlerton
*
table_type
;
handlerton
*
table_type
;
enum
legacy_db_type
frm_db_type
;
enum
legacy_db_type
frm_db_type
=
DB_TYPE_UNKNOWN
;
DBUG_PRINT
(
"table"
,
(
"table_l: '%s'.'%s' table: 0x%lx s: 0x%lx"
,
DBUG_PRINT
(
"table"
,
(
"table_l: '%s'.'%s' table: 0x%lx s: 0x%lx"
,
table
->
db
,
table
->
table_name
,
(
long
)
table
->
table
,
table
->
db
,
table
->
table_name
,
(
long
)
table
->
table
,
...
@@ -1988,7 +1979,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -1988,7 +1979,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
built_query
.
append
(
"`,"
);
built_query
.
append
(
"`,"
);
}
}
table_type
=
table
->
db_type
;
if
(
!
drop_temporary
)
if
(
!
drop_temporary
)
{
{
TABLE
*
locked_table
;
TABLE
*
locked_table
;
...
@@ -2015,9 +2005,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -2015,9 +2005,9 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
table
->
internal_tmp_table
?
table
->
internal_tmp_table
?
FN_IS_TMP
:
0
);
FN_IS_TMP
:
0
);
}
}
DEBUG_SYNC
(
thd
,
"rm_table_part2_before_delete_table"
);
if
(
drop_temporary
||
if
(
drop_temporary
||
((
table_type
==
NULL
&&
((
access
(
path
,
F_OK
)
&&
access
(
path
,
F_OK
)
&&
ha_create_table_from_engine
(
thd
,
db
,
alias
))
||
ha_create_table_from_engine
(
thd
,
db
,
alias
))
||
(
!
drop_view
&&
(
!
drop_view
&&
mysql_frm_type
(
thd
,
path
,
&
frm_db_type
)
!=
FRMTYPE_TABLE
)))
mysql_frm_type
(
thd
,
path
,
&
frm_db_type
)
!=
FRMTYPE_TABLE
)))
...
@@ -2033,15 +2023,25 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -2033,15 +2023,25 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
else
else
{
{
char
*
end
;
char
*
end
;
if
(
table_type
==
NULL
)
/*
Cannot use the db_type from the table, since that might have changed
while waiting for the exclusive name lock. We are under LOCK_open,
so reading from the frm-file is safe.
*/
if
(
frm_db_type
==
DB_TYPE_UNKNOWN
)
{
{
mysql_frm_type
(
thd
,
path
,
&
frm_db_type
);
mysql_frm_type
(
thd
,
path
,
&
frm_db_type
);
table_type
=
ha_resolve_by_legacy_type
(
thd
,
frm_db_type
);
DBUG_PRINT
(
"info"
,
(
"frm_db_type %d from %s"
,
frm_db_type
,
path
)
);
}
}
table_type
=
ha_resolve_by_legacy_type
(
thd
,
frm_db_type
);
// Remove extension for delete
// Remove extension for delete
*
(
end
=
path
+
path_length
-
reg_ext_length
)
=
'\0'
;
*
(
end
=
path
+
path_length
-
reg_ext_length
)
=
'\0'
;
DBUG_PRINT
(
"info"
,
(
"deleting table of type %d"
,
(
table_type
?
table_type
->
db_type
:
0
)));
error
=
ha_delete_table
(
thd
,
table_type
,
path
,
db
,
table
->
table_name
,
error
=
ha_delete_table
(
thd
,
table_type
,
path
,
db
,
table
->
table_name
,
!
dont_log_query
);
!
dont_log_query
);
/* No error if non existent table and 'IF EXIST' clause or view */
if
((
error
==
ENOENT
||
error
==
HA_ERR_NO_SUCH_TABLE
)
&&
if
((
error
==
ENOENT
||
error
==
HA_ERR_NO_SUCH_TABLE
)
&&
(
if_exists
||
table_type
==
NULL
))
(
if_exists
||
table_type
==
NULL
))
{
{
...
@@ -2081,6 +2081,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
...
@@ -2081,6 +2081,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
on the table name.
on the table name.
*/
*/
pthread_mutex_unlock
(
&
LOCK_open
);
pthread_mutex_unlock
(
&
LOCK_open
);
DEBUG_SYNC
(
thd
,
"rm_table_part2_before_binlog"
);
thd
->
thread_specific_used
|=
tmp_table_deleted
;
thd
->
thread_specific_used
|=
tmp_table_deleted
;
error
=
0
;
error
=
0
;
if
(
wrong_tables
.
length
())
if
(
wrong_tables
.
length
())
...
@@ -7120,6 +7121,7 @@ view_err:
...
@@ -7120,6 +7121,7 @@ view_err:
else
else
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
create_info
->
data_file_name
=
create_info
->
index_file_name
=
0
;
DEBUG_SYNC
(
thd
,
"alter_table_before_create_table_no_lock"
);
/*
/*
Create a table with a temporary name.
Create a table with a temporary name.
With create_info->frm_only == 1 this creates a .frm file only.
With create_info->frm_only == 1 this creates a .frm file only.
...
@@ -7320,6 +7322,7 @@ view_err:
...
@@ -7320,6 +7322,7 @@ view_err:
intern_close_table
(
new_table
);
intern_close_table
(
new_table
);
my_free
(
new_table
,
MYF
(
0
));
my_free
(
new_table
,
MYF
(
0
));
}
}
DEBUG_SYNC
(
thd
,
"alter_table_before_rename_result_table"
);
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
VOID
(
pthread_mutex_lock
(
&
LOCK_open
));
if
(
error
)
if
(
error
)
{
{
...
@@ -7462,6 +7465,7 @@ view_err:
...
@@ -7462,6 +7465,7 @@ view_err:
thd_proc_info
(
thd
,
"end"
);
thd_proc_info
(
thd
,
"end"
);
DBUG_EXECUTE_IF
(
"sleep_alter_before_main_binlog"
,
my_sleep
(
6000000
););
DBUG_EXECUTE_IF
(
"sleep_alter_before_main_binlog"
,
my_sleep
(
6000000
););
DEBUG_SYNC
(
thd
,
"alter_table_before_main_binlog"
);
ha_binlog_log_query
(
thd
,
create_info
->
db_type
,
LOGCOM_ALTER_TABLE
,
ha_binlog_log_query
(
thd
,
create_info
->
db_type
,
LOGCOM_ALTER_TABLE
,
thd
->
query
(),
thd
->
query_length
(),
thd
->
query
(),
thd
->
query_length
(),
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment