Commit c5ab0159 authored by unknown's avatar unknown

Merge aivanov@bk-internal.mysql.com:/home/bk/mysql-5.0

into  mysql.com:/home/alexi/innodb/mysql-5.0-merge

parents 686b42da 5dddbb4a
...@@ -1915,13 +1915,13 @@ btr_cur_pessimistic_update( ...@@ -1915,13 +1915,13 @@ btr_cur_pessimistic_update(
ut_a(rec || optim_err != DB_UNDERFLOW); ut_a(rec || optim_err != DB_UNDERFLOW);
if (rec) { if (rec) {
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
lock_rec_restore_from_page_infimum(rec, page); lock_rec_restore_from_page_infimum(rec, page);
rec_set_field_extern_bits(rec, index, rec_set_field_extern_bits(rec, index,
ext_vect, n_ext_vect, mtr); ext_vect, n_ext_vect, mtr);
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) { if (!rec_get_deleted_flag(rec, rec_offs_comp(offsets))) {
/* The new inserted record owns its possible externally /* The new inserted record owns its possible externally
stored fields */ stored fields */
...@@ -3329,7 +3329,10 @@ btr_store_big_rec_extern_fields( ...@@ -3329,7 +3329,10 @@ btr_store_big_rec_extern_fields(
dict_index_t* index, /* in: index of rec; the index tree dict_index_t* index, /* in: index of rec; the index tree
MUST be X-latched */ MUST be X-latched */
rec_t* rec, /* in: record */ rec_t* rec, /* in: record */
const ulint* offsets, /* in: rec_get_offsets(rec, index) */ const ulint* offsets, /* in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
big_rec_t* big_rec_vec, /* in: vector containing fields big_rec_t* big_rec_vec, /* in: vector containing fields
to be stored externally */ to be stored externally */
mtr_t* local_mtr __attribute__((unused))) /* in: mtr mtr_t* local_mtr __attribute__((unused))) /* in: mtr
......
...@@ -1600,14 +1600,29 @@ btr_search_validate(void) ...@@ -1600,14 +1600,29 @@ btr_search_validate(void)
ulint n_page_dumps = 0; ulint n_page_dumps = 0;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
ulint cell_count;
mem_heap_t* heap = NULL; mem_heap_t* heap = NULL;
ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint offsets_[REC_OFFS_NORMAL_SIZE];
ulint* offsets = offsets_; ulint* offsets = offsets_;
*offsets_ = (sizeof offsets_) / sizeof *offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_;
/* How many cells to check before temporarily releasing
btr_search_latch. */
ulint chunk_size = 10000;
rw_lock_x_lock(&btr_search_latch); rw_lock_x_lock(&btr_search_latch);
for (i = 0; i < hash_get_n_cells(btr_search_sys->hash_index); i++) { cell_count = hash_get_n_cells(btr_search_sys->hash_index);
for (i = 0; i < cell_count; i++) {
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if ((i != 0) && ((i % chunk_size) == 0)) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node; node = hash_get_nth_cell(btr_search_sys->hash_index, i)->node;
while (node != NULL) { while (node != NULL) {
...@@ -1660,10 +1675,21 @@ btr_search_validate(void) ...@@ -1660,10 +1675,21 @@ btr_search_validate(void)
node = node->next; node = node->next;
} }
} }
if (!ha_validate(btr_search_sys->hash_index)) {
ok = FALSE; for (i = 0; i < cell_count; i += chunk_size) {
ulint end_index = ut_min(i + chunk_size - 1, cell_count - 1);
/* We release btr_search_latch every once in a while to
give other queries a chance to run. */
if (i != 0) {
rw_lock_x_unlock(&btr_search_latch);
os_thread_yield();
rw_lock_x_lock(&btr_search_latch);
}
if (!ha_validate(btr_search_sys->hash_index, i, end_index)) {
ok = FALSE;
}
} }
rw_lock_x_unlock(&btr_search_latch); rw_lock_x_unlock(&btr_search_latch);
......
...@@ -464,12 +464,17 @@ buf_block_init( ...@@ -464,12 +464,17 @@ buf_block_init(
byte* frame) /* in: pointer to buffer frame, or NULL if in byte* frame) /* in: pointer to buffer frame, or NULL if in
the case of AWE there is no frame */ the case of AWE there is no frame */
{ {
block->magic_n = 0;
block->state = BUF_BLOCK_NOT_USED; block->state = BUF_BLOCK_NOT_USED;
block->frame = frame; block->frame = frame;
block->awe_info = NULL; block->awe_info = NULL;
block->buf_fix_count = 0;
block->io_fix = 0;
block->modify_clock = ut_dulint_zero; block->modify_clock = ut_dulint_zero;
block->file_page_was_freed = FALSE; block->file_page_was_freed = FALSE;
......
...@@ -294,14 +294,14 @@ buf_LRU_try_free_flushed_blocks(void) ...@@ -294,14 +294,14 @@ buf_LRU_try_free_flushed_blocks(void)
} }
/********************************************************************** /**********************************************************************
Returns TRUE if less than 15 % of the buffer pool is available. This can be Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer used in heuristics to prevent huge transactions eating up the whole buffer
pool for their locks. */ pool for their locks. */
ibool ibool
buf_LRU_buf_pool_running_out(void) buf_LRU_buf_pool_running_out(void)
/*==============================*/ /*==============================*/
/* out: TRUE if less than 15 % of buffer pool /* out: TRUE if less than 25 % of buffer pool
left */ left */
{ {
ibool ret = FALSE; ibool ret = FALSE;
...@@ -309,7 +309,7 @@ buf_LRU_buf_pool_running_out(void) ...@@ -309,7 +309,7 @@ buf_LRU_buf_pool_running_out(void)
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 7) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
ret = TRUE; ret = TRUE;
} }
...@@ -340,11 +340,11 @@ buf_LRU_get_free_block(void) ...@@ -340,11 +340,11 @@ buf_LRU_get_free_block(void)
mutex_enter(&(buf_pool->mutex)); mutex_enter(&(buf_pool->mutex));
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 10) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 20) {
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: ERROR: over 9 / 10 of the buffer pool is occupied by\n" " InnoDB: ERROR: over 95 percent of the buffer pool is occupied by\n"
"InnoDB: lock heaps or the adaptive hash index! Check that your\n" "InnoDB: lock heaps or the adaptive hash index! Check that your\n"
"InnoDB: transactions do not set too many row locks.\n" "InnoDB: transactions do not set too many row locks.\n"
"InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n" "InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n"
...@@ -356,17 +356,17 @@ buf_LRU_get_free_block(void) ...@@ -356,17 +356,17 @@ buf_LRU_get_free_block(void)
ut_error; ut_error;
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free) } else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) { + UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 3) {
if (!buf_lru_switched_on_innodb_mon) { if (!buf_lru_switched_on_innodb_mon) {
/* Over 80 % of the buffer pool is occupied by lock /* Over 67 % of the buffer pool is occupied by lock
heaps or the adaptive hash index. This may be a memory heaps or the adaptive hash index. This may be a memory
leak! */ leak! */
ut_print_timestamp(stderr); ut_print_timestamp(stderr);
fprintf(stderr, fprintf(stderr,
" InnoDB: WARNING: over 4 / 5 of the buffer pool is occupied by\n" " InnoDB: WARNING: over 67 percent of the buffer pool is occupied by\n"
"InnoDB: lock heaps or the adaptive hash index! Check that your\n" "InnoDB: lock heaps or the adaptive hash index! Check that your\n"
"InnoDB: transactions do not set too many row locks.\n" "InnoDB: transactions do not set too many row locks.\n"
"InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n" "InnoDB: Your buffer pool size is %lu MB. Maybe you should make\n"
......
...@@ -252,7 +252,7 @@ dtype_print( ...@@ -252,7 +252,7 @@ dtype_print(
} else if (prtype == DATA_ENGLISH) { } else if (prtype == DATA_ENGLISH) {
fputs("DATA_ENGLISH", stderr); fputs("DATA_ENGLISH", stderr);
} else { } else {
fprintf(stderr, "prtype %lu", (ulong) mtype); fprintf(stderr, "prtype %lu", (ulong) prtype);
} }
} }
......
...@@ -2194,8 +2194,9 @@ dict_foreign_error_report( ...@@ -2194,8 +2194,9 @@ dict_foreign_error_report(
fputs(msg, file); fputs(msg, file);
fputs(" Constraint:\n", file); fputs(" Constraint:\n", file);
dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE); dict_print_info_on_foreign_key_in_create_format(file, NULL, fk, TRUE);
putc('\n', file);
if (fk->foreign_index) { if (fk->foreign_index) {
fputs("\nThe index in the foreign key in table is ", file); fputs("The index in the foreign key in table is ", file);
ut_print_name(file, NULL, fk->foreign_index->name); ut_print_name(file, NULL, fk->foreign_index->name);
fputs( fputs(
"\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n" "\nSee http://dev.mysql.com/doc/mysql/en/InnoDB_foreign_key_constraints.html\n"
......
...@@ -3557,6 +3557,7 @@ fil_extend_space_to_desired_size( ...@@ -3557,6 +3557,7 @@ fil_extend_space_to_desired_size(
*actual_size = space->size; *actual_size = space->size;
#ifndef UNIV_HOTBACKUP
if (space_id == 0) { if (space_id == 0) {
ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE; ulint pages_per_mb = (1024 * 1024) / UNIV_PAGE_SIZE;
...@@ -3566,6 +3567,7 @@ fil_extend_space_to_desired_size( ...@@ -3566,6 +3567,7 @@ fil_extend_space_to_desired_size(
srv_data_file_sizes[srv_n_data_files - 1] = srv_data_file_sizes[srv_n_data_files - 1] =
(node->size / pages_per_mb) * pages_per_mb; (node->size / pages_per_mb) * pages_per_mb;
} }
#endif /* !UNIV_HOTBACKUP */
/* /*
printf("Extended %s to %lu, actual size %lu pages\n", space->name, printf("Extended %s to %lu, actual size %lu pages\n", space->name,
...@@ -3820,6 +3822,31 @@ fil_node_complete_io( ...@@ -3820,6 +3822,31 @@ fil_node_complete_io(
} }
} }
/************************************************************************
Report information about an invalid page access. */
static
void
fil_report_invalid_page_access(
/*===========================*/
ulint block_offset, /* in: block offset */
ulint space_id, /* in: space id */
const char* space_name, /* in: space name */
ulint byte_offset, /* in: byte offset */
ulint len, /* in: I/O length */
ulint type) /* in: I/O type */
{
fprintf(stderr,
"InnoDB: Error: trying to access page number %lu in space %lu,\n"
"InnoDB: space name %s,\n"
"InnoDB: which is outside the tablespace bounds.\n"
"InnoDB: Byte offset %lu, len %lu, i/o type %lu.\n"
"InnoDB: If you get this error at mysqld startup, please check that\n"
"InnoDB: your my.cnf matches the ibdata files that you have in the\n"
"InnoDB: MySQL server.\n",
(ulong) block_offset, (ulong) space_id, space_name,
(ulong) byte_offset, (ulong) len, (ulong) type);
}
/************************************************************************ /************************************************************************
Reads or writes data. This operation is asynchronous (aio). */ Reads or writes data. This operation is asynchronous (aio). */
...@@ -3926,14 +3953,8 @@ fil_io( ...@@ -3926,14 +3953,8 @@ fil_io(
for (;;) { for (;;) {
if (node == NULL) { if (node == NULL) {
fprintf(stderr, fil_report_invalid_page_access(block_offset, space_id,
"InnoDB: Error: trying to access page number %lu in space %lu,\n" space->name, byte_offset, len, type);
"InnoDB: space name %s,\n"
"InnoDB: which is outside the tablespace bounds.\n"
"InnoDB: Byte offset %lu, len %lu, i/o type %lu\n",
(ulong) block_offset, (ulong) space_id,
space->name, (ulong) byte_offset, (ulong) len,
(ulong) type);
ut_error; ut_error;
} }
...@@ -3962,15 +3983,10 @@ fil_io( ...@@ -3962,15 +3983,10 @@ fil_io(
if (space->purpose == FIL_TABLESPACE && space->id != 0 if (space->purpose == FIL_TABLESPACE && space->id != 0
&& node->size <= block_offset) { && node->size <= block_offset) {
fprintf(stderr, fil_report_invalid_page_access(block_offset, space_id,
"InnoDB: Error: trying to access page number %lu in space %lu,\n" space->name, byte_offset, len, type);
"InnoDB: space name %s,\n"
"InnoDB: which is outside the tablespace bounds.\n" ut_error;
"InnoDB: Byte offset %lu, len %lu, i/o type %lu\n",
(ulong) block_offset, (ulong) space_id,
space->name, (ulong) byte_offset, (ulong) len,
(ulong) type);
ut_a(0);
} }
/* Now we have made the changes in the data structures of system */ /* Now we have made the changes in the data structures of system */
......
...@@ -276,20 +276,26 @@ ha_remove_all_nodes_to_page( ...@@ -276,20 +276,26 @@ ha_remove_all_nodes_to_page(
} }
/***************************************************************** /*****************************************************************
Validates a hash table. */ Validates a given range of the cells in hash table. */
ibool ibool
ha_validate( ha_validate(
/*========*/ /*========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
hash_table_t* table) /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index) /* in: end index */
{ {
hash_cell_t* cell; hash_cell_t* cell;
ha_node_t* node; ha_node_t* node;
ibool ok = TRUE; ibool ok = TRUE;
ulint i; ulint i;
for (i = 0; i < hash_get_n_cells(table); i++) { ut_a(start_index <= end_index);
ut_a(start_index < hash_get_n_cells(table));
ut_a(end_index < hash_get_n_cells(table));
for (i = start_index; i <= end_index; i++) {
cell = hash_get_nth_cell(table, i); cell = hash_get_nth_cell(table, i);
......
...@@ -459,7 +459,10 @@ btr_store_big_rec_extern_fields( ...@@ -459,7 +459,10 @@ btr_store_big_rec_extern_fields(
dict_index_t* index, /* in: index of rec; the index tree dict_index_t* index, /* in: index of rec; the index tree
MUST be X-latched */ MUST be X-latched */
rec_t* rec, /* in: record */ rec_t* rec, /* in: record */
const ulint* offsets, /* in: rec_get_offsets(rec, index) */ const ulint* offsets, /* in: rec_get_offsets(rec, index);
the "external storage" flags in offsets
will not correspond to rec when
this function returns */
big_rec_t* big_rec_vec, /* in: vector containing fields big_rec_t* big_rec_vec, /* in: vector containing fields
to be stored externally */ to be stored externally */
mtr_t* local_mtr); /* in: mtr containing the latch to mtr_t* local_mtr); /* in: mtr containing the latch to
......
...@@ -26,14 +26,14 @@ void ...@@ -26,14 +26,14 @@ void
buf_LRU_try_free_flushed_blocks(void); buf_LRU_try_free_flushed_blocks(void);
/*==================================*/ /*==================================*/
/********************************************************************** /**********************************************************************
Returns TRUE if less than 15 % of the buffer pool is available. This can be Returns TRUE if less than 25 % of the buffer pool is available. This can be
used in heuristics to prevent huge transactions eating up the whole buffer used in heuristics to prevent huge transactions eating up the whole buffer
pool for their locks. */ pool for their locks. */
ibool ibool
buf_LRU_buf_pool_running_out(void); buf_LRU_buf_pool_running_out(void);
/*==============================*/ /*==============================*/
/* out: TRUE if less than 15 % of buffer pool /* out: TRUE if less than 25 % of buffer pool
left */ left */
/*####################################################################### /*#######################################################################
......
...@@ -114,13 +114,15 @@ ha_remove_all_nodes_to_page( ...@@ -114,13 +114,15 @@ ha_remove_all_nodes_to_page(
ulint fold, /* in: fold value */ ulint fold, /* in: fold value */
page_t* page); /* in: buffer page */ page_t* page); /* in: buffer page */
/***************************************************************** /*****************************************************************
Validates a hash table. */ Validates a given range of the cells in hash table. */
ibool ibool
ha_validate( ha_validate(
/*========*/ /*========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
hash_table_t* table); /* in: hash table */ hash_table_t* table, /* in: hash table */
ulint start_index, /* in: start index */
ulint end_index); /* in: end index */
/***************************************************************** /*****************************************************************
Prints info of a hash table. */ Prints info of a hash table. */
......
...@@ -175,19 +175,6 @@ page_rec_is_comp( ...@@ -175,19 +175,6 @@ page_rec_is_comp(
/* out: nonzero if in compact format */ /* out: nonzero if in compact format */
const rec_t* rec) /* in: record */ const rec_t* rec) /* in: record */
{ {
#ifdef UNIV_RELEASE_NOT_YET_STABLE
if (UNIV_UNLIKELY((ulint)rec < (ulint)(buf_pool->frame_zero))
|| UNIV_UNLIKELY((ulint)rec >= (ulint)(buf_pool->high_end))) {
ut_print_timestamp(stderr);
fprintf(stderr,
"InnoDB: Error: trying to read a stray page rec %p\n"
"InnoDB: buf pool start is at %p, end at %p\n",
rec, buf_pool->frame_zero,
buf_pool->high_end);
ut_error;
}
#endif
return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE))); return(page_is_comp(ut_align_down((rec_t*) rec, UNIV_PAGE_SIZE)));
} }
......
...@@ -80,10 +80,6 @@ memory is read outside the allocated blocks. */ ...@@ -80,10 +80,6 @@ memory is read outside the allocated blocks. */
/* Make a non-inline debug version */ /* Make a non-inline debug version */
/* You can remove this define when the release is stable. This define adds
some consistency checks to code. They use a little CPU time. */
#define UNIV_RELEASE_NOT_YET_STABLE
/* /*
#define UNIV_DEBUG #define UNIV_DEBUG
#define UNIV_MEM_DEBUG #define UNIV_MEM_DEBUG
......
...@@ -28,6 +28,7 @@ Created 4/20/1996 Heikki Tuuri ...@@ -28,6 +28,7 @@ Created 4/20/1996 Heikki Tuuri
#include "eval0eval.h" #include "eval0eval.h"
#include "data0data.h" #include "data0data.h"
#include "usr0sess.h" #include "usr0sess.h"
#include "buf0lru.h"
#define ROW_INS_PREV 1 #define ROW_INS_PREV 1
#define ROW_INS_NEXT 2 #define ROW_INS_NEXT 2
...@@ -278,10 +279,17 @@ row_ins_sec_index_entry_by_modify( ...@@ -278,10 +279,17 @@ row_ins_sec_index_entry_by_modify(
} }
} else { } else {
ut_a(mode == BTR_MODIFY_TREE); ut_a(mode == BTR_MODIFY_TREE);
if (buf_LRU_buf_pool_running_out()) {
err = DB_LOCK_TABLE_FULL;
goto func_exit;
}
err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG, cursor, err = btr_cur_pessimistic_update(BTR_KEEP_SYS_FLAG, cursor,
&dummy_big_rec, update, 0, thr, mtr); &dummy_big_rec, update, 0, thr, mtr);
} }
func_exit:
mem_heap_free(heap); mem_heap_free(heap);
return(err); return(err);
...@@ -342,10 +350,16 @@ row_ins_clust_index_entry_by_modify( ...@@ -342,10 +350,16 @@ row_ins_clust_index_entry_by_modify(
} }
} else { } else {
ut_a(mode == BTR_MODIFY_TREE); ut_a(mode == BTR_MODIFY_TREE);
if (buf_LRU_buf_pool_running_out()) {
err = DB_LOCK_TABLE_FULL;
goto func_exit;
}
err = btr_cur_pessimistic_update(0, cursor, big_rec, update, err = btr_cur_pessimistic_update(0, cursor, big_rec, update,
0, thr, mtr); 0, thr, mtr);
} }
func_exit:
mem_heap_free(heap); mem_heap_free(heap);
return(err); return(err);
...@@ -1860,7 +1874,6 @@ row_ins_duplicate_error_in_clust( ...@@ -1860,7 +1874,6 @@ row_ins_duplicate_error_in_clust(
err = DB_DUPLICATE_KEY; err = DB_DUPLICATE_KEY;
goto func_exit; goto func_exit;
} }
mem_heap_free(heap);
} }
ut_a(!(cursor->index->type & DICT_CLUSTERED)); ut_a(!(cursor->index->type & DICT_CLUSTERED));
...@@ -1869,6 +1882,9 @@ row_ins_duplicate_error_in_clust( ...@@ -1869,6 +1882,9 @@ row_ins_duplicate_error_in_clust(
err = DB_SUCCESS; err = DB_SUCCESS;
func_exit: func_exit:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
return(err); return(err);
#else /* UNIV_HOTBACKUP */ #else /* UNIV_HOTBACKUP */
/* This function depends on MySQL code that is not included in /* This function depends on MySQL code that is not included in
...@@ -2068,6 +2084,12 @@ row_ins_index_entry_low( ...@@ -2068,6 +2084,12 @@ row_ins_index_entry_low(
&insert_rec, &big_rec, thr, &mtr); &insert_rec, &big_rec, thr, &mtr);
} else { } else {
ut_a(mode == BTR_MODIFY_TREE); ut_a(mode == BTR_MODIFY_TREE);
if (buf_LRU_buf_pool_running_out()) {
err = DB_LOCK_TABLE_FULL;
goto function_exit;
}
err = btr_cur_pessimistic_insert(0, &cursor, entry, err = btr_cur_pessimistic_insert(0, &cursor, entry,
&insert_rec, &big_rec, thr, &mtr); &insert_rec, &big_rec, thr, &mtr);
} }
......
...@@ -2358,16 +2358,16 @@ row_sel_field_store_in_mysql_format( ...@@ -2358,16 +2358,16 @@ row_sel_field_store_in_mysql_format(
} else if (templ->type == DATA_MYSQL) { } else if (templ->type == DATA_MYSQL) {
memcpy(dest, data, len); memcpy(dest, data, len);
ut_a(templ->mysql_col_len >= len); ut_ad(templ->mysql_col_len >= len);
ut_a(templ->mbmaxlen >= templ->mbminlen); ut_ad(templ->mbmaxlen >= templ->mbminlen);
ut_a(templ->mbmaxlen > templ->mbminlen ut_ad(templ->mbmaxlen > templ->mbminlen
|| templ->mysql_col_len == len); || templ->mysql_col_len == len);
/* The following assertion would fail for old tables /* The following assertion would fail for old tables
containing UTF-8 ENUM columns due to Bug #9526. */ containing UTF-8 ENUM columns due to Bug #9526. */
ut_ad(!templ->mbmaxlen ut_ad(!templ->mbmaxlen
|| !(templ->mysql_col_len % templ->mbmaxlen)); || !(templ->mysql_col_len % templ->mbmaxlen));
ut_a(len * templ->mbmaxlen >= templ->mysql_col_len); ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len);
if (templ->mbminlen != templ->mbmaxlen) { if (templ->mbminlen != templ->mbmaxlen) {
/* Pad with spaces. This undoes the stripping /* Pad with spaces. This undoes the stripping
...@@ -2377,7 +2377,7 @@ row_sel_field_store_in_mysql_format( ...@@ -2377,7 +2377,7 @@ row_sel_field_store_in_mysql_format(
memset(dest + len, 0x20, templ->mysql_col_len - len); memset(dest + len, 0x20, templ->mysql_col_len - len);
} }
} else { } else {
ut_a(templ->type == DATA_CHAR ut_ad(templ->type == DATA_CHAR
|| templ->type == DATA_FIXBINARY || templ->type == DATA_FIXBINARY
/*|| templ->type == DATA_SYS_CHILD /*|| templ->type == DATA_SYS_CHILD
|| templ->type == DATA_SYS*/ || templ->type == DATA_SYS*/
......
...@@ -28,6 +28,7 @@ Created 12/27/1996 Heikki Tuuri ...@@ -28,6 +28,7 @@ Created 12/27/1996 Heikki Tuuri
#include "log0log.h" #include "log0log.h"
#include "pars0sym.h" #include "pars0sym.h"
#include "eval0eval.h" #include "eval0eval.h"
#include "buf0lru.h"
/* What kind of latch and lock can we assume when the control comes to /* What kind of latch and lock can we assume when the control comes to
...@@ -1523,6 +1524,10 @@ row_upd_clust_rec( ...@@ -1523,6 +1524,10 @@ row_upd_clust_rec(
return(err); return(err);
} }
if (buf_LRU_buf_pool_running_out()) {
return(DB_LOCK_TABLE_FULL);
}
/* We may have to modify the tree structure: do a pessimistic descent /* We may have to modify the tree structure: do a pessimistic descent
down the index tree */ down the index tree */
......
...@@ -2124,5 +2124,6 @@ drop trigger t2t; ...@@ -2124,5 +2124,6 @@ drop trigger t2t;
drop trigger t3t; drop trigger t3t;
drop trigger t4t; drop trigger t4t;
drop table t1, t2, t3, t4, t5; drop table t1, t2, t3, t4, t5;
connection default;
disconnect a; disconnect a;
disconnect b; disconnect b;
...@@ -513,13 +513,13 @@ convert_error_code_to_mysql( ...@@ -513,13 +513,13 @@ convert_error_code_to_mysql(
return(HA_ERR_NO_SAVEPOINT); return(HA_ERR_NO_SAVEPOINT);
} else if (error == (int) DB_LOCK_TABLE_FULL) { } else if (error == (int) DB_LOCK_TABLE_FULL) {
/* Since we rolled back the whole transaction, we must /* Since we rolled back the whole transaction, we must
tell it also to MySQL so that MySQL knows to empty the tell it also to MySQL so that MySQL knows to empty the
cached binlog for this transaction */ cached binlog for this transaction */
if (thd) { if (thd) {
ha_rollback(thd); ha_rollback(thd);
} }
return(HA_ERR_LOCK_TABLE_FULL); return(HA_ERR_LOCK_TABLE_FULL);
} else { } else {
...@@ -6726,32 +6726,37 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length, ...@@ -6726,32 +6726,37 @@ static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
static INNOBASE_SHARE *get_share(const char *table_name) static INNOBASE_SHARE *get_share(const char *table_name)
{ {
INNOBASE_SHARE *share; INNOBASE_SHARE *share;
pthread_mutex_lock(&innobase_share_mutex); pthread_mutex_lock(&innobase_share_mutex);
uint length=(uint) strlen(table_name); uint length=(uint) strlen(table_name);
if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
(mysql_byte*) table_name, if (!(share=(INNOBASE_SHARE*) hash_search(&innobase_open_tables,
length))) (mysql_byte*) table_name,
{ length))) {
if ((share=(INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
MYF(MY_WME | MY_ZEROFILL)))) share = (INNOBASE_SHARE *) my_malloc(sizeof(*share)+length+1,
{ MYF(MY_FAE | MY_ZEROFILL));
share->table_name_length=length;
share->table_name=(char*) (share+1); share->table_name_length=length;
strmov(share->table_name,table_name); share->table_name=(char*) (share+1);
if (my_hash_insert(&innobase_open_tables, (mysql_byte*) share)) strmov(share->table_name,table_name);
{
pthread_mutex_unlock(&innobase_share_mutex); if (my_hash_insert(&innobase_open_tables,
my_free((gptr) share,0); (mysql_byte*) share)) {
return 0; pthread_mutex_unlock(&innobase_share_mutex);
} my_free((gptr) share,0);
thr_lock_init(&share->lock);
pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST); return 0;
} }
}
share->use_count++; thr_lock_init(&share->lock);
pthread_mutex_unlock(&innobase_share_mutex); pthread_mutex_init(&share->mutex,MY_MUTEX_INIT_FAST);
return share; }
share->use_count++;
pthread_mutex_unlock(&innobase_share_mutex);
return share;
} }
static void free_share(INNOBASE_SHARE *share) static void free_share(INNOBASE_SHARE *share)
...@@ -6825,14 +6830,16 @@ ha_innobase::store_lock( ...@@ -6825,14 +6830,16 @@ ha_innobase::store_lock(
prebuilt->trx->isolation_level != TRX_ISO_SERIALIZABLE && prebuilt->trx->isolation_level != TRX_ISO_SERIALIZABLE &&
(lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) &&
(thd->lex->sql_command == SQLCOM_INSERT_SELECT || (thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
thd->lex->sql_command == SQLCOM_UPDATE)) { thd->lex->sql_command == SQLCOM_UPDATE ||
thd->lex->sql_command == SQLCOM_CREATE_TABLE)) {
/* In case we have innobase_locks_unsafe_for_binlog /* In case we have innobase_locks_unsafe_for_binlog
option set and isolation level of the transaction option set and isolation level of the transaction
is not set to serializable and MySQL is doing is not set to serializable and MySQL is doing
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
without FOR UPDATE or IN SHARE MODE in select, then CREATE ... SELECT... without FOR UPDATE or
we use consistent read for select. */ IN SHARE MODE in select, then we use consistent
read for select. */
prebuilt->select_lock_type = LOCK_NONE; prebuilt->select_lock_type = LOCK_NONE;
prebuilt->stored_select_lock_type = LOCK_NONE; prebuilt->stored_select_lock_type = LOCK_NONE;
...@@ -6885,14 +6892,15 @@ ha_innobase::store_lock( ...@@ -6885,14 +6892,15 @@ ha_innobase::store_lock(
writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ writers. Note that ALTER TABLE uses a TL_WRITE_ALLOW_READ
< TL_WRITE_CONCURRENT_INSERT. < TL_WRITE_CONCURRENT_INSERT.
We especially allow multiple writers if MySQL is at the We especially allow multiple writers if MySQL is at the
start of a stored procedure call (SQLCOM_CALL) start of a stored procedure call (SQLCOM_CALL) or a
(MySQL does have thd->in_lock_tables TRUE there). */ stored function call (MySQL does have thd->in_lock_tables
TRUE there). */
if ((lock_type >= TL_WRITE_CONCURRENT_INSERT if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
&& lock_type <= TL_WRITE) && lock_type <= TL_WRITE)
&& !(thd->in_lock_tables && !(thd->in_lock_tables
&& thd->lex->sql_command == SQLCOM_LOCK_TABLES) && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
&& !thd->tablespace_op && !thd->tablespace_op
&& thd->lex->sql_command != SQLCOM_TRUNCATE && thd->lex->sql_command != SQLCOM_TRUNCATE
&& thd->lex->sql_command != SQLCOM_OPTIMIZE && thd->lex->sql_command != SQLCOM_OPTIMIZE
......
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