Below is the list of changes that have just been committed into a local
4.0 repository of mydev. When mydev does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet
1.2143 05/08/31 19:24:49 ingo@stripped +4 -0
Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement
Changed definition of open_table(), added 'flags'
to be able to ignore flush requests. This should be used
if open_table() runs when there are already locked tables
in this command. Explicit LOCK TABLE is not affected.
No test case. The bug can only be triggered by true concurrency.
The stress test suite provides a test case for this.
sql/sql_table.cc
1.199 05/08/31 19:24:47 ingo@stripped +19 -2
Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement
Changed calls to open_table(). Requested to ignore
flush at places where the command did already lock tables.
This could happen in CREATE ... SELECT and ALTER TABLE.
sql/sql_base.cc
1.192 05/08/31 19:24:47 ingo@stripped +36 -12
Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement
Changed definition of open_table(), added 'flags'
to be able to ignore flush requests. This should be used
if open_table() runs when there are already locked tables
in this command. Explicit LOCK TABLE is not affected.
sql/mysql_priv.h
1.237 05/08/31 19:24:47 ingo@stripped +2 -2
Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement
Changed declaraction of open_table(), added 'flags'.
sql/field.h
1.61 05/08/31 19:24:47 ingo@stripped +2 -2
Bug#12845 - Stress test: Server crashes on CREATE .. SELECT statement
Changed declaraction of open_table(), added 'flags'.
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: ingo
# Host: chilla.local
# Root: /home/mydev/mysql-4.0-4000
--- 1.60/sql/field.h 2005-03-28 21:36:22 +02:00
+++ 1.61/sql/field.h 2005-08-31 19:24:47 +02:00
@@ -595,8 +595,8 @@
bool get_time(TIME *ltime);
#if MYSQL_VERSION_ID < 40100
- friend TABLE *open_table(THD *thd,const char *db,const char *table_name,
- const char *alias,bool *refresh);
+ friend TABLE *open_table(THD *thd, const char *db, const char *table_name,
+ const char *alias, bool *refresh, uint flags);
#endif
};
--- 1.236/sql/mysql_priv.h 2005-07-26 16:53:32 +02:00
+++ 1.237/sql/mysql_priv.h 2005-08-31 19:24:47 +02:00
@@ -483,8 +483,8 @@
ha_rows rows, ulong options);
int mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok);
TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type update);
-TABLE *open_table(THD *thd,const char *db,const char *table,const char *alias,
- bool *refresh);
+TABLE *open_table(THD *thd, const char *db, const char *table_name,
+ const char *alias, bool *refresh, uint flags);
TABLE *reopen_name_locked_table(THD* thd, TABLE_LIST* table);
TABLE *find_locked_table(THD *thd, const char *db,const char *table_name);
bool reopen_table(TABLE *table,bool locked=0);
--- 1.191/sql/sql_base.cc 2005-07-26 16:53:32 +02:00
+++ 1.192/sql/sql_base.cc 2005-08-31 19:24:47 +02:00
@@ -788,18 +788,35 @@
}
-/******************************************************************************
-** open a table
-** Uses a cache of open tables to find a table not in use.
-** If refresh is a NULL pointer, then the is no version number checking and
-** the table is not put in the thread-open-list
-** If the return value is NULL and refresh is set then one must close
-** all tables and retry the open
-******************************************************************************/
+/*
+ Open a table.
+
+ SYNOPSIS
+ open_table()
+ thd Thread context
+ db Database name.
+ table_name Real table name.
+ alias Table alias.
+ refresh Pointer to memory that will be set to 1 if
+ we need to close all tables and reopen them.
+ If this is a NULL pointer, then there is no version
+ number checking and the table is not put in the
+ thread-open-list.
+ flags Bitmap of flags to modify how open works:
+ MYSQL_LOCK_IGNORE_FLUSH - Open table even if someone
+ has done a flush or namelock on it.
+ IMPLEMENTATION
+ Uses a cache of open tables to find a table not in use.
-TABLE *open_table(THD *thd,const char *db,const char *table_name,
- const char *alias,bool *refresh)
+ RETURN
+ NULL Open failed. If refresh is set then one should close
+ all other tables and retry the open.
+ # Success. Pointer to TABLE object for open table.
+*/
+
+TABLE *open_table(THD *thd, const char *db, const char *table_name,
+ const char *alias, bool *refresh, uint flags)
{
reg1 TABLE *table;
char key[MAX_DBKEY_LENGTH];
@@ -871,6 +888,13 @@
{
if (table->version != refresh_version)
{
+ if (flags & MYSQL_LOCK_IGNORE_FLUSH)
+ {
+ /* Force close at once after usage */
+ thd->version= table->version;
+ continue;
+ }
+
/*
** There is a refresh in progress for this table
** Wait until the table is freed or the thread is killed.
@@ -1470,7 +1494,7 @@
!(tables->table=open_table(thd,
tables->db,
tables->real_name,
- tables->alias, &refresh)))
+ tables->alias, &refresh, 0)))
{
if (refresh) // Refresh in progress
{
@@ -1582,7 +1606,7 @@
thd->proc_info="Opening table";
while (!(table=open_table(thd,table_list->db,
table_list->real_name,table_list->alias,
- &refresh)) && refresh) ;
+ &refresh, 0)) && refresh) ;
if (table)
{
#if defined( __WIN__) || defined(OS2)
--- 1.198/sql/sql_table.cc 2005-07-20 21:18:57 +02:00
+++ 1.199/sql/sql_table.cc 2005-08-31 19:24:47 +02:00
@@ -882,11 +882,18 @@
don't want to delete from it) 2) it would be written before the CREATE
TABLE, which is a wrong order. So we keep binary logging disabled when we
open_table().
+
+ When calling this function, one can already have locked tables.
+ If these become refreshed until open_table(), they must not be closed
+ by open_table(). Otherwise the THR_LOCK_DATA would be freed, and at
+ command end, mysql_unlock_tables() might crash. To prevent this, we
+ instruct open_table() to ignore flushes. (Bug #12845)
*/
tmp_disable_binlog(thd);
if (!mysql_create_table(thd,db,name,create_info,*extra_fields,*keys,0))
{
- if (!(table=open_table(thd,db,name,name,(bool*) 0)))
+ if (! (table= open_table(thd, db, name, name,
+ (bool*) 0, MYSQL_LOCK_IGNORE_FLUSH)))
quick_rm_table(create_info->db_type,db,table_case_name(create_info,name));
}
reenable_binlog(thd);
@@ -1931,7 +1938,17 @@
DBUG_RETURN(error);
}
if (table->tmp_table)
- new_table=open_table(thd,new_db,tmp_name,tmp_name,0);
+ {
+ /*
+ The old table is still locked. If it becomes refreshed until
+ open_table(), it must not be closed by open_table().
+ Otherwise the THR_LOCK_DATA would be freed, and at command end,
+ mysql_unlock_tables() might crash. To prevent this, we instruct
+ open_table() to ignore flushes. (Bug #12845)
+ */
+ new_table= open_table(thd, new_db, tmp_name, tmp_name,
+ 0, MYSQL_LOCK_IGNORE_FLUSH);
+ }
else
{
char path[FN_REFLEN];
| Thread |
|---|
| • bk commit into 4.0 tree (ingo:1.2143) BUG#12845 | ingo | 31 Aug |