mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 19:11:46 +01:00
branches/innodb+: Merge revisions 2460:2579 from branches/zip
The followin mysql-tests failed (and they are known to fail): main.information_schema [ fail ] main.innodb_file_per_table_basic[ fail ] main.type_bit_innodb [ fail ] Tested against : MYSQL_SERVER_VERSION "5.1.28"
This commit is contained in:
parent
c871d1146f
commit
4b06a4b130
65 changed files with 1252 additions and 305 deletions
37
ChangeLog
37
ChangeLog
|
@ -1,3 +1,40 @@
|
|||
2008-06-09 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb.result:
|
||||
Fix the failing innodb test by merging changes that MySQL made to that
|
||||
file
|
||||
|
||||
2008-06-06 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c, handler/ha_innodb.cc, include/buf0buf.h,
|
||||
include/srv0srv.h, srv/srv0srv.c:
|
||||
Fix Bug#36600 SHOW STATUS takes a lot of CPU in
|
||||
buf_get_latched_pages_number
|
||||
|
||||
* handler/ha_innodb.cc, os/os0file.c:
|
||||
Fix Bug#11894 innodb_file_per_table crashes w/ Windows .sym symbolic
|
||||
link hack
|
||||
|
||||
* include/ut0ut.h, srv/srv0srv.c, ut/ut0ut.c:
|
||||
Fix Bug#36819 ut_usectime does not handle errors from gettimeofday
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#35602 Failed to read auto-increment value from storage engine
|
||||
|
||||
* srv/srv0start.c:
|
||||
Fix Bug#36149 Read buffer overflow in srv0start.c found during "make
|
||||
test"
|
||||
|
||||
2008-05-08 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, mysql-test/innodb_bug36172.result,
|
||||
mysql-test/innodb_bug36172.test:
|
||||
Fix Bug#36172 insert into compressed innodb table crashes
|
||||
|
||||
2008-05-08 The InnoDB Team
|
||||
|
||||
InnoDB Plugin 1.0.1 released
|
||||
|
||||
2008-05-06 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/srv0srv.h, include/sync0sync.h,
|
||||
|
|
|
@ -2215,7 +2215,7 @@ btr_node_ptr_delete(
|
|||
/* Delete node pointer on father page */
|
||||
btr_page_get_father(index, block, mtr, &cursor);
|
||||
|
||||
compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, FALSE,
|
||||
compressed = btr_cur_pessimistic_delete(&err, TRUE, &cursor, RB_NONE,
|
||||
mtr);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ Created 10/16/1994 Heikki Tuuri
|
|||
#include "btr0sea.h"
|
||||
#include "row0upd.h"
|
||||
#include "trx0rec.h"
|
||||
#include "trx0roll.h" /* trx_is_recv() */
|
||||
#include "que0que.h"
|
||||
#include "row0row.h"
|
||||
#include "srv0srv.h"
|
||||
|
@ -116,6 +117,7 @@ btr_rec_free_updated_extern_fields(
|
|||
part will be updated, or NULL */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
const upd_t* update, /* in: update vector */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr); /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the tree */
|
||||
/***************************************************************
|
||||
|
@ -130,9 +132,7 @@ btr_rec_free_externally_stored_fields(
|
|||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
|
||||
part will be updated, or NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr); /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the index
|
||||
tree */
|
||||
|
@ -2279,8 +2279,9 @@ btr_cur_pessimistic_update(
|
|||
|
||||
ut_ad(big_rec_vec == NULL);
|
||||
|
||||
btr_rec_free_updated_extern_fields(index, rec, page_zip,
|
||||
offsets, update, mtr);
|
||||
btr_rec_free_updated_extern_fields(
|
||||
index, rec, page_zip, offsets, update,
|
||||
trx_is_recv(trx) ? RB_RECOVERY : RB_NORMAL, mtr);
|
||||
}
|
||||
|
||||
/* We have to set appropriate extern storage bits in the new
|
||||
|
@ -2951,7 +2952,7 @@ btr_cur_pessimistic_delete(
|
|||
if compression does not occur, the cursor
|
||||
stays valid: it points to successor of
|
||||
deleted record on function exit */
|
||||
ibool in_rollback,/* in: TRUE if called in rollback */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr) /* in: mtr */
|
||||
{
|
||||
buf_block_t* block;
|
||||
|
@ -3005,7 +3006,7 @@ btr_cur_pessimistic_delete(
|
|||
if (rec_offs_any_extern(offsets)) {
|
||||
btr_rec_free_externally_stored_fields(index,
|
||||
rec, offsets, page_zip,
|
||||
in_rollback, mtr);
|
||||
rb_ctx, mtr);
|
||||
#ifdef UNIV_ZIP_DEBUG
|
||||
ut_a(!page_zip || page_zip_validate(page_zip, page));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
|
@ -3314,7 +3315,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
/* We sample some pages in the index to get an estimate */
|
||||
|
||||
for (i = 0; i < srv_stats_sample; i++) {
|
||||
for (i = 0; i < srv_stats_sample_pages; i++) {
|
||||
rec_t* supremum;
|
||||
mtr_start(&mtr);
|
||||
|
||||
|
@ -3322,7 +3323,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
/* Count the number of different key values for each prefix of
|
||||
the key on this index page. If the prefix does not determine
|
||||
the index record uniquely in te B-tree, then we subtract one
|
||||
the index record uniquely in the B-tree, then we subtract one
|
||||
because otherwise our algorithm would give a wrong estimate
|
||||
for an index where there is just one key value. */
|
||||
|
||||
|
@ -3403,7 +3404,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
}
|
||||
|
||||
/* If we saw k borders between different key values on
|
||||
srv_stats_sample leaf pages, we can estimate how many
|
||||
srv_stats_sample_pages leaf pages, we can estimate how many
|
||||
there will be in index->stat_n_leaf_pages */
|
||||
|
||||
/* We must take into account that our sample actually represents
|
||||
|
@ -3414,26 +3415,26 @@ btr_estimate_number_of_different_key_vals(
|
|||
index->stat_n_diff_key_vals[j]
|
||||
= ((n_diff[j]
|
||||
* (ib_int64_t)index->stat_n_leaf_pages
|
||||
+ srv_stats_sample - 1
|
||||
+ srv_stats_sample_pages - 1
|
||||
+ total_external_size
|
||||
+ not_empty_flag)
|
||||
/ (srv_stats_sample
|
||||
/ (srv_stats_sample_pages
|
||||
+ total_external_size));
|
||||
|
||||
/* If the tree is small, smaller than
|
||||
10 * srv_stats_sample + total_external_size, then
|
||||
10 * srv_stats_sample_pages + total_external_size, then
|
||||
the above estimate is ok. For bigger trees it is common that we
|
||||
do not see any borders between key values in the few pages
|
||||
we pick. But still there may be srv_stats_sample
|
||||
we pick. But still there may be srv_stats_sample_pages
|
||||
different key values, or even more. Let us try to approximate
|
||||
that: */
|
||||
|
||||
add_on = index->stat_n_leaf_pages
|
||||
/ (10 * (srv_stats_sample
|
||||
/ (10 * (srv_stats_sample_pages
|
||||
+ total_external_size));
|
||||
|
||||
if (add_on > srv_stats_sample) {
|
||||
add_on = srv_stats_sample;
|
||||
if (add_on > srv_stats_sample_pages) {
|
||||
add_on = srv_stats_sample_pages;
|
||||
}
|
||||
|
||||
index->stat_n_diff_key_vals[j] += add_on;
|
||||
|
@ -4224,9 +4225,7 @@ btr_free_externally_stored_field(
|
|||
to rec, or NULL if rec == NULL */
|
||||
ulint i, /* in: field number of field_ref;
|
||||
ignored if rec == NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* local_mtr __attribute__((unused))) /* in: mtr
|
||||
containing the latch to data an an
|
||||
X-latch to the index tree */
|
||||
|
@ -4256,6 +4255,15 @@ btr_free_externally_stored_field(
|
|||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
if (UNIV_UNLIKELY(!memcmp(field_ref, field_ref_zero,
|
||||
BTR_EXTERN_FIELD_REF_SIZE))) {
|
||||
/* In the rollback of uncommitted transactions, we may
|
||||
encounter a clustered index record whose BLOBs have
|
||||
not been written. There is nothing to free then. */
|
||||
ut_a(rb_ctx == RB_RECOVERY);
|
||||
return;
|
||||
}
|
||||
|
||||
space_id = mach_read_from_4(field_ref + BTR_EXTERN_SPACE_ID);
|
||||
|
||||
if (UNIV_UNLIKELY(space_id != dict_index_get_space(index))) {
|
||||
|
@ -4300,7 +4308,7 @@ btr_free_externally_stored_field(
|
|||
|| (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
|
||||
& BTR_EXTERN_OWNER_FLAG)
|
||||
/* Rollback and inherited field */
|
||||
|| (do_not_free_inherited
|
||||
|| (rb_ctx != RB_NONE
|
||||
&& (mach_read_from_1(field_ref + BTR_EXTERN_LEN)
|
||||
& BTR_EXTERN_INHERITED_FLAG))) {
|
||||
|
||||
|
@ -4402,9 +4410,7 @@ btr_rec_free_externally_stored_fields(
|
|||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
page_zip_des_t* page_zip,/* in: compressed page whose uncompressed
|
||||
part will be updated, or NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr) /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the index
|
||||
tree */
|
||||
|
@ -4428,8 +4434,7 @@ btr_rec_free_externally_stored_fields(
|
|||
|
||||
btr_free_externally_stored_field(
|
||||
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
|
||||
rec, offsets, page_zip, i,
|
||||
do_not_free_inherited, mtr);
|
||||
rec, offsets, page_zip, i, rb_ctx, mtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4448,6 +4453,7 @@ btr_rec_free_updated_extern_fields(
|
|||
part will be updated, or NULL */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
const upd_t* update, /* in: update vector */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr) /* in: mini-transaction handle which contains
|
||||
an X-latch to record page and to the tree */
|
||||
{
|
||||
|
@ -4473,7 +4479,7 @@ btr_rec_free_updated_extern_fields(
|
|||
btr_free_externally_stored_field(
|
||||
index, data + len - BTR_EXTERN_FIELD_REF_SIZE,
|
||||
rec, offsets, page_zip,
|
||||
ufield->field_no, TRUE, mtr);
|
||||
ufield->field_no, rb_ctx, mtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -208,6 +208,7 @@ btr_pcur_restore_position(
|
|||
|| UNIV_UNLIKELY(cursor->pos_state != BTR_PCUR_WAS_POSITIONED
|
||||
&& cursor->pos_state != BTR_PCUR_IS_POSITIONED)) {
|
||||
ut_print_buf(stderr, cursor, sizeof(btr_pcur_t));
|
||||
putc('\n', stderr);
|
||||
if (cursor->trx_if_known) {
|
||||
trx_print(stderr, cursor->trx_if_known, 0);
|
||||
}
|
||||
|
|
|
@ -188,6 +188,7 @@ btr_search_info_create(
|
|||
info->magic_n = BTR_SEARCH_MAGIC_N;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
info->ref_count = 0;
|
||||
info->root_guess = NULL;
|
||||
|
||||
info->hash_analysis = 0;
|
||||
|
@ -211,6 +212,32 @@ btr_search_info_create(
|
|||
return(info);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Returns the value of ref_count. The value is protected by
|
||||
btr_search_latch. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
btr_search_info_get_ref_count(
|
||||
/*==========================*/
|
||||
/* out: ref_count value. */
|
||||
btr_search_t* info) /* in: search info. */
|
||||
{
|
||||
ulint ret;
|
||||
|
||||
ut_ad(info);
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
|
||||
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_EX));
|
||||
#endif /* UNIV_SYNC_DEBUG */
|
||||
|
||||
rw_lock_s_lock(&btr_search_latch);
|
||||
ret = info->ref_count;
|
||||
rw_lock_s_unlock(&btr_search_latch);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Updates the search info of an index about hash successes. NOTE that info
|
||||
is NOT protected by any semaphore, to save CPU time! Do not assume its fields
|
||||
|
@ -1070,8 +1097,12 @@ next_rec:
|
|||
ha_remove_all_nodes_to_page(table, folds[i], page);
|
||||
}
|
||||
|
||||
ut_a(index->search_info->ref_count > 0);
|
||||
index->search_info->ref_count--;
|
||||
|
||||
block->is_hashed = FALSE;
|
||||
block->index = NULL;
|
||||
|
||||
cleanup:
|
||||
#ifdef UNIV_DEBUG
|
||||
if (UNIV_UNLIKELY(block->n_pointers)) {
|
||||
|
@ -1295,6 +1326,15 @@ btr_search_build_page_hash_index(
|
|||
goto exit_func;
|
||||
}
|
||||
|
||||
/* This counter is decremented every time we drop page
|
||||
hash index entries and is incremented here. Since we can
|
||||
rebuild hash index for a page that is already hashed, we
|
||||
have to take care not to increment the counter in that
|
||||
case. */
|
||||
if (!block->is_hashed) {
|
||||
index->search_info->ref_count++;
|
||||
}
|
||||
|
||||
block->is_hashed = TRUE;
|
||||
block->n_hash_helps = 0;
|
||||
|
||||
|
|
|
@ -406,7 +406,7 @@ buf_page_is_corrupted(
|
|||
}
|
||||
|
||||
/* InnoDB versions < 4.0.14 and < 4.1.1 stored the space id
|
||||
(always equal to 0), to FIL_PAGE_SPACE_SPACE_OR_CHKSUM */
|
||||
(always equal to 0), to FIL_PAGE_SPACE_OR_CHKSUM */
|
||||
|
||||
if (checksum_field != 0
|
||||
&& checksum_field != BUF_NO_CHECKSUM_MAGIC
|
||||
|
@ -443,7 +443,7 @@ buf_page_print(
|
|||
fprintf(stderr, " InnoDB: Page dump in ascii and hex (%lu bytes):\n",
|
||||
(ulong) size);
|
||||
ut_print_buf(stderr, read_buf, size);
|
||||
fputs("InnoDB: End of page dump\n", stderr);
|
||||
fputs("\nInnoDB: End of page dump\n", stderr);
|
||||
|
||||
if (zip_size) {
|
||||
/* Print compressed page. */
|
||||
|
@ -3187,9 +3187,6 @@ corrupt:
|
|||
ut_error;
|
||||
}
|
||||
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
buf_pool_mutex_exit();
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (buf_debug_prints) {
|
||||
fprintf(stderr, "Has %s page space %lu page no %lu\n",
|
||||
|
@ -3198,6 +3195,9 @@ corrupt:
|
|||
(ulong) buf_page_get_page_no(bpage));
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
mutex_exit(buf_page_get_mutex(bpage));
|
||||
buf_pool_mutex_exit();
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
@ -3563,6 +3563,7 @@ buf_print(void)
|
|||
}
|
||||
#endif /* UNIV_DEBUG_PRINT || UNIV_DEBUG || UNIV_BUF_DEBUG */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/*************************************************************************
|
||||
Returns the number of latched pages in the buffer pool. */
|
||||
UNIV_INTERN
|
||||
|
@ -3649,6 +3650,7 @@ buf_get_latched_pages_number(void)
|
|||
|
||||
return(fixed_pages_number);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/*************************************************************************
|
||||
Returns the number of pending buf pool ios. */
|
||||
|
|
|
@ -168,6 +168,7 @@ buf_flush_ready_for_replace(
|
|||
" in the LRU list!\n",
|
||||
(ulong) buf_page_get_state(bpage));
|
||||
ut_print_buf(stderr, bpage, sizeof(buf_page_t));
|
||||
putc('\n', stderr);
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
@ -634,6 +635,13 @@ buf_flush_init_for_writing(
|
|||
return;
|
||||
}
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: ERROR: The compressed page to be written"
|
||||
" seems corrupt:", stderr);
|
||||
ut_print_buf(stderr, page, zip_size);
|
||||
fputs("\nInnoDB: Possibly older version of the page:", stderr);
|
||||
ut_print_buf(stderr, page_zip->data, zip_size);
|
||||
putc('\n', stderr);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1246,6 +1246,12 @@ alloc:
|
|||
|
||||
if (buf_page_is_old(b)) {
|
||||
buf_pool->LRU_old_len++;
|
||||
if (UNIV_UNLIKELY
|
||||
(buf_pool->LRU_old
|
||||
== UT_LIST_GET_NEXT(LRU, b))) {
|
||||
|
||||
buf_pool->LRU_old = b;
|
||||
}
|
||||
}
|
||||
|
||||
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
|
@ -1455,6 +1461,8 @@ buf_LRU_block_remove_hashed_page(
|
|||
buf_block_modify_clock_inc((buf_block_t*) bpage);
|
||||
if (bpage->zip.data) {
|
||||
const page_t* page = ((buf_block_t*) bpage)->frame;
|
||||
const ulint zip_size
|
||||
= page_zip_get_size(&bpage->zip);
|
||||
|
||||
ut_a(!zip || bpage->oldest_modification == 0);
|
||||
|
||||
|
@ -1472,7 +1480,7 @@ buf_LRU_block_remove_hashed_page(
|
|||
to the compressed page, which will
|
||||
be preserved. */
|
||||
memcpy(bpage->zip.data, page,
|
||||
page_zip_get_size(&bpage->zip));
|
||||
zip_size);
|
||||
}
|
||||
break;
|
||||
case FIL_PAGE_TYPE_ZBLOB:
|
||||
|
@ -1484,6 +1492,15 @@ buf_LRU_block_remove_hashed_page(
|
|||
#endif /* UNIV_ZIP_DEBUG */
|
||||
break;
|
||||
default:
|
||||
ut_print_timestamp(stderr);
|
||||
fputs(" InnoDB: ERROR: The compressed page"
|
||||
" to be evicted seems corrupt:", stderr);
|
||||
ut_print_buf(stderr, page, zip_size);
|
||||
fputs("\nInnoDB: Possibly older version"
|
||||
" of the page:", stderr);
|
||||
ut_print_buf(stderr, bpage->zip.data,
|
||||
zip_size);
|
||||
putc('\n', stderr);
|
||||
ut_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -1446,12 +1446,59 @@ dict_index_remove_from_cache(
|
|||
dict_index_t* index) /* in, own: index */
|
||||
{
|
||||
ulint size;
|
||||
ulint retries = 0;
|
||||
btr_search_t* info;
|
||||
|
||||
ut_ad(table && index);
|
||||
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
|
||||
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
|
||||
ut_ad(mutex_own(&(dict_sys->mutex)));
|
||||
|
||||
/* We always create search info whether or not adaptive
|
||||
hash index is enabled or not. */
|
||||
info = index->search_info;
|
||||
ut_ad(info);
|
||||
|
||||
/* We are not allowed to free the in-memory index struct
|
||||
dict_index_t until all entries in the adaptive hash index
|
||||
that point to any of the page belonging to his b-tree index
|
||||
are dropped. This is so because dropping of these entries
|
||||
require access to dict_index_t struct. To avoid such scenario
|
||||
We keep a count of number of such pages in the search_info and
|
||||
only free the dict_index_t struct when this count drops to
|
||||
zero. */
|
||||
|
||||
for (;;) {
|
||||
ulint ref_count = btr_search_info_get_ref_count(info);
|
||||
if (ref_count == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
/* Sleep for 10ms before trying again. */
|
||||
os_thread_sleep(10000);
|
||||
++retries;
|
||||
|
||||
if (retries % 500 == 0) {
|
||||
/* No luck after 5 seconds of wait. */
|
||||
fprintf(stderr, "InnoDB: Error: Waited for"
|
||||
" %lu secs for hash index"
|
||||
" ref_count (%lu) to drop"
|
||||
" to 0.\n"
|
||||
"index: \"%s\""
|
||||
" table: \"%s\"\n",
|
||||
retries/100,
|
||||
ref_count,
|
||||
index->name,
|
||||
table->name);
|
||||
}
|
||||
|
||||
/* To avoid a hang here we commit suicide if the
|
||||
ref_count doesn't drop to zero in 600 seconds. */
|
||||
if (retries >= 60000) {
|
||||
ut_error;
|
||||
}
|
||||
}
|
||||
|
||||
rw_lock_free(&index->lock);
|
||||
|
||||
/* Remove the index from the list of indexes of the table */
|
||||
|
|
|
@ -1577,6 +1577,7 @@ fsp_alloc_free_page(
|
|||
if (free == ULINT_UNDEFINED) {
|
||||
|
||||
ut_print_buf(stderr, ((byte*)descr) - 500, 1000);
|
||||
putc('\n', stderr);
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
@ -1760,6 +1761,7 @@ fsp_free_extent(
|
|||
if (xdes_get_state(descr, mtr) == XDES_FREE) {
|
||||
|
||||
ut_print_buf(stderr, (byte*)descr - 500, 1000);
|
||||
putc('\n', stderr);
|
||||
|
||||
ut_error;
|
||||
}
|
||||
|
|
21
ha/ha0ha.c
21
ha/ha0ha.c
|
@ -373,11 +373,20 @@ ha_print_info(
|
|||
FILE* file, /* in: file where to print */
|
||||
hash_table_t* table) /* in: hash table */
|
||||
{
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Some of the code here is disabled for performance reasons in production
|
||||
builds, see http://bugs.mysql.com/36941 */
|
||||
#define PRINT_USED_CELLS
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#ifdef PRINT_USED_CELLS
|
||||
hash_cell_t* cell;
|
||||
ulint cells = 0;
|
||||
ulint n_bufs;
|
||||
ulint i;
|
||||
#endif /* PRINT_USED_CELLS */
|
||||
ulint n_bufs;
|
||||
|
||||
#ifdef PRINT_USED_CELLS
|
||||
for (i = 0; i < hash_get_n_cells(table); i++) {
|
||||
|
||||
cell = hash_get_nth_cell(table, i);
|
||||
|
@ -387,10 +396,14 @@ ha_print_info(
|
|||
cells++;
|
||||
}
|
||||
}
|
||||
#endif /* PRINT_USED_CELLS */
|
||||
|
||||
fprintf(file,
|
||||
"Hash table size %lu, used cells %lu",
|
||||
(ulong) hash_get_n_cells(table), (ulong) cells);
|
||||
fprintf(file, "Hash table size %lu",
|
||||
(ulong) hash_get_n_cells(table));
|
||||
|
||||
#ifdef PRINT_USED_CELLS
|
||||
fprintf(file, ", used cells %lu", (ulong) cells);
|
||||
#endif /* PRINT_USED_CELLS */
|
||||
|
||||
if (table->heaps == NULL && table->heap != NULL) {
|
||||
|
||||
|
|
|
@ -468,8 +468,10 @@ static SHOW_VAR innodb_status_variables[]= {
|
|||
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
|
||||
{"buffer_pool_pages_free",
|
||||
(char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
|
||||
#ifdef UNIV_DEBUG
|
||||
{"buffer_pool_pages_latched",
|
||||
(char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
|
||||
#endif /* UNIV_DEBUG */
|
||||
{"buffer_pool_pages_misc",
|
||||
(char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
|
||||
{"buffer_pool_pages_total",
|
||||
|
@ -3709,7 +3711,8 @@ ha_innobase::innobase_autoinc_lock(void)
|
|||
old style only if another transaction has already acquired
|
||||
the AUTOINC lock on behalf of a LOAD FILE or INSERT ... SELECT
|
||||
etc. type of statement. */
|
||||
if (thd_sql_command(user_thd) == SQLCOM_INSERT) {
|
||||
if (thd_sql_command(user_thd) == SQLCOM_INSERT
|
||||
|| thd_sql_command(user_thd) == SQLCOM_REPLACE) {
|
||||
dict_table_t* table = prebuilt->table;
|
||||
|
||||
/* Acquire the AUTOINC mutex. */
|
||||
|
@ -5614,6 +5617,29 @@ ha_innobase::create(
|
|||
DBUG_ENTER("ha_innobase::create");
|
||||
|
||||
DBUG_ASSERT(thd != NULL);
|
||||
DBUG_ASSERT(create_info != NULL);
|
||||
|
||||
#ifdef __WIN__
|
||||
/* Names passed in from server are in two formats:
|
||||
1. <database_name>/<table_name>: for normal table creation
|
||||
2. full path: for temp table creation, or sym link
|
||||
|
||||
When srv_file_per_table is on, check for full path pattern, i.e.
|
||||
X:\dir\..., X is a driver letter, or
|
||||
\\dir1\dir2\..., UNC path
|
||||
returns error if it is in full path format, but not creating a temp.
|
||||
table. Currently InnoDB does not support symbolic link on Windows. */
|
||||
|
||||
if (srv_file_per_table
|
||||
&& (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) {
|
||||
|
||||
if ((name[1] == ':')
|
||||
|| (name[0] == '\\' && name[1] == '\\')) {
|
||||
sql_print_error("Cannot create table %s\n", name);
|
||||
DBUG_RETURN(HA_ERR_GENERIC);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (form->s->fields > 1000) {
|
||||
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
|
||||
|
@ -6615,6 +6641,14 @@ ha_innobase::info(
|
|||
if (thd_sql_command(user_thd) == SQLCOM_TRUNCATE) {
|
||||
|
||||
n_rows = 0;
|
||||
|
||||
/* We need to reset the prebuilt value too, otherwise
|
||||
checks for values greater than the last value written
|
||||
to the table will fail and the autoinc counter will
|
||||
not be updated. This will force write_row() into
|
||||
attempting an update of the table's AUTOINC counter. */
|
||||
|
||||
prebuilt->last_value = 0;
|
||||
}
|
||||
|
||||
stats.records = (ha_rows)n_rows;
|
||||
|
@ -9024,7 +9058,7 @@ innodb_file_format_check_validate(
|
|||
|
||||
if (innobase_file_format_check_on_off(file_format_input)) {
|
||||
sql_print_warning(
|
||||
"InnoDB: invalid innodb_file_format_check"
|
||||
"InnoDB: invalid innodb_file_format_check "
|
||||
"value; on/off can only be set at startup or "
|
||||
"in the configuration file");
|
||||
} else if (innobase_file_format_check_validate(
|
||||
|
@ -9209,6 +9243,11 @@ static MYSQL_SYSVAR_BOOL(stats_on_metadata, innobase_stats_on_metadata,
|
|||
"Enable statistics gathering for metadata commands such as SHOW TABLE STATUS (on by default)",
|
||||
NULL, NULL, TRUE);
|
||||
|
||||
static MYSQL_SYSVAR_ULONGLONG(stats_sample_pages, srv_stats_sample_pages,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"The number of index pages to sample when calculating statistics (default 8)",
|
||||
NULL, NULL, 8, 1, ~0ULL, 0);
|
||||
|
||||
static MYSQL_SYSVAR_BOOL(adaptive_hash_index, innobase_adaptive_hash_index,
|
||||
PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY,
|
||||
"Enable InnoDB adaptive hash index (enabled by default). "
|
||||
|
@ -9286,12 +9325,6 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files,
|
|||
"How many files at the maximum InnoDB keeps open at the same time.",
|
||||
NULL, NULL, 300L, 10L, ~0L, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(stats_sample, srv_stats_sample,
|
||||
PLUGIN_VAR_OPCMDARG,
|
||||
"When estimating number of different key values in an index, sample "
|
||||
"this many index pages",
|
||||
NULL, NULL, SRV_STATS_SAMPLE_DEFAULT, 1, 1000, 0);
|
||||
|
||||
static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds,
|
||||
PLUGIN_VAR_RQCMDARG,
|
||||
"Count of spin-loop rounds in InnoDB mutexes",
|
||||
|
@ -9362,9 +9395,9 @@ static struct st_mysql_sys_var* innobase_system_variables[]= {
|
|||
MYSQL_SYSVAR(open_files),
|
||||
MYSQL_SYSVAR(rollback_on_timeout),
|
||||
MYSQL_SYSVAR(stats_on_metadata),
|
||||
MYSQL_SYSVAR(stats_sample_pages),
|
||||
MYSQL_SYSVAR(adaptive_hash_index),
|
||||
MYSQL_SYSVAR(replication_delay),
|
||||
MYSQL_SYSVAR(stats_sample),
|
||||
MYSQL_SYSVAR(status_file),
|
||||
MYSQL_SYSVAR(strict_mode),
|
||||
MYSQL_SYSVAR(support_xa),
|
||||
|
@ -9432,9 +9465,10 @@ innodb_plugin_init(void)
|
|||
/*====================*/
|
||||
/* out: TRUE if the dynamic InnoDB plugin should start */
|
||||
{
|
||||
# if !MYSQL_STORAGE_ENGINE_PLUGIN
|
||||
# error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
|
||||
# endif
|
||||
#if !MYSQL_STORAGE_ENGINE_PLUGIN
|
||||
#error "MYSQL_STORAGE_ENGINE_PLUGIN must be nonzero."
|
||||
#endif
|
||||
|
||||
switch (builtin_innobase_plugin) {
|
||||
case 0:
|
||||
return(true);
|
||||
|
@ -9445,54 +9479,79 @@ innodb_plugin_init(void)
|
|||
}
|
||||
|
||||
/* Copy the system variables. */
|
||||
struct st_mysql_plugin* builtin
|
||||
= (struct st_mysql_plugin*) &builtin_innobase_plugin;
|
||||
struct st_mysql_sys_var** v = builtin->system_vars;
|
||||
struct st_mysql_sys_var** w = innobase_system_variables;
|
||||
|
||||
for (; *v; v++, w++) {
|
||||
if (!*w) {
|
||||
fprintf(stderr, "InnoDB: unknown parameter %s,0x%x\n",
|
||||
(*v)->name, (*v)->flags);
|
||||
return(false);
|
||||
} else if (!innobase_match_parameter((*v)->name, (*w)->name)) {
|
||||
/* Skip the destination parameter, since it doesn't
|
||||
exist in the source. */
|
||||
v--;
|
||||
continue;
|
||||
/* Ignore changes that affect the READONLY flag. */
|
||||
} else if (((*v)->flags ^ (*w)->flags) & ~PLUGIN_VAR_READONLY) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: parameter mismatch:"
|
||||
" %s,%s,0x%x,0x%x\n",
|
||||
(*v)->name, (*w)->name,
|
||||
(*v)->flags, (*w)->flags);
|
||||
return(false);
|
||||
} else if ((*v)->flags & PLUGIN_VAR_THDLOCAL) {
|
||||
/* Do not copy session variables. */
|
||||
struct st_mysql_plugin* builtin;
|
||||
struct st_mysql_sys_var** sta; /* static parameters */
|
||||
struct st_mysql_sys_var** dyn; /* dynamic parameters */
|
||||
|
||||
builtin = (struct st_mysql_plugin*) &builtin_innobase_plugin;
|
||||
|
||||
for (sta = builtin->system_vars; *sta != NULL; sta++) {
|
||||
|
||||
/* do not copy session variables */
|
||||
if ((*sta)->flags & PLUGIN_VAR_THDLOCAL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
switch ((*v)->flags
|
||||
& ~(PLUGIN_VAR_MASK | PLUGIN_VAR_UNSIGNED)) {
|
||||
# define COPY_VAR(label, type) \
|
||||
case label: \
|
||||
*(type*)(*w)->value = *(type*)(*v)->value; \
|
||||
break;
|
||||
for (dyn = innobase_system_variables; *dyn != NULL; dyn++) {
|
||||
|
||||
COPY_VAR(PLUGIN_VAR_BOOL, char);
|
||||
COPY_VAR(PLUGIN_VAR_INT, int);
|
||||
COPY_VAR(PLUGIN_VAR_LONG, long);
|
||||
COPY_VAR(PLUGIN_VAR_LONGLONG, long long);
|
||||
COPY_VAR(PLUGIN_VAR_STR, char*);
|
||||
if (innobase_match_parameter((*sta)->name,
|
||||
(*dyn)->name)) {
|
||||
|
||||
default:
|
||||
fprintf(stderr, "InnoDB: unknown flags 0x%x for %s\n",
|
||||
(*v)->flags, (*v)->name);
|
||||
/* found the corresponding parameter */
|
||||
|
||||
/* check if the flags are the same,
|
||||
ignoring differences in the READONLY flag;
|
||||
e.g. we are not copying string variable to
|
||||
an integer one */
|
||||
if (((*sta)->flags & ~PLUGIN_VAR_READONLY)
|
||||
!= ((*dyn)->flags & ~PLUGIN_VAR_READONLY)) {
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: %s in static InnoDB "
|
||||
"(flags=0x%x) differs from "
|
||||
"%s in dynamic InnoDB "
|
||||
"(flags=0x%x)\n",
|
||||
(*sta)->name, (*sta)->flags,
|
||||
(*dyn)->name, (*dyn)->flags);
|
||||
|
||||
/* we could break; here leaving this
|
||||
parameter uncopied */
|
||||
return(false);
|
||||
}
|
||||
|
||||
/* assign the value of the static parameter
|
||||
to the dynamic one, according to their type */
|
||||
|
||||
#define COPY_VAR(label, type) \
|
||||
case label: \
|
||||
*(type*)(*dyn)->value = *(type*)(*sta)->value; \
|
||||
break;
|
||||
|
||||
switch ((*sta)->flags
|
||||
& ~(PLUGIN_VAR_MASK
|
||||
| PLUGIN_VAR_UNSIGNED)) {
|
||||
|
||||
COPY_VAR(PLUGIN_VAR_BOOL, char);
|
||||
COPY_VAR(PLUGIN_VAR_INT, int);
|
||||
COPY_VAR(PLUGIN_VAR_LONG, long);
|
||||
COPY_VAR(PLUGIN_VAR_LONGLONG, long long);
|
||||
COPY_VAR(PLUGIN_VAR_STR, char*);
|
||||
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"InnoDB: unknown flags "
|
||||
"0x%x for %s\n",
|
||||
(*sta)->flags, (*sta)->name);
|
||||
}
|
||||
|
||||
/* Make the static InnoDB variable point to
|
||||
the dynamic one */
|
||||
(*sta)->value = (*dyn)->value;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make the static InnoDB variable point to the dynamic one */
|
||||
(*v)->value = (*w)->value;
|
||||
}
|
||||
|
||||
return(true);
|
||||
|
|
|
@ -635,9 +635,6 @@ ha_innobase::add_index(
|
|||
trx = trx_allocate_for_mysql();
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
trans_register_ha(user_thd, FALSE, ht);
|
||||
prebuilt->trx->active_trans = 1;
|
||||
|
||||
trx->mysql_thd = user_thd;
|
||||
trx->mysql_query_str = thd_query(user_thd);
|
||||
|
||||
|
@ -1084,9 +1081,6 @@ ha_innobase::final_drop_index(
|
|||
trx = trx_allocate_for_mysql();
|
||||
trx_start_if_not_started(trx);
|
||||
|
||||
trans_register_ha(user_thd, FALSE, ht);
|
||||
prebuilt->trx->active_trans = 1;
|
||||
|
||||
trx->mysql_thd = user_thd;
|
||||
trx->mysql_query_str = thd_query(user_thd);
|
||||
|
||||
|
|
|
@ -3548,7 +3548,7 @@ ibuf_delete_rec(
|
|||
root = ibuf_tree_root_get(mtr);
|
||||
|
||||
btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur),
|
||||
FALSE, mtr);
|
||||
RB_NONE, mtr);
|
||||
ut_a(err == DB_SUCCESS);
|
||||
|
||||
#ifdef UNIV_IBUF_COUNT_DEBUG
|
||||
|
|
|
@ -380,7 +380,7 @@ btr_cur_pessimistic_delete(
|
|||
if compression does not occur, the cursor
|
||||
stays valid: it points to successor of
|
||||
deleted record on function exit */
|
||||
ibool in_rollback,/* in: TRUE if called in rollback */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/***************************************************************
|
||||
Parses a redo log record of updating a record in-place. */
|
||||
|
@ -522,9 +522,7 @@ btr_free_externally_stored_field(
|
|||
to rec, or NULL if rec == NULL */
|
||||
ulint i, /* in: field number of field_ref;
|
||||
ignored if rec == NULL */
|
||||
ibool do_not_free_inherited,/* in: TRUE if called in a
|
||||
rollback and we do not want to free
|
||||
inherited fields */
|
||||
enum trx_rb_ctx rb_ctx, /* in: rollback context */
|
||||
mtr_t* local_mtr); /* in: mtr containing the latch to
|
||||
data an an X-latch to the index
|
||||
tree */
|
||||
|
|
|
@ -54,6 +54,15 @@ btr_search_info_create(
|
|||
/*===================*/
|
||||
/* out, own: search info struct */
|
||||
mem_heap_t* heap); /* in: heap where created */
|
||||
/*********************************************************************
|
||||
Returns the value of ref_count. The value is protected by
|
||||
btr_search_latch. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
btr_search_info_get_ref_count(
|
||||
/*==========================*/
|
||||
/* out: ref_count value. */
|
||||
btr_search_t* info); /* in: search info. */
|
||||
/*************************************************************************
|
||||
Updates the search info. */
|
||||
UNIV_INLINE
|
||||
|
@ -162,6 +171,13 @@ extern ibool btr_search_disabled;
|
|||
/* The search info struct in an index */
|
||||
|
||||
struct btr_search_struct{
|
||||
ulint ref_count; /* Number of blocks in this index tree
|
||||
that have search index built
|
||||
i.e. block->index points to this index.
|
||||
Protected by btr_search_latch except
|
||||
when during initialization in
|
||||
btr_search_info_create(). */
|
||||
|
||||
/* The following fields are not protected by any latch.
|
||||
Unfortunately, this means that they must be aligned to
|
||||
the machine word, i.e., they cannot be turned into bit-fields. */
|
||||
|
|
|
@ -537,12 +537,14 @@ buf_page_print(
|
|||
const byte* read_buf, /* in: a database page */
|
||||
ulint zip_size); /* in: compressed page size, or
|
||||
0 for uncompressed pages */
|
||||
#ifdef UNIV_DEBUG
|
||||
/*************************************************************************
|
||||
Returns the number of latched pages in the buffer pool. */
|
||||
UNIV_INTERN
|
||||
ulint
|
||||
buf_get_latched_pages_number(void);
|
||||
/*==============================*/
|
||||
#endif /* UNIV_DEBUG */
|
||||
/*************************************************************************
|
||||
Returns the number of pending buf pool ios. */
|
||||
UNIV_INTERN
|
||||
|
@ -1307,13 +1309,17 @@ struct buf_pool_struct{
|
|||
/* base node of the LRU list */
|
||||
buf_page_t* LRU_old; /* pointer to the about 3/8 oldest
|
||||
blocks in the LRU list; NULL if LRU
|
||||
length less than BUF_LRU_OLD_MIN_LEN */
|
||||
length less than BUF_LRU_OLD_MIN_LEN;
|
||||
NOTE: when LRU_old != NULL, its length
|
||||
should always equal LRU_old_len */
|
||||
ulint LRU_old_len; /* length of the LRU list from
|
||||
the block to which LRU_old points
|
||||
onward, including that block;
|
||||
see buf0lru.c for the restrictions
|
||||
on this value; not defined if
|
||||
LRU_old == NULL */
|
||||
LRU_old == NULL;
|
||||
NOTE: LRU_old_len must be adjusted
|
||||
whenever LRU_old shrinks or grows! */
|
||||
|
||||
UT_LIST_BASE_NODE_T(buf_block_t) unzip_LRU;
|
||||
/* base node of the unzip_LRU list */
|
||||
|
|
|
@ -221,7 +221,7 @@ struct dict_index_struct{
|
|||
unsigned page:32;/* index tree root page number */
|
||||
unsigned type:4; /* index type (DICT_CLUSTERED, DICT_UNIQUE,
|
||||
DICT_UNIVERSAL, DICT_IBUF) */
|
||||
unsigned trx_id_offset:10;/* position of the the trx id column
|
||||
unsigned trx_id_offset:10;/* position of the trx id column
|
||||
in a clustered index record, if the fields
|
||||
before it are known to be of a fixed size,
|
||||
0 otherwise */
|
||||
|
|
|
@ -76,21 +76,6 @@ typedef struct page_zip_stat_struct page_zip_stat_t;
|
|||
/** Statistics on compression, indexed by page_zip_des_t::ssize - 1 */
|
||||
extern page_zip_stat_t page_zip_stat[PAGE_ZIP_NUM_SSIZE - 1];
|
||||
|
||||
/**************************************************************************
|
||||
Write data to the compressed page. The data must already be written to
|
||||
the uncompressed page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
page_zip_write(
|
||||
/*===========*/
|
||||
page_zip_des_t* page_zip,/* in/out: compressed page */
|
||||
const byte* rec, /* in: record whose data is being written */
|
||||
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
|
||||
lint offset, /* in: start address of the block,
|
||||
relative to rec */
|
||||
ulint length) /* in: length of the data */
|
||||
__attribute__((nonnull));
|
||||
|
||||
/**************************************************************************
|
||||
Write the "deleted" flag of a record on a compressed page. The flag must
|
||||
already have been written on the uncompressed page. */
|
||||
|
|
|
@ -355,7 +355,15 @@ page_zip_write_header(
|
|||
{
|
||||
ulint pos;
|
||||
|
||||
#if 0
|
||||
/* In btr_cur_pessimistic_insert(), we allocate temp_page
|
||||
from the buffer pool to see if a record fits on a compressed
|
||||
page by itself. The buf_block_align() call in
|
||||
buf_frame_get_page_zip() only works for file pages, not
|
||||
temporarily allocated blocks. Thus, we must unfortunately
|
||||
disable the following assertion. */
|
||||
ut_ad(buf_frame_get_page_zip(str) == page_zip);
|
||||
#endif
|
||||
ut_ad(page_zip_simple_validate(page_zip));
|
||||
UNIV_MEM_ASSERT_RW(page_zip->data, page_zip_get_size(page_zip));
|
||||
|
||||
|
|
|
@ -136,10 +136,7 @@ extern ibool srv_innodb_status;
|
|||
|
||||
extern ibool srv_stats_on_metadata;
|
||||
|
||||
/* When estimating number of different key values in an index, sample
|
||||
this many index pages */
|
||||
#define SRV_STATS_SAMPLE_DEFAULT 8
|
||||
extern ulong srv_stats_sample;
|
||||
extern unsigned long long srv_stats_sample_pages;
|
||||
|
||||
extern ibool srv_use_doublewrite_buf;
|
||||
extern ibool srv_use_checksums;
|
||||
|
@ -522,7 +519,9 @@ struct export_var_struct{
|
|||
ulint innodb_buffer_pool_pages_dirty;
|
||||
ulint innodb_buffer_pool_pages_misc;
|
||||
ulint innodb_buffer_pool_pages_free;
|
||||
#ifdef UNIV_DEBUG
|
||||
ulint innodb_buffer_pool_pages_latched;
|
||||
#endif /* UNIV_DEBUG */
|
||||
ulint innodb_buffer_pool_read_requests;
|
||||
ulint innodb_buffer_pool_reads;
|
||||
ulint innodb_buffer_pool_wait_free;
|
||||
|
|
|
@ -178,6 +178,9 @@ trx_undo_rec_get_partial_row(
|
|||
record! */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
dtuple_t** row, /* out, own: partial row */
|
||||
ibool ignore_prefix, /* in: flag to indicate if we
|
||||
expect blob prefixes in undo. Used
|
||||
only in the assertion. */
|
||||
mem_heap_t* heap); /* in: memory heap from which the memory
|
||||
needed is allocated */
|
||||
/***************************************************************************
|
||||
|
|
|
@ -15,6 +15,17 @@ Created 3/26/1996 Heikki Tuuri
|
|||
#include "mtr0mtr.h"
|
||||
#include "trx0sys.h"
|
||||
|
||||
/***********************************************************************
|
||||
Determines if this transaction is rolling back an incomplete transaction
|
||||
in crash recovery. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_is_recv(
|
||||
/*========*/
|
||||
/* out: TRUE if trx is an incomplete
|
||||
transaction that is being rolled back
|
||||
in crash recovery */
|
||||
const trx_t* trx); /* in: transaction */
|
||||
/***********************************************************************
|
||||
Returns a transaction savepoint taken at this point in time. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -310,6 +310,15 @@ UNIV_INTERN
|
|||
void
|
||||
trx_sys_file_format_close(void);
|
||||
/*===========================*/
|
||||
/************************************************************************
|
||||
Tags the system table space with minimum format id if it has not been
|
||||
tagged yet.
|
||||
WARNING: This function is only called during the startup and AFTER the
|
||||
redo log application during recovery has finished. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_file_format_tag_init(void);
|
||||
/*==============================*/
|
||||
/*********************************************************************
|
||||
Get the name representation of the file format from its id. */
|
||||
UNIV_INTERN
|
||||
|
@ -319,14 +328,16 @@ trx_sys_file_format_id_to_name(
|
|||
/* out: pointer to the name */
|
||||
const uint id); /* in: id of the file format */
|
||||
/*********************************************************************
|
||||
Set the file format tag unconditonally. */
|
||||
Set the file format id unconditionally except if it's already the
|
||||
same value. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_sys_file_format_max_set(
|
||||
/*===========================*/
|
||||
/*========================*/
|
||||
/* out: TRUE if value updated */
|
||||
ulint file_format, /* in: file format id */
|
||||
char** name); /* out: max format name */
|
||||
ulint format_id, /* in: file format id */
|
||||
char** name); /* out: max file format name or
|
||||
NULL if not needed. */
|
||||
/*********************************************************************
|
||||
Get the name representation of the file format from its id. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -36,6 +36,14 @@ typedef struct roll_node_struct roll_node_t;
|
|||
typedef struct commit_node_struct commit_node_t;
|
||||
typedef struct trx_named_savept_struct trx_named_savept_t;
|
||||
|
||||
/* Rollback contexts */
|
||||
enum trx_rb_ctx {
|
||||
RB_NONE = 0, /* no rollback */
|
||||
RB_NORMAL, /* normal rollback */
|
||||
RB_RECOVERY, /* rolling back an incomplete transaction,
|
||||
in crash recovery */
|
||||
};
|
||||
|
||||
/* Transaction savepoint */
|
||||
typedef struct trx_savept_struct trx_savept_t;
|
||||
struct trx_savept_struct{
|
||||
|
|
|
@ -232,10 +232,9 @@ ulint
|
|||
trx_undo_assign_undo(
|
||||
/*=================*/
|
||||
/* out: DB_SUCCESS if undo log assign
|
||||
* successful, possible error codes are:
|
||||
* ER_TOO_MANY_CONCURRENT_TRXS
|
||||
* DB_OUT_OF_FILE_SPAC
|
||||
* DB_OUT_OF_MEMORY */
|
||||
successful, possible error codes are:
|
||||
DB_TOO_MANY_CONCURRENT_TRXS
|
||||
DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
|
||||
trx_t* trx, /* in: transaction */
|
||||
ulint type); /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
|
||||
/**********************************************************************
|
||||
|
|
|
@ -150,11 +150,15 @@ ib_time_t
|
|||
ut_time(void);
|
||||
/*=========*/
|
||||
/**************************************************************
|
||||
Returns system time. */
|
||||
Returns system time.
|
||||
Upon successful completion, the value 0 is returned; otherwise the
|
||||
value -1 is returned and the global variable errno is set to indicate the
|
||||
error. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
int
|
||||
ut_usectime(
|
||||
/*========*/
|
||||
/* out: 0 on success, -1 otherwise */
|
||||
ulint* sec, /* out: seconds since the Epoch */
|
||||
ulint* ms); /* out: microseconds since the Epoch+*sec */
|
||||
|
||||
|
|
|
@ -4264,6 +4264,15 @@ lock_rec_print(
|
|||
}
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* Print the number of lock structs from lock_print_info_summary() only
|
||||
in non-production builds for performance reasons, see
|
||||
http://bugs.mysql.com/36942 */
|
||||
#define PRINT_NUM_OF_LOCK_STRUCTS
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
|
||||
/*************************************************************************
|
||||
Calculates the number of record lock structs in the record lock hash table. */
|
||||
static
|
||||
|
@ -4290,6 +4299,7 @@ lock_get_n_rec_locks(void)
|
|||
|
||||
return(n_locks);
|
||||
}
|
||||
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
|
||||
|
||||
/*************************************************************************
|
||||
Prints info of locks for all transactions. */
|
||||
|
@ -4331,9 +4341,11 @@ lock_print_info_summary(
|
|||
"History list length %lu\n",
|
||||
(ulong) trx_sys->rseg_history_len);
|
||||
|
||||
#ifdef PRINT_NUM_OF_LOCK_STRUCTS
|
||||
fprintf(file,
|
||||
"Total number of lock structs in row lock hash table %lu\n",
|
||||
(ulong) lock_get_n_rec_locks());
|
||||
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
|
|
|
@ -491,6 +491,7 @@ mem_heap_validate_or_print(
|
|||
|
||||
if (print) {
|
||||
ut_print_buf(stderr, user_field, len);
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
total_len += len;
|
||||
|
|
|
@ -330,40 +330,33 @@ mem_heap_create_block(
|
|||
}
|
||||
|
||||
/* In dynamic allocation, calculate the size: block header + data. */
|
||||
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
|
||||
|
||||
if (type == MEM_HEAP_DYNAMIC) {
|
||||
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
|
||||
|
||||
ut_ad(type == MEM_HEAP_DYNAMIC || n <= MEM_MAX_ALLOC_IN_BUF);
|
||||
|
||||
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
|
||||
block = mem_area_alloc(&len, mem_comm_pool);
|
||||
} else {
|
||||
ut_ad(n <= MEM_MAX_ALLOC_IN_BUF);
|
||||
len = UNIV_PAGE_SIZE;
|
||||
|
||||
len = MEM_BLOCK_HEADER_SIZE + MEM_SPACE_NEEDED(n);
|
||||
if ((type & MEM_HEAP_BTR_SEARCH) && heap) {
|
||||
/* We cannot allocate the block from the
|
||||
buffer pool, but must get the free block from
|
||||
the heap header free block field */
|
||||
|
||||
if (len < UNIV_PAGE_SIZE / 2) {
|
||||
buf_block = heap->free_block;
|
||||
heap->free_block = NULL;
|
||||
|
||||
block = mem_area_alloc(&len, mem_comm_pool);
|
||||
} else {
|
||||
len = UNIV_PAGE_SIZE;
|
||||
if (UNIV_UNLIKELY(!buf_block)) {
|
||||
|
||||
if ((type & MEM_HEAP_BTR_SEARCH) && heap) {
|
||||
/* We cannot allocate the block from the
|
||||
buffer pool, but must get the free block from
|
||||
the heap header free block field */
|
||||
|
||||
buf_block = heap->free_block;
|
||||
heap->free_block = NULL;
|
||||
|
||||
if (UNIV_UNLIKELY(!buf_block)) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
buf_block = buf_block_alloc(0);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
block = (mem_block_t*) buf_block->frame;
|
||||
} else {
|
||||
buf_block = buf_block_alloc(0);
|
||||
}
|
||||
|
||||
block = (mem_block_t*) buf_block->frame;
|
||||
}
|
||||
|
||||
ut_ad(block);
|
||||
|
@ -492,19 +485,14 @@ mem_heap_block_free(
|
|||
UNIV_MEM_ASSERT_AND_FREE(block, len);
|
||||
#endif /* UNIV_MEM_DEBUG */
|
||||
|
||||
if (type == MEM_HEAP_DYNAMIC) {
|
||||
if (type == MEM_HEAP_DYNAMIC || len < UNIV_PAGE_SIZE / 2) {
|
||||
|
||||
ut_ad(!buf_block);
|
||||
mem_area_free(block, mem_comm_pool);
|
||||
} else {
|
||||
ut_ad(type & MEM_HEAP_BUFFER);
|
||||
|
||||
if (len >= UNIV_PAGE_SIZE / 2) {
|
||||
buf_block_free(buf_block);
|
||||
} else {
|
||||
ut_ad(!buf_block);
|
||||
mem_area_free(block, mem_comm_pool);
|
||||
}
|
||||
buf_block_free(buf_block);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -87,3 +87,85 @@ SELECT * FROM t1;
|
|||
c1 c2
|
||||
18446744073709551615 NULL
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
TRUNCATE TABLE t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
DELETE FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=latin1
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
c1
|
||||
1
|
||||
2
|
||||
3
|
||||
7
|
||||
8
|
||||
9
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` int(11) NOT NULL AUTO_INCREMENT,
|
||||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -105,3 +105,37 @@ INSERT INTO t1 VALUES (18446744073709551615, null);
|
|||
INSERT INTO t1 (c2) VALUES ('innodb');
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 37531
|
||||
# After truncate, auto_increment behaves incorrectly for InnoDB
|
||||
#
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
TRUNCATE TABLE t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Deleting all records should not reset the AUTOINC counter.
|
||||
#
|
||||
CREATE TABLE t1(c1 INT PRIMARY KEY AUTO_INCREMENT) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DELETE FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
INSERT INTO t1 VALUES (1), (2), (3);
|
||||
INSERT INTO t1 VALUES (NULL), (NULL), (NULL);
|
||||
SELECT c1 FROM t1;
|
||||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
|
|
@ -765,7 +765,6 @@ insert into t2 values ('jejdkrun87'),('adfd72nh9k'),
|
|||
('adfdpplkeock'),('adfdijnmnb78k'),('adfdijn0loKNHJik');
|
||||
create table t1(a int, b blob, c text, d text not null)
|
||||
engine=innodb default charset = utf8;
|
||||
insert into t1 values (null,null,null,'null');
|
||||
insert into t1
|
||||
select a,left(repeat(d,100*a),65535),repeat(d,20*a),d from t2,t3;
|
||||
drop table t2, t3;
|
||||
|
@ -775,7 +774,6 @@ count(*)
|
|||
select a,
|
||||
length(b),b=left(repeat(d,100*a),65535),length(c),c=repeat(d,20*a),d from t1;
|
||||
a length(b) b=left(repeat(d,100*a),65535) length(c) c=repeat(d,20*a) d
|
||||
NULL NULL NULL NULL NULL null
|
||||
22 22000 1 4400 1 adfd72nh9k
|
||||
22 35200 1 7040 1 adfdijn0loKNHJik
|
||||
22 28600 1 5720 1 adfdijnmnb78k
|
||||
|
@ -802,9 +800,6 @@ NULL NULL NULL NULL NULL null
|
|||
66 65535 1 15840 1 adfdpplkeock
|
||||
66 65535 1 13200 1 jejdkrun87
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
ERROR 42000: All parts of a PRIMARY KEY must be NOT NULL; if you need NULL in a key, use UNIQUE instead
|
||||
delete from t1 where d='null';
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
ERROR 23000: Duplicate entry '22' for key 'PRIMARY'
|
||||
delete from t1 where a%2;
|
||||
check table t1;
|
||||
|
@ -847,7 +842,7 @@ Table Op Msg_type Msg_text
|
|||
test.t1 check status OK
|
||||
explain select * from t1 where b like 'adfd%';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range b b 769 NULL 11 Using where
|
||||
1 SIMPLE t1 ALL b NULL NULL NULL 15 Using where
|
||||
create table t2(a int, b varchar(255), primary key(a,b)) engine=innodb;
|
||||
insert into t2 select a,left(b,255) from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -239,16 +239,47 @@ insert into t2 values ('jejdkrun87'),('adfd72nh9k'),
|
|||
create table t1(a int, b blob, c text, d text not null)
|
||||
engine=innodb default charset = utf8;
|
||||
|
||||
insert into t1 values (null,null,null,'null');
|
||||
# r2667 The following test is disabled because MySQL behavior changed.
|
||||
# r2667 The test was added with this comment:
|
||||
# r2667
|
||||
# r2667 ------------------------------------------------------------------------
|
||||
# r2667 r1699 | marko | 2007-08-10 19:53:19 +0300 (Fri, 10 Aug 2007) | 5 lines
|
||||
# r2667
|
||||
# r2667 branches/zip: Add changes that accidentally omitted from r1698:
|
||||
# r2667
|
||||
# r2667 innodb-index.test, innodb-index.result: Add a test for creating
|
||||
# r2667 a PRIMARY KEY on a column that contains a NULL value.
|
||||
# r2667 ------------------------------------------------------------------------
|
||||
# r2667
|
||||
# r2667 but in BZR-r2667:
|
||||
# r2667 http://bazaar.launchpad.net/~mysql/mysql-server/mysql-5.1/revision/davi%40mysql.com-20080617141221-8yre8ys9j4uw3xx5?start_revid=joerg%40mysql.com-20080630105418-7qoe5ehomgrcdb89
|
||||
# r2667 MySQL changed the behavior to do full table copy when creating PRIMARY INDEX
|
||||
# r2667 on a non-NULL column instead of calling ::add_index() which would fail (and
|
||||
# r2667 this is what we were testing here). Before r2667 the code execution path was
|
||||
# r2667 like this (when adding PRIMARY INDEX on a non-NULL column with ALTER TABLE):
|
||||
# r2667
|
||||
# r2667 mysql_alter_table()
|
||||
# r2667 compare_tables() // would return ALTER_TABLE_INDEX_CHANGED
|
||||
# r2667 ::add_index() // would fail with "primary index cannot contain NULL"
|
||||
# r2667
|
||||
# r2667 after r2667 the code execution path is the following:
|
||||
# r2667
|
||||
# r2667 mysql_alter_table()
|
||||
# r2667 compare_tables() // returns ALTER_TABLE_DATA_CHANGED
|
||||
# r2667 full copy is done, without calling ::add_index()
|
||||
# r2667
|
||||
# r2667 To enable, remove "# r2667: " below.
|
||||
# r2667
|
||||
# r2667: insert into t1 values (null,null,null,'null');
|
||||
insert into t1
|
||||
select a,left(repeat(d,100*a),65535),repeat(d,20*a),d from t2,t3;
|
||||
drop table t2, t3;
|
||||
select count(*) from t1 where a=44;
|
||||
select a,
|
||||
length(b),b=left(repeat(d,100*a),65535),length(c),c=repeat(d,20*a),d from t1;
|
||||
--error ER_PRIMARY_CANT_HAVE_NULL
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
delete from t1 where d='null';
|
||||
# r2667: --error ER_PRIMARY_CANT_HAVE_NULL
|
||||
# r2667: alter table t1 add primary key (a), add key (b(20));
|
||||
# r2667: delete from t1 where d='null';
|
||||
--error ER_DUP_ENTRY
|
||||
alter table t1 add primary key (a), add key (b(20));
|
||||
delete from t1 where a%2;
|
||||
|
|
|
@ -3,11 +3,11 @@ create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=inn
|
|||
select * from t1;
|
||||
c1 c2 stamp
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11");
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
ERROR HY000: DELAYED option not supported for table 't1'
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12");
|
||||
ERROR HY000: Table storage engine for 't1' doesn't have this option
|
||||
ERROR HY000: DELAYED option not supported for table 't1'
|
||||
select * from t1;
|
||||
c1 c2 stamp
|
||||
drop table t1;
|
||||
|
|
|
@ -11,10 +11,10 @@ drop table if exists t1;
|
|||
#
|
||||
create table t1 (c1 char(5) unique not null, c2 int, stamp timestamp) engine=innodb;
|
||||
select * from t1;
|
||||
--error 1031
|
||||
--error ER_DELAYED_NOT_SUPPORTED
|
||||
replace delayed into t1 (c1, c2) values ( "text1","11");
|
||||
select * from t1;
|
||||
--error 1031
|
||||
--error ER_DELAYED_NOT_SUPPORTED
|
||||
replace delayed into t1 (c1, c2) values ( "text1","12");
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
|
|
@ -131,6 +131,25 @@ INSERT INTO t1 VALUES(
|
|||
'FOXajs|.7@IR[dmv(2<FPZdnx+5?IS]gq{.8BLV`jt~1;EOYcmw*4>HR\fpz-7AKU_is}0:DNXblv)3=GQ[eoy,6@JT^hr|/9CMWaku(3>IT_ju)4?JU`kv*5@KValw+6ALWbmx,7BMXcny-8CNYdoz.9DOZep{/:EP[fq|0;FQ\gr}1<GR]hs~2=HS^it(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(5BO\iv,9FS`mz0=JWdq~4AN[hu+8ER_ly/<IVcp}3@MZgt*7DQ^kx.;HUbo|2?LYfs)6CP]jw-:GTan{1>KXer(6DR`n|3AO]ky0>LZhv-;IWes*8FTbp~5CQ_m{2@N\jx/=KYgu,:HVdr)7ESao}4BP^lz1?M[iw.<JXft+9GUcq(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(8HXhx1AQaq*:JZjz3CScs,<L\l|5EUeu.>N^n~7GWgw0@P`p)9IYiy2BRbr+;K[k{4DTdt-=M]m}6FVfv/?O_o(9J[l}7HYj{5FWhy3DUfw1BSdu/@Qbs->O`q+<M^o):K\m~8IZk|6GXiz4EVgx2CTev0ARct.?Par,=N_p*;L]n(:L^p+=Oas.@Rdv1CUgy4FXj|7I[m(:L^p+=Oas.@Rdv1CUgy4FXj|7');
|
||||
ERROR 42000: Row size too large. The maximum row size for the used table type, not counting BLOBs, is 8126. You have to change some columns to TEXT or BLOBs
|
||||
drop table t1;
|
||||
create table t1( c1 int not null, c2 blob, c3 blob, c4 blob,
|
||||
primary key(c1, c2(22), c3(22)))
|
||||
engine = innodb row_format = dynamic;
|
||||
begin;
|
||||
insert into t1 values(1, repeat('A', 20000), repeat('B', 20000),
|
||||
repeat('C', 20000));
|
||||
update t1 set c3 = repeat('D', 20000) where c1 = 1;
|
||||
commit;
|
||||
select count(*) from t1 where c2 = repeat('A', 20000);
|
||||
count(*)
|
||||
1
|
||||
select count(*) from t1 where c3 = repeat('D', 20000);
|
||||
count(*)
|
||||
1
|
||||
select count(*) from t1 where c4 = repeat('C', 20000);
|
||||
count(*)
|
||||
1
|
||||
update t1 set c3 = repeat('E', 20000) where c1 = 1;
|
||||
drop table t1;
|
||||
set global innodb_file_format=`0`;
|
||||
select @@innodb_file_format;
|
||||
@@innodb_file_format
|
||||
|
@ -381,13 +400,4 @@ show table status;
|
|||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
set global innodb_file_format_check=`Cheetah`;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check=`on`;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_format_check=`off`;
|
||||
ERROR HY000: Incorrect arguments to SET
|
||||
select @@innodb_file_format_check;
|
||||
@@innodb_file_format_check
|
||||
Barracuda
|
||||
drop table normal_table, zip_table;
|
||||
|
|
|
@ -100,6 +100,31 @@ INSERT INTO t1 VALUES(
|
|||
'FOXajs|.7@IR[dmv(2<FPZdnx+5?IS]gq{.8BLV`jt~1;EOYcmw*4>HR\fpz-7AKU_is}0:DNXblv)3=GQ[eoy,6@JT^hr|/9CMWaku(3>IT_ju)4?JU`kv*5@KValw+6ALWbmx,7BMXcny-8CNYdoz.9DOZep{/:EP[fq|0;FQ\gr}1<GR]hs~2=HS^it(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(4@LXdp|1=IUamy.:FR^jv+7CO[gs(5BO\iv,9FS`mz0=JWdq~4AN[hu+8ER_ly/<IVcp}3@MZgt*7DQ^kx.;HUbo|2?LYfs)6CP]jw-:GTan{1>KXer(6DR`n|3AO]ky0>LZhv-;IWes*8FTbp~5CQ_m{2@N\jx/=KYgu,:HVdr)7ESao}4BP^lz1?M[iw.<JXft+9GUcq(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(7FUds+:IXgv.=L[jy1@O^m|4CRap(8HXhx1AQaq*:JZjz3CScs,<L\l|5EUeu.>N^n~7GWgw0@P`p)9IYiy2BRbr+;K[k{4DTdt-=M]m}6FVfv/?O_o(9J[l}7HYj{5FWhy3DUfw1BSdu/@Qbs->O`q+<M^o):K\m~8IZk|6GXiz4EVgx2CTev0ARct.?Par,=N_p*;L]n(:L^p+=Oas.@Rdv1CUgy4FXj|7I[m(:L^p+=Oas.@Rdv1CUgy4FXj|7');
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test blob column inheritance (mantis issue#36)
|
||||
#
|
||||
|
||||
create table t1( c1 int not null, c2 blob, c3 blob, c4 blob,
|
||||
primary key(c1, c2(22), c3(22)))
|
||||
engine = innodb row_format = dynamic;
|
||||
begin;
|
||||
insert into t1 values(1, repeat('A', 20000), repeat('B', 20000),
|
||||
repeat('C', 20000));
|
||||
|
||||
update t1 set c3 = repeat('D', 20000) where c1 = 1;
|
||||
commit;
|
||||
|
||||
# one blob column which is unchanged in update and part of PK
|
||||
# one blob column which is changed and part of of PK
|
||||
# one blob column which is not part of PK and is unchanged
|
||||
select count(*) from t1 where c2 = repeat('A', 20000);
|
||||
select count(*) from t1 where c3 = repeat('D', 20000);
|
||||
select count(*) from t1 where c4 = repeat('C', 20000);
|
||||
|
||||
update t1 set c3 = repeat('E', 20000) where c1 = 1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
#
|
||||
# Test innodb_file_format
|
||||
#
|
||||
|
@ -291,12 +316,5 @@ select @@innodb_file_format_check;
|
|||
show table status;
|
||||
-- enable_result_log
|
||||
select @@innodb_file_format_check;
|
||||
-- error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check=`Cheetah`;
|
||||
-- error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check=`on`;
|
||||
-- error ER_WRONG_ARGUMENTS
|
||||
set global innodb_file_format_check=`off`;
|
||||
select @@innodb_file_format_check;
|
||||
drop table normal_table, zip_table;
|
||||
-- disable_result_log
|
||||
|
|
|
@ -925,7 +925,7 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t1 index NULL b 4 NULL # Using index
|
||||
explain select a,b from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 4 NULL #
|
||||
1 SIMPLE t1 index NULL b 4 NULL # Using index
|
||||
explain select a,b,c from t1;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL #
|
||||
|
@ -1166,14 +1166,14 @@ UPDATE t1 set a=a+100 where b between 2 and 3 and a < 1000;
|
|||
SELECT * from t1;
|
||||
a b
|
||||
1 1
|
||||
102 2
|
||||
103 3
|
||||
4 4
|
||||
5 5
|
||||
6 6
|
||||
7 7
|
||||
8 8
|
||||
9 9
|
||||
102 2
|
||||
103 3
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (a int not null primary key, b int not null, key (b)) engine=innodb;
|
||||
CREATE TABLE t2 (a int not null primary key, b int not null, key (b)) engine=innodb;
|
||||
|
@ -1197,6 +1197,7 @@ a b
|
|||
update t1,t2 set t1.a=t1.a+100 where t1.a=101;
|
||||
select * from t1;
|
||||
a b
|
||||
201 1
|
||||
102 2
|
||||
103 3
|
||||
104 4
|
||||
|
@ -1208,11 +1209,10 @@ a b
|
|||
110 10
|
||||
111 11
|
||||
112 12
|
||||
201 1
|
||||
update t1,t2 set t1.b=t1.b+10 where t1.b=2;
|
||||
select * from t1;
|
||||
a b
|
||||
102 12
|
||||
201 1
|
||||
103 3
|
||||
104 4
|
||||
105 5
|
||||
|
@ -1222,34 +1222,34 @@ a b
|
|||
109 9
|
||||
110 10
|
||||
111 11
|
||||
102 12
|
||||
112 12
|
||||
201 1
|
||||
update t1,t2 set t1.b=t1.b+2,t2.b=t1.b+10 where t1.b between 3 and 5 and t1.a=t2.a+100;
|
||||
select * from t1;
|
||||
a b
|
||||
102 12
|
||||
201 1
|
||||
103 5
|
||||
104 6
|
||||
105 7
|
||||
106 6
|
||||
105 7
|
||||
107 7
|
||||
108 8
|
||||
109 9
|
||||
110 10
|
||||
111 11
|
||||
102 12
|
||||
112 12
|
||||
201 1
|
||||
select * from t2;
|
||||
a b
|
||||
1 1
|
||||
2 2
|
||||
3 13
|
||||
4 14
|
||||
5 15
|
||||
6 6
|
||||
7 7
|
||||
8 8
|
||||
9 9
|
||||
3 13
|
||||
4 14
|
||||
5 15
|
||||
drop table t1,t2;
|
||||
CREATE TABLE t2 ( NEXT_T BIGINT NOT NULL PRIMARY KEY) ENGINE=MyISAM;
|
||||
CREATE TABLE t1 ( B_ID INTEGER NOT NULL PRIMARY KEY) ENGINE=InnoDB;
|
||||
|
@ -1300,11 +1300,11 @@ insert into t1 (id) values (null),(null),(null),(null),(null);
|
|||
update t1 set fk=69 where fk is null order by id limit 1;
|
||||
SELECT * from t1;
|
||||
id fk
|
||||
1 69
|
||||
2 NULL
|
||||
3 NULL
|
||||
4 NULL
|
||||
5 NULL
|
||||
1 69
|
||||
drop table t1;
|
||||
create table t1 (a int not null, b int not null, key (a));
|
||||
insert into t1 values (1,1),(1,2),(1,3),(3,1),(3,2),(3,3),(3,1),(3,2),(3,3),(2,1),(2,2),(2,3);
|
||||
|
@ -1836,7 +1836,6 @@ set @a=repeat(' ',20);
|
|||
insert into t1 values (concat('+',@a),concat('+',@a),concat('+',@a));
|
||||
Warnings:
|
||||
Note 1265 Data truncated for column 'v' at row 1
|
||||
Note 1265 Data truncated for column 'c' at row 1
|
||||
select concat('*',v,'*',c,'*',t,'*') from t1;
|
||||
concat('*',v,'*',c,'*',t,'*')
|
||||
*+ *+*+ *
|
||||
|
@ -2440,8 +2439,8 @@ insert into t1 (b) values (1);
|
|||
replace into t1 (b) values (2), (1), (3);
|
||||
select * from t1;
|
||||
a b
|
||||
2 2
|
||||
3 1
|
||||
2 2
|
||||
4 3
|
||||
truncate table t1;
|
||||
insert into t1 (b) values (1);
|
||||
|
@ -2450,8 +2449,8 @@ replace into t1 (b) values (1);
|
|||
replace into t1 (b) values (3);
|
||||
select * from t1;
|
||||
a b
|
||||
2 2
|
||||
3 1
|
||||
2 2
|
||||
4 3
|
||||
drop table t1;
|
||||
create table t1 (rowid int not null auto_increment, val int not null,primary
|
||||
|
|
30
mysql-test/patches/README
Normal file
30
mysql-test/patches/README
Normal file
|
@ -0,0 +1,30 @@
|
|||
This directory contains patches that need to be applied to the MySQL
|
||||
source tree in order to get the mysql-test suite to succeed (when
|
||||
storage/innobase is replaced with this InnoDB branch). Things to keep
|
||||
in mind when adding new patches here:
|
||||
|
||||
* The patch must be appliable from the mysql top-level source directory.
|
||||
|
||||
* The patch filename must end in ".diff".
|
||||
|
||||
* All patches here are expected to apply cleanly to the latest MySQL 5.1
|
||||
tree with storage/innobase is replaced with this InnoDB branch. If
|
||||
changes to either of those cause the patch to fail, then please check
|
||||
whether the patch is still needed and, if yes, adjust it so it applies
|
||||
cleanly.
|
||||
|
||||
* If applicable, always submit the patch at http://bugs.mysql.com and
|
||||
name the file here like bug%d.diff. Once the patch is committed to
|
||||
MySQL remove the file from here.
|
||||
|
||||
* If the patch cannot be proposed for inclusion in the MySQL source tree
|
||||
(via http://bugs.mysql.com) then add a comment at the beginning of the
|
||||
patch explaining the problem it is solving, how it does solve it and
|
||||
why it is not applicable for inclusion in the MySQL source tree.
|
||||
Obviously this is a very bad situation and should be avoided at all
|
||||
costs, especially for files that are in the MySQL source repository
|
||||
(not in storage/innobase).
|
||||
|
||||
* If you ever need to add a patch here that is not related to mysql-test
|
||||
suite, then please move this directory from ./mysql-test/patches to
|
||||
./patches and remove this text.
|
38
mysql-test/patches/bug31231.diff
Normal file
38
mysql-test/patches/bug31231.diff
Normal file
|
@ -0,0 +1,38 @@
|
|||
diff -pu sql/mysql_priv.h sql/mysql_priv.h
|
||||
--- sql/mysql_priv.h 2007-11-14 15:28:19.000000000 +0200
|
||||
+++ sql/mysql_priv.h 2008-01-08 10:45:53.000000000 +0200
|
||||
@@ -2094,6 +2094,7 @@ uint build_table_shadow_filename(char *b
|
||||
#define FN_TO_IS_TMP (1 << 1)
|
||||
#define FN_IS_TMP (FN_FROM_IS_TMP | FN_TO_IS_TMP)
|
||||
#define NO_FRM_RENAME (1 << 2)
|
||||
+#define FN_FRM_ONLY (1 << 3)
|
||||
|
||||
/* from hostname.cc */
|
||||
struct in_addr;
|
||||
diff -pu sql/sql_table.cc sql/sql_table.cc
|
||||
--- sql/sql_table.cc 2007-11-02 00:48:11.000000000 +0200
|
||||
+++ sql/sql_table.cc 2008-01-08 10:46:04.000000000 +0200
|
||||
@@ -1791,8 +1791,9 @@ bool quick_rm_table(handlerton *base,con
|
||||
if (my_delete(path,MYF(0)))
|
||||
error= 1; /* purecov: inspected */
|
||||
path[path_length - reg_ext_length]= '\0'; // Remove reg_ext
|
||||
- DBUG_RETURN(ha_delete_table(current_thd, base, path, db, table_name, 0) ||
|
||||
- error);
|
||||
+ if (!(flags & FN_FRM_ONLY))
|
||||
+ error|= ha_delete_table(current_thd, base, path, db, table_name, 0);
|
||||
+ DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -6680,7 +6681,10 @@ err1:
|
||||
close_temporary_table(thd, new_table, 1, 1);
|
||||
}
|
||||
else
|
||||
- VOID(quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP));
|
||||
+ VOID(quick_rm_table(new_db_type, new_db, tmp_name,
|
||||
+ create_info->frm_only
|
||||
+ ? FN_IS_TMP | FN_FRM_ONLY
|
||||
+ : FN_IS_TMP));
|
||||
|
||||
err:
|
||||
/*
|
85
mysql-test/patches/bug35261.diff
Normal file
85
mysql-test/patches/bug35261.diff
Normal file
|
@ -0,0 +1,85 @@
|
|||
--- mysql-test/t/date_formats.test.orig 2007-06-15 02:53:07.000000000 +0300
|
||||
+++ mysql-test/t/date_formats.test 2008-03-19 17:25:10.000000000 +0200
|
||||
@@ -7,9 +7,15 @@
|
||||
--enable_warnings
|
||||
|
||||
--replace_result ROW <format> STATEMENT <format> MIXED <format>
|
||||
-SHOW GLOBAL VARIABLES LIKE "%e_format";
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.global_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
--replace_result ROW <format> STATEMENT <format> MIXED <format>
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
|
||||
#
|
||||
# Test setting a lot of different formats to see which formats are accepted and
|
||||
@@ -37,7 +43,10 @@
|
||||
set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
|
||||
|
||||
--replace_result ROW <format> STATEMENT <format> MIXED <format>
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
|
||||
--error 1231
|
||||
SET time_format='%h:%i:%s';
|
||||
--- mysql-test/r/date_formats.result.orig 2008-02-12 21:09:14.000000000 +0200
|
||||
+++ mysql-test/r/date_formats.result 2008-03-19 17:26:33.000000000 +0200
|
||||
@@ -1,14 +1,20 @@
|
||||
drop table if exists t1;
|
||||
-SHOW GLOBAL VARIABLES LIKE "%e_format";
|
||||
-Variable_name Value
|
||||
-date_format %d.%m.%Y
|
||||
-datetime_format %Y-%m-%d %H:%i:%s
|
||||
-time_format %H.%i.%s
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
-Variable_name Value
|
||||
-date_format %d.%m.%Y
|
||||
-datetime_format %Y-%m-%d %H:%i:%s
|
||||
-time_format %H.%i.%s
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.global_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
+variable_name variable_value
|
||||
+DATETIME_FORMAT %Y-%m-%d %H:%i:%s
|
||||
+DATE_FORMAT %d.%m.%Y
|
||||
+TIME_FORMAT %H.%i.%s
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
+variable_name variable_value
|
||||
+DATETIME_FORMAT %Y-%m-%d %H:%i:%s
|
||||
+DATE_FORMAT %d.%m.%Y
|
||||
+TIME_FORMAT %H.%i.%s
|
||||
SET time_format='%H%i%s';
|
||||
SET time_format='%H:%i:%s.%f';
|
||||
SET time_format='%h-%i-%s.%f%p';
|
||||
@@ -26,11 +32,14 @@
|
||||
set datetime_format= '%H:%i:%s.%f %m-%d-%Y';
|
||||
set datetime_format= '%h:%i:%s %p %Y-%m-%d';
|
||||
set datetime_format= '%h:%i:%s.%f %p %Y-%m-%d';
|
||||
-SHOW SESSION VARIABLES LIKE "%e_format";
|
||||
-Variable_name Value
|
||||
-date_format %m-%d-%Y
|
||||
-datetime_format %h:%i:%s.%f %p %Y-%m-%d
|
||||
-time_format %h:%i:%s%p
|
||||
+SELECT variable_name, variable_value
|
||||
+FROM information_schema.session_variables
|
||||
+WHERE variable_name IN ('date_format', 'datetime_format', 'time_format')
|
||||
+ORDER BY variable_name;
|
||||
+variable_name variable_value
|
||||
+DATETIME_FORMAT %h:%i:%s.%f %p %Y-%m-%d
|
||||
+DATE_FORMAT %m-%d-%Y
|
||||
+TIME_FORMAT %h:%i:%s%p
|
||||
SET time_format='%h:%i:%s';
|
||||
ERROR 42000: Variable 'time_format' can't be set to the value of '%h:%i:%s'
|
||||
SET time_format='%H %i:%s';
|
32
mysql-test/patches/bug37312.diff
Normal file
32
mysql-test/patches/bug37312.diff
Normal file
|
@ -0,0 +1,32 @@
|
|||
--- mysql-test/extra/binlog_tests/innodb_stat.test.orig 2008-06-10 15:12:02.000000000 +0300
|
||||
+++ mysql-test/extra/binlog_tests/innodb_stat.test 2008-06-10 15:12:06.000000000 +0300
|
||||
@@ -41,6 +41,7 @@
|
||||
|
||||
# Test for testable InnoDB status variables. This test
|
||||
# uses previous ones(pages_created, rows_deleted, ...).
|
||||
+-- replace_regex /51[12]/51_/
|
||||
show status like "Innodb_buffer_pool_pages_total";
|
||||
show status like "Innodb_page_size";
|
||||
show status like "Innodb_rows_deleted";
|
||||
--- mysql-test/suite/binlog/r/binlog_row_innodb_stat.result.orig 2008-06-10 15:29:44.000000000 +0300
|
||||
+++ mysql-test/suite/binlog/r/binlog_row_innodb_stat.result 2008-06-10 15:30:04.000000000 +0300
|
||||
@@ -24,7 +24,7 @@
|
||||
drop table t1;
|
||||
show status like "Innodb_buffer_pool_pages_total";
|
||||
Variable_name Value
|
||||
-Innodb_buffer_pool_pages_total 512
|
||||
+Innodb_buffer_pool_pages_total 51_
|
||||
show status like "Innodb_page_size";
|
||||
Variable_name Value
|
||||
Innodb_page_size 16384
|
||||
--- mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result.orig 2008-06-10 15:33:43.000000000 +0300
|
||||
+++ mysql-test/suite/binlog/r/binlog_stm_innodb_stat.result 2008-06-10 15:33:55.000000000 +0300
|
||||
@@ -24,7 +24,7 @@
|
||||
drop table t1;
|
||||
show status like "Innodb_buffer_pool_pages_total";
|
||||
Variable_name Value
|
||||
-Innodb_buffer_pool_pages_total 512
|
||||
+Innodb_buffer_pool_pages_total 51_
|
||||
show status like "Innodb_page_size";
|
||||
Variable_name Value
|
||||
Innodb_page_size 16384
|
62
mysql-test/patches/innodb-index.diff
Normal file
62
mysql-test/patches/innodb-index.diff
Normal file
|
@ -0,0 +1,62 @@
|
|||
This part of the innodb-index test causes mysqld to print some warnings
|
||||
and subsequently the whole mysql-test suite to fail.
|
||||
|
||||
A permanent solution is probably to remove the printouts from the source
|
||||
code or to somehow tell the mysql-test suite that warnings are expected.
|
||||
Currently we simply do not execute the problematic tests. Please
|
||||
coordinate a permanent solution with Marko, who added those tests.
|
||||
|
||||
This cannot be proposed to MySQL because it touches files that are not
|
||||
in the MySQL source repository.
|
||||
|
||||
Index: storage/innobase/mysql-test/innodb-index.result
|
||||
===================================================================
|
||||
--- storage/innobase/mysql-test/innodb-index.result (revision 2229)
|
||||
+++ storage/innobase/mysql-test/innodb-index.result (working copy)
|
||||
@@ -43,19 +43,12 @@ t1 CREATE TABLE `t1` (
|
||||
`b` int(11) DEFAULT NULL,
|
||||
`c` char(10) NOT NULL,
|
||||
`d` varchar(20) DEFAULT NULL,
|
||||
KEY `d2` (`d`),
|
||||
KEY `b` (`b`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
-CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-ERROR HY000: Table 'test.t1#1' already exists
|
||||
-rename table `t1#1` to `t1#2`;
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-ERROR HY000: Table 'test.t1#2' already exists
|
||||
-drop table `t1#2`;
|
||||
alter table t1 add unique index (c), add index (d);
|
||||
show create table t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`a` int(11) NOT NULL,
|
||||
`b` int(11) DEFAULT NULL,
|
||||
Index: storage/innobase/mysql-test/innodb-index.test
|
||||
===================================================================
|
||||
--- storage/innobase/mysql-test/innodb-index.test (revision 2229)
|
||||
+++ storage/innobase/mysql-test/innodb-index.test (working copy)
|
||||
@@ -14,22 +14,12 @@ select * from t1 force index (d2) order
|
||||
--error ER_DUP_ENTRY
|
||||
alter table t1 add unique index (b);
|
||||
show create table t1;
|
||||
alter table t1 add index (b);
|
||||
show create table t1;
|
||||
|
||||
-# Check how existing tables interfere with temporary tables.
|
||||
-CREATE TABLE `t1#1`(a INT PRIMARY KEY) ENGINE=InnoDB;
|
||||
-
|
||||
---error 156
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-rename table `t1#1` to `t1#2`;
|
||||
---error 156
|
||||
-alter table t1 add unique index (c), add index (d);
|
||||
-drop table `t1#2`;
|
||||
-
|
||||
alter table t1 add unique index (c), add index (d);
|
||||
show create table t1;
|
||||
explain select * from t1 force index(c) order by c;
|
||||
--error ER_REQUIRES_PRIMARY_KEY
|
||||
drop index c on t1;
|
||||
alter table t1 add primary key (a), drop index c;
|
32
os/os0file.c
32
os/os0file.c
|
@ -1241,9 +1241,19 @@ try_again:
|
|||
if (file == INVALID_HANDLE_VALUE) {
|
||||
*success = FALSE;
|
||||
|
||||
retry = os_file_handle_error(name,
|
||||
create_mode == OS_FILE_CREATE ?
|
||||
"create" : "open");
|
||||
/* When srv_file_per_table is on, file creation failure may not
|
||||
be critical to the whole instance. Do not crash the server in
|
||||
case of unknown errors. */
|
||||
if (srv_file_per_table) {
|
||||
retry = os_file_handle_error_no_exit(name,
|
||||
create_mode == OS_FILE_CREATE ?
|
||||
"create" : "open");
|
||||
} else {
|
||||
retry = os_file_handle_error(name,
|
||||
create_mode == OS_FILE_CREATE ?
|
||||
"create" : "open");
|
||||
}
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
}
|
||||
|
@ -1318,9 +1328,19 @@ try_again:
|
|||
if (file == -1) {
|
||||
*success = FALSE;
|
||||
|
||||
retry = os_file_handle_error(name,
|
||||
create_mode == OS_FILE_CREATE ?
|
||||
"create" : "open");
|
||||
/* When srv_file_per_table is on, file creation failure may not
|
||||
be critical to the whole instance. Do not crash the server in
|
||||
case of unknown errors. */
|
||||
if (srv_file_per_table) {
|
||||
retry = os_file_handle_error_no_exit(name,
|
||||
create_mode == OS_FILE_CREATE ?
|
||||
"create" : "open");
|
||||
} else {
|
||||
retry = os_file_handle_error(name,
|
||||
create_mode == OS_FILE_CREATE ?
|
||||
"create" : "open");
|
||||
}
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
} else {
|
||||
|
|
|
@ -726,7 +726,7 @@ os_fast_mutex_free(
|
|||
|
||||
ret = pthread_mutex_destroy(fast_mutex);
|
||||
|
||||
if (ret != 0) {
|
||||
if (UNIV_UNLIKELY(ret != 0)) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
" InnoDB: error: return value %lu when calling\n"
|
||||
|
@ -735,7 +735,7 @@ os_fast_mutex_free(
|
|||
"InnoDB: Byte contents of the pthread mutex at %p:\n",
|
||||
(void*) fast_mutex);
|
||||
ut_print_buf(stderr, fast_mutex, sizeof(os_fast_mutex_t));
|
||||
fprintf(stderr, "\n");
|
||||
putc('\n', stderr);
|
||||
}
|
||||
#endif
|
||||
if (UNIV_LIKELY(os_sync_mutex_inited)) {
|
||||
|
|
|
@ -848,6 +848,7 @@ page_cur_parse_insert_rec(
|
|||
|
||||
fputs("Dump of 300 bytes of log:\n", stderr);
|
||||
ut_print_buf(stderr, ptr2, 300);
|
||||
putc('\n', stderr);
|
||||
|
||||
buf_page_print(page, 0);
|
||||
|
||||
|
|
|
@ -598,6 +598,8 @@ page_copy_rec_list_end(
|
|||
ut_ad(buf_block_get_frame(block) == page);
|
||||
ut_ad(page_is_leaf(page) == page_is_leaf(new_page));
|
||||
ut_ad(page_is_comp(page) == page_is_comp(new_page));
|
||||
/* Here, "ret" may be pointing to a user record or the
|
||||
predefined supremum record. */
|
||||
|
||||
if (UNIV_LIKELY_NULL(new_page_zip)) {
|
||||
log_mode = mtr_set_log_mode(mtr, MTR_LOG_NONE);
|
||||
|
@ -620,6 +622,12 @@ page_copy_rec_list_end(
|
|||
store the number of preceding records on the page. */
|
||||
ulint ret_pos
|
||||
= page_rec_get_n_recs_before(ret);
|
||||
/* Before copying, "ret" was the successor of
|
||||
the predefined infimum record. It must still
|
||||
have at least one predecessor (the predefined
|
||||
infimum record, or a freshly copied record
|
||||
that is smaller than "ret"). */
|
||||
ut_a(ret_pos > 0);
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
(!page_zip_reorganize(new_block, index, mtr))) {
|
||||
|
@ -685,6 +693,9 @@ page_copy_rec_list_start(
|
|||
ulint* offsets = offsets_;
|
||||
rec_offs_init(offsets_);
|
||||
|
||||
/* Here, "ret" may be pointing to a user record or the
|
||||
predefined infimum record. */
|
||||
|
||||
if (page_rec_is_infimum(rec)) {
|
||||
|
||||
return(ret);
|
||||
|
@ -725,6 +736,11 @@ page_copy_rec_list_start(
|
|||
store the number of preceding records on the page. */
|
||||
ulint ret_pos
|
||||
= page_rec_get_n_recs_before(ret);
|
||||
/* Before copying, "ret" was the predecessor
|
||||
of the predefined supremum record. If it was
|
||||
the predefined infimum record, then it would
|
||||
still be the infimum. Thus, the assertion
|
||||
ut_a(ret_pos > 0) would fail here. */
|
||||
|
||||
if (UNIV_UNLIKELY
|
||||
(!page_zip_reorganize(new_block, index, mtr))) {
|
||||
|
|
|
@ -3203,7 +3203,15 @@ page_zip_write_rec(
|
|||
ulint heap_no;
|
||||
byte* slot;
|
||||
|
||||
#if 0
|
||||
/* In btr_cur_pessimistic_insert(), we allocate temp_page
|
||||
from the buffer pool to see if a record fits on a compressed
|
||||
page by itself. The buf_block_align() call in
|
||||
buf_frame_get_page_zip() only works for file pages, not
|
||||
temporarily allocated blocks. Thus, we must unfortunately
|
||||
disable the following assertion. */
|
||||
ut_ad(buf_frame_get_page_zip(rec) == page_zip);
|
||||
#endif
|
||||
ut_ad(page_zip_simple_validate(page_zip));
|
||||
ut_ad(page_zip_get_size(page_zip)
|
||||
> PAGE_DATA + page_zip_dir_size(page_zip));
|
||||
|
|
|
@ -144,7 +144,8 @@ row_purge_remove_clust_if_poss_low(
|
|||
success = btr_cur_optimistic_delete(btr_cur, &mtr);
|
||||
} else {
|
||||
ut_ad(mode == BTR_MODIFY_TREE);
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, FALSE, &mtr);
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
||||
RB_NONE, &mtr);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
success = TRUE;
|
||||
|
@ -266,14 +267,9 @@ row_purge_remove_sec_if_poss_low_nonbuffered(
|
|||
} else {
|
||||
ut_ad(mode == BTR_MODIFY_TREE);
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
||||
FALSE, &mtr);
|
||||
if (err == DB_SUCCESS) {
|
||||
success = TRUE;
|
||||
} else if (err == DB_OUT_OF_FILE_SPACE) {
|
||||
success = FALSE;
|
||||
} else {
|
||||
ut_error;
|
||||
}
|
||||
RB_NONE, &mtr);
|
||||
success = err == DB_SUCCESS;
|
||||
ut_a(success || err == DB_OUT_OF_FILE_SPACE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +571,7 @@ skip_secondaries:
|
|||
index,
|
||||
data_field + dfield_get_len(&ufield->new_val)
|
||||
- BTR_EXTERN_FIELD_REF_SIZE,
|
||||
NULL, NULL, NULL, 0, FALSE, &mtr);
|
||||
NULL, NULL, NULL, 0, RB_NONE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
}
|
||||
|
@ -676,8 +672,10 @@ err_exit:
|
|||
/* Read to the partial row the fields that occur in indexes */
|
||||
|
||||
if (!(cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
|
||||
ptr = trx_undo_rec_get_partial_row(ptr, clust_index,
|
||||
&node->row, node->heap);
|
||||
ptr = trx_undo_rec_get_partial_row(
|
||||
ptr, clust_index, &node->row,
|
||||
type == TRX_UNDO_UPD_DEL_REC,
|
||||
node->heap);
|
||||
}
|
||||
|
||||
return(TRUE);
|
||||
|
|
|
@ -97,12 +97,6 @@ row_build_index_entry(
|
|||
} else {
|
||||
dtuple_set_n_fields_cmp(
|
||||
entry, dict_index_get_n_unique_in_tree(index));
|
||||
if (dict_index_is_clust(index)) {
|
||||
/* Do not fetch externally stored columns to
|
||||
the clustered index. Such columns are handled
|
||||
at a higher level. */
|
||||
ext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < entry_len; i++) {
|
||||
|
@ -121,8 +115,15 @@ row_build_index_entry(
|
|||
|
||||
dfield_copy(dfield, dfield2);
|
||||
|
||||
if (dfield_is_null(dfield)) {
|
||||
} else if (UNIV_LIKELY_NULL(ext)) {
|
||||
if (dfield_is_null(dfield) || ind_field->prefix_len == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* If a column prefix index, take only the prefix.
|
||||
Prefix-indexed columns may be externally stored. */
|
||||
ut_ad(col->ord_part);
|
||||
|
||||
if (UNIV_LIKELY_NULL(ext)) {
|
||||
/* See if the column is stored externally. */
|
||||
const byte* buf = row_ext_lookup(ext, col_no,
|
||||
&len);
|
||||
|
@ -139,15 +140,10 @@ row_build_index_entry(
|
|||
|| dict_index_is_clust(index));
|
||||
}
|
||||
|
||||
/* If a column prefix index, take only the prefix */
|
||||
if (ind_field->prefix_len > 0 && !dfield_is_null(dfield)) {
|
||||
ut_ad(col->ord_part);
|
||||
len = dtype_get_at_most_n_mbchars(
|
||||
col->prtype, col->mbminlen, col->mbmaxlen,
|
||||
ind_field->prefix_len,
|
||||
len, dfield_get_data(dfield));
|
||||
dfield_set_len(dfield, len);
|
||||
}
|
||||
len = dtype_get_at_most_n_mbchars(
|
||||
col->prtype, col->mbminlen, col->mbmaxlen,
|
||||
ind_field->prefix_len, len, dfield_get_data(dfield));
|
||||
dfield_set_len(dfield, len);
|
||||
}
|
||||
|
||||
ut_ad(dtuple_check_typed(entry));
|
||||
|
|
|
@ -2173,17 +2173,16 @@ row_fetch_print(
|
|||
fprintf(stderr, " column %lu:\n", (ulong)i);
|
||||
|
||||
dtype_print(type);
|
||||
fprintf(stderr, "\n");
|
||||
putc('\n', stderr);
|
||||
|
||||
if (dfield_get_len(dfield) != UNIV_SQL_NULL) {
|
||||
ut_print_buf(stderr, dfield_get_data(dfield),
|
||||
dfield_get_len(dfield));
|
||||
putc('\n', stderr);
|
||||
} else {
|
||||
fprintf(stderr, " <NULL>;");
|
||||
fputs(" <NULL>;\n", stderr);
|
||||
}
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
|
||||
exp = que_node_get_next(exp);
|
||||
i++;
|
||||
}
|
||||
|
@ -2466,7 +2465,7 @@ row_sel_convert_mysql_key_to_innobase(
|
|||
(ulong) (key_ptr - key_end));
|
||||
fflush(stderr);
|
||||
ut_print_buf(stderr, original_key_ptr, key_len);
|
||||
fprintf(stderr, "\n");
|
||||
putc('\n', stderr);
|
||||
|
||||
if (!is_null) {
|
||||
ulint len = dfield_get_len(dfield);
|
||||
|
|
|
@ -87,7 +87,10 @@ retry:
|
|||
&(node->pcur), &mtr);
|
||||
ut_a(success);
|
||||
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
||||
trx_is_recv(node->trx)
|
||||
? RB_RECOVERY
|
||||
: RB_NORMAL, &mtr);
|
||||
|
||||
/* The delete operation may fail if we have little
|
||||
file space left: TODO: easiest to crash the database
|
||||
|
@ -160,7 +163,14 @@ row_undo_ins_remove_sec_low(
|
|||
} else {
|
||||
ut_ad(mode == BTR_MODIFY_TREE);
|
||||
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, TRUE, &mtr);
|
||||
/* No need to distinguish RB_RECOVERY here, because we
|
||||
are deleting a secondary index record: the distinction
|
||||
between RB_NORMAL and RB_RECOVERY only matters when
|
||||
deleting a record that contains externally stored
|
||||
columns. */
|
||||
ut_ad(!dict_index_is_clust(index));
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
||||
RB_NORMAL, &mtr);
|
||||
}
|
||||
|
||||
btr_pcur_close(&pcur);
|
||||
|
@ -284,12 +294,24 @@ row_undo_ins(
|
|||
|
||||
entry = row_build_index_entry(node->row, node->ext,
|
||||
node->index, node->heap);
|
||||
ut_a(entry);
|
||||
err = row_undo_ins_remove_sec(node->index, entry);
|
||||
if (UNIV_UNLIKELY(!entry)) {
|
||||
/* The database must have crashed after
|
||||
inserting a clustered index record but before
|
||||
writing all the externally stored columns of
|
||||
that record. Because secondary index entries
|
||||
are inserted after the clustered index record,
|
||||
we may assume that the secondary index record
|
||||
does not exist. However, this situation may
|
||||
only occur during the rollback of incomplete
|
||||
transactions. */
|
||||
ut_a(trx_is_recv(node->trx));
|
||||
} else {
|
||||
err = row_undo_ins_remove_sec(node->index, entry);
|
||||
|
||||
if (err != DB_SUCCESS) {
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
return(err);
|
||||
return(err);
|
||||
}
|
||||
}
|
||||
|
||||
node->index = dict_table_get_next_index(node->index);
|
||||
|
|
|
@ -178,9 +178,9 @@ row_undo_mod_remove_clust_low(
|
|||
|
||||
/* Note that since this operation is analogous to purge,
|
||||
we can free also inherited externally stored fields:
|
||||
hence the last FALSE in the call below */
|
||||
hence the RB_NONE in the call below */
|
||||
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, FALSE, mtr);
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur, RB_NONE, mtr);
|
||||
|
||||
/* The delete operation may fail if we have little
|
||||
file space left: TODO: easiest to crash the database
|
||||
|
@ -350,8 +350,14 @@ row_undo_mod_del_mark_or_remove_sec_low(
|
|||
} else {
|
||||
ut_ad(mode == BTR_MODIFY_TREE);
|
||||
|
||||
/* No need to distinguish RB_RECOVERY here, because we
|
||||
are deleting a secondary index record: the distinction
|
||||
between RB_NORMAL and RB_RECOVERY only matters when
|
||||
deleting a record that contains externally stored
|
||||
columns. */
|
||||
ut_ad(!dict_index_is_clust(index));
|
||||
btr_cur_pessimistic_delete(&err, FALSE, btr_cur,
|
||||
TRUE, &mtr);
|
||||
RB_NORMAL, &mtr);
|
||||
|
||||
/* The delete operation may fail if we have little
|
||||
file space left: TODO: easiest to crash the database
|
||||
|
@ -506,7 +512,7 @@ row_undo_mod_upd_del_sec(
|
|||
mem_heap_t* heap;
|
||||
dtuple_t* entry;
|
||||
dict_index_t* index;
|
||||
ulint err;
|
||||
ulint err = DB_SUCCESS;
|
||||
|
||||
heap = mem_heap_create(1024);
|
||||
|
||||
|
@ -515,22 +521,35 @@ row_undo_mod_upd_del_sec(
|
|||
|
||||
entry = row_build_index_entry(node->row, node->ext,
|
||||
index, heap);
|
||||
ut_a(entry);
|
||||
err = row_undo_mod_del_mark_or_remove_sec(node, thr, index,
|
||||
entry);
|
||||
if (err != DB_SUCCESS) {
|
||||
if (UNIV_UNLIKELY(!entry)) {
|
||||
/* The database must have crashed after
|
||||
inserting a clustered index record but before
|
||||
writing all the externally stored columns of
|
||||
that record. Because secondary index entries
|
||||
are inserted after the clustered index record,
|
||||
we may assume that the secondary index record
|
||||
does not exist. However, this situation may
|
||||
only occur during the rollback of incomplete
|
||||
transactions. */
|
||||
ut_a(trx_is_recv(thr_get_trx(thr)));
|
||||
} else {
|
||||
err = row_undo_mod_del_mark_or_remove_sec(
|
||||
node, thr, index, entry);
|
||||
|
||||
mem_heap_free(heap);
|
||||
if (err != DB_SUCCESS) {
|
||||
|
||||
return(err);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mem_heap_empty(heap);
|
||||
|
||||
node->index = dict_table_get_next_index(node->index);
|
||||
}
|
||||
|
||||
mem_heap_free(heap);
|
||||
|
||||
return(DB_SUCCESS);
|
||||
return(err);
|
||||
}
|
||||
|
||||
/***************************************************************
|
||||
|
|
|
@ -163,6 +163,26 @@ row_vers_impl_x_locked_off_kernel(
|
|||
clust_offsets = rec_get_offsets(
|
||||
prev_version, clust_index, NULL,
|
||||
ULINT_UNDEFINED, &heap);
|
||||
|
||||
vers_del = rec_get_deleted_flag(prev_version,
|
||||
comp);
|
||||
prev_trx_id = row_get_rec_trx_id(prev_version,
|
||||
clust_index,
|
||||
clust_offsets);
|
||||
|
||||
/* If the trx_id and prev_trx_id are
|
||||
different and if the prev_version is marked
|
||||
deleted then the prev_trx_id must have
|
||||
already committed for the trx_id to be able to
|
||||
modify the row. Therefore, prev_trx_id cannot
|
||||
hold any implicit lock. */
|
||||
if (0 != ut_dulint_cmp(trx_id, prev_trx_id)
|
||||
&& vers_del) {
|
||||
|
||||
mutex_enter(&kernel_mutex);
|
||||
break;
|
||||
}
|
||||
|
||||
/* The stack of versions is locked by mtr.
|
||||
Thus, it is safe to fetch the prefixes for
|
||||
externally stored columns. */
|
||||
|
@ -206,8 +226,6 @@ row_vers_impl_x_locked_off_kernel(
|
|||
if prev_version would require rec to be in a different
|
||||
state. */
|
||||
|
||||
vers_del = rec_get_deleted_flag(prev_version, comp);
|
||||
|
||||
/* We check if entry and rec are identified in the alphabetical
|
||||
ordering */
|
||||
if (0 == cmp_dtuple_rec(entry, rec, offsets)) {
|
||||
|
@ -243,9 +261,6 @@ row_vers_impl_x_locked_off_kernel(
|
|||
break;
|
||||
}
|
||||
|
||||
prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
|
||||
clust_offsets);
|
||||
|
||||
if (0 != ut_dulint_cmp(trx_id, prev_trx_id)) {
|
||||
/* The versions modified by the trx_id transaction end
|
||||
to prev_version: no implicit x-lock */
|
||||
|
|
|
@ -305,7 +305,7 @@ UNIV_INTERN ibool srv_stats_on_metadata = TRUE;
|
|||
|
||||
/* When estimating number of different key values in an index, sample
|
||||
this many index pages */
|
||||
UNIV_INTERN ulong srv_stats_sample = SRV_STATS_SAMPLE_DEFAULT;
|
||||
UNIV_INTERN ib_uint64_t srv_stats_sample_pages = 8;
|
||||
|
||||
UNIV_INTERN ibool srv_use_doublewrite_buf = TRUE;
|
||||
UNIV_INTERN ibool srv_use_checksums = TRUE;
|
||||
|
@ -1422,8 +1422,11 @@ srv_suspend_mysql_thread(
|
|||
srv_n_lock_wait_count++;
|
||||
srv_n_lock_wait_current_count++;
|
||||
|
||||
ut_usectime(&sec, &ms);
|
||||
start_time = (ib_int64_t)sec * 1000000 + ms;
|
||||
if (ut_usectime(&sec, &ms) == -1) {
|
||||
start_time = -1;
|
||||
} else {
|
||||
start_time = (ib_int64_t) sec * 1000000 + ms;
|
||||
}
|
||||
}
|
||||
/* Wake the lock timeout monitor thread, if it is suspended */
|
||||
|
||||
|
@ -1486,14 +1489,20 @@ srv_suspend_mysql_thread(
|
|||
wait_time = ut_difftime(ut_time(), slot->suspend_time);
|
||||
|
||||
if (thr->lock_state == QUE_THR_LOCK_ROW) {
|
||||
ut_usectime(&sec, &ms);
|
||||
finish_time = (ib_int64_t)sec * 1000000 + ms;
|
||||
if (ut_usectime(&sec, &ms) == -1) {
|
||||
finish_time = -1;
|
||||
} else {
|
||||
finish_time = (ib_int64_t) sec * 1000000 + ms;
|
||||
}
|
||||
|
||||
diff_time = (ulint) (finish_time - start_time);
|
||||
|
||||
srv_n_lock_wait_current_count--;
|
||||
srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
|
||||
if (diff_time > srv_n_lock_max_wait_time) {
|
||||
if (diff_time > srv_n_lock_max_wait_time &&
|
||||
/* only update the variable if we successfully
|
||||
retrieved the start and finish times. See Bug#36819. */
|
||||
start_time != -1 && finish_time != -1) {
|
||||
srv_n_lock_max_wait_time = diff_time;
|
||||
}
|
||||
}
|
||||
|
@ -1796,8 +1805,10 @@ srv_export_innodb_status(void)
|
|||
= UT_LIST_GET_LEN(buf_pool->flush_list);
|
||||
export_vars.innodb_buffer_pool_pages_free
|
||||
= UT_LIST_GET_LEN(buf_pool->free);
|
||||
#ifdef UNIV_DEBUG
|
||||
export_vars.innodb_buffer_pool_pages_latched
|
||||
= buf_get_latched_pages_number();
|
||||
#endif /* UNIV_DEBUG */
|
||||
export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
|
||||
|
||||
export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
|
||||
|
|
|
@ -200,13 +200,13 @@ srv_parse_data_file_paths_and_sizes(
|
|||
|
||||
str = srv_parse_megabytes(str, &size);
|
||||
|
||||
if (0 == memcmp(str, ":autoextend",
|
||||
(sizeof ":autoextend") - 1)) {
|
||||
if (0 == strncmp(str, ":autoextend",
|
||||
(sizeof ":autoextend") - 1)) {
|
||||
|
||||
str += (sizeof ":autoextend") - 1;
|
||||
|
||||
if (0 == memcmp(str, ":max:",
|
||||
(sizeof ":max:") - 1)) {
|
||||
if (0 == strncmp(str, ":max:",
|
||||
(sizeof ":max:") - 1)) {
|
||||
|
||||
str += (sizeof ":max:") - 1;
|
||||
|
||||
|
@ -288,14 +288,15 @@ srv_parse_data_file_paths_and_sizes(
|
|||
(*data_file_names)[i] = path;
|
||||
(*data_file_sizes)[i] = size;
|
||||
|
||||
if (0 == memcmp(str, ":autoextend",
|
||||
(sizeof ":autoextend") - 1)) {
|
||||
if (0 == strncmp(str, ":autoextend",
|
||||
(sizeof ":autoextend") - 1)) {
|
||||
|
||||
*is_auto_extending = TRUE;
|
||||
|
||||
str += (sizeof ":autoextend") - 1;
|
||||
|
||||
if (0 == memcmp(str, ":max:", (sizeof ":max:") - 1)) {
|
||||
if (0 == strncmp(str, ":max:",
|
||||
(sizeof ":max:") - 1)) {
|
||||
|
||||
str += (sizeof ":max:") - 1;
|
||||
|
||||
|
@ -1236,6 +1237,19 @@ innobase_start_or_create_for_mysql(void)
|
|||
return(DB_ERROR);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* We have observed deadlocks with a 5MB buffer pool but
|
||||
the actual lower limit could very well be a little higher. */
|
||||
|
||||
if (srv_buf_pool_size <= 5 * 1024 * 1024) {
|
||||
|
||||
fprintf(stderr, "InnoDB: Warning: Small buffer pool size "
|
||||
"(%luM), the flst_validate() debug function "
|
||||
"can cause a deadlock if the buffer pool fills up.\n",
|
||||
srv_buf_pool_size / 1024 / 1024);
|
||||
}
|
||||
#endif
|
||||
|
||||
fsp_init();
|
||||
log_init();
|
||||
|
||||
|
@ -1448,7 +1462,17 @@ innobase_start_or_create_for_mysql(void)
|
|||
} else {
|
||||
|
||||
/* Check if we support the max format that is stamped
|
||||
on the system tablespace. */
|
||||
on the system tablespace.
|
||||
Note: We are NOT allowed to make any modifications to
|
||||
the TRX_SYS_PAGE_NO page before recovery because this
|
||||
page also contains the max_trx_id etc. important system
|
||||
variables that are required for recovery. We need to
|
||||
ensure that we return the system to a state where normal
|
||||
recovery is guaranteed to work. We do this by
|
||||
invalidating the buffer cache, this will force the
|
||||
reread of the page and restoration to it's last known
|
||||
consistent state, this is REQUIRED for the recovery
|
||||
process to work. */
|
||||
err = trx_sys_file_format_max_check(
|
||||
srv_check_file_format_at_startup);
|
||||
|
||||
|
@ -1456,6 +1480,13 @@ innobase_start_or_create_for_mysql(void)
|
|||
return(err);
|
||||
}
|
||||
|
||||
/* Invalidate the buffer pool to ensure that we reread
|
||||
the page that we read above, during recovery.
|
||||
Note that this is not as heavy weight as it seems. At
|
||||
this point there will be only ONE page in the buf_LRU
|
||||
and there must be no page in the buf_flush list. */
|
||||
buf_pool_invalidate();
|
||||
|
||||
/* We always try to do a recovery, even if the database had
|
||||
been shut down normally: this is the normal startup path */
|
||||
|
||||
|
@ -1512,6 +1543,13 @@ innobase_start_or_create_for_mysql(void)
|
|||
are initialized in trx_sys_init_at_db_start(). */
|
||||
|
||||
recv_recovery_from_checkpoint_finish();
|
||||
|
||||
/* It is possible that file_format tag has never
|
||||
been set. In this case we initialize it to minimum
|
||||
value. Important to note that we can do it ONLY after
|
||||
we have finished the recovery process so that the
|
||||
image of TRX_SYS_PAGE_NO is not stale. */
|
||||
trx_sys_file_format_tag_init();
|
||||
}
|
||||
|
||||
if (!create_new_db && sum_of_new_sizes > 0) {
|
||||
|
|
|
@ -1089,6 +1089,9 @@ sync_thread_add_level(
|
|||
|| sync_thread_levels_g(array, SYNC_REC_LOCK));
|
||||
break;
|
||||
case SYNC_IBUF_BITMAP:
|
||||
/* Either the thread must own the master mutex to all
|
||||
the bitmap pages, or it is allowed to latch only ONE
|
||||
bitmap page. */
|
||||
ut_a((sync_thread_levels_contain(array, SYNC_IBUF_BITMAP_MUTEX)
|
||||
&& sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1))
|
||||
|| sync_thread_levels_g(array, SYNC_IBUF_BITMAP));
|
||||
|
|
|
@ -391,7 +391,15 @@ fill_trx_row(
|
|||
|
||||
row->trx_weight = (ullint) ut_conv_dulint_to_longlong(TRX_WEIGHT(trx));
|
||||
|
||||
row->trx_mysql_thread_id = ib_thd_get_thread_id(trx->mysql_thd);
|
||||
if (trx->mysql_thd != NULL) {
|
||||
row->trx_mysql_thread_id
|
||||
= ib_thd_get_thread_id(trx->mysql_thd);
|
||||
} else {
|
||||
/* For internal transactions e.g., purge and transactions
|
||||
being recovered at startup there is no associated MySQL
|
||||
thread data structure. */
|
||||
row->trx_mysql_thread_id = 0;
|
||||
}
|
||||
|
||||
if (trx->mysql_query_str != NULL && *trx->mysql_query_str != NULL) {
|
||||
|
||||
|
|
|
@ -533,6 +533,8 @@ trx_undo_page_report_modify(
|
|||
ulint type_cmpl;
|
||||
byte* type_cmpl_ptr;
|
||||
ulint i;
|
||||
dulint trx_id;
|
||||
ibool ignore_prefix = FALSE;
|
||||
byte ext_buf[REC_MAX_INDEX_COL_LEN
|
||||
+ BTR_EXTERN_FIELD_REF_SIZE];
|
||||
|
||||
|
@ -565,6 +567,11 @@ trx_undo_page_report_modify(
|
|||
type_cmpl = TRX_UNDO_DEL_MARK_REC;
|
||||
} else if (rec_get_deleted_flag(rec, dict_table_is_comp(table))) {
|
||||
type_cmpl = TRX_UNDO_UPD_DEL_REC;
|
||||
/* We are about to update a delete marked record.
|
||||
We don't typically need the prefix in this case unless
|
||||
the delete marking is done by the same transaction
|
||||
(which we check below). */
|
||||
ignore_prefix = TRUE;
|
||||
} else {
|
||||
type_cmpl = TRX_UNDO_UPD_EXIST_REC;
|
||||
}
|
||||
|
@ -588,7 +595,16 @@ trx_undo_page_report_modify(
|
|||
index, DATA_TRX_ID), &flen);
|
||||
ut_ad(flen == DATA_TRX_ID_LEN);
|
||||
|
||||
ptr += mach_dulint_write_compressed(ptr, trx_read_trx_id(field));
|
||||
trx_id = trx_read_trx_id(field);
|
||||
|
||||
/* If it is an update of a delete marked record, then we are
|
||||
allowed to ignore blob prefixes if the delete marking was done
|
||||
by some other trx as it must have committed by now for us to
|
||||
allow an over-write. */
|
||||
if (ignore_prefix) {
|
||||
ignore_prefix = ut_dulint_cmp(trx_id, trx->id) != 0;
|
||||
}
|
||||
ptr += mach_dulint_write_compressed(ptr, trx_id);
|
||||
|
||||
field = rec_get_nth_field(rec, offsets,
|
||||
dict_index_get_sys_col_pos(
|
||||
|
@ -663,6 +679,7 @@ trx_undo_page_report_modify(
|
|||
ptr,
|
||||
dict_index_get_nth_col(index, pos)
|
||||
->ord_part
|
||||
&& !ignore_prefix
|
||||
&& flen < REC_MAX_INDEX_COL_LEN
|
||||
? ext_buf : NULL,
|
||||
dict_table_zip_size(table),
|
||||
|
@ -746,6 +763,7 @@ trx_undo_page_report_modify(
|
|||
ptr = trx_undo_page_report_modify_ext(
|
||||
ptr,
|
||||
flen < REC_MAX_INDEX_COL_LEN
|
||||
&& !ignore_prefix
|
||||
? ext_buf : NULL,
|
||||
dict_table_zip_size(table),
|
||||
&field, &flen);
|
||||
|
@ -996,6 +1014,9 @@ trx_undo_rec_get_partial_row(
|
|||
record! */
|
||||
dict_index_t* index, /* in: clustered index */
|
||||
dtuple_t** row, /* out, own: partial row */
|
||||
ibool ignore_prefix, /* in: flag to indicate if we
|
||||
expect blob prefixes in undo. Used
|
||||
only in the assertion. */
|
||||
mem_heap_t* heap) /* in: memory heap from which the memory
|
||||
needed is allocated */
|
||||
{
|
||||
|
@ -1045,7 +1066,8 @@ trx_undo_rec_get_partial_row(
|
|||
/* If the prefix of this column is indexed,
|
||||
ensure that enough prefix is stored in the
|
||||
undo log record. */
|
||||
ut_a(!col->ord_part
|
||||
ut_a(ignore_prefix
|
||||
|| !col->ord_part
|
||||
|| dfield_get_len(dfield)
|
||||
>= REC_MAX_INDEX_COL_LEN
|
||||
+ BTR_EXTERN_FIELD_REF_SIZE);
|
||||
|
|
|
@ -373,6 +373,21 @@ trx_release_savepoint_for_mysql(
|
|||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Determines if this transaction is rolling back an incomplete transaction
|
||||
in crash recovery. */
|
||||
UNIV_INTERN
|
||||
ibool
|
||||
trx_is_recv(
|
||||
/*========*/
|
||||
/* out: TRUE if trx is an incomplete
|
||||
transaction that is being rolled back
|
||||
in crash recovery */
|
||||
const trx_t* trx) /* in: transaction */
|
||||
{
|
||||
return(trx == trx_roll_crash_recv_trx);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Returns a transaction savepoint taken at this point in time. */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -1106,7 +1106,8 @@ static
|
|||
ulint
|
||||
trx_sys_file_format_max_read(void)
|
||||
/*==============================*/
|
||||
/* out: the file format */
|
||||
/* out: the file format or
|
||||
ULINT_UNDEFINED if not set. */
|
||||
{
|
||||
mtr_t mtr;
|
||||
const byte* ptr;
|
||||
|
@ -1131,10 +1132,8 @@ trx_sys_file_format_max_read(void)
|
|||
if (file_format_id.high != TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_HIGH
|
||||
|| format_id >= FILE_FORMAT_NAME_N) {
|
||||
|
||||
/* Either it has never been tagged, or garbage in it.
|
||||
Reset the tag in either case. */
|
||||
format_id = DICT_TF_FORMAT_51;
|
||||
trx_sys_file_format_max_write(format_id, NULL);
|
||||
/* Either it has never been tagged, or garbage in it. */
|
||||
return(ULINT_UNDEFINED);
|
||||
}
|
||||
|
||||
return(format_id);
|
||||
|
@ -1170,6 +1169,11 @@ trx_sys_file_format_max_check(
|
|||
recover if the file format is not supported by the engine
|
||||
unless forced by the user. */
|
||||
format_id = trx_sys_file_format_max_read();
|
||||
if (format_id == ULINT_UNDEFINED) {
|
||||
/* Format ID was not set. Set it to minimum possible
|
||||
value. */
|
||||
format_id = DICT_TF_FORMAT_51;
|
||||
}
|
||||
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
|
@ -1212,11 +1216,11 @@ trx_sys_file_format_max_set(
|
|||
/*========================*/
|
||||
/* out: TRUE if value updated */
|
||||
ulint format_id, /* in: file format id */
|
||||
char** name) /* out: max file format name */
|
||||
char** name) /* out: max file format name or
|
||||
NULL if not needed. */
|
||||
{
|
||||
ibool ret = FALSE;
|
||||
|
||||
ut_a(name);
|
||||
ut_a(format_id <= DICT_TF_FORMAT_MAX);
|
||||
|
||||
mutex_enter(&file_format_max.mutex);
|
||||
|
@ -1232,6 +1236,26 @@ trx_sys_file_format_max_set(
|
|||
return(ret);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Tags the system table space with minimum format id if it has not been
|
||||
tagged yet.
|
||||
WARNING: This function is only called during the startup and AFTER the
|
||||
redo log application during recovery has finished. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
trx_sys_file_format_tag_init(void)
|
||||
/*==============================*/
|
||||
{
|
||||
ulint format_id;
|
||||
|
||||
format_id = trx_sys_file_format_max_read();
|
||||
|
||||
/* If format_id is not set then set it to the minimum. */
|
||||
if (format_id == ULINT_UNDEFINED) {
|
||||
trx_sys_file_format_max_set(DICT_TF_FORMAT_51, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Update the file format tag in the tablespace only if the given format id
|
||||
is greater than the known max id. */
|
||||
|
|
|
@ -264,6 +264,7 @@ trx_free(
|
|||
trx_print(stderr, trx, 600);
|
||||
|
||||
ut_print_buf(stderr, trx, sizeof(trx_t));
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
ut_a(trx->magic_n == TRX_MAGIC_N);
|
||||
|
@ -805,6 +806,20 @@ trx_commit_off_kernel(
|
|||
trx->conc_state = TRX_COMMITTED_IN_MEMORY;
|
||||
/*--------------------------------------*/
|
||||
|
||||
/* If we release kernel_mutex below and we are still doing
|
||||
recovery i.e.: back ground rollback thread is still active
|
||||
then there is a chance that the rollback thread may see
|
||||
this trx as COMMITTED_IN_MEMORY and goes adhead to clean it
|
||||
up calling trx_cleanup_at_db_startup(). This can happen
|
||||
in the case we are committing a trx here that is left in
|
||||
PREPARED state during the crash. Note that commit of the
|
||||
rollback of a PREPARED trx happens in the recovery thread
|
||||
while the rollback of other transactions happen in the
|
||||
background thread. To avoid this race we unconditionally
|
||||
unset the is_recovered flag from the trx. */
|
||||
|
||||
trx->is_recovered = FALSE;
|
||||
|
||||
lock_release_off_kernel(trx);
|
||||
|
||||
if (trx->global_read_view) {
|
||||
|
|
|
@ -1708,7 +1708,7 @@ trx_undo_assign_undo(
|
|||
/*=================*/
|
||||
/* out: DB_SUCCESS if undo log assign
|
||||
successful, possible error codes are:
|
||||
DD_TOO_MANY_CONCURRENT_TRXS
|
||||
DB_TOO_MANY_CONCURRENT_TRXS
|
||||
DB_OUT_OF_FILE_SPACE DB_OUT_OF_MEMORY*/
|
||||
trx_t* trx, /* in: transaction */
|
||||
ulint type) /* in: TRX_UNDO_INSERT or TRX_UNDO_UPDATE */
|
||||
|
|
36
ut/ut0ut.c
36
ut/ut0ut.c
|
@ -105,19 +105,45 @@ ut_time(void)
|
|||
}
|
||||
|
||||
/**************************************************************
|
||||
Returns system time. */
|
||||
Returns system time.
|
||||
Upon successful completion, the value 0 is returned; otherwise the
|
||||
value -1 is returned and the global variable errno is set to indicate the
|
||||
error. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
int
|
||||
ut_usectime(
|
||||
/*========*/
|
||||
/* out: 0 on success, -1 otherwise */
|
||||
ulint* sec, /* out: seconds since the Epoch */
|
||||
ulint* ms) /* out: microseconds since the Epoch+*sec */
|
||||
{
|
||||
struct timeval tv;
|
||||
int ret;
|
||||
int errno_gettimeofday;
|
||||
int i;
|
||||
|
||||
ut_gettimeofday(&tv, NULL);
|
||||
*sec = (ulint) tv.tv_sec;
|
||||
*ms = (ulint) tv.tv_usec;
|
||||
for (i = 0; i < 10; i++) {
|
||||
|
||||
ret = ut_gettimeofday(&tv, NULL);
|
||||
|
||||
if (ret == -1) {
|
||||
errno_gettimeofday = errno;
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: gettimeofday(): %s\n",
|
||||
strerror(errno_gettimeofday));
|
||||
os_thread_sleep(100000); /* 0.1 sec */
|
||||
errno = errno_gettimeofday;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret != -1) {
|
||||
*sec = (ulint) tv.tv_sec;
|
||||
*ms = (ulint) tv.tv_usec;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
|
|
Loading…
Add table
Reference in a new issue