Below is the list of changes that have just been committed into a local
5.1 repository of mkindahl. When mkindahl 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.2119 06/02/23 13:34:03 mats@stripped +4 -0
Bug#17181 (mysqlslap test server crash):
Moving assignments to table_map_id for thread-safe handling of
table shares.
sql/table.cc
1.210 06/02/23 13:33:54 mats@stripped +28 -18
Setting default values of table_map_id and table_map_version inside
alloc_table_share() and init_tmp_table_share().
Removing the settings from open_table_from_share().
sql/sql_base.cc
1.304 06/02/23 13:33:53 mats@stripped +35 -26
Assign_new_table_id() now takes a table share instead of a table.
Moving call to assign_new_table_id() into get_table_share().
sql/mysql_priv.h
1.379 06/02/23 13:33:53 mats@stripped +1 -1
New protptype for assign_new_table_id().
sql/ha_ndbcluster_binlog.cc
1.18 06/02/23 13:33:53 mats@stripped +1 -1
Assign_new_table_id() now takes table share instead of table.
# 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: mats
# Host: dl145k.mysql.com
# Root: /users/mkindahl/bk/b17181-mysql-5.1-new
--- 1.378/sql/mysql_priv.h 2006-02-13 08:53:41 +01:00
+++ 1.379/sql/mysql_priv.h 2006-02-23 13:33:53 +01:00
@@ -657,7 +657,7 @@
void table_cache_free(void);
bool table_def_init(void);
void table_def_free(void);
-void assign_new_table_id(TABLE *table);
+void assign_new_table_id(TABLE_SHARE *share);
uint cached_open_tables(void);
uint cached_table_definitions(void);
void kill_mysql(void);
--- 1.303/sql/sql_base.cc 2006-02-13 20:34:30 +01:00
+++ 1.304/sql/sql_base.cc 2006-02-23 13:33:53 +01:00
@@ -313,6 +313,22 @@
conflicts
*/
(void) pthread_mutex_lock(&share->mutex);
+
+ /*
+ We assign a new table id under the protection of the LOCK_open and
+ the share's own mutex. We do this insted of creating a new mutex
+ and using it for the sole purpose of serializing accesses to a
+ static variable, we assign the table id here. We assign it to the
+ share before inserting it into the table_def_cache to be really
+ sure that it cannot be read from the cache without having a table
+ id assigned.
+
+ CAVEAT. This means that the table cannot be used for
+ binlogging/replication purposes, unless get_table_share() has been
+ called directly or indirectly.
+ */
+ assign_new_table_id(share);
+
if (my_hash_insert(&table_def_cache, (byte*) share))
{
#ifdef NOT_YET
@@ -2383,43 +2399,50 @@
/*
- Function to assign a new table map id to a table.
+ Function to assign a new table map id to a table share.
PARAMETERS
- table - Pointer to table structure
+ share - Pointer to table share structure
PRE-CONDITION(S)
- table is non-NULL
+ share is non-NULL
The LOCK_open mutex is locked
+ The share->mutex is locked
POST-CONDITION(S)
- table->s->table_map_id is given a value that with a high certainty
- is not used by any other table.
+ share->table_map_id is given a value that with a high certainty is
+ not used by any other table (the only case where a table id can be
+ reused is on wrap-around, which means more than 4 billion table
+ shares open at the same time).
- table->s->table_map_id is not ULONG_MAX.
+ share->table_map_id is not ULONG_MAX.
*/
-void assign_new_table_id(TABLE *table)
+void assign_new_table_id(TABLE_SHARE *share)
{
static ulong last_table_id= ULONG_MAX;
- DBUG_ENTER("assign_new_table_id(TABLE*)");
+ DBUG_ENTER("assign_new_table_id");
/* Preconditions */
- DBUG_ASSERT(table != NULL);
+ DBUG_ASSERT(share != NULL);
safe_mutex_assert_owner(&LOCK_open);
+ safe_mutex_assert_owner(&share->mutex);
ulong tid= ++last_table_id; /* get next id */
- /* There is one reserved number that cannot be used. */
+ /*
+ There is one reserved number that cannot be used. Remember to
+ change this when 6-byte global table id's are introduced.
+ */
if (unlikely(tid == ULONG_MAX))
tid= ++last_table_id;
- table->s->table_map_id= tid;
+ share->table_map_id= tid;
DBUG_PRINT("info", ("table_id=%lu", tid));
/* Post conditions */
- DBUG_ASSERT(table->s->table_map_id != ULONG_MAX);
+ DBUG_ASSERT(share->table_map_id != ULONG_MAX);
DBUG_VOID_RETURN;
}
@@ -2572,20 +2595,6 @@
goto err;
break;
}
-
- /*
- We assign a new table id under the protection of the LOCK_open
- mutex. We assign a new table id here instead of inside openfrm()
- since that function can be used without acquiring any lock (e.g.,
- inside ha_create_table()). Insted of creatint a new mutex and
- using it for the sole purpose of serializing accesses to a static
- variable, we assign the table id here.
-
- CAVEAT. This means that the table cannot be used for
- binlogging/replication purposes, unless open_table() has been called
- directly or indirectly.
- */
- assign_new_table_id(entry);
if (Table_triggers_list::check_n_load(thd, share->db.str,
share->table_name.str, entry, 0))
--- 1.209/sql/table.cc 2006-02-14 20:10:43 +01:00
+++ 1.210/sql/table.cc 2006-02-23 13:33:54 +01:00
@@ -130,6 +130,24 @@
share->version= refresh_version;
share->flush_version= flush_version;
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ This constant is used to mark that no table map version has been
+ assigned. No arithmetic is done on the value: it will be
+ overwritten with a value taken from MYSQL_BIN_LOG.
+ */
+ share->table_map_version= ~(ulonglong)0;
+
+ /*
+ Since alloc_table_share() can be called without any locking (for
+ example, ha_create_table... functions), we do not assign a table
+ map id here. Instead we assign a value that is not used
+ elsewhere, and then assign a table map id inside open_table()
+ under the protection of the LOCK_open mutex.
+ */
+ share->table_map_id= ULONG_MAX;
+#endif
+
memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root));
pthread_mutex_init(&share->mutex, MY_MUTEX_INIT_FAST);
pthread_cond_init(&share->cond, NULL);
@@ -180,6 +198,15 @@
share->path.length= share->normalized_path.length= strlen(path);
share->frm_version= FRM_VER_TRUE_VARCHAR;
+#ifdef HAVE_ROW_BASED_REPLICATION
+ /*
+ Temporary tables are not replicated, but we set up these fields
+ anyway to be able to catch errors.
+ */
+ share->table_map_version= ~(ulonglong)0;
+ share->table_map_id= ULONG_MAX;
+#endif
+
DBUG_VOID_RETURN;
}
@@ -371,6 +398,7 @@
share->error= error;
open_table_error(share, error, (share->open_errno= my_errno), 0);
}
+
DBUG_RETURN(error);
}
@@ -1503,24 +1531,6 @@
*root_ptr= old_root;
thd->status_var.opened_tables++;
-#ifdef HAVE_REPLICATION
-
- /*
- This constant is used to mark that no table map version has been
- assigned. No arithmetic is done on the value: it will be
- overwritten with a value taken from MYSQL_BIN_LOG.
- */
- share->table_map_version= ~(ulonglong)0;
-
- /*
- Since openfrm() can be called without any locking (for example,
- ha_create_table... functions), we do not assign a table map id
- here. Instead we assign a value that is not used elsewhere, and
- then assign a table map id inside open_table() under the
- protection of the LOCK_open mutex.
- */
- share->table_map_id= ULONG_MAX;
-#endif
DBUG_RETURN (0);
--- 1.17/sql/ha_ndbcluster_binlog.cc 2006-02-16 03:24:44 +01:00
+++ 1.18/sql/ha_ndbcluster_binlog.cc 2006-02-23 13:33:53 +01:00
@@ -310,7 +310,7 @@
table= 0;
break;
}
- assign_new_table_id(table);
+ assign_new_table_id(table_share);
if (!table->record[1] || table->record[1] == table->record[0])
{
table->record[1]= alloc_root(&table->mem_root,
| Thread |
|---|
| • bk commit into 5.1 tree (mats:1.2119) BUG#17181 | Mats Kindahl | 23 Feb |