Commit 546c6eb3 authored by heikki@donna.mysql.fi's avatar heikki@donna.mysql.fi

dict0dict.h InnoDB now tries to provide autoinc column value from a counter table in data dict

dict0mem.h	InnoDB now tries to provide autoinc column value from a counter table in data dict
sync0sync.h	InnoDB now tries to provide autoinc column value from a counter table in data dict
univ.i  	InnoDB now tries to provide autoinc column value from a counter table in data dict
dict0dict.c	InnoDB now tries to provide autoinc column value from a counter table in data dict
dict0mem.c	InnoDB now tries to provide autoinc column value from a counter table in data dict
sync0sync.c	InnoDB now tries to provide autoinc column value from a counter table in data dict
ha_innobase.cc	InnoDB now tries to provide autoinc column value from a counter table in data dict
parent 1970e436
...@@ -235,6 +235,71 @@ dict_table_get_index_noninline( ...@@ -235,6 +235,71 @@ dict_table_get_index_noninline(
return(dict_table_get_index(table, name)); return(dict_table_get_index(table, name));
} }
/************************************************************************
Initializes the autoinc counter. It is not an error to initialize already
initialized counter. */
void
dict_table_autoinc_initialize(
/*==========================*/
dict_table_t* table, /* in: table */
ib_longlong value) /* in: value which was assigned to a row */
{
mutex_enter(&(table->autoinc_mutex));
table->autoinc_inited = TRUE;
table->autoinc = value;
mutex_exit(&(table->autoinc_mutex));
}
/************************************************************************
Gets the next autoinc value, 0 if not yet initialized. */
ib_longlong
dict_table_autoinc_get(
/*===================*/
/* out: value for a new row, or 0 */
dict_table_t* table) /* in: table */
{
ib_longlong value;
mutex_enter(&(table->autoinc_mutex));
if (!table->autoinc_inited) {
value = 0;
} else {
table->autoinc = table->autoinc + 1;
value = table->autoinc;
}
mutex_exit(&(table->autoinc_mutex));
return(value);
}
/************************************************************************
Updates the autoinc counter if the value supplied is bigger than the
current value. If not inited, does nothing. */
void
dict_table_autoinc_update(
/*======================*/
dict_table_t* table, /* in: table */
ib_longlong value) /* in: value which was assigned to a row */
{
mutex_enter(&(table->autoinc_mutex));
if (table->autoinc_inited) {
if (value > table->autoinc) {
table->autoinc = value;
}
}
mutex_exit(&(table->autoinc_mutex));
}
/************************************************************************ /************************************************************************
Looks for column n in an index. */ Looks for column n in an index. */
...@@ -568,6 +633,8 @@ dict_table_remove_from_cache( ...@@ -568,6 +633,8 @@ dict_table_remove_from_cache(
/* Remove table from LRU list of tables */ /* Remove table from LRU list of tables */
UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table); UT_LIST_REMOVE(table_LRU, dict_sys->table_LRU, table);
mutex_free(&(table->autoinc_mutex));
size = mem_heap_get_size(table->heap); size = mem_heap_get_size(table->heap);
ut_ad(dict_sys->size >= size); ut_ad(dict_sys->size >= size);
......
...@@ -71,6 +71,11 @@ dict_mem_table_create( ...@@ -71,6 +71,11 @@ dict_mem_table_create(
table->stat_modif_counter = 0; table->stat_modif_counter = 0;
mutex_create(&(table->autoinc_mutex));
mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX);
table->autoinc_inited = FALSE;
table->magic_n = DICT_TABLE_MAGIC_N; table->magic_n = DICT_TABLE_MAGIC_N;
return(table); return(table);
......
...@@ -88,6 +88,32 @@ ulint ...@@ -88,6 +88,32 @@ ulint
dict_col_get_clust_pos( dict_col_get_clust_pos(
/*===================*/ /*===================*/
dict_col_t* col); dict_col_t* col);
/************************************************************************
Initializes the autoinc counter. It is not an error to initialize already
initialized counter. */
void
dict_table_autoinc_initialize(
/*==========================*/
dict_table_t* table, /* in: table */
ib_longlong value); /* in: value which was assigned to a row */
/************************************************************************
Gets the next autoinc value, 0 if not yet initialized. */
ib_longlong
dict_table_autoinc_get(
/*===================*/
/* out: value for a new row, or 0 */
dict_table_t* table); /* in: table */
/************************************************************************
Updates the autoinc counter if the value supplied is bigger than the
current value. If not inited, does nothing. */
void
dict_table_autoinc_update(
/*======================*/
dict_table_t* table, /* in: table */
ib_longlong value); /* in: value which was assigned to a row */
/************************************************************************** /**************************************************************************
Adds a table object to the dictionary cache. */ Adds a table object to the dictionary cache. */
......
...@@ -302,6 +302,16 @@ struct dict_table_struct{ ...@@ -302,6 +302,16 @@ struct dict_table_struct{
for MySQL SHOW TABLE STATUS; this counter for MySQL SHOW TABLE STATUS; this counter
is not protected by any latch, because this is not protected by any latch, because this
is only used for heuristics */ is only used for heuristics */
/*----------------------*/
mutex_t autoinc_mutex;
/* mutex protecting the autoincrement
counter */
ibool autoinc_inited;
/* TRUE if the autoinc counter has been
inited; MySQL gets the init value by executing
SELECT MAX(auto inc column) */
ib_longlong autoinc;/* autoinc counter value already given to
a row */
ulint magic_n;/* magic number */ ulint magic_n;/* magic number */
}; };
#define DICT_TABLE_MAGIC_N 76333786 #define DICT_TABLE_MAGIC_N 76333786
......
...@@ -372,6 +372,7 @@ Memory pool mutex */ ...@@ -372,6 +372,7 @@ Memory pool mutex */
latching order checking */ latching order checking */
#define SYNC_LEVEL_NONE 2000 /* default: level not defined */ #define SYNC_LEVEL_NONE 2000 /* default: level not defined */
#define SYNC_DICT 1000 #define SYNC_DICT 1000
#define SYNC_DICT_AUTOINC_MUTEX 999
#define SYNC_PURGE_IS_RUNNING 997 #define SYNC_PURGE_IS_RUNNING 997
#define SYNC_DICT_HEADER 995 #define SYNC_DICT_HEADER 995
#define SYNC_IBUF_HEADER 914 #define SYNC_IBUF_HEADER 914
......
...@@ -155,6 +155,12 @@ typedef unsigned long int ulint; ...@@ -155,6 +155,12 @@ typedef unsigned long int ulint;
typedef long int lint; typedef long int lint;
#ifdef __WIN__
typedef __int64 ib_longlong;
#else
typedef longlong ib_longlong;
#endif
/* The following type should be at least a 64-bit floating point number */ /* The following type should be at least a 64-bit floating point number */
typedef double utfloat; typedef double utfloat;
......
...@@ -1001,6 +1001,8 @@ sync_thread_add_level( ...@@ -1001,6 +1001,8 @@ sync_thread_add_level(
&& !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX) && !sync_thread_levels_contain(array, SYNC_IBUF_MUTEX)
&& !sync_thread_levels_contain(array, && !sync_thread_levels_contain(array,
SYNC_IBUF_PESS_INSERT_MUTEX)); SYNC_IBUF_PESS_INSERT_MUTEX));
} else if (level == SYNC_DICT_AUTOINC_MUTEX) {
ut_a(sync_thread_levels_g(array, SYNC_DICT_AUTOINC_MUTEX));
} else if (level == SYNC_DICT_HEADER) { } else if (level == SYNC_DICT_HEADER) {
ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER)); ut_a(sync_thread_levels_g(array, SYNC_DICT_HEADER));
} else if (level == SYNC_PURGE_IS_RUNNING) { } else if (level == SYNC_PURGE_IS_RUNNING) {
......
...@@ -1242,6 +1242,7 @@ ha_innobase::write_row( ...@@ -1242,6 +1242,7 @@ ha_innobase::write_row(
{ {
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt; row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
int error; int error;
longlong auto_inc;
DBUG_ENTER("ha_innobase::write_row"); DBUG_ENTER("ha_innobase::write_row");
...@@ -1261,10 +1262,43 @@ ha_innobase::write_row( ...@@ -1261,10 +1262,43 @@ ha_innobase::write_row(
make sure all columns are fetched in the select done by make sure all columns are fetched in the select done by
update_auto_increment */ update_auto_increment */
/* Fetch the value the user possibly has set in the
autoincrement field */
auto_inc = table->next_number_field->val_int();
if (auto_inc != 0) {
/* This call will calculate the max of the
current value and the value supplied by the user, if
the auto_inc counter is already initialized
for the table */
dict_table_autoinc_update(prebuilt->table, auto_inc);
} else {
auto_inc = dict_table_autoinc_get(prebuilt->table);
/* If auto_inc is now != 0 the autoinc counter
was already initialized for the table: we can give
the new value for MySQL to place in the field */
if (auto_inc != 0) {
user_thd->next_insert_id = auto_inc;
}
}
prebuilt->in_update_remember_pos = FALSE; prebuilt->in_update_remember_pos = FALSE;
update_auto_increment(); update_auto_increment();
if (auto_inc == 0) {
/* The autoinc counter for our table was not yet
initialized, initialize it now */
auto_inc = table->next_number_field->val_int();
dict_table_autoinc_initialize(prebuilt->table,
auto_inc);
}
/* We have to set sql_stat_start to TRUE because /* We have to set sql_stat_start to TRUE because
update_auto_increment has called a select, and update_auto_increment has called a select, and
has reset that flag; row_insert_for_mysql has to has reset that flag; row_insert_for_mysql has to
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment