mirror of
https://github.com/MariaDB/server.git
synced 2025-01-31 11:01:52 +01:00
branches/innodb+: Merge 2579:2637 from branches/zip.
This commit is contained in:
parent
f208759f13
commit
8638150c6c
38 changed files with 1169 additions and 406 deletions
175
ChangeLog
175
ChangeLog
|
@ -1,3 +1,178 @@
|
|||
2008-09-17 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, data/data0data.c, include/page0zip.h,
|
||||
include/page0zip.ic, page/page0zip.c,
|
||||
mysql-test/innodb_bug36172.test:
|
||||
Prevent infinite B-tree page splits in compressed tables by
|
||||
ensuring that there will always be enough space for two node
|
||||
pointer records in an empty B-tree page. Also, require that at
|
||||
least one data record will fit in an empty compressed page. This
|
||||
will reduce the maximum size of records in compressed tables.
|
||||
This was reported as Mantis issue #73.
|
||||
|
||||
2008-09-09 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb.result:
|
||||
Fix the failing innodb test by merging changes that MySQL made to
|
||||
that file (r2646.12.1 in MySQL BZR repository)
|
||||
|
||||
2008-09-09 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
|
||||
mysql-test/innodb-autoinc.test:
|
||||
Fix Bug#38839 auto increment does not work properly with InnoDB after
|
||||
update
|
||||
|
||||
2008-09-09 The InnoDB Team
|
||||
|
||||
* dict/dict0dict.c, handler/handler0alter.cc, include/dict0dict.h,
|
||||
mysql-test/innodb-index.result, mysql-test/innodb-index.test:
|
||||
Fix Bug#38786 InnoDB plugin crashes on drop table/create table with FK
|
||||
|
||||
2008-08-21 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, include/ha_prototypes.h, row/row0sel.c:
|
||||
Fix Bug#37885 row_search_for_mysql may gap lock unnecessarily with SQL
|
||||
comments in query
|
||||
|
||||
2008-08-21 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Fix Bug#38185 ha_innobase::info can hold locks even when called with
|
||||
HA_STATUS_NO_LOCK
|
||||
|
||||
2008-08-18 The InnoDB Team
|
||||
|
||||
* buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.ic, include/univ.i:
|
||||
Introduce UNIV_LRU_DEBUG for debugging the LRU buffer pool cache
|
||||
|
||||
2008-08-08 The InnoDB Team
|
||||
|
||||
* buf/buf0lru.c, include/buf0buf.h:
|
||||
Fix two recovery bugs that could lead to a crash in debug builds with
|
||||
small buffer size
|
||||
|
||||
2008-08-07 The InnoDB Team
|
||||
|
||||
* btr/btr0cur.c, handler/ha_innodb.cc, include/srv0srv.h,
|
||||
srv/srv0srv.c:
|
||||
Add a parameter innodb_stats_sample_pages to allow users to control
|
||||
the number of index dives when InnoDB estimates the cardinality of
|
||||
an index (ANALYZE TABLE, SHOW TABLE STATUS etc)
|
||||
|
||||
2008-08-07 The InnoDB Team
|
||||
|
||||
* trx/trx0i_s.c:
|
||||
Fix a bug that would lead to a crash if a SELECT was issued from the
|
||||
INFORMATION_SCHEMA tables and there are rolling back transactions at
|
||||
the same time
|
||||
|
||||
2008-08-06 The InnoDB Team
|
||||
|
||||
* btr/btr0btr.c, btr/btr0cur.c, ibuf/ibuf0ibuf.c, include/btr0cur.h,
|
||||
include/trx0roll.h, include/trx0types.h, row/row0purge.c,
|
||||
row/row0uins.c, row/row0umod.c, trx/trx0roll.c:
|
||||
In the rollback of incomplete transactions after crash recovery,
|
||||
tolerate clustered index records whose externally stored columns
|
||||
have not been written.
|
||||
|
||||
2008-07-30 The InnoDB Team
|
||||
|
||||
* trx/trx0trx.c:
|
||||
Fixes a race in recovery where the recovery thread recovering a
|
||||
PREPARED trx and the background rollback thread can both try
|
||||
to free the trx after its status is set to COMMITTED_IN_MEMORY.
|
||||
|
||||
2008-07-29 The InnoDB Team
|
||||
|
||||
* include/trx0rec.h, row/row0purge.c, row/row0vers.c, trx/trx0rec.c:
|
||||
Fix a BLOB corruption bug
|
||||
|
||||
2008-07-15 The InnoDB Team
|
||||
|
||||
* btr/btr0sea.c, dict/dict0dict.c, include/btr0sea.h:
|
||||
Fixed a timing hole where a thread dropping an index can free the
|
||||
in-memory index struct while another thread is still using that
|
||||
structure to remove entries from adaptive hash index belonging
|
||||
to one of the pages that belongs to the index being dropped.
|
||||
|
||||
2008-07-04 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-index.result:
|
||||
Fix the failing innodb-index test by adjusting the result to a new
|
||||
MySQL behavior (the change occured in BZR-r2667)
|
||||
|
||||
2008-07-03 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test:
|
||||
Remove the negative test cases that produce warnings
|
||||
|
||||
2008-07-02 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-replace.result, mysql-test/innodb-index.test:
|
||||
Disable part of innodb-index test because MySQL changed its behavior
|
||||
and is not calling ::add_index() anymore when adding primary index on
|
||||
non-NULL column
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-replace.result, mysql-test/innodb-replace.test:
|
||||
Fix the failing innodb-replace test by merging changes that MySQL
|
||||
made to that file (r2659 in MySQL BZR repository)
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* lock/lock0lock.c:
|
||||
Fix Bug#36942 Performance problem in lock_get_n_rec_locks (SHOW INNODB
|
||||
STATUS)
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* ha/ha0ha.c:
|
||||
Fix Bug#36941 Performance problem in ha_print_info (SHOW INNODB
|
||||
STATUS)
|
||||
|
||||
2008-07-01 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc, mysql-test/innodb-autoinc.result,
|
||||
mysql-test/innodb-autoinc.test:
|
||||
Fix Bug#37531 After truncate, auto_increment behaves incorrectly for
|
||||
InnoDB
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* handler/ha_innodb.cc:
|
||||
Rewrite the function innodb_plugin_init() to support parameters in
|
||||
different order (in static and dynamic InnoDB) and to support more
|
||||
parameters in the static InnoDB
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* handler/handler0alter.cc:
|
||||
Fix a bug in ::add_index() which set the transaction state to "active"
|
||||
but never restored it to the original value. This bug caused warnings
|
||||
to be printed by the rpl.rpl_ddl mysql-test.
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* mysql-test/patches:
|
||||
Add a directory which contains patches, which need to be applied to
|
||||
MySQL source in order to get some mysql-tests to succeed. The patches
|
||||
cannot be committed in MySQL repository because they are specific to
|
||||
the InnoDB plugin.
|
||||
|
||||
2008-06-19 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb-zip.result, mysql-test/innodb-zip.test,
|
||||
row/row0row.c:
|
||||
Fix an anomaly when updating a record with BLOB prefix
|
||||
|
||||
2008-06-18 The InnoDB Team
|
||||
|
||||
* include/trx0sys.h, srv/srv0start.c, trx/trx0sys.c:
|
||||
Fix a bug in recovery which was a side effect of the file_format_check
|
||||
changes
|
||||
|
||||
2008-06-09 The InnoDB Team
|
||||
|
||||
* mysql-test/innodb.result:
|
||||
|
|
|
@ -78,6 +78,26 @@ make them consecutive on disk if possible. From the other file segment
|
|||
we allocate pages for the non-leaf levels of the tree.
|
||||
*/
|
||||
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
/******************************************************************
|
||||
Checks a file segment header within a B-tree root page. */
|
||||
static
|
||||
ibool
|
||||
btr_root_fseg_validate(
|
||||
/*===================*/
|
||||
/* out: TRUE if valid */
|
||||
const fseg_header_t* seg_header, /* in: segment header */
|
||||
ulint space) /* in: tablespace identifier */
|
||||
{
|
||||
ulint offset = mach_read_from_2(seg_header + FSEG_HDR_OFFSET);
|
||||
|
||||
ut_a(mach_read_from_4(seg_header + FSEG_HDR_SPACE) == space);
|
||||
ut_a(offset >= FIL_PAGE_DATA);
|
||||
ut_a(offset <= UNIV_PAGE_SIZE - FIL_PAGE_DATA_END);
|
||||
return(TRUE);
|
||||
}
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
/******************************************************************
|
||||
Gets the root node of a tree and x-latches it. */
|
||||
static
|
||||
|
@ -100,6 +120,12 @@ btr_root_block_get(
|
|||
block = btr_block_get(space, zip_size, root_page_no, RW_X_LATCH, mtr);
|
||||
ut_a((ibool)!!page_is_comp(buf_block_get_frame(block))
|
||||
== dict_table_is_comp(index->table));
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ buf_block_get_frame(block), space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ buf_block_get_frame(block), space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
return(block);
|
||||
}
|
||||
|
@ -833,6 +859,12 @@ leaf_loop:
|
|||
mtr_start(&mtr);
|
||||
|
||||
root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
/* NOTE: page hash indexes are dropped when a page is freed inside
|
||||
fsp0fsp. */
|
||||
|
@ -849,6 +881,10 @@ top_loop:
|
|||
mtr_start(&mtr);
|
||||
|
||||
root = btr_page_get(space, zip_size, root_page_no, RW_X_LATCH, &mtr);
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
finished = fseg_free_step_not_header(
|
||||
root + PAGE_HEADER + PAGE_BTR_SEG_TOP, &mtr);
|
||||
|
@ -881,6 +917,9 @@ btr_free_root(
|
|||
btr_search_drop_page_hash_index(block);
|
||||
|
||||
header = buf_block_get_frame(block) + PAGE_HEADER + PAGE_BTR_SEG_TOP;
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(header, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
|
||||
while (!fseg_free_step(header, mtr));
|
||||
}
|
||||
|
@ -1117,8 +1156,13 @@ btr_root_raise_and_insert(
|
|||
ut_a(!root_page_zip || page_zip_validate(root_page_zip, root));
|
||||
#endif /* UNIV_ZIP_DEBUG */
|
||||
index = btr_cur_get_index(cursor);
|
||||
|
||||
ut_ad(dict_index_get_page(index) == page_get_page_no(root));
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, dict_index_get_space(index)));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, dict_index_get_space(index)));
|
||||
ut_a(dict_index_get_page(index) == page_get_page_no(root));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
ut_ad(mtr_memo_contains(mtr, dict_index_get_lock(index),
|
||||
MTR_MEMO_X_LOCK));
|
||||
ut_ad(mtr_memo_contains(mtr, root_block, MTR_MEMO_PAGE_X_FIX));
|
||||
|
@ -2664,6 +2708,14 @@ btr_discard_only_page_on_level(
|
|||
== dict_index_get_page(index))) {
|
||||
/* The father is the root page */
|
||||
|
||||
#ifdef UNIV_BTR_DEBUG
|
||||
const page_t* root = buf_block_get_frame(father_block);
|
||||
const ulint space = dict_index_get_space(index);
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_LEAF
|
||||
+ root, space));
|
||||
ut_a(btr_root_fseg_validate(FIL_PAGE_DATA + PAGE_BTR_SEG_TOP
|
||||
+ root, space));
|
||||
#endif /* UNIV_BTR_DEBUG */
|
||||
btr_page_empty(father_block, father_page_zip, mtr, index);
|
||||
|
||||
/* We play safe and reset the free bits for the father */
|
||||
|
|
134
btr/btr0cur.c
134
btr/btr0cur.c
|
@ -969,7 +969,7 @@ btr_cur_open_at_rnd_pos(
|
|||
|
||||
/*****************************************************************
|
||||
Inserts a record if there is enough space, or if enough space can
|
||||
be freed by reorganizing. Differs from _optimistic_insert because
|
||||
be freed by reorganizing. Differs from btr_cur_optimistic_insert because
|
||||
no heuristics is applied to whether it pays to use CPU time for
|
||||
reorganizing the page or not. */
|
||||
static
|
||||
|
@ -1173,7 +1173,8 @@ btr_cur_optimistic_insert(
|
|||
/* Calculate the record size when entry is converted to a record */
|
||||
rec_size = rec_get_converted_size(index, entry, n_ext);
|
||||
|
||||
if (page_zip_rec_needs_ext(rec_size, page_is_comp(page), zip_size)) {
|
||||
if (page_zip_rec_needs_ext(rec_size, page_is_comp(page),
|
||||
dtuple_get_n_fields(entry), zip_size)) {
|
||||
|
||||
/* The record is so big that we have to store some fields
|
||||
externally on separate database pages */
|
||||
|
@ -1187,6 +1188,46 @@ btr_cur_optimistic_insert(
|
|||
rec_size = rec_get_converted_size(index, entry, n_ext);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(zip_size)) {
|
||||
/* Estimate the free space of an empty compressed page.
|
||||
Subtract one byte for the encoded heap_no in the
|
||||
modification log. */
|
||||
ulint free_space_zip = page_zip_empty_size(
|
||||
cursor->index->n_fields, zip_size) - 1;
|
||||
ulint extra;
|
||||
ulint n_uniq = dict_index_get_n_unique_in_tree(index);
|
||||
|
||||
ut_ad(dict_table_is_comp(index->table));
|
||||
|
||||
/* There should be enough room for two node pointer
|
||||
records on an empty non-leaf page. This prevents
|
||||
infinite page splits. */
|
||||
|
||||
if (UNIV_LIKELY(entry->n_fields >= n_uniq)
|
||||
&& UNIV_UNLIKELY(rec_get_converted_size_comp(
|
||||
index, REC_STATUS_NODE_PTR,
|
||||
entry->fields, n_uniq,
|
||||
&extra)
|
||||
/* On a compressed page, there is
|
||||
a two-byte entry in the dense
|
||||
page directory for every record.
|
||||
But there is no record header. */
|
||||
- (REC_N_NEW_EXTRA_BYTES - 2)
|
||||
> free_space_zip / 2)) {
|
||||
|
||||
if (big_rec_vec) {
|
||||
dtuple_convert_back_big_rec(
|
||||
index, entry, big_rec_vec);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
}
|
||||
|
||||
/* If there have been many consecutive inserts, and we are on the leaf
|
||||
level, check if we have to split the page to reserve enough free space
|
||||
for future updates of records. */
|
||||
|
@ -1418,6 +1459,7 @@ btr_cur_pessimistic_insert(
|
|||
|
||||
if (page_zip_rec_needs_ext(rec_get_converted_size(index, entry, n_ext),
|
||||
dict_table_is_comp(index->table),
|
||||
dict_index_get_n_fields(index),
|
||||
zip_size)) {
|
||||
/* The record is so big that we have to store some fields
|
||||
externally on separate database pages */
|
||||
|
@ -1441,45 +1483,6 @@ btr_cur_pessimistic_insert(
|
|||
}
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(zip_size)) {
|
||||
/* Estimate the free space of an empty compressed page. */
|
||||
ulint free_space_zip = page_zip_empty_size(
|
||||
cursor->index->n_fields, zip_size);
|
||||
|
||||
if (UNIV_UNLIKELY(rec_get_converted_size(index, entry, n_ext)
|
||||
> free_space_zip)) {
|
||||
/* Try to insert the record by itself on a new page.
|
||||
If it fails, no amount of splitting will help. */
|
||||
buf_block_t* temp_block
|
||||
= buf_block_alloc(zip_size);
|
||||
page_t* temp_page
|
||||
= page_create_zip(temp_block, index, 0, NULL);
|
||||
page_cur_t temp_cursor;
|
||||
rec_t* temp_rec;
|
||||
|
||||
page_cur_position(temp_page + PAGE_NEW_INFIMUM,
|
||||
temp_block, &temp_cursor);
|
||||
|
||||
temp_rec = page_cur_tuple_insert(&temp_cursor,
|
||||
entry, index,
|
||||
n_ext, NULL);
|
||||
buf_block_free(temp_block);
|
||||
|
||||
if (UNIV_UNLIKELY(!temp_rec)) {
|
||||
if (big_rec_vec) {
|
||||
dtuple_convert_back_big_rec(
|
||||
index, entry, big_rec_vec);
|
||||
}
|
||||
|
||||
if (heap) {
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
return(DB_TOO_BIG_RECORD);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dict_index_get_page(index)
|
||||
== buf_block_get_page_no(btr_cur_get_block(cursor))) {
|
||||
|
||||
|
@ -2289,10 +2292,20 @@ btr_cur_pessimistic_update(
|
|||
offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, heap);
|
||||
n_ext += btr_push_update_extern_fields(new_entry, update, *heap);
|
||||
|
||||
if (page_zip_rec_needs_ext(rec_get_converted_size(index, new_entry,
|
||||
n_ext),
|
||||
page_is_comp(page), page_zip
|
||||
? page_zip_get_size(page_zip) : 0)) {
|
||||
if (UNIV_LIKELY_NULL(page_zip)) {
|
||||
ut_ad(page_is_comp(page));
|
||||
if (page_zip_rec_needs_ext(
|
||||
rec_get_converted_size(index, new_entry, n_ext),
|
||||
TRUE,
|
||||
dict_index_get_n_fields(index),
|
||||
page_zip_get_size(page_zip))) {
|
||||
|
||||
goto make_external;
|
||||
}
|
||||
} else if (page_zip_rec_needs_ext(
|
||||
rec_get_converted_size(index, new_entry, n_ext),
|
||||
page_is_comp(page), 0, 0)) {
|
||||
make_external:
|
||||
big_rec_vec = dtuple_convert_big_rec(index, new_entry, &n_ext);
|
||||
if (UNIV_UNLIKELY(big_rec_vec == NULL)) {
|
||||
|
||||
|
@ -3270,6 +3283,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
ulint matched_fields;
|
||||
ulint matched_bytes;
|
||||
ib_int64_t* n_diff;
|
||||
ullint n_sample_pages; /* number of pages to sample */
|
||||
ulint not_empty_flag = 0;
|
||||
ulint total_external_size = 0;
|
||||
ulint i;
|
||||
|
@ -3288,9 +3302,21 @@ btr_estimate_number_of_different_key_vals(
|
|||
|
||||
n_diff = mem_zalloc((n_cols + 1) * sizeof(ib_int64_t));
|
||||
|
||||
/* It makes no sense to test more pages than are contained
|
||||
in the index, thus we lower the number if it is too high */
|
||||
if (srv_stats_sample_pages > index->stat_index_size) {
|
||||
if (index->stat_index_size > 0) {
|
||||
n_sample_pages = index->stat_index_size;
|
||||
} else {
|
||||
n_sample_pages = 1;
|
||||
}
|
||||
} else {
|
||||
n_sample_pages = srv_stats_sample_pages;
|
||||
}
|
||||
|
||||
/* We sample some pages in the index to get an estimate */
|
||||
|
||||
for (i = 0; i < srv_stats_sample_pages; i++) {
|
||||
for (i = 0; i < n_sample_pages; i++) {
|
||||
rec_t* supremum;
|
||||
mtr_start(&mtr);
|
||||
|
||||
|
@ -3379,7 +3405,7 @@ btr_estimate_number_of_different_key_vals(
|
|||
}
|
||||
|
||||
/* If we saw k borders between different key values on
|
||||
srv_stats_sample_pages leaf pages, we can estimate how many
|
||||
n_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
|
||||
|
@ -3390,26 +3416,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_pages - 1
|
||||
+ n_sample_pages - 1
|
||||
+ total_external_size
|
||||
+ not_empty_flag)
|
||||
/ (srv_stats_sample_pages
|
||||
/ (n_sample_pages
|
||||
+ total_external_size));
|
||||
|
||||
/* If the tree is small, smaller than
|
||||
10 * srv_stats_sample_pages + total_external_size, then
|
||||
10 * n_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_pages
|
||||
we pick. But still there may be n_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_pages
|
||||
/ (10 * (n_sample_pages
|
||||
+ total_external_size));
|
||||
|
||||
if (add_on > srv_stats_sample_pages) {
|
||||
add_on = srv_stats_sample_pages;
|
||||
if (add_on > n_sample_pages) {
|
||||
add_on = n_sample_pages;
|
||||
}
|
||||
|
||||
index->stat_n_diff_key_vals[j] += add_on;
|
||||
|
|
|
@ -971,21 +971,21 @@ btr_search_drop_page_hash_index(
|
|||
for which we know that
|
||||
block->buf_fix_count == 0 */
|
||||
{
|
||||
hash_table_t* table;
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
page_t* page;
|
||||
rec_t* rec;
|
||||
ulint fold;
|
||||
ulint prev_fold;
|
||||
dulint index_id;
|
||||
ulint n_cached;
|
||||
ulint n_recs;
|
||||
ulint* folds;
|
||||
ulint i;
|
||||
mem_heap_t* heap;
|
||||
dict_index_t* index;
|
||||
ulint* offsets;
|
||||
hash_table_t* table;
|
||||
ulint n_fields;
|
||||
ulint n_bytes;
|
||||
const page_t* page;
|
||||
const rec_t* rec;
|
||||
ulint fold;
|
||||
ulint prev_fold;
|
||||
dulint index_id;
|
||||
ulint n_cached;
|
||||
ulint n_recs;
|
||||
ulint* folds;
|
||||
ulint i;
|
||||
mem_heap_t* heap;
|
||||
const dict_index_t* index;
|
||||
ulint* offsets;
|
||||
|
||||
#ifdef UNIV_SYNC_DEBUG
|
||||
ut_ad(!rw_lock_own(&btr_search_latch, RW_LOCK_SHARED));
|
||||
|
@ -1034,7 +1034,7 @@ retry:
|
|||
n_cached = 0;
|
||||
|
||||
rec = page_get_infimum_rec(page);
|
||||
rec = page_rec_get_next(rec);
|
||||
rec = page_rec_get_next_low(rec, page_is_comp(page));
|
||||
|
||||
index_id = btr_page_get_index_id(page);
|
||||
|
||||
|
@ -1062,7 +1062,7 @@ retry:
|
|||
folds[n_cached] = fold;
|
||||
n_cached++;
|
||||
next_rec:
|
||||
rec = page_rec_get_next(rec);
|
||||
rec = page_rec_get_next_low(rec, page_rec_is_comp(rec));
|
||||
prev_fold = fold;
|
||||
}
|
||||
|
||||
|
|
|
@ -1053,6 +1053,14 @@ buf_relocate(
|
|||
|
||||
if (UNIV_UNLIKELY(buf_pool->LRU_old == bpage)) {
|
||||
buf_pool->LRU_old = dpage;
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
}
|
||||
|
||||
ut_d(UT_LIST_VALIDATE(LRU, buf_page_t, buf_pool->LRU));
|
||||
|
|
|
@ -712,7 +712,7 @@ loop:
|
|||
if (n_iterations > 30) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr,
|
||||
"InnoDB: Warning: difficult to find free blocks from\n"
|
||||
" InnoDB: Warning: difficult to find free blocks in\n"
|
||||
"InnoDB: the buffer pool (%lu search iterations)!"
|
||||
" Consider\n"
|
||||
"InnoDB: increasing the buffer pool size.\n"
|
||||
|
@ -790,12 +790,25 @@ buf_LRU_old_adjust_len(void)
|
|||
#if 3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5
|
||||
# error "3 * (BUF_LRU_OLD_MIN_LEN / 8) <= BUF_LRU_OLD_TOLERANCE + 5"
|
||||
#endif
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
for (;;) {
|
||||
old_len = buf_pool->LRU_old_len;
|
||||
new_len = 3 * (UT_LIST_GET_LEN(buf_pool->LRU) / 8);
|
||||
|
||||
ut_ad(buf_pool->LRU_old->in_LRU_list);
|
||||
ut_a(buf_pool->LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
/* Update the LRU_old pointer if necessary */
|
||||
|
||||
|
@ -803,6 +816,9 @@ buf_LRU_old_adjust_len(void)
|
|||
|
||||
buf_pool->LRU_old = UT_LIST_GET_PREV(
|
||||
LRU, buf_pool->LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(!buf_pool->LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
||||
buf_pool->LRU_old_len++;
|
||||
|
||||
|
@ -813,8 +829,6 @@ buf_LRU_old_adjust_len(void)
|
|||
LRU, buf_pool->LRU_old);
|
||||
buf_pool->LRU_old_len--;
|
||||
} else {
|
||||
ut_a(buf_pool->LRU_old); /* Check that we did not
|
||||
fall out of the LRU list */
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -901,6 +915,9 @@ buf_LRU_remove_block(
|
|||
|
||||
buf_pool->LRU_old = UT_LIST_GET_PREV(LRU, bpage);
|
||||
ut_a(buf_pool->LRU_old);
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(!buf_pool->LRU_old->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
buf_page_set_old(buf_pool->LRU_old, TRUE);
|
||||
|
||||
buf_pool->LRU_old_len++;
|
||||
|
@ -974,8 +991,6 @@ buf_LRU_add_block_to_end_low(
|
|||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
|
||||
last_bpage = UT_LIST_GET_LAST(buf_pool->LRU);
|
||||
|
||||
if (last_bpage) {
|
||||
|
@ -988,6 +1003,8 @@ buf_LRU_add_block_to_end_low(
|
|||
UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage);
|
||||
ut_d(bpage->in_LRU_list = TRUE);
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) >= BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
buf_pool->LRU_old_len++;
|
||||
|
@ -1035,8 +1052,6 @@ buf_LRU_add_block_low(
|
|||
ut_a(buf_page_in_file(bpage));
|
||||
ut_ad(!bpage->in_LRU_list);
|
||||
|
||||
buf_page_set_old(bpage, old);
|
||||
|
||||
if (!old || (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN)) {
|
||||
|
||||
UT_LIST_ADD_FIRST(LRU, buf_pool->LRU, bpage);
|
||||
|
@ -1044,6 +1059,15 @@ buf_LRU_add_block_low(
|
|||
bpage->LRU_position = buf_pool_clock_tic();
|
||||
bpage->freed_page_clock = buf_pool->freed_page_clock;
|
||||
} else {
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
/* buf_pool->LRU_old must be the first item in the LRU list
|
||||
whose "old" flag is set. */
|
||||
ut_a(buf_pool->LRU_old->old);
|
||||
ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)
|
||||
|| !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old);
|
||||
ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)
|
||||
|| UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
UT_LIST_INSERT_AFTER(LRU, buf_pool->LRU, buf_pool->LRU_old,
|
||||
bpage);
|
||||
buf_pool->LRU_old_len++;
|
||||
|
@ -1056,6 +1080,8 @@ buf_LRU_add_block_low(
|
|||
|
||||
ut_d(bpage->in_LRU_list = TRUE);
|
||||
|
||||
buf_page_set_old(bpage, old);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
ut_ad(buf_pool->LRU_old);
|
||||
|
@ -1252,6 +1278,15 @@ alloc:
|
|||
|
||||
buf_pool->LRU_old = b;
|
||||
}
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
ut_a(prev_b->old
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)
|
||||
|| UT_LIST_GET_NEXT(LRU, b)->old);
|
||||
} else {
|
||||
ut_a(!prev_b->old
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)
|
||||
|| !UT_LIST_GET_NEXT(LRU, b)->old);
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
}
|
||||
|
||||
lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
|
||||
|
|
|
@ -607,6 +607,7 @@ dtuple_convert_big_rec(
|
|||
while (page_zip_rec_needs_ext(rec_get_converted_size(index, entry,
|
||||
*n_ext),
|
||||
dict_table_is_comp(index->table),
|
||||
dict_index_get_n_fields(index),
|
||||
dict_table_zip_size(index->table))) {
|
||||
ulint i;
|
||||
ulint longest = 0;
|
||||
|
|
|
@ -543,11 +543,7 @@ dict_build_index_def_step(
|
|||
ut_ad((UT_LIST_GET_LEN(table->indexes) > 0)
|
||||
|| dict_index_is_clust(index));
|
||||
|
||||
/* For fast index creation we have already allocated an index id
|
||||
for this index so that we could write an UNDO log record for it.*/
|
||||
if (ut_dulint_is_zero(index->id)) {
|
||||
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
|
||||
}
|
||||
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
|
||||
|
||||
/* Inherit the space id from the table; we store all indexes of a
|
||||
table in the same tablespace */
|
||||
|
|
188
dict/dict0dict.c
188
dict/dict0dict.c
|
@ -55,56 +55,6 @@ UNIV_INTERN rw_lock_t dict_operation_lock;
|
|||
/* Identifies generated InnoDB foreign key names */
|
||||
static char dict_ibfk[] = "_ibfk_";
|
||||
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes;
|
||||
should be at least 5 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes;
|
||||
should be at least 3 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Makes all characters in a NUL-terminated UTF-8 string lower case.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_casedn_str(
|
||||
/*================*/
|
||||
char* a); /* in/out: string to put in lower case */
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set.
|
||||
|
||||
NOTE: the prototype of this function is copied from ha_innodb.cc! If you change
|
||||
this function, you MUST change also the prototype here! */
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
/*=================*/
|
||||
/* out: connection character set */
|
||||
void* mysql_thd); /* in: MySQL thread handle */
|
||||
#endif /* !UNIV_HOTBACKUP */
|
||||
|
||||
/***********************************************************************
|
||||
Tries to find column names for the index and sets the col field of the
|
||||
index. */
|
||||
|
@ -1948,27 +1898,19 @@ dict_table_get_referenced_constraint(
|
|||
dict_table_t* table, /* in: InnoDB table */
|
||||
dict_index_t* index) /* in: InnoDB index */
|
||||
{
|
||||
dict_foreign_t* foreign = NULL;
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
ut_ad(index && table);
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(table != NULL);
|
||||
|
||||
/* If the referenced list is empty, nothing to do */
|
||||
for (foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) {
|
||||
|
||||
if (UT_LIST_GET_LEN(table->referenced_list) == 0) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->referenced_list);
|
||||
|
||||
while (foreign) {
|
||||
if (foreign->referenced_index == index
|
||||
|| foreign->referenced_index == index) {
|
||||
if (foreign->referenced_index == index) {
|
||||
|
||||
return(foreign);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
@ -1987,29 +1929,20 @@ dict_table_get_foreign_constraint(
|
|||
dict_table_t* table, /* in: InnoDB table */
|
||||
dict_index_t* index) /* in: InnoDB index */
|
||||
{
|
||||
dict_foreign_t* foreign = NULL;
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
ut_ad(index && table);
|
||||
ut_ad(index != NULL);
|
||||
ut_ad(table != NULL);
|
||||
|
||||
/* If list empty then nothgin to do */
|
||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
||||
|
||||
if (UT_LIST_GET_LEN(table->foreign_list) == 0) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* Check whether this index is defined for a foreign key */
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
|
||||
while (foreign) {
|
||||
if (foreign->foreign_index == index
|
||||
|| foreign->referenced_index == index) {
|
||||
|
||||
return(foreign);
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
||||
}
|
||||
|
||||
return(NULL);
|
||||
|
@ -2179,6 +2112,30 @@ next_rec:
|
|||
return(NULL);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Find an index that is equivalent to the one passed in and is not marked
|
||||
for deletion. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_foreign_find_equiv_index(
|
||||
/*==========================*/
|
||||
/* out: index equivalent to
|
||||
foreign->foreign_index, or NULL */
|
||||
dict_foreign_t* foreign)/* in: foreign key */
|
||||
{
|
||||
ut_a(foreign != NULL);
|
||||
|
||||
/* Try to find an index which contains the columns as the
|
||||
first fields and in the right order, and the types are the
|
||||
same as in foreign->foreign_index */
|
||||
|
||||
return(dict_foreign_find_index(
|
||||
foreign->foreign_table,
|
||||
foreign->foreign_col_names, foreign->n_fields,
|
||||
foreign->foreign_index, TRUE, /* check types */
|
||||
FALSE/* allow columns to be NULL */));
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Returns an index object by matching on the name and column names and
|
||||
if more than one index matches return the index with the max id */
|
||||
|
@ -2409,7 +2366,7 @@ dict_foreign_add_to_cache(
|
|||
Scans from pointer onwards. Stops if is at the start of a copy of
|
||||
'string' where characters are compared without case sensitivity, and
|
||||
only outside `` or "" quotes. Stops also at '\0'. */
|
||||
UNIV_INTERN
|
||||
static
|
||||
const char*
|
||||
dict_scan_to(
|
||||
/*=========*/
|
||||
|
@ -2584,7 +2541,7 @@ convert_id:
|
|||
len = 3 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
innobase_convert_from_id(dst, str, len);
|
||||
innobase_convert_from_id(cs, dst, str, len);
|
||||
} else if (!strncmp(str, srv_mysql50_table_name_prefix,
|
||||
sizeof srv_mysql50_table_name_prefix)) {
|
||||
/* This is a pre-5.1 table name
|
||||
|
@ -2598,7 +2555,7 @@ convert_id:
|
|||
len = 5 * len + 1;
|
||||
*id = dst = mem_heap_alloc(heap, len);
|
||||
|
||||
innobase_convert_from_table_id(dst, str, len);
|
||||
innobase_convert_from_table_id(cs, dst, str, len);
|
||||
}
|
||||
|
||||
return(ptr);
|
||||
|
@ -4502,41 +4459,6 @@ dict_table_get_index_on_name(
|
|||
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Find and index that is equivalent to the one passed in. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_table_find_equivalent_index(
|
||||
/*=============================*/
|
||||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index) /* in: index to match */
|
||||
{
|
||||
ulint i;
|
||||
const char** column_names;
|
||||
dict_index_t* equiv_index;
|
||||
|
||||
if (UT_LIST_GET_LEN(table->foreign_list) == 0) {
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
column_names = mem_alloc(index->n_fields * sizeof *column_names);
|
||||
|
||||
/* Convert the column names to the format & type accepted by the find
|
||||
index function */
|
||||
for (i = 0; i < index->n_fields; i++) {
|
||||
column_names[i] = index->fields[i].name;
|
||||
}
|
||||
|
||||
equiv_index = dict_foreign_find_index(
|
||||
table, column_names, index->n_fields,
|
||||
index, TRUE, FALSE);
|
||||
|
||||
mem_free((void*) column_names);
|
||||
|
||||
return(equiv_index);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Replace the index passed in with another equivalent index in the tables
|
||||
foreign key list. */
|
||||
|
@ -4547,30 +4469,18 @@ dict_table_replace_index_in_foreign_list(
|
|||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index) /* in: index to be replaced */
|
||||
{
|
||||
dict_index_t* new_index;
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
new_index = dict_table_find_equivalent_index(table, index);
|
||||
for (foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
foreign;
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign)) {
|
||||
|
||||
/* If match found */
|
||||
if (new_index) {
|
||||
dict_foreign_t* foreign;
|
||||
if (foreign->foreign_index == index) {
|
||||
dict_index_t* new_index
|
||||
= dict_foreign_find_equiv_index(foreign);
|
||||
ut_a(new_index);
|
||||
|
||||
ut_a(new_index != index);
|
||||
|
||||
foreign = UT_LIST_GET_FIRST(table->foreign_list);
|
||||
|
||||
/* If the list is not empty then this should hold */
|
||||
ut_a(foreign);
|
||||
|
||||
/* Iterate over the foreign index list and replace the index
|
||||
passed in with the new index */
|
||||
while (foreign) {
|
||||
|
||||
if (foreign->foreign_index == index) {
|
||||
foreign->foreign_index = new_index;
|
||||
}
|
||||
|
||||
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
|
||||
foreign->foreign_index = new_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -304,8 +304,7 @@ static MYSQL_THDVAR_BOOL(table_locks, PLUGIN_VAR_OPCMDARG,
|
|||
/* check_func */ NULL, /* update_func */ NULL,
|
||||
/* default */ TRUE);
|
||||
|
||||
static MYSQL_THDVAR_BOOL(strict_mode,
|
||||
PLUGIN_VAR_NOCMDARG,
|
||||
static MYSQL_THDVAR_BOOL(strict_mode, PLUGIN_VAR_OPCMDARG,
|
||||
"Use strict mode when evaluating create options.",
|
||||
NULL, NULL, FALSE);
|
||||
|
||||
|
@ -641,6 +640,18 @@ thd_has_edited_nontrans_tables(
|
|||
return((ibool) thd_non_transactional_update((THD*) thd));
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Returns true if the thread is executing a SELECT statement. */
|
||||
extern "C" UNIV_INTERN
|
||||
ibool
|
||||
thd_is_select(
|
||||
/*==========*/
|
||||
/* out: true if thd is executing SELECT */
|
||||
const void* thd) /* in: thread handle (THD*) */
|
||||
{
|
||||
return(thd_sql_command((const THD*) thd) == SQLCOM_SELECT);
|
||||
}
|
||||
|
||||
/************************************************************************
|
||||
Obtain the InnoDB transaction of a MySQL thread. */
|
||||
inline
|
||||
|
@ -894,41 +905,35 @@ innobase_get_cset_width(
|
|||
}
|
||||
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
Converts an identifier to a table name. */
|
||||
extern "C" UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len) /* in: length of 'to', in bytes */
|
||||
struct charset_info_st* cs, /* in: the 'from' character set */
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len) /* in: length of 'to', in bytes */
|
||||
{
|
||||
uint errors;
|
||||
|
||||
strconvert(thd_charset(current_thd), from,
|
||||
&my_charset_filename, to, (uint) len, &errors);
|
||||
strconvert(cs, from, &my_charset_filename, to, (uint) len, &errors);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
Converts an identifier to UTF-8. */
|
||||
extern "C" UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len) /* in: length of 'to', in bytes */
|
||||
struct charset_info_st* cs, /* in: the 'from' character set */
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len) /* in: length of 'to', in bytes */
|
||||
{
|
||||
uint errors;
|
||||
|
||||
strconvert(thd_charset(current_thd), from,
|
||||
system_charset_info, to, (uint) len, &errors);
|
||||
strconvert(cs, from, system_charset_info, to, (uint) len, &errors);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
|
@ -945,10 +950,7 @@ innobase_strcasecmp(
|
|||
}
|
||||
|
||||
/**********************************************************************
|
||||
Makes all characters in a NUL-terminated UTF-8 string lower case.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
Makes all characters in a NUL-terminated UTF-8 string lower case. */
|
||||
extern "C" UNIV_INTERN
|
||||
void
|
||||
innobase_casedn_str(
|
||||
|
@ -959,10 +961,7 @@ innobase_casedn_str(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set.
|
||||
|
||||
NOTE that the exact prototype of this function has to be in
|
||||
/innobase/dict/dict0dict.c! */
|
||||
Determines the connection character set. */
|
||||
extern "C" UNIV_INTERN
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
|
@ -2709,6 +2708,14 @@ ha_innobase::open(
|
|||
UT_NOT_USED(test_if_locked);
|
||||
|
||||
thd = ha_thd();
|
||||
|
||||
/* Under some cases MySQL seems to call this function while
|
||||
holding btr_search_latch. This breaks the latching order as
|
||||
we acquire dict_sys->mutex below and leads to a deadlock. */
|
||||
if (thd != NULL) {
|
||||
innobase_release_temporary_latches(ht, thd);
|
||||
}
|
||||
|
||||
normalize_table_name(norm_name, name);
|
||||
|
||||
user_thd = NULL;
|
||||
|
@ -6659,9 +6666,21 @@ ha_innobase::info(
|
|||
stats.index_file_length = ((ulonglong)
|
||||
ib_table->stat_sum_of_other_index_sizes)
|
||||
* UNIV_PAGE_SIZE;
|
||||
stats.delete_length =
|
||||
fsp_get_available_space_in_free_extents(
|
||||
ib_table->space) * 1024;
|
||||
|
||||
/* Since fsp_get_available_space_in_free_extents() is
|
||||
acquiring latches inside InnoDB, we do not call it if we
|
||||
are asked by MySQL to avoid locking. Another reason to
|
||||
avoid the call is that it uses quite a lot of CPU.
|
||||
See Bug#38185.
|
||||
We do not update delete_length if no locking is requested
|
||||
so the "old" value can remain. delete_length is initialized
|
||||
to 0 in the ha_statistics' constructor. */
|
||||
if (!(flag & HA_STATUS_NO_LOCK)) {
|
||||
stats.delete_length =
|
||||
fsp_get_available_space_in_free_extents(
|
||||
ib_table->space) * 1024;
|
||||
}
|
||||
|
||||
stats.check_time = 0;
|
||||
|
||||
if (stats.records == 0) {
|
||||
|
@ -7242,13 +7261,20 @@ UNIV_INTERN
|
|||
int
|
||||
ha_innobase::reset()
|
||||
{
|
||||
if (prebuilt->blob_heap) {
|
||||
row_mysql_prebuilt_free_blob_heap(prebuilt);
|
||||
}
|
||||
reset_template(prebuilt);
|
||||
return 0;
|
||||
}
|
||||
if (prebuilt->blob_heap) {
|
||||
row_mysql_prebuilt_free_blob_heap(prebuilt);
|
||||
}
|
||||
|
||||
reset_template(prebuilt);
|
||||
|
||||
/* TODO: This should really be reset in reset_template() but for now
|
||||
it's safer to do it explicitly here. */
|
||||
|
||||
/* This is a statement level counter. */
|
||||
prebuilt->last_value = 0;
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
MySQL calls this function at the start of each SQL statement inside LOCK
|
||||
|
|
|
@ -983,15 +983,16 @@ ha_innobase::prepare_drop_index(
|
|||
|
||||
if (trx->check_foreigns
|
||||
&& thd_sql_command(user_thd) != SQLCOM_CREATE_INDEX) {
|
||||
dict_index_t* index
|
||||
= dict_table_get_first_index(prebuilt->table);
|
||||
dict_index_t* index;
|
||||
|
||||
do {
|
||||
for (index = dict_table_get_first_index(prebuilt->table);
|
||||
index;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
if (!index->to_be_dropped) {
|
||||
|
||||
goto next_index;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if the index is referenced. */
|
||||
|
@ -1019,20 +1020,61 @@ index_needed:
|
|||
ut_a(foreign->foreign_index == index);
|
||||
|
||||
/* Search for an equivalent index that
|
||||
the foreign key contraint could use
|
||||
the foreign key constraint could use
|
||||
if this index were to be deleted. */
|
||||
if (!dict_table_find_equivalent_index(
|
||||
prebuilt->table,
|
||||
foreign->foreign_index)) {
|
||||
if (!dict_foreign_find_equiv_index(
|
||||
foreign)) {
|
||||
|
||||
goto index_needed;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (thd_sql_command(user_thd) == SQLCOM_CREATE_INDEX) {
|
||||
/* This is a drop of a foreign key constraint index that
|
||||
was created by MySQL when the constraint was added. MySQL
|
||||
does this when the user creates an index explicitly which
|
||||
can be used in place of the automatically generated index. */
|
||||
|
||||
next_index:
|
||||
index = dict_table_get_next_index(index);
|
||||
} while (index);
|
||||
dict_index_t* index;
|
||||
|
||||
for (index = dict_table_get_first_index(prebuilt->table);
|
||||
index;
|
||||
index = dict_table_get_next_index(index)) {
|
||||
dict_foreign_t* foreign;
|
||||
|
||||
if (!index->to_be_dropped) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check if this index references some other table */
|
||||
foreign = dict_table_get_foreign_constraint(
|
||||
prebuilt->table, index);
|
||||
|
||||
if (foreign == NULL) {
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
ut_a(foreign->foreign_index == index);
|
||||
|
||||
/* Search for an equivalent index that the
|
||||
foreign key constraint could use if this index
|
||||
were to be deleted. */
|
||||
|
||||
if (!dict_foreign_find_equiv_index(foreign)) {
|
||||
trx_set_detailed_error(
|
||||
trx,
|
||||
"Index needed in foreign key "
|
||||
"constraint");
|
||||
|
||||
trx->error_info = foreign->foreign_index;
|
||||
|
||||
err = HA_ERR_DROP_INDEX_FK;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func_exit:
|
||||
|
|
|
@ -852,9 +852,13 @@ ibuf_set_free_bits_func(
|
|||
|
||||
/****************************************************************************
|
||||
Resets the free bits of the page in the ibuf bitmap. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict further
|
||||
work to only ibuf bitmap operations, which would result if the latch to the
|
||||
bitmap page were kept. */
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to decrement or reset the bits in the bitmap in a mini-transaction
|
||||
that is committed before the mini-transaction that affects the free
|
||||
space. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_reset_free_bits(
|
||||
|
@ -867,9 +871,13 @@ ibuf_reset_free_bits(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Updates the free bits for an uncompressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for an uncompressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_low(
|
||||
|
@ -899,9 +907,13 @@ ibuf_update_free_bits_low(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Updates the free bits for a compressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for a compressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_zip(
|
||||
|
@ -940,9 +952,12 @@ ibuf_update_free_bits_zip(
|
|||
}
|
||||
|
||||
/**************************************************************************
|
||||
Updates the free bits for the two pages to reflect the present state. Does
|
||||
this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations until mtr is committed. */
|
||||
Updates the free bits for the two pages to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules
|
||||
virtually prevent any further operations until mtr is committed.
|
||||
NOTE: The free bits in the insert buffer bitmap must never exceed the
|
||||
free space on a page. It is safe to set the free bits in the same
|
||||
mini-transaction that updated the pages. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_for_two_pages_low(
|
||||
|
|
|
@ -444,6 +444,15 @@ buf_page_set_old(
|
|||
{
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
ut_ad(buf_pool_mutex_own());
|
||||
ut_ad(bpage->in_LRU_list);
|
||||
|
||||
#ifdef UNIV_LRU_DEBUG
|
||||
if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)
|
||||
&& UT_LIST_GET_PREV(LRU, bpage)->old
|
||||
== UT_LIST_GET_NEXT(LRU, bpage)->old) {
|
||||
ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old);
|
||||
}
|
||||
#endif /* UNIV_LRU_DEBUG */
|
||||
|
||||
bpage->old = old;
|
||||
}
|
||||
|
|
|
@ -420,6 +420,16 @@ dict_table_get_on_id_low(
|
|||
/* out: table, NULL if does not exist */
|
||||
dulint table_id); /* in: table id */
|
||||
/**************************************************************************
|
||||
Find an index that is equivalent to the one passed in and is not marked
|
||||
for deletion. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_foreign_find_equiv_index(
|
||||
/*==========================*/
|
||||
/* out: index equivalent to
|
||||
foreign->foreign_index, or NULL */
|
||||
dict_foreign_t* foreign);/* in: foreign key */
|
||||
/**************************************************************************
|
||||
Returns an index object by matching on the name and column names and if
|
||||
more than index is found return the index with the higher id.*/
|
||||
UNIV_INTERN
|
||||
|
@ -1068,17 +1078,6 @@ dict_tables_have_same_db(
|
|||
const char* name2); /* in: table name in the form
|
||||
dbname '/' tablename */
|
||||
/*************************************************************************
|
||||
Scans from pointer onwards. Stops if is at the start of a copy of
|
||||
'string' where characters are compared without case sensitivity. Stops
|
||||
also at '\0'. */
|
||||
|
||||
const char*
|
||||
dict_scan_to(
|
||||
/*=========*/
|
||||
/* out: scanned up to this */
|
||||
const char* ptr, /* in: scan from */
|
||||
const char* string);/* in: look for this */
|
||||
/*************************************************************************
|
||||
Removes an index from the cache */
|
||||
UNIV_INTERN
|
||||
void
|
||||
|
@ -1096,15 +1095,6 @@ dict_table_get_index_on_name(
|
|||
dict_table_t* table, /* in: table */
|
||||
const char* name); /* in: name of the index to find */
|
||||
/**************************************************************************
|
||||
Find and index that is equivalent to the one passed in and is not marked
|
||||
for deletion. */
|
||||
UNIV_INTERN
|
||||
dict_index_t*
|
||||
dict_table_find_equivalent_index(
|
||||
/*=============================*/
|
||||
dict_table_t* table, /* in/out: table */
|
||||
dict_index_t* index); /* in: index to match */
|
||||
/**************************************************************************
|
||||
In case there is more than one index with the same name return the index
|
||||
with the min(id). */
|
||||
UNIV_INTERN
|
||||
|
|
|
@ -38,6 +38,8 @@ flst_write_addr(
|
|||
{
|
||||
ut_ad(faddr && mtr);
|
||||
ut_ad(mtr_memo_contains_page(mtr, faddr, MTR_MEMO_PAGE_X_FIX));
|
||||
ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA);
|
||||
ut_a(ut_align_offset(faddr, UNIV_PAGE_SIZE) >= FIL_PAGE_DATA);
|
||||
|
||||
mlog_write_ulint(faddr + FIL_ADDR_PAGE, addr.page, MLOG_4BYTES, mtr);
|
||||
mlog_write_ulint(faddr + FIL_ADDR_BYTE, addr.boffset,
|
||||
|
@ -61,6 +63,8 @@ flst_read_addr(
|
|||
addr.page = mtr_read_ulint(faddr + FIL_ADDR_PAGE, MLOG_4BYTES, mtr);
|
||||
addr.boffset = mtr_read_ulint(faddr + FIL_ADDR_BYTE, MLOG_2BYTES,
|
||||
mtr);
|
||||
ut_a(addr.page == FIL_NULL || addr.boffset >= FIL_PAGE_DATA);
|
||||
ut_a(ut_align_offset(faddr, UNIV_PAGE_SIZE) >= FIL_PAGE_DATA);
|
||||
return(addr);
|
||||
}
|
||||
|
||||
|
|
|
@ -158,5 +158,53 @@ innobase_strcasecmp(
|
|||
/* out: 0 if a=b, <0 if a<b, >1 if a>b */
|
||||
const char* a, /* in: first string to compare */
|
||||
const char* b); /* in: second string to compare */
|
||||
|
||||
/**********************************************************************
|
||||
Returns true if the thread is executing a SELECT statement. */
|
||||
|
||||
ibool
|
||||
thd_is_select(
|
||||
/*==========*/
|
||||
/* out: true if thd is executing SELECT */
|
||||
const void* thd); /* in: thread handle (THD*) */
|
||||
|
||||
/**********************************************************************
|
||||
Converts an identifier to a table name. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_table_id(
|
||||
/*===========================*/
|
||||
struct charset_info_st* cs, /* in: the 'from' character set */
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes; should
|
||||
be at least 5 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Converts an identifier to UTF-8. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_convert_from_id(
|
||||
/*=====================*/
|
||||
struct charset_info_st* cs, /* in: the 'from' character set */
|
||||
char* to, /* out: converted identifier */
|
||||
const char* from, /* in: identifier to convert */
|
||||
ulint len); /* in: length of 'to', in bytes; should
|
||||
be at least 3 * strlen(to) + 1 */
|
||||
/**********************************************************************
|
||||
Makes all characters in a NUL-terminated UTF-8 string lower case. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
innobase_casedn_str(
|
||||
/*================*/
|
||||
char* a); /* in/out: string to put in lower case */
|
||||
|
||||
/**************************************************************************
|
||||
Determines the connection character set. */
|
||||
struct charset_info_st*
|
||||
innobase_get_charset(
|
||||
/*=================*/
|
||||
/* out: connection character set */
|
||||
void* mysql_thd); /* in: MySQL thread handle */
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
|
@ -90,7 +90,7 @@ do {\
|
|||
if (cell3333->node == NULL) {\
|
||||
cell3333->node = DATA;\
|
||||
} else {\
|
||||
struct3333 = cell3333->node;\
|
||||
struct3333 = (TYPE*) cell3333->node;\
|
||||
\
|
||||
while (struct3333->NAME != NULL) {\
|
||||
\
|
||||
|
|
|
@ -31,6 +31,26 @@ typedef enum {
|
|||
|
||||
extern ibuf_t* ibuf;
|
||||
|
||||
/* The purpose of the insert buffer is to reduce random disk access.
|
||||
When we wish to insert a record into a non-unique secondary index and
|
||||
the B-tree leaf page where the record belongs to is not in the buffer
|
||||
pool, we insert the record into the insert buffer B-tree, indexed by
|
||||
(space_id, page_no). When the page is eventually read into the buffer
|
||||
pool, we look up the insert buffer B-tree for any modifications to the
|
||||
page, and apply these upon the completion of the read operation. This
|
||||
is called the insert buffer merge. */
|
||||
|
||||
/* The insert buffer merge must always succeed. To guarantee this,
|
||||
the insert buffer subsystem keeps track of the free space in pages for
|
||||
which it can buffer operations. Two bits per page in the insert
|
||||
buffer bitmap indicate the available space in coarse increments. The
|
||||
free bits in the insert buffer bitmap must never exceed the free space
|
||||
on a page. It is safe to decrement or reset the bits in the bitmap in
|
||||
a mini-transaction that is committed before the mini-transaction that
|
||||
affects the free space. It is unsafe to increment the bits in a
|
||||
separately committed mini-transaction, because in crash recovery, the
|
||||
free bits could momentarily be set too high. */
|
||||
|
||||
/**********************************************************************
|
||||
Creates the insert buffer data structure at a database startup. */
|
||||
UNIV_INTERN
|
||||
|
@ -54,9 +74,13 @@ ibuf_bitmap_page_init(
|
|||
mtr_t* mtr); /* in: mtr */
|
||||
/****************************************************************************
|
||||
Resets the free bits of the page in the ibuf bitmap. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict further
|
||||
work to only ibuf bitmap operations, which would result if the latch to the
|
||||
bitmap page were kept. */
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to decrement or reset the bits in the bitmap in a mini-transaction
|
||||
that is committed before the mini-transaction that affects the free
|
||||
space. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_reset_free_bits(
|
||||
|
@ -66,10 +90,17 @@ ibuf_reset_free_bits(
|
|||
non-unique, and page level is 0 */
|
||||
/****************************************************************************
|
||||
Updates the free bits of an uncompressed page in the ibuf bitmap if
|
||||
there is not enough free on the page any more. This is done in a
|
||||
there is not enough free on the page any more. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. */
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is
|
||||
unsafe to increment the bits in a separately committed
|
||||
mini-transaction, because in crash recovery, the free bits could
|
||||
momentarily be set too high. It is only safe to use this function for
|
||||
decrementing the free bits. Should more free space become available,
|
||||
we must not update the free bits here, because that would break crash
|
||||
recovery. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ibuf_update_free_bits_if_full(
|
||||
|
@ -86,9 +117,13 @@ ibuf_update_free_bits_if_full(
|
|||
used in the latest operation, if known, or
|
||||
ULINT_UNDEFINED */
|
||||
/**************************************************************************
|
||||
Updates the free bits for an uncompressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for an uncompressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_low(
|
||||
|
@ -101,9 +136,13 @@ ibuf_update_free_bits_low(
|
|||
performed to the page */
|
||||
mtr_t* mtr); /* in/out: mtr */
|
||||
/**************************************************************************
|
||||
Updates the free bits for a compressed page to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations for this OS thread until mtr is committed. */
|
||||
Updates the free bits for a compressed page to reflect the present
|
||||
state. Does this in the mtr given, which means that the latching
|
||||
order rules virtually prevent any further operations for this OS
|
||||
thread until mtr is committed. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is safe
|
||||
to set the free bits in the same mini-transaction that updated the
|
||||
page. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_zip(
|
||||
|
@ -111,9 +150,12 @@ ibuf_update_free_bits_zip(
|
|||
buf_block_t* block, /* in/out: index page */
|
||||
mtr_t* mtr); /* in/out: mtr */
|
||||
/**************************************************************************
|
||||
Updates the free bits for the two pages to reflect the present state. Does
|
||||
this in the mtr given, which means that the latching order rules virtually
|
||||
prevent any further operations until mtr is committed. */
|
||||
Updates the free bits for the two pages to reflect the present state.
|
||||
Does this in the mtr given, which means that the latching order rules
|
||||
virtually prevent any further operations until mtr is committed.
|
||||
NOTE: The free bits in the insert buffer bitmap must never exceed the
|
||||
free space on a page. It is safe to set the free bits in the same
|
||||
mini-transaction that updated the pages. */
|
||||
UNIV_INTERN
|
||||
void
|
||||
ibuf_update_free_bits_for_two_pages_low(
|
||||
|
|
|
@ -251,10 +251,17 @@ ibuf_index_page_calc_free(
|
|||
|
||||
/****************************************************************************
|
||||
Updates the free bits of an uncompressed page in the ibuf bitmap if
|
||||
there is not enough free on the page any more. This is done in a
|
||||
there is not enough free on the page any more. This is done in a
|
||||
separate mini-transaction, hence this operation does not restrict
|
||||
further work to only ibuf bitmap operations, which would result if the
|
||||
latch to the bitmap page were kept. */
|
||||
latch to the bitmap page were kept. NOTE: The free bits in the insert
|
||||
buffer bitmap must never exceed the free space on a page. It is
|
||||
unsafe to increment the bits in a separately committed
|
||||
mini-transaction, because in crash recovery, the free bits could
|
||||
momentarily be set too high. It is only safe to use this function for
|
||||
decrementing the free bits. Should more free space become available,
|
||||
we must not update the free bits here, because that would break crash
|
||||
recovery. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
ibuf_update_free_bits_if_full(
|
||||
|
|
|
@ -244,21 +244,25 @@ page_header_reset_last_insert(
|
|||
uncompressed part will be updated, or NULL */
|
||||
mtr_t* mtr); /* in: mtr */
|
||||
/****************************************************************
|
||||
Gets the first record on the page. */
|
||||
Gets the offset of the first record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_infimum_rec(
|
||||
/*=================*/
|
||||
/* out: the first record in record list */
|
||||
page_t* page); /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_infimum_offset(
|
||||
/*====================*/
|
||||
/* out: offset of the first record
|
||||
in record list, relative from page */
|
||||
const page_t* page); /* in: page which must have record(s) */
|
||||
/****************************************************************
|
||||
Gets the last record on the page. */
|
||||
Gets the offset of the last record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_supremum_rec(
|
||||
/*==================*/
|
||||
/* out: the last record in record list */
|
||||
page_t* page); /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_supremum_offset(
|
||||
/*=====================*/
|
||||
/* out: offset of the last record in
|
||||
record list, relative from page */
|
||||
const page_t* page); /* in: page which must have record(s) */
|
||||
#define page_get_infimum_rec(page) ((page) + page_get_infimum_offset(page))
|
||||
#define page_get_supremum_rec(page) ((page) + page_get_supremum_offset(page))
|
||||
/****************************************************************
|
||||
Returns the middle record of record list. If there are an even number
|
||||
of records in the list, returns the first record of upper half-list. */
|
||||
|
|
|
@ -246,38 +246,42 @@ page_is_leaf(
|
|||
}
|
||||
|
||||
/****************************************************************
|
||||
Gets the first record on the page. */
|
||||
Gets the offset of the first record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_infimum_rec(
|
||||
/*=================*/
|
||||
/* out: the first record in record list */
|
||||
page_t* page) /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_infimum_offset(
|
||||
/*====================*/
|
||||
/* out: offset of the first record
|
||||
in record list, relative from page */
|
||||
const page_t* page) /* in: page which must have record(s) */
|
||||
{
|
||||
ut_ad(page);
|
||||
ut_ad(!page_offset(page));
|
||||
|
||||
if (page_is_comp(page)) {
|
||||
return(page + PAGE_NEW_INFIMUM);
|
||||
return(PAGE_NEW_INFIMUM);
|
||||
} else {
|
||||
return(page + PAGE_OLD_INFIMUM);
|
||||
return(PAGE_OLD_INFIMUM);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
Gets the last record on the page. */
|
||||
Gets the offset of the last record on the page. */
|
||||
UNIV_INLINE
|
||||
rec_t*
|
||||
page_get_supremum_rec(
|
||||
/*==================*/
|
||||
/* out: the last record in record list */
|
||||
page_t* page) /* in: page which must have record(s) */
|
||||
ulint
|
||||
page_get_supremum_offset(
|
||||
/*=====================*/
|
||||
/* out: offset of the last record in
|
||||
record list, relative from page */
|
||||
const page_t* page) /* in: page which must have record(s) */
|
||||
{
|
||||
ut_ad(page);
|
||||
ut_ad(!page_offset(page));
|
||||
|
||||
if (page_is_comp(page)) {
|
||||
return(page + PAGE_NEW_SUPREMUM);
|
||||
return(PAGE_NEW_SUPREMUM);
|
||||
} else {
|
||||
return(page + PAGE_OLD_SUPREMUM);
|
||||
return(PAGE_OLD_SUPREMUM);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,8 @@ page_zip_rec_needs_ext(
|
|||
can be stored locally on the page */
|
||||
ulint rec_size, /* in: length of the record in bytes */
|
||||
ulint comp, /* in: nonzero=compact format */
|
||||
ulint n_fields, /* in: number of fields in the record;
|
||||
ignored if zip_size == 0 */
|
||||
ulint zip_size) /* in: compressed page size in bytes, or 0 */
|
||||
__attribute__((const));
|
||||
|
||||
|
|
|
@ -148,10 +148,13 @@ page_zip_rec_needs_ext(
|
|||
can be stored locally on the page */
|
||||
ulint rec_size, /* in: length of the record in bytes */
|
||||
ulint comp, /* in: nonzero=compact format */
|
||||
ulint n_fields, /* in: number of fields in the record;
|
||||
ignored if zip_size == 0 */
|
||||
ulint zip_size) /* in: compressed page size in bytes, or 0 */
|
||||
{
|
||||
ut_ad(rec_size > comp ? REC_N_NEW_EXTRA_BYTES : REC_N_OLD_EXTRA_BYTES);
|
||||
ut_ad(ut_is_2pow(zip_size));
|
||||
ut_ad(comp || !zip_size);
|
||||
|
||||
#if UNIV_PAGE_SIZE > REC_MAX_DATA_SIZE
|
||||
if (UNIV_UNLIKELY(rec_size >= REC_MAX_DATA_SIZE)) {
|
||||
|
@ -159,21 +162,18 @@ page_zip_rec_needs_ext(
|
|||
}
|
||||
#endif
|
||||
|
||||
if (UNIV_UNLIKELY(!comp)) {
|
||||
ut_ad(!zip_size);
|
||||
return(rec_size >= page_get_free_space_of_empty(FALSE) / 2);
|
||||
if (UNIV_UNLIKELY(zip_size)) {
|
||||
ut_ad(comp);
|
||||
/* On a compressed page, there is a two-byte entry in
|
||||
the dense page directory for every record. But there
|
||||
is no record header. There should be enough room for
|
||||
one record on an empty leaf page. Subtract 1 byte for
|
||||
the encoded heap number. */
|
||||
return(rec_size - (REC_N_NEW_EXTRA_BYTES - 2)
|
||||
>= (page_zip_empty_size(n_fields, zip_size) - 1));
|
||||
}
|
||||
|
||||
/* If zip_size != 0, the record should fit on the compressed page.
|
||||
If not, the right-hand-side of the comparison will overwrap
|
||||
and the condition will not hold. Thus, we do not need to test
|
||||
for zip_size != 0. We subtract the size of the page header and
|
||||
assume that compressing the index information takes 50 bytes. */
|
||||
if (rec_size >= zip_size - (PAGE_DATA + 50)) {
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
return(rec_size >= page_get_free_space_of_empty(TRUE) / 2);
|
||||
return(rec_size >= page_get_free_space_of_empty(comp) / 2);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
|
@ -355,15 +355,7 @@ 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));
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ command. Not tested on Windows. */
|
|||
#define UNIV_DEBUG_FILE_ACCESSES /* Debug .ibd file access
|
||||
(field file_page_was_freed
|
||||
in buf_page_t) */
|
||||
#define UNIV_LRU_DEBUG /* debug the buffer pool LRU */
|
||||
#define UNIV_HASH_DEBUG /* debug HASH_ macros */
|
||||
#define UNIV_LIST_DEBUG /* debug UT_LIST_ macros */
|
||||
#define UNIV_MEM_DEBUG /* detect memory leaks etc */
|
||||
|
|
2
mysql-test/innodb-analyze.result
Normal file
2
mysql-test/innodb-analyze.result
Normal file
|
@ -0,0 +1,2 @@
|
|||
Variable_name Value
|
||||
innodb_stats_sample_pages 1
|
63
mysql-test/innodb-analyze.test
Normal file
63
mysql-test/innodb-analyze.test
Normal file
|
@ -0,0 +1,63 @@
|
|||
#
|
||||
# Test that mysqld does not crash when running ANALYZE TABLE with
|
||||
# different values of the parameter innodb_stats_sample_pages.
|
||||
#
|
||||
|
||||
-- source include/have_innodb.inc
|
||||
|
||||
# we care only that the following SQL commands do not produce errors
|
||||
# and do not crash the server
|
||||
-- disable_query_log
|
||||
-- disable_result_log
|
||||
-- enable_warnings
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=0;
|
||||
|
||||
# check that the value has been adjusted to 1
|
||||
-- enable_result_log
|
||||
SHOW VARIABLES LIKE 'innodb_stats_sample_pages';
|
||||
-- disable_result_log
|
||||
|
||||
CREATE TABLE innodb_analyze (
|
||||
a INT,
|
||||
b INT,
|
||||
KEY(a),
|
||||
KEY(b,a)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
# test with empty table
|
||||
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=2;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=4;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=8;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=16;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
INSERT INTO innodb_analyze VALUES
|
||||
(1,1), (1,1), (1,2), (1,3), (1,4), (1,5),
|
||||
(8,1), (8,8), (8,2), (7,1), (1,4), (3,5);
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=1;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=2;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=4;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=8;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
SET GLOBAL innodb_stats_sample_pages=16;
|
||||
ANALYZE TABLE innodb_analyze;
|
||||
|
||||
DROP TABLE innodb_analyze;
|
|
@ -169,3 +169,30 @@ t1 CREATE TABLE `t1` (
|
|||
PRIMARY KEY (`c1`)
|
||||
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1);
|
||||
INSERT INTO t1 VALUES (NULL,8);
|
||||
SELECT * FROM t1;
|
||||
c1 c2
|
||||
2 1
|
||||
3 8
|
||||
DROP TABLE t1;
|
||||
DROP TABLE IF EXISTS t1;
|
||||
Warnings:
|
||||
Note 1051 Unknown table 't1'
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1), (NULL, 8);
|
||||
INSERT INTO t1 VALUES (NULL,9);
|
||||
SELECT * FROM t1;
|
||||
c1 c2
|
||||
2 1
|
||||
3 8
|
||||
5 9
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -139,3 +139,24 @@ SELECT c1 FROM t1;
|
|||
SHOW CREATE TABLE t1;
|
||||
DROP TABLE t1;
|
||||
|
||||
#
|
||||
# Bug 38839
|
||||
# Reset the last value generated at end of statement
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1);
|
||||
INSERT INTO t1 VALUES (NULL,8);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
# Bug 38839 -- same as above but for multi value insert
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) ENGINE=InnoDB;
|
||||
INSERT INTO t1 VALUES (NULL, 1);
|
||||
DELETE FROM t1 WHERE c1 = 1;
|
||||
INSERT INTO t1 VALUES (2,1), (NULL, 8);
|
||||
INSERT INTO t1 VALUES (NULL,9);
|
||||
SELECT * FROM t1;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -960,3 +960,167 @@ t1 CREATE TABLE `t1` (
|
|||
KEY `t1st` (`s`(1),`t`(1))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
drop table t1;
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `i_t2_c3_c2` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`))
|
||||
INSERT INTO t1 VALUES(0);
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
DROP TABLE t2;
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1,c2,c3)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`,`c2`,`c3`),
|
||||
KEY `fk_t2_ca` (`c3`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`,`c2`,`c3`),
|
||||
KEY `i_t2_c3_c2` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
INSERT INTO t2 VALUES(0,0,1);
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`))
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
DELETE FROM t1;
|
||||
ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`) REFERENCES `t1` (`c1`))
|
||||
DELETE FROM t2;
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
c2 INT(4) NOT NULL,
|
||||
PRIMARY KEY (c2,c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL;
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
ERROR HY000: Can't create table '#sql-temporary' (errno: 150)
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
SHOW CREATE TABLE t1;
|
||||
Table Create Table
|
||||
t1 CREATE TABLE `t1` (
|
||||
`c1` bigint(12) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c2`,`c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c2_c1 ON t2(c2, c1);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`,`c2`),
|
||||
KEY `i_t2_c2_c1` (`c2`,`c1`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c1_c2 ON t2(c3, c1, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `fk_t2_ca` (`c3`,`c2`),
|
||||
KEY `i_t2_c2_c1` (`c2`,`c1`),
|
||||
KEY `i_t2_c3_c1_c2` (`c3`,`c1`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`c1` bigint(16) NOT NULL,
|
||||
`c2` bigint(12) NOT NULL,
|
||||
`c3` bigint(12) NOT NULL,
|
||||
PRIMARY KEY (`c1`),
|
||||
KEY `i_t2_c2_c1` (`c2`,`c1`),
|
||||
KEY `i_t2_c3_c1_c2` (`c3`,`c1`,`c2`),
|
||||
KEY `i_t2_c3_c2` (`c3`,`c2`),
|
||||
CONSTRAINT `fk_t2_ca` FOREIGN KEY (`c3`, `c2`) REFERENCES `t1` (`c2`, `c1`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -387,3 +387,114 @@ create index t1ut on t1 (u(1), t(1));
|
|||
create index t1st on t1 (s(1), t(1));
|
||||
show create table t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test to check whether CREATE INDEX handles implicit foreign key
|
||||
# constraint modifications (Issue #70, Bug #38786)
|
||||
#
|
||||
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
|
||||
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
|
||||
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
|
||||
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
|
||||
|
||||
--error ER_NO_REFERENCED_ROW_2
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
INSERT INTO t1 VALUES(0);
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
|
||||
DROP TABLE t2;
|
||||
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1,c2,c3)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3) REFERENCES t1(c1);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
|
||||
SHOW CREATE TABLE t2;
|
||||
--error ER_NO_REFERENCED_ROW_2
|
||||
INSERT INTO t2 VALUES(0,0,1);
|
||||
INSERT INTO t2 VALUES(0,0,0);
|
||||
--error ER_ROW_IS_REFERENCED_2
|
||||
DELETE FROM t1;
|
||||
DELETE FROM t2;
|
||||
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
||||
CREATE TABLE t1(
|
||||
c1 BIGINT(12) NOT NULL,
|
||||
c2 INT(4) NOT NULL,
|
||||
PRIMARY KEY (c2,c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
CREATE TABLE t2(
|
||||
c1 BIGINT(16) NOT NULL,
|
||||
c2 BIGINT(12) NOT NULL,
|
||||
c3 BIGINT(12) NOT NULL,
|
||||
PRIMARY KEY (c1)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
|
||||
--replace_regex /'test\.#sql-[0-9a-f-]*_1'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c1);
|
||||
--replace_regex /'test\.#sql-[0-9a-f-]*_1'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
--replace_regex /'test\.#sql-[0-9a-f-]*_1'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
ALTER TABLE t1 MODIFY COLUMN c2 BIGINT(12) NOT NULL;
|
||||
--replace_regex /'test\.#sql-[0-9a-f-]*_1'/'#sql-temporary'/
|
||||
--error ER_CANT_CREATE_TABLE
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c1,c2);
|
||||
|
||||
ALTER TABLE t2 ADD CONSTRAINT fk_t2_ca
|
||||
FOREIGN KEY (c3,c2) REFERENCES t1(c2,c1);
|
||||
SHOW CREATE TABLE t1;
|
||||
SHOW CREATE TABLE t2;
|
||||
CREATE INDEX i_t2_c2_c1 ON t2(c2, c1);
|
||||
SHOW CREATE TABLE t2;
|
||||
CREATE INDEX i_t2_c3_c1_c2 ON t2(c3, c1, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
CREATE INDEX i_t2_c3_c2 ON t2(c3, c2);
|
||||
SHOW CREATE TABLE t2;
|
||||
|
||||
DROP TABLE t2;
|
||||
DROP TABLE t1;
|
||||
|
|
|
@ -174,6 +174,11 @@ set global innodb_file_format=``;
|
|||
ERROR HY000: Incorrect arguments to SET
|
||||
set global innodb_file_per_table = on;
|
||||
set global innodb_file_format = `1`;
|
||||
set innodb_strict_mode = off;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
Warnings:
|
||||
Warning 1478 InnoDB: ignoring KEY_BLOCK_SIZE=0.
|
||||
drop table t1;
|
||||
set innodb_strict_mode = on;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
ERROR HY000: Can't create table 'test.t1' (errno: 1478)
|
||||
|
@ -376,7 +381,6 @@ test t9 Redundant
|
|||
drop table t8, t9;
|
||||
set global innodb_file_per_table=0;
|
||||
set global innodb_file_format=Antelope;
|
||||
set innodb_strict_mode=0;
|
||||
set global innodb_file_per_table=on;
|
||||
set global innodb_file_format=`Barracuda`;
|
||||
set global innodb_file_format_check=`Antelope`;
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
let $per_table=`select @@innodb_file_per_table`;
|
||||
let $format=`select @@innodb_file_format`;
|
||||
let $mode=`select @@innodb_strict_mode`;
|
||||
set global innodb_file_per_table=off;
|
||||
set global innodb_file_format=`0`;
|
||||
|
||||
|
@ -152,6 +151,10 @@ set global innodb_file_format=``;
|
|||
set global innodb_file_per_table = on;
|
||||
set global innodb_file_format = `1`;
|
||||
|
||||
set innodb_strict_mode = off;
|
||||
create table t1 (id int primary key) engine = innodb key_block_size = 0;
|
||||
drop table t1;
|
||||
|
||||
#set strict_mode
|
||||
set innodb_strict_mode = on;
|
||||
|
||||
|
@ -294,7 +297,6 @@ drop table t8, t9;
|
|||
|
||||
eval set global innodb_file_per_table=$per_table;
|
||||
eval set global innodb_file_format=$format;
|
||||
eval set innodb_strict_mode=$mode;
|
||||
#
|
||||
# Testing of tablespace tagging
|
||||
#
|
||||
|
|
|
@ -166,6 +166,7 @@ level id parent_id
|
|||
1 1007 101
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
show keys from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
|
@ -190,6 +191,7 @@ create table t1 (a int) engine=innodb;
|
|||
insert into t1 values (1), (2);
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
delete from t1 where a = 1;
|
||||
select * from t1;
|
||||
|
@ -738,6 +740,7 @@ world 2
|
|||
hello 1
|
||||
optimize table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
show keys from t1;
|
||||
Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment
|
||||
|
@ -3111,6 +3114,7 @@ BEGIN;
|
|||
INSERT INTO t1 VALUES (1);
|
||||
OPTIMIZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
test.t1 optimize status OK
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (id int PRIMARY KEY, f int NOT NULL, INDEX(f)) ENGINE=InnoDB;
|
||||
|
|
|
@ -18,7 +18,7 @@ SET GLOBAL innodb_file_format='Barracuda';
|
|||
SET GLOBAL innodb_file_per_table=on;
|
||||
|
||||
DROP TABLE IF EXISTS `table0`;
|
||||
CREATE TABLE `table0` ( `col0` tinyint(1) DEFAULT NULL, `col1` tinyint(1) DEFAULT NULL, `col2` tinyint(4) DEFAULT NULL, `col3` date DEFAULT NULL, `col4` time DEFAULT NULL, `col5` set('test1','test2','test3') DEFAULT NULL, `col6` time DEFAULT NULL, `col7` text, `col8` decimal(10,0) DEFAULT NULL, `col9` set('test1','test2','test3') DEFAULT NULL, `col10` float DEFAULT NULL, `col11` double DEFAULT NULL, `col12` enum('test1','test2','test3') DEFAULT NULL, `col13` tinyblob, `col14` year(4) DEFAULT NULL, `col15` set('test1','test2','test3') DEFAULT NULL, `col16` decimal(10,0) DEFAULT NULL, `col17` decimal(10,0) DEFAULT NULL, `col18` blob, `col19` datetime DEFAULT NULL, `col20` double DEFAULT NULL, `col21` decimal(10,0) DEFAULT NULL, `col22` datetime DEFAULT NULL, `col23` decimal(10,0) DEFAULT NULL, `col24` decimal(10,0) DEFAULT NULL, `col25` longtext, `col26` tinyblob, `col27` time DEFAULT NULL, `col28` tinyblob, `col29` enum('test1','test2','test3') DEFAULT NULL, `col30` smallint(6) DEFAULT NULL, `col31` double DEFAULT NULL, `col32` float DEFAULT NULL, `col33` char(175) DEFAULT NULL, `col34` tinytext, `col35` tinytext, `col36` tinyblob, `col37` tinyblob, `col38` tinytext, `col39` mediumblob, `col40` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `col41` double DEFAULT NULL, `col42` smallint(6) DEFAULT NULL, `col43` longblob, `col44` varchar(80) DEFAULT NULL, `col45` mediumtext, `col46` decimal(10,0) DEFAULT NULL, `col47` bigint(20) DEFAULT NULL, `col48` date DEFAULT NULL, `col49` tinyblob, `col50` date DEFAULT NULL, `col51` tinyint(1) DEFAULT NULL, `col52` mediumint(9) DEFAULT NULL, `col53` float DEFAULT NULL, `col54` tinyblob, `col55` longtext, `col56` smallint(6) DEFAULT NULL, `col57` enum('test1','test2','test3') DEFAULT NULL, `col58` datetime DEFAULT NULL, `col59` mediumtext, `col60` varchar(232) DEFAULT NULL, `col61` decimal(10,0) DEFAULT NULL, `col62` year(4) DEFAULT NULL, `col63` smallint(6) DEFAULT NULL, `col64` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col65` blob, `col66` longblob, `col67` int(11) DEFAULT NULL, `col68` longtext, `col69` enum('test1','test2','test3') DEFAULT NULL, `col70` int(11) DEFAULT NULL, `col71` time DEFAULT NULL, `col72` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col73` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col74` varchar(170) DEFAULT NULL, `col75` set('test1','test2','test3') DEFAULT NULL, `col76` tinyblob, `col77` bigint(20) DEFAULT NULL, `col78` decimal(10,0) DEFAULT NULL, `col79` datetime DEFAULT NULL, `col80` year(4) DEFAULT NULL, `col81` decimal(10,0) DEFAULT NULL, `col82` longblob, `col83` text, `col84` char(83) DEFAULT NULL, `col85` decimal(10,0) DEFAULT NULL, `col86` float DEFAULT NULL, `col87` int(11) DEFAULT NULL, `col88` varchar(145) DEFAULT NULL, `col89` date DEFAULT NULL, `col90` decimal(10,0) DEFAULT NULL, `col91` decimal(10,0) DEFAULT NULL, `col92` mediumblob, `col93` time DEFAULT NULL, KEY `idx0` (`col69`,`col90`,`col8`), KEY `idx1` (`col60`), KEY `idx2` (`col60`,`col70`,`col74`), KEY `idx3` (`col22`,`col32`,`col72`,`col30`), KEY `idx4` (`col29`), KEY `idx5` (`col19`,`col45`(143)), KEY `idx6` (`col46`,`col48`,`col5`,`col39`(118)), KEY `idx7` (`col48`,`col61`), KEY `idx8` (`col93`), KEY `idx9` (`col31`), KEY `idx10` (`col30`,`col21`), KEY `idx11` (`col67`), KEY `idx12` (`col44`,`col6`,`col8`,`col38`(226)), KEY `idx13` (`col71`,`col41`,`col15`,`col49`(88)), KEY `idx14` (`col78`), KEY `idx15` (`col63`,`col67`,`col64`), KEY `idx16` (`col17`,`col86`), KEY `idx17` (`col77`,`col56`,`col10`,`col55`(24)), KEY `idx18` (`col62`), KEY `idx19` (`col31`,`col57`,`col56`,`col53`), KEY `idx20` (`col46`), KEY `idx21` (`col83`(54)), KEY `idx22` (`col51`,`col7`(120)), KEY `idx23` (`col7`(163),`col31`,`col71`,`col14`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1;
|
||||
CREATE TABLE `table0` ( `col0` tinyint(1) DEFAULT NULL, `col1` tinyint(1) DEFAULT NULL, `col2` tinyint(4) DEFAULT NULL, `col3` date DEFAULT NULL, `col4` time DEFAULT NULL, `col5` set('test1','test2','test3') DEFAULT NULL, `col6` time DEFAULT NULL, `col7` text, `col8` decimal(10,0) DEFAULT NULL, `col9` set('test1','test2','test3') DEFAULT NULL, `col10` float DEFAULT NULL, `col11` double DEFAULT NULL, `col12` enum('test1','test2','test3') DEFAULT NULL, `col13` tinyblob, `col14` year(4) DEFAULT NULL, `col15` set('test1','test2','test3') DEFAULT NULL, `col16` decimal(10,0) DEFAULT NULL, `col17` decimal(10,0) DEFAULT NULL, `col18` blob, `col19` datetime DEFAULT NULL, `col20` double DEFAULT NULL, `col21` decimal(10,0) DEFAULT NULL, `col22` datetime DEFAULT NULL, `col23` decimal(10,0) DEFAULT NULL, `col24` decimal(10,0) DEFAULT NULL, `col25` longtext, `col26` tinyblob, `col27` time DEFAULT NULL, `col28` tinyblob, `col29` enum('test1','test2','test3') DEFAULT NULL, `col30` smallint(6) DEFAULT NULL, `col31` double DEFAULT NULL, `col32` float DEFAULT NULL, `col33` char(175) DEFAULT NULL, `col34` tinytext, `col35` tinytext, `col36` tinyblob, `col37` tinyblob, `col38` tinytext, `col39` mediumblob, `col40` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `col41` double DEFAULT NULL, `col42` smallint(6) DEFAULT NULL, `col43` longblob, `col44` varchar(80) DEFAULT NULL, `col45` mediumtext, `col46` decimal(10,0) DEFAULT NULL, `col47` bigint(20) DEFAULT NULL, `col48` date DEFAULT NULL, `col49` tinyblob, `col50` date DEFAULT NULL, `col51` tinyint(1) DEFAULT NULL, `col52` mediumint(9) DEFAULT NULL, `col53` float DEFAULT NULL, `col54` tinyblob, `col55` longtext, `col56` smallint(6) DEFAULT NULL, `col57` enum('test1','test2','test3') DEFAULT NULL, `col58` datetime DEFAULT NULL, `col59` mediumtext, `col60` varchar(232) DEFAULT NULL, `col61` decimal(10,0) DEFAULT NULL, `col62` year(4) DEFAULT NULL, `col63` smallint(6) DEFAULT NULL, `col64` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col65` blob, `col66` longblob, `col67` int(11) DEFAULT NULL, `col68` longtext, `col69` enum('test1','test2','test3') DEFAULT NULL, `col70` int(11) DEFAULT NULL, `col71` time DEFAULT NULL, `col72` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col73` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `col74` varchar(170) DEFAULT NULL, `col75` set('test1','test2','test3') DEFAULT NULL, `col76` tinyblob, `col77` bigint(20) DEFAULT NULL, `col78` decimal(10,0) DEFAULT NULL, `col79` datetime DEFAULT NULL, `col80` year(4) DEFAULT NULL, `col81` decimal(10,0) DEFAULT NULL, `col82` longblob, `col83` text, `col84` char(83) DEFAULT NULL, `col85` decimal(10,0) DEFAULT NULL, `col86` float DEFAULT NULL, `col87` int(11) DEFAULT NULL, `col88` varchar(145) DEFAULT NULL, `col89` date DEFAULT NULL, `col90` decimal(10,0) DEFAULT NULL, `col91` decimal(10,0) DEFAULT NULL, `col92` mediumblob, `col93` time DEFAULT NULL, KEY `idx0` (`col69`,`col90`,`col8`), KEY `idx1` (`col60`), KEY `idx2` (`col60`,`col70`,`col74`), KEY `idx3` (`col22`,`col32`,`col72`,`col30`), KEY `idx4` (`col29`), KEY `idx5` (`col19`,`col45`(143)), KEY `idx6` (`col46`,`col48`,`col5`,`col39`(118)), KEY `idx7` (`col48`,`col61`), KEY `idx8` (`col93`), KEY `idx9` (`col31`), KEY `idx10` (`col30`,`col21`), KEY `idx11` (`col67`), KEY `idx12` (`col44`,`col6`,`col8`,`col38`(226)), KEY `idx13` (`col71`,`col41`,`col15`,`col49`(88)), KEY `idx14` (`col78`), KEY `idx15` (`col63`,`col67`,`col64`), KEY `idx16` (`col17`,`col86`), KEY `idx17` (`col77`,`col56`,`col10`,`col55`(24)), KEY `idx18` (`col62`), KEY `idx19` (`col31`,`col57`,`col56`,`col53`), KEY `idx20` (`col46`), KEY `idx21` (`col83`(54)), KEY `idx22` (`col51`,`col7`(120)), KEY `idx23` (`col7`(163),`col31`,`col71`,`col14`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=2;
|
||||
insert ignore into `table0` set `col23` = 7887371.5084383683, `col24` = 4293854615.6906948000, `col25` = 'vitalist', `col26` = 'widespread', `col27` = '3570490', `col28` = 'habitual', `col30` = -5471, `col31` = 4286985783.6771750000, `col32` = 6354540.9826654866, `col33` = 'defoliation', `col34` = 'logarithms', `col35` = 'tegument\'s', `col36` = 'scouting\'s', `col37` = 'intermittency', `col38` = 'elongates', `col39` = 'prophecies', `col40` = '20560103035939', `col41` = 4292809130.0544143000, `col42` = 22057, `col43` = 'Hess\'s', `col44` = 'bandstand', `col45` = 'phenylketonuria', `col46` = 6338767.4018677324, `col47` = 5310247, `col48` = '12592418', `col49` = 'churchman\'s', `col50` = '32226125', `col51` = -58, `col52` = -6207968, `col53` = 1244839.3255104220, `col54` = 'robotized', `col55` = 'monotonous', `col56` = -26909, `col58` = '20720107023550', `col59` = 'suggestiveness\'s', `col60` = 'gemology', `col61` = 4287800670.2229986000, `col62` = '1944', `col63` = -16827, `col64` = '20700107212324', `col65` = 'Nicolais', `col66` = 'apteryx', `col67` = 6935317, `col68` = 'stroganoff', `col70` = 3316430, `col71` = '3277608', `col72` = '19300511045918', `col73` = '20421201003327', `col74` = 'attenuant', `col75` = '15173', `col76` = 'upstroke\'s', `col77` = 8118987, `col78` = 6791516.2735374002, `col79` = '20780701144624', `col80` = '2134', `col81` = 4290682351.3127537000, `col82` = 'unexplainably', `col83` = 'Storm', `col84` = 'Greyso\'s', `col85` = 4289119212.4306774000, `col86` = 7617575.8796655172, `col87` = -6325335, `col88` = 'fondue\'s', `col89` = '40608940', `col90` = 1659421.8093508712, `col91` = 8346904.6584368423, `col92` = 'reloads', `col93` = '5188366';
|
||||
CHECK TABLE table0 EXTENDED;
|
||||
INSERT IGNORE INTO `table0` SET `col19` = '19940127002709', `col20` = 2383927.9055146948, `col21` = 4293243420.5621204000, `col22` = '20511211123705', `col23` = 4289899778.6573381000, `col24` = 4293449279.0540481000, `col25` = 'emphysemic', `col26` = 'dentally', `col27` = '2347406', `col28` = 'eruct', `col30` = 1222, `col31` = 4294372994.9941406000, `col32` = 4291385574.1173744000, `col33` = 'borrowing\'s', `col34` = 'septics', `col35` = 'ratter\'s', `col36` = 'Kaye', `col37` = 'Florentia', `col38` = 'allium', `col39` = 'barkeep', `col40` = '19510407003441', `col41` = 4293559200.4215522000, `col42` = 22482, `col43` = 'decussate', `col44` = 'Brom\'s', `col45` = 'violated', `col46` = 4925506.4635456400, `col47` = 930549, `col48` = '51296066', `col49` = 'voluminously', `col50` = '29306676', `col51` = -88, `col52` = -2153690, `col53` = 4290250202.1464887000, `col54` = 'expropriation', `col55` = 'Aberdeen\'s', `col56` = 20343, `col58` = '19640415171532', `col59` = 'extern', `col60` = 'Ubana', `col61` = 4290487961.8539081000, `col62` = '2147', `col63` = -24271, `col64` = '20750801194548', `col65` = 'Cunaxa\'s', `col66` = 'pasticcio', `col67` = 2795817, `col68` = 'Indore\'s', `col70` = 6864127, `col71` = '1817832', `col72` = '20540506114211', `col73` = '20040101012300', `col74` = 'rationalized', `col75` = '45522', `col76` = 'indene', `col77` = -6964559, `col78` = 4247535.5266884370, `col79` = '20720416124357', `col80` = '2143', `col81` = 4292060102.4466386000, `col82` = 'striving', `col83` = 'boneblack\'s', `col84` = 'redolent', `col85` = 6489697.9009369183, `col86` = 4287473465.9731131000, `col87` = 7726015, `col88` = 'perplexed', `col89` = '17153791', `col90` = 5478587.1108127078, `col91` = 4287091404.7004304000, `col92` = 'Boulez\'s', `col93` = '2931278';
|
||||
|
|
|
@ -3203,15 +3203,7 @@ 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));
|
||||
|
@ -4263,7 +4255,7 @@ page_zip_reorganize(
|
|||
/* Recreate the page: note that global data on page (possible
|
||||
segment headers, next page-field, etc.) is preserved intact */
|
||||
|
||||
page_create(block, mtr, dict_table_is_comp(index->table));
|
||||
page_create(block, mtr, TRUE);
|
||||
block->check_index_page_at_flush = TRUE;
|
||||
|
||||
/* Copy the records from the temporary space to the recreated page;
|
||||
|
|
|
@ -2181,14 +2181,6 @@ row_merge_create_index(
|
|||
|
||||
ut_a(index);
|
||||
|
||||
/* Create the index id, as it will be required when we build
|
||||
the index. We assign the id here because we want to write an
|
||||
UNDO record before we insert the entry into SYS_INDEXES. */
|
||||
ut_a(ut_dulint_is_zero(index->id));
|
||||
|
||||
index->id = dict_hdr_get_new_id(DICT_HDR_INDEX_ID);
|
||||
index->table = table;
|
||||
|
||||
for (i = 0; i < n_fields; i++) {
|
||||
merge_index_field_t* ifield = &index_def->fields[i];
|
||||
|
||||
|
@ -2196,8 +2188,7 @@ row_merge_create_index(
|
|||
ifield->prefix_len);
|
||||
}
|
||||
|
||||
/* Add the index to SYS_INDEXES, this will use the prototype
|
||||
to create an entry in SYS_INDEXES. */
|
||||
/* Add the index to SYS_INDEXES, using the index prototype. */
|
||||
err = row_merge_create_index_graph(trx, table, index);
|
||||
|
||||
if (err == DB_SUCCESS) {
|
||||
|
|
|
@ -32,6 +32,7 @@ Created 12/19/1997 Heikki Tuuri
|
|||
#include "row0mysql.h"
|
||||
#include "read0read.h"
|
||||
#include "buf0lru.h"
|
||||
#include "ha_prototypes.h"
|
||||
|
||||
/* Maximum number of rows to prefetch; MySQL interface has another parameter */
|
||||
#define SEL_MAX_N_PREFETCH 16
|
||||
|
@ -3699,19 +3700,11 @@ shortcut_fails_too_big_rec:
|
|||
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
&& prebuilt->select_lock_type != LOCK_NONE
|
||||
&& trx->mysql_thd != NULL
|
||||
&& trx->mysql_query_str != NULL
|
||||
&& *trx->mysql_query_str != NULL) {
|
||||
&& thd_is_select(trx->mysql_thd)) {
|
||||
/* It is a plain locking SELECT and the isolation
|
||||
level is low: do not lock gaps */
|
||||
|
||||
/* Scan the MySQL query string; check if SELECT is the first
|
||||
word there */
|
||||
|
||||
if (dict_str_starts_with_keyword(
|
||||
trx->mysql_thd, *trx->mysql_query_str, "SELECT")) {
|
||||
/* It is a plain locking SELECT and the isolation
|
||||
level is low: do not lock gaps */
|
||||
|
||||
set_also_gap_locks = FALSE;
|
||||
}
|
||||
set_also_gap_locks = FALSE;
|
||||
}
|
||||
|
||||
/* Note that if the search mode was GE or G, then the cursor
|
||||
|
|
|
@ -1470,7 +1470,7 @@ innobase_start_or_create_for_mysql(void)
|
|||
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
|
||||
reread of the page and restoration to its last known
|
||||
consistent state, this is REQUIRED for the recovery
|
||||
process to work. */
|
||||
err = trx_sys_file_format_max_check(
|
||||
|
|
Loading…
Add table
Reference in a new issue