mirror of
https://github.com/MariaDB/server.git
synced 2026-04-27 02:35:29 +02:00
Merge of innodb_plugin for MySQL 5.1.53 with xtradb
Fixed compiler warnings in xtradb Added back resetting of null bitmap but now in row_search_for_mysql() storage/xtradb/row/row0sel.c: Added back resetting of null bitmap but now in row_search_for_mysql()
This commit is contained in:
parent
721a6a6a6d
commit
f900b65810
24 changed files with 541 additions and 205 deletions
|
|
@ -8,10 +8,8 @@ AC_DEFUN([MY_MAINTAINER_MODE], [
|
|||
[AS_HELP_STRING([--enable-mysql-maintainer-mode],
|
||||
[Enable a MySQL maintainer-specific development environment])],
|
||||
[USE_MYSQL_MAINTAINER_MODE=$enableval],
|
||||
[USE_MYSQL_MAINTAINER_MODE=no])
|
||||
# Remove the # from following comments after merge with xtradb for 5.1.53
|
||||
# [AS_IF([test "$with_debug" != "no"],
|
||||
# [USE_MYSQL_MAINTAINER_MODE=yes], [USE_MYSQL_MAINTAINER_MODE=no])])
|
||||
[AS_IF([test "$with_debug" != "no"],
|
||||
[USE_MYSQL_MAINTAINER_MODE=yes], [USE_MYSQL_MAINTAINER_MODE=no])])
|
||||
AC_MSG_RESULT([$USE_MYSQL_MAINTAINER_MODE])
|
||||
])
|
||||
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@ pack_row(TABLE *table, MY_BITMAP const* cols,
|
|||
unsigned int null_mask= 1U;
|
||||
for ( ; (field= *p_field) ; p_field++)
|
||||
{
|
||||
DBUG_PRINT("debug", ("null_mask=%d; null_ptr=%p; row_data=%p; null_byte_count=%d",
|
||||
DBUG_PRINT("debug", ("null_mask: %d null_ptr: %p row_data: %p null_byte_count: %d",
|
||||
null_mask, null_ptr, row_data, null_byte_count));
|
||||
if (bitmap_is_set(cols, p_field - table->field))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,25 +1,73 @@
|
|||
2010-10-24 The InnoDB Team
|
||||
|
||||
* row/row0mysql.c
|
||||
Fix Bug #57700 Latching order violation in
|
||||
row_truncate_table_for_mysql()
|
||||
|
||||
2010-10-20 The InnoDB Team
|
||||
|
||||
* dict/dict0load.c
|
||||
Fix Bug #57616 Sig 11 in dict_load_table() when failed to load
|
||||
index or foreign key
|
||||
|
||||
2010-10-19 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, buf/buf0buf.c, buf/buf0flu.c, handler/ha_innodb.cc,
|
||||
ibuf/ibuf0ibuf.c, include/btr0cur.h, include/buf0flu.h,
|
||||
include/ibuf0ibuf.h, include/row0mysql.h,
|
||||
row/row0mysql.c, row/row0sel.c,
|
||||
innodb_bug56680.test, innodb_bug56680.result:
|
||||
Fix Bug #56680 InnoDB may return wrong results from a
|
||||
case-insensitive covering index
|
||||
|
||||
2010-10-18 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, handler/ha_innodb.h, innodb_bug57252.result,
|
||||
innodb_bug57252.test:
|
||||
Fix Bug#57252 disabling innobase_stats_on_metadata disables ANALYZE
|
||||
|
||||
2010-10-14 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, innodb_bug56143.result, innodb_bug56143.test:
|
||||
Fix Bug#56143 too many foreign keys causes output of show create
|
||||
table to become invalid
|
||||
|
||||
2010-10-14 The InnoDB Team
|
||||
|
||||
* srv/srv0start.c:
|
||||
Fix Bug#57397 io_handler_thread() will never cleanup
|
||||
|
||||
2010-10-11 The InnoDB Team
|
||||
|
||||
* row/row0sel.c
|
||||
Fix Bug #57345 btr_pcur_store_position abort for load with
|
||||
concurrent lock/unlock tables
|
||||
|
||||
2010-10-11 The InnoDB Team
|
||||
|
||||
* row/row0mysql.c, innodb_bug56947.result, innodb_bug56947.test:
|
||||
Fix Bug #56947 InnoDB leaks memory when failing to create a table
|
||||
|
||||
2010-10-06 The InnoDB Team
|
||||
|
||||
* row/row0mysql.c, innodb_bug57255.result, innodb_bug57255.test
|
||||
Fix Bug #Cascade Delete results in "Got error -1 from storage engine"
|
||||
|
||||
Fix Bug #57255 Cascade Delete results in "Got error -1 from
|
||||
storage engine"
|
||||
|
||||
2010-09-27 The InnoDB Team
|
||||
|
||||
* row/row0sel.c, innodb_bug56716.result, innodb_bug56716.test:
|
||||
Fix Bug #56716 InnoDB locks a record gap without locking the table
|
||||
Fix Bug#56716 InnoDB locks a record gap without locking the table
|
||||
|
||||
2010-09-06 The InnoDB Team
|
||||
* dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result
|
||||
Fix Bug #53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery
|
||||
|
||||
* dict/dict0load.c, innodb_bug53756.test innodb_bug53756.result:
|
||||
Fix Bug#53756 ALTER TABLE ADD PRIMARY KEY affects crash recovery
|
||||
|
||||
2010-08-24 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.c, dict/dict0dict.c:
|
||||
Fix Bug #55832 selects crash too easily when innodb_force_recovery>3
|
||||
Fix Bug#55832 selects crash too easily when innodb_force_recovery>3
|
||||
|
||||
2010-08-03 The InnoDB Team
|
||||
|
||||
|
|
@ -37,13 +85,13 @@
|
|||
2010-08-03 The InnoDB Team
|
||||
|
||||
* include/ut0mem.h, ut/ut0mem.c:
|
||||
Fix Bug #55627 segv in ut_free pars_lexer_close innobase_shutdown
|
||||
Fix Bug#55627 segv in ut_free pars_lexer_close innobase_shutdown
|
||||
innodb-use-sys-malloc=0
|
||||
|
||||
2010-08-01 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc
|
||||
Fix Bug #55382 Assignment with SELECT expressions takes unexpected
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#55382 Assignment with SELECT expressions takes unexpected
|
||||
S locks in READ COMMITTED
|
||||
|
||||
2010-07-27 The InnoDB Team
|
||||
|
|
@ -65,8 +113,8 @@
|
|||
|
||||
2010-06-29 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, include/btr0cur.h,
|
||||
include/row0mysql.h, row/row0merge.c, row/row0sel.c:
|
||||
* btr/btr0cur.c, include/btr0cur.h, include/row0mysql.h,
|
||||
row/row0merge.c, row/row0sel.c:
|
||||
Fix Bug#54358 READ UNCOMMITTED access failure of off-page DYNAMIC
|
||||
or COMPRESSED columns
|
||||
|
||||
|
|
|
|||
|
|
@ -1803,7 +1803,7 @@ func_exit:
|
|||
See if there is enough place in the page modification log to log
|
||||
an update-in-place.
|
||||
@return TRUE if enough place */
|
||||
static
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
btr_cur_update_alloc_zip(
|
||||
/*=====================*/
|
||||
|
|
|
|||
|
|
@ -2511,6 +2511,30 @@ wait_until_unfixed:
|
|||
bytes. */
|
||||
UNIV_MEM_ASSERT_RW(&block->page, sizeof block->page);
|
||||
#endif
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
if (mode == BUF_GET_IF_IN_POOL && ibuf_debug) {
|
||||
/* Try to evict the block from the buffer pool, to use the
|
||||
insert buffer as much as possible. */
|
||||
|
||||
if (buf_LRU_free_block(&block->page, TRUE, NULL)
|
||||
== BUF_LRU_FREED) {
|
||||
buf_pool_mutex_exit();
|
||||
mutex_exit(&block->mutex);
|
||||
fprintf(stderr,
|
||||
"innodb_change_buffering_debug evict %u %u\n",
|
||||
(unsigned) space, (unsigned) offset);
|
||||
return(NULL);
|
||||
} else if (buf_flush_page_try(block)) {
|
||||
fprintf(stderr,
|
||||
"innodb_change_buffering_debug flush %u %u\n",
|
||||
(unsigned) space, (unsigned) offset);
|
||||
guess = block;
|
||||
goto loop;
|
||||
}
|
||||
|
||||
/* Failed to evict the page; change it directly */
|
||||
}
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
|
||||
buf_block_buf_fix_inc(block, file, line);
|
||||
|
||||
|
|
|
|||
|
|
@ -1064,6 +1064,82 @@ buf_flush_write_block_low(
|
|||
}
|
||||
}
|
||||
|
||||
# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
/********************************************************************//**
|
||||
Writes a flushable page asynchronously from the buffer pool to a file.
|
||||
NOTE: buf_pool_mutex and block->mutex must be held upon entering this
|
||||
function, and they will be released by this function after flushing.
|
||||
This is loosely based on buf_flush_batch() and buf_flush_page().
|
||||
@return TRUE if the page was flushed and the mutexes released */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_flush_page_try(
|
||||
/*===============*/
|
||||
buf_block_t* block) /*!< in/out: buffer control block */
|
||||
{
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(buf_block_get_state(block) == BUF_BLOCK_FILE_PAGE);
|
||||
ut_ad(mutex_own(&block->mutex));
|
||||
|
||||
if (!buf_flush_ready_for_flush(&block->page, BUF_FLUSH_LRU)) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
if (buf_pool->n_flush[BUF_FLUSH_LRU] > 0
|
||||
|| buf_pool->init_flush[BUF_FLUSH_LRU]) {
|
||||
/* There is already a flush batch of the same type running */
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
buf_pool->init_flush[BUF_FLUSH_LRU] = TRUE;
|
||||
|
||||
buf_page_set_io_fix(&block->page, BUF_IO_WRITE);
|
||||
|
||||
buf_page_set_flush_type(&block->page, BUF_FLUSH_LRU);
|
||||
|
||||
if (buf_pool->n_flush[BUF_FLUSH_LRU]++ == 0) {
|
||||
|
||||
os_event_reset(buf_pool->no_flush[BUF_FLUSH_LRU]);
|
||||
}
|
||||
|
||||
/* VERY IMPORTANT:
|
||||
Because any thread may call the LRU flush, even when owning
|
||||
locks on pages, to avoid deadlocks, we must make sure that the
|
||||
s-lock is acquired on the page without waiting: this is
|
||||
accomplished because buf_flush_ready_for_flush() must hold,
|
||||
and that requires the page not to be bufferfixed. */
|
||||
|
||||
rw_lock_s_lock_gen(&block->lock, BUF_IO_WRITE);
|
||||
|
||||
/* Note that the s-latch is acquired before releasing the
|
||||
buf_pool mutex: this ensures that the latch is acquired
|
||||
immediately. */
|
||||
|
||||
mutex_exit(&block->mutex);
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
/* Even though block is not protected by any mutex at this
|
||||
point, it is safe to access block, because it is io_fixed and
|
||||
oldest_modification != 0. Thus, it cannot be relocated in the
|
||||
buffer pool or removed from flush_list or LRU_list. */
|
||||
|
||||
buf_flush_write_block_low(&block->page);
|
||||
|
||||
buf_pool_mutex_enter();
|
||||
buf_pool->init_flush[BUF_FLUSH_LRU] = FALSE;
|
||||
|
||||
if (buf_pool->n_flush[BUF_FLUSH_LRU] == 0) {
|
||||
/* The running flush batch has ended */
|
||||
os_event_set(buf_pool->no_flush[BUF_FLUSH_LRU]);
|
||||
}
|
||||
|
||||
buf_pool_mutex_exit();
|
||||
buf_flush_buffered_writes();
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
|
||||
/********************************************************************//**
|
||||
Writes a flushable page asynchronously from the buffer pool to a file.
|
||||
NOTE: in simulated aio we must call
|
||||
|
|
|
|||
|
|
@ -1024,13 +1024,13 @@ err_exit:
|
|||
if (err != DB_SUCCESS) {
|
||||
dict_table_remove_from_cache(table);
|
||||
table = NULL;
|
||||
} else {
|
||||
table->fk_max_recusive_level = 0;
|
||||
}
|
||||
} else if (!srv_force_recovery) {
|
||||
dict_table_remove_from_cache(table);
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
table->fk_max_recusive_level = 0;
|
||||
#if 0
|
||||
if (err != DB_SUCCESS && table != NULL) {
|
||||
|
||||
|
|
|
|||
|
|
@ -4751,17 +4751,18 @@ include_field:
|
|||
n_requested_fields++;
|
||||
|
||||
templ->col_no = i;
|
||||
templ->clust_rec_field_no = dict_col_get_clust_pos(
|
||||
&index->table->cols[i], clust_index);
|
||||
ut_ad(templ->clust_rec_field_no != ULINT_UNDEFINED);
|
||||
|
||||
if (index == clust_index) {
|
||||
templ->rec_field_no = dict_col_get_clust_pos(
|
||||
&index->table->cols[i], index);
|
||||
templ->rec_field_no = templ->clust_rec_field_no;
|
||||
} else {
|
||||
templ->rec_field_no = dict_index_get_nth_col_pos(
|
||||
index, i);
|
||||
}
|
||||
|
||||
if (templ->rec_field_no == ULINT_UNDEFINED) {
|
||||
prebuilt->need_to_access_clustered = TRUE;
|
||||
if (templ->rec_field_no == ULINT_UNDEFINED) {
|
||||
prebuilt->need_to_access_clustered = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (field->null_ptr) {
|
||||
|
|
@ -4813,9 +4814,7 @@ skip_field:
|
|||
for (i = 0; i < n_requested_fields; i++) {
|
||||
templ = prebuilt->mysql_template + i;
|
||||
|
||||
templ->rec_field_no = dict_col_get_clust_pos(
|
||||
&index->table->cols[templ->col_no],
|
||||
clust_index);
|
||||
templ->rec_field_no = templ->clust_rec_field_no;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -6756,8 +6755,8 @@ create_options_are_valid(
|
|||
? "COMPRESSED"
|
||||
: "DYNAMIC";
|
||||
|
||||
/* These two ROW_FORMATs require
|
||||
srv_file_per_table and srv_file_format */
|
||||
/* These two ROW_FORMATs require srv_file_per_table
|
||||
and srv_file_format > Antelope */
|
||||
if (!srv_file_per_table) {
|
||||
push_warning_printf(
|
||||
thd,
|
||||
|
|
@ -6767,7 +6766,6 @@ create_options_are_valid(
|
|||
" requires innodb_file_per_table.",
|
||||
row_format_name);
|
||||
ret = FALSE;
|
||||
|
||||
}
|
||||
|
||||
if (srv_file_format < DICT_TF_FORMAT_ZIP) {
|
||||
|
|
@ -6966,6 +6964,8 @@ ha_innobase::create(
|
|||
ulint ssize, ksize;
|
||||
ulint key_block_size = create_info->key_block_size;
|
||||
|
||||
/* Set 'flags' to the correct key_block_size.
|
||||
It will be zero if key_block_size is an invalid number.*/
|
||||
for (ssize = ksize = 1; ssize <= DICT_TF_ZSSIZE_MAX;
|
||||
ssize++, ksize <<= 1) {
|
||||
if (key_block_size == ksize) {
|
||||
|
|
@ -7006,10 +7006,10 @@ ha_innobase::create(
|
|||
row_type = form->s->row_type;
|
||||
|
||||
if (flags) {
|
||||
/* KEY_BLOCK_SIZE was specified. */
|
||||
if (!(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) {
|
||||
/* ROW_FORMAT was not specified;
|
||||
default to ROW_FORMAT=COMPRESSED */
|
||||
/* if KEY_BLOCK_SIZE was specified on this statement and
|
||||
ROW_FORMAT was not, automatically change ROW_FORMAT to COMPRESSED.*/
|
||||
if ( (create_info->used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE)
|
||||
&& !(create_info->used_fields & HA_CREATE_USED_ROW_FORMAT)) {
|
||||
row_type = ROW_TYPE_COMPRESSED;
|
||||
} else if (row_type != ROW_TYPE_COMPRESSED) {
|
||||
/* ROW_FORMAT other than COMPRESSED
|
||||
|
|
@ -7028,7 +7028,7 @@ ha_innobase::create(
|
|||
flags = 0;
|
||||
}
|
||||
} else {
|
||||
/* No KEY_BLOCK_SIZE */
|
||||
/* flags == 0 means no KEY_BLOCK_SIZE.*/
|
||||
if (row_type == ROW_TYPE_COMPRESSED) {
|
||||
/* ROW_FORMAT=COMPRESSED without
|
||||
KEY_BLOCK_SIZE implies half the
|
||||
|
|
@ -7923,9 +7923,12 @@ Returns statistics information of the table to the MySQL interpreter,
|
|||
in various fields of the handle object. */
|
||||
UNIV_INTERN
|
||||
int
|
||||
ha_innobase::info(
|
||||
/*==============*/
|
||||
uint flag) /*!< in: what information MySQL requests */
|
||||
ha_innobase::info_low(
|
||||
/*==================*/
|
||||
uint flag, /*!< in: what information MySQL
|
||||
requests */
|
||||
bool called_from_analyze) /* in: TRUE if called from
|
||||
::analyze() */
|
||||
{
|
||||
dict_table_t* ib_table;
|
||||
dict_index_t* index;
|
||||
|
|
@ -7956,8 +7959,7 @@ ha_innobase::info(
|
|||
ib_table = prebuilt->table;
|
||||
|
||||
if (flag & HA_STATUS_TIME) {
|
||||
if ((innobase_stats_on_metadata
|
||||
|| thd_sql_command(user_thd) == SQLCOM_ANALYZE)
|
||||
if ((called_from_analyze || innobase_stats_on_metadata)
|
||||
&& !share->ib_table->is_corrupt) {
|
||||
/* In sql_show we call with this flag: update
|
||||
then statistics so that they are up-to-date */
|
||||
|
|
@ -8228,6 +8230,18 @@ func_exit:
|
|||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Returns statistics information of the table to the MySQL interpreter,
|
||||
in various fields of the handle object. */
|
||||
UNIV_INTERN
|
||||
int
|
||||
ha_innobase::info(
|
||||
/*==============*/
|
||||
uint flag) /*!< in: what information MySQL requests */
|
||||
{
|
||||
return(info_low(flag, false /* not called from analyze */));
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Updates index cardinalities of the table, based on 8 random dives into
|
||||
each index tree. This does NOT calculate exact statistics on the table.
|
||||
|
|
@ -8244,7 +8258,8 @@ ha_innobase::analyze(
|
|||
}
|
||||
|
||||
/* Simply call ::info() with all the flags */
|
||||
info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE);
|
||||
info_low(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE,
|
||||
true /* called from analyze */);
|
||||
|
||||
if (share->ib_table->is_corrupt) {
|
||||
return(HA_ADMIN_CORRUPT);
|
||||
|
|
@ -8553,8 +8568,6 @@ ha_innobase::get_foreign_key_create_info(void)
|
|||
flen = ftell(srv_dict_tmpfile);
|
||||
if (flen < 0) {
|
||||
flen = 0;
|
||||
} else if (flen > 64000 - 1) {
|
||||
flen = 64000 - 1;
|
||||
}
|
||||
|
||||
/* allocate buffer for the string, and
|
||||
|
|
@ -9867,7 +9880,11 @@ ha_innobase::innobase_peek_autoinc(void)
|
|||
|
||||
auto_inc = dict_table_autoinc_read(innodb_table);
|
||||
|
||||
ut_a(auto_inc > 0);
|
||||
if (auto_inc == 0) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: AUTOINC next value generation "
|
||||
"is disabled for '%s'\n", innodb_table->name);
|
||||
}
|
||||
|
||||
dict_table_autoinc_unlock(innodb_table);
|
||||
|
||||
|
|
@ -11508,6 +11525,13 @@ static MYSQL_SYSVAR_STR(change_buffering, innobase_change_buffering,
|
|||
innodb_change_buffering_validate,
|
||||
innodb_change_buffering_update, "inserts");
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
static MYSQL_SYSVAR_UINT(change_buffering_debug, ibuf_debug,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Debug flags for InnoDB change buffering (0=none)",
|
||||
NULL, NULL, 0, 0, 1, 0);
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(read_ahead_threshold, srv_read_ahead_threshold,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Number of pages that must be accessed sequentially for InnoDB to "
|
||||
|
|
@ -11717,6 +11741,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(dict_size_limit),
|
||||
MYSQL_SYSVAR(use_sys_malloc),
|
||||
MYSQL_SYSVAR(change_buffering),
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
MYSQL_SYSVAR(change_buffering_debug),
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
MYSQL_SYSVAR(read_ahead_threshold),
|
||||
MYSQL_SYSVAR(io_capacity),
|
||||
MYSQL_SYSVAR(auto_lru_dump),
|
||||
|
|
|
|||
|
|
@ -110,6 +110,7 @@ class ha_innobase: public handler
|
|||
ulint innobase_update_autoinc(ulonglong auto_inc);
|
||||
void innobase_initialize_autoinc();
|
||||
dict_index_t* innobase_get_index(uint keynr);
|
||||
int info_low(uint flag, bool called_from_analyze);
|
||||
|
||||
/* Init values for the class: */
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ Created 7/19/1997 Heikki Tuuri
|
|||
#include "btr0cur.h"
|
||||
#include "btr0pcur.h"
|
||||
#include "btr0btr.h"
|
||||
#include "row0upd.h"
|
||||
#include "sync0sync.h"
|
||||
#include "dict0boot.h"
|
||||
#include "fut0lst.h"
|
||||
|
|
@ -170,6 +171,11 @@ access order rules. */
|
|||
/** Operations that can currently be buffered. */
|
||||
UNIV_INTERN ibuf_use_t ibuf_use = IBUF_USE_INSERT;
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
/** Flag to control insert buffer debugging. */
|
||||
UNIV_INTERN uint ibuf_debug;
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
|
||||
/** The insert buffer control structure */
|
||||
UNIV_INTERN ibuf_t* ibuf = NULL;
|
||||
|
||||
|
|
@ -2886,9 +2892,80 @@ During merge, inserts to an index page a secondary index entry extracted
|
|||
from the insert buffer. */
|
||||
static
|
||||
void
|
||||
ibuf_insert_to_index_page_low(
|
||||
/*==========================*/
|
||||
const dtuple_t* entry, /*!< in: buffered entry to insert */
|
||||
buf_block_t* block, /*!< in/out: index page where the buffered
|
||||
entry should be placed */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
mtr_t* mtr, /*!< in/out: mtr */
|
||||
page_cur_t* page_cur)/*!< in/out: cursor positioned on the record
|
||||
after which to insert the buffered entry */
|
||||
{
|
||||
const page_t* page;
|
||||
ulint space;
|
||||
ulint page_no;
|
||||
ulint zip_size;
|
||||
const page_t* bitmap_page;
|
||||
ulint old_bits;
|
||||
|
||||
if (UNIV_LIKELY
|
||||
(page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the record did not fit, reorganize */
|
||||
|
||||
btr_page_reorganize(block, index, mtr);
|
||||
page_cur_search(block, index, entry, PAGE_CUR_LE, page_cur);
|
||||
|
||||
/* This time the record must fit */
|
||||
|
||||
if (UNIV_LIKELY
|
||||
(page_cur_tuple_insert(page_cur, entry, index, 0, mtr) != NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
page = buf_block_get_frame(block);
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: Insert buffer insert fails;"
|
||||
" page free %lu, dtuple size %lu\n",
|
||||
(ulong) page_get_max_insert_size(page, 1),
|
||||
(ulong) rec_get_converted_size(index, entry, 0));
|
||||
fputs("InnoDB: Cannot insert index record ", stderr);
|
||||
dtuple_print(stderr, entry);
|
||||
fputs("\nInnoDB: The table where this index record belongs\n"
|
||||
"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
|
||||
"InnoDB: that table.\n", stderr);
|
||||
|
||||
space = page_get_space_id(page);
|
||||
zip_size = buf_block_get_zip_size(block);
|
||||
page_no = page_get_page_no(page);
|
||||
|
||||
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
|
||||
old_bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
|
||||
IBUF_BITMAP_FREE, mtr);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: space %lu, page %lu, zip_size %lu, bitmap bits %lu\n",
|
||||
(ulong) space, (ulong) page_no,
|
||||
(ulong) zip_size, (ulong) old_bits);
|
||||
|
||||
fputs("InnoDB: Submit a detailed bug report"
|
||||
" to http://bugs.mysql.com\n", stderr);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
During merge, inserts to an index page a secondary index entry extracted
|
||||
from the insert buffer. */
|
||||
static
|
||||
void
|
||||
ibuf_insert_to_index_page(
|
||||
/*======================*/
|
||||
dtuple_t* entry, /*!< in: buffered entry to insert */
|
||||
const dtuple_t* entry, /*!< in: buffered entry to insert */
|
||||
buf_block_t* block, /*!< in/out: index page where the buffered entry
|
||||
should be placed */
|
||||
dict_index_t* index, /*!< in: record descriptor */
|
||||
|
|
@ -2898,11 +2975,10 @@ ibuf_insert_to_index_page(
|
|||
ulint low_match;
|
||||
page_t* page = buf_block_get_frame(block);
|
||||
rec_t* rec;
|
||||
page_t* bitmap_page;
|
||||
ulint old_bits;
|
||||
|
||||
ut_ad(ibuf_inside());
|
||||
ut_ad(dtuple_check_typed(entry));
|
||||
ut_ad(!buf_block_align(page)->is_hashed);
|
||||
|
||||
if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
|
||||
!= (ibool)!!page_is_comp(page))) {
|
||||
|
|
@ -2940,71 +3016,86 @@ dump:
|
|||
low_match = page_cur_search(block, index, entry,
|
||||
PAGE_CUR_LE, &page_cur);
|
||||
|
||||
if (low_match == dtuple_get_n_fields(entry)) {
|
||||
if (UNIV_UNLIKELY(low_match == dtuple_get_n_fields(entry))) {
|
||||
mem_heap_t* heap;
|
||||
upd_t* update;
|
||||
ulint* offsets;
|
||||
page_zip_des_t* page_zip;
|
||||
|
||||
rec = page_cur_get_rec(&page_cur);
|
||||
|
||||
/* This is based on
|
||||
row_ins_sec_index_entry_by_modify(BTR_MODIFY_LEAF). */
|
||||
ut_ad(rec_get_deleted_flag(rec, page_is_comp(page)));
|
||||
|
||||
heap = mem_heap_create(1024);
|
||||
|
||||
offsets = rec_get_offsets(rec, index, NULL, ULINT_UNDEFINED,
|
||||
&heap);
|
||||
update = row_upd_build_sec_rec_difference_binary(
|
||||
index, entry, rec, NULL, heap);
|
||||
|
||||
page_zip = buf_block_get_page_zip(block);
|
||||
|
||||
btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr);
|
||||
} else {
|
||||
rec = page_cur_tuple_insert(&page_cur, entry, index, 0, mtr);
|
||||
|
||||
if (UNIV_LIKELY(rec != NULL)) {
|
||||
if (update->n_fields == 0) {
|
||||
/* The records only differ in the delete-mark.
|
||||
Clear the delete-mark, like we did before
|
||||
Bug #56680 was fixed. */
|
||||
btr_cur_del_unmark_for_ibuf(rec, page_zip, mtr);
|
||||
updated_in_place:
|
||||
mem_heap_free(heap);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If the record did not fit, reorganize */
|
||||
/* Copy the info bits. Clear the delete-mark. */
|
||||
update->info_bits = rec_get_info_bits(rec, page_is_comp(page));
|
||||
update->info_bits &= ~REC_INFO_DELETED_FLAG;
|
||||
|
||||
btr_page_reorganize(block, index, mtr);
|
||||
page_cur_search(block, index, entry, PAGE_CUR_LE, &page_cur);
|
||||
|
||||
/* This time the record must fit */
|
||||
if (UNIV_UNLIKELY
|
||||
(!page_cur_tuple_insert(&page_cur, entry, index,
|
||||
0, mtr))) {
|
||||
ulint space;
|
||||
ulint page_no;
|
||||
ulint zip_size;
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: Insert buffer insert"
|
||||
" fails; page free %lu,"
|
||||
" dtuple size %lu\n",
|
||||
(ulong) page_get_max_insert_size(
|
||||
page, 1),
|
||||
(ulong) rec_get_converted_size(
|
||||
index, entry, 0));
|
||||
fputs("InnoDB: Cannot insert index record ",
|
||||
stderr);
|
||||
dtuple_print(stderr, entry);
|
||||
fputs("\nInnoDB: The table where"
|
||||
" this index record belongs\n"
|
||||
"InnoDB: is now probably corrupt."
|
||||
" Please run CHECK TABLE on\n"
|
||||
"InnoDB: that table.\n", stderr);
|
||||
|
||||
space = page_get_space_id(page);
|
||||
zip_size = buf_block_get_zip_size(block);
|
||||
page_no = page_get_page_no(page);
|
||||
|
||||
bitmap_page = ibuf_bitmap_get_map_page(
|
||||
space, page_no, zip_size, mtr);
|
||||
old_bits = ibuf_bitmap_page_get_bits(
|
||||
bitmap_page, page_no, zip_size,
|
||||
IBUF_BITMAP_FREE, mtr);
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: space %lu, page %lu,"
|
||||
" zip_size %lu, bitmap bits %lu\n",
|
||||
(ulong) space, (ulong) page_no,
|
||||
(ulong) zip_size, (ulong) old_bits);
|
||||
|
||||
fputs("InnoDB: Submit a detailed bug report"
|
||||
" to http://bugs.mysql.com\n", stderr);
|
||||
/* We cannot invoke btr_cur_optimistic_update() here,
|
||||
because we do not have a btr_cur_t or que_thr_t,
|
||||
as the insert buffer merge occurs at a very low level. */
|
||||
if (!row_upd_changes_field_size_or_external(index, offsets,
|
||||
update)
|
||||
&& (!page_zip || btr_cur_update_alloc_zip(
|
||||
page_zip, block, index,
|
||||
rec_offs_size(offsets), FALSE, mtr))) {
|
||||
/* This is the easy case. Do something similar
|
||||
to btr_cur_update_in_place(). */
|
||||
row_upd_rec_in_place(rec, index, offsets,
|
||||
update, page_zip);
|
||||
goto updated_in_place;
|
||||
}
|
||||
|
||||
/* A collation may identify values that differ in
|
||||
storage length.
|
||||
Some examples (1 or 2 bytes):
|
||||
utf8_turkish_ci: I = U+0131 LATIN SMALL LETTER DOTLESS I
|
||||
utf8_general_ci: S = U+00DF LATIN SMALL LETTER SHARP S
|
||||
utf8_general_ci: A = U+00E4 LATIN SMALL LETTER A WITH DIAERESIS
|
||||
|
||||
latin1_german2_ci: SS = U+00DF LATIN SMALL LETTER SHARP S
|
||||
|
||||
Examples of a character (3-byte UTF-8 sequence)
|
||||
identified with 2 or 4 characters (1-byte UTF-8 sequences):
|
||||
|
||||
utf8_unicode_ci: 'II' = U+2171 SMALL ROMAN NUMERAL TWO
|
||||
utf8_unicode_ci: '(10)' = U+247D PARENTHESIZED NUMBER TEN
|
||||
*/
|
||||
|
||||
/* Delete the different-length record, and insert the
|
||||
buffered one. */
|
||||
|
||||
lock_rec_store_on_page_infimum(block, rec);
|
||||
page_cur_delete_rec(&page_cur, index, offsets, mtr);
|
||||
page_cur_move_to_prev(&page_cur);
|
||||
mem_heap_free(heap);
|
||||
|
||||
ibuf_insert_to_index_page_low(entry, block, index, mtr,
|
||||
&page_cur);
|
||||
lock_rec_restore_from_page_infimum(block, rec, block);
|
||||
} else {
|
||||
ibuf_insert_to_index_page_low(entry, block, index, mtr,
|
||||
&page_cur);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -242,6 +242,22 @@ btr_cur_pessimistic_insert(
|
|||
que_thr_t* thr, /*!< in: query thread or NULL */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
/*************************************************************//**
|
||||
See if there is enough place in the page modification log to log
|
||||
an update-in-place.
|
||||
@return TRUE if enough place */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
btr_cur_update_alloc_zip(
|
||||
/*=====================*/
|
||||
page_zip_des_t* page_zip,/*!< in/out: compressed page */
|
||||
buf_block_t* block, /*!< in/out: buffer page */
|
||||
dict_index_t* index, /*!< in: the index corresponding to the block */
|
||||
ulint length, /*!< in: size needed */
|
||||
ibool create, /*!< in: TRUE=delete-and-insert,
|
||||
FALSE=update-in-place */
|
||||
mtr_t* mtr) /*!< in: mini-transaction */
|
||||
__attribute__((nonnull, warn_unused_result));
|
||||
/*************************************************************//**
|
||||
Updates a record when the update causes no size changes in its fields.
|
||||
@return DB_SUCCESS or error number */
|
||||
UNIV_INTERN
|
||||
|
|
|
|||
|
|
@ -76,6 +76,20 @@ buf_flush_init_for_writing(
|
|||
ib_uint64_t newest_lsn); /*!< in: newest modification lsn
|
||||
to the page */
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
# if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
/********************************************************************//**
|
||||
Writes a flushable page asynchronously from the buffer pool to a file.
|
||||
NOTE: buf_pool_mutex and block->mutex must be held upon entering this
|
||||
function, and they will be released by this function after flushing.
|
||||
This is loosely based on buf_flush_batch() and buf_flush_page().
|
||||
@return TRUE if the page was flushed and the mutexes released */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
buf_flush_page_try(
|
||||
/*===============*/
|
||||
buf_block_t* block) /*!< in/out: buffer control block */
|
||||
__attribute__((nonnull, warn_unused_result));
|
||||
# endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
/*******************************************************************//**
|
||||
This utility flushes dirty blocks from the end of the LRU list or flush_list.
|
||||
NOTE 1: in the case of an LRU flush the calling thread may own latches to
|
||||
|
|
|
|||
|
|
@ -48,6 +48,11 @@ typedef enum {
|
|||
/** Operations that can currently be buffered. */
|
||||
extern ibuf_use_t ibuf_use;
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_IBUF_DEBUG
|
||||
/** Flag to control insert buffer debugging. */
|
||||
extern uint ibuf_debug;
|
||||
#endif /* UNIV_DEBUG || UNIV_IBUF_DEBUG */
|
||||
|
||||
/** The insert buffer control structure */
|
||||
extern ibuf_t* ibuf;
|
||||
|
||||
|
|
|
|||
|
|
@ -535,6 +535,10 @@ struct mysql_row_templ_struct {
|
|||
Innobase record in the current index;
|
||||
not defined if template_type is
|
||||
ROW_MYSQL_WHOLE_ROW */
|
||||
ulint clust_rec_field_no; /*!< field number of the column in an
|
||||
Innobase record in the clustered index;
|
||||
not defined if template_type is
|
||||
ROW_MYSQL_WHOLE_ROW */
|
||||
ulint mysql_col_offset; /*!< offset of the column in the MySQL
|
||||
row format */
|
||||
ulint mysql_col_len; /*!< length of the column in the MySQL
|
||||
|
|
|
|||
|
|
@ -167,8 +167,11 @@ row_upd_changes_field_size_or_external(
|
|||
const upd_t* update);/*!< in: update vector */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
/***********************************************************//**
|
||||
Replaces the new column values stored in the update vector to the record
|
||||
given. No field size changes are allowed. */
|
||||
Replaces the new column values stored in the update vector to the
|
||||
record given. No field size changes are allowed. This function is
|
||||
usually invoked on a clustered index. The only use case for a
|
||||
secondary index is row_ins_sec_index_entry_by_modify() or its
|
||||
counterpart in ibuf_insert_to_index_page(). */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_upd_rec_in_place(
|
||||
|
|
|
|||
|
|
@ -1222,10 +1222,12 @@ UNIV_INTERN
|
|||
void
|
||||
os_file_set_nocache(
|
||||
/*================*/
|
||||
int fd, /*!< in: file descriptor to alter */
|
||||
const char* file_name, /*!< in: file name, used in the
|
||||
diagnostic message */
|
||||
const char* operation_name) /*!< in: "open" or "create"; used in the
|
||||
int fd /*!< in: file descriptor to alter */
|
||||
__attribute__((unused)),
|
||||
const char* file_name /*!< in: used in the diagnostic message */
|
||||
__attribute__((unused)),
|
||||
const char* operation_name __attribute__((unused)))
|
||||
/*!< in: "open" or "create"; used in the
|
||||
diagnostic message */
|
||||
{
|
||||
/* some versions of Solaris may not have DIRECTIO_ON */
|
||||
|
|
@ -2355,7 +2357,10 @@ _os_file_read(
|
|||
ulint i;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
|
||||
no more than 32 bits. */
|
||||
ut_a((offset & 0xFFFFFFFFUL) == offset);
|
||||
ut_a((n & 0xFFFFFFFFUL) == n);
|
||||
|
||||
os_n_file_reads++;
|
||||
os_bytes_read_since_printout += n;
|
||||
|
|
@ -2479,7 +2484,10 @@ os_file_read_no_error_handling(
|
|||
ulint i;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
|
||||
no more than 32 bits. */
|
||||
ut_a((offset & 0xFFFFFFFFUL) == offset);
|
||||
ut_a((n & 0xFFFFFFFFUL) == n);
|
||||
|
||||
os_n_file_reads++;
|
||||
os_bytes_read_since_printout += n;
|
||||
|
|
@ -2609,7 +2617,10 @@ os_file_write(
|
|||
ulint i;
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
ut_a((offset & 0xFFFFFFFF) == offset);
|
||||
/* On 64-bit Windows, ulint is 64 bits. But offset and n should be
|
||||
no more than 32 bits. */
|
||||
ut_a((offset & 0xFFFFFFFFUL) == offset);
|
||||
ut_a((n & 0xFFFFFFFFUL) == n);
|
||||
|
||||
os_n_file_writes++;
|
||||
|
||||
|
|
@ -3379,16 +3390,17 @@ os_aio_array_reserve_slot(
|
|||
offset */
|
||||
ulint offset_high, /*!< in: most significant 32 bits of
|
||||
offset */
|
||||
ulint len, /*!< in: length of the block to read or write */
|
||||
trx_t* trx)
|
||||
ulint len) /*!< in: length of the block to read or write */
|
||||
{
|
||||
os_aio_slot_t* slot;
|
||||
#ifdef WIN_ASYNC_IO
|
||||
OVERLAPPED* control;
|
||||
#endif
|
||||
ulint i;
|
||||
ulint slots_per_seg;
|
||||
ulint local_seg;
|
||||
#ifdef WIN_ASYNC_IO
|
||||
OVERLAPPED* control;
|
||||
|
||||
ut_a((len & 0xFFFFFFFFUL) == len);
|
||||
#endif
|
||||
|
||||
/* No need of a mutex. Only reading constant fields */
|
||||
slots_per_seg = array->n_slots / array->n_segments;
|
||||
|
|
@ -3690,6 +3702,9 @@ os_aio(
|
|||
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_ad(os_aio_validate());
|
||||
#ifdef WIN_ASYNC_IO
|
||||
ut_ad((n & 0xFFFFFFFFUL) == n);
|
||||
#endif
|
||||
|
||||
wake_later = mode & OS_AIO_SIMULATED_WAKE_LATER;
|
||||
mode = mode & (~OS_AIO_SIMULATED_WAKE_LATER);
|
||||
|
|
@ -3747,7 +3762,7 @@ try_again:
|
|||
trx->io_read += n;
|
||||
}
|
||||
slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
|
||||
name, buf, offset, offset_high, n, trx);
|
||||
name, buf, offset, offset_high, n);
|
||||
if (type == OS_FILE_READ) {
|
||||
if (os_aio_use_native_aio) {
|
||||
#ifdef WIN_ASYNC_IO
|
||||
|
|
@ -3935,16 +3950,18 @@ os_aio_windows_handle(
|
|||
/* retry failed read/write operation synchronously.
|
||||
No need to hold array->mutex. */
|
||||
|
||||
ut_a((slot->len & 0xFFFFFFFFUL) == slot->len);
|
||||
|
||||
switch (slot->type) {
|
||||
case OS_FILE_WRITE:
|
||||
ret = WriteFile(slot->file, slot->buf,
|
||||
slot->len, &len,
|
||||
(DWORD) slot->len, &len,
|
||||
&(slot->control));
|
||||
|
||||
break;
|
||||
case OS_FILE_READ:
|
||||
ret = ReadFile(slot->file, slot->buf,
|
||||
slot->len, &len,
|
||||
(DWORD) slot->len, &len,
|
||||
&(slot->control));
|
||||
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -141,10 +141,11 @@ MYSQL_PLUGIN_ACTIONS(xtradb, [
|
|||
|
||||
AC_MSG_CHECKING(whether Solaris libc atomic functions are available)
|
||||
# either define HAVE_IB_SOLARIS_ATOMICS or not
|
||||
AC_CHECK_FUNCS(atomic_add_long \
|
||||
AC_CHECK_FUNCS(atomic_cas_ulong \
|
||||
atomic_cas_32 \
|
||||
atomic_cas_64 \
|
||||
atomic_cas_ulong,
|
||||
atomic_add_long_nv \
|
||||
atomic_swap_uchar,
|
||||
|
||||
AC_DEFINE([HAVE_IB_SOLARIS_ATOMICS], [1],
|
||||
[Define to 1 if Solaris libc atomic functions \
|
||||
|
|
|
|||
|
|
@ -445,7 +445,7 @@ row_mysql_convert_row_to_innobase(
|
|||
row is used, as row may contain
|
||||
pointers to this record! */
|
||||
{
|
||||
mysql_row_templ_t* templ;
|
||||
const mysql_row_templ_t*templ;
|
||||
dfield_t* dfield;
|
||||
ulint i;
|
||||
|
||||
|
|
@ -1890,15 +1890,13 @@ err_exit:
|
|||
|
||||
err = trx->error_state;
|
||||
|
||||
if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
|
||||
switch (err) {
|
||||
case DB_SUCCESS:
|
||||
break;
|
||||
case DB_OUT_OF_FILE_SPACE:
|
||||
trx->error_state = DB_SUCCESS;
|
||||
trx_general_rollback_for_mysql(trx, NULL);
|
||||
/* TO DO: free table? The code below will dereference
|
||||
table->name, though. */
|
||||
}
|
||||
|
||||
switch (err) {
|
||||
case DB_OUT_OF_FILE_SPACE:
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: Warning: cannot create table ",
|
||||
stderr);
|
||||
|
|
@ -1913,9 +1911,13 @@ err_exit:
|
|||
break;
|
||||
|
||||
case DB_DUPLICATE_KEY:
|
||||
default:
|
||||
/* We may also get err == DB_ERROR if the .ibd file for the
|
||||
table already exists */
|
||||
|
||||
trx->error_state = DB_SUCCESS;
|
||||
trx_general_rollback_for_mysql(trx, NULL);
|
||||
dict_mem_table_free(table);
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -2830,15 +2832,6 @@ row_truncate_table_for_mysql(
|
|||
|
||||
trx->table_id = table->id;
|
||||
|
||||
/* Lock all index trees for this table, as we will
|
||||
truncate the table/index and possibly change their metadata.
|
||||
All DML/DDL are blocked by table level lock, with
|
||||
a few exceptions such as queries into information schema
|
||||
about the table, MySQL could try to access index stats
|
||||
for this kind of query, we need to use index locks to
|
||||
sync up */
|
||||
dict_table_x_lock_indexes(table);
|
||||
|
||||
if (table->space && !table->dir_path_of_temp_table) {
|
||||
/* Discard and create the single-table tablespace. */
|
||||
ulint space = table->space;
|
||||
|
|
@ -2851,6 +2844,11 @@ row_truncate_table_for_mysql(
|
|||
|
||||
dict_hdr_get_new_id(NULL, NULL, &space);
|
||||
|
||||
/* Lock all index trees for this table. We must
|
||||
do so after dict_hdr_get_new_id() to preserve
|
||||
the latch order */
|
||||
dict_table_x_lock_indexes(table);
|
||||
|
||||
if (space == ULINT_UNDEFINED
|
||||
|| fil_create_new_single_table_tablespace(
|
||||
space, table->name, FALSE, flags,
|
||||
|
|
@ -2884,6 +2882,15 @@ row_truncate_table_for_mysql(
|
|||
FIL_IBD_FILE_INITIAL_SIZE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
} else {
|
||||
/* Lock all index trees for this table, as we will
|
||||
truncate the table/index and possibly change their metadata.
|
||||
All DML/DDL are blocked by table level lock, with
|
||||
a few exceptions such as queries into information schema
|
||||
about the table, MySQL could try to access index stats
|
||||
for this kind of query, we need to use index locks to
|
||||
sync up */
|
||||
dict_table_x_lock_indexes(table);
|
||||
}
|
||||
|
||||
/* scan SYS_INDEXES for all indexes of the table */
|
||||
|
|
|
|||
|
|
@ -2675,39 +2675,39 @@ row_sel_store_mysql_rec(
|
|||
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
|
||||
const rec_t* rec, /*!< in: Innobase record in the index
|
||||
which was described in prebuilt's
|
||||
template; must be protected by
|
||||
a page latch */
|
||||
template, or in the clustered index;
|
||||
must be protected by a page latch */
|
||||
ibool rec_clust, /*!< in: TRUE if rec is in the
|
||||
clustered index instead of
|
||||
prebuilt->index */
|
||||
const ulint* offsets) /*!< in: array returned by
|
||||
rec_get_offsets() */
|
||||
rec_get_offsets(rec) */
|
||||
{
|
||||
mysql_row_templ_t* templ;
|
||||
mem_heap_t* extern_field_heap = NULL;
|
||||
mem_heap_t* heap;
|
||||
const byte* data;
|
||||
ulint len;
|
||||
ulint i;
|
||||
mem_heap_t* extern_field_heap = NULL;
|
||||
mem_heap_t* heap;
|
||||
ulint i;
|
||||
|
||||
ut_ad(prebuilt->mysql_template);
|
||||
ut_ad(prebuilt->default_rec);
|
||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||
ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
|
||||
|
||||
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
|
||||
mem_heap_free(prebuilt->blob_heap);
|
||||
prebuilt->blob_heap = NULL;
|
||||
}
|
||||
|
||||
/* init null bytes with default values as they might be
|
||||
left uninitialized in some cases and these uninited bytes
|
||||
might be copied into mysql record buffer that leads to
|
||||
valgrind warnings */
|
||||
memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len);
|
||||
|
||||
for (i = 0; i < prebuilt->n_template; i++) {
|
||||
|
||||
templ = prebuilt->mysql_template + i;
|
||||
const mysql_row_templ_t*templ = prebuilt->mysql_template + i;
|
||||
const byte* data;
|
||||
ulint len;
|
||||
ulint field_no;
|
||||
|
||||
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
|
||||
templ->rec_field_no))) {
|
||||
field_no = rec_clust
|
||||
? templ->clust_rec_field_no : templ->rec_field_no;
|
||||
|
||||
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
|
||||
|
||||
/* Copy an externally stored field to the temporary
|
||||
heap */
|
||||
|
|
@ -2735,7 +2735,7 @@ row_sel_store_mysql_rec(
|
|||
data = btr_rec_copy_externally_stored_field(
|
||||
rec, offsets,
|
||||
dict_table_zip_size(prebuilt->table),
|
||||
templ->rec_field_no, &len, heap);
|
||||
field_no, &len, heap);
|
||||
|
||||
if (UNIV_UNLIKELY(!data)) {
|
||||
/* The externally stored field
|
||||
|
|
@ -2756,8 +2756,7 @@ row_sel_store_mysql_rec(
|
|||
} else {
|
||||
/* Field is stored in the row. */
|
||||
|
||||
data = rec_get_nth_field(rec, offsets,
|
||||
templ->rec_field_no, &len);
|
||||
data = rec_get_nth_field(rec, offsets, field_no, &len);
|
||||
|
||||
if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
|
||||
&& len != UNIV_SQL_NULL) {
|
||||
|
|
@ -3119,7 +3118,7 @@ row_sel_pop_cached_row_for_mysql(
|
|||
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */
|
||||
{
|
||||
ulint i;
|
||||
mysql_row_templ_t* templ;
|
||||
const mysql_row_templ_t*templ;
|
||||
byte* cached_rec;
|
||||
ut_ad(prebuilt->n_fetch_cached > 0);
|
||||
ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
|
||||
|
|
@ -3176,15 +3175,21 @@ ibool
|
|||
row_sel_push_cache_row_for_mysql(
|
||||
/*=============================*/
|
||||
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
|
||||
const rec_t* rec, /*!< in: record to push; must
|
||||
be protected by a page latch */
|
||||
const ulint* offsets) /*!< in: rec_get_offsets() */
|
||||
const rec_t* rec, /*!< in: record to push, in the index
|
||||
which was described in prebuilt's
|
||||
template, or in the clustered index;
|
||||
must be protected by a page latch */
|
||||
ibool rec_clust, /*!< in: TRUE if rec is in the
|
||||
clustered index instead of
|
||||
prebuilt->index */
|
||||
const ulint* offsets) /*!< in: rec_get_offsets(rec) */
|
||||
{
|
||||
byte* buf;
|
||||
ulint i;
|
||||
|
||||
ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
|
||||
ut_ad(rec_offs_validate(rec, NULL, offsets));
|
||||
ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
|
||||
ut_a(!prebuilt->templ_contains_blob);
|
||||
|
||||
if (prebuilt->fetch_cache[0] == NULL) {
|
||||
|
|
@ -3213,7 +3218,7 @@ row_sel_push_cache_row_for_mysql(
|
|||
if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
|
||||
prebuilt->fetch_cache[
|
||||
prebuilt->n_fetch_cached],
|
||||
prebuilt, rec, offsets))) {
|
||||
prebuilt, rec, rec_clust, offsets))) {
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -3400,6 +3405,12 @@ row_search_for_mysql(
|
|||
ut_error;
|
||||
}
|
||||
|
||||
/* init null bytes with default values as they might be
|
||||
left uninitialized in some cases and these uninited bytes
|
||||
might be copied into mysql record buffer that leads to
|
||||
valgrind warnings */
|
||||
memcpy(buf, prebuilt->default_rec, prebuilt->null_bitmap_len);
|
||||
|
||||
#if 0
|
||||
/* August 19, 2005 by Heikki: temporarily disable this error
|
||||
print until the cursor lock count is done correctly.
|
||||
|
|
@ -3615,7 +3626,8 @@ row_search_for_mysql(
|
|||
ut_ad(!rec_get_deleted_flag(rec, comp));
|
||||
|
||||
if (!row_sel_store_mysql_rec(buf, prebuilt,
|
||||
rec, offsets)) {
|
||||
rec, FALSE,
|
||||
offsets)) {
|
||||
/* Only fresh inserts may contain
|
||||
incomplete externally stored
|
||||
columns. Pretend that such
|
||||
|
|
@ -4273,7 +4285,6 @@ no_gap_lock:
|
|||
is necessary, because we can only get the undo
|
||||
information via the clustered index record. */
|
||||
|
||||
ut_ad(index != clust_index);
|
||||
ut_ad(!dict_index_is_clust(index));
|
||||
|
||||
if (!lock_sec_rec_cons_read_sees(
|
||||
|
|
@ -4389,26 +4400,10 @@ requires_clust_rec:
|
|||
goto next_rec;
|
||||
}
|
||||
|
||||
if (prebuilt->need_to_access_clustered) {
|
||||
|
||||
result_rec = clust_rec;
|
||||
|
||||
ut_ad(rec_offs_validate(result_rec, clust_index,
|
||||
offsets));
|
||||
} else {
|
||||
/* We used 'offsets' for the clust rec, recalculate
|
||||
them for 'rec' */
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
result_rec = rec;
|
||||
}
|
||||
|
||||
/* result_rec can legitimately be delete-marked
|
||||
now that it has been established that it points to a
|
||||
clustered index record that exists in the read view. */
|
||||
result_rec = clust_rec;
|
||||
ut_ad(rec_offs_validate(result_rec, clust_index, offsets));
|
||||
} else {
|
||||
result_rec = rec;
|
||||
ut_ad(!rec_get_deleted_flag(rec, comp));
|
||||
}
|
||||
|
||||
/* We found a qualifying record 'result_rec'. At this point,
|
||||
|
|
@ -4417,6 +4412,7 @@ requires_clust_rec:
|
|||
ut_ad(rec_offs_validate(result_rec,
|
||||
result_rec != rec ? clust_index : index,
|
||||
offsets));
|
||||
ut_ad(!rec_get_deleted_flag(result_rec, comp));
|
||||
|
||||
/* At this point, the clustered index record is protected
|
||||
by a page latch that was acquired when pcur was positioned.
|
||||
|
|
@ -4441,6 +4437,7 @@ requires_clust_rec:
|
|||
cursor. */
|
||||
|
||||
if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
|
||||
result_rec != rec,
|
||||
offsets)) {
|
||||
/* Only fresh inserts may contain incomplete
|
||||
externally stored columns. Pretend that such
|
||||
|
|
@ -4458,15 +4455,31 @@ requires_clust_rec:
|
|||
|
||||
goto next_rec;
|
||||
} else {
|
||||
if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) {
|
||||
if (UNIV_UNLIKELY
|
||||
(prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) {
|
||||
/* CHECK TABLE: fetch the row */
|
||||
|
||||
if (result_rec != rec
|
||||
&& !prebuilt->need_to_access_clustered) {
|
||||
/* We used 'offsets' for the clust
|
||||
rec, recalculate them for 'rec' */
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED,
|
||||
&heap);
|
||||
result_rec = rec;
|
||||
}
|
||||
|
||||
memcpy(buf + 4, result_rec
|
||||
- rec_offs_extra_size(offsets),
|
||||
rec_offs_size(offsets));
|
||||
mach_write_to_4(buf,
|
||||
rec_offs_extra_size(offsets) + 4);
|
||||
} else {
|
||||
if (!row_sel_store_mysql_rec(buf, prebuilt,
|
||||
result_rec, offsets)) {
|
||||
/* Returning a row to MySQL */
|
||||
|
||||
if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
|
||||
result_rec != rec,
|
||||
offsets)) {
|
||||
/* Only fresh inserts may contain
|
||||
incomplete externally stored
|
||||
columns. Pretend that such records do
|
||||
|
|
|
|||
|
|
@ -466,8 +466,11 @@ row_upd_changes_field_size_or_external(
|
|||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/***********************************************************//**
|
||||
Replaces the new column values stored in the update vector to the record
|
||||
given. No field size changes are allowed. */
|
||||
Replaces the new column values stored in the update vector to the
|
||||
record given. No field size changes are allowed. This function is
|
||||
usually invoked on a clustered index. The only use case for a
|
||||
secondary index is row_ins_sec_index_entry_by_modify() or its
|
||||
counterpart in ibuf_insert_to_index_page(). */
|
||||
UNIV_INTERN
|
||||
void
|
||||
row_upd_rec_in_place(
|
||||
|
|
|
|||
|
|
@ -463,7 +463,6 @@ io_handler_thread(
|
|||
the aio array */
|
||||
{
|
||||
ulint segment;
|
||||
ulint i;
|
||||
|
||||
segment = *((ulint*)arg);
|
||||
|
||||
|
|
@ -471,7 +470,7 @@ io_handler_thread(
|
|||
fprintf(stderr, "Io handler thread %lu starts, id %lu\n", segment,
|
||||
os_thread_pf(os_thread_get_curr_id()));
|
||||
#endif
|
||||
for (i = 0;; i++) {
|
||||
while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
|
||||
fil_aio_wait(segment);
|
||||
|
||||
mutex_enter(&ios_mutex);
|
||||
|
|
@ -479,8 +478,6 @@ io_handler_thread(
|
|||
mutex_exit(&ios_mutex);
|
||||
}
|
||||
|
||||
thr_local_free(os_thread_get_curr_id());
|
||||
|
||||
/* We count the number of threads in os_thread_exit(). A created
|
||||
thread should always use that to exit and not use return() to exit.
|
||||
The thread actually never comes here because it is exited in an
|
||||
|
|
@ -2091,7 +2088,7 @@ innobase_shutdown_for_mysql(void)
|
|||
#ifdef __NETWARE__
|
||||
if (!panic_shutdown)
|
||||
#endif
|
||||
logs_empty_and_mark_files_at_shutdown();
|
||||
logs_empty_and_mark_files_at_shutdown();
|
||||
|
||||
if (srv_conc_n_threads != 0) {
|
||||
fprintf(stderr,
|
||||
|
|
|
|||
|
|
@ -248,10 +248,8 @@ rw_lock_create_func(
|
|||
lock->mutex.cmutex_name = cmutex_name;
|
||||
ut_d(lock->mutex.mutex_type = 1);
|
||||
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
# ifdef UNIV_DEBUG
|
||||
UT_NOT_USED(cfile_name);
|
||||
UT_NOT_USED(cline);
|
||||
# endif
|
||||
(void) cfile_name;
|
||||
(void) cline;
|
||||
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
|
||||
|
||||
lock->lock_word = X_LOCK_DECR;
|
||||
|
|
|
|||
|
|
@ -266,6 +266,9 @@ mutex_create_func(
|
|||
#ifdef UNIV_DEBUG
|
||||
mutex->cfile_name = cfile_name;
|
||||
mutex->cline = cline;
|
||||
#else
|
||||
(void) cfile_name;
|
||||
(void) cline;
|
||||
#endif /* UNIV_DEBUG */
|
||||
mutex->count_os_wait = 0;
|
||||
mutex->cmutex_name= cmutex_name;
|
||||
|
|
|
|||
|
|
@ -1861,21 +1861,11 @@ trx_undo_set_state_at_finish(
|
|||
|
||||
if (undo->size == 1
|
||||
&& mach_read_from_2(page_hdr + TRX_UNDO_PAGE_FREE)
|
||||
< TRX_UNDO_PAGE_REUSE_LIMIT) {
|
||||
< TRX_UNDO_PAGE_REUSE_LIMIT
|
||||
&& UT_LIST_GET_LEN(rseg->update_undo_list) < 500
|
||||
&& UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
|
||||
|
||||
/* This is a heuristic to avoid the problem of all UNDO
|
||||
slots ending up in one of the UNDO lists. Previously if
|
||||
the server crashed with all the slots in one of the lists,
|
||||
transactions that required the slots of a different type
|
||||
would fail for lack of slots. */
|
||||
|
||||
if (UT_LIST_GET_LEN(rseg->update_undo_list) < 500
|
||||
&& UT_LIST_GET_LEN(rseg->insert_undo_list) < 500) {
|
||||
|
||||
state = TRX_UNDO_CACHED;
|
||||
} else {
|
||||
state = TRX_UNDO_TO_FREE;
|
||||
}
|
||||
state = TRX_UNDO_CACHED;
|
||||
|
||||
} else if (undo->type == TRX_UNDO_INSERT) {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue