Commit a859c594 authored by unknown's avatar unknown

Apply InnoDB snapshot innodb-5.1-ss1751.

Bug #16979: AUTO_INC lock in InnoDB works a table level lock
  Add a table level counter that tracks the number of AUTOINC locks that are
  pending and/or granted on a table. We peek at this value to determine whether
  a transaction doing a simple INSERT in innodb_autoinc_lock_mode = 1, needs to
  acquire the AUTOINC lock or not. This change is related to Bug# 16979.
Bug #27950: Duplicate entry error in auto-inc after mysqld restart
  We check whether the AUTOINC sub-system has been initialized (first) by
  holding the AUTOINC mutex and if initialization is required then we
  initialize using our normal procedure.


storage/innobase/dict/dict0boot.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
storage/innobase/dict/dict0crea.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
storage/innobase/dict/dict0load.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
storage/innobase/dict/dict0mem.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1749:
  Add a table level counter that tracks the number of AUTOINC locks that are
  pending and/or granted on a table. We peek at this value to determine whether
  a transaction doing a simple INSERT in innodb_autoinc_lock_mode = 1, needs to
  acquire the AUTOINC lock or not. This change is related to Bug# 16979.
storage/innobase/handler/ha_innodb.cc:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1735:
  Add variable "innodb_autoinc_lock_mode"  to control the behavior of the
  AUTOINC locking. There are three modes, 0 for backward compatibility, 1 for the
  new style locking (default, safe for statement-based replication) and
  2 for no AUTOINC locking (unsafe for statement-based replication).
  
  
  Revision r1750:
  We check whether the AUTOINC sub-system has been initialized (first) by
  holding the AUTOINC mutex and if initialization is required then we
  initialize using our normal procedure. This change is related to Bug#27950.
  
  
  Revision r1746:
  Remove some code from ha_innodb.cc that was already enclosed in #if 0.
  The code was related to replication and group commit, and it was
  unreachable already as of MySQL 5.0.
  
  Approved by Heikki
  
  
  Revision r1749:
  Add a table level counter that tracks the number of AUTOINC locks that are
  pending and/or granted on a table. We peek at this value to determine whether
  a transaction doing a simple INSERT in innodb_autoinc_lock_mode = 1, needs to
  acquire the AUTOINC lock or not. This change is related to Bug# 16979.
storage/innobase/include/dict0mem.h:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1749:
  Add a table level counter that tracks the number of AUTOINC locks that are
  pending and/or granted on a table. We peek at this value to determine whether
  a transaction doing a simple INSERT in innodb_autoinc_lock_mode = 1, needs to
  acquire the AUTOINC lock or not. This change is related to Bug# 16979.
  
  
  
  Revision r1747:
  Correct an outdated comment about dict_table_t:col_names that should have
  been adjusted in r1719, or r1264 in branches/zip.
storage/innobase/include/mem0mem.ic:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1744:
  Merge r1739 from branches/zip:
  
  mem_heap_free_heap_top(): Declare the memory freed with UNIV_MEM_FREE().
  Before this change, the memory freed by mem_heap_empty() was not completely
  flagged free in UNIV_DEBUG_VALGRIND builds.  After this change, Valgrind
  will hopefully catch all errors caught by UNIV_MEM_DEBUG.
storage/innobase/include/sync0rw.ic:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1751:
  rw_lock_s_lock_func(): Correct a typo in a comment.
storage/innobase/include/trx0trx.h:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1742:
  Remove some unused fields of trx_t: mysql_master_log_file_name,
  mysql_master_log_pos, repl_wait_binlog_name, repl_wait_binlog_pos.
  
  Approved by Heikki.
storage/innobase/lock/lock0lock.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1749:
  Add a table level counter that tracks the number of AUTOINC locks that are
  pending and/or granted on a table. We peek at this value to determine whether
  a transaction doing a simple INSERT in innodb_autoinc_lock_mode = 1, needs to
  acquire the AUTOINC lock or not. This change is related to Bug# 16979.
storage/innobase/mtr/mtr0log.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
storage/innobase/pars/pars0pars.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
storage/innobase/srv/srv0srv.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
storage/innobase/trx/trx0sys.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1743:
  trx_sys_print_mysql_binlog_offset_from_page(): Enclose the definition
  in #ifdef UNIV_HOTBACKUP, to match the function declaration.
storage/innobase/trx/trx0trx.c:
  Apply InnoDB snapshot innodb-5.1-ss1751.
  
  Revision r1742:
  Remove some unused fields of trx_t: mysql_master_log_file_name,
  mysql_master_log_pos, repl_wait_binlog_name, repl_wait_binlog_pos.
  
  Approved by Heikki.
parent 6d4b3c58
......@@ -211,6 +211,7 @@ dict_boot(void)
dict_table_t* table;
dict_index_t* index;
dict_hdr_t* dict_hdr;
mem_heap_t* heap;
mtr_t mtr;
mtr_start(&mtr);
......@@ -218,6 +219,8 @@ dict_boot(void)
/* Create the hash tables etc. */
dict_init();
heap = mem_heap_create(450);
mutex_enter(&(dict_sys->mutex));
/* Get the dictionary header */
......@@ -244,19 +247,20 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_TABLES", DICT_HDR_SPACE, 8, 0);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "N_COLS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "MIX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "MIX_LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "CLUSTER_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "N_COLS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "MIX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "MIX_LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "CLUSTER_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
table->id = DICT_TABLES_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_tables = table;
mem_heap_empty(heap);
index = dict_mem_index_create("SYS_TABLES", "CLUST_IND",
DICT_HDR_SPACE,
......@@ -283,18 +287,19 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_COLUMNS", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "MTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "PRTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "PREC", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "MTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PRTYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "LEN", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PREC", DATA_INT, 0, 4);
table->id = DICT_COLUMNS_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_columns = table;
mem_heap_empty(heap);
index = dict_mem_index_create("SYS_COLUMNS", "CLUST_IND",
DICT_HDR_SPACE,
......@@ -311,13 +316,13 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_INDEXES", DICT_HDR_SPACE, 7, 0);
dict_mem_table_add_col(table, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "N_FIELDS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "PAGE_NO", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TABLE_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "N_FIELDS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "TYPE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "SPACE", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "PAGE_NO", DATA_INT, 0, 4);
/* The '+ 2' below comes from the 2 system fields */
#if DICT_SYS_INDEXES_PAGE_NO_FIELD != 6 + 2
......@@ -331,8 +336,9 @@ dict_boot(void)
#endif
table->id = DICT_INDEXES_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_indexes = table;
mem_heap_empty(heap);
index = dict_mem_index_create("SYS_INDEXES", "CLUST_IND",
DICT_HDR_SPACE,
......@@ -349,13 +355,14 @@ dict_boot(void)
/*-------------------------*/
table = dict_mem_table_create("SYS_FIELDS", DICT_HDR_SPACE, 3, 0);
dict_mem_table_add_col(table, "INDEX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, "COL_NAME", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "INDEX_ID", DATA_BINARY, 0, 0);
dict_mem_table_add_col(table, heap, "POS", DATA_INT, 0, 4);
dict_mem_table_add_col(table, heap, "COL_NAME", DATA_BINARY, 0, 0);
table->id = DICT_FIELDS_ID;
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
dict_sys->sys_fields = table;
mem_heap_free(heap);
index = dict_mem_index_create("SYS_FIELDS", "CLUST_IND",
DICT_HDR_SPACE,
......
......@@ -960,7 +960,7 @@ dict_create_table_step(
if (node->state == TABLE_ADD_TO_CACHE) {
dict_table_add_to_cache(node->table);
dict_table_add_to_cache(node->table, node->heap);
err = DB_SUCCESS;
}
......
......@@ -423,7 +423,8 @@ dict_load_columns(
ut_a(name_of_col_is(sys_columns, sys_index, 8, "PREC"));
dict_mem_table_add_col(table, name, mtype, prtype, col_len);
dict_mem_table_add_col(table, heap, name,
mtype, prtype, col_len);
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
}
......@@ -746,7 +747,7 @@ dict_load_table(
ut_ad(mutex_own(&(dict_sys->mutex)));
heap = mem_heap_create(1000);
heap = mem_heap_create(32000);
mtr_start(&mtr);
......@@ -852,7 +853,9 @@ dict_load_table(
dict_load_columns(table, heap);
dict_table_add_to_cache(table);
dict_table_add_to_cache(table, heap);
mem_heap_empty(heap);
dict_load_indexes(table, heap);
......
......@@ -95,6 +95,10 @@ dict_mem_table_create(
default to 1 here.*/
table->autoinc_increment = 1;
/* The number of transactions that are either waiting on the
AUTOINC lock or have been granted the lock. */
table->n_waiting_or_granted_auto_inc_locks = 0;
#ifdef UNIV_DEBUG
table->magic_n = DICT_TABLE_MAGIC_N;
#endif /* UNIV_DEBUG */
......
......@@ -92,11 +92,15 @@ extern "C" {
#include "../storage/innobase/include/ha_prototypes.h"
}
static const long AUTOINC_OLD_STYLE_LOCKING = 0;
static const long AUTOINC_NEW_STYLE_LOCKING = 1;
static const long AUTOINC_NO_LOCKING = 2;
static long innobase_mirrored_log_groups, innobase_log_files_in_group,
innobase_log_buffer_size, innobase_buffer_pool_awe_mem_mb,
innobase_additional_mem_pool_size, innobase_file_io_threads,
innobase_lock_wait_timeout, innobase_force_recovery,
innobase_open_files;
innobase_open_files, innobase_autoinc_lock_mode;
static long long innobase_buffer_pool_size, innobase_log_file_size;
......@@ -1928,110 +1932,6 @@ innobase_commit(
DBUG_RETURN(0);
}
#if 0
/* TODO: put the
MySQL-4.1 functionality back to 5.0. This is needed to get InnoDB Hot Backup
to work. */
/*********************************************************************
This is called when MySQL writes the binlog entry for the current
transaction. Writes to the InnoDB tablespace info which tells where the
MySQL binlog entry for the current transaction ended. Also commits the
transaction inside InnoDB but does NOT flush InnoDB log files to disk.
To flush you have to call innobase_commit_complete(). We have separated
flushing to eliminate the bottleneck of LOCK_log in log.cc which disabled
InnoDB's group commit capability. */
static
int
innobase_report_binlog_offset_and_commit(
/*=====================================*/
/* out: 0 */
handlerton *hton, /* in: Innodb handlerton */
THD* thd, /* in: user thread */
void* trx_handle, /* in: InnoDB trx handle */
char* log_file_name, /* in: latest binlog file name */
my_off_t end_offset) /* in: the offset in the binlog file
up to which we wrote */
{
trx_t* trx;
trx = (trx_t*)trx_handle;
ut_a(trx != NULL);
trx->mysql_log_file_name = log_file_name;
trx->mysql_log_offset = (ib_longlong)end_offset;
trx->flush_log_later = TRUE;
innobase_commit(hton, thd, TRUE);
trx->flush_log_later = FALSE;
return(0);
}
/***********************************************************************
This function stores the binlog offset and flushes logs. */
static
void
innobase_store_binlog_offset_and_flush_log(
/*=======================================*/
char* binlog_name, /* in: binlog name */
longlong offset) /* in: binlog offset */
{
mtr_t mtr;
assert(binlog_name != NULL);
/* Start a mini-transaction */
mtr_start_noninline(&mtr);
/* Update the latest MySQL binlog name and offset info
in trx sys header */
trx_sys_update_mysql_binlog_offset(
binlog_name,
offset,
TRX_SYS_MYSQL_LOG_INFO, &mtr);
/* Commits the mini-transaction */
mtr_commit(&mtr);
/* Synchronous flush of the log buffer to disk */
log_buffer_flush_to_disk();
}
/*********************************************************************
This is called after MySQL has written the binlog entry for the current
transaction. Flushes the InnoDB log files to disk if required. */
static
int
innobase_commit_complete(
/*=====================*/
/* out: 0 */
THD* thd) /* in: user thread */
{
trx_t* trx;
trx = thd_to_trx(thd);
if (trx && trx->active_trans) {
trx->active_trans = 0;
if (UNIV_UNLIKELY(srv_flush_log_at_trx_commit == 0)) {
return(0);
}
trx_commit_complete_for_mysql(trx);
}
return(0);
}
#endif
/*********************************************************************
Rolls back a transaction or the latest SQL statement. */
static
......@@ -3353,24 +3253,46 @@ ha_innobase::innobase_autoinc_lock(void)
{
ulint error = DB_SUCCESS;
if (thd_sql_command(user_thd) == SQLCOM_INSERT) {
switch (innobase_autoinc_lock_mode) {
case AUTOINC_NO_LOCKING:
/* Acquire only the AUTOINC mutex. */
dict_table_autoinc_lock(prebuilt->table);
break;
/* We peek at the dict_table_t::auto_inc_lock to check if
another statement has locked it */
if (prebuilt->trx->auto_inc_lock != NULL) {
/* Release the mutex to avoid deadlocks */
dict_table_autoinc_unlock(prebuilt->table);
case AUTOINC_NEW_STYLE_LOCKING:
/* For simple (single/multi) row INSERTs, we fallback to the
old style only if another transaction has already acquired
the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
etc. type of statement. */
if (thd_sql_command(user_thd) == SQLCOM_INSERT) {
dict_table_t* table = prebuilt->table;
goto acquire_auto_inc_lock;
}
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock(table);
/* We need to check that another transaction isn't
already holding the AUTOINC lock on the table. */
if (table->n_waiting_or_granted_auto_inc_locks) {
/* Release the mutex to avoid deadlocks. */
dict_table_autoinc_unlock(table);
} else {
acquire_auto_inc_lock:
break;
}
}
/* Fall through to old style locking. */
case AUTOINC_OLD_STYLE_LOCKING:
error = row_lock_table_autoinc_for_mysql(prebuilt);
if (error == DB_SUCCESS) {
/* Acquire the AUTOINC mutex. */
dict_table_autoinc_lock(prebuilt->table);
}
break;
default:
ut_error;
}
return(ulong(error));
......@@ -3610,6 +3532,7 @@ ha_innobase::write_row(
if (auto_inc > prebuilt->last_value) {
set_max_autoinc:
ut_a(prebuilt->table->autoinc_increment > 0);
auto_inc += prebuilt->table->autoinc_increment;
innobase_set_max_autoinc(auto_inc);
......@@ -3884,6 +3807,14 @@ ha_innobase::delete_row(
if (table->found_next_number_field && record == table->record[0]) {
ulonglong dummy = 0;
/* First check whether the AUTOINC sub-system has been
initialized using the AUTOINC mutex. If not then we
do it the "proper" way, by acquiring the heavier locks. */
dict_table_autoinc_lock(prebuilt->table);
if (!prebuilt->table->autoinc_inited) {
dict_table_autoinc_unlock(prebuilt->table);
error = innobase_get_auto_increment(&dummy);
if (error == DB_SUCCESS) {
......@@ -3891,6 +3822,9 @@ ha_innobase::delete_row(
} else {
goto error_exit;
}
} else {
dict_table_autoinc_unlock(prebuilt->table);
}
}
if (!prebuilt->upd_node) {
......@@ -7411,13 +7345,24 @@ ha_innobase::get_auto_increment(
*nb_reserved_values = prebuilt->trx->n_autoinc_rows;
/* With old style AUTOINC locking we only update the table's
AUTOINC counter after attempting to insert the row. */
if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) {
/* Compute the last value in the interval */
prebuilt->last_value = *first_value + (*nb_reserved_values * increment);
prebuilt->last_value = *first_value +
(*nb_reserved_values * increment);
ut_a(prebuilt->last_value >= *first_value);
/* Update the table autoinc variable */
dict_table_autoinc_update(prebuilt->table, prebuilt->last_value);
dict_table_autoinc_update(
prebuilt->table, prebuilt->last_value);
} else {
/* This will force write_row() into attempting an update
of the table's AUTOINC counter. */
prebuilt->last_value = 0;
}
/* The increment to be used to increase the AUTOINC value, we use
this in write_row() and update_row() to increase the autoinc counter
......@@ -8080,6 +8025,17 @@ static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path,
"Path to individual files and their sizes.",
NULL, NULL, NULL);
static MYSQL_SYSVAR_LONG(autoinc_lock_mode, innobase_autoinc_lock_mode,
PLUGIN_VAR_RQCMDARG,
"The AUTOINC lock modes supported by InnoDB:\n"
" 0 => Old style AUTOINC locking (for backward compatibility)\n"
" 1 => New style AUTOINC locking\n"
" 2 => No AUTOINC locking (unsafe for SBR)",
NULL, NULL,
AUTOINC_NEW_STYLE_LOCKING, /* Default setting */
AUTOINC_OLD_STYLE_LOCKING, /* Minimum value */
AUTOINC_NO_LOCKING, 0); /* Maximum value */
static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(additional_mem_pool_size),
MYSQL_SYSVAR(autoextend_increment),
......@@ -8118,6 +8074,7 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
MYSQL_SYSVAR(table_locks),
MYSQL_SYSVAR(thread_concurrency),
MYSQL_SYSVAR(thread_sleep_delay),
MYSQL_SYSVAR(autoinc_lock_mode),
NULL
};
......
......@@ -315,11 +315,11 @@ struct dict_table_struct{
unsigned n_cols:10;/* number of columns */
dict_col_t* cols; /* array of column descriptions */
const char* col_names;
/* n_def column names packed in an
"name1\0name2\0...nameN\0" array. until
n_def reaches n_cols, this is allocated with
ut_malloc, and the final size array is
allocated through the table's heap. */
/* Column names packed in a character string
"name1\0name2\0...nameN\0". Until
the string contains n_cols, it will be
allocated from a temporary heap. The final
string will be allocated from table->heap. */
hash_node_t name_hash; /* hash chain node */
hash_node_t id_hash; /* hash chain node */
UT_LIST_BASE_NODE_T(dict_index_t)
......@@ -416,6 +416,16 @@ struct dict_table_struct{
/* The increment step of the auto increment
column. Value must be greater than or equal
to 1 */
ulong n_waiting_or_granted_auto_inc_locks;
/* This counter is used to track the number
of granted and pending autoinc locks on this
table. This value is set after acquiring the
kernel mutex but we peek the contents to
determine whether other transactions have
acquired the AUTOINC lock or not. Of course
only one transaction can be granted the
lock but there can be multiple waiters. */
#ifdef UNIV_DEBUG
ulint magic_n;/* magic number */
# define DICT_TABLE_MAGIC_N 76333786
......
......@@ -271,15 +271,19 @@ mem_heap_free_heap_top(
ut_ad(mem_block_get_start(block) <= mem_block_get_free(block));
/* In the debug version erase block from top up */
mem_erase_buf(old_top, (byte*)block + block->len - old_top);
{
ulint len = (byte*)block + block->len - old_top;
mem_erase_buf(old_top, len);
UNIV_MEM_FREE(old_top, len);
}
/* Update allocated memory count */
mutex_enter(&mem_hash_mutex);
mem_current_allocated_memory -= (total_size - size);
mutex_exit(&mem_hash_mutex);
#endif
#else /* UNIV_MEM_DEBUG */
UNIV_MEM_FREE(old_top, (byte*)block + block->len - old_top);
#endif /* UNIV_MEM_DEBUG */
/* If free == start, we may free the block if it is not the first
one */
......
......@@ -231,7 +231,7 @@ rw_lock_s_lock_func(
owns an s-lock here, it may end up in a deadlock with another thread
which requests an x-lock here. Therefore, we will forbid recursive
s-locking of a latch: the following assert will warn the programmer
of the possibility of a tjis kind of deadlock. If we want to implement
of the possibility of this kind of a deadlock. If we want to implement
safe recursive s-locking, we should keep in a list the thread ids of
the threads which have s-locked a latch. This would use some CPU
time. */
......
......@@ -482,31 +482,6 @@ struct trx_struct{
ib_longlong mysql_log_offset;/* if MySQL binlog is used, this field
contains the end offset of the binlog
entry */
const char* mysql_master_log_file_name;
/* if the database server is a MySQL
replication slave, we have here the
master binlog name up to which
replication has processed; otherwise
this is a pointer to a null
character */
ib_longlong mysql_master_log_pos;
/* if the database server is a MySQL
replication slave, this is the
position in the log file up to which
replication has processed */
/* A MySQL variable mysql_thd->synchronous_repl tells if we have
to use synchronous replication. See ha_innodb.cc. */
char* repl_wait_binlog_name;/* NULL, or if synchronous MySQL
replication is used, the binlog name
up to which we must communicate the
binlog to the slave, before returning
from a commit; this is the same as
mysql_log_file_name, but we allocate
and copy the name to a separate buffer
here */
ib_longlong repl_wait_binlog_pos;/* see above at
repl_wait_binlog_name */
os_thread_id_t mysql_thread_id;/* id of the MySQL thread associated
with this transaction object */
ulint mysql_process_no;/* since in Linux, 'top' reports
......
......@@ -3386,6 +3386,10 @@ lock_table_create(
ut_ad(table && trx);
ut_ad(mutex_own(&kernel_mutex));
if ((type_mode & LOCK_MODE_MASK) == LOCK_AUTO_INC) {
++table->n_waiting_or_granted_auto_inc_locks;
}
if (type_mode == LOCK_AUTO_INC) {
/* Only one trx can have the lock on the table
at a time: we may use the memory preallocated
......@@ -3436,6 +3440,9 @@ lock_table_remove_low(
if (lock == trx->auto_inc_lock) {
trx->auto_inc_lock = NULL;
ut_a(table->n_waiting_or_granted_auto_inc_locks > 0);
--table->n_waiting_or_granted_auto_inc_locks;
}
UT_LIST_REMOVE(trx_locks, trx->trx_locks, lock);
......
......@@ -517,8 +517,9 @@ mlog_parse_index(
n = mach_read_from_2(ptr);
ptr += 2;
n_uniq = mach_read_from_2(ptr);
ptr += 2;
ut_ad(n_uniq <= n);
if (end_ptr < ptr + (n + 1) * 2) {
if (end_ptr < ptr + n * 2) {
return(NULL);
}
} else {
......@@ -531,18 +532,18 @@ mlog_parse_index(
ind->table = table;
ind->n_uniq = (unsigned int) n_uniq;
if (n_uniq != n) {
ut_a(n_uniq + DATA_ROLL_PTR <= n);
ind->type = DICT_CLUSTERED;
}
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
ind->cached = TRUE;
if (comp) {
for (i = 0; i < n; i++) {
ulint len = mach_read_from_2(ptr += 2);
ulint len = mach_read_from_2(ptr);
ptr += 2;
/* The high-order bit of len is the NOT NULL flag;
the rest is 0 or 0x7fff for variable-length fields,
and 1..0x7ffe for fixed-length fields. */
dict_mem_table_add_col(
table, "DUMMY",
table, NULL, NULL,
((len + 1) & 0x7fff) <= 1
? DATA_BINARY : DATA_FIXBINARY,
len & 0x8000 ? DATA_NOT_NULL : 0,
......@@ -552,8 +553,23 @@ mlog_parse_index(
dict_table_get_nth_col(table, i),
0);
}
ptr += 2;
dict_table_add_system_columns(table, table->heap);
if (n_uniq != n) {
/* Identify DB_TRX_ID and DB_ROLL_PTR in the index. */
ut_a(DATA_TRX_ID_LEN
== dict_index_get_nth_col(ind, DATA_TRX_ID - 1
+ n_uniq)->len);
ut_a(DATA_ROLL_PTR_LEN
== dict_index_get_nth_col(ind, DATA_ROLL_PTR - 1
+ n_uniq)->len);
ind->fields[DATA_TRX_ID - 1 + n_uniq].col
= &table->cols[n + DATA_TRX_ID];
ind->fields[DATA_ROLL_PTR - 1 + n_uniq].col
= &table->cols[n + DATA_ROLL_PTR];
}
}
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
ind->cached = TRUE;
*index = ind;
return(ptr);
}
......@@ -1640,7 +1640,8 @@ pars_create_table(
while (column) {
dtype = dfield_get_type(que_node_get_val(column));
dict_mem_table_add_col(table, column->name, dtype->mtype,
dict_mem_table_add_col(table, table->heap,
column->name, dtype->mtype,
dtype->prtype, dtype->len);
column->resolved = TRUE;
column->token_type = SYM_COLUMN;
......
......@@ -907,7 +907,7 @@ srv_init(void)
/* create dummy table and index for old-style infimum and supremum */
table = dict_mem_table_create("SYS_DUMMY1",
DICT_HDR_SPACE, 1, 0);
dict_mem_table_add_col(table, "DUMMY", DATA_CHAR,
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
srv_sys->dummy_ind1 = dict_mem_index_create(
......@@ -918,7 +918,7 @@ srv_init(void)
/* create dummy table and index for new-style infimum and supremum */
table = dict_mem_table_create("SYS_DUMMY2",
DICT_HDR_SPACE, 1, DICT_TF_COMPACT);
dict_mem_table_add_col(table, "DUMMY", DATA_CHAR,
dict_mem_table_add_col(table, NULL, NULL, DATA_CHAR,
DATA_ENGLISH | DATA_NOT_NULL, 8);
srv_sys->dummy_ind2 = dict_mem_index_create(
"SYS_DUMMY2", "SYS_DUMMY2", DICT_HDR_SPACE, 0, 1);
......
......@@ -646,6 +646,7 @@ trx_sys_update_mysql_binlog_offset(
MLOG_4BYTES, mtr);
}
#ifdef UNIV_HOTBACKUP
/*********************************************************************
Prints to stderr the MySQL binlog info in the system header if the
magic number shows it valid. */
......@@ -677,6 +678,7 @@ trx_sys_print_mysql_binlog_offset_from_page(
+ TRX_SYS_MYSQL_LOG_NAME);
}
}
#endif /* UNIV_HOTBACKUP */
/*********************************************************************
Stores the MySQL binlog offset info in the trx system header if
......
......@@ -139,11 +139,6 @@ trx_create(
trx->mysql_log_file_name = NULL;
trx->mysql_log_offset = 0;
trx->mysql_master_log_file_name = "";
trx->mysql_master_log_pos = 0;
trx->repl_wait_binlog_name = NULL;
trx->repl_wait_binlog_pos = 0;
mutex_create(&trx->undo_mutex, SYNC_TRX_UNDO);
......@@ -325,11 +320,6 @@ trx_free(
trx_undo_arr_free(trx->undo_no_arr);
}
if (trx->repl_wait_binlog_name != NULL) {
mem_free(trx->repl_wait_binlog_name);
}
ut_a(UT_LIST_GET_LEN(trx->signals) == 0);
ut_a(UT_LIST_GET_LEN(trx->reply_signals) == 0);
......@@ -809,14 +799,6 @@ trx_commit_off_kernel(
trx->mysql_log_file_name = NULL;
}
if (trx->mysql_master_log_file_name[0] != '\0') {
/* This database server is a MySQL replication slave */
trx_sys_update_mysql_binlog_offset(
trx->mysql_master_log_file_name,
trx->mysql_master_log_pos,
TRX_SYS_MYSQL_MASTER_LOG_INFO, &mtr);
}
/* The following call commits the mini-transaction, making the
whole transaction committed in the file-based world, at this
log sequence number. The transaction becomes 'durable' when
......
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