Commit c1286aa4 authored by marko's avatar marko

branches/zip: Merge revisions 887:934 from trunk.

parent 5d64128b
...@@ -92,7 +92,7 @@ EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr ...@@ -92,7 +92,7 @@ EXTRA_DIST = include/btr0btr.h include/btr0btr.ic include/btr0cur.h include/btr
include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \ include/ut0sort.h include/ut0ut.h include/ut0ut.ic include/ut0vec.h include/ut0vec.ic include/ha_prototypes.h \
include/ut0list.h include/ut0list.ic \ include/ut0list.h include/ut0list.ic \
include/ut0wqueue.h \ include/ut0wqueue.h \
CMakeLists.txt CMakeLists.txt plug.in
noinst_LIBRARIES = libinnobase.a noinst_LIBRARIES = libinnobase.a
libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \ libinnobase_a_LIBADD = usr/libusr.a srv/libsrv.a dict/libdict.a \
......
...@@ -2157,23 +2157,56 @@ btr_lift_page_up( ...@@ -2157,23 +2157,56 @@ btr_lift_page_up(
record from the page should be removed */ record from the page should be removed */
mtr_t* mtr) /* in: mtr */ mtr_t* mtr) /* in: mtr */
{ {
btr_cur_t father_cursor;
buf_block_t* father_block; buf_block_t* father_block;
page_t* father_page; page_t* father_page;
ulint page_level; ulint page_level;
page_zip_des_t* father_page_zip; page_zip_des_t* father_page_zip;
page_t* page = buf_block_get_frame(block); page_t* page = buf_block_get_frame(block);
ulint root_page_no;
buf_block_t* blocks[BTR_MAX_LEVELS];
ulint n_blocks; /* last used index in blocks[] */
ulint i;
ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL);
ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); ut_ad(btr_page_get_next(page, mtr) == FIL_NULL);
ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX)); ut_ad(mtr_memo_contains(mtr, block, MTR_MEMO_PAGE_X_FIX));
btr_page_get_father(index, block, mtr, &father_cursor); {
father_block = btr_cur_get_block(&father_cursor); btr_cur_t cursor;
father_page_zip = buf_block_get_page_zip(father_block); mem_heap_t* heap = mem_heap_create(100);
father_page = buf_block_get_frame(father_block); ulint* offsets;
page_level = btr_page_get_level(page, mtr); offsets = btr_page_get_father_block(NULL, heap, index,
block, mtr, &cursor);
father_block = btr_cur_get_block(&cursor);
father_page_zip = buf_block_get_page_zip(father_block);
father_page = buf_block_get_frame(father_block);
page_level = btr_page_get_level(page, mtr);
root_page_no = dict_index_get_page(index);
n_blocks = 0;
blocks[0] = father_block;
/* Store all ancestor pages so we can reset their
levels later on. We have to do all the searches on
the tree now because later on, after we've replaced
the first level, the tree is in an inconsistent state
and can not be searched. */
while (buf_block_get_page_no(blocks[n_blocks])
!= root_page_no) {
ut_a(n_blocks < BTR_MAX_LEVELS);
offsets = btr_page_get_father_block(offsets, heap,
index,
blocks[n_blocks],
mtr, &cursor);
blocks[++n_blocks] = btr_cur_get_block(&cursor);
}
mem_heap_free(heap);
}
btr_search_drop_page_hash_index(block); btr_search_drop_page_hash_index(block);
...@@ -2199,6 +2232,16 @@ btr_lift_page_up( ...@@ -2199,6 +2232,16 @@ btr_lift_page_up(
lock_update_copy_and_discard(father_block, block); lock_update_copy_and_discard(father_block, block);
/* Go upward to root page, decrementing levels by one. */
for (i = 0; i <= n_blocks; i++, page_level++) {
page_t* page = buf_block_get_frame(blocks[i]);
ut_ad(btr_page_get_level(page, mtr) == page_level + 1);
btr_page_set_level(page, buf_block_get_page_zip(blocks[i]),
page_level, mtr);
}
/* Free the file page */ /* Free the file page */
btr_page_free(index, block, mtr); btr_page_free(index, block, mtr);
......
...@@ -326,7 +326,7 @@ dict_col_copy_type_noninline( ...@@ -326,7 +326,7 @@ dict_col_copy_type_noninline(
const dict_col_t* col, /* in: column */ const dict_col_t* col, /* in: column */
dtype_t* type) /* out: data type */ dtype_t* type) /* out: data type */
{ {
return(dict_col_copy_type(col, type)); dict_col_copy_type(col, type);
} }
/************************************************************************ /************************************************************************
...@@ -3559,51 +3559,13 @@ dict_index_get_if_in_cache_low( ...@@ -3559,51 +3559,13 @@ dict_index_get_if_in_cache_low(
/* out: index, NULL if not found */ /* out: index, NULL if not found */
dulint index_id) /* in: index id */ dulint index_id) /* in: index id */
{ {
dict_table_t* table;
dict_index_t* index; dict_index_t* index;
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
ut_ad(mutex_own(&(dict_sys->mutex))); ut_ad(mutex_own(&(dict_sys->mutex)));
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
table = UT_LIST_GET_FIRST(dict_sys->table_LRU); index = dict_index_find_on_id_low(index_id);
while (table) {
index = UT_LIST_GET_FIRST(table->indexes);
while (index) {
if (0 == ut_dulint_cmp(index->id, index_id)) {
return(index);
}
index = UT_LIST_GET_NEXT(indexes, index);
}
table = UT_LIST_GET_NEXT(table_LRU, table);
}
return(NULL);
}
/**************************************************************************
Returns an index object if it is found in the dictionary cache. */
dict_index_t*
dict_index_get_if_in_cache(
/*=======================*/
/* out: index, NULL if not found */
dulint index_id) /* in: index id */
{
dict_index_t* index;
if (dict_sys == NULL) {
return(NULL);
}
mutex_enter(&(dict_sys->mutex));
index = dict_index_get_if_in_cache_low(index_id);
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
...@@ -4183,18 +4145,8 @@ dict_print_info_on_foreign_key_in_create_format( ...@@ -4183,18 +4145,8 @@ dict_print_info_on_foreign_key_in_create_format(
dict_remove_db_name( dict_remove_db_name(
foreign->referenced_table_name)); foreign->referenced_table_name));
} else { } else {
/* Look for the '/' in the table name */
i = 0;
while (foreign->referenced_table_name[i] != '/') {
i++;
}
ut_print_namel(file, trx, TRUE,
foreign->referenced_table_name, i);
putc('.', file);
ut_print_name(file, trx, TRUE, ut_print_name(file, trx, TRUE,
foreign->referenced_table_name + i + 1); foreign->referenced_table_name);
} }
putc(' ', file); putc(' ', file);
......
...@@ -6639,7 +6639,7 @@ innodb_mutex_show_status( ...@@ -6639,7 +6639,7 @@ innodb_mutex_show_status(
mutex->count_spin_rounds, mutex->count_spin_rounds,
mutex->count_os_wait, mutex->count_os_wait,
mutex->count_os_yield, mutex->count_os_yield,
mutex->lspent_time/1000); (ulong) mutex->lspent_time/1000);
if (stat_print(thd, innobase_hton_name, if (stat_print(thd, innobase_hton_name,
hton_name_len, buf1, buf1len, hton_name_len, buf1, buf1len,
...@@ -6669,7 +6669,7 @@ innodb_mutex_show_status( ...@@ -6669,7 +6669,7 @@ innodb_mutex_show_status(
rw_lock_count, rw_lock_count_spin_loop, rw_lock_count, rw_lock_count_spin_loop,
rw_lock_count_spin_rounds, rw_lock_count_spin_rounds,
rw_lock_count_os_wait, rw_lock_count_os_yield, rw_lock_count_os_wait, rw_lock_count_os_yield,
rw_lock_wait_time/1000); (ulong) rw_lock_wait_time/1000);
if (stat_print(thd, innobase_hton_name, hton_name_len, if (stat_print(thd, innobase_hton_name, hton_name_len,
STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) { STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
...@@ -6821,7 +6821,8 @@ ha_innobase::store_lock( ...@@ -6821,7 +6821,8 @@ ha_innobase::store_lock(
&& lock_type != TL_IGNORE)) { && lock_type != TL_IGNORE)) {
/* The OR cases above are in this order: /* The OR cases above are in this order:
1) MySQL is doing LOCK TABLES ... READ LOCAL, or 1) MySQL is doing LOCK TABLES ... READ LOCAL, or we
are processing a stored procedure or function, or
2) (we do not know when TL_READ_HIGH_PRIORITY is used), or 2) (we do not know when TL_READ_HIGH_PRIORITY is used), or
3) this is a SELECT ... IN SHARE MODE, or 3) this is a SELECT ... IN SHARE MODE, or
4) we are doing a complex SQL statement like 4) we are doing a complex SQL statement like
...@@ -6889,7 +6890,8 @@ ha_innobase::store_lock( ...@@ -6889,7 +6890,8 @@ ha_innobase::store_lock(
single transaction stored procedure call deterministic single transaction stored procedure call deterministic
(if it does not use a consistent read). */ (if it does not use a consistent read). */
if (lock_type == TL_READ && thd->in_lock_tables) { if (lock_type == TL_READ
&& thd->lex->sql_command == SQLCOM_LOCK_TABLES) {
/* We come here if MySQL is processing LOCK TABLES /* We come here if MySQL is processing LOCK TABLES
... READ LOCAL. MyISAM under that table lock type ... READ LOCAL. MyISAM under that table lock type
reads the table as it was at the time the lock was reads the table as it was at the time the lock was
...@@ -6948,8 +6950,7 @@ ha_innobase::store_lock( ...@@ -6948,8 +6950,7 @@ ha_innobase::store_lock(
(MySQL does have thd->in_lock_tables TRUE there). */ (MySQL does have thd->in_lock_tables TRUE there). */
if (lock_type == TL_READ_NO_INSERT if (lock_type == TL_READ_NO_INSERT
&& (!thd->in_lock_tables && thd->lex->sql_command != SQLCOM_LOCK_TABLES) {
|| thd->lex->sql_command == SQLCOM_CALL)) {
lock_type = TL_READ; lock_type = TL_READ;
} }
...@@ -7649,6 +7650,7 @@ mysql_declare_plugin(innobase) ...@@ -7649,6 +7650,7 @@ mysql_declare_plugin(innobase)
innobase_hton_name, innobase_hton_name,
"Innobase OY", "Innobase OY",
"Supports transactions, row-level locking, and foreign keys", "Supports transactions, row-level locking, and foreign keys",
PLUGIN_LICENSE_GPL,
innobase_init, /* Plugin Init */ innobase_init, /* Plugin Init */
NULL, /* Plugin Deinit */ NULL, /* Plugin Deinit */
0x0100 /* 1.0 */, 0x0100 /* 1.0 */,
......
...@@ -23,7 +23,17 @@ special big record storage structure */ ...@@ -23,7 +23,17 @@ special big record storage structure */
#define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200) #define BTR_PAGE_MAX_REC_SIZE (UNIV_PAGE_SIZE / 2 - 200)
/* Latching modes for the search function (in btr0cur.*) */ /* Maximum depth of a B-tree in InnoDB. Note that this isn't a maximum as
such; none of the tree operations avoid producing trees bigger than this. It
is instead a "max depth that other code must work with", useful for e.g.
fixed-size arrays that must store some information about each level in a
tree. In other words: if a B-tree with bigger depth than this is
encountered, it is not acceptable for it to lead to mysterious memory
corruption, but it is acceptable for the program to die with a clear assert
failure. */
#define BTR_MAX_LEVELS 100
/* Latching modes for btr_cur_search_to_nth_level(). */
#define BTR_SEARCH_LEAF RW_S_LATCH #define BTR_SEARCH_LEAF RW_S_LATCH
#define BTR_MODIFY_LEAF RW_X_LATCH #define BTR_MODIFY_LEAF RW_X_LATCH
#define BTR_NO_LATCHES RW_NO_LATCH #define BTR_NO_LATCHES RW_NO_LATCH
......
...@@ -826,8 +826,6 @@ const dict_col_t* ...@@ -826,8 +826,6 @@ const dict_col_t*
dict_field_get_col( dict_field_get_col(
/*===============*/ /*===============*/
const dict_field_t* field); const dict_field_t* field);
/**************************************************************************
In an index tree, finds the index corresponding to a record in the tree. */
/************************************************************************** /**************************************************************************
Returns an index object if it is found in the dictionary cache. Returns an index object if it is found in the dictionary cache.
...@@ -838,6 +836,7 @@ dict_index_get_if_in_cache_low( ...@@ -838,6 +836,7 @@ dict_index_get_if_in_cache_low(
/*===========================*/ /*===========================*/
/* out: index, NULL if not found */ /* out: index, NULL if not found */
dulint index_id); /* in: index id */ dulint index_id); /* in: index id */
#ifdef UNIV_DEBUG
/************************************************************************** /**************************************************************************
Returns an index object if it is found in the dictionary cache. */ Returns an index object if it is found in the dictionary cache. */
...@@ -846,7 +845,6 @@ dict_index_get_if_in_cache( ...@@ -846,7 +845,6 @@ dict_index_get_if_in_cache(
/*=======================*/ /*=======================*/
/* out: index, NULL if not found */ /* out: index, NULL if not found */
dulint index_id); /* in: index id */ dulint index_id); /* in: index id */
#ifdef UNIV_DEBUG
/************************************************************************** /**************************************************************************
Checks that a tuple has n_fields_cmp value in a sensible range, so that Checks that a tuple has n_fields_cmp value in a sensible range, so that
no comparison can occur with the page number field in a node pointer. */ no comparison can occur with the page number field in a node pointer. */
......
...@@ -30,6 +30,7 @@ check fields at the both ends of the field. */ ...@@ -30,6 +30,7 @@ check fields at the both ends of the field. */
#define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT) #define MEM_SPACE_NEEDED(N) ut_calc_align((N), UNIV_MEM_ALIGNMENT)
#endif #endif
#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
/******************************************************************* /*******************************************************************
Checks a memory heap for consistency and prints the contents if requested. Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in Outputs the sum of sizes of buffers given to the user (only in
...@@ -59,15 +60,8 @@ mem_heap_validate_or_print( ...@@ -59,15 +60,8 @@ mem_heap_validate_or_print(
ulint* n_blocks); /* out: number of blocks in the heap, ulint* n_blocks); /* out: number of blocks in the heap,
if a NULL pointer is passed as this if a NULL pointer is passed as this
argument, it is ignored */ argument, it is ignored */
#ifdef UNIV_MEM_DEBUG #endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
/****************************************************************** #ifdef UNIV_DEBUG
Prints the contents of a memory heap. */
void
mem_heap_print(
/*===========*/
mem_heap_t* heap); /* in: memory heap */
#endif /* UNIV_MEM_DEBUG */
/****************************************************************** /******************************************************************
Checks that an object is a memory heap (or a block of it) */ Checks that an object is a memory heap (or a block of it) */
...@@ -76,6 +70,7 @@ mem_heap_check( ...@@ -76,6 +70,7 @@ mem_heap_check(
/*===========*/ /*===========*/
/* out: TRUE if ok */ /* out: TRUE if ok */
mem_heap_t* heap); /* in: memory heap */ mem_heap_t* heap); /* in: memory heap */
#endif /* UNIV_DEBUG */
/****************************************************************** /******************************************************************
Validates the contents of a memory heap. */ Validates the contents of a memory heap. */
......
...@@ -358,8 +358,9 @@ rw_lock_print( ...@@ -358,8 +358,9 @@ rw_lock_print(
Prints debug info of currently locked rw-locks. */ Prints debug info of currently locked rw-locks. */
void void
rw_lock_list_print_info(void); rw_lock_list_print_info(
/*=========================*/ /*====================*/
FILE* file); /* in: file where to print */
/******************************************************************* /*******************************************************************
Returns the number of currently locked rw-locks. Returns the number of currently locked rw-locks.
Works only in the debug version. */ Works only in the debug version. */
......
...@@ -224,12 +224,6 @@ Counts currently reserved mutexes. Works only in the debug version. */ ...@@ -224,12 +224,6 @@ Counts currently reserved mutexes. Works only in the debug version. */
ulint ulint
mutex_n_reserved(void); mutex_n_reserved(void);
/*==================*/ /*==================*/
/**********************************************************************
Prints debug info of currently reserved mutexes. */
void
mutex_list_print_info(void);
/*========================*/
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
/********************************************************************** /**********************************************************************
NOT to be used outside this module except in debugging! Gets the value NOT to be used outside this module except in debugging! Gets the value
......
...@@ -10,18 +10,18 @@ Created 1/20/1994 Heikki Tuuri ...@@ -10,18 +10,18 @@ Created 1/20/1994 Heikki Tuuri
#define univ_i #define univ_i
#if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__) #if (defined(WIN32) || defined(_WIN32) || defined(WIN64) || defined(_WIN64)) && !defined(MYSQL_SERVER) && !defined(__WIN__)
#undef __WIN__ # undef __WIN__
#define __WIN__ # define __WIN__
#include <windows.h> # include <windows.h>
#if !defined(WIN64) && !defined(_WIN64) # if !defined(WIN64) && !defined(_WIN64)
#define UNIV_CAN_USE_X86_ASSEMBLER # define UNIV_CAN_USE_X86_ASSEMBLER
#endif # endif
#ifdef _NT_ # ifdef _NT_
#define __NT__ # define __NT__
#endif # endif
#else #else
/* The defines used with MySQL */ /* The defines used with MySQL */
...@@ -30,42 +30,33 @@ Created 1/20/1994 Heikki Tuuri ...@@ -30,42 +30,33 @@ Created 1/20/1994 Heikki Tuuri
in compiling more Posix-compatible. These headers also define __WIN__ in compiling more Posix-compatible. These headers also define __WIN__
if we are compiling on Windows. */ if we are compiling on Windows. */
#include <my_global.h> # include <my_global.h>
#include <my_pthread.h> # include <my_pthread.h>
/* Include <sys/stat.h> to get S_I... macros defined for os0file.c */ /* Include <sys/stat.h> to get S_I... macros defined for os0file.c */
#include <sys/stat.h> # include <sys/stat.h>
#undef PACKAGE # undef PACKAGE
#undef VERSION # undef VERSION
/* Include the header file generated by GNU autoconf */ /* Include the header file generated by GNU autoconf */
#ifndef __WIN__ # include "config.h"
#include "config.h"
#endif
#ifdef HAVE_SCHED_H
#include <sched.h>
#endif
/* When compiling for Itanium IA64, undefine the flag below to prevent use
of the 32-bit x86 assembler in mutex operations. */
#if defined(__WIN__) && !defined(WIN64) && !defined(_WIN64) # ifdef HAVE_SCHED_H
#define UNIV_CAN_USE_X86_ASSEMBLER # include <sched.h>
#endif # endif
/* We only try to do explicit inlining of functions with gcc and /* We only try to do explicit inlining of functions with gcc and
Microsoft Visual C++ */ Microsoft Visual C++ */
#if !defined(__GNUC__) && !defined(__WIN__) # if !defined(__GNUC__)
#undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */ # undef UNIV_MUST_NOT_INLINE /* Remove compiler warning */
#define UNIV_MUST_NOT_INLINE # define UNIV_MUST_NOT_INLINE
#endif # endif
#ifdef HAVE_PREAD # ifdef HAVE_PREAD
#define HAVE_PWRITE # define HAVE_PWRITE
#endif # endif
#endif /* #if (defined(WIN32) || ... */ #endif /* #if (defined(WIN32) || ... */
......
...@@ -221,7 +221,10 @@ ut_print_filename( ...@@ -221,7 +221,10 @@ ut_print_filename(
struct trx_struct; struct trx_struct;
/************************************************************************** /**************************************************************************
Outputs a NUL-terminated string, quoted as an SQL identifier. */ Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
as in SQL database_name.identifier. */
void void
ut_print_name( ut_print_name(
...@@ -233,7 +236,10 @@ ut_print_name( ...@@ -233,7 +236,10 @@ ut_print_name(
const char* name); /* in: name to print */ const char* name); /* in: name to print */
/************************************************************************** /**************************************************************************
Outputs a fixed-length string, quoted as an SQL identifier. */ Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
as in SQL database_name.identifier. */
void void
ut_print_namel( ut_print_namel(
......
...@@ -66,7 +66,6 @@ mem_hash_get_nth_cell(ulint i) ...@@ -66,7 +66,6 @@ mem_hash_get_nth_cell(ulint i)
return(&(mem_hash_table[i])); return(&(mem_hash_table[i]));
} }
#endif /* UNIV_MEM_DEBUG */
/* Accessor functions for a memory field in the debug version */ /* Accessor functions for a memory field in the debug version */
...@@ -106,6 +105,7 @@ mem_field_trailer_get_check(byte* field) ...@@ -106,6 +105,7 @@ mem_field_trailer_get_check(byte* field)
return(mach_read_from_4(field return(mach_read_from_4(field
+ mem_field_header_get_len(field))); + mem_field_header_get_len(field)));
} }
#endif /* UNIV_MEM_DEBUG */
/********************************************************************** /**********************************************************************
Initializes the memory system. */ Initializes the memory system. */
...@@ -136,6 +136,7 @@ mem_init( ...@@ -136,6 +136,7 @@ mem_init(
mem_comm_pool = mem_pool_create(size); mem_comm_pool = mem_pool_create(size);
} }
#ifdef UNIV_MEM_DEBUG
/********************************************************************** /**********************************************************************
Initializes an allocated memory field in the debug version. */ Initializes an allocated memory field in the debug version. */
...@@ -163,7 +164,6 @@ mem_field_init( ...@@ -163,7 +164,6 @@ mem_field_init(
mem_field_header_set_check(usr_buf, rnd); mem_field_header_set_check(usr_buf, rnd);
mem_field_trailer_set_check(usr_buf, rnd); mem_field_trailer_set_check(usr_buf, rnd);
#ifdef UNIV_MEM_DEBUG
/* Update the memory allocation information */ /* Update the memory allocation information */
mutex_enter(&mem_hash_mutex); mutex_enter(&mem_hash_mutex);
...@@ -182,7 +182,6 @@ mem_field_init( ...@@ -182,7 +182,6 @@ mem_field_init(
combination of 0xBA and 0xBE */ combination of 0xBA and 0xBE */
mem_init_buf(usr_buf, n); mem_init_buf(usr_buf, n);
#endif /* UNIV_MEM_DEBUG */
} }
/********************************************************************** /**********************************************************************
...@@ -199,7 +198,6 @@ mem_field_erase( ...@@ -199,7 +198,6 @@ mem_field_erase(
usr_buf = buf + MEM_FIELD_HEADER_SIZE; usr_buf = buf + MEM_FIELD_HEADER_SIZE;
#ifdef UNIV_MEM_DEBUG
mutex_enter(&mem_hash_mutex); mutex_enter(&mem_hash_mutex);
mem_current_allocated_memory -= n; mem_current_allocated_memory -= n;
mutex_exit(&mem_hash_mutex); mutex_exit(&mem_hash_mutex);
...@@ -211,10 +209,8 @@ mem_field_erase( ...@@ -211,10 +209,8 @@ mem_field_erase(
combination of 0xDE and 0xAD */ combination of 0xDE and 0xAD */
mem_erase_buf(buf, MEM_SPACE_NEEDED(n)); mem_erase_buf(buf, MEM_SPACE_NEEDED(n));
#endif /* UNIV_MEM_DEBUG */
} }
#ifdef UNIV_MEM_DEBUG
/******************************************************************* /*******************************************************************
Initializes a buffer to a random combination of hex BA and BE. Initializes a buffer to a random combination of hex BA and BE.
Used to initialize allocated memory. */ Used to initialize allocated memory. */
...@@ -376,6 +372,7 @@ mem_hash_remove( ...@@ -376,6 +372,7 @@ mem_hash_remove(
} }
#endif /* UNIV_MEM_DEBUG */ #endif /* UNIV_MEM_DEBUG */
#if defined UNIV_MEM_DEBUG || defined UNIV_DEBUG
/******************************************************************* /*******************************************************************
Checks a memory heap for consistency and prints the contents if requested. Checks a memory heap for consistency and prints the contents if requested.
Outputs the sum of sizes of buffers given to the user (only in Outputs the sum of sizes of buffers given to the user (only in
...@@ -549,10 +546,12 @@ mem_heap_validate_or_print( ...@@ -549,10 +546,12 @@ mem_heap_validate_or_print(
} }
*error = FALSE; *error = FALSE;
} }
#endif /* UNIV_MEM_DEBUG || UNIV_DEBUG */
#ifdef UNIV_DEBUG
/****************************************************************** /******************************************************************
Prints the contents of a memory heap. */ Prints the contents of a memory heap. */
static
void void
mem_heap_print( mem_heap_print(
/*===========*/ /*===========*/
...@@ -615,6 +614,7 @@ mem_heap_validate( ...@@ -615,6 +614,7 @@ mem_heap_validate(
return(TRUE); return(TRUE);
} }
#endif /* UNIV_DEBUG */
#ifdef UNIV_MEM_DEBUG #ifdef UNIV_MEM_DEBUG
/********************************************************************* /*********************************************************************
......
...@@ -35,7 +35,7 @@ The main components of the memory consumption are: ...@@ -35,7 +35,7 @@ The main components of the memory consumption are:
8. session for each user, and 8. session for each user, and
9. stack for each OS thread. 9. stack for each OS thread.
Items 1-3 are managed by an LRU algorithm. Items 5 and 6 can potentially Items 1 and 2 are managed by an LRU algorithm. Items 5 and 6 can potentially
consume very much memory. Items 7 and 8 should consume quite little memory, consume very much memory. Items 7 and 8 should consume quite little memory,
and the OS should take care of item 9, which too should consume little memory. and the OS should take care of item 9, which too should consume little memory.
...@@ -54,16 +54,15 @@ common pool and the buffers in the buffer pool into a single LRU list and ...@@ -54,16 +54,15 @@ common pool and the buffers in the buffer pool into a single LRU list and
manage it uniformly, but this approach does not take into account the parsing manage it uniformly, but this approach does not take into account the parsing
and other costs unique to SQL statements. and other costs unique to SQL statements.
So, let the SQL statements and the data dictionary entries form one single The locks for a transaction can be seen as a part of the state of the
LRU list, let us call it the dictionary LRU list. The locks for a transaction transaction. Hence, they should be stored in the common pool. We still
can be seen as a part of the state of the transaction. Hence, they should be have the problem of a very big update transaction, for example, which
stored in the common pool. We still have the problem of a very big update will set very many x-locks on rows, and the locks will consume a lot
transaction, for example, which will set very many x-locks on rows, and the of memory, say, half of the buffer pool size.
locks will consume a lot of memory, say, half of the buffer pool size.
Another problem is what to do if we are not able to malloc a requested Another problem is what to do if we are not able to malloc a requested
block of memory from the common pool. Then we can truncate the LRU list of block of memory from the common pool. Then we can request memory from
the dictionary cache. If it does not help, a system error results. the operating system. If it does not help, a system error results.
Because 5 and 6 may potentially consume very much memory, we let them grow Because 5 and 6 may potentially consume very much memory, we let them grow
into the buffer pool. We may let the locks of a transaction take frames into the buffer pool. We may let the locks of a transaction take frames
......
-- require r/have_innodb.require
disable_query_log; disable_query_log;
show variables like "have_innodb"; --require r/true.require
select support = 'Enabled' as `TRUE` from information_schema.engines where engine = 'innodb';
enable_query_log; enable_query_log;
DROP TABLE IF EXISTS t1, t2, t3, t4;
CREATE TABLE t1 (id INTEGER) ENGINE=MYISAM;
CREATE TABLE t2 (id INTEGER primary key) ENGINE=INNODB;
CREATE TABLE t3 (a char(32) primary key,id INTEGER) ENGINE=INNODB;
CREATE TABLE t4 (a char(32) primary key,id INTEGER) ENGINE=MYISAM;
INSERT INTO t1 (id) VALUES (1);
INSERT INTO t1 SELECT id+1 FROM t1;
INSERT INTO t1 SELECT id+2 FROM t1;
INSERT INTO t1 SELECT id+4 FROM t1;
INSERT INTO t1 SELECT id+8 FROM t1;
INSERT INTO t1 SELECT id+16 FROM t1;
INSERT INTO t1 SELECT id+32 FROM t1;
INSERT INTO t1 SELECT id+64 FROM t1;
INSERT INTO t1 SELECT id+128 FROM t1;
INSERT INTO t1 SELECT id+256 FROM t1;
INSERT INTO t1 SELECT id+512 FROM t1;
INSERT INTO t1 SELECT id+1024 FROM t1;
INSERT INTO t1 SELECT id+2048 FROM t1;
INSERT INTO t1 SELECT id+4096 FROM t1;
INSERT INTO t1 SELECT id+8192 FROM t1;
INSERT INTO t1 SELECT id+16384 FROM t1;
INSERT INTO t1 SELECT id+32768 FROM t1;
INSERT INTO t1 SELECT id+65536 FROM t1;
INSERT INTO t1 SELECT id+131072 FROM t1;
INSERT INTO t1 SELECT id+262144 FROM t1;
INSERT INTO t1 SELECT id+524288 FROM t1;
INSERT INTO t1 SELECT id+1048576 FROM t1;
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t3 SELECT concat(id),id from t2 ORDER BY -id;
INSERT INTO t4 SELECT * from t3 ORDER BY concat(a);
select sum(id) from t3;
sum(id)
2199024304128
drop table t1,t2,t3,t4;
#
# Test some things that takes a long time
-- source include/big_test.inc
-- source include/have_innodb.inc
--disable_warnings
DROP TABLE IF EXISTS t1, t2, t3, t4;
--enable_warnings
#
# Test test how filesort and buffered-record-reads works with innodb
#
CREATE TABLE t1 (id INTEGER) ENGINE=MYISAM;
CREATE TABLE t2 (id INTEGER primary key) ENGINE=INNODB;
CREATE TABLE t3 (a char(32) primary key,id INTEGER) ENGINE=INNODB;
CREATE TABLE t4 (a char(32) primary key,id INTEGER) ENGINE=MYISAM;
INSERT INTO t1 (id) VALUES (1);
INSERT INTO t1 SELECT id+1 FROM t1;
INSERT INTO t1 SELECT id+2 FROM t1;
INSERT INTO t1 SELECT id+4 FROM t1;
INSERT INTO t1 SELECT id+8 FROM t1;
INSERT INTO t1 SELECT id+16 FROM t1;
INSERT INTO t1 SELECT id+32 FROM t1;
INSERT INTO t1 SELECT id+64 FROM t1;
INSERT INTO t1 SELECT id+128 FROM t1;
INSERT INTO t1 SELECT id+256 FROM t1;
INSERT INTO t1 SELECT id+512 FROM t1;
INSERT INTO t1 SELECT id+1024 FROM t1;
INSERT INTO t1 SELECT id+2048 FROM t1;
INSERT INTO t1 SELECT id+4096 FROM t1;
INSERT INTO t1 SELECT id+8192 FROM t1;
INSERT INTO t1 SELECT id+16384 FROM t1;
INSERT INTO t1 SELECT id+32768 FROM t1;
INSERT INTO t1 SELECT id+65536 FROM t1;
INSERT INTO t1 SELECT id+131072 FROM t1;
INSERT INTO t1 SELECT id+262144 FROM t1;
INSERT INTO t1 SELECT id+524288 FROM t1;
INSERT INTO t1 SELECT id+1048576 FROM t1;
INSERT INTO t2 SELECT * FROM t1;
INSERT INTO t3 SELECT concat(id),id from t2 ORDER BY -id;
INSERT INTO t4 SELECT * from t3 ORDER BY concat(a);
select sum(id) from t3;
drop table t1,t2,t3,t4;
drop table if exists t1,t2;
create table t1 (id integer, x integer) engine=INNODB;
insert into t1 values(0, 0);
set autocommit=0;
SELECT * from t1 where id = 0 FOR UPDATE;
id x
0 0
set autocommit=0;
update t1 set x=2 where id = 0;
update t1 set x=1 where id = 0;
select * from t1;
id x
0 1
commit;
commit;
select * from t1;
id x
0 2
commit;
drop table t1;
create table t1 (id integer, x integer) engine=INNODB;
create table t2 (b integer, a integer) engine=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 10), (1, 20), (2, 30);
commit;
set autocommit=0;
select * from t2;
b a
0 10
1 20
2 30
update t2 set a=100 where b=(SELECT x from t1 where id = b FOR UPDATE);
select * from t2;
b a
0 100
1 20
2 30
select * from t1;
id x
0 0
300 300
set autocommit=0;
update t1 set x=2 where id = 0;
update t1 set x=1 where id = 0;
select * from t1;
id x
0 1
300 300
commit;
commit;
select * from t1;
id x
0 2
300 300
commit;
drop table t1, t2;
create table t1 (id integer, x integer) engine=INNODB;
create table t2 (b integer, a integer) engine=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 0), (1, 20), (2, 30);
commit;
select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
a b
0 0
20 1
30 2
300 300
select * from t2;
b a
0 0
1 20
2 30
select * from t1;
id x
0 0
300 300
update t2 set a=2 where b = 0;
select * from t2;
b a
0 2
1 20
2 30
update t1 set x=2 where id = 0;
update t1 set x=1 where id = 0;
select * from t1;
id x
0 1
300 300
commit;
commit;
select * from t1;
id x
0 2
300 300
commit;
drop table t1, t2;
-- source include/have_innodb.inc
# Can't test this with embedded server
-- source include/not_embedded.inc
connect (con1,localhost,root,,);
connect (con2,localhost,root,,);
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
#
# Testing of FOR UPDATE
#
connection con1;
create table t1 (id integer, x integer) engine=INNODB;
insert into t1 values(0, 0);
set autocommit=0;
SELECT * from t1 where id = 0 FOR UPDATE;
connection con2;
set autocommit=0;
# The following query should hang because con1 is locking the page
--send
update t1 set x=2 where id = 0;
--sleep 2
connection con1;
update t1 set x=1 where id = 0;
select * from t1;
commit;
connection con2;
reap;
commit;
connection con1;
select * from t1;
commit;
drop table t1;
#
# Testing of FOR UPDATE
#
connection con1;
create table t1 (id integer, x integer) engine=INNODB;
create table t2 (b integer, a integer) engine=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 10), (1, 20), (2, 30);
commit;
set autocommit=0;
select * from t2;
update t2 set a=100 where b=(SELECT x from t1 where id = b FOR UPDATE);
select * from t2;
select * from t1;
connection con2;
set autocommit=0;
# The following query should hang because con1 is locking the page
--send
update t1 set x=2 where id = 0;
--sleep 2
connection con1;
update t1 set x=1 where id = 0;
select * from t1;
commit;
connection con2;
reap;
commit;
connection con1;
select * from t1;
commit;
drop table t1, t2;
create table t1 (id integer, x integer) engine=INNODB;
create table t2 (b integer, a integer) engine=INNODB;
insert into t1 values(0, 0), (300, 300);
insert into t2 values(0, 0), (1, 20), (2, 30);
commit;
connection con1;
select a,b from t2 UNION SELECT id, x from t1 FOR UPDATE;
select * from t2;
select * from t1;
connection con2;
# The following query should hang because con1 is locking the page
update t2 set a=2 where b = 0;
select * from t2;
--send
update t1 set x=2 where id = 0;
--sleep 2
connection con1;
update t1 set x=1 where id = 0;
select * from t1;
commit;
connection con2;
reap;
commit;
connection con1;
select * from t1;
commit;
drop table t1, t2;
# End of 4.1 tests
--set-variable=query_cache_size=1M
drop table if exists t1,t2,t3;
flush status;
set autocommit=0;
create table t1 (a int not null) engine=innodb;
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 0
drop table t1;
commit;
set autocommit=1;
begin;
create table t1 (a int not null) engine=innodb;
insert into t1 values (1),(2),(3);
select * from t1;
a
1
2
3
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
drop table t1;
commit;
create table t1 (a int not null) engine=innodb;
create table t2 (a int not null) engine=innodb;
create table t3 (a int not null) engine=innodb;
insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1),(2);
select * from t1;
a
1
2
select * from t2;
a
1
2
select * from t3;
a
1
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 0
begin;
select * from t1;
a
1
2
select * from t2;
a
1
2
select * from t3;
a
1
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 3
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 3
insert into t1 values (3);
insert into t2 values (3);
insert into t1 values (4);
select * from t1;
a
1
2
3
4
select * from t2;
a
1
2
3
select * from t3;
a
1
2
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
show status like "Qcache_hits";
Variable_name Value
Qcache_hits 4
commit;
show status like "Qcache_queries_in_cache";
Variable_name Value
Qcache_queries_in_cache 1
drop table t3,t2,t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=InnoDB;
select count(*) from t1;
count(*)
0
insert into t1 (id) values (0);
select count(*) from t1;
count(*)
1
drop table t1;
set GLOBAL query_cache_size=1355776;
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a)) ENGINE=innodb;
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b)) ENGINE=innodb;
CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`)) ENGINE=innodb;
INSERT INTO t1 VALUES (1,'me');
INSERT INTO t2 VALUES (1,'you');
INSERT INTO t3 VALUES (2,1,1,2);
delete from t3 where t1_id = 1 and t2_id = 1;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
id a
begin;
insert into t3 VALUES ( NULL, 1, 1, 2 );
insert into t3 VALUES ( NULL, 1, 1, 2 );
ERROR 23000: Duplicate entry '1-1' for key 't1_id'
commit;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
id a
1 me
drop table t3,t2,t1;
-- source include/have_innodb.inc
-- source include/have_query_cache.inc
# Initialise
--disable_warnings
drop table if exists t1,t2,t3;
--enable_warnings
#
# Without auto_commit.
#
flush status;
set autocommit=0;
create table t1 (a int not null) engine=innodb;
insert into t1 values (1),(2),(3);
select * from t1;
show status like "Qcache_queries_in_cache";
drop table t1;
commit;
set autocommit=1;
begin;
create table t1 (a int not null) engine=innodb;
insert into t1 values (1),(2),(3);
select * from t1;
show status like "Qcache_queries_in_cache";
drop table t1;
commit;
create table t1 (a int not null) engine=innodb;
create table t2 (a int not null) engine=innodb;
create table t3 (a int not null) engine=innodb;
insert into t1 values (1),(2);
insert into t2 values (1),(2);
insert into t3 values (1),(2);
select * from t1;
select * from t2;
select * from t3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
begin;
select * from t1;
select * from t2;
select * from t3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
insert into t1 values (3);
insert into t2 values (3);
insert into t1 values (4);
select * from t1;
select * from t2;
select * from t3;
show status like "Qcache_queries_in_cache";
show status like "Qcache_hits";
commit;
show status like "Qcache_queries_in_cache";
drop table t3,t2,t1;
CREATE TABLE t1 (id int(11) NOT NULL auto_increment, PRIMARY KEY (id)) ENGINE=InnoDB;
select count(*) from t1;
insert into t1 (id) values (0);
select count(*) from t1;
drop table t1;
#
# one statement roll back inside transation
#
let $save_query_cache_size=`select @@global.query_cache_size`;
set GLOBAL query_cache_size=1355776;
CREATE TABLE t1 ( id int(10) NOT NULL auto_increment, a varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY a (a)) ENGINE=innodb;
CREATE TABLE t2 ( id int(10) NOT NULL auto_increment, b varchar(25) default NULL, PRIMARY KEY (id), UNIQUE KEY b (b)) ENGINE=innodb;
CREATE TABLE t3 ( id int(10) NOT NULL auto_increment, t1_id int(10) NOT NULL default '0', t2_id int(10) NOT NULL default '0', state int(11) default NULL, PRIMARY KEY (id), UNIQUE KEY t1_id (t1_id,t2_id), KEY t2_id (t2_id,t1_id), CONSTRAINT `t3_ibfk_1` FOREIGN KEY (`t1_id`) REFERENCES `t1` (`id`), CONSTRAINT `t3_ibfk_2` FOREIGN KEY (`t2_id`) REFERENCES `t2` (`id`)) ENGINE=innodb;
INSERT INTO t1 VALUES (1,'me');
INSERT INTO t2 VALUES (1,'you');
INSERT INTO t3 VALUES (2,1,1,2);
delete from t3 where t1_id = 1 and t2_id = 1;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
begin;
insert into t3 VALUES ( NULL, 1, 1, 2 );
-- error 1062
insert into t3 VALUES ( NULL, 1, 1, 2 );
commit;
select t1.* from t1, t2, t3 where t3.state & 1 = 0 and t3.t1_id = t1.id and t3.t2_id = t2.id and t1.id = 1 order by t1.a asc;
drop table t3,t2,t1;
--disable_query_log
eval set GLOBAL query_cache_size=$save_query_cache_size;
--enable_query_log
# End of 4.1 tests
drop table if exists t1,t2;
create table t1 (a int, b char(10), key a(a), key b(a,b)) engine=innodb;
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
(20,"ggg"),(21,"hhh"),(22,"iii");
handler t1 open as t2;
handler t2 read a first;
a b
14 aaa
handler t2 read a next;
a b
15 bbb
handler t2 read a next;
a b
16 ccc
handler t2 read a prev;
a b
15 bbb
handler t2 read a last;
a b
22 iii
handler t2 read a prev;
a b
21 hhh
handler t2 read a prev;
a b
20 ggg
handler t2 read a first;
a b
14 aaa
handler t2 read a prev;
a b
handler t2 read a last;
a b
22 iii
handler t2 read a prev;
a b
21 hhh
handler t2 read a next;
a b
22 iii
handler t2 read a next;
a b
handler t2 read a=(15);
a b
15 bbb
handler t2 read a=(16);
a b
16 ccc
handler t2 read a=(19,"fff");
ERROR 42000: Too many key parts specified; max 1 parts allowed
handler t2 read b=(19,"fff");
a b
19 fff
handler t2 read b=(19,"yyy");
a b
19 yyy
handler t2 read b=(19);
a b
19 fff
handler t1 read a last;
ERROR 42S02: Unknown table 't1' in HANDLER
handler t2 read a=(11);
a b
handler t2 read a>=(11);
a b
14 aaa
handler t2 read a=(18);
a b
18 eee
handler t2 read a>=(18);
a b
18 eee
handler t2 read a>(18);
a b
19 fff
handler t2 read a<=(18);
a b
18 eee
handler t2 read a<(18);
a b
17 ddd
handler t2 read a first limit 5;
a b
14 aaa
15 bbb
16 ccc
16 xxx
17 ddd
handler t2 read a next limit 3;
a b
18 eee
19 fff
19 yyy
handler t2 read a prev limit 10;
a b
19 fff
18 eee
17 ddd
16 xxx
16 ccc
15 bbb
14 aaa
handler t2 read a>=(16) limit 4;
a b
16 ccc
16 xxx
17 ddd
18 eee
handler t2 read a>=(16) limit 2,2;
a b
17 ddd
18 eee
handler t2 read a last limit 3;
a b
22 iii
21 hhh
20 ggg
handler t2 read a=(19);
a b
19 fff
handler t2 read a=(19) where b="yyy";
a b
19 yyy
handler t2 read first;
a b
17 ddd
handler t2 read next;
a b
18 eee
handler t2 read last;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
handler t2 close;
handler t1 open;
handler t1 read a next;
a b
14 aaa
handler t1 read a next;
a b
15 bbb
handler t1 close;
handler t1 open;
handler t1 read a prev;
a b
22 iii
handler t1 read a prev;
a b
21 hhh
handler t1 close;
handler t1 open as t2;
handler t2 read first;
a b
17 ddd
alter table t1 engine=innodb;
handler t2 read first;
ERROR 42S02: Unknown table 't2' in HANDLER
drop table t1;
CREATE TABLE t1 ( no1 smallint(5) NOT NULL default '0', no2 int(10) NOT NULL default '0', PRIMARY KEY (no1,no2)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,274),(1,275),(2,6),(2,8),(4,1),(4,2);
HANDLER t1 OPEN;
HANDLER t1 READ `primary` = (1, 1000);
no1 no2
HANDLER t1 READ `primary` PREV;
no1 no2
1 275
DROP TABLE t1;
-- source include/have_innodb.inc
#
# test of HANDLER ...
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (a int, b char(10), key a(a), key b(a,b)) engine=innodb;
insert into t1 values
(17,"ddd"),(18,"eee"),(19,"fff"),(19,"yyy"),
(14,"aaa"),(15,"bbb"),(16,"ccc"),(16,"xxx"),
(20,"ggg"),(21,"hhh"),(22,"iii");
handler t1 open as t2;
handler t2 read a first;
handler t2 read a next;
handler t2 read a next;
handler t2 read a prev;
handler t2 read a last;
handler t2 read a prev;
handler t2 read a prev;
handler t2 read a first;
handler t2 read a prev;
handler t2 read a last;
handler t2 read a prev;
handler t2 read a next;
handler t2 read a next;
handler t2 read a=(15);
handler t2 read a=(16);
--error 1070
handler t2 read a=(19,"fff");
handler t2 read b=(19,"fff");
handler t2 read b=(19,"yyy");
handler t2 read b=(19);
--error 1109
handler t1 read a last;
handler t2 read a=(11);
handler t2 read a>=(11);
handler t2 read a=(18);
handler t2 read a>=(18);
handler t2 read a>(18);
handler t2 read a<=(18);
handler t2 read a<(18);
handler t2 read a first limit 5;
handler t2 read a next limit 3;
handler t2 read a prev limit 10;
handler t2 read a>=(16) limit 4;
handler t2 read a>=(16) limit 2,2;
handler t2 read a last limit 3;
handler t2 read a=(19);
handler t2 read a=(19) where b="yyy";
handler t2 read first;
handler t2 read next;
--error 1064
handler t2 read last;
handler t2 close;
handler t1 open;
handler t1 read a next; # this used to crash as a bug#5373
handler t1 read a next;
handler t1 close;
handler t1 open;
handler t1 read a prev; # this used to crash as a bug#5373
handler t1 read a prev;
handler t1 close;
handler t1 open as t2;
handler t2 read first;
alter table t1 engine=innodb;
--error 1109
handler t2 read first;
drop table t1;
CREATE TABLE t1 ( no1 smallint(5) NOT NULL default '0', no2 int(10) NOT NULL default '0', PRIMARY KEY (no1,no2)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,274),(1,275),(2,6),(2,8),(4,1),(4,2);
HANDLER t1 OPEN;
HANDLER t1 READ `primary` = (1, 1000);
HANDLER t1 READ `primary` PREV;
DROP TABLE t1;
# End of 4.1 tests
SET SESSION STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4; drop table if exists t1,t2,t1m,t1i,t2m,t2i,t4;
create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb create table t1(f1 varchar(800) binary not null, key(f1))
character set utf8 collate utf8_general_ci; character set utf8 collate utf8_general_ci;
Warnings: Warnings:
Warning 1071 Specified key was too long; max key length is 765 bytes Warning 1071 Specified key was too long; max key length is 765 bytes
...@@ -10,8 +11,8 @@ c_id int(11) not null default '0', ...@@ -10,8 +11,8 @@ c_id int(11) not null default '0',
org_id int(11) default null, org_id int(11) default null,
unique key contacts$c_id (c_id), unique key contacts$c_id (c_id),
key contacts$org_id (org_id) key contacts$org_id (org_id)
) engine=innodb; );
insert into t1 values insert into t1 values
(2,null),(120,null),(141,null),(218,7), (128,1), (2,null),(120,null),(141,null),(218,7), (128,1),
(151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3), (151,2),(234,2),(236,2),(243,2),(255,2),(259,2),(232,3),(235,3),(238,3),
(246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4); (246,3),(253,3),(269,3),(285,3),(291,3),(293,3),(131,4),(230,4),(231,4);
...@@ -33,16 +34,16 @@ sla_set int(11) default null, ...@@ -33,16 +34,16 @@ sla_set int(11) default null,
unique key t2$slai_id (slai_id), unique key t2$slai_id (slai_id),
key t2$owner_id (owner_id), key t2$owner_id (owner_id),
key t2$sla_id (sla_id) key t2$sla_id (sla_id)
) engine=innodb; );
insert into t2(slai_id, owner_tbl, owner_id, sla_id) values insert into t2(slai_id, owner_tbl, owner_id, sla_id) values
(1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7), (1,3,1,1), (3,3,10,2), (4,3,3,6), (5,3,2,5), (6,3,8,3), (7,3,9,7),
(8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12); (8,3,6,8), (9,3,4,9), (10,3,5,10), (11,3,11,11), (12,3,7,12);
flush tables; flush tables;
select si.slai_id select si.slai_id
from t1 c join t2 si on from t1 c join t2 si on
((si.owner_tbl = 3 and si.owner_id = c.org_id) or ((si.owner_tbl = 3 and si.owner_id = c.org_id) or
( si.owner_tbl = 2 and si.owner_id = c.c_id)) ( si.owner_tbl = 2 and si.owner_id = c.c_id))
where where
c.c_id = 218 and expiredate is null; c.c_id = 218 and expiredate is null;
slai_id slai_id
12 12
...@@ -53,17 +54,17 @@ c_id org_id ...@@ -53,17 +54,17 @@ c_id org_id
141 NULL 141 NULL
select si.slai_id select si.slai_id
from t1 c join t2 si on from t1 c join t2 si on
((si.owner_tbl = 3 and si.owner_id = c.org_id) or ((si.owner_tbl = 3 and si.owner_id = c.org_id) or
( si.owner_tbl = 2 and si.owner_id = c.c_id)) ( si.owner_tbl = 2 and si.owner_id = c.c_id))
where where
c.c_id = 218 and expiredate is null; c.c_id = 218 and expiredate is null;
slai_id slai_id
12 12
drop table t1, t2; drop table t1, t2;
CREATE TABLE t1 (a int, b int, KEY b (b)) Engine=InnoDB; CREATE TABLE t1 (a int, b int, KEY b (b));
CREATE TABLE t2 (a int, b int, PRIMARY KEY (a,b)) Engine=InnoDB; CREATE TABLE t2 (a int, b int, PRIMARY KEY (a,b));
CREATE TABLE t3 (a int, b int, c int, PRIMARY KEY (a), CREATE TABLE t3 (a int, b int, c int, PRIMARY KEY (a),
UNIQUE KEY b (b,c), KEY a (a,b,c)) Engine=InnoDB; UNIQUE KEY b (b,c), KEY a (a,b,c));
INSERT INTO t1 VALUES (1, 1); INSERT INTO t1 VALUES (1, 1);
INSERT INTO t1 SELECT a + 1, b + 1 FROM t1; INSERT INTO t1 SELECT a + 1, b + 1 FROM t1;
INSERT INTO t1 SELECT a + 2, b + 2 FROM t1; INSERT INTO t1 SELECT a + 2, b + 2 FROM t1;
...@@ -73,14 +74,14 @@ DELETE FROM t2 WHERE a = 1 AND b < 2; ...@@ -73,14 +74,14 @@ DELETE FROM t2 WHERE a = 1 AND b < 2;
INSERT INTO t3 VALUES (1,1,1),(2,1,2); INSERT INTO t3 VALUES (1,1,1),(2,1,2);
INSERT INTO t3 SELECT a + 2, a + 2, 3 FROM t3; INSERT INTO t3 SELECT a + 2, a + 2, 3 FROM t3;
INSERT INTO t3 SELECT a + 4, a + 4, 3 FROM t3; INSERT INTO t3 SELECT a + 4, a + 4, 3 FROM t3;
SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE
t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2) t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2)
ORDER BY t1.b LIMIT 2; ORDER BY t1.b LIMIT 2;
b a b a
1 1 1 1
2 2 2 2
SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE SELECT STRAIGHT_JOIN SQL_NO_CACHE t1.b, t1.a FROM t1, t3, t2 WHERE
t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2) t3.a = t2.a AND t2.b = t1.a AND t3.b = 1 AND t3.c IN (1, 2)
ORDER BY t1.b LIMIT 5; ORDER BY t1.b LIMIT 5;
b a b a
1 1 1 1
...@@ -98,8 +99,8 @@ CREATE TABLE `t2` ( ...@@ -98,8 +99,8 @@ CREATE TABLE `t2` (
`id4` INT NOT NULL, `id4` INT NOT NULL,
UNIQUE (`id2`,`id4`), UNIQUE (`id2`,`id4`),
KEY (`id1`) KEY (`id1`)
) ENGINE=InnoDB; );
INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES INSERT INTO `t2`(`id1`,`id2`,`id3`,`id4`) VALUES
(1,1,1,0), (1,1,1,0),
(1,1,2,1), (1,1,2,1),
(5,1,2,2), (5,1,2,2),
...@@ -110,66 +111,12 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` = ...@@ -110,66 +111,12 @@ SELECT `id1` FROM `t1` WHERE `id1` NOT IN (SELECT `id1` FROM `t2` WHERE `id2` =
id1 id1
2 2
DROP TABLE t1, t2; DROP TABLE t1, t2;
create table t1m (a int) engine=myisam; create table t1m (a int) engine = MEMORY;
create table t1i (a int) engine=innodb; create table t1i (a int);
create table t2m (a int) engine=myisam; create table t2m (a int) engine = MEMORY;
create table t2i (a int) engine=innodb; create table t2i (a int);
insert into t2m values (5); insert into t2m values (5);
insert into t2i values (5); insert into t2i values (5);
select min(a) from t1m;
min(a)
NULL
select min(7) from t1m;
min(7)
NULL
select min(7) from DUAL;
min(7)
7
explain select min(7) from t2m join t1m;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
select min(7) from t2m join t1m;
min(7)
NULL
select max(a) from t1m;
max(a)
NULL
select max(7) from t1m;
max(7)
NULL
select max(7) from DUAL;
max(7)
7
explain select max(7) from t2m join t1m;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
select max(7) from t2m join t1m;
max(7)
NULL
select 1, min(a) from t1m where a=99;
1 min(a)
1 NULL
select 1, min(a) from t1m where 1=99;
1 min(a)
1 NULL
select 1, min(1) from t1m where a=99;
1 min(1)
1 NULL
select 1, min(1) from t1m where 1=99;
1 min(1)
1 NULL
select 1, max(a) from t1m where a=99;
1 max(a)
1 NULL
select 1, max(a) from t1m where 1=99;
1 max(a)
1 NULL
select 1, max(1) from t1m where a=99;
1 max(1)
1 NULL
select 1, max(1) from t1m where 1=99;
1 max(1)
1 NULL
select min(a) from t1i; select min(a) from t1i;
min(a) min(a)
NULL NULL
...@@ -250,7 +197,7 @@ count(*) min(7) max(7) ...@@ -250,7 +197,7 @@ count(*) min(7) max(7)
drop table t1m, t1i, t2m, t2i; drop table t1m, t1i, t2m, t2i;
create table t1 ( create table t1 (
a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' ' a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
); ) ENGINE = MEMORY;
insert into t1 (a1, a2, b, c, d) values insert into t1 (a1, a2, b, c, d) values
('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'), ('a','a','a','a111','xy1'),('a','a','a','b111','xy2'),('a','a','a','c111','xy3'),('a','a','a','d111','xy4'),
('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'), ('a','a','b','e112','xy1'),('a','a','b','f112','xy2'),('a','a','b','g112','xy3'),('a','a','b','h112','xy4'),
...@@ -286,14 +233,14 @@ insert into t1 (a1, a2, b, c, d) values ...@@ -286,14 +233,14 @@ insert into t1 (a1, a2, b, c, d) values
('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4'); ('d','b','b','m422','xy1'),('d','b','b','n422','xy2'),('d','b','b','o422','xy3'),('d','b','b','p422','xy4');
create table t4 ( create table t4 (
pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' ' pk_col int auto_increment primary key, a1 char(64), a2 char(64), b char(16), c char(16) not null, d char(16), dummy char(64) default ' '
) engine=innodb; );
insert into t4 (a1, a2, b, c, d, dummy) select * from t1; insert into t4 (a1, a2, b, c, d, dummy) select * from t1;
create index idx12672_0 on t4 (a1); create index idx12672_0 on t4 (a1);
create index idx12672_1 on t4 (a1,a2,b,c); create index idx12672_1 on t4 (a1,a2,b,c);
create index idx12672_2 on t4 (a1,a2,b); create index idx12672_2 on t4 (a1,a2,b);
analyze table t1; analyze table t4;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 analyze status OK test.t4 analyze status OK
select distinct a1 from t4 where pk_col not in (1,2,3,4); select distinct a1 from t4 where pk_col not in (1,2,3,4);
a1 a1
a a
...@@ -303,18 +250,18 @@ d ...@@ -303,18 +250,18 @@ d
drop table t1,t4; drop table t1,t4;
create table t1 ( create table t1 (
a varchar(30), b varchar(30), primary key(a), key(b) a varchar(30), b varchar(30), primary key(a), key(b)
) engine=innodb; );
select distinct a from t1; select distinct a from t1;
a a
drop table t1; drop table t1;
create table t1(a int, key(a)) engine=innodb; create table t1(a int, key(a));
insert into t1 values(1); insert into t1 values(1);
select a, count(a) from t1 group by a with rollup; select a, count(a) from t1 group by a with rollup;
a count(a) a count(a)
1 1 1 1
NULL 1 NULL 1
drop table t1; drop table t1;
create table t1 (f1 int, f2 char(1), primary key(f1,f2)) engine=innodb; create table t1 (f1 int, f2 char(1), primary key(f1,f2));
insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d"); insert into t1 values ( 1,"e"),(2,"a"),( 3,"c"),(4,"d");
alter table t1 drop primary key, add primary key (f2, f1); alter table t1 drop primary key, add primary key (f2, f1);
explain select distinct f1 a, f1 b from t1; explain select distinct f1 a, f1 b from t1;
...@@ -325,25 +272,24 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -325,25 +272,24 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary 1 SIMPLE t1 range NULL PRIMARY 5 NULL 3 Using index for group-by; Using temporary
drop table t1; drop table t1;
CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20), CREATE TABLE t1 (id int(11) NOT NULL PRIMARY KEY, name varchar(20),
INDEX (name)) ENGINE=InnoDB; INDEX (name));
CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11), CREATE TABLE t2 (id int(11) NOT NULL PRIMARY KEY, fkey int(11));
FOREIGN KEY (fkey) REFERENCES t2(id)) ENGINE=InnoDB; ALTER TABLE t2 ADD FOREIGN KEY (fkey) REFERENCES t2(id);
INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B');
INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3);
EXPLAIN EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%'; WHERE t1.name LIKE 'A%';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index 1 SIMPLE t1 index PRIMARY,name name 23 NULL 3 Using where; Using index
1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index 1 SIMPLE t2 ref fkey fkey 5 test.t1.id 1 Using where; Using index
EXPLAIN EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%' OR FALSE; WHERE t1.name LIKE 'A%' OR FALSE;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index 1 SIMPLE t2 index NULL fkey 5 NULL 5 Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 4 test.t2.fkey 1 Using where
DROP TABLE t1,t2; DROP TABLE t1,t2;
set storage_engine=innodb;
CREATE TABLE t1 (a int, b int); CREATE TABLE t1 (a int, b int);
insert into t1 values (1,1),(1,2); insert into t1 values (1,1),(1,2);
CREATE TABLE t2 (primary key (a)) select * from t1; CREATE TABLE t2 (primary key (a)) select * from t1;
...@@ -401,7 +347,7 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' ...@@ -401,7 +347,7 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY'
SELECT * from t2; SELECT * from t2;
a b a b
drop table t1,t2; drop table t1,t2;
create table t1(f1 varchar(800) binary not null, key(f1)) engine = innodb create table t1(f1 varchar(800) binary not null, key(f1))
character set utf8 collate utf8_general_ci; character set utf8 collate utf8_general_ci;
Warnings: Warnings:
Warning 1071 Specified key was too long; max key length is 765 bytes Warning 1071 Specified key was too long; max key length is 765 bytes
...@@ -413,7 +359,7 @@ CREATE TABLE `t2` ( ...@@ -413,7 +359,7 @@ CREATE TABLE `t2` (
`c` int(11) default NULL, `c` int(11) default NULL,
PRIMARY KEY (`k`), PRIMARY KEY (`k`),
UNIQUE KEY `idx_1` (`a`) UNIQUE KEY `idx_1` (`a`)
) ENGINE=InnoDB; );
insert into t2 ( a ) values ( 6 ) on duplicate key update c = insert into t2 ( a ) values ( 6 ) on duplicate key update c =
ifnull( c, ifnull( c,
0 ) + 1; 0 ) + 1;
......
This diff is collapsed.
--innodb_locks_unsafe_for_binlog=true --innodb_lock_wait_timeout=1
drop table if exists t1,t2;
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
id f_id f
drop table t1,t2;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
a b
1 1
2 2
3 1
4 2
5 1
6 2
7 3
update t1 set b = 5 where b = 1;
set autocommit = 0;
select * from t1 where a = 2 and b = 2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
commit;
drop table t1;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
commit;
set autocommit = 0;
update t1 set b = 5 where b = 1;
set autocommit = 0;
select * from t1 where a = 7 and b = 3 for update;
a b
7 3
commit;
commit;
drop table t1;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values (1,2),(5,3),(4,2);
create table t2(d int not null, e int, primary key(d)) engine=innodb;
insert into t2 values (8,6),(12,1),(3,1);
commit;
set autocommit = 0;
select * from t2 for update;
d e
3 1
8 6
12 1
set autocommit = 0;
insert into t1 select * from t2;
update t1 set b = (select e from t2 where a = d);
create table t3(d int not null, e int, primary key(d)) engine=innodb
select * from t2;
commit;
commit;
drop table t1, t2, t3;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values (1,2),(5,3),(4,2);
create table t2(a int not null, b int, primary key(a)) engine=innodb;
insert into t2 values (8,6),(12,1),(3,1);
create table t3(d int not null, b int, primary key(d)) engine=innodb;
insert into t3 values (8,6),(12,1),(3,1);
create table t5(a int not null, b int, primary key(a)) engine=innodb;
insert into t5 values (1,2),(5,3),(4,2);
create table t6(d int not null, e int, primary key(d)) engine=innodb;
insert into t6 values (8,6),(12,1),(3,1);
create table t8(a int not null, b int, primary key(a)) engine=innodb;
insert into t8 values (1,2),(5,3),(4,2);
create table t9(d int not null, e int, primary key(d)) engine=innodb;
insert into t9 values (8,6),(12,1),(3,1);
commit;
set autocommit = 0;
select * from t2 for update;
a b
3 1
8 6
12 1
set autocommit = 0;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
insert into t1 select * from t2;
set autocommit = 0;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
update t3 set b = (select b from t2 where a = d);
set autocommit = 0;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
set autocommit = 0;
insert into t5 (select * from t2 lock in share mode);
set autocommit = 0;
update t6 set e = (select b from t2 where a = d lock in share mode);
set autocommit = 0;
create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
set autocommit = 0;
insert into t8 (select * from t2 for update);
set autocommit = 0;
update t9 set e = (select b from t2 where a = d for update);
set autocommit = 0;
create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
commit;
drop table t1, t2, t3, t5, t6, t8, t9;
-- source include/have_innodb.inc
#
# Note that these tests uses options
# innodb_locks_unsafe_for_binlog = true
# innodb_lock_timeout = 5
#
# Test cases for a bug #15650
#
--disable_warnings
drop table if exists t1,t2;
--enable_warnings
create table t1 (id int not null, f_id int not null, f int not null,
primary key(f_id, id)) engine=innodb;
create table t2 (id int not null,s_id int not null,s varchar(200),
primary key(id)) engine=innodb;
INSERT INTO t1 VALUES (8, 1, 3);
INSERT INTO t1 VALUES (1, 2, 1);
INSERT INTO t2 VALUES (1, 0, '');
INSERT INTO t2 VALUES (8, 1, '');
commit;
DELETE ml.* FROM t1 AS ml LEFT JOIN t2 AS mm ON (mm.id=ml.id)
WHERE mm.id IS NULL;
select ml.* from t1 as ml left join t2 as mm on (mm.id=ml.id)
where mm.id is null lock in share mode;
drop table t1,t2;
#
# Test case for unlock row bug where unlock releases all locks granted for
# a row. Only the latest lock should be released.
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
commit;
set autocommit = 0;
select * from t1 lock in share mode;
update t1 set b = 5 where b = 1;
connection b;
set autocommit = 0;
#
# S-lock to records (2,2),(4,2), and (6,2) should not be released in a update
#
--error 1205
select * from t1 where a = 2 and b = 2 for update;
connection a;
commit;
connection b;
commit;
drop table t1;
connection default;
disconnect a;
disconnect b;
#
# unlock row test
#
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values(1,1),(2,2),(3,1),(4,2),(5,1),(6,2),(7,3);
commit;
set autocommit = 0;
update t1 set b = 5 where b = 1;
connection b;
set autocommit = 0;
#
# X-lock to record (7,3) should be released in a update
#
select * from t1 where a = 7 and b = 3 for update;
commit;
connection a;
commit;
drop table t1;
connection default;
disconnect a;
disconnect b;
#
# Consistent read should be used in following selects
#
# 1) INSERT INTO ... SELECT
# 2) UPDATE ... = ( SELECT ...)
# 3) CREATE ... SELECT
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values (1,2),(5,3),(4,2);
create table t2(d int not null, e int, primary key(d)) engine=innodb;
insert into t2 values (8,6),(12,1),(3,1);
commit;
set autocommit = 0;
select * from t2 for update;
connection b;
set autocommit = 0;
insert into t1 select * from t2;
update t1 set b = (select e from t2 where a = d);
create table t3(d int not null, e int, primary key(d)) engine=innodb
select * from t2;
commit;
connection a;
commit;
connection default;
disconnect a;
disconnect b;
drop table t1, t2, t3;
#
# Consistent read should not be used if
#
# (a) isolation level is serializable OR
# (b) select ... lock in share mode OR
# (c) select ... for update
#
# in following queries:
#
# 1) INSERT INTO ... SELECT
# 2) UPDATE ... = ( SELECT ...)
# 3) CREATE ... SELECT
connect (a,localhost,root,,);
connect (b,localhost,root,,);
connect (c,localhost,root,,);
connect (d,localhost,root,,);
connect (e,localhost,root,,);
connect (f,localhost,root,,);
connect (g,localhost,root,,);
connect (h,localhost,root,,);
connect (i,localhost,root,,);
connect (j,localhost,root,,);
connection a;
create table t1(a int not null, b int, primary key(a)) engine=innodb;
insert into t1 values (1,2),(5,3),(4,2);
create table t2(a int not null, b int, primary key(a)) engine=innodb;
insert into t2 values (8,6),(12,1),(3,1);
create table t3(d int not null, b int, primary key(d)) engine=innodb;
insert into t3 values (8,6),(12,1),(3,1);
create table t5(a int not null, b int, primary key(a)) engine=innodb;
insert into t5 values (1,2),(5,3),(4,2);
create table t6(d int not null, e int, primary key(d)) engine=innodb;
insert into t6 values (8,6),(12,1),(3,1);
create table t8(a int not null, b int, primary key(a)) engine=innodb;
insert into t8 values (1,2),(5,3),(4,2);
create table t9(d int not null, e int, primary key(d)) engine=innodb;
insert into t9 values (8,6),(12,1),(3,1);
commit;
set autocommit = 0;
select * from t2 for update;
connection b;
set autocommit = 0;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
--send
insert into t1 select * from t2;
connection c;
set autocommit = 0;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
--send
update t3 set b = (select b from t2 where a = d);
connection d;
set autocommit = 0;
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;
--send
create table t4(a int not null, b int, primary key(a)) engine=innodb select * from t2;
connection e;
set autocommit = 0;
--send
insert into t5 (select * from t2 lock in share mode);
connection f;
set autocommit = 0;
--send
update t6 set e = (select b from t2 where a = d lock in share mode);
connection g;
set autocommit = 0;
--send
create table t7(a int not null, b int, primary key(a)) engine=innodb select * from t2 lock in share mode;
connection h;
set autocommit = 0;
--send
insert into t8 (select * from t2 for update);
connection i;
set autocommit = 0;
--send
update t9 set e = (select b from t2 where a = d for update);
connection j;
set autocommit = 0;
--send
create table t10(a int not null, b int, primary key(a)) engine=innodb select * from t2 for update;
connection b;
--error 1205
reap;
connection c;
--error 1205
reap;
connection d;
--error 1205
reap;
connection e;
--error 1205
reap;
connection f;
--error 1205
reap;
connection g;
--error 1205
reap;
connection h;
--error 1205
reap;
connection i;
--error 1205
reap;
connection j;
--error 1205
reap;
connection a;
commit;
connection default;
disconnect a;
disconnect b;
disconnect c;
disconnect d;
disconnect e;
disconnect f;
disconnect g;
disconnect h;
disconnect i;
disconnect j;
drop table t1, t2, t3, t5, t6, t8, t9;
...@@ -1158,7 +1158,7 @@ innobase_start_or_create_for_mysql(void) ...@@ -1158,7 +1158,7 @@ innobase_start_or_create_for_mysql(void)
maximum number of threads that can wait in the 'srv_conc array' for maximum number of threads that can wait in the 'srv_conc array' for
their time to enter InnoDB. */ their time to enter InnoDB. */
#if defined(__WIN__) || defined(__NETWARE__) #if defined(__NETWARE__)
/* Create less event semaphores because Win 98/ME had /* Create less event semaphores because Win 98/ME had
difficulty creating 40000 event semaphores. Comment from difficulty creating 40000 event semaphores. Comment from
......
...@@ -758,8 +758,9 @@ rw_lock_is_locked( ...@@ -758,8 +758,9 @@ rw_lock_is_locked(
Prints debug info of currently locked rw-locks. */ Prints debug info of currently locked rw-locks. */
void void
rw_lock_list_print_info(void) rw_lock_list_print_info(
/*=========================*/ /*====================*/
FILE* file) /* in: file where to print */
{ {
rw_lock_t* lock; rw_lock_t* lock;
ulint count = 0; ulint count = 0;
...@@ -769,7 +770,7 @@ rw_lock_list_print_info(void) ...@@ -769,7 +770,7 @@ rw_lock_list_print_info(void)
fputs("-------------\n" fputs("-------------\n"
"RW-LATCH INFO\n" "RW-LATCH INFO\n"
"-------------\n", stderr); "-------------\n", file);
lock = UT_LIST_GET_FIRST(rw_lock_list); lock = UT_LIST_GET_FIRST(rw_lock_list);
...@@ -783,12 +784,12 @@ rw_lock_list_print_info(void) ...@@ -783,12 +784,12 @@ rw_lock_list_print_info(void)
|| (rw_lock_get_reader_count(lock) != 0) || (rw_lock_get_reader_count(lock) != 0)
|| (rw_lock_get_waiters(lock) != 0)) { || (rw_lock_get_waiters(lock) != 0)) {
fprintf(stderr, "RW-LOCK: %p ", (void*) lock); fprintf(file, "RW-LOCK: %p ", (void*) lock);
if (rw_lock_get_waiters(lock)) { if (rw_lock_get_waiters(lock)) {
fputs(" Waiters for the lock exist\n", stderr); fputs(" Waiters for the lock exist\n", file);
} else { } else {
putc('\n', stderr); putc('\n', file);
} }
info = UT_LIST_GET_FIRST(lock->debug_list); info = UT_LIST_GET_FIRST(lock->debug_list);
...@@ -802,7 +803,7 @@ rw_lock_list_print_info(void) ...@@ -802,7 +803,7 @@ rw_lock_list_print_info(void)
lock = UT_LIST_GET_NEXT(list, lock); lock = UT_LIST_GET_NEXT(list, lock);
} }
fprintf(stderr, "Total number of rw-locks %ld\n", count); fprintf(file, "Total number of rw-locks %ld\n", count);
mutex_exit(&rw_lock_list_mutex); mutex_exit(&rw_lock_list_mutex);
} }
......
...@@ -628,10 +628,11 @@ mutex_own( ...@@ -628,10 +628,11 @@ mutex_own(
/********************************************************************** /**********************************************************************
Prints debug info of currently reserved mutexes. */ Prints debug info of currently reserved mutexes. */
static
void void
mutex_list_print_info(void) mutex_list_print_info(
/*=======================*/ /*==================*/
FILE* file) /* in: file where to print */
{ {
mutex_t* mutex; mutex_t* mutex;
const char* file_name; const char* file_name;
...@@ -641,7 +642,7 @@ mutex_list_print_info(void) ...@@ -641,7 +642,7 @@ mutex_list_print_info(void)
fputs("----------\n" fputs("----------\n"
"MUTEX INFO\n" "MUTEX INFO\n"
"----------\n", stderr); "----------\n", file);
mutex_enter(&mutex_list_mutex); mutex_enter(&mutex_list_mutex);
...@@ -653,7 +654,7 @@ mutex_list_print_info(void) ...@@ -653,7 +654,7 @@ mutex_list_print_info(void)
if (mutex_get_lock_word(mutex) != 0) { if (mutex_get_lock_word(mutex) != 0) {
mutex_get_debug_info(mutex, &file_name, &line, mutex_get_debug_info(mutex, &file_name, &line,
&thread_id); &thread_id);
fprintf(stderr, fprintf(file,
"Locked mutex: addr %p thread %ld" "Locked mutex: addr %p thread %ld"
" file %s line %ld\n", " file %s line %ld\n",
(void*) mutex, os_thread_pf(thread_id), (void*) mutex, os_thread_pf(thread_id),
...@@ -663,7 +664,7 @@ mutex_list_print_info(void) ...@@ -663,7 +664,7 @@ mutex_list_print_info(void)
mutex = UT_LIST_GET_NEXT(list, mutex); mutex = UT_LIST_GET_NEXT(list, mutex);
} }
fprintf(stderr, "Total number of mutexes %ld\n", count); fprintf(file, "Total number of mutexes %ld\n", count);
mutex_exit(&mutex_list_mutex); mutex_exit(&mutex_list_mutex);
} }
...@@ -1343,7 +1344,7 @@ sync_print_wait_info( ...@@ -1343,7 +1344,7 @@ sync_print_wait_info(
FILE* file) /* in: file where to print */ FILE* file) /* in: file where to print */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
fprintf(stderr, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n", fprintf(file, "Mutex exits %lu, rws exits %lu, rwx exits %lu\n",
mutex_exit_count, rw_s_exit_count, rw_x_exit_count); mutex_exit_count, rw_s_exit_count, rw_x_exit_count);
#endif #endif
...@@ -1369,9 +1370,9 @@ sync_print( ...@@ -1369,9 +1370,9 @@ sync_print(
FILE* file) /* in: file where to print */ FILE* file) /* in: file where to print */
{ {
#ifdef UNIV_SYNC_DEBUG #ifdef UNIV_SYNC_DEBUG
mutex_list_print_info(); mutex_list_print_info(file);
rw_lock_list_print_info(); rw_lock_list_print_info(file);
#endif /* UNIV_SYNC_DEBUG */ #endif /* UNIV_SYNC_DEBUG */
sync_array_print_info(file, sync_primary_wait_array); sync_array_print_info(file, sync_primary_wait_array);
......
...@@ -385,7 +385,10 @@ ut_print_filename( ...@@ -385,7 +385,10 @@ ut_print_filename(
} }
/************************************************************************** /**************************************************************************
Outputs a NUL-terminated string, quoted as an SQL identifier. */ Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
as in SQL database_name.identifier. */
void void
ut_print_name( ut_print_name(
...@@ -400,7 +403,10 @@ ut_print_name( ...@@ -400,7 +403,10 @@ ut_print_name(
} }
/************************************************************************** /**************************************************************************
Outputs a fixed-length string, quoted as an SQL identifier. */ Outputs a fixed-length string, quoted as an SQL identifier.
If the string contains a slash '/', the string will be
output as two identifiers separated by a period (.),
as in SQL database_name.identifier. */
void void
ut_print_namel( ut_print_namel(
...@@ -415,7 +421,7 @@ ut_print_namel( ...@@ -415,7 +421,7 @@ ut_print_namel(
#ifdef UNIV_HOTBACKUP #ifdef UNIV_HOTBACKUP
fwrite(name, 1, namelen, f); fwrite(name, 1, namelen, f);
#else #else
char* slash = strchr(name, '/'); char* slash = memchr(name, '/', namelen);
if (UNIV_LIKELY_NULL(slash)) { if (UNIV_LIKELY_NULL(slash)) {
/* Print the database name and table name separately. */ /* Print the database name and table name separately. */
......
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