Below is the list of changes that have just been committed into a local
5.1 repository of tim. When tim does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2006-09-21 03:48:26-06:00, tsmith@stripped +4 -0
Merge siva.hindu.god:/usr/home/tim/m/bk/inno/50
into siva.hindu.god:/usr/home/tim/m/bk/inno/51-t
MERGE: 1.1810.1697.150
storage/innobase/handler/ha_innodb.cc@stripped, 2006-09-21 03:47:53-06:00, tsmith@stripped +1 -0
Null merge
MERGE: 1.202.1.98
storage/innobase/handler/ha_innodb.cc@stripped, 2006-09-21 03:47:25-06:00, tsmith@stripped +0 -0
Merge rename: sql/ha_innodb.cc -> storage/innobase/handler/ha_innodb.cc
storage/innobase/ibuf/ibuf0ibuf.c@stripped, 2006-09-21 03:48:05-06:00, tsmith@stripped +1 -10
Null merge
MERGE: 1.36.6.2
storage/innobase/ibuf/ibuf0ibuf.c@stripped, 2006-09-21 03:47:25-06:00, tsmith@stripped +0 -0
Merge rename: innobase/ibuf/ibuf0ibuf.c -> storage/innobase/ibuf/ibuf0ibuf.c
storage/innobase/include/data0type.h@stripped, 2006-09-21 03:48:14-06:00, tsmith@stripped +0 -3
Null merge
MERGE: 1.20.3.2
storage/innobase/include/data0type.h@stripped, 2006-09-21 03:47:25-06:00, tsmith@stripped +0 -0
Merge rename: innobase/include/data0type.h -> storage/innobase/include/data0type.h
storage/innobase/include/data0type.ic@stripped, 2006-09-21 03:48:19-06:00, tsmith@stripped +0 -7
Null merge
MERGE: 1.24.4.2
storage/innobase/include/data0type.ic@stripped, 2006-09-21 03:47:25-06:00, tsmith@stripped +0 -0
Merge rename: innobase/include/data0type.ic -> storage/innobase/include/data0type.ic
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: tsmith
# Host: siva.hindu.god
# Root: /usr/home/tim/m/bk/inno/51-t/RESYNC
--- 1.36.6.1/innobase/ibuf/ibuf0ibuf.c 2006-09-21 03:48:35 -06:00
+++ 1.50/storage/innobase/ibuf/ibuf0ibuf.c 2006-09-21 03:48:35 -06:00
@@ -29,7 +29,7 @@ Created 7/19/1997 Heikki Tuuri
#include "log0recv.h"
#include "que0que.h"
-/* STRUCTURE OF AN INSERT BUFFER RECORD
+/* STRUCTURE OF AN INSERT BUFFER RECORD
In versions < 4.1.x:
@@ -140,11 +140,11 @@ access order rules. */
/* The insert buffer control structure */
ibuf_t* ibuf = NULL;
-static
-ulint ibuf_rnd = 986058871;
+static ulint ibuf_rnd = 986058871;
ulint ibuf_flush_count = 0;
+#ifdef UNIV_IBUF_DEBUG
/* Dimensions for the ibuf_count array */
#define IBUF_COUNT_N_SPACES 500
#define IBUF_COUNT_N_PAGES 2000
@@ -153,6 +153,7 @@ ulint ibuf_flush_count = 0;
static ulint* ibuf_counts[IBUF_COUNT_N_SPACES];
static ibool ibuf_counts_inited = FALSE;
+#endif
/* The start address for an insert buffer bitmap page bitmap */
#define IBUF_BITMAP PAGE_DATA
@@ -304,10 +305,10 @@ ibuf_tree_root_get(
ut_a(space == 0);
ut_ad(ibuf_inside());
- mtr_x_lock(dict_tree_get_lock((data->index)->tree), mtr);
+ mtr_x_lock(dict_index_get_lock(data->index), mtr);
page = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
- mtr);
+ mtr);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
#endif /* UNIV_SYNC_DEBUG */
@@ -315,6 +316,7 @@ ibuf_tree_root_get(
return(page);
}
+#ifdef UNIV_IBUF_DEBUG
/**********************************************************************
Gets the ibuf count for a given page. */
@@ -339,7 +341,6 @@ ibuf_count_get(
/**********************************************************************
Sets the ibuf count for a given page. */
-#ifdef UNIV_IBUF_DEBUG
static
void
ibuf_count_set(
@@ -369,14 +370,13 @@ ibuf_init_at_db_start(void)
/* Note that also a pessimistic delete can sometimes make a B-tree
grow in size, as the references on the upper levels of the tree can
change */
-
+
ibuf->max_size = buf_pool_get_curr_size() / UNIV_PAGE_SIZE
- / IBUF_POOL_SIZE_PER_MAX_SIZE;
- ibuf->meter = IBUF_THRESHOLD + 1;
+ / IBUF_POOL_SIZE_PER_MAX_SIZE;
UT_LIST_INIT(ibuf->data_list);
- ibuf->size = 0;
+ ibuf->size = 0;
#ifdef UNIV_IBUF_DEBUG
{
@@ -385,28 +385,23 @@ ibuf_init_at_db_start(void)
for (i = 0; i < IBUF_COUNT_N_SPACES; i++) {
ibuf_counts[i] = mem_alloc(sizeof(ulint)
- * IBUF_COUNT_N_PAGES);
+ * IBUF_COUNT_N_PAGES);
for (j = 0; j < IBUF_COUNT_N_PAGES; j++) {
ibuf_count_set(i, j, 0);
}
}
- }
-#endif
- mutex_create(&ibuf_pessimistic_insert_mutex);
-
- mutex_set_level(&ibuf_pessimistic_insert_mutex,
- SYNC_IBUF_PESS_INSERT_MUTEX);
- mutex_create(&ibuf_mutex);
- mutex_set_level(&ibuf_mutex, SYNC_IBUF_MUTEX);
+ ibuf_counts_inited = TRUE;
+ }
+#endif
+ mutex_create(&ibuf_pessimistic_insert_mutex,
+ SYNC_IBUF_PESS_INSERT_MUTEX);
- mutex_create(&ibuf_bitmap_mutex);
+ mutex_create(&ibuf_mutex, SYNC_IBUF_MUTEX);
- mutex_set_level(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
+ mutex_create(&ibuf_bitmap_mutex, SYNC_IBUF_BITMAP_MUTEX);
fil_ibuf_init_at_db_start();
-
- ibuf_counts_inited = TRUE;
}
/**********************************************************************
@@ -427,14 +422,14 @@ ibuf_data_sizes_update(
#endif /* UNIV_SYNC_DEBUG */
old_size = data->size;
-
+
data->free_list_len = flst_get_len(root + PAGE_HEADER
+ PAGE_BTR_IBUF_FREE_LIST, mtr);
data->height = 1 + btr_page_get_level(root, mtr);
data->size = data->seg_size - (1 + data->free_list_len);
- /* the '1 +' is the ibuf header page */
+ /* the '1 +' is the ibuf header page */
ut_ad(data->size < data->seg_size);
if (page_get_n_recs(root) == 0) {
@@ -448,8 +443,10 @@ ibuf_data_sizes_update(
ibuf->size = ibuf->size + data->size - old_size;
-/* fprintf(stderr, "ibuf size %lu, space ibuf size %lu\n", ibuf->size,
- data->size); */
+#if 0
+ fprintf(stderr, "ibuf size %lu, space ibuf size %lu\n",
+ ibuf->size, data->size);
+#endif
}
/**********************************************************************
@@ -473,17 +470,9 @@ ibuf_data_init_for_space(
dict_table_t* table;
dict_index_t* index;
ulint n_used;
-
- ut_a(space == 0);
-
-#ifdef UNIV_LOG_DEBUG
- if (space % 2 == 1) {
- fputs("No ibuf op in replicate space\n", stderr);
+ ut_a(space == 0);
- return(NULL);
- }
-#endif
data = mem_alloc(sizeof(ibuf_data_t));
data->space = space;
@@ -497,15 +486,15 @@ ibuf_data_init_for_space(
header_page = ibuf_header_page_get(space, &mtr);
fseg_n_reserved_pages(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
- &n_used, &mtr);
+ &n_used, &mtr);
ibuf_enter();
-
+
ut_ad(n_used >= 2);
data->seg_size = n_used;
-
+
root = buf_page_get(space, FSP_IBUF_TREE_ROOT_PAGE_NO, RW_X_LATCH,
- &mtr);
+ &mtr);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(root, SYNC_TREE_NODE);
#endif /* UNIV_SYNC_DEBUG */
@@ -514,17 +503,17 @@ ibuf_data_init_for_space(
data->n_inserts = 0;
data->n_merges = 0;
data->n_merged_recs = 0;
-
+
ibuf_data_sizes_update(data, root, &mtr);
-/*
+ /*
if (!data->empty) {
- fprintf(stderr,
-"InnoDB: index entries found in the insert buffer\n");
+ fprintf(stderr,
+ "InnoDB: index entries found in the insert buffer\n");
} else {
- fprintf(stderr,
-"InnoDB: insert buffer empty\n");
+ fprintf(stderr,
+ "InnoDB: insert buffer empty\n");
}
-*/
+ */
mutex_exit(&ibuf_mutex);
mtr_commit(&mtr);
@@ -533,20 +522,21 @@ ibuf_data_init_for_space(
sprintf(buf, "SYS_IBUF_TABLE_%lu", (ulong) space);
/* use old-style record format for the insert buffer */
- table = dict_mem_table_create(buf, space, 2, FALSE);
+ table = dict_mem_table_create(buf, space, 2, 0);
- dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0, 0);
- dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0, 0);
+ dict_mem_table_add_col(table, "PAGE_NO", DATA_BINARY, 0, 0);
+ dict_mem_table_add_col(table, "TYPES", DATA_BINARY, 0, 0);
table->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
dict_table_add_to_cache(table);
- index = dict_mem_index_create(buf, "CLUST_IND", space,
- DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF,2);
+ index = dict_mem_index_create(
+ buf, "CLUST_IND", space,
+ DICT_CLUSTERED | DICT_UNIVERSAL | DICT_IBUF, 2);
- dict_mem_index_add_field(index, "PAGE_NO", 0, 0);
- dict_mem_index_add_field(index, "TYPES", 0, 0);
+ dict_mem_index_add_field(index, "PAGE_NO", 0);
+ dict_mem_index_add_field(index, "TYPES", 0);
index->id = ut_dulint_add(DICT_IBUF_ID_MIN, space);
@@ -574,18 +564,18 @@ ibuf_bitmap_page_init(
{
ulint bit_offset;
ulint byte_offset;
- ulint i;
/* Write all zeros to the bitmap */
bit_offset = XDES_DESCRIBED_PER_PAGE * IBUF_BITS_PER_PAGE;
- byte_offset = bit_offset / 8 + 1;
+ byte_offset = bit_offset / 8 + 1; /* better: (bit_offset + 7) / 8 */
- for (i = IBUF_BITMAP; i < IBUF_BITMAP + byte_offset; i++) {
+ fil_page_set_type(page, FIL_PAGE_IBUF_BITMAP);
- *(page + i) = (byte)0;
- }
+ memset(page + IBUF_BITMAP, 0, byte_offset);
+
+ /* The remaining area (up to the page trailer) is uninitialized. */
mlog_write_initial_log_record(page, MLOG_IBUF_BITMAP_INIT, mtr);
}
@@ -621,8 +611,9 @@ ibuf_bitmap_page_get_bits(
page_t* page, /* in: bitmap page */
ulint page_no,/* in: page whose bits to get */
ulint bit, /* in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ... */
- mtr_t* mtr __attribute__((unused))) /* in: mtr containing an x-latch
- to the bitmap page */
+ mtr_t* mtr __attribute__((unused))) /* in: mtr containing an
+ x-latch to the bitmap
+ page */
{
ulint byte_offset;
ulint bit_offset;
@@ -630,12 +621,14 @@ ibuf_bitmap_page_get_bits(
ulint value;
ut_ad(bit < IBUF_BITS_PER_PAGE);
- ut_ad(IBUF_BITS_PER_PAGE % 2 == 0);
+#if IBUF_BITS_PER_PAGE % 2
+# error "IBUF_BITS_PER_PAGE % 2 != 0"
+#endif
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
- MTR_MEMO_PAGE_X_FIX));
+ MTR_MEMO_PAGE_X_FIX));
bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE
- + bit;
+ + bit;
byte_offset = bit_offset / 8;
bit_offset = bit_offset % 8;
@@ -648,7 +641,7 @@ ibuf_bitmap_page_get_bits(
if (bit == IBUF_BITMAP_FREE) {
ut_ad(bit_offset + 1 < 8);
-
+
value = value * 2 + ut_bit_get_nth(map_byte, bit_offset + 1);
}
@@ -672,15 +665,18 @@ ibuf_bitmap_page_set_bits(
ulint map_byte;
ut_ad(bit < IBUF_BITS_PER_PAGE);
- ut_ad(IBUF_BITS_PER_PAGE % 2 == 0);
+#if IBUF_BITS_PER_PAGE % 2
+# error "IBUF_BITS_PER_PAGE % 2 != 0"
+#endif
ut_ad(mtr_memo_contains(mtr, buf_block_align(page),
- MTR_MEMO_PAGE_X_FIX));
+ MTR_MEMO_PAGE_X_FIX));
#ifdef UNIV_IBUF_DEBUG
ut_a((bit != IBUF_BITMAP_BUFFERED) || (val != FALSE)
- || (0 == ibuf_count_get(buf_frame_get_space_id(page), page_no)));
+ || (0 == ibuf_count_get(buf_frame_get_space_id(page),
+ page_no)));
#endif
bit_offset = (page_no % XDES_DESCRIBED_PER_PAGE) * IBUF_BITS_PER_PAGE
- + bit;
+ + bit;
byte_offset = bit_offset / 8;
bit_offset = bit_offset % 8;
@@ -692,16 +688,16 @@ ibuf_bitmap_page_set_bits(
if (bit == IBUF_BITMAP_FREE) {
ut_ad(bit_offset + 1 < 8);
ut_ad(val <= 3);
-
+
map_byte = ut_bit_set_nth(map_byte, bit_offset, val / 2);
map_byte = ut_bit_set_nth(map_byte, bit_offset + 1, val % 2);
} else {
ut_ad(val <= 1);
map_byte = ut_bit_set_nth(map_byte, bit_offset, val);
}
-
+
mlog_write_ulint(page + IBUF_BITMAP + byte_offset, map_byte,
- MLOG_1BYTE, mtr);
+ MLOG_1BYTE, mtr);
}
/************************************************************************
@@ -716,7 +712,7 @@ ibuf_bitmap_page_no_calc(
{
return(FSP_IBUF_BITMAP_OFFSET
+ XDES_DESCRIBED_PER_PAGE
- * (page_no / XDES_DESCRIBED_PER_PAGE));
+ * (page_no / XDES_DESCRIBED_PER_PAGE));
}
/************************************************************************
@@ -737,7 +733,7 @@ ibuf_bitmap_get_map_page(
page_t* page;
page = buf_page_get(space, ibuf_bitmap_page_no_calc(page_no),
- RW_X_LATCH, mtr);
+ RW_X_LATCH, mtr);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_IBUF_BITMAP);
#endif /* UNIV_SYNC_DEBUG */
@@ -772,18 +768,21 @@ ibuf_set_free_bits_low(
return;
}
- bitmap_page = ibuf_bitmap_get_map_page(buf_frame_get_space_id(page),
- buf_frame_get_page_no(page), mtr);
+ bitmap_page = ibuf_bitmap_get_map_page(
+ buf_frame_get_space_id(page),
+ buf_frame_get_page_no(page), mtr);
#ifdef UNIV_IBUF_DEBUG
- /* fprintf(stderr,
+# if 0
+ fprintf(stderr,
"Setting page no %lu free bits to %lu should be %lu\n",
- buf_frame_get_page_no(page), val,
- ibuf_index_page_calc_free(page)); */
-
+ buf_frame_get_page_no(page), val,
+ ibuf_index_page_calc_free(page));
+# endif
+
ut_a(val <= ibuf_index_page_calc_free(page));
-#endif
+#endif /* UNIV_IBUF_DEBUG */
ibuf_bitmap_page_set_bits(bitmap_page, buf_frame_get_page_no(page),
- IBUF_BITMAP_FREE, val, mtr);
+ IBUF_BITMAP_FREE, val, mtr);
}
@@ -818,35 +817,41 @@ ibuf_set_free_bits(
}
mtr_start(&mtr);
-
- bitmap_page = ibuf_bitmap_get_map_page(buf_frame_get_space_id(page),
- buf_frame_get_page_no(page), &mtr);
+
+ bitmap_page = ibuf_bitmap_get_map_page(
+ buf_frame_get_space_id(page), buf_frame_get_page_no(page),
+ &mtr);
if (max_val != ULINT_UNDEFINED) {
#ifdef UNIV_IBUF_DEBUG
ulint old_val;
- old_val = ibuf_bitmap_page_get_bits(bitmap_page,
- buf_frame_get_page_no(page),
- IBUF_BITMAP_FREE, &mtr);
+ old_val = ibuf_bitmap_page_get_bits(
+ bitmap_page, buf_frame_get_page_no(page),
+ IBUF_BITMAP_FREE, &mtr);
+# if 0
if (old_val != max_val) {
- /* fprintf(stderr,
- "Ibuf: page %lu old val %lu max val %lu\n",
- buf_frame_get_page_no(page), old_val, max_val); */
+ fprintf(stderr,
+ "Ibuf: page %lu old val %lu max val %lu\n",
+ buf_frame_get_page_no(page),
+ old_val, max_val);
}
+# endif
ut_a(old_val <= max_val);
#endif
}
#ifdef UNIV_IBUF_DEBUG
-/* fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n",
- buf_frame_get_page_no(page), val,
- ibuf_index_page_calc_free(page)); */
+# if 0
+ fprintf(stderr, "Setting page no %lu free bits to %lu should be %lu\n",
+ buf_frame_get_page_no(page), val,
+ ibuf_index_page_calc_free(page));
+# endif
ut_a(val <= ibuf_index_page_calc_free(page));
-#endif
+#endif
ibuf_bitmap_page_set_bits(bitmap_page, buf_frame_get_page_no(page),
- IBUF_BITMAP_FREE, val, &mtr);
+ IBUF_BITMAP_FREE, val, &mtr);
mtr_commit(&mtr);
}
@@ -931,7 +936,7 @@ ibuf_update_free_bits_for_two_pages_low(
performed by another OS thread. */
mutex_enter(&ibuf_bitmap_mutex);
-
+
state = ibuf_index_page_calc_free(page1);
ibuf_set_free_bits_low(index->type, page1, state, mtr);
@@ -954,7 +959,7 @@ ibuf_fixed_addr_page(
ulint page_no)/* in: page number */
{
return((space == 0 && page_no == IBUF_TREE_ROOT_PAGE_NO)
- || ibuf_bitmap_page(page_no));
+ || ibuf_bitmap_page(page_no));
}
/***************************************************************************
@@ -996,7 +1001,7 @@ ibuf_page(
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
- &mtr);
+ &mtr);
mtr_commit(&mtr);
return(ret);
@@ -1018,14 +1023,6 @@ ibuf_page_low(
page_t* bitmap_page;
ibool ret;
-#ifdef UNIV_LOG_DEBUG
- if (space % 2 != 0) {
-
- fputs("No ibuf in a replicate space\n", stderr);
-
- return(FALSE);
- }
-#endif
if (ibuf_fixed_addr_page(space, page_no)) {
return(TRUE);
@@ -1034,7 +1031,7 @@ ibuf_page_low(
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, mtr);
ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
- mtr);
+ mtr);
return(ret);
}
@@ -1119,13 +1116,19 @@ ibuf_dummy_index_create(
{
dict_table_t* table;
dict_index_t* index;
+
table = dict_mem_table_create("IBUF_DUMMY",
- DICT_HDR_SPACE, n, comp);
+ DICT_HDR_SPACE, n,
+ comp ? DICT_TF_COMPACT : 0);
+
index = dict_mem_index_create("IBUF_DUMMY", "IBUF_DUMMY",
- DICT_HDR_SPACE, 0, n);
+ DICT_HDR_SPACE, 0, n);
+
index->table = table;
+
/* avoid ut_ad(index->cached) in dict_index_get_n_unique_in_tree */
index->cached = TRUE;
+
return(index);
}
/************************************************************************
@@ -1133,19 +1136,18 @@ Add a column to the dummy index */
static
void
ibuf_dummy_index_add_col(
-/*====================*/
+/*=====================*/
dict_index_t* index, /* in: dummy index */
dtype_t* type, /* in: the data type of the column */
ulint len) /* in: length of the column */
{
ulint i = index->table->n_def;
dict_mem_table_add_col(index->table, "DUMMY",
- dtype_get_mtype(type),
- dtype_get_prtype(type),
- dtype_get_len(type),
- dtype_get_prec(type));
- dict_index_add_col(index,
- dict_table_get_nth_col(index->table, i), 0, len);
+ dtype_get_mtype(type),
+ dtype_get_prtype(type),
+ dtype_get_len(type));
+ dict_index_add_col(index, index->table, (dict_col_t*)
+ dict_table_get_nth_col(index->table, i), len);
}
/************************************************************************
Deallocates a dummy index for inserting a record to a non-clustered index.
@@ -1153,7 +1155,7 @@ Deallocates a dummy index for inserting
static
void
ibuf_dummy_index_free(
-/*====================*/
+/*==================*/
dict_index_t* index) /* in: dummy index */
{
dict_table_t* table = index->table;
@@ -1162,6 +1164,11 @@ ibuf_dummy_index_free(
dict_mem_table_free(table);
}
+void
+dict_index_print_low(
+/*=================*/
+ dict_index_t* index); /* in: index */
+
/*************************************************************************
Builds the entry to insert into a non-clustered index when we have the
corresponding record in an ibuf index. */
@@ -1232,8 +1239,8 @@ ibuf_build_entry_from_ibuf_rec(
types = rec_get_nth_field_old(ibuf_rec, 3, &len);
ut_a(len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE <= 1);
- index = ibuf_dummy_index_create(n_fields,
- len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
+ index = ibuf_dummy_index_create(
+ n_fields, len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
if (len % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE) {
/* compact record format */
@@ -1312,9 +1319,8 @@ ibuf_rec_get_volume(
ulint volume;
dict_index_t* dummy_index;
mem_heap_t* heap = mem_heap_create(500);
- dtuple_t* entry =
- ibuf_build_entry_from_ibuf_rec(
- ibuf_rec, heap, &dummy_index);
+ dtuple_t* entry = ibuf_build_entry_from_ibuf_rec(
+ ibuf_rec, heap, &dummy_index);
volume = rec_get_converted_size(dummy_index, entry);
ibuf_dummy_index_free(dummy_index);
mem_heap_free(heap);
@@ -1330,13 +1336,15 @@ ibuf_rec_get_volume(
if (new_format) {
data = rec_get_nth_field_old(ibuf_rec, i + 4, &len);
- dtype_new_read_for_order_and_null_size(&dtype,
- types + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
+ dtype_new_read_for_order_and_null_size(
+ &dtype, types + i
+ * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE);
} else {
data = rec_get_nth_field_old(ibuf_rec, i + 2, &len);
- dtype_read_for_order_and_null_size(&dtype,
- types + i * DATA_ORDER_NULL_TYPE_BUF_SIZE);
+ dtype_read_for_order_and_null_size(
+ &dtype, types + i
+ * DATA_ORDER_NULL_TYPE_BUF_SIZE);
}
if (len == UNIV_SQL_NULL) {
@@ -1347,7 +1355,7 @@ ibuf_rec_get_volume(
}
return(data_size + rec_get_converted_extra_size(data_size, n_fields)
- + page_dir_calc_reserved_space(1));
+ + page_dir_calc_reserved_space(1));
}
/*************************************************************************
@@ -1375,7 +1383,7 @@ ibuf_entry_build(
byte* buf;
byte* buf2;
ulint i;
-
+
/* Starting from 4.1.x, we have to build a tuple whose
(1) first field is the space id,
(2) the second field a single marker byte (0) to tell that this
@@ -1383,9 +1391,9 @@ ibuf_entry_build(
(3) the third contains the page number, and
(4) the fourth contains the relevent type information of each data
field; the length of this field % DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE is
- (a) 0 for b-trees in the old format, and
- (b) 1 for b-trees in the compact format, the first byte of the field
- being the marker (0);
+ (a) 0 for b-trees in the old format, and
+ (b) 1 for b-trees in the compact format, the first byte of the field
+ being the marker (0);
(5) and the rest of the fields are copied from entry. All fields
in the tuple are ordered like the type binary in our insert buffer
tree. */
@@ -1426,13 +1434,12 @@ ibuf_entry_build(
dfield_set_data(field, buf, 4);
- ut_ad(index->table->comp <= 1);
/* Store the type info in buf2, and add the fields from entry to
tuple */
buf2 = mem_heap_alloc(heap, n_fields
- * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
- + index->table->comp);
- if (index->table->comp) {
+ * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
+ + dict_table_is_comp(index->table));
+ if (dict_table_is_comp(index->table)) {
*buf2++ = 0; /* write the compact format indicator */
}
for (i = 0; i < n_fields; i++) {
@@ -1444,29 +1451,28 @@ ibuf_entry_build(
dfield_copy(field, entry_field);
dtype_new_store_for_order_and_null_size(
- buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
- dfield_get_type(entry_field),
- dict_index_get_nth_field(index, i)
- ->prefix_len);
+ buf2 + i * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE,
+ dfield_get_type(entry_field),
+ dict_index_get_nth_field(index, i)->prefix_len);
}
/* Store the type info in buf2 to field 3 of tuple */
field = dtuple_get_nth_field(tuple, 3);
- if (index->table->comp) {
+ if (dict_table_is_comp(index->table)) {
buf2--;
}
dfield_set_data(field, buf2, n_fields
- * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
- + index->table->comp);
+ * DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
+ + dict_table_is_comp(index->table));
/* Set all the types in the new tuple binary */
dtuple_set_types_binary(tuple, n_fields + 4);
return(tuple);
-}
+}
/*************************************************************************
Builds a search tuple used to search buffered inserts for an index page.
@@ -1483,7 +1489,7 @@ ibuf_search_tuple_build(
dtuple_t* tuple;
dfield_t* field;
byte* buf;
-
+
ut_a(space == 0);
ut_a(trx_doublewrite_must_reset_space_ids);
ut_a(!trx_sys_multiple_tablespace_format);
@@ -1520,7 +1526,7 @@ ibuf_new_search_tuple_build(
dtuple_t* tuple;
dfield_t* field;
byte* buf;
-
+
ut_a(trx_sys_multiple_tablespace_format);
tuple = dtuple_create(heap, 3);
@@ -1636,7 +1642,7 @@ ibuf_add_free_page(
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
mtr_x_lock(fil_space_get_latch(space), &mtr);
-
+
header_page = ibuf_header_page_get(space, &mtr);
/* Allocate a new page: NOTE that if the page has been a part of a
@@ -1650,8 +1656,8 @@ ibuf_add_free_page(
header page apart from the ibuf tree. */
page_no = fseg_alloc_free_page(header_page + IBUF_HEADER
- + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
- &mtr);
+ + IBUF_TREE_SEG_HEADER, 0, FSP_UP,
+ &mtr);
if (page_no == FIL_NULL) {
mtr_commit(&mtr);
@@ -1675,7 +1681,8 @@ ibuf_add_free_page(
flst_add_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
- fil_page_set_type(page, FIL_PAGE_IBUF_FREE_LIST);
+ mlog_write_ulint(page + FIL_PAGE_TYPE, FIL_PAGE_IBUF_FREE_LIST,
+ MLOG_2BYTES, &mtr);
ibuf_data->seg_size++;
ibuf_data->free_list_len++;
@@ -1686,7 +1693,7 @@ ibuf_add_free_page(
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
- TRUE, &mtr);
+ TRUE, &mtr);
mtr_commit(&mtr);
mutex_exit(&ibuf_mutex);
@@ -1720,7 +1727,7 @@ ibuf_remove_free_page(
/* Acquire the fsp latch before the ibuf header, obeying the latching
order */
mtr_x_lock(fil_space_get_latch(space), &mtr);
-
+
header_page = ibuf_header_page_get(space, &mtr);
/* Prevent pessimistic inserts to insert buffer trees for a while */
@@ -1735,51 +1742,51 @@ ibuf_remove_free_page(
mutex_exit(&ibuf_mutex);
ibuf_exit();
-
+
mutex_exit(&ibuf_pessimistic_insert_mutex);
mtr_commit(&mtr);
return;
}
-
+
mtr_start(&mtr2);
-
+
root = ibuf_tree_root_get(ibuf_data, space, &mtr2);
page_no = flst_get_last(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
- &mtr2)
- .page;
+ &mtr2)
+ .page;
/* NOTE that we must release the latch on the ibuf tree root
because in fseg_free_page we access level 1 pages, and the root
is a level 2 page. */
-
+
mtr_commit(&mtr2);
mutex_exit(&ibuf_mutex);
ibuf_exit();
-
+
/* Since pessimistic inserts were prevented, we know that the
page is still in the free list. NOTE that also deletes may take
pages from the free list, but they take them from the start, and
the free list was so long that they cannot have taken the last
page from it. */
-
+
fseg_free_page(header_page + IBUF_HEADER + IBUF_TREE_SEG_HEADER,
- space, page_no, &mtr);
+ space, page_no, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_reset_file_page_was_freed(space, page_no);
#endif
ibuf_enter();
-
+
mutex_enter(&ibuf_mutex);
root = ibuf_tree_root_get(ibuf_data, space, &mtr);
ut_ad(page_no == flst_get_last(root + PAGE_HEADER
- + PAGE_BTR_IBUF_FREE_LIST, &mtr)
- .page);
+ + PAGE_BTR_IBUF_FREE_LIST, &mtr)
+ .page);
page = buf_page_get(space, page_no, RW_X_LATCH, &mtr);
@@ -1788,13 +1795,13 @@ ibuf_remove_free_page(
#endif /* UNIV_SYNC_DEBUG */
/* Remove the page from the free list and update the ibuf size data */
-
+
flst_remove(root + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST,
page + PAGE_HEADER + PAGE_BTR_IBUF_FREE_LIST_NODE, &mtr);
ibuf_data->seg_size--;
ibuf_data->free_list_len--;
-
+
mutex_exit(&ibuf_pessimistic_insert_mutex);
/* Set the bit indicating that this page is no more an ibuf tree page
@@ -1803,7 +1810,7 @@ ibuf_remove_free_page(
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
ibuf_bitmap_page_set_bits(bitmap_page, page_no, IBUF_BITMAP_IBUF,
- FALSE, &mtr);
+ FALSE, &mtr);
#ifdef UNIV_DEBUG_FILE_ACCESSES
buf_page_set_file_page_was_freed(space, page_no);
#endif
@@ -1817,7 +1824,7 @@ ibuf_remove_free_page(
/***************************************************************************
Frees excess pages from the ibuf free list. This function is called when an OS
thread calls fsp services to allocate a new file segment, or a new page to a
-file segment, and the thread did not own the fsp latch before this call. */
+file segment, and the thread did not own the fsp latch before this call. */
void
ibuf_free_excess_pages(
@@ -1828,8 +1835,9 @@ ibuf_free_excess_pages(
ulint i;
if (space != 0) {
- fprintf(stderr,
-"InnoDB: Error: calling ibuf_free_excess_pages for space %lu\n", (ulong) space);
+ fprintf(stderr,
+ "InnoDB: Error: calling ibuf_free_excess_pages"
+ " for space %lu\n", (ulong) space);
return;
}
@@ -1838,7 +1846,7 @@ ibuf_free_excess_pages(
#endif /* UNIV_SYNC_DEBUG */
ut_ad(rw_lock_get_x_lock_count(fil_space_get_latch(space)) == 1);
ut_ad(!ibuf_inside());
-
+
/* NOTE: We require that the thread did not own the latch before,
because then we know that we can obey the correct latching order
for ibuf latches */
@@ -1848,9 +1856,9 @@ ibuf_free_excess_pages(
if (ibuf_data == NULL) {
/* Not yet initialized */
-#ifdef UNIV_DEBUG
- /*fprintf(stderr,
- "Ibuf for space %lu not yet initialized\n", space); */
+#if 0 /* defined UNIV_DEBUG */
+ fprintf(stderr,
+ "Ibuf for space %lu not yet initialized\n", space);
#endif
return;
@@ -1936,7 +1944,7 @@ ibuf_get_merge_page_nos(
n_pages = 0;
prev_page_no = 0;
prev_space_id = 0;
-
+
/* Go backwards from the first rec until we reach the border of the
'merge area', or the page start or the limit of storeable pages is
reached */
@@ -1948,11 +1956,11 @@ ibuf_get_merge_page_nos(
if (rec_space_id != first_space_id
|| rec_page_no / IBUF_MERGE_AREA
- != first_page_no / IBUF_MERGE_AREA) {
+ != first_page_no / IBUF_MERGE_AREA) {
- break;
+ break;
}
-
+
if (rec_page_no != prev_page_no
|| rec_space_id != prev_space_id) {
n_pages++;
@@ -1974,7 +1982,7 @@ ibuf_get_merge_page_nos(
prev_space_id = 0;
sum_volumes = 0;
volume_for_page = 0;
-
+
while (*n_stored < limit) {
if (page_rec_is_supremum(rec)) {
/* When no more records available, mark this with
@@ -1992,21 +2000,20 @@ ibuf_get_merge_page_nos(
#endif
if ((rec_space_id != prev_space_id
|| rec_page_no != prev_page_no)
- && (prev_space_id != 0 || prev_page_no != 0)) {
+ && (prev_space_id != 0 || prev_page_no != 0)) {
if ((prev_page_no == first_page_no
&& prev_space_id == first_space_id)
|| contract
- || (volume_for_page >
- ((IBUF_MERGE_THRESHOLD - 1)
- * 4 * UNIV_PAGE_SIZE
- / IBUF_PAGE_SIZE_PER_FREE_SPACE)
- / IBUF_MERGE_THRESHOLD)) {
+ || (volume_for_page
+ > ((IBUF_MERGE_THRESHOLD - 1)
+ * 4 * UNIV_PAGE_SIZE
+ / IBUF_PAGE_SIZE_PER_FREE_SPACE)
+ / IBUF_MERGE_THRESHOLD)) {
- space_ids[*n_stored] = prev_space_id;
+ space_ids[*n_stored] = prev_space_id;
space_versions[*n_stored]
- = fil_space_get_version(
- prev_space_id);
+ = fil_space_get_version(prev_space_id);
page_nos[*n_stored] = prev_page_no;
(*n_stored)++;
@@ -2016,9 +2023,9 @@ ibuf_get_merge_page_nos(
if (rec_space_id != first_space_id
|| rec_page_no / IBUF_MERGE_AREA
- != first_page_no / IBUF_MERGE_AREA) {
+ != first_page_no / IBUF_MERGE_AREA) {
- break;
+ break;
}
volume_for_page = 0;
@@ -2033,7 +2040,7 @@ ibuf_get_merge_page_nos(
rec_volume = ibuf_rec_get_volume(rec);
volume_for_page += rec_volume;
-
+
prev_page_no = rec_page_no;
prev_space_id = rec_space_id;
@@ -2043,8 +2050,10 @@ ibuf_get_merge_page_nos(
#ifdef UNIV_IBUF_DEBUG
ut_a(*n_stored <= IBUF_MAX_N_PAGES_MERGED);
#endif
-/* fprintf(stderr, "Ibuf merge batch %lu pages %lu volume\n", *n_stored,
- sum_volumes); */
+#if 0
+ fprintf(stderr, "Ibuf merge batch %lu pages %lu volume\n",
+ *n_stored, sum_volumes);
+#endif
return(sum_volumes);
}
@@ -2080,7 +2089,7 @@ loop:
mutex_enter(&ibuf_mutex);
- ut_ad(ibuf_validate_low());
+ ut_ad(ibuf_validate_low());
/* Choose an ibuf tree at random (though there really is only one tree
in the current implementation) */
@@ -2095,15 +2104,15 @@ loop:
for (;;) {
if (!data->empty) {
all_trees_empty = FALSE;
-
+
if (rnd_pos < data->size) {
break;
}
-
+
rnd_pos -= data->size;
}
-
+
data = UT_LIST_GET_NEXT(data_list, data);
if (data == NULL) {
@@ -2112,7 +2121,7 @@ loop:
return(0);
}
-
+
data = UT_LIST_GET_FIRST(ibuf->data_list);
}
}
@@ -2126,7 +2135,7 @@ loop:
mtr_start(&mtr);
ibuf_enter();
-
+
/* Open a cursor to a randomly chosen leaf of the tree, at a random
position within the leaf */
@@ -2135,26 +2144,27 @@ loop:
if (0 == page_get_n_recs(btr_pcur_get_page(&pcur))) {
/* This tree is empty */
-
- data->empty = TRUE;
- ibuf_exit();
+ data->empty = TRUE;
+
+ ibuf_exit();
- mtr_commit(&mtr);
- btr_pcur_close(&pcur);
+ mtr_commit(&mtr);
+ btr_pcur_close(&pcur);
- mutex_exit(&ibuf_mutex);
+ mutex_exit(&ibuf_mutex);
- goto loop;
+ goto loop;
}
-
+
mutex_exit(&ibuf_mutex);
sum_sizes = ibuf_get_merge_page_nos(TRUE, btr_pcur_get_rec(&pcur),
- space_ids, space_versions, page_nos, &n_stored);
-#ifdef UNIV_IBUF_DEBUG
- /* fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n",
- sync, n_stored, sum_sizes); */
+ space_ids, space_versions,
+ page_nos, &n_stored);
+#if 0 /* defined UNIV_IBUF_DEBUG */
+ fprintf(stderr, "Ibuf contract sync %lu pages %lu volume %lu\n",
+ sync, n_stored, sum_sizes);
#endif
ibuf_exit();
@@ -2162,9 +2172,9 @@ loop:
btr_pcur_close(&pcur);
buf_read_ibuf_merge_pages(sync, space_ids, space_versions, page_nos,
- n_stored);
+ n_stored);
*n_pages = n_stored;
-
+
return(sum_sizes + 1);
}
@@ -2203,13 +2213,13 @@ ibuf_contract_for_n_pages(
them */
{
ulint sum_bytes = 0;
- ulint sum_pages = 0;
+ ulint sum_pages = 0;
ulint n_bytes;
ulint n_pag2;
-
+
while (sum_pages < n_pages) {
n_bytes = ibuf_contract_ext(&n_pag2, sync);
-
+
if (n_bytes == 0) {
return(sum_bytes);
}
@@ -2243,7 +2253,7 @@ ibuf_contract_after_insert(
}
sync = FALSE;
-
+
if (ibuf->size >= ibuf->max_size + IBUF_CONTRACT_ON_INSERT_SYNC) {
sync = TRUE;
@@ -2290,17 +2300,17 @@ ibuf_get_volume_buffered(
page_t* prev_page;
ulint next_page_no;
page_t* next_page;
-
+
ut_a(trx_sys_multiple_tablespace_format);
ut_ad((pcur->latch_mode == BTR_MODIFY_PREV)
- || (pcur->latch_mode == BTR_MODIFY_TREE));
+ || (pcur->latch_mode == BTR_MODIFY_TREE));
/* Count the volume of records earlier in the alphabetical order than
pcur */
volume = 0;
-
+
rec = btr_pcur_get_rec(pcur);
page = buf_frame_align(rec);
@@ -2314,7 +2324,7 @@ ibuf_get_volume_buffered(
break;
}
-
+
if (page_no != ibuf_rec_get_page_no(rec)
|| space != ibuf_rec_get_space(rec)) {
@@ -2327,7 +2337,7 @@ ibuf_get_volume_buffered(
}
/* Look at the previous page */
-
+
prev_page_no = btr_page_get_prev(page, mtr);
if (prev_page_no == FIL_NULL) {
@@ -2336,6 +2346,10 @@ ibuf_get_volume_buffered(
}
prev_page = buf_page_get(0, prev_page_no, RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_next(prev_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(prev_page, SYNC_TREE_NODE);
@@ -2343,17 +2357,17 @@ ibuf_get_volume_buffered(
rec = page_get_supremum_rec(prev_page);
rec = page_rec_get_prev(rec);
-
+
for (;;) {
if (page_rec_is_infimum(rec)) {
/* We cannot go to yet a previous page, because we
do not have the x-latch on it, and cannot acquire one
because of the latching order: we have to give up */
-
+
return(UNIV_PAGE_SIZE);
}
-
+
if (page_no != ibuf_rec_get_page_no(rec)
|| space != ibuf_rec_get_space(rec)) {
@@ -2364,7 +2378,7 @@ ibuf_get_volume_buffered(
rec = page_rec_get_prev(rec);
}
-
+
count_later:
rec = btr_pcur_get_rec(pcur);
@@ -2377,7 +2391,7 @@ count_later:
break;
}
-
+
if (page_no != ibuf_rec_get_page_no(rec)
|| space != ibuf_rec_get_space(rec)) {
@@ -2390,7 +2404,7 @@ count_later:
}
/* Look at the next page */
-
+
next_page_no = btr_page_get_next(page, mtr);
if (next_page_no == FIL_NULL) {
@@ -2399,6 +2413,10 @@ count_later:
}
next_page = buf_page_get(0, next_page_no, RW_X_LATCH, mtr);
+#ifdef UNIV_BTR_DEBUG
+ ut_a(btr_page_get_prev(next_page, mtr)
+ == buf_frame_get_page_no(page));
+#endif /* UNIV_BTR_DEBUG */
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(next_page, SYNC_TREE_NODE);
@@ -2411,10 +2429,10 @@ count_later:
if (page_rec_is_supremum(rec)) {
/* We give up */
-
+
return(UNIV_PAGE_SIZE);
}
-
+
if (page_no != ibuf_rec_get_page_no(rec)
|| space != ibuf_rec_get_space(rec)) {
@@ -2447,14 +2465,14 @@ ibuf_update_max_tablespace_id(void)
ibuf_data = fil_space_get_ibuf_data(0);
ibuf_index = ibuf_data->index;
- ut_a(!ibuf_index->table->comp);
+ ut_a(!dict_table_is_comp(ibuf_index->table));
ibuf_enter();
mtr_start(&mtr);
btr_pcur_open_at_index_side(FALSE, ibuf_index, BTR_SEARCH_LEAF,
- &pcur, TRUE, &mtr);
+ &pcur, TRUE, &mtr);
btr_pcur_move_to_prev(&pcur, &mtr);
if (btr_pcur_is_before_first_on_page(&pcur, &mtr)) {
@@ -2467,7 +2485,7 @@ ibuf_update_max_tablespace_id(void)
field = rec_get_nth_field_old(rec, 0, &len);
ut_a(len == 4);
-
+
max_space_id = mach_read_from_4(field);
}
@@ -2517,7 +2535,7 @@ ibuf_insert_low(
ulint bits;
mtr_t mtr;
mtr_t bitmap_mtr;
-
+
ut_a(!(index->type & DICT_CLUSTERED));
ut_ad(dtuple_check_typed(entry));
@@ -2542,7 +2560,7 @@ ibuf_insert_low(
#ifdef UNIV_IBUF_DEBUG
fputs("Ibuf too big\n", stderr);
-#endif
+#endif
/* Use synchronous contract (== TRUE) */
ibuf_contract(TRUE);
@@ -2563,7 +2581,7 @@ ibuf_insert_low(
mutex_exit(&ibuf_mutex);
ibuf_exit();
-
+
mutex_exit(&ibuf_pessimistic_insert_mutex);
err = ibuf_add_free_page(0, ibuf_data);
@@ -2576,7 +2594,7 @@ ibuf_insert_low(
mutex_enter(&ibuf_pessimistic_insert_mutex);
ibuf_enter();
-
+
mutex_enter(&ibuf_mutex);
}
} else {
@@ -2587,7 +2605,7 @@ ibuf_insert_low(
heap = mem_heap_create(512);
- /* Build the entry which contains the space id and the page number as
+ /* Build the entry which contains the space id and the page number as
the first fields and the type information for other fields, and which
will be inserted to the insert buffer. */
@@ -2608,14 +2626,14 @@ ibuf_insert_low(
#ifdef UNIV_IBUF_DEBUG
ut_a((buffered == 0) || ibuf_count_get(space, page_no));
#endif
- mtr_start(&bitmap_mtr);
+ mtr_start(&bitmap_mtr);
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &bitmap_mtr);
/* We check if the index page is suitable for buffered entries */
if (buf_page_peek(space, page_no)
- || lock_rec_expl_exist_on_page(space, page_no)) {
+ || lock_rec_expl_exist_on_page(space, page_no)) {
err = DB_STRONG_FAIL;
mtr_commit(&bitmap_mtr);
@@ -2624,37 +2642,39 @@ ibuf_insert_low(
}
bits = ibuf_bitmap_page_get_bits(bitmap_page, page_no,
- IBUF_BITMAP_FREE, &bitmap_mtr);
+ IBUF_BITMAP_FREE, &bitmap_mtr);
if (buffered + entry_size + page_dir_calc_reserved_space(1)
- > ibuf_index_page_calc_free_from_bits(bits)) {
+ > ibuf_index_page_calc_free_from_bits(bits)) {
mtr_commit(&bitmap_mtr);
- /* It may not fit */
+ /* It may not fit */
err = DB_STRONG_FAIL;
- do_merge = TRUE;
+ do_merge = TRUE;
ibuf_get_merge_page_nos(FALSE, btr_pcur_get_rec(&pcur),
space_ids, space_versions,
page_nos, &n_stored);
goto function_exit;
- }
+ }
/* Set the bitmap bit denoting that the insert buffer contains
buffered entries for this index page, if the bit is not set yet */
old_bit_value = ibuf_bitmap_page_get_bits(bitmap_page, page_no,
- IBUF_BITMAP_BUFFERED, &bitmap_mtr);
+ IBUF_BITMAP_BUFFERED,
+ &bitmap_mtr);
if (!old_bit_value) {
ibuf_bitmap_page_set_bits(bitmap_page, page_no,
- IBUF_BITMAP_BUFFERED, TRUE, &bitmap_mtr);
+ IBUF_BITMAP_BUFFERED, TRUE,
+ &bitmap_mtr);
}
mtr_commit(&bitmap_mtr);
-
+
cursor = btr_pcur_get_btr_cur(&pcur);
-
+
if (mode == BTR_MODIFY_PREV) {
err = btr_cur_optimistic_insert(BTR_NO_LOCKING_FLAG, cursor,
ibuf_entry, &ins_rec,
@@ -2663,7 +2683,7 @@ ibuf_insert_low(
if (err == DB_SUCCESS) {
/* Update the page max trx id field */
page_update_max_trx_id(buf_frame_align(ins_rec),
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id);
}
} else {
ut_ad(mode == BTR_MODIFY_TREE);
@@ -2672,19 +2692,19 @@ ibuf_insert_low(
because a pessimistic insert releases the tree x-latch,
which would cause the x-latching of the root after that to
break the latching order. */
-
+
root = ibuf_tree_root_get(ibuf_data, 0, &mtr);
err = btr_cur_pessimistic_insert(BTR_NO_LOCKING_FLAG
| BTR_NO_UNDO_LOG_FLAG,
- cursor,
- ibuf_entry, &ins_rec,
- &dummy_big_rec, thr,
- &mtr);
+ cursor,
+ ibuf_entry, &ins_rec,
+ &dummy_big_rec, thr,
+ &mtr);
if (err == DB_SUCCESS) {
/* Update the page max trx id field */
page_update_max_trx_id(buf_frame_align(ins_rec),
- thr_get_trx(thr)->id);
+ thr_get_trx(thr)->id);
}
ibuf_data_sizes_update(ibuf_data, root, &mtr);
@@ -2693,26 +2713,27 @@ ibuf_insert_low(
function_exit:
#ifdef UNIV_IBUF_DEBUG
if (err == DB_SUCCESS) {
- printf(
-"Incrementing ibuf count of space %lu page %lu\n"
-"from %lu by 1\n", space, page_no, ibuf_count_get(space, page_no));
+ fprintf(stderr,
+ "Incrementing ibuf count of space %lu page %lu\n"
+ "from %lu by 1\n", space, page_no,
+ ibuf_count_get(space, page_no));
ibuf_count_set(space, page_no,
- ibuf_count_get(space, page_no) + 1);
+ ibuf_count_get(space, page_no) + 1);
}
#endif
- if (mode == BTR_MODIFY_TREE) {
+ if (mode == BTR_MODIFY_TREE) {
ut_ad(ibuf_validate_low());
mutex_exit(&ibuf_mutex);
mutex_exit(&ibuf_pessimistic_insert_mutex);
}
-
+
mtr_commit(&mtr);
- btr_pcur_close(&pcur);
+ btr_pcur_close(&pcur);
ibuf_exit();
- mem_heap_free(heap);
+ mem_heap_free(heap);
mutex_enter(&ibuf_mutex);
@@ -2720,21 +2741,21 @@ function_exit:
ibuf_data->empty = FALSE;
ibuf_data->n_inserts++;
}
-
+
mutex_exit(&ibuf_mutex);
- if ((mode == BTR_MODIFY_TREE) && (err == DB_SUCCESS)) {
+ if ((mode == BTR_MODIFY_TREE) && (err == DB_SUCCESS)) {
ibuf_contract_after_insert(entry_size);
}
-
+
if (do_merge) {
#ifdef UNIV_IBUF_DEBUG
ut_a(n_stored <= IBUF_MAX_N_PAGES_MERGED);
#endif
buf_read_ibuf_merge_pages(FALSE, space_ids, space_versions,
- page_nos, n_stored);
+ page_nos, n_stored);
}
-
+
return(err);
}
@@ -2759,23 +2780,24 @@ ibuf_insert(
ut_ad(dtuple_check_typed(entry));
ut_a(!(index->type & DICT_CLUSTERED));
-
+
if (rec_get_converted_size(index, entry)
- >= page_get_free_space_of_empty(index->table->comp) / 2) {
+ >= (page_get_free_space_of_empty(dict_table_is_comp(index->table))
+ / 2)) {
return(FALSE);
}
-
+
err = ibuf_insert_low(BTR_MODIFY_PREV, entry, index, space, page_no,
- thr);
+ thr);
if (err == DB_FAIL) {
err = ibuf_insert_low(BTR_MODIFY_TREE, entry, index, space,
- page_no, thr);
+ page_no, thr);
}
-
+
if (err == DB_SUCCESS) {
#ifdef UNIV_IBUF_DEBUG
/* fprintf(stderr, "Ibuf insert for page no %lu of index %s\n",
- page_no, index->name); */
+ page_no, index->name); */
#endif
return(TRUE);
@@ -2785,7 +2807,7 @@ ibuf_insert(
return(FALSE);
}
}
-
+
/************************************************************************
During merge, inserts to an index page a secondary index entry extracted
from the insert buffer. */
@@ -2808,84 +2830,96 @@ ibuf_insert_to_index_page(
ut_ad(ibuf_inside());
ut_ad(dtuple_check_typed(entry));
- if (UNIV_UNLIKELY(index->table->comp != (ibool)!!page_is_comp(page))) {
- fputs(
-"InnoDB: Trying to insert a record from the insert buffer to an index page\n"
-"InnoDB: but the 'compact' flag does not match!\n", stderr);
+ if (UNIV_UNLIKELY(dict_table_is_comp(index->table)
+ != (ibool)!!page_is_comp(page))) {
+ fputs("InnoDB: Trying to insert a record from"
+ " the insert buffer to an index page\n"
+ "InnoDB: but the 'compact' flag does not match!\n",
+ stderr);
goto dump;
}
rec = page_rec_get_next(page_get_infimum_rec(page));
if (UNIV_UNLIKELY(rec_get_n_fields(rec, index)
- != dtuple_get_n_fields(entry))) {
- fputs(
-"InnoDB: Trying to insert a record from the insert buffer to an index page\n"
-"InnoDB: but the number of fields does not match!\n", stderr);
- dump:
+ != dtuple_get_n_fields(entry))) {
+ fputs("InnoDB: Trying to insert a record from"
+ " the insert buffer to an index page\n"
+ "InnoDB: but the number of fields does not match!\n",
+ stderr);
+dump:
buf_page_print(page);
- dtuple_print(stderr, entry);
+ dtuple_print(stderr, entry);
- fputs(
-"InnoDB: The table where where this index record belongs\n"
-"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
-"InnoDB: your tables.\n"
-"InnoDB: Send a detailed bug report to mysql@stripped!\n", stderr);
+ fputs("InnoDB: The table where where"
+ " this index record belongs\n"
+ "InnoDB: is now probably corrupt."
+ " Please run CHECK TABLE on\n"
+ "InnoDB: your tables.\n"
+ "InnoDB: Submit a detailed bug report to"
+ " http://bugs.mysql.com!\n", stderr);
return;
}
low_match = page_cur_search(page, index, entry,
- PAGE_CUR_LE, &page_cur);
-
+ PAGE_CUR_LE, &page_cur);
+
if (low_match == dtuple_get_n_fields(entry)) {
rec = page_cur_get_rec(&page_cur);
-
+
btr_cur_del_unmark_for_ibuf(rec, mtr);
} else {
rec = page_cur_tuple_insert(&page_cur, entry, index, mtr);
-
+
if (rec == NULL) {
/* If the record did not fit, reorganize */
btr_page_reorganize(page, index, mtr);
page_cur_search(page, index, entry,
- PAGE_CUR_LE, &page_cur);
+ PAGE_CUR_LE, &page_cur);
/* This time the record must fit */
if (UNIV_UNLIKELY(!page_cur_tuple_insert(
- &page_cur, entry, index, mtr))) {
+ &page_cur, entry, index,
+ mtr))) {
ut_print_timestamp(stderr);
fprintf(stderr,
-"InnoDB: Error: Insert buffer insert fails; page free %lu, dtuple size %lu\n",
- (ulong) page_get_max_insert_size(page, 1),
- (ulong) rec_get_converted_size(index, entry));
+ "InnoDB: Error: Insert buffer insert"
+ " fails; page free %lu,"
+ " dtuple size %lu\n",
+ (ulong) page_get_max_insert_size(
+ page, 1),
+ (ulong) rec_get_converted_size(
+ index, entry));
fputs("InnoDB: Cannot insert index record ",
- stderr);
+ stderr);
dtuple_print(stderr, entry);
- fputs(
-"\nInnoDB: The table where where this index record belongs\n"
-"InnoDB: is now probably corrupt. Please run CHECK TABLE on\n"
-"InnoDB: that table.\n", stderr);
-
+ fputs("\nInnoDB: The table where"
+ " this index record belongs\n"
+ "InnoDB: is now probably corrupt."
+ " Please run CHECK TABLE on\n"
+ "InnoDB: that table.\n", stderr);
+
bitmap_page = ibuf_bitmap_get_map_page(
- buf_frame_get_space_id(page),
- buf_frame_get_page_no(page),
- mtr);
+ buf_frame_get_space_id(page),
+ buf_frame_get_page_no(page),
+ mtr);
old_bits = ibuf_bitmap_page_get_bits(
- bitmap_page,
- buf_frame_get_page_no(page),
- IBUF_BITMAP_FREE, mtr);
-
- fprintf(stderr, "Bitmap bits %lu\n", (ulong) old_bits);
-
- fputs(
-"InnoDB: Submit a detailed bug report to http://bugs.mysql.com\n", stderr);
- }
+ bitmap_page,
+ buf_frame_get_page_no(page),
+ IBUF_BITMAP_FREE, mtr);
+
+ fprintf(stderr, "Bitmap bits %lu\n",
+ (ulong) old_bits);
+
+ fputs("InnoDB: Submit a detailed bug report"
+ " to http://bugs.mysql.com\n", stderr);
+ }
}
}
}
@@ -2913,22 +2947,23 @@ ibuf_delete_rec(
ibuf_data_t* ibuf_data;
page_t* root;
ulint err;
-
+
ut_ad(ibuf_inside());
success = btr_cur_optimistic_delete(btr_pcur_get_btr_cur(pcur), mtr);
if (success) {
#ifdef UNIV_IBUF_DEBUG
- printf(
-"Decrementing ibuf count of space %lu page %lu\n"
-"from %lu by 1\n", space, page_no, ibuf_count_get(space, page_no));
+ fprintf(stderr,
+ "Decrementing ibuf count of space %lu page %lu\n"
+ "from %lu by 1\n", space, page_no,
+ ibuf_count_get(space, page_no));
ibuf_count_set(space, page_no,
- ibuf_count_get(space, page_no) - 1);
+ ibuf_count_get(space, page_no) - 1);
#endif
return(FALSE);
}
-
+
/* We have to resort to a pessimistic delete from ibuf */
btr_pcur_store_position(pcur, mtr);
@@ -2942,14 +2977,16 @@ ibuf_delete_rec(
mutex_enter(&ibuf_mutex);
mtr_start(mtr);
-
+
success = btr_pcur_restore_position(BTR_MODIFY_TREE, pcur, mtr);
if (!success) {
fprintf(stderr,
- "InnoDB: ERROR: Submit the output to http://bugs.mysql.com\n"
- "InnoDB: ibuf cursor restoration fails!\n"
- "InnoDB: ibuf record inserted to page %lu\n", (ulong) page_no);
+ "InnoDB: ERROR: Submit the output to"
+ " http://bugs.mysql.com\n"
+ "InnoDB: ibuf cursor restoration fails!\n"
+ "InnoDB: ibuf record inserted to page %lu\n",
+ (ulong) page_no);
fflush(stderr);
rec_print_old(stderr, btr_pcur_get_rec(pcur));
@@ -2957,13 +2994,13 @@ ibuf_delete_rec(
dtuple_print(stderr, search_tuple);
rec_print_old(stderr,
- page_rec_get_next(btr_pcur_get_rec(pcur)));
+ page_rec_get_next(btr_pcur_get_rec(pcur)));
fflush(stderr);
btr_pcur_commit_specify_mtr(pcur, mtr);
fputs("InnoDB: Validating insert buffer tree:\n", stderr);
- if (!btr_validate_tree(ibuf_data->index->tree, NULL)) {
+ if (!btr_validate_index(ibuf_data->index, NULL)) {
ut_error;
}
@@ -2980,7 +3017,7 @@ ibuf_delete_rec(
root = ibuf_tree_root_get(ibuf_data, 0, mtr);
btr_cur_pessimistic_delete(&err, TRUE, btr_pcur_get_btr_cur(pcur),
- FALSE, mtr);
+ FALSE, mtr);
ut_a(err == DB_SUCCESS);
#ifdef UNIV_IBUF_DEBUG
@@ -3042,16 +3079,8 @@ ibuf_merge_or_delete_for_page(
return;
}
-#ifdef UNIV_LOG_DEBUG
- if (space % 2 != 0) {
-
- fputs("No ibuf operation in a replicate space\n", stderr);
-
- return;
- }
-#endif
if (ibuf_fixed_addr_page(space, page_no) || fsp_descr_page(page_no)
- || trx_sys_hdr_page(space, page_no)) {
+ || trx_sys_hdr_page(space, page_no)) {
return;
}
@@ -3077,7 +3106,7 @@ ibuf_merge_or_delete_for_page(
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
if (!ibuf_bitmap_page_get_bits(bitmap_page, page_no,
- IBUF_BITMAP_BUFFERED, &mtr)) {
+ IBUF_BITMAP_BUFFERED, &mtr)) {
/* No inserts buffered for this page */
mtr_commit(&mtr);
@@ -3101,12 +3130,12 @@ ibuf_merge_or_delete_for_page(
if (!trx_sys_multiple_tablespace_format) {
ut_a(trx_doublewrite_must_reset_space_ids);
- search_tuple = ibuf_search_tuple_build(space, page_no, heap);
+ search_tuple = ibuf_search_tuple_build(space, page_no, heap);
} else {
- search_tuple = ibuf_new_search_tuple_build(space, page_no,
- heap);
+ search_tuple = ibuf_new_search_tuple_build(space, page_no,
+ heap);
}
-
+
if (page) {
/* Move the ownership of the x-latch on the page to this OS
thread, so that we can acquire a second x-latch on it. This
@@ -3115,22 +3144,22 @@ ibuf_merge_or_delete_for_page(
block = buf_block_align(page);
rw_lock_x_lock_move_ownership(&(block->lock));
-
+
if (fil_page_get_type(page) != FIL_PAGE_INDEX) {
corruption_noticed = TRUE;
-
+
ut_print_timestamp(stderr);
mtr_start(&mtr);
fputs(" InnoDB: Dump of the ibuf bitmap page:\n",
- stderr);
-
+ stderr);
+
bitmap_page = ibuf_bitmap_get_map_page(space, page_no,
- &mtr);
+ &mtr);
buf_page_print(bitmap_page);
-
+
mtr_commit(&mtr);
fputs("\nInnoDB: Dump of the page:\n", stderr);
@@ -3138,13 +3167,20 @@ ibuf_merge_or_delete_for_page(
buf_page_print(page);
fprintf(stderr,
-"InnoDB: Error: corruption in the tablespace. Bitmap shows insert\n"
-"InnoDB: buffer records to page n:o %lu though the page\n"
-"InnoDB: type is %lu, which is not an index page!\n"
-"InnoDB: We try to resolve the problem by skipping the insert buffer\n"
-"InnoDB: merge for this page. Please run CHECK TABLE on your tables\n"
-"InnoDB: to determine if they are corrupt after this.\n\n"
-"InnoDB: Please submit a detailed bug report to http://bugs.mysql.com\n\n",
+ "InnoDB: Error: corruption in the tablespace."
+ " Bitmap shows insert\n"
+ "InnoDB: buffer records to page n:o %lu"
+ " though the page\n"
+ "InnoDB: type is %lu, which is"
+ " not an index page!\n"
+ "InnoDB: We try to resolve the problem"
+ " by skipping the insert buffer\n"
+ "InnoDB: merge for this page."
+ " Please run CHECK TABLE on your tables\n"
+ "InnoDB: to determine if they are corrupt"
+ " after this.\n\n"
+ "InnoDB: Please submit a detailed bug report"
+ " to http://bugs.mysql.com\n\n",
(ulong) page_no,
(ulong) fil_page_get_type(page));
}
@@ -3159,19 +3195,19 @@ loop:
if (page) {
ibool success = buf_page_get_known_nowait(RW_X_LATCH, page,
- BUF_KEEP_OLD,
- __FILE__, __LINE__,
- &mtr);
+ BUF_KEEP_OLD,
+ __FILE__, __LINE__,
+ &mtr);
ut_a(success);
#ifdef UNIV_SYNC_DEBUG
buf_page_dbg_add_level(page, SYNC_TREE_NODE);
#endif /* UNIV_SYNC_DEBUG */
}
-
+
/* Position pcur in the insert buffer at the first entry for this
index page */
btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE,
- BTR_MODIFY_LEAF, &pcur, &mtr);
+ BTR_MODIFY_LEAF, &pcur, &mtr);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
@@ -3196,7 +3232,7 @@ loop:
fputs("InnoDB: Discarding record\n ", stderr);
rec_print_old(stderr, ibuf_rec);
fputs("\n from the insert buffer!\n\n", stderr);
- } else if (page) {
+ } else if (page) {
/* Now we have at pcur a record which should be
inserted to the index page; NOTE that the call below
copies pointers to fields in ibuf_rec, and we must
@@ -3204,27 +3240,27 @@ loop:
insertion is finished! */
dict_index_t* dummy_index;
dulint max_trx_id = page_get_max_trx_id(
- buf_frame_align(ibuf_rec));
+ buf_frame_align(ibuf_rec));
page_update_max_trx_id(page, max_trx_id);
-
- entry = ibuf_build_entry_from_ibuf_rec(ibuf_rec,
- heap, &dummy_index);
+
+ entry = ibuf_build_entry_from_ibuf_rec(
+ ibuf_rec, heap, &dummy_index);
#ifdef UNIV_IBUF_DEBUG
volume += rec_get_converted_size(dummy_index, entry)
- + page_dir_calc_reserved_space(1);
+ + page_dir_calc_reserved_space(1);
ut_a(volume <= 4 * UNIV_PAGE_SIZE
- / IBUF_PAGE_SIZE_PER_FREE_SPACE);
+ / IBUF_PAGE_SIZE_PER_FREE_SPACE);
#endif
ibuf_insert_to_index_page(entry, page,
- dummy_index, &mtr);
+ dummy_index, &mtr);
ibuf_dummy_index_free(dummy_index);
}
n_inserts++;
-
+
/* Delete the record from ibuf */
if (ibuf_delete_rec(space, page_no, &pcur, search_tuple,
- &mtr)) {
+ &mtr)) {
/* Deletion was pessimistic and mtr was committed:
we start from the beginning again */
@@ -3233,7 +3269,7 @@ loop:
if (btr_pcur_is_after_last_on_page(&pcur, &mtr)) {
mtr_commit(&mtr);
- btr_pcur_close(&pcur);
+ btr_pcur_close(&pcur);
goto loop;
}
@@ -3249,36 +3285,38 @@ reset_bit:
if (update_ibuf_bitmap) {
bitmap_page = ibuf_bitmap_get_map_page(space, page_no, &mtr);
ibuf_bitmap_page_set_bits(bitmap_page, page_no,
- IBUF_BITMAP_BUFFERED, FALSE, &mtr);
- if (page) {
- ulint old_bits = ibuf_bitmap_page_get_bits(bitmap_page,
- page_no, IBUF_BITMAP_FREE, &mtr);
- ulint new_bits = ibuf_index_page_calc_free(page);
-#ifdef UNIV_IBUF_DEBUG
- /* fprintf(stderr, "Old bits %lu new bits %lu max size %lu\n",
- old_bits, new_bits,
- page_get_max_insert_size_after_reorganize(page, 1)); */
+ IBUF_BITMAP_BUFFERED, FALSE, &mtr);
+ if (page) {
+ ulint old_bits = ibuf_bitmap_page_get_bits(
+ bitmap_page, page_no, IBUF_BITMAP_FREE, &mtr);
+ ulint new_bits = ibuf_index_page_calc_free(page);
+#if 0 /* defined UNIV_IBUF_DEBUG */
+ fprintf(stderr, "Old bits %lu new bits %lu"
+ " max size %lu\n",
+ old_bits, new_bits,
+ page_get_max_insert_size_after_reorganize(
+ page, 1));
#endif
if (old_bits != new_bits) {
ibuf_bitmap_page_set_bits(bitmap_page, page_no,
- IBUF_BITMAP_FREE,
- new_bits, &mtr);
+ IBUF_BITMAP_FREE,
+ new_bits, &mtr);
}
}
}
-#ifdef UNIV_IBUF_DEBUG
- /* fprintf(stderr,
+#if 0 /* defined UNIV_IBUF_DEBUG */
+ fprintf(stderr,
"Ibuf merge %lu records volume %lu to page no %lu\n",
- n_inserts, volume, page_no); */
+ n_inserts, volume, page_no);
#endif
mtr_commit(&mtr);
- btr_pcur_close(&pcur);
+ btr_pcur_close(&pcur);
mem_heap_free(heap);
/* Protect our statistics keeping from race conditions */
mutex_enter(&ibuf_mutex);
- ibuf_data->n_merges++;
+ ibuf_data->n_merges++;
ibuf_data->n_merged_recs += n_inserts;
mutex_exit(&ibuf_mutex);
@@ -3326,7 +3364,7 @@ ibuf_delete_for_discarded_space(
cursor positioned at the first entry for this space id */
search_tuple = ibuf_new_search_tuple_build(space, 0, heap);
-
+
n_inserts = 0;
loop:
ibuf_enter();
@@ -3336,7 +3374,7 @@ loop:
/* Position pcur in the insert buffer at the first entry for the
space */
btr_pcur_open_on_user_rec(ibuf_data->index, search_tuple, PAGE_CUR_GE,
- BTR_MODIFY_LEAF, &pcur, &mtr);
+ BTR_MODIFY_LEAF, &pcur, &mtr);
if (!btr_pcur_is_on_user_rec(&pcur, &mtr)) {
ut_ad(btr_pcur_is_after_last_in_tree(&pcur, &mtr));
@@ -3357,10 +3395,10 @@ loop:
page_no = ibuf_rec_get_page_no(ibuf_rec);
n_inserts++;
-
+
/* Delete the record from ibuf */
closed = ibuf_delete_rec(space, page_no, &pcur, search_tuple,
- &mtr);
+ &mtr);
if (closed) {
/* Deletion was pessimistic and mtr was committed:
we start from the beginning again */
@@ -3372,7 +3410,7 @@ loop:
if (btr_pcur_is_after_last_on_page(&pcur, &mtr)) {
mtr_commit(&mtr);
- btr_pcur_close(&pcur);
+ btr_pcur_close(&pcur);
ibuf_exit();
@@ -3382,19 +3420,19 @@ loop:
leave_loop:
mtr_commit(&mtr);
- btr_pcur_close(&pcur);
+ btr_pcur_close(&pcur);
/* Protect our statistics keeping from race conditions */
mutex_enter(&ibuf_mutex);
- ibuf_data->n_merges++;
+ ibuf_data->n_merges++;
ibuf_data->n_merged_recs += n_inserts;
mutex_exit(&ibuf_mutex);
/*
fprintf(stderr,
- "InnoDB: Discarded %lu ibuf entries for space %lu\n",
- (ulong) n_inserts, (ulong) space);
+ "InnoDB: Discarded %lu ibuf entries for space %lu\n",
+ (ulong) n_inserts, (ulong) space);
*/
ibuf_exit();
@@ -3418,12 +3456,12 @@ ibuf_validate_low(void)
#endif /* UNIV_SYNC_DEBUG */
sum_sizes = 0;
-
+
data = UT_LIST_GET_FIRST(ibuf->data_list);
while (data) {
sum_sizes += data->size;
-
+
data = UT_LIST_GET_NEXT(data_list, data);
}
@@ -3461,12 +3499,14 @@ ibuf_is_empty(void)
if (data->empty == FALSE) {
fprintf(stderr,
-"InnoDB: Warning: insert buffer tree is empty but the data struct does not\n"
-"InnoDB: know it. This condition is legal if the master thread has not yet\n"
-"InnoDB: run to completion.\n");
+ "InnoDB: Warning: insert buffer tree is empty"
+ " but the data struct does not\n"
+ "InnoDB: know it. This condition is legal"
+ " if the master thread has not yet\n"
+ "InnoDB: run to completion.\n");
}
} else {
- ut_a(data->empty == FALSE);
+ ut_a(data->empty == FALSE);
is_empty = FALSE;
}
@@ -3501,22 +3541,23 @@ ibuf_print(
while (data) {
fprintf(file,
- "Ibuf: size %lu, free list len %lu, seg size %lu,\n"
- "%lu inserts, %lu merged recs, %lu merges\n",
- (ulong) data->size,
- (ulong) data->free_list_len,
- (ulong) data->seg_size,
- (ulong) data->n_inserts,
- (ulong) data->n_merged_recs,
- (ulong) data->n_merges);
+ "Ibuf: size %lu, free list len %lu, seg size %lu,\n"
+ "%lu inserts, %lu merged recs, %lu merges\n",
+ (ulong) data->size,
+ (ulong) data->free_list_len,
+ (ulong) data->seg_size,
+ (ulong) data->n_inserts,
+ (ulong) data->n_merged_recs,
+ (ulong) data->n_merges);
#ifdef UNIV_IBUF_DEBUG
for (i = 0; i < IBUF_COUNT_N_PAGES; i++) {
if (ibuf_count_get(data->space, i) > 0) {
fprintf(stderr,
"Ibuf count for page %lu is %lu\n",
- (ulong) i,
- (ulong) ibuf_count_get(data->space, i));
+ (ulong) i,
+ (ulong)
+ ibuf_count_get(data->space, i));
}
}
#endif
--- 1.20.3.1/innobase/include/data0type.h 2006-09-21 03:48:35 -06:00
+++ 1.29/storage/innobase/include/data0type.h 2006-09-21 03:48:35 -06:00
@@ -18,10 +18,6 @@ extern ulint data_mysql_default_charset_
/* SQL data type struct */
typedef struct dtype_struct dtype_t;
-/* This variable is initialized as the standard binary variable length
-data type */
-extern dtype_t* dtype_binary;
-
/*-------------------------------------------*/
/* The 'MAIN TYPE' of a column */
#define DATA_VARCHAR 1 /* character varying of the
@@ -102,7 +98,7 @@ InnoDB's own internal system tables have
columns, and for them the precise type is usually not used at all.
*/
-#define DATA_ENGLISH 4 /* English language character string: this
+#define DATA_ENGLISH 4 /* English language character string: this
is a relic from pre-MySQL time and only used
for InnoDB's own system tables */
#define DATA_ERROR 111 /* another relic from pre-MySQL time */
@@ -124,11 +120,7 @@ be less than 256 */
#define DATA_ROLL_PTR 2 /* rollback data pointer: 7 bytes */
#define DATA_ROLL_PTR_LEN 7
-#define DATA_MIX_ID 3 /* mixed index label: a dulint, stored in
- a row in a compressed form */
-#define DATA_MIX_ID_LEN 9 /* maximum stored length for mix id (in a
- compressed dulint form) */
-#define DATA_N_SYS_COLS 4 /* number of system columns defined above */
+#define DATA_N_SYS_COLS 3 /* number of system columns defined above */
/* Flags ORed to the precise data type */
#define DATA_NOT_NULL 256 /* this is ORed to the precise type when
@@ -176,7 +168,11 @@ dtype_get_at_most_n_mbchars(
/*========================*/
/* out: length of the prefix,
in bytes */
- const dtype_t* dtype, /* in: data type */
+ ulint prtype, /* in: precise type */
+ ulint mbminlen, /* in: minimum length of a
+ multi-byte character */
+ ulint mbmaxlen, /* in: maximum length of a
+ multi-byte character */
ulint prefix_len, /* in: length of the requested
prefix, in characters, multiplied by
dtype_get_mbmaxlen(dtype) */
@@ -224,8 +220,7 @@ dtype_set(
dtype_t* type, /* in: type struct to init */
ulint mtype, /* in: main data type */
ulint prtype, /* in: precise type */
- ulint len, /* in: length of type */
- ulint prec); /* in: precision of type */
+ ulint len); /* in: precision of type */
/*************************************************************************
Copies a data type structure. */
UNIV_INLINE
@@ -233,7 +228,7 @@ void
dtype_copy(
/*=======*/
dtype_t* type1, /* in: type struct to copy to */
- dtype_t* type2); /* in: type struct to copy from */
+ const dtype_t* type2); /* in: type struct to copy from */
/*************************************************************************
Gets the SQL main data type. */
UNIV_INLINE
@@ -249,6 +244,18 @@ dtype_get_prtype(
/*=============*/
dtype_t* type);
/*************************************************************************
+Compute the mbminlen and mbmaxlen members of a data type structure. */
+UNIV_INLINE
+void
+dtype_get_mblen(
+/*============*/
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type (and collation) */
+ ulint* mbminlen, /* out: minimum length of a
+ multi-byte character */
+ ulint* mbmaxlen); /* out: maximum length of a
+ multi-byte character */
+/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
ulint
@@ -280,13 +287,6 @@ dtype_get_len(
/*==========*/
dtype_t* type);
/*************************************************************************
-Gets the type precision. */
-UNIV_INLINE
-ulint
-dtype_get_prec(
-/*===========*/
- dtype_t* type);
-/*************************************************************************
Gets the minimum length of a character, in bytes. */
UNIV_INLINE
ulint
@@ -312,40 +312,52 @@ dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- const dtype_t* type); /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype); /* in: precise type */
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
ulint
-dtype_get_fixed_size(
-/*=================*/
+dtype_get_fixed_size_low(
+/*=====================*/
/* out: fixed size, or 0 */
- dtype_t* type); /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen); /* in: maximum length of a multibyte char */
/***************************************************************************
Returns the minimum size of a data type. */
UNIV_INLINE
ulint
-dtype_get_min_size(
-/*===============*/
+dtype_get_min_size_low(
+/*===================*/
/* out: minimum size */
- const dtype_t* type); /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen); /* in: maximum length of a multibyte char */
/***************************************************************************
-Returns a stored SQL NULL size for a type. For fixed length types it is
-the fixed length of the type, otherwise 0. */
+Returns the maximum size of a data type. Note: types in system tables may be
+incomplete and return incorrect information. */
UNIV_INLINE
ulint
-dtype_get_sql_null_size(
-/*====================*/
- /* out: SQL null storage size */
- dtype_t* type); /* in: type */
+dtype_get_max_size_low(
+/*===================*/
+ /* out: maximum size */
+ ulint mtype, /* in: main type */
+ ulint len); /* in: length */
/***************************************************************************
-Returns TRUE if a type is of a fixed size. */
+Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
+For fixed length types it is the fixed length of the type, otherwise 0. */
UNIV_INLINE
-ibool
-dtype_is_fixed_size(
-/*================*/
- /* out: TRUE if fixed size */
- dtype_t* type); /* in: type */
+ulint
+dtype_get_sql_null_size(
+/*====================*/
+ /* out: SQL null storage size
+ in ROW_FORMAT=REDUNDANT */
+ const dtype_t* type); /* in: type */
/**************************************************************************
Reads to a type the stored information which determines its alphabetical
ordering and the storage size of an SQL NULL value. */
@@ -405,25 +417,30 @@ dtype_new_read_for_order_and_null_size()
sym_tab_add_null_lit() */
struct dtype_struct{
- ulint mtype; /* main data type */
- ulint prtype; /* precise type; MySQL data type, charset code,
- flags to indicate nullability, signedness,
- whether this is a binary string, whether this
- is a true VARCHAR where MySQL uses 2 bytes to
- store the length */
+ unsigned mtype:8; /* main data type */
+ unsigned prtype:24; /* precise type; MySQL data
+ type, charset code, flags to
+ indicate nullability,
+ signedness, whether this is a
+ binary string, whether this is
+ a true VARCHAR where MySQL
+ uses 2 bytes to store the length */
/* the remaining fields do not affect alphabetical ordering: */
- ulint len; /* length; for MySQL data this is
- field->pack_length(), except that for a
- >= 5.0.3 type true VARCHAR this is the
- maximum byte length of the string data
- (in addition to the string, MySQL uses 1 or
- 2 bytes to store the string length) */
- ulint prec; /* precision */
-
- ulint mbminlen; /* minimum length of a character, in bytes */
- ulint mbmaxlen; /* maximum length of a character, in bytes */
+ unsigned len:16; /* length; for MySQL data this
+ is field->pack_length(),
+ except that for a >= 5.0.3
+ type true VARCHAR this is the
+ maximum byte length of the
+ string data (in addition to
+ the string, MySQL uses 1 or 2
+ bytes to store the string length) */
+
+ unsigned mbminlen:2; /* minimum length of a
+ character, in bytes */
+ unsigned mbmaxlen:3; /* maximum length of a
+ character, in bytes */
};
#ifndef UNIV_NONINL
--- 1.24.4.1/innobase/include/data0type.ic 2006-09-21 03:48:35 -06:00
+++ 1.32/storage/innobase/include/data0type.ic 2006-09-21 03:48:35 -06:00
@@ -8,6 +8,7 @@ Created 1/16/1996 Heikki Tuuri
#include "mach0data.h"
+#ifndef UNIV_HOTBACKUP
/**********************************************************************
Get the variable length bounds of the given character set.
@@ -20,6 +21,7 @@ innobase_get_cset_width(
ulint cset, /* in: MySQL charset-collation code */
ulint* mbminlen, /* out: minimum length of a char (in bytes) */
ulint* mbmaxlen); /* out: maximum length of a char (in bytes) */
+#endif /* !UNIV_HOTBACKUP */
/*************************************************************************
Gets the MySQL charset-collation code for MySQL string types. */
@@ -46,24 +48,53 @@ dtype_get_mysql_type(
}
/*************************************************************************
-Sets the mbminlen and mbmaxlen members of a data type structure. */
+Compute the mbminlen and mbmaxlen members of a data type structure. */
UNIV_INLINE
void
-dtype_set_mblen(
+dtype_get_mblen(
/*============*/
- dtype_t* type) /* in/out: type struct */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type (and collation) */
+ ulint* mbminlen, /* out: minimum length of a
+ multi-byte character */
+ ulint* mbmaxlen) /* out: maximum length of a
+ multi-byte character */
{
- ut_ad(type);
- if (dtype_is_string_type(type->mtype)) {
- innobase_get_cset_width(dtype_get_charset_coll(type->prtype),
- &type->mbminlen, &type->mbmaxlen);
- ut_ad(type->mbminlen <= type->mbmaxlen);
+ if (dtype_is_string_type(mtype)) {
+#ifndef UNIV_HOTBACKUP
+ innobase_get_cset_width(dtype_get_charset_coll(prtype),
+ mbminlen, mbmaxlen);
+ ut_ad(*mbminlen <= *mbmaxlen);
+ ut_ad(*mbminlen <= 2); /* cf. the bit-field in dtype_t */
+ ut_ad(*mbmaxlen < 1 << 3); /* cf. the bit-field in dtype_t */
+#else /* !UNIV_HOTBACKUP */
+ ut_a(mtype <= DATA_BINARY);
+ *mbminlen = *mbmaxlen = 1;
+#endif /* !UNIV_HOTBACKUP */
} else {
- type->mbminlen = type->mbmaxlen = 0;
+ *mbminlen = *mbmaxlen = 0;
}
}
/*************************************************************************
+Compute the mbminlen and mbmaxlen members of a data type structure. */
+UNIV_INLINE
+void
+dtype_set_mblen(
+/*============*/
+ dtype_t* type) /* in/out: type */
+{
+ ulint mbminlen;
+ ulint mbmaxlen;
+
+ dtype_get_mblen(type->mtype, type->prtype, &mbminlen, &mbmaxlen);
+ type->mbminlen = mbminlen;
+ type->mbmaxlen = mbmaxlen;
+
+ ut_ad(dtype_validate(type));
+}
+
+/*************************************************************************
Sets a data type structure. */
UNIV_INLINE
void
@@ -72,19 +103,16 @@ dtype_set(
dtype_t* type, /* in: type struct to init */
ulint mtype, /* in: main data type */
ulint prtype, /* in: precise type */
- ulint len, /* in: length of type */
- ulint prec) /* in: precision of type */
+ ulint len) /* in: precision of type */
{
ut_ad(type);
ut_ad(mtype <= DATA_MTYPE_MAX);
-
+
type->mtype = mtype;
type->prtype = prtype;
type->len = len;
- type->prec = prec;
dtype_set_mblen(type);
- ut_ad(dtype_validate(type));
}
/*************************************************************************
@@ -94,7 +122,7 @@ void
dtype_copy(
/*=======*/
dtype_t* type1, /* in: type struct to copy to */
- dtype_t* type2) /* in: type struct to copy from */
+ const dtype_t* type2) /* in: type struct to copy from */
{
*type1 = *type2;
@@ -141,19 +169,6 @@ dtype_get_len(
}
/*************************************************************************
-Gets the type precision. */
-UNIV_INLINE
-ulint
-dtype_get_prec(
-/*===========*/
- dtype_t* type)
-{
- ut_ad(type);
-
- return(type->prec);
-}
-
-/*************************************************************************
Gets the minimum length of a character, in bytes. */
UNIV_INLINE
ulint
@@ -181,20 +196,21 @@ dtype_get_mbmaxlen(
}
/*************************************************************************
-Gets the padding character code for the type. */
+Gets the padding character code for a type. */
UNIV_INLINE
ulint
dtype_get_pad_char(
/*===============*/
/* out: padding character code, or
ULINT_UNDEFINED if no padding specified */
- const dtype_t* type) /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype) /* in: precise type */
{
- switch (type->mtype) {
+ switch (mtype) {
case DATA_FIXBINARY:
case DATA_BINARY:
- if (UNIV_UNLIKELY(dtype_get_charset_coll(type->prtype)
- == DATA_MYSQL_BINARY_CHARSET_COLL)) {
+ if (UNIV_UNLIKELY(dtype_get_charset_coll(prtype)
+ == DATA_MYSQL_BINARY_CHARSET_COLL)) {
/* Starting from 5.0.18, do not pad
VARBINARY or BINARY columns. */
return(ULINT_UNDEFINED);
@@ -205,11 +221,11 @@ dtype_get_pad_char(
case DATA_MYSQL:
case DATA_VARMYSQL:
/* Space is the padding character for all char and binary
- strings, and starting from 5.0.3, also for TEXT strings. */
+ strings, and starting from 5.0.3, also for TEXT strings. */
return(0x20);
case DATA_BLOB:
- if ((type->prtype & DATA_BINARY_TYPE) == 0) {
+ if (!(prtype & DATA_BINARY_TYPE)) {
return(0x20);
}
/* Fall through */
@@ -245,9 +261,9 @@ dtype_new_store_for_order_and_null_size(
buf[0] = buf[0] | 128;
}
- /* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) {
- buf[0] = buf[0] | 64;
- }
+ /* In versions < 4.1.2 we had: if (type->prtype & DATA_NONLATIN1) {
+ buf[0] = buf[0] | 64;
+ }
*/
buf[1] = (byte)(type->prtype & 0xFFUL);
@@ -275,21 +291,23 @@ dtype_read_for_order_and_null_size(
dtype_t* type, /* in: type struct */
byte* buf) /* in: buffer for stored type order info */
{
- ut_ad(4 == DATA_ORDER_NULL_TYPE_BUF_SIZE);
-
+#if 4 != DATA_ORDER_NULL_TYPE_BUF_SIZE
+# error "4 != DATA_ORDER_NULL_TYPE_BUF_SIZE"
+#endif
+
type->mtype = buf[0] & 63;
type->prtype = buf[1];
if (buf[0] & 128) {
- type->prtype = type->prtype | DATA_BINARY_TYPE;
+ type->prtype = type->prtype | DATA_BINARY_TYPE;
}
type->len = mach_read_from_2(buf + 2);
-
+
type->prtype = dtype_form_prtype(type->prtype,
- data_mysql_default_charset_coll);
+ data_mysql_default_charset_coll);
dtype_set_mblen(type);
-}
+}
/**************************************************************************
Reads to a type the stored information which determines its alphabetical
@@ -307,7 +325,7 @@ dtype_new_read_for_order_and_null_size(
#if 6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE
#error "6 != DATA_NEW_ORDER_NULL_TYPE_BUF_SIZE"
#endif
-
+
type->mtype = buf[0] & 63;
type->prtype = buf[1];
@@ -337,97 +355,100 @@ dtype_new_read_for_order_and_null_size(
charset_coll = data_mysql_default_charset_coll;
}
-
+
type->prtype = dtype_form_prtype(type->prtype, charset_coll);
- }
+ }
dtype_set_mblen(type);
}
-#ifndef UNIV_HOTBACKUP
/***************************************************************************
Returns the size of a fixed size data type, 0 if not a fixed size type. */
UNIV_INLINE
ulint
-dtype_get_fixed_size(
-/*=================*/
+dtype_get_fixed_size_low(
+/*=====================*/
/* out: fixed size, or 0 */
- dtype_t* type) /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen) /* in: maximum length of a multibyte char */
{
- ulint mtype;
-
- mtype = dtype_get_mtype(type);
-
switch (mtype) {
case DATA_SYS:
#ifdef UNIV_DEBUG
- switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
- default:
- ut_ad(0);
- return(0);
- case DATA_ROW_ID:
- ut_ad(type->len == DATA_ROW_ID_LEN);
- break;
- case DATA_TRX_ID:
- ut_ad(type->len == DATA_TRX_ID_LEN);
- break;
- case DATA_ROLL_PTR:
- ut_ad(type->len == DATA_ROLL_PTR_LEN);
- break;
- case DATA_MIX_ID:
- ut_ad(type->len == DATA_MIX_ID_LEN);
- break;
- }
+ switch (prtype & DATA_MYSQL_TYPE_MASK) {
+ case DATA_ROW_ID:
+ ut_ad(len == DATA_ROW_ID_LEN);
+ break;
+ case DATA_TRX_ID:
+ ut_ad(len == DATA_TRX_ID_LEN);
+ break;
+ case DATA_ROLL_PTR:
+ ut_ad(len == DATA_ROLL_PTR_LEN);
+ break;
+ default:
+ ut_ad(0);
+ return(0);
+ }
#endif /* UNIV_DEBUG */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
- return(dtype_get_len(type));
+ return(len);
case DATA_MYSQL:
- if (type->prtype & DATA_BINARY_TYPE) {
- return(dtype_get_len(type));
- } else {
- /* We play it safe here and ask MySQL for
- mbminlen and mbmaxlen. Although
- type->mbminlen and type->mbmaxlen are
- initialized if and only if type->prtype
- is (in one of the 3 functions in this file),
- it could be that none of these functions
- has been called. */
-
- ulint mbminlen, mbmaxlen;
-
- innobase_get_cset_width(
- dtype_get_charset_coll(type->prtype),
- &mbminlen, &mbmaxlen);
-
- if (UNIV_UNLIKELY(type->mbminlen != mbminlen)
- || UNIV_UNLIKELY(type->mbmaxlen != mbmaxlen)) {
-
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: "
- "mbminlen=%lu, "
- "mbmaxlen=%lu, "
- "type->mbminlen=%lu, "
- "type->mbmaxlen=%lu\n",
- (ulong) mbminlen,
- (ulong) mbmaxlen,
- (ulong) type->mbminlen,
- (ulong) type->mbmaxlen);
- }
- if (mbminlen == mbmaxlen) {
- return(dtype_get_len(type));
- }
+ if (prtype & DATA_BINARY_TYPE) {
+ return(len);
+ } else {
+#ifdef UNIV_HOTBACKUP
+ if (mbminlen == mbmaxlen) {
+ return(len);
+ }
+#else /* UNIV_HOTBACKUP */
+ /* We play it safe here and ask MySQL for
+ mbminlen and mbmaxlen. Although
+ mbminlen and mbmaxlen are
+ initialized if and only if prtype
+ is (in one of the 3 functions in this file),
+ it could be that none of these functions
+ has been called. */
+
+ ulint i_mbminlen, i_mbmaxlen;
+
+ innobase_get_cset_width(
+ dtype_get_charset_coll(prtype),
+ &i_mbminlen, &i_mbmaxlen);
+
+ if (UNIV_UNLIKELY(mbminlen != i_mbminlen)
+ || UNIV_UNLIKELY(mbmaxlen != i_mbmaxlen)) {
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: "
+ "mbminlen=%lu, "
+ "mbmaxlen=%lu, "
+ "type->mbminlen=%lu, "
+ "type->mbmaxlen=%lu\n",
+ (ulong) i_mbminlen,
+ (ulong) i_mbmaxlen,
+ (ulong) mbminlen,
+ (ulong) mbmaxlen);
+ }
+ if (mbminlen == mbmaxlen) {
+ return(len);
}
- /* fall through for variable-length charsets */
+#endif /* !UNIV_HOTBACKUP */
+ }
+ /* fall through for variable-length charsets */
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
case DATA_VARMYSQL:
case DATA_BLOB:
- return(0);
- default: ut_error;
+ return(0);
+ default:
+ ut_error;
}
return(0);
@@ -437,90 +458,105 @@ dtype_get_fixed_size(
Returns the minimum size of a data type. */
UNIV_INLINE
ulint
-dtype_get_min_size(
-/*===============*/
+dtype_get_min_size_low(
+/*===================*/
/* out: minimum size */
- const dtype_t* type) /* in: type */
+ ulint mtype, /* in: main type */
+ ulint prtype, /* in: precise type */
+ ulint len, /* in: length */
+ ulint mbminlen, /* in: minimum length of a multibyte char */
+ ulint mbmaxlen) /* in: maximum length of a multibyte char */
{
- switch (type->mtype) {
+ switch (mtype) {
case DATA_SYS:
#ifdef UNIV_DEBUG
- switch (type->prtype & DATA_MYSQL_TYPE_MASK) {
- default:
- ut_ad(0);
- return(0);
- case DATA_ROW_ID:
- ut_ad(type->len == DATA_ROW_ID_LEN);
- break;
- case DATA_TRX_ID:
- ut_ad(type->len == DATA_TRX_ID_LEN);
- break;
- case DATA_ROLL_PTR:
- ut_ad(type->len == DATA_ROLL_PTR_LEN);
- break;
- case DATA_MIX_ID:
- ut_ad(type->len == DATA_MIX_ID_LEN);
- break;
- }
+ switch (prtype & DATA_MYSQL_TYPE_MASK) {
+ case DATA_ROW_ID:
+ ut_ad(len == DATA_ROW_ID_LEN);
+ break;
+ case DATA_TRX_ID:
+ ut_ad(len == DATA_TRX_ID_LEN);
+ break;
+ case DATA_ROLL_PTR:
+ ut_ad(len == DATA_ROLL_PTR_LEN);
+ break;
+ default:
+ ut_ad(0);
+ return(0);
+ }
#endif /* UNIV_DEBUG */
case DATA_CHAR:
case DATA_FIXBINARY:
case DATA_INT:
case DATA_FLOAT:
case DATA_DOUBLE:
- return(type->len);
+ return(len);
case DATA_MYSQL:
- if ((type->prtype & DATA_BINARY_TYPE)
- || type->mbminlen == type->mbmaxlen) {
- return(type->len);
- }
- /* this is a variable-length character set */
- ut_a(type->mbminlen > 0);
- ut_a(type->mbmaxlen > type->mbminlen);
- ut_a(type->len % type->mbmaxlen == 0);
- return(type->len * type->mbminlen / type->mbmaxlen);
+ if ((prtype & DATA_BINARY_TYPE) || mbminlen == mbmaxlen) {
+ return(len);
+ }
+ /* this is a variable-length character set */
+ ut_a(mbminlen > 0);
+ ut_a(mbmaxlen > mbminlen);
+ ut_a(len % mbmaxlen == 0);
+ return(len * mbminlen / mbmaxlen);
case DATA_VARCHAR:
case DATA_BINARY:
case DATA_DECIMAL:
case DATA_VARMYSQL:
case DATA_BLOB:
- return(0);
- default: ut_error;
+ return(0);
+ default:
+ ut_error;
}
return(0);
}
-#endif /* !UNIV_HOTBACKUP */
/***************************************************************************
-Returns a stored SQL NULL size for a type. For fixed length types it is
-the fixed length of the type, otherwise 0. */
+Returns the maximum size of a data type. Note: types in system tables may be
+incomplete and return incorrect information. */
UNIV_INLINE
ulint
-dtype_get_sql_null_size(
-/*====================*/
- /* out: SQL null storage size */
- dtype_t* type) /* in: type */
+dtype_get_max_size_low(
+/*===================*/
+ /* out: maximum size */
+ ulint mtype, /* in: main type */
+ ulint len) /* in: length */
{
- return(dtype_get_fixed_size(type));
+ switch (mtype) {
+ case DATA_SYS:
+ case DATA_CHAR:
+ case DATA_FIXBINARY:
+ case DATA_INT:
+ case DATA_FLOAT:
+ case DATA_DOUBLE:
+ case DATA_MYSQL:
+ case DATA_VARCHAR:
+ case DATA_BINARY:
+ case DATA_DECIMAL:
+ case DATA_VARMYSQL:
+ return(len);
+ case DATA_BLOB:
+ break;
+ default:
+ ut_error;
+ }
+
+ return(ULINT_MAX);
}
/***************************************************************************
-Returns TRUE if a type is of a fixed size. */
+Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a type.
+For fixed length types it is the fixed length of the type, otherwise 0. */
UNIV_INLINE
-ibool
-dtype_is_fixed_size(
-/*================*/
- /* out: TRUE if fixed size */
- dtype_t* type) /* in: type */
+ulint
+dtype_get_sql_null_size(
+/*====================*/
+ /* out: SQL null storage size
+ in ROW_FORMAT=REDUNDANT */
+ const dtype_t* type) /* in: type */
{
- ulint size;
-
- size = dtype_get_fixed_size(type);
-
- if (size) {
- return(TRUE);
- }
-
- return(FALSE);
+ return(dtype_get_fixed_size_low(type->mtype, type->prtype, type->len,
+ type->mbminlen, type->mbmaxlen) > 0);
}
--- 1.202.1.97/sql/ha_innodb.cc 2006-09-21 03:48:35 -06:00
+++ 1.299/storage/innobase/handler/ha_innodb.cc 2006-09-21 03:48:35 -06:00
@@ -7,12 +7,12 @@
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
/* This file defines the InnoDB handler: the interface between MySQL and InnoDB
NOTE: You can only use noninlined InnoDB functions in this file, because we
@@ -31,10 +31,10 @@ have disables the InnoDB inlining in thi
#pragma implementation // gcc: Class implementation
#endif
-#include "mysql_priv.h"
-#include "slave.h"
+#include <mysql_priv.h>
+
+#ifdef WITH_INNOBASE_STORAGE_ENGINE
-#ifdef HAVE_INNOBASE_DB
#include <m_ctype.h>
#include <hash.h>
#include <myisampack.h>
@@ -45,9 +45,9 @@ have disables the InnoDB inlining in thi
#include "ha_innodb.h"
-pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
- prepare_commit_mutex; /* to force correct commit order in
- binlog */
+pthread_mutex_t innobase_share_mutex, /* to protect innobase_open_files */
+ prepare_commit_mutex; /* to force correct commit order in
+ binlog */
ulong commit_threads= 0;
pthread_mutex_t commit_threads_m;
pthread_cond_t commit_cond;
@@ -58,45 +58,45 @@ bool innodb_inited= 0;
/* These variables are used to implement (semi-)synchronous MySQL binlog
replication for InnoDB tables. */
-pthread_cond_t innobase_repl_cond; /* Posix cond variable;
- this variable is signaled
- when enough binlog has been
- sent to slave, so that a
- waiting trx can return the
- 'ok' message to the client
- for a commit */
-pthread_mutex_t innobase_repl_cond_mutex; /* Posix cond variable mutex
- that also protects the next
- innobase_repl_... variables */
-uint innobase_repl_state; /* 1 if synchronous replication
- is switched on and is working
- ok; else 0 */
-uint innobase_repl_file_name_inited = 0; /* This is set to 1 when
- innobase_repl_file_name
- contains meaningful data */
-char* innobase_repl_file_name; /* The binlog name up to which
- we have sent some binlog to
- the slave */
-my_off_t innobase_repl_pos; /* The position in that file
- up to which we have sent the
- binlog to the slave */
-uint innobase_repl_n_wait_threads = 0; /* This tells how many
- transactions currently are
- waiting for the binlog to be
- sent to the client */
-uint innobase_repl_wait_file_name_inited = 0; /* This is set to 1
- when we know the 'smallest'
- wait position */
-char* innobase_repl_wait_file_name; /* NULL, or the 'smallest'
- innobase_repl_file_name that
- a transaction is waiting for */
-my_off_t innobase_repl_wait_pos; /* The smallest position in
- that file that a trx is
- waiting for: the trx can
- proceed and send an 'ok' to
- the client when MySQL has sent
- the binlog up to this position
- to the slave */
+pthread_cond_t innobase_repl_cond; /* Posix cond variable;
+ this variable is signaled
+ when enough binlog has been
+ sent to slave, so that a
+ waiting trx can return the
+ 'ok' message to the client
+ for a commit */
+pthread_mutex_t innobase_repl_cond_mutex; /* Posix cond variable mutex
+ that also protects the next
+ innobase_repl_... variables */
+uint innobase_repl_state; /* 1 if synchronous replication
+ is switched on and is working
+ ok; else 0 */
+uint innobase_repl_file_name_inited = 0; /* This is set to 1 when
+ innobase_repl_file_name
+ contains meaningful data */
+char* innobase_repl_file_name; /* The binlog name up to which
+ we have sent some binlog to
+ the slave */
+my_off_t innobase_repl_pos; /* The position in that file
+ up to which we have sent the
+ binlog to the slave */
+uint innobase_repl_n_wait_threads = 0; /* This tells how many
+ transactions currently are
+ waiting for the binlog to be
+ sent to the client */
+uint innobase_repl_wait_file_name_inited = 0; /* This is set to 1
+ when we know the 'smallest'
+ wait position */
+char* innobase_repl_wait_file_name; /* NULL, or the 'smallest'
+ innobase_repl_file_name that
+ a transaction is waiting for */
+my_off_t innobase_repl_wait_pos; /* The smallest position in
+ that file that a trx is
+ waiting for: the trx can
+ proceed and send an 'ok' to
+ the client when MySQL has sent
+ the binlog up to this position
+ to the slave */
/*-----------------------------------------------------------------*/
@@ -111,43 +111,45 @@ typedef byte mysql_byte;
/* Include necessary InnoDB headers */
extern "C" {
-#include "../innobase/include/univ.i"
-#include "../innobase/include/os0file.h"
-#include "../innobase/include/os0thread.h"
-#include "../innobase/include/srv0start.h"
-#include "../innobase/include/srv0srv.h"
-#include "../innobase/include/trx0roll.h"
-#include "../innobase/include/trx0trx.h"
-#include "../innobase/include/trx0sys.h"
-#include "../innobase/include/mtr0mtr.h"
-#include "../innobase/include/row0ins.h"
-#include "../innobase/include/row0mysql.h"
-#include "../innobase/include/row0sel.h"
-#include "../innobase/include/row0upd.h"
-#include "../innobase/include/log0log.h"
-#include "../innobase/include/lock0lock.h"
-#include "../innobase/include/dict0crea.h"
-#include "../innobase/include/btr0cur.h"
-#include "../innobase/include/btr0btr.h"
-#include "../innobase/include/fsp0fsp.h"
-#include "../innobase/include/sync0sync.h"
-#include "../innobase/include/fil0fil.h"
-#include "../innobase/include/trx0xa.h"
+#include "../storage/innobase/include/univ.i"
+#include "../storage/innobase/include/os0file.h"
+#include "../storage/innobase/include/os0thread.h"
+#include "../storage/innobase/include/srv0start.h"
+#include "../storage/innobase/include/srv0srv.h"
+#include "../storage/innobase/include/trx0roll.h"
+#include "../storage/innobase/include/trx0trx.h"
+#include "../storage/innobase/include/trx0sys.h"
+#include "../storage/innobase/include/mtr0mtr.h"
+#include "../storage/innobase/include/row0ins.h"
+#include "../storage/innobase/include/row0mysql.h"
+#include "../storage/innobase/include/row0sel.h"
+#include "../storage/innobase/include/row0upd.h"
+#include "../storage/innobase/include/log0log.h"
+#include "../storage/innobase/include/lock0lock.h"
+#include "../storage/innobase/include/dict0crea.h"
+#include "../storage/innobase/include/btr0cur.h"
+#include "../storage/innobase/include/btr0btr.h"
+#include "../storage/innobase/include/fsp0fsp.h"
+#include "../storage/innobase/include/sync0sync.h"
+#include "../storage/innobase/include/fil0fil.h"
+#include "../storage/innobase/include/trx0xa.h"
+#include "../storage/innobase/include/thr0loc.h"
+#include "../storage/innobase/include/ha_prototypes.h"
}
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
#define HA_INNOBASE_RANGE_COUNT 100
-ulong innobase_large_page_size = 0;
+ulong innobase_large_page_size = 0;
/* The default values for the following, type long or longlong, start-up
parameters are declared in mysqld.cc: */
long innobase_mirrored_log_groups, innobase_log_files_in_group,
- innobase_log_buffer_size, innobase_buffer_pool_awe_mem_mb,
- innobase_additional_mem_pool_size, innobase_file_io_threads,
- innobase_lock_wait_timeout, innobase_force_recovery,
- innobase_open_files;
+ innobase_log_buffer_size, innobase_buffer_pool_awe_mem_mb,
+ innobase_additional_mem_pool_size, innobase_file_io_threads,
+ innobase_lock_wait_timeout, innobase_force_recovery,
+ innobase_open_files;
longlong innobase_buffer_pool_size, innobase_log_file_size;
@@ -155,7 +157,7 @@ longlong innobase_buffer_pool_size, inno
are determined in innobase_init below: */
char* innobase_data_home_dir = NULL;
-char* innobase_data_file_path = NULL;
+char* innobase_data_file_path = NULL;
char* innobase_log_group_home_dir = NULL;
char* innobase_log_arch_dir = NULL;/* unused */
/* The following has a misleading name: starting from 4.0.5, this also
@@ -167,12 +169,12 @@ values */
ulong innobase_fast_shutdown = 1;
my_bool innobase_log_archive = FALSE;/* unused */
-my_bool innobase_use_doublewrite = TRUE;
-my_bool innobase_use_checksums = TRUE;
-my_bool innobase_use_large_pages = FALSE;
+my_bool innobase_use_doublewrite = TRUE;
+my_bool innobase_use_checksums = TRUE;
+my_bool innobase_use_large_pages = FALSE;
my_bool innobase_use_native_aio = FALSE;
my_bool innobase_file_per_table = FALSE;
-my_bool innobase_locks_unsafe_for_binlog = FALSE;
+my_bool innobase_locks_unsafe_for_binlog = FALSE;
my_bool innobase_create_status_file = FALSE;
static char *internal_innobase_data_file_path = NULL;
@@ -185,14 +187,14 @@ it every INNOBASE_WAKE_INTERVAL'th step.
#define INNOBASE_WAKE_INTERVAL 32
ulong innobase_active_counter = 0;
-static HASH innobase_open_tables;
+static HASH innobase_open_tables;
-#ifdef __NETWARE__ /* some special cleanup for NetWare */
+#ifdef __NETWARE__ /* some special cleanup for NetWare */
bool nw_panic = FALSE;
#endif
static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)));
+ my_bool not_used __attribute__((unused)));
static INNOBASE_SHARE *get_share(const char *table_name);
static void free_share(INNOBASE_SHARE *share);
static int innobase_close_connection(THD* thd);
@@ -201,30 +203,18 @@ static int innobase_rollback(THD* thd, b
static int innobase_rollback_to_savepoint(THD* thd, void *savepoint);
static int innobase_savepoint(THD* thd, void *savepoint);
static int innobase_release_savepoint(THD* thd, void *savepoint);
+static handler *innobase_create_handler(TABLE_SHARE *table,
+ MEM_ROOT *mem_root);
+
+static const char innobase_hton_name[]= "InnoDB";
+
+handlerton *innobase_hton;
+
+static handler *innobase_create_handler(TABLE_SHARE *table, MEM_ROOT *mem_root)
+{
+ return new (mem_root) ha_innobase(table);
+}
-handlerton innobase_hton = {
- "InnoDB",
- SHOW_OPTION_YES,
- "Supports transactions, row-level locking, and foreign keys",
- DB_TYPE_INNODB,
- innobase_init,
- 0, /* slot */
- sizeof(trx_named_savept_t), /* savepoint size. TODO: use it */
- innobase_close_connection,
- innobase_savepoint,
- innobase_rollback_to_savepoint,
- innobase_release_savepoint,
- innobase_commit, /* commit */
- innobase_rollback, /* rollback */
- innobase_xa_prepare, /* prepare */
- innobase_xa_recover, /* recover */
- innobase_commit_by_xid, /* commit_by_xid */
- innobase_rollback_by_xid, /* rollback_by_xid */
- innobase_create_cursor_view,
- innobase_set_cursor_view,
- innobase_close_cursor_view,
- HTON_NO_FLAGS
-};
/*********************************************************************
Commits a transaction in an InnoDB database. */
@@ -234,21 +224,21 @@ innobase_commit_low(
/*================*/
trx_t* trx); /* in: transaction handle */
-struct show_var_st innodb_status_variables[]= {
+SHOW_VAR innodb_status_variables[]= {
{"buffer_pool_pages_data",
- (char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_pages_data, SHOW_LONG},
{"buffer_pool_pages_dirty",
- (char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_pages_dirty, SHOW_LONG},
{"buffer_pool_pages_flushed",
(char*) &export_vars.innodb_buffer_pool_pages_flushed, SHOW_LONG},
{"buffer_pool_pages_free",
- (char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_pages_free, SHOW_LONG},
{"buffer_pool_pages_latched",
(char*) &export_vars.innodb_buffer_pool_pages_latched, SHOW_LONG},
{"buffer_pool_pages_misc",
- (char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_pages_misc, SHOW_LONG},
{"buffer_pool_pages_total",
- (char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_pages_total, SHOW_LONG},
{"buffer_pool_read_ahead_rnd",
(char*) &export_vars.innodb_buffer_pool_read_ahead_rnd, SHOW_LONG},
{"buffer_pool_read_ahead_seq",
@@ -256,72 +246,73 @@ struct show_var_st innodb_status_variabl
{"buffer_pool_read_requests",
(char*) &export_vars.innodb_buffer_pool_read_requests, SHOW_LONG},
{"buffer_pool_reads",
- (char*) &export_vars.innodb_buffer_pool_reads, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_reads, SHOW_LONG},
{"buffer_pool_wait_free",
- (char*) &export_vars.innodb_buffer_pool_wait_free, SHOW_LONG},
+ (char*) &export_vars.innodb_buffer_pool_wait_free, SHOW_LONG},
{"buffer_pool_write_requests",
(char*) &export_vars.innodb_buffer_pool_write_requests, SHOW_LONG},
{"data_fsyncs",
- (char*) &export_vars.innodb_data_fsyncs, SHOW_LONG},
+ (char*) &export_vars.innodb_data_fsyncs, SHOW_LONG},
{"data_pending_fsyncs",
- (char*) &export_vars.innodb_data_pending_fsyncs, SHOW_LONG},
+ (char*) &export_vars.innodb_data_pending_fsyncs, SHOW_LONG},
{"data_pending_reads",
- (char*) &export_vars.innodb_data_pending_reads, SHOW_LONG},
+ (char*) &export_vars.innodb_data_pending_reads, SHOW_LONG},
{"data_pending_writes",
- (char*) &export_vars.innodb_data_pending_writes, SHOW_LONG},
+ (char*) &export_vars.innodb_data_pending_writes, SHOW_LONG},
{"data_read",
- (char*) &export_vars.innodb_data_read, SHOW_LONG},
+ (char*) &export_vars.innodb_data_read, SHOW_LONG},
{"data_reads",
- (char*) &export_vars.innodb_data_reads, SHOW_LONG},
+ (char*) &export_vars.innodb_data_reads, SHOW_LONG},
{"data_writes",
- (char*) &export_vars.innodb_data_writes, SHOW_LONG},
+ (char*) &export_vars.innodb_data_writes, SHOW_LONG},
{"data_written",
- (char*) &export_vars.innodb_data_written, SHOW_LONG},
+ (char*) &export_vars.innodb_data_written, SHOW_LONG},
{"dblwr_pages_written",
- (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
+ (char*) &export_vars.innodb_dblwr_pages_written, SHOW_LONG},
{"dblwr_writes",
- (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
+ (char*) &export_vars.innodb_dblwr_writes, SHOW_LONG},
{"log_waits",
- (char*) &export_vars.innodb_log_waits, SHOW_LONG},
+ (char*) &export_vars.innodb_log_waits, SHOW_LONG},
{"log_write_requests",
- (char*) &export_vars.innodb_log_write_requests, SHOW_LONG},
+ (char*) &export_vars.innodb_log_write_requests, SHOW_LONG},
{"log_writes",
- (char*) &export_vars.innodb_log_writes, SHOW_LONG},
+ (char*) &export_vars.innodb_log_writes, SHOW_LONG},
{"os_log_fsyncs",
- (char*) &export_vars.innodb_os_log_fsyncs, SHOW_LONG},
+ (char*) &export_vars.innodb_os_log_fsyncs, SHOW_LONG},
{"os_log_pending_fsyncs",
- (char*) &export_vars.innodb_os_log_pending_fsyncs, SHOW_LONG},
+ (char*) &export_vars.innodb_os_log_pending_fsyncs, SHOW_LONG},
{"os_log_pending_writes",
- (char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG},
+ (char*) &export_vars.innodb_os_log_pending_writes, SHOW_LONG},
{"os_log_written",
- (char*) &export_vars.innodb_os_log_written, SHOW_LONG},
+ (char*) &export_vars.innodb_os_log_written, SHOW_LONG},
{"page_size",
- (char*) &export_vars.innodb_page_size, SHOW_LONG},
+ (char*) &export_vars.innodb_page_size, SHOW_LONG},
{"pages_created",
- (char*) &export_vars.innodb_pages_created, SHOW_LONG},
+ (char*) &export_vars.innodb_pages_created, SHOW_LONG},
{"pages_read",
- (char*) &export_vars.innodb_pages_read, SHOW_LONG},
+ (char*) &export_vars.innodb_pages_read, SHOW_LONG},
{"pages_written",
- (char*) &export_vars.innodb_pages_written, SHOW_LONG},
+ (char*) &export_vars.innodb_pages_written, SHOW_LONG},
{"row_lock_current_waits",
- (char*) &export_vars.innodb_row_lock_current_waits, SHOW_LONG},
+ (char*) &export_vars.innodb_row_lock_current_waits, SHOW_LONG},
{"row_lock_time",
- (char*) &export_vars.innodb_row_lock_time, SHOW_LONGLONG},
+ (char*) &export_vars.innodb_row_lock_time, SHOW_LONGLONG},
{"row_lock_time_avg",
- (char*) &export_vars.innodb_row_lock_time_avg, SHOW_LONG},
+ (char*) &export_vars.innodb_row_lock_time_avg, SHOW_LONG},
{"row_lock_time_max",
- (char*) &export_vars.innodb_row_lock_time_max, SHOW_LONG},
+ (char*) &export_vars.innodb_row_lock_time_max, SHOW_LONG},
{"row_lock_waits",
- (char*) &export_vars.innodb_row_lock_waits, SHOW_LONG},
+ (char*) &export_vars.innodb_row_lock_waits, SHOW_LONG},
{"rows_deleted",
- (char*) &export_vars.innodb_rows_deleted, SHOW_LONG},
+ (char*) &export_vars.innodb_rows_deleted, SHOW_LONG},
{"rows_inserted",
- (char*) &export_vars.innodb_rows_inserted, SHOW_LONG},
+ (char*) &export_vars.innodb_rows_inserted, SHOW_LONG},
{"rows_read",
- (char*) &export_vars.innodb_rows_read, SHOW_LONG},
+ (char*) &export_vars.innodb_rows_read, SHOW_LONG},
{"rows_updated",
- (char*) &export_vars.innodb_rows_updated, SHOW_LONG},
- {NullS, NullS, SHOW_LONG}};
+ (char*) &export_vars.innodb_rows_updated, SHOW_LONG},
+ {NullS, NullS, SHOW_LONG}
+};
/* General functions */
@@ -386,23 +377,24 @@ Call this function when mysqld passes co
avoid deadlocks on the adaptive hash S-latch possibly held by thd. For more
documentation, see handler.cc. */
-void
+int
innobase_release_temporary_latches(
/*===============================*/
- THD *thd)
+ THD *thd)
{
trx_t* trx;
if (!innodb_inited) {
- return;
+ return 0;
}
- trx = (trx_t*) thd->ha_data[innobase_hton.slot];
+ trx = (trx_t*) thd->ha_data[innobase_hton->slot];
if (trx) {
- innobase_release_stat_resources(trx);
+ innobase_release_stat_resources(trx);
}
+ return 0;
}
/************************************************************************
@@ -438,81 +430,85 @@ convert_error_code_to_mysql(
return(0);
- } else if (error == (int) DB_DUPLICATE_KEY) {
+ } else if (error == (int) DB_DUPLICATE_KEY) {
- return(HA_ERR_FOUND_DUPP_KEY);
+ return(HA_ERR_FOUND_DUPP_KEY);
- } else if (error == (int) DB_RECORD_NOT_FOUND) {
+ } else if (error == (int) DB_FOREIGN_DUPLICATE_KEY) {
- return(HA_ERR_NO_ACTIVE_RECORD);
+ return(HA_ERR_FOREIGN_DUPLICATE_KEY);
- } else if (error == (int) DB_ERROR) {
+ } else if (error == (int) DB_RECORD_NOT_FOUND) {
- return(-1); /* unspecified error */
+ return(HA_ERR_NO_ACTIVE_RECORD);
- } else if (error == (int) DB_DEADLOCK) {
- /* Since we rolled back the whole transaction, we must
- tell it also to MySQL so that MySQL knows to empty the
- cached binlog for this transaction */
+ } else if (error == (int) DB_ERROR) {
- if (thd) {
- ha_rollback(thd);
- }
+ return(-1); /* unspecified error */
+
+ } else if (error == (int) DB_DEADLOCK) {
+ /* Since we rolled back the whole transaction, we must
+ tell it also to MySQL so that MySQL knows to empty the
+ cached binlog for this transaction */
- return(HA_ERR_LOCK_DEADLOCK);
+ if (thd) {
+ ha_rollback(thd);
+ }
- } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
+ return(HA_ERR_LOCK_DEADLOCK);
+
+ } else if (error == (int) DB_LOCK_WAIT_TIMEOUT) {
/* Starting from 5.0.13, we let MySQL just roll back the
latest SQL statement in a lock wait timeout. Previously, we
rolled back the whole transaction. */
- return(HA_ERR_LOCK_WAIT_TIMEOUT);
+ return(HA_ERR_LOCK_WAIT_TIMEOUT);
- } else if (error == (int) DB_NO_REFERENCED_ROW) {
+ } else if (error == (int) DB_NO_REFERENCED_ROW) {
- return(HA_ERR_NO_REFERENCED_ROW);
+ return(HA_ERR_NO_REFERENCED_ROW);
- } else if (error == (int) DB_ROW_IS_REFERENCED) {
+ } else if (error == (int) DB_ROW_IS_REFERENCED) {
- return(HA_ERR_ROW_IS_REFERENCED);
+ return(HA_ERR_ROW_IS_REFERENCED);
- } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
+ } else if (error == (int) DB_CANNOT_ADD_CONSTRAINT) {
- return(HA_ERR_CANNOT_ADD_FOREIGN);
+ return(HA_ERR_CANNOT_ADD_FOREIGN);
- } else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
+ } else if (error == (int) DB_CANNOT_DROP_CONSTRAINT) {
- return(HA_ERR_ROW_IS_REFERENCED); /* TODO: This is a bit
+ return(HA_ERR_ROW_IS_REFERENCED); /* TODO: This is a bit
misleading, a new MySQL error
code should be introduced */
- } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
+ } else if (error == (int) DB_COL_APPEARS_TWICE_IN_INDEX) {
- return(HA_ERR_CRASHED);
+ return(HA_ERR_CRASHED);
- } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
+ } else if (error == (int) DB_OUT_OF_FILE_SPACE) {
- return(HA_ERR_RECORD_FILE_FULL);
+ return(HA_ERR_RECORD_FILE_FULL);
- } else if (error == (int) DB_TABLE_IS_BEING_USED) {
+ } else if (error == (int) DB_TABLE_IS_BEING_USED) {
- return(HA_ERR_WRONG_COMMAND);
+ return(HA_ERR_WRONG_COMMAND);
- } else if (error == (int) DB_TABLE_NOT_FOUND) {
+ } else if (error == (int) DB_TABLE_NOT_FOUND) {
- return(HA_ERR_KEY_NOT_FOUND);
+ return(HA_ERR_KEY_NOT_FOUND);
- } else if (error == (int) DB_TOO_BIG_RECORD) {
+ } else if (error == (int) DB_TOO_BIG_RECORD) {
- return(HA_ERR_TO_BIG_ROW);
+ return(HA_ERR_TO_BIG_ROW);
- } else if (error == (int) DB_CORRUPTION) {
+ } else if (error == (int) DB_CORRUPTION) {
- return(HA_ERR_CRASHED);
- } else if (error == (int) DB_NO_SAVEPOINT) {
+ return(HA_ERR_CRASHED);
+ } else if (error == (int) DB_NO_SAVEPOINT) {
- return(HA_ERR_NO_SAVEPOINT);
- } else if (error == (int) DB_LOCK_TABLE_FULL) {
+ return(HA_ERR_NO_SAVEPOINT);
+ } else if (error == (int) DB_LOCK_TABLE_FULL) {
/* Since we rolled back the whole transaction, we must
tell it also to MySQL so that MySQL knows to empty the
cached binlog for this transaction */
@@ -564,21 +560,21 @@ extern "C"
void
innobase_mysql_print_thd(
/*=====================*/
- FILE* f, /* in: output stream */
- void* input_thd, /* in: pointer to a MySQL THD object */
+ FILE* f, /* in: output stream */
+ void* input_thd, /* in: pointer to a MySQL THD object */
uint max_query_len) /* in: max query length to print, or 0 to
use the default max length */
{
const THD* thd;
- const Security_context *sctx;
+ const Security_context *sctx;
const char* s;
- thd = (const THD*) input_thd;
- /* We probably want to have original user as part of debug output. */
- sctx = &thd->main_security_ctx;
+ thd = (const THD*) input_thd;
+ /* We probably want to have original user as part of debug output. */
+ sctx = &thd->main_security_ctx;
- fprintf(f, "MySQL thread id %lu, query id %lu",
+ fprintf(f, "MySQL thread id %lu, query id %lu",
thd->thread_id, (ulong) thd->query_id);
if (sctx->host) {
putc(' ', f);
@@ -590,10 +586,10 @@ innobase_mysql_print_thd(
fputs(sctx->ip, f);
}
- if (sctx->user) {
+ if (sctx->user) {
putc(' ', f);
fputs(sctx->user, f);
- }
+ }
if ((s = thd->proc_info)) {
putc(' ', f);
@@ -613,8 +609,7 @@ innobase_mysql_print_thd(
/* Points to buf or dyn_str. */
char* str = buf;
- if (max_query_len == 0)
- {
+ if (max_query_len == 0) {
/* ADDITIONAL SAFETY: the default is to print at
most 300 chars to reduce the probability of a
seg fault if there is a race in
@@ -626,20 +621,18 @@ innobase_mysql_print_thd(
len = min(thd->query_length, max_query_len);
- if (len > (sizeof(buf) - 1))
- {
+ if (len > (sizeof(buf) - 1)) {
dyn_str = my_malloc(len + 1, MYF(0));
str = dyn_str;
}
- /* Use strmake to reduce the timeframe for a race,
- compared to fwrite() */
+ /* Use strmake to reduce the timeframe for a race,
+ compared to fwrite() */
len = (uint) (strmake(str, s, len) - str);
putc('\n', f);
fwrite(str, 1, len, f);
- if (dyn_str)
- {
+ if (dyn_str) {
my_free(dyn_str, MYF(0));
}
}
@@ -676,6 +669,61 @@ 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! */
+extern "C"
+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 */
+{
+ uint errors;
+
+ strconvert(current_thd->charset(), from,
+ &my_charset_filename, to, len, &errors);
+}
+
+/**********************************************************************
+Converts an identifier to UTF-8.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+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 */
+{
+ uint errors;
+
+ strconvert(current_thd->charset(), from,
+ system_charset_info, to, len, &errors);
+}
+
+/**********************************************************************
+Removes the filename encoding of a table or database name.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+void
+innobase_convert_from_filename(
+/*===========================*/
+ char* s) /* in: identifier; out: decoded identifier */
+{
+ uint errors;
+
+ strconvert(&my_charset_filename, s,
+ system_charset_info, s, strlen(s), &errors);
+}
+
+/**********************************************************************
Compares NUL-terminated UTF-8 strings case insensitively.
NOTE that the exact prototype of this function has to be in
@@ -705,6 +753,21 @@ innobase_casedn_str(
my_casedn_str(system_charset_info, a);
}
+/**************************************************************************
+Determines the connection character set.
+
+NOTE that the exact prototype of this function has to be in
+/innobase/dict/dict0dict.c! */
+extern "C"
+struct charset_info_st*
+innobase_get_charset(
+/*=================*/
+ /* out: connection character set */
+ void* mysql_thd) /* in: MySQL thread handle */
+{
+ return(((THD*) mysql_thd)->charset());
+}
+
/*************************************************************************
Creates a temporary file. */
extern "C"
@@ -741,16 +804,35 @@ innobase_mysql_tmpfile(void)
if (fd2 < 0) {
DBUG_PRINT("error",("Got error %d on dup",fd2));
my_errno=errno;
- my_error(EE_OUT_OF_FILERESOURCES,
- MYF(ME_BELL+ME_WAITTANG),
- filename, my_errno);
- }
+ my_error(EE_OUT_OF_FILERESOURCES,
+ MYF(ME_BELL+ME_WAITTANG),
+ filename, my_errno);
+ }
my_close(fd, MYF(MY_WME));
}
return(fd2);
}
/*************************************************************************
+Wrapper around MySQL's copy_and_convert function, see it for
+documentation. */
+extern "C"
+ulint
+innobase_convert_string(
+/*====================*/
+ void* to,
+ ulint to_length,
+ CHARSET_INFO* to_cs,
+ const void* from,
+ ulint from_length,
+ CHARSET_INFO* from_cs,
+ uint* errors)
+{
+ return(copy_and_convert((char*)to, to_length, to_cs,
+ (const char*)from, from_length, from_cs, errors));
+}
+
+/*************************************************************************
Gets the InnoDB transaction handle for a MySQL handler object, creates
an InnoDB transaction struct if the corresponding MySQL thread struct still
lacks one. */
@@ -765,24 +847,24 @@ check_trx_exists(
ut_ad(thd == current_thd);
- trx = (trx_t*) thd->ha_data[innobase_hton.slot];
+ trx = (trx_t*) thd->ha_data[innobase_hton->slot];
if (trx == NULL) {
- DBUG_ASSERT(thd != NULL);
+ DBUG_ASSERT(thd != NULL);
trx = trx_allocate_for_mysql();
trx->mysql_thd = thd;
trx->mysql_query_str = &(thd->query);
- trx->active_trans = 0;
+ trx->active_trans = 0;
/* Update the info whether we should skip XA steps that eat
CPU time */
trx->support_xa = (ibool)(thd->variables.innodb_support_xa);
- thd->ha_data[innobase_hton.slot] = trx;
+ thd->ha_data[innobase_hton->slot] = trx;
} else {
if (trx->magic_n != TRX_MAGIC_N) {
- mem_analyze_corruption((byte*)trx);
+ mem_analyze_corruption(trx);
ut_a(0);
}
@@ -807,16 +889,16 @@ check_trx_exists(
/*************************************************************************
Construct ha_innobase handler. */
-ha_innobase::ha_innobase(TABLE *table_arg)
- :handler(&innobase_hton, table_arg),
+ha_innobase::ha_innobase(TABLE_SHARE *table_arg)
+ :handler(innobase_hton, table_arg),
int_table_flags(HA_REC_NOT_IN_SEQ |
- HA_NULL_IN_KEY |
- HA_CAN_INDEX_BLOBS |
- HA_CAN_SQL_HANDLER |
- HA_NOT_EXACT_COUNT |
- HA_PRIMARY_KEY_IN_READ_INDEX |
- HA_CAN_GEOMETRY |
- HA_TABLE_SCAN_ON_INDEX),
+ HA_NULL_IN_KEY |
+ HA_CAN_INDEX_BLOBS |
+ HA_CAN_SQL_HANDLER |
+ HA_PRIMARY_KEY_REQUIRED_FOR_POSITION |
+ HA_PRIMARY_KEY_IN_READ_INDEX |
+ HA_CAN_GEOMETRY | HA_PARTIAL_COLUMN_READ |
+ HA_TABLE_SCAN_ON_INDEX),
start_of_scan(0),
num_write_row(0)
{}
@@ -858,8 +940,8 @@ innobase_register_stmt(
/*===================*/
THD* thd) /* in: MySQL thd (connection) object */
{
- /* Register the statement */
- trans_register_ha(thd, FALSE, &innobase_hton);
+ /* Register the statement */
+ trans_register_ha(thd, FALSE, innobase_hton);
}
/*************************************************************************
@@ -880,11 +962,11 @@ innobase_register_trx_and_stmt(
innobase_register_stmt(thd);
- if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) {
- /* No autocommit mode, register for a transaction */
- trans_register_ha(thd, TRUE, &innobase_hton);
- }
+ /* No autocommit mode, register for a transaction */
+ trans_register_ha(thd, TRUE, innobase_hton);
+ }
}
/* BACKGROUND INFO: HOW THE MYSQL QUERY CACHE WORKS WITH INNODB
@@ -964,7 +1046,7 @@ innobase_query_caching_of_table_permitte
name */
uint full_name_len, /* in: length of the full name, i.e.
len(dbname) + len(tablename) + 1 */
- ulonglong *unused) /* unused for this engine */
+ ulonglong *unused) /* unused for this engine */
{
ibool is_autocommit;
trx_t* trx;
@@ -979,7 +1061,7 @@ innobase_query_caching_of_table_permitte
return((my_bool)FALSE);
}
- trx = check_trx_exists(thd);
+ trx = check_trx_exists(thd);
if (trx->has_search_latch) {
ut_print_timestamp(stderr);
sql_print_error("The calling thread is holding the adaptive "
@@ -1036,11 +1118,11 @@ innobase_query_caching_of_table_permitte
/* The call of row_search_.. will start a new transaction if it is
not yet started */
- if (trx->active_trans == 0) {
+ if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
- trx->active_trans = 1;
- }
+ innobase_register_trx_and_stmt(thd);
+ trx->active_trans = 1;
+ }
if (row_search_check_if_query_cache_permitted(trx, norm_name)) {
@@ -1084,23 +1166,70 @@ innobase_invalidate_query_cache(
}
/*********************************************************************
-Get the quote character to be used in SQL identifiers.
+Display an SQL identifier.
This definition must match the one in innobase/ut/ut0ut.c! */
extern "C"
-int
-mysql_get_identifier_quote_char(
-/*============================*/
- /* out: quote character to be
- used in SQL identifiers; EOF if none */
+void
+innobase_print_identifier(
+/*======================*/
+ FILE* f, /* in: output stream */
trx_t* trx, /* in: transaction */
+ ibool table_id,/* in: TRUE=print a table name,
+ FALSE=print other identifier */
const char* name, /* in: name to print */
ulint namelen)/* in: length of name */
{
+ const char* s = name;
+ char* qname = NULL;
+ int q;
+
+ if (table_id) {
+ /* Decode the table name. The filename_to_tablename()
+ function expects a NUL-terminated string. The input and
+ output strings buffers must not be shared. The function
+ only produces more output when the name contains other
+ characters than [0-9A-Z_a-z]. */
+ char* temp_name = my_malloc(namelen + 1, MYF(MY_WME));
+ uint qnamelen = namelen
+ + (1 + sizeof srv_mysql50_table_name_prefix);
+
+ if (temp_name) {
+ qname = my_malloc(qnamelen, MYF(MY_WME));
+ if (qname) {
+ memcpy(temp_name, name, namelen);
+ temp_name[namelen] = 0;
+ s = qname;
+ namelen = filename_to_tablename(temp_name,
+ qname, qnamelen);
+ }
+ my_free(temp_name, MYF(0));
+ }
+ }
+
if (!trx || !trx->mysql_thd) {
- return(EOF);
+
+ q = '"';
+ } else {
+ q = get_quote_char_for_identifier((THD*) trx->mysql_thd,
+ s, (int) namelen);
}
- return(get_quote_char_for_identifier((THD*) trx->mysql_thd,
- name, (int) namelen));
+
+ if (q == EOF) {
+ fwrite(s, 1, namelen, f);
+ } else {
+ const char* e = s + namelen;
+ putc(q, f);
+ while (s < e) {
+ int c = *s++;
+ if (c == q) {
+ putc(c, f);
+ }
+ putc(c, f);
+ }
+ putc(q, f);
+ }
+
+ my_free(qname, MYF(MY_ALLOW_ZERO_PTR));
}
/**************************************************************************
@@ -1116,7 +1245,7 @@ trx_is_interrupted(
}
/**************************************************************************
-Obtain a pointer to the MySQL THD object, as in current_thd(). This
+Obtain a pointer to the MySQL THD object, as in current_thd(). This
definition must match the one in sql/ha_innodb.cc! */
extern "C"
void*
@@ -1138,58 +1267,58 @@ void
ha_innobase::init_table_handle_for_HANDLER(void)
/*============================================*/
{
- row_prebuilt_t* prebuilt;
+ row_prebuilt_t* prebuilt;
- /* If current thd does not yet have a trx struct, create one.
- If the current handle does not yet have a prebuilt struct, create
- one. Update the trx pointers in the prebuilt struct. Normally
- this operation is done in external_lock. */
+ /* If current thd does not yet have a trx struct, create one.
+ If the current handle does not yet have a prebuilt struct, create
+ one. Update the trx pointers in the prebuilt struct. Normally
+ this operation is done in external_lock. */
- update_thd(current_thd);
+ update_thd(current_thd);
- /* Initialize the prebuilt struct much like it would be inited in
- external_lock */
+ /* Initialize the prebuilt struct much like it would be inited in
+ external_lock */
- prebuilt = (row_prebuilt_t*)innobase_prebuilt;
+ prebuilt = (row_prebuilt_t*)innobase_prebuilt;
innobase_release_stat_resources(prebuilt->trx);
- /* If the transaction is not started yet, start it */
+ /* If the transaction is not started yet, start it */
- trx_start_if_not_started_noninline(prebuilt->trx);
+ trx_start_if_not_started_noninline(prebuilt->trx);
- /* Assign a read view if the transaction does not have it yet */
+ /* Assign a read view if the transaction does not have it yet */
- trx_assign_read_view(prebuilt->trx);
+ trx_assign_read_view(prebuilt->trx);
/* Set the MySQL flag to mark that there is an active transaction */
- if (prebuilt->trx->active_trans == 0) {
+ if (prebuilt->trx->active_trans == 0) {
- innobase_register_trx_and_stmt(current_thd);
+ innobase_register_trx_and_stmt(current_thd);
- prebuilt->trx->active_trans = 1;
- }
+ prebuilt->trx->active_trans = 1;
+ }
- /* We did the necessary inits in this function, no need to repeat them
- in row_search_for_mysql */
+ /* We did the necessary inits in this function, no need to repeat them
+ in row_search_for_mysql */
- prebuilt->sql_stat_start = FALSE;
+ prebuilt->sql_stat_start = FALSE;
- /* We let HANDLER always to do the reads as consistent reads, even
- if the trx isolation level would have been specified as SERIALIZABLE */
+ /* We let HANDLER always to do the reads as consistent reads, even
+ if the trx isolation level would have been specified as SERIALIZABLE */
- prebuilt->select_lock_type = LOCK_NONE;
- prebuilt->stored_select_lock_type = LOCK_NONE;
+ prebuilt->select_lock_type = LOCK_NONE;
+ prebuilt->stored_select_lock_type = LOCK_NONE;
- /* Always fetch all columns in the index record */
+ /* Always fetch all columns in the index record */
- prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
+ prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
- /* We want always to fetch all columns in the whole row? Or do
+ /* We want always to fetch all columns in the whole row? Or do
we???? */
- prebuilt->read_just_key = FALSE;
+ prebuilt->read_just_key = FALSE;
prebuilt->used_in_HANDLER = TRUE;
@@ -1199,23 +1328,66 @@ ha_innobase::init_table_handle_for_HANDL
/*************************************************************************
Opens an InnoDB database. */
-bool
-innobase_init(void)
+int
+innobase_init(void *p)
/*===============*/
- /* out: &innobase_hton, or NULL on error */
{
static char current_dir[3]; /* Set if using current lib */
int err;
bool ret;
- char *default_path;
+ char *default_path;
+
+ DBUG_ENTER("innobase_init");
+ innobase_hton= (handlerton *)p;
- DBUG_ENTER("innobase_init");
+ innobase_hton->state=have_innodb;
+ innobase_hton->db_type= DB_TYPE_INNODB;
+ innobase_hton->savepoint_offset=sizeof(trx_named_savept_t);
+ innobase_hton->close_connection=innobase_close_connection;
+ innobase_hton->savepoint_set=innobase_savepoint;
+ innobase_hton->savepoint_rollback=innobase_rollback_to_savepoint;
+ innobase_hton->savepoint_release=innobase_release_savepoint;
+ innobase_hton->commit=innobase_commit;
+ innobase_hton->rollback=innobase_rollback;
+ innobase_hton->prepare=innobase_xa_prepare;
+ innobase_hton->recover=innobase_xa_recover;
+ innobase_hton->commit_by_xid=innobase_commit_by_xid;
+ innobase_hton->rollback_by_xid=innobase_rollback_by_xid;
+ innobase_hton->create_cursor_read_view=innobase_create_cursor_view;
+ innobase_hton->set_cursor_read_view=innobase_set_cursor_view;
+ innobase_hton->close_cursor_read_view=innobase_close_cursor_view;
+ innobase_hton->create=innobase_create_handler;
+ innobase_hton->drop_database=innobase_drop_database;
+ innobase_hton->panic=innobase_end;
+ innobase_hton->start_consistent_snapshot=innobase_start_trx_and_assign_read_view;
+ innobase_hton->flush_logs=innobase_flush_logs;
+ innobase_hton->show_status=innobase_show_status;
+ innobase_hton->flags=HTON_NO_FLAGS;
+ innobase_hton->release_temporary_latches=innobase_release_temporary_latches;
- if (have_innodb != SHOW_OPTION_YES)
- goto error;
+ if (have_innodb != SHOW_OPTION_YES)
+ DBUG_RETURN(0); // nothing else to do
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
+#ifdef UNIV_DEBUG
+ static const char test_filename[] = "-@";
+ char test_tablename[sizeof test_filename
+ + sizeof srv_mysql50_table_name_prefix];
+ if ((sizeof test_tablename) - 1
+ != filename_to_tablename(test_filename, test_tablename,
+ sizeof test_tablename)
+ || strncmp(test_tablename,
+ srv_mysql50_table_name_prefix,
+ sizeof srv_mysql50_table_name_prefix)
+ || strcmp(test_tablename
+ + sizeof srv_mysql50_table_name_prefix,
+ test_filename)) {
+ sql_print_error("tablename encoding has been changed");
+ goto error;
+ }
+#endif /* UNIV_DEBUG */
+
/* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) {
if (innobase_buffer_pool_size > UINT_MAX32) {
@@ -1235,7 +1407,7 @@ innobase_init(void)
}
}
- os_innodb_umask = (ulint)my_umask;
+ os_innodb_umask = (ulint)my_umask;
/* First calculate the default path for innodb_data_home_dir etc.,
in case the user has not given any value.
@@ -1247,20 +1419,20 @@ innobase_init(void)
default_path = mysql_real_data_home;
fil_path_to_mysql_datadir = mysql_real_data_home;
} else {
- /* It's better to use current lib, to keep paths short */
- current_dir[0] = FN_CURLIB;
- current_dir[1] = FN_LIBCHAR;
- current_dir[2] = 0;
- default_path = current_dir;
+ /* It's better to use current lib, to keep paths short */
+ current_dir[0] = FN_CURLIB;
+ current_dir[1] = FN_LIBCHAR;
+ current_dir[2] = 0;
+ default_path = current_dir;
}
ut_a(default_path);
if (specialflag & SPECIAL_NO_PRIOR) {
- srv_set_thread_priorities = FALSE;
+ srv_set_thread_priorities = FALSE;
} else {
- srv_set_thread_priorities = TRUE;
- srv_query_thread_priority = QUERY_PRIOR;
+ srv_set_thread_priorities = TRUE;
+ srv_query_thread_priority = QUERY_PRIOR;
}
/* Set InnoDB initialization parameters according to the values
@@ -1274,11 +1446,11 @@ innobase_init(void)
default_path);
/* Set default InnoDB data file size to 10 MB and let it be
- auto-extending. Thus users can use InnoDB in >= 4.0 without having
+ auto-extending. Thus users can use InnoDB in >= 4.0 without having
to specify any startup options. */
if (!innobase_data_file_path) {
- innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
+ innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
}
/* Since InnoDB edits the argument in the next call, we make another
@@ -1296,11 +1468,11 @@ innobase_init(void)
&srv_auto_extend_last_data_file,
&srv_last_file_size_max);
if (ret == FALSE) {
- sql_print_error(
+ sql_print_error(
"InnoDB: syntax error in innodb_data_file_path");
- my_free(internal_innobase_data_file_path,
+ my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- goto error;
+ goto error;
}
/* -------------- Log files ---------------------------*/
@@ -1308,7 +1480,7 @@ innobase_init(void)
/* The default dir for log files is the datadir of MySQL */
if (!innobase_log_group_home_dir) {
- innobase_log_group_home_dir = default_path;
+ innobase_log_group_home_dir = default_path;
}
#ifdef UNIV_LOG_ARCHIVE
@@ -1329,9 +1501,9 @@ innobase_init(void)
sql_print_error("syntax error in innodb_log_group_home_dir, or a "
"wrong number of mirrored log groups");
- my_free(internal_innobase_data_file_path,
+ my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- goto error;
+ goto error;
}
/* --------------------------------------------------*/
@@ -1347,25 +1519,25 @@ innobase_init(void)
#endif /* UNIV_LOG_ARCHIVE */
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
- /* We set srv_pool_size here in units of 1 kB. InnoDB internally
- changes the value so that it becomes the number of database pages. */
+ /* We set srv_pool_size here in units of 1 kB. InnoDB internally
+ changes the value so that it becomes the number of database pages. */
+
+ if (innobase_buffer_pool_awe_mem_mb == 0) {
+ /* Careful here: we first convert the signed long int to ulint
+ and only after that divide */
- if (innobase_buffer_pool_awe_mem_mb == 0) {
- /* Careful here: we first convert the signed long int to ulint
- and only after that divide */
-
- srv_pool_size = ((ulint) innobase_buffer_pool_size) / 1024;
- } else {
- srv_use_awe = TRUE;
- srv_pool_size = (ulint)
- (1024 * innobase_buffer_pool_awe_mem_mb);
- srv_awe_window_size = (ulint) innobase_buffer_pool_size;
-
- /* Note that what the user specified as
- innodb_buffer_pool_size is actually the AWE memory window
- size in this case, and the real buffer pool size is
- determined by .._awe_mem_mb. */
- }
+ srv_pool_size = ((ulint) innobase_buffer_pool_size) / 1024;
+ } else {
+ srv_use_awe = TRUE;
+ srv_pool_size = (ulint)
+ (1024 * innobase_buffer_pool_awe_mem_mb);
+ srv_awe_window_size = (ulint) innobase_buffer_pool_size;
+
+ /* Note that what the user specified as
+ innodb_buffer_pool_size is actually the AWE memory window
+ size in this case, and the real buffer pool size is
+ determined by .._awe_mem_mb. */
+ }
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
@@ -1381,7 +1553,7 @@ innobase_init(void)
os_large_page_size = (ulint) innobase_large_page_size;
srv_file_per_table = (ibool) innobase_file_per_table;
- srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
+ srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
srv_max_n_open_files = (ulint) innobase_open_files;
srv_innodb_status = (ibool) innobase_create_status_file;
@@ -1407,7 +1579,7 @@ innobase_init(void)
memcpy(srv_latin1_ordering, my_charset_latin1.sort_order, 256);
/* Since we in this module access directly the fields of a trx
- struct, and due to different headers and flags it might happen that
+ struct, and due to different headers and flags it might happen that
mutex_t has a different size in this module and in InnoDB
modules, we check at run time that the size is the same in
these compilation modules. */
@@ -1417,46 +1589,31 @@ innobase_init(void)
err = innobase_start_or_create_for_mysql();
if (err != DB_SUCCESS) {
- my_free(internal_innobase_data_file_path,
+ my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- goto error;
+ goto error;
}
(void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
- (hash_get_key) innobase_get_key, 0, 0);
- pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
- pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
- pthread_cond_init(&commit_cond, NULL);
+ (hash_get_key) innobase_get_key, 0, 0);
+ pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
+ pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
+ pthread_cond_init(&commit_cond, NULL);
innodb_inited= 1;
- /* If this is a replication slave and we needed to do a crash recovery,
- set the master binlog position to what InnoDB internally knew about
- how far we got transactions durable inside InnoDB. There is a
- problem here: if the user used also MyISAM tables, InnoDB might not
- know the right position for them.
-
- THIS DOES NOT WORK CURRENTLY because replication seems to initialize
- glob_mi also after innobase_init. */
-
-/* if (trx_sys_mysql_master_log_pos != -1) {
- ut_memcpy(glob_mi.log_file_name, trx_sys_mysql_master_log_name,
- 1 + ut_strlen(trx_sys_mysql_master_log_name));
- glob_mi.pos = trx_sys_mysql_master_log_pos;
- }
-*/
DBUG_RETURN(FALSE);
error:
- have_innodb= SHOW_OPTION_DISABLED; // If we couldn't use handler
- DBUG_RETURN(TRUE);
+ have_innodb= SHOW_OPTION_DISABLED; // If we couldn't use handler
+ DBUG_RETURN(TRUE);
}
/***********************************************************************
Closes an InnoDB database. */
-bool
-innobase_end(void)
+int
+innobase_end(ha_panic_function type)
/*==============*/
/* out: TRUE if error */
{
@@ -1464,29 +1621,29 @@ innobase_end(void)
DBUG_ENTER("innobase_end");
-#ifdef __NETWARE__ /* some special cleanup for NetWare */
+#ifdef __NETWARE__ /* some special cleanup for NetWare */
if (nw_panic) {
set_panic_flag_for_netware();
}
#endif
if (innodb_inited) {
- srv_fast_shutdown = (ulint) innobase_fast_shutdown;
- innodb_inited = 0;
- if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
- err = 1;
+ srv_fast_shutdown = (ulint) innobase_fast_shutdown;
+ innodb_inited = 0;
+ if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
+ err = 1;
}
- hash_free(&innobase_open_tables);
- my_free(internal_innobase_data_file_path,
+ hash_free(&innobase_open_tables);
+ my_free(internal_innobase_data_file_path,
MYF(MY_ALLOW_ZERO_PTR));
- pthread_mutex_destroy(&innobase_share_mutex);
- pthread_mutex_destroy(&prepare_commit_mutex);
- pthread_mutex_destroy(&commit_threads_m);
- pthread_mutex_destroy(&commit_cond_m);
- pthread_cond_destroy(&commit_cond);
+ pthread_mutex_destroy(&innobase_share_mutex);
+ pthread_mutex_destroy(&prepare_commit_mutex);
+ pthread_mutex_destroy(&commit_threads_m);
+ pthread_mutex_destroy(&commit_cond_m);
+ pthread_cond_destroy(&commit_cond);
}
- DBUG_RETURN(err);
+ DBUG_RETURN(err);
}
/********************************************************************
@@ -1498,13 +1655,13 @@ innobase_flush_logs(void)
/*=====================*/
/* out: TRUE if error */
{
- bool result = 0;
+ bool result = 0;
- DBUG_ENTER("innobase_flush_logs");
+ DBUG_ENTER("innobase_flush_logs");
log_buffer_flush_to_disk();
- DBUG_RETURN(result);
+ DBUG_RETURN(result);
}
/*********************************************************************
@@ -1515,23 +1672,10 @@ innobase_commit_low(
/*================*/
trx_t* trx) /* in: transaction handle */
{
- if (trx->conc_state == TRX_NOT_STARTED) {
+ if (trx->conc_state == TRX_NOT_STARTED) {
- return;
- }
-
-#ifdef HAVE_REPLICATION
- THD *thd=current_thd;
-
- if (thd && thd->slave_thread) {
- /* Update the replication position info inside InnoDB */
-
- trx->mysql_master_log_file_name
- = active_mi->rli.group_master_log_name;
- trx->mysql_master_log_pos = ((ib_longlong)
- active_mi->rli.future_group_master_log_pos);
- }
-#endif /* HAVE_REPLICATION */
+ return;
+ }
trx_commit_for_mysql(trx);
}
@@ -1551,7 +1695,7 @@ innobase_start_trx_and_assign_read_view(
{
trx_t* trx;
- DBUG_ENTER("innobase_start_trx_and_assign_read_view");
+ DBUG_ENTER("innobase_start_trx_and_assign_read_view");
/* Create a new trx struct for thd, if it does not yet have one */
@@ -1573,12 +1717,12 @@ innobase_start_trx_and_assign_read_view(
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(current_thd);
+ innobase_register_trx_and_stmt(current_thd);
- trx->active_trans = 1;
- }
+ trx->active_trans = 1;
+ }
DBUG_RETURN(0);
}
@@ -1593,13 +1737,13 @@ innobase_commit(
/* out: 0 */
THD* thd, /* in: MySQL thread handle of the user for whom
the transaction should be committed */
- bool all) /* in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
+ bool all) /* in: TRUE - commit transaction
+ FALSE - the current SQL statement ended */
{
trx_t* trx;
- DBUG_ENTER("innobase_commit");
- DBUG_PRINT("trans", ("ending transaction"));
+ DBUG_ENTER("innobase_commit");
+ DBUG_PRINT("trans", ("ending transaction"));
trx = check_trx_exists(thd);
@@ -1610,11 +1754,11 @@ innobase_commit(
reserve the kernel mutex, we have to release the search system latch
first to obey the latching order. */
- if (trx->has_search_latch) {
- trx_search_latch_release_if_reserved(trx);
- }
+ if (trx->has_search_latch) {
+ trx_search_latch_release_if_reserved(trx);
+ }
- /* The flag trx->active_trans is set to 1 in
+ /* The flag trx->active_trans is set to 1 in
1. ::external_lock(),
2. ::start_stmt(),
@@ -1629,59 +1773,60 @@ innobase_commit(
For the time being, we play safe and do the cleanup though there should
be nothing to clean up. */
- if (trx->active_trans == 0
- && trx->conc_state != TRX_NOT_STARTED) {
+ if (trx->active_trans == 0
+ && trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but trx->conc_state != "
- "TRX_NOT_STARTED");
+ sql_print_error("trx->active_trans == 0, but"
+ " trx->conc_state != TRX_NOT_STARTED");
}
- if (all
- || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+ if (all
+ || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
- /* We were instructed to commit the whole transaction, or
+ /* We were instructed to commit the whole transaction, or
this is an SQL statement end and autocommit is on */
- /* We need current binlog position for ibbackup to work.
- Note, the position is current because of prepare_commit_mutex */
+ /* We need current binlog position for ibbackup to work.
+ Note, the position is current because of
+ prepare_commit_mutex */
retry:
- if (srv_commit_concurrency > 0)
- {
- pthread_mutex_lock(&commit_cond_m);
- commit_threads++;
- if (commit_threads > srv_commit_concurrency)
- {
- commit_threads--;
- pthread_cond_wait(&commit_cond, &commit_cond_m);
- pthread_mutex_unlock(&commit_cond_m);
- goto retry;
- }
- else
- pthread_mutex_unlock(&commit_cond_m);
- }
-
- trx->mysql_log_file_name = mysql_bin_log.get_log_fname();
- trx->mysql_log_offset =
- (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file;
+ if (srv_commit_concurrency > 0) {
+ pthread_mutex_lock(&commit_cond_m);
+ commit_threads++;
+
+ if (commit_threads > srv_commit_concurrency) {
+ commit_threads--;
+ pthread_cond_wait(&commit_cond,
+ &commit_cond_m);
+ pthread_mutex_unlock(&commit_cond_m);
+ goto retry;
+ }
+ else {
+ pthread_mutex_unlock(&commit_cond_m);
+ }
+ }
+
+ trx->mysql_log_file_name = mysql_bin_log.get_log_fname();
+ trx->mysql_log_offset =
+ (ib_longlong)mysql_bin_log.get_log_file()->pos_in_file;
innobase_commit_low(trx);
- if (srv_commit_concurrency > 0)
- {
- pthread_mutex_lock(&commit_cond_m);
- commit_threads--;
- pthread_cond_signal(&commit_cond);
- pthread_mutex_unlock(&commit_cond_m);
- }
+ if (srv_commit_concurrency > 0) {
+ pthread_mutex_lock(&commit_cond_m);
+ commit_threads--;
+ pthread_cond_signal(&commit_cond);
+ pthread_mutex_unlock(&commit_cond_m);
+ }
- if (trx->active_trans == 2) {
+ if (trx->active_trans == 2) {
- pthread_mutex_unlock(&prepare_commit_mutex);
- }
+ pthread_mutex_unlock(&prepare_commit_mutex);
+ }
- trx->active_trans = 0;
+ trx->active_trans = 0;
} else {
- /* We just mark the SQL statement ended and do not do a
+ /* We just mark the SQL statement ended and do not do a
transaction commit */
if (trx->auto_inc_lock) {
@@ -1699,11 +1844,11 @@ retry:
/* Tell the InnoDB server that there might be work for utility
threads: */
- if (trx->declared_to_be_inside_innodb) {
- /* Release our possible ticket in the FIFO */
+ if (trx->declared_to_be_inside_innodb) {
+ /* Release our possible ticket in the FIFO */
- srv_conc_force_exit_innodb(trx);
- }
+ srv_conc_force_exit_innodb(trx);
+ }
srv_active_wake_master_thread();
DBUG_RETURN(0);
@@ -1725,12 +1870,12 @@ InnoDB's group commit capability. */
int
innobase_report_binlog_offset_and_commit(
/*=====================================*/
- /* out: 0 */
- THD* thd, /* in: user thread */
- void* trx_handle, /* in: InnoDB trx handle */
- char* log_file_name, /* in: latest binlog file name */
- my_off_t end_offset) /* in: the offset in the binlog file
- up to which we wrote */
+ /* out: 0 */
+ THD* thd, /* in: user thread */
+ void* trx_handle, /* in: InnoDB trx handle */
+ char* log_file_name, /* in: latest binlog file name */
+ my_off_t end_offset) /* in: the offset in the binlog file
+ up to which we wrote */
{
trx_t* trx;
@@ -1757,26 +1902,26 @@ This function stores the binlog offset a
void
innobase_store_binlog_offset_and_flush_log(
/*=======================================*/
- char *binlog_name, /* in: binlog name */
- longlong offset) /* in: binlog offset */
+ char* binlog_name, /* in: binlog name */
+ longlong offset) /* in: binlog offset */
{
mtr_t mtr;
assert(binlog_name != NULL);
/* Start a mini-transaction */
- mtr_start_noninline(&mtr);
+ mtr_start_noninline(&mtr);
/* Update the latest MySQL binlog name and offset info
- in trx sys header */
+ in trx sys header */
- trx_sys_update_mysql_binlog_offset(
- binlog_name,
- offset,
- TRX_SYS_MYSQL_LOG_INFO, &mtr);
+ trx_sys_update_mysql_binlog_offset(
+ binlog_name,
+ offset,
+ TRX_SYS_MYSQL_LOG_INFO, &mtr);
- /* Commits the mini-transaction */
- mtr_commit(&mtr);
+ /* Commits the mini-transaction */
+ mtr_commit(&mtr);
/* Synchronous flush of the log buffer to disk */
log_buffer_flush_to_disk();
@@ -1790,24 +1935,24 @@ transaction. Flushes the InnoDB log file
int
innobase_commit_complete(
/*=====================*/
- /* out: 0 */
- THD* thd) /* in: user thread */
+ /* out: 0 */
+ THD* thd) /* in: user thread */
{
trx_t* trx;
- trx = (trx_t*) thd->ha_data[innobase_hton.slot];
+ trx = (trx_t*) thd->ha_data[innobase_hton->slot];
- if (trx && trx->active_trans) {
+ if (trx && trx->active_trans) {
- trx->active_trans = 0;
+ trx->active_trans = 0;
- if (UNIV_UNLIKELY(srv_flush_log_at_trx_commit == 0)) {
+ if (UNIV_UNLIKELY(srv_flush_log_at_trx_commit == 0)) {
- return(0);
- }
+ return(0);
+ }
- trx_commit_complete_for_mysql(trx);
- }
+ trx_commit_complete_for_mysql(trx);
+ }
return(0);
}
@@ -1821,8 +1966,8 @@ innobase_rollback(
/* out: 0 or error number */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- bool all) /* in: TRUE - commit transaction
- FALSE - the current SQL statement ended */
+ bool all) /* in: TRUE - commit transaction
+ FALSE - the current SQL statement ended */
{
int error = 0;
trx_t* trx;
@@ -1841,7 +1986,7 @@ innobase_rollback(
innobase_release_stat_resources(trx);
- if (trx->auto_inc_lock) {
+ if (trx->auto_inc_lock) {
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -1849,11 +1994,11 @@ innobase_rollback(
row_unlock_table_autoinc_for_mysql(trx);
}
- if (all
- || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+ if (all
+ || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
error = trx_rollback_for_mysql(trx);
- trx->active_trans = 0;
+ trx->active_trans = 0;
} else {
error = trx_rollback_last_sql_stat_for_mysql(trx);
}
@@ -1881,7 +2026,7 @@ innobase_rollback_trx(
innobase_release_stat_resources(trx);
- if (trx->auto_inc_lock) {
+ if (trx->auto_inc_lock) {
/* If we had reserved the auto-inc lock for some table (if
we come here to roll back the latest SQL statement) we
release it now before a possibly lengthy rollback */
@@ -1904,12 +2049,12 @@ innobase_rollback_to_savepoint(
no savepoint with the given name */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void *savepoint) /* in: savepoint data */
+ void* savepoint) /* in: savepoint data */
{
- ib_longlong mysql_binlog_cache_pos;
- int error = 0;
- trx_t* trx;
- char name[64];
+ ib_longlong mysql_binlog_cache_pos;
+ int error = 0;
+ trx_t* trx;
+ char name[64];
DBUG_ENTER("innobase_rollback_to_savepoint");
@@ -1921,11 +2066,11 @@ innobase_rollback_to_savepoint(
innobase_release_stat_resources(trx);
- /* TODO: use provided savepoint data area to store savepoint data */
+ /* TODO: use provided savepoint data area to store savepoint data */
- longlong2str((ulint)savepoint, name, 36);
+ longlong2str((ulint)savepoint, name, 36);
- error = (int) trx_rollback_to_savepoint_for_mysql(trx, name,
+ error = (int) trx_rollback_to_savepoint_for_mysql(trx, name,
&mysql_binlog_cache_pos);
DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
}
@@ -1940,19 +2085,19 @@ innobase_release_savepoint(
no savepoint with the given name */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void* savepoint) /* in: savepoint data */
+ void* savepoint) /* in: savepoint data */
{
- int error = 0;
- trx_t* trx;
- char name[64];
+ int error = 0;
+ trx_t* trx;
+ char name[64];
DBUG_ENTER("innobase_release_savepoint");
trx = check_trx_exists(thd);
- /* TODO: use provided savepoint data area to store savepoint data */
+ /* TODO: use provided savepoint data area to store savepoint data */
- longlong2str((ulint)savepoint, name, 36);
+ longlong2str((ulint)savepoint, name, 36);
error = (int) trx_release_savepoint_for_mysql(trx, name);
@@ -1967,20 +2112,20 @@ innobase_savepoint(
/*===============*/
/* out: always 0, that is, always succeeds */
THD* thd, /* in: handle to the MySQL thread */
- void* savepoint) /* in: savepoint data */
+ void* savepoint) /* in: savepoint data */
{
int error = 0;
trx_t* trx;
DBUG_ENTER("innobase_savepoint");
- /*
- In the autocommit mode there is no sense to set a savepoint
- (unless we are in sub-statement), so SQL layer ensures that
- this method is never called in such situation.
- */
- DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
- thd->in_sub_stmt);
+ /*
+ In the autocommit mode there is no sense to set a savepoint
+ (unless we are in sub-statement), so SQL layer ensures that
+ this method is never called in such situation.
+ */
+ DBUG_ASSERT(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN) ||
+ thd->in_sub_stmt);
trx = check_trx_exists(thd);
@@ -1990,14 +2135,14 @@ innobase_savepoint(
innobase_release_stat_resources(trx);
- /* cannot happen outside of transaction */
- DBUG_ASSERT(trx->active_trans);
+ /* cannot happen outside of transaction */
+ DBUG_ASSERT(trx->active_trans);
- /* TODO: use provided savepoint data area to store savepoint data */
- char name[64];
- longlong2str((ulint)savepoint,name,36);
+ /* TODO: use provided savepoint data area to store savepoint data */
+ char name[64];
+ longlong2str((ulint)savepoint,name,36);
- error = (int) trx_savepoint_for_mysql(trx, name, (ib_longlong)0);
+ error = (int) trx_savepoint_for_mysql(trx, name, (ib_longlong)0);
DBUG_RETURN(convert_error_code_to_mysql(error, NULL));
}
@@ -2014,28 +2159,31 @@ innobase_close_connection(
{
trx_t* trx;
- trx = (trx_t*)thd->ha_data[innobase_hton.slot];
+ trx = (trx_t*)thd->ha_data[innobase_hton->slot];
ut_a(trx);
- if (trx->active_trans == 0
- && trx->conc_state != TRX_NOT_STARTED) {
+ if (trx->active_trans == 0
+ && trx->conc_state != TRX_NOT_STARTED) {
- sql_print_error("trx->active_trans == 0, but trx->conc_state != "
- "TRX_NOT_STARTED");
+ sql_print_error("trx->active_trans == 0, but"
+ " trx->conc_state != TRX_NOT_STARTED");
}
if (trx->conc_state != TRX_NOT_STARTED &&
- global_system_variables.log_warnings)
- sql_print_warning("MySQL is closing a connection that has an active "
- "InnoDB transaction. %lu row modifications will "
- "roll back.",
- (ulong)trx->undo_no.low);
+ global_system_variables.log_warnings) {
+ sql_print_warning(
+ "MySQL is closing a connection that has an active "
+ "InnoDB transaction. %lu row modifications will "
+ "roll back.",
+ (ulong) trx->undo_no.low);
+ }
innobase_rollback_trx(trx);
- trx_free_for_mysql(trx);
+ thr_local_free(trx->mysql_thread_id);
+ trx_free_for_mysql(trx);
return(0);
}
@@ -2055,7 +2203,7 @@ ha_innobase::get_row_type() const
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
if (prebuilt && prebuilt->table) {
- if (prebuilt->table->comp) {
+ if (dict_table_is_comp_noninline(prebuilt->table)) {
return(ROW_TYPE_COMPACT);
} else {
return(ROW_TYPE_REDUNDANT);
@@ -2136,11 +2284,11 @@ ha_innobase::open(
/*==============*/
/* out: 1 if error, 0 if success */
const char* name, /* in: table name */
- int mode, /* in: not used */
- uint test_if_locked) /* in: not used */
+ int mode, /* in: not used */
+ uint test_if_locked) /* in: not used */
{
dict_table_t* ib_table;
- char norm_name[1000];
+ char norm_name[1000];
THD* thd;
DBUG_ENTER("ha_innobase::open");
@@ -2169,20 +2317,20 @@ ha_innobase::open(
table->s->reclength + table->s->max_key_length
+ MAX_REF_PARTS * 3;
if (!(mysql_byte*) my_multi_malloc(MYF(MY_WME),
- &upd_buff, upd_and_key_val_buff_len,
- &key_val_buff, upd_and_key_val_buff_len,
- NullS)) {
- free_share(share);
+ &upd_buff, upd_and_key_val_buff_len,
+ &key_val_buff, upd_and_key_val_buff_len,
+ NullS)) {
+ free_share(share);
- DBUG_RETURN(1);
- }
+ DBUG_RETURN(1);
+ }
/* Get pointer to a table object in InnoDB dictionary cache */
- ib_table = dict_table_get_and_increment_handle_count(
- norm_name, NULL);
- if (NULL == ib_table) {
- ut_print_timestamp(stderr);
+ ib_table = dict_table_get_and_increment_handle_count(norm_name);
+
+ if (NULL == ib_table) {
+ ut_print_timestamp(stderr);
sql_print_error("Cannot find table %s from the internal data "
"dictionary\nof InnoDB though the .frm file "
"for the table exists. Maybe you\nhave "
@@ -2190,33 +2338,33 @@ ha_innobase::open(
"have forgotten\nto delete the corresponding "
".frm files of InnoDB tables, or you\n"
"have moved .frm files to another database?\n"
- "See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n"
+ "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
- free_share(share);
- my_free((gptr) upd_buff, MYF(0));
- my_errno = ENOENT;
+ free_share(share);
+ my_free((gptr) upd_buff, MYF(0));
+ my_errno = ENOENT;
- DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
- }
+ DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
+ }
- if (ib_table->ibd_file_missing && !thd->tablespace_op) {
- ut_print_timestamp(stderr);
+ if (ib_table->ibd_file_missing && !thd->tablespace_op) {
+ ut_print_timestamp(stderr);
sql_print_error("MySQL is trying to open a table handle but "
"the .ibd file for\ntable %s does not exist.\n"
"Have you deleted the .ibd file from the "
"database directory under\nthe MySQL datadir, "
"or have you used DISCARD TABLESPACE?\n"
- "See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n"
+ "See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
norm_name);
- free_share(share);
- my_free((gptr) upd_buff, MYF(0));
- my_errno = ENOENT;
+ free_share(share);
+ my_free((gptr) upd_buff, MYF(0));
+ my_errno = ENOENT;
dict_table_decrement_handle_count(ib_table);
- DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
- }
+ DBUG_RETURN(HA_ERR_NO_SUCH_TABLE);
+ }
innobase_prebuilt = row_create_prebuilt(ib_table);
@@ -2225,32 +2373,32 @@ ha_innobase::open(
/* Looks like MySQL-3.23 sometimes has primary key number != 0 */
- primary_key = table->s->primary_key;
+ primary_key = table->s->primary_key;
key_used_on_scan = primary_key;
/* Allocate a buffer for a 'row reference'. A row reference is
a string of bytes of length ref_length which uniquely specifies
- a row in our table. Note that MySQL may also compare two row
- references for equality by doing a simple memcmp on the strings
- of length ref_length! */
+ a row in our table. Note that MySQL may also compare two row
+ references for equality by doing a simple memcmp on the strings
+ of length ref_length! */
- if (!row_table_got_default_clust_index(ib_table)) {
- if (primary_key >= MAX_KEY) {
+ if (!row_table_got_default_clust_index(ib_table)) {
+ if (primary_key >= MAX_KEY) {
sql_print_error("Table %s has a primary key in InnoDB data "
"dictionary, but not in MySQL!", name);
}
((row_prebuilt_t*)innobase_prebuilt)
->clust_index_was_generated = FALSE;
- /* MySQL allocates the buffer for ref. key_info->key_length
+ /* MySQL allocates the buffer for ref. key_info->key_length
includes space for all key columns + one byte for each column
that may be NULL. ref_length must be as exact as possible to
save space, because all row reference buffers are allocated
based on ref_length. */
- ref_length = table->key_info[primary_key].key_length;
+ ref_length = table->key_info[primary_key].key_length;
} else {
- if (primary_key != MAX_KEY) {
+ if (primary_key != MAX_KEY) {
sql_print_error("Table %s has no primary key in InnoDB data "
"dictionary, but has one in MySQL! If you "
"created the table with a MySQL version < "
@@ -2265,7 +2413,7 @@ ha_innobase::open(
((row_prebuilt_t*)innobase_prebuilt)
->clust_index_was_generated = TRUE;
- ref_length = DATA_ROW_ID_LEN;
+ ref_length = DATA_ROW_ID_LEN;
/* If we automatically created the clustered index, then
MySQL does not know about it, and MySQL must NOT be aware
@@ -2276,21 +2424,22 @@ ha_innobase::open(
and it will never be updated anyway. */
if (key_used_on_scan != MAX_KEY) {
- sql_print_warning("Table %s key_used_on_scan is %lu even "
- "though there is no primary key inside "
- "InnoDB.", name, (ulong) key_used_on_scan);
+ sql_print_warning(
+ "Table %s key_used_on_scan is %lu even "
+ "though there is no primary key inside "
+ "InnoDB.", name, (ulong) key_used_on_scan);
}
}
- block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
+ stats.block_size = 16 * 1024; /* Index block size in InnoDB: used by MySQL
in query optimization */
/* Init table lock structure */
thr_lock_data_init(&share->lock,&lock,(void*) 0);
- info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
+ info(HA_STATUS_NO_LOCK | HA_STATUS_VARIABLE | HA_STATUS_CONST);
- DBUG_RETURN(0);
+ DBUG_RETURN(0);
}
uint
@@ -2307,19 +2456,19 @@ ha_innobase::close(void)
/*====================*/
/* out: 0 */
{
- DBUG_ENTER("ha_innobase::close");
+ DBUG_ENTER("ha_innobase::close");
row_prebuilt_free((row_prebuilt_t*) innobase_prebuilt);
- my_free((gptr) upd_buff, MYF(0));
- free_share(share);
+ my_free((gptr) upd_buff, MYF(0));
+ free_share(share);
/* Tell InnoDB server that there might be work for
utility threads: */
srv_active_wake_master_thread();
- DBUG_RETURN(0);
+ DBUG_RETURN(0);
}
/* The following accessor functions should really be inside MySQL code! */
@@ -2409,7 +2558,7 @@ innobase_mysql_cmp(
{
CHARSET_INFO* charset;
enum_field_types mysql_tp;
- int ret;
+ int ret;
DBUG_ASSERT(a_length != UNIV_SQL_NULL);
DBUG_ASSERT(b_length != UNIV_SQL_NULL);
@@ -2418,14 +2567,14 @@ innobase_mysql_cmp(
switch (mysql_tp) {
- case MYSQL_TYPE_BIT:
+ case MYSQL_TYPE_BIT:
case MYSQL_TYPE_STRING:
case MYSQL_TYPE_VAR_STRING:
case FIELD_TYPE_TINY_BLOB:
case FIELD_TYPE_MEDIUM_BLOB:
case FIELD_TYPE_BLOB:
case FIELD_TYPE_LONG_BLOB:
- case MYSQL_TYPE_VARCHAR:
+ case MYSQL_TYPE_VARCHAR:
/* Use the charset number to pick the right charset struct for
the comparison. Since the MySQL function get_charset may be
slow before Bar removes the mutex operation there, we first
@@ -2447,21 +2596,21 @@ innobase_mysql_cmp(
}
}
- /* Starting from 4.1.3, we use strnncollsp() in comparisons of
- non-latin1_swedish_ci strings. NOTE that the collation order
- changes then: 'b\0\0...' is ordered BEFORE 'b ...'. Users
- having indexes on such data need to rebuild their tables! */
-
- ret = charset->coll->strnncollsp(charset,
- a, a_length,
- b, b_length, 0);
+ /* Starting from 4.1.3, we use strnncollsp() in comparisons of
+ non-latin1_swedish_ci strings. NOTE that the collation order
+ changes then: 'b\0\0...' is ordered BEFORE 'b ...'. Users
+ having indexes on such data need to rebuild their tables! */
+
+ ret = charset->coll->strnncollsp(charset,
+ a, a_length,
+ b, b_length, 0);
if (ret < 0) {
- return(-1);
+ return(-1);
} else if (ret > 0) {
- return(1);
+ return(1);
} else {
- return(0);
- }
+ return(0);
+ }
default:
assert(0);
}
@@ -2502,7 +2651,7 @@ get_innobase_type_from_mysql_type(
}
if (field->real_type() == FIELD_TYPE_ENUM
- || field->real_type() == FIELD_TYPE_SET) {
+ || field->real_type() == FIELD_TYPE_SET) {
/* MySQL has field->type() a string type for these, but the
data is actually internally stored as an unsigned integer
@@ -2516,58 +2665,58 @@ get_innobase_type_from_mysql_type(
}
switch (field->type()) {
- /* NOTE that we only allow string types in DATA_MYSQL
- and DATA_VARMYSQL */
- case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
- case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
- if (field->binary()) {
- return(DATA_BINARY);
- } else if (strcmp(
- field->charset()->name,
- "latin1_swedish_ci") == 0) {
- return(DATA_VARCHAR);
- } else {
- return(DATA_VARMYSQL);
- }
- case MYSQL_TYPE_BIT:
- case MYSQL_TYPE_STRING: if (field->binary()) {
-
- return(DATA_FIXBINARY);
- } else if (strcmp(
- field->charset()->name,
- "latin1_swedish_ci") == 0) {
- return(DATA_CHAR);
- } else {
- return(DATA_MYSQL);
- }
- case FIELD_TYPE_NEWDECIMAL:
- return(DATA_FIXBINARY);
- case FIELD_TYPE_LONG:
- case FIELD_TYPE_LONGLONG:
- case FIELD_TYPE_TINY:
- case FIELD_TYPE_SHORT:
- case FIELD_TYPE_INT24:
- case FIELD_TYPE_DATE:
- case FIELD_TYPE_DATETIME:
- case FIELD_TYPE_YEAR:
- case FIELD_TYPE_NEWDATE:
- case FIELD_TYPE_TIME:
- case FIELD_TYPE_TIMESTAMP:
- return(DATA_INT);
- case FIELD_TYPE_FLOAT:
- return(DATA_FLOAT);
- case FIELD_TYPE_DOUBLE:
- return(DATA_DOUBLE);
- case FIELD_TYPE_DECIMAL:
- return(DATA_DECIMAL);
- case FIELD_TYPE_GEOMETRY:
- case FIELD_TYPE_TINY_BLOB:
- case FIELD_TYPE_MEDIUM_BLOB:
- case FIELD_TYPE_BLOB:
- case FIELD_TYPE_LONG_BLOB:
- return(DATA_BLOB);
- default:
- assert(0);
+ /* NOTE that we only allow string types in DATA_MYSQL and
+ DATA_VARMYSQL */
+ case MYSQL_TYPE_VAR_STRING: /* old <= 4.1 VARCHAR */
+ case MYSQL_TYPE_VARCHAR: /* new >= 5.0.3 true VARCHAR */
+ if (field->binary()) {
+ return(DATA_BINARY);
+ } else if (strcmp(
+ field->charset()->name,
+ "latin1_swedish_ci") == 0) {
+ return(DATA_VARCHAR);
+ } else {
+ return(DATA_VARMYSQL);
+ }
+ case MYSQL_TYPE_BIT:
+ case MYSQL_TYPE_STRING: if (field->binary()) {
+
+ return(DATA_FIXBINARY);
+ } else if (strcmp(
+ field->charset()->name,
+ "latin1_swedish_ci") == 0) {
+ return(DATA_CHAR);
+ } else {
+ return(DATA_MYSQL);
+ }
+ case FIELD_TYPE_NEWDECIMAL:
+ return(DATA_FIXBINARY);
+ case FIELD_TYPE_LONG:
+ case FIELD_TYPE_LONGLONG:
+ case FIELD_TYPE_TINY:
+ case FIELD_TYPE_SHORT:
+ case FIELD_TYPE_INT24:
+ case FIELD_TYPE_DATE:
+ case FIELD_TYPE_DATETIME:
+ case FIELD_TYPE_YEAR:
+ case FIELD_TYPE_NEWDATE:
+ case FIELD_TYPE_TIME:
+ case FIELD_TYPE_TIMESTAMP:
+ return(DATA_INT);
+ case FIELD_TYPE_FLOAT:
+ return(DATA_FLOAT);
+ case FIELD_TYPE_DOUBLE:
+ return(DATA_DOUBLE);
+ case FIELD_TYPE_DECIMAL:
+ return(DATA_DECIMAL);
+ case FIELD_TYPE_GEOMETRY:
+ case FIELD_TYPE_TINY_BLOB:
+ case FIELD_TYPE_MEDIUM_BLOB:
+ case FIELD_TYPE_BLOB:
+ case FIELD_TYPE_LONG_BLOB:
+ return(DATA_BLOB);
+ default:
+ assert(0);
}
return(0);
@@ -2609,21 +2758,21 @@ uint
ha_innobase::store_key_val_for_row(
/*===============================*/
/* out: key value length as stored in buff */
- uint keynr, /* in: key number */
+ uint keynr, /* in: key number */
char* buff, /* in/out: buffer for the key value (in MySQL
format) */
uint buff_len,/* in: buffer length */
const mysql_byte* record)/* in: row in MySQL format */
{
- KEY* key_info = table->key_info + keynr;
- KEY_PART_INFO* key_part = key_info->key_part;
- KEY_PART_INFO* end = key_part + key_info->key_parts;
+ KEY* key_info = table->key_info + keynr;
+ KEY_PART_INFO* key_part = key_info->key_part;
+ KEY_PART_INFO* end = key_part + key_info->key_parts;
char* buff_start = buff;
enum_field_types mysql_type;
Field* field;
ibool is_null;
- DBUG_ENTER("store_key_val_for_row");
+ DBUG_ENTER("store_key_val_for_row");
/* The format for storing a key field in MySQL is the following:
@@ -2652,19 +2801,19 @@ ha_innobase::store_key_val_for_row(
bzero(buff, buff_len);
- for (; key_part != end; key_part++) {
- is_null = FALSE;
+ for (; key_part != end; key_part++) {
+ is_null = FALSE;
- if (key_part->null_bit) {
- if (record[key_part->null_offset]
+ if (key_part->null_bit) {
+ if (record[key_part->null_offset]
& key_part->null_bit) {
*buff = 1;
is_null = TRUE;
- } else {
+ } else {
*buff = 0;
}
buff++;
- }
+ }
field = key_part->field;
mysql_type = field->type();
@@ -2733,13 +2882,12 @@ ha_innobase::store_key_val_for_row(
buff += key_len;
} else if (mysql_type == FIELD_TYPE_TINY_BLOB
- || mysql_type == FIELD_TYPE_MEDIUM_BLOB
- || mysql_type == FIELD_TYPE_BLOB
- || mysql_type == FIELD_TYPE_LONG_BLOB) {
+ || mysql_type == FIELD_TYPE_MEDIUM_BLOB
+ || mysql_type == FIELD_TYPE_BLOB
+ || mysql_type == FIELD_TYPE_LONG_BLOB) {
CHARSET_INFO* cs;
ulint key_len;
- ulint len;
ulint true_len;
int error=0;
ulint blob_len;
@@ -2749,7 +2897,7 @@ ha_innobase::store_key_val_for_row(
key_len = key_part->length;
- if (is_null) {
+ if (is_null) {
buff += key_len + 2;
continue;
@@ -2757,7 +2905,7 @@ ha_innobase::store_key_val_for_row(
cs = field->charset();
- blob_data = row_mysql_read_blob_ref(&blob_len,
+ blob_data = row_mysql_read_blob_ref(&blob_len,
(byte*) (record
+ (ulint)get_field_offset(table, field)),
(ulint) field->pack_length());
@@ -2765,7 +2913,7 @@ ha_innobase::store_key_val_for_row(
true_len = blob_len;
ut_a(get_field_offset(table, field)
- == key_part->offset);
+ == key_part->offset);
/* For multi byte character sets we need to calculate
the true length of the key */
@@ -2815,7 +2963,7 @@ ha_innobase::store_key_val_for_row(
key_len = key_part->length;
- if (is_null) {
+ if (is_null) {
buff += key_len;
continue;
@@ -2867,7 +3015,7 @@ ha_innobase::store_key_val_for_row(
buff += pad_len;
}
}
- }
+ }
ut_a(buff <= buff_start + buff_len);
@@ -2886,7 +3034,7 @@ build_template(
only if templ_type is
ROW_MYSQL_REC_FIELDS */
TABLE* table, /* in: MySQL table */
- ulint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
+ uint templ_type) /* in: ROW_MYSQL_WHOLE_ROW or
ROW_MYSQL_REC_FIELDS */
{
dict_index_t* index;
@@ -2906,38 +3054,39 @@ build_template(
use exclusive row level locks, for example, if the read is
done in an UPDATE statement. */
- templ_type = ROW_MYSQL_WHOLE_ROW;
+ templ_type = ROW_MYSQL_WHOLE_ROW;
}
if (templ_type == ROW_MYSQL_REC_FIELDS) {
- if (prebuilt->hint_need_to_fetch_extra_cols
- == ROW_RETRIEVE_ALL_COLS) {
+ if (prebuilt->hint_need_to_fetch_extra_cols
+ == ROW_RETRIEVE_ALL_COLS) {
- /* We know we must at least fetch all columns in the key, or
- all columns in the table */
+ /* We know we must at least fetch all columns in the
+ key, or all columns in the table */
- if (prebuilt->read_just_key) {
- /* MySQL has instructed us that it is enough to
- fetch the columns in the key; looks like MySQL
- can set this flag also when there is only a
- prefix of the column in the key: in that case we
- retrieve the whole column from the clustered
- index */
+ if (prebuilt->read_just_key) {
+ /* MySQL has instructed us that it is enough
+ to fetch the columns in the key; looks like
+ MySQL can set this flag also when there is
+ only a prefix of the column in the key: in
+ that case we retrieve the whole column from
+ the clustered index */
- fetch_all_in_key = TRUE;
- } else {
- templ_type = ROW_MYSQL_WHOLE_ROW;
- }
- } else if (prebuilt->hint_need_to_fetch_extra_cols
- == ROW_RETRIEVE_PRIMARY_KEY) {
- /* We must at least fetch all primary key cols. Note that if
- the clustered index was internally generated by InnoDB on the
- row id (no primary key was defined), then
- row_search_for_mysql() will always retrieve the row id to a
- special buffer in the prebuilt struct. */
+ fetch_all_in_key = TRUE;
+ } else {
+ templ_type = ROW_MYSQL_WHOLE_ROW;
+ }
+ } else if (prebuilt->hint_need_to_fetch_extra_cols
+ == ROW_RETRIEVE_PRIMARY_KEY) {
+ /* We must at least fetch all primary key cols. Note
+ that if the clustered index was internally generated
+ by InnoDB on the row id (no primary key was
+ defined), then row_search_for_mysql() will always
+ retrieve the row id to a special buffer in the
+ prebuilt struct. */
- fetch_primary_key_cols = TRUE;
- }
+ fetch_primary_key_cols = TRUE;
+ }
}
clust_index = dict_table_get_first_index_noninline(prebuilt->table);
@@ -2994,15 +3143,16 @@ build_template(
goto include_field;
}
- if (thd->query_id == field->query_id) {
+ if (bitmap_is_set(table->read_set, i) ||
+ bitmap_is_set(table->write_set, i)) {
/* This field is needed in the query */
goto include_field;
}
if (fetch_primary_key_cols
- && dict_table_col_in_clustered_key(index->table,
- i)) {
+ && dict_table_col_in_clustered_key(
+ index->table, i)) {
/* This field is needed in the query */
goto include_field;
@@ -3018,8 +3168,8 @@ include_field:
templ->col_no = i;
if (index == clust_index) {
- templ->rec_field_no = (index->table->cols + i)
- ->clust_pos;
+ templ->rec_field_no = dict_col_get_clust_pos_noninline(
+ &index->table->cols[i], index);
} else {
templ->rec_field_no = dict_index_get_nth_col_pos(
index, i);
@@ -3048,19 +3198,19 @@ include_field:
mysql_prefix_len = templ->mysql_col_offset
+ templ->mysql_col_len;
}
- templ->type = index->table->cols[i].type.mtype;
+ templ->type = index->table->cols[i].mtype;
templ->mysql_type = (ulint)field->type();
if (templ->mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
templ->mysql_length_bytes = (ulint)
- (((Field_varstring*)field)->length_bytes);
+ (((Field_varstring*)field)->length_bytes);
}
templ->charset = dtype_get_charset_coll_noninline(
- index->table->cols[i].type.prtype);
- templ->mbminlen = index->table->cols[i].type.mbminlen;
- templ->mbmaxlen = index->table->cols[i].type.mbmaxlen;
- templ->is_unsigned = index->table->cols[i].type.prtype
+ index->table->cols[i].prtype);
+ templ->mbminlen = index->table->cols[i].mbminlen;
+ templ->mbmaxlen = index->table->cols[i].mbmaxlen;
+ templ->is_unsigned = index->table->cols[i].prtype
& DATA_UNSIGNED;
if (templ->type == DATA_BLOB) {
prebuilt->templ_contains_blob = TRUE;
@@ -3078,8 +3228,9 @@ skip_field:
for (i = 0; i < n_requested_fields; i++) {
templ = prebuilt->mysql_template + i;
- templ->rec_field_no =
- (index->table->cols + templ->col_no)->clust_pos;
+ templ->rec_field_no = dict_col_get_clust_pos_noninline(
+ &index->table->cols[templ->col_no],
+ clust_index);
}
}
}
@@ -3092,22 +3243,22 @@ int
ha_innobase::write_row(
/*===================*/
/* out: error code */
- mysql_byte* record) /* in: a row in MySQL format */
+ mysql_byte* record) /* in: a row in MySQL format */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
- int error;
+ int error;
longlong auto_inc;
longlong dummy;
- ibool auto_inc_used= FALSE;
+ ibool auto_inc_used= FALSE;
- DBUG_ENTER("ha_innobase::write_row");
+ DBUG_ENTER("ha_innobase::write_row");
if (prebuilt->trx !=
- (trx_t*) current_thd->ha_data[innobase_hton.slot]) {
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]) {
sql_print_error("The transaction object for the table handle is at "
"%p, but for the current thread it is at %p",
prebuilt->trx,
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
fputs("InnoDB: Dump of 200 bytes around prebuilt: ", stderr);
ut_print_buf(stderr, ((const byte*)prebuilt) - 100, 200);
@@ -3115,23 +3266,23 @@ ha_innobase::write_row(
"InnoDB: Dump of 200 bytes around transaction.all: ",
stderr);
ut_print_buf(stderr,
- ((byte*)(&(current_thd->ha_data[innobase_hton.slot]))) - 100,
+ ((byte*)(&(current_thd->ha_data[innobase_hton->slot]))) - 100,
200);
putc('\n', stderr);
ut_error;
}
- statistic_increment(current_thd->status_var.ha_write_count,
- &LOCK_status);
+ statistic_increment(current_thd->status_var.ha_write_count,
+ &LOCK_status);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
- table->timestamp_field->set_time();
+ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_INSERT)
+ table->timestamp_field->set_time();
if ((user_thd->lex->sql_command == SQLCOM_ALTER_TABLE
- || user_thd->lex->sql_command == SQLCOM_OPTIMIZE
- || user_thd->lex->sql_command == SQLCOM_CREATE_INDEX
- || user_thd->lex->sql_command == SQLCOM_DROP_INDEX)
- && num_write_row >= 10000) {
+ || user_thd->lex->sql_command == SQLCOM_OPTIMIZE
+ || user_thd->lex->sql_command == SQLCOM_CREATE_INDEX
+ || user_thd->lex->sql_command == SQLCOM_DROP_INDEX)
+ && num_write_row >= 10000) {
/* ALTER TABLE is COMMITted at every 10000 copied rows.
The IX table lock for the original table has to be re-issued.
As this method will be called on a temporary table where the
@@ -3169,11 +3320,11 @@ no_commit:
no need to re-acquire locks on it. */
/* Altering to InnoDB format */
- innobase_commit(user_thd, 1);
+ innobase_commit(user_thd, 1);
/* Note that this transaction is still active. */
prebuilt->trx->active_trans = 1;
/* We will need an IX lock on the destination table. */
- prebuilt->sql_stat_start = TRUE;
+ prebuilt->sql_stat_start = TRUE;
} else {
/* Ensure that there are no other table locks than
LOCK_IX and LOCK_AUTO_INC on the destination table. */
@@ -3185,26 +3336,26 @@ no_commit:
/* Commit the transaction. This will release the table
locks, so they have to be acquired again. */
- innobase_commit(user_thd, 1);
+ innobase_commit(user_thd, 1);
/* Note that this transaction is still active. */
prebuilt->trx->active_trans = 1;
/* Re-acquire the table lock on the source table. */
row_lock_table_for_mysql(prebuilt, src_table, mode);
/* We will need an IX lock on the destination table. */
- prebuilt->sql_stat_start = TRUE;
+ prebuilt->sql_stat_start = TRUE;
}
}
num_write_row++;
if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
innobase_release_stat_resources(prebuilt->trx);
}
- if (table->next_number_field && record == table->record[0]) {
+ if (table->next_number_field && record == table->record[0]) {
/* This is the case where the table has an
auto-increment column */
@@ -3214,7 +3365,7 @@ no_commit:
if (0 == dict_table_autoinc_peek(prebuilt->table)) {
/* This call initializes the counter */
- error = innobase_read_and_init_auto_inc(&dummy);
+ error = innobase_read_and_init_auto_inc(&dummy);
if (error) {
/* Deadlock or lock wait timeout */
@@ -3250,10 +3401,10 @@ no_commit:
}
/* We must use the handler code to update the auto-increment
- value to be sure that we increment it correctly. */
+ value to be sure that we increment it correctly. */
- update_auto_increment();
- auto_inc_used = 1;
+ update_auto_increment();
+ auto_inc_used = 1;
}
@@ -3271,34 +3422,34 @@ no_commit:
if (error == DB_SUCCESS && auto_inc_used) {
- /* Fetch the value that was set in the autoincrement field */
+ /* Fetch the value that was set in the autoincrement field */
- auto_inc = table->next_number_field->val_int();
+ auto_inc = table->next_number_field->val_int();
- if (auto_inc != 0) {
+ if (auto_inc != 0) {
/* This call will update the counter according to the
value that was inserted in the table */
- dict_table_autoinc_update(prebuilt->table, auto_inc);
- }
- }
-
- /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate
- key error themselves, and we must update the autoinc counter if we are
- performing those statements. */
-
- if (error == DB_DUPLICATE_KEY && auto_inc_used
- && (user_thd->lex->sql_command == SQLCOM_REPLACE
- || user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT
- || (user_thd->lex->sql_command == SQLCOM_LOAD
- && user_thd->lex->duplicates == DUP_REPLACE))) {
-
- auto_inc = table->next_number_field->val_int();
-
- if (auto_inc != 0) {
- dict_table_autoinc_update(prebuilt->table, auto_inc);
- }
- }
+ dict_table_autoinc_update(prebuilt->table, auto_inc);
+ }
+ }
+
+ /* A REPLACE command and LOAD DATA INFILE REPLACE handle a duplicate
+ key error themselves, and we must update the autoinc counter if we are
+ performing those statements. */
+
+ if (error == DB_DUPLICATE_KEY && auto_inc_used
+ && (user_thd->lex->sql_command == SQLCOM_REPLACE
+ || user_thd->lex->sql_command == SQLCOM_REPLACE_SELECT
+ || (user_thd->lex->sql_command == SQLCOM_LOAD
+ && user_thd->lex->duplicates == DUP_REPLACE))) {
+
+ auto_inc = table->next_number_field->val_int();
+
+ if (auto_inc != 0) {
+ dict_table_autoinc_update(prebuilt->table, auto_inc);
+ }
+ }
innodb_srv_conc_exit_innodb(prebuilt->trx);
@@ -3309,7 +3460,7 @@ no_commit:
func_exit:
innobase_active_small();
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/**************************************************************************
@@ -3321,8 +3472,8 @@ calc_row_difference(
/*================*/
/* out: error number or 0 */
upd_t* uvect, /* in/out: update vector */
- mysql_byte* old_row, /* in: old row in MySQL format */
- mysql_byte* new_row, /* in: new row in MySQL format */
+ mysql_byte* old_row, /* in: old row in MySQL format */
+ mysql_byte* new_row, /* in: new row in MySQL format */
struct st_table* table, /* in: table in MySQL data
dictionary */
mysql_byte* upd_buff, /* in: buffer to use */
@@ -3338,16 +3489,18 @@ calc_row_difference(
ulint n_len;
ulint col_pack_len;
byte* new_mysql_row_col;
- byte* o_ptr;
- byte* n_ptr;
- byte* buf;
+ byte* o_ptr;
+ byte* n_ptr;
+ byte* buf;
upd_field_t* ufield;
ulint col_type;
ulint n_changed = 0;
dfield_t dfield;
+ dict_index_t* clust_index;
uint i;
n_fields = table->s->fields;
+ clust_index = dict_table_get_first_index_noninline(prebuilt->table);
/* We use upd_buff to convert changed fields */
buf = (byte*) upd_buff;
@@ -3378,7 +3531,7 @@ calc_row_difference(
field_mysql_type = field->type();
- col_type = prebuilt->table->cols[i].type.mtype;
+ col_type = prebuilt->table->cols[i].mtype;
switch (col_type) {
@@ -3397,14 +3550,14 @@ calc_row_difference(
1 or 2 bytes */
o_ptr = row_mysql_read_true_varchar(
- &o_len, o_ptr,
- (ulint)
- (((Field_varstring*)field)->length_bytes));
+ &o_len, o_ptr,
+ (ulint)
+ (((Field_varstring*)field)->length_bytes));
n_ptr = row_mysql_read_true_varchar(
- &n_len, n_ptr,
- (ulint)
- (((Field_varstring*)field)->length_bytes));
+ &n_len, n_ptr,
+ (ulint)
+ (((Field_varstring*)field)->length_bytes));
}
break;
@@ -3433,16 +3586,18 @@ calc_row_difference(
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
- dfield.type = (prebuilt->table->cols + i)->type;
+ dict_col_copy_type_noninline(prebuilt->table->cols + i,
+ &dfield.type);
if (n_len != UNIV_SQL_NULL) {
buf = row_mysql_store_col_in_innobase_format(
- &dfield,
- (byte*)buf,
- TRUE,
- new_mysql_row_col,
- col_pack_len,
- prebuilt->table->comp);
+ &dfield,
+ (byte*)buf,
+ TRUE,
+ new_mysql_row_col,
+ col_pack_len,
+ dict_table_is_comp_noninline(
+ prebuilt->table));
ufield->new_val.data = dfield.data;
ufield->new_val.len = dfield.len;
} else {
@@ -3451,7 +3606,8 @@ calc_row_difference(
}
ufield->exp = NULL;
- ufield->field_no = prebuilt->table->cols[i].clust_pos;
+ ufield->field_no = dict_col_get_clust_pos_noninline(
+ &prebuilt->table->cols[i], clust_index);
n_changed++;
}
}
@@ -3476,8 +3632,8 @@ int
ha_innobase::update_row(
/*====================*/
/* out: error number or 0 */
- const mysql_byte* old_row,/* in: old row in MySQL format */
- mysql_byte* new_row)/* in: new row in MySQL format */
+ const mysql_byte* old_row,/* in: old row in MySQL format */
+ mysql_byte* new_row)/* in: new row in MySQL format */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
upd_t* uvect;
@@ -3485,15 +3641,15 @@ ha_innobase::update_row(
DBUG_ENTER("ha_innobase::update_row");
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
- if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
- table->timestamp_field->set_time();
+ if (table->timestamp_field_type & TIMESTAMP_AUTO_SET_ON_UPDATE)
+ table->timestamp_field->set_time();
if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
innobase_release_stat_resources(prebuilt->trx);
}
@@ -3546,12 +3702,12 @@ ha_innobase::delete_row(
DBUG_ENTER("ha_innobase::delete_row");
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
innobase_release_stat_resources(prebuilt->trx);
}
@@ -3581,8 +3737,9 @@ ha_innobase::delete_row(
}
/**************************************************************************
-Removes a new lock set on a row. This method does nothing unless the
-option innodb_locks_unsafe_for_binlog is set.*/
+Removes a new lock set on a row, if it was not read optimistically. This can
+be called after a row has been read in the processing of an UPDATE or a DELETE
+query, if the option innodb_locks_unsafe_for_binlog is set. */
void
ha_innobase::unlock_row(void)
@@ -3592,7 +3749,7 @@ ha_innobase::unlock_row(void)
DBUG_ENTER("ha_innobase::unlock_row");
- if (last_query_id != user_thd->query_id) {
+ if (UNIV_UNLIKELY(last_query_id != user_thd->query_id)) {
ut_print_timestamp(stderr);
sql_print_error("last_query_id is %lu != user_thd_query_id is "
"%lu", (ulong) last_query_id,
@@ -3608,12 +3765,55 @@ ha_innobase::unlock_row(void)
DBUG_VOID_RETURN;
}
- if (srv_locks_unsafe_for_binlog) {
+ switch (prebuilt->row_read_type) {
+ case ROW_READ_WITH_LOCKS:
+ if (!srv_locks_unsafe_for_binlog
+ || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED) {
+ break;
+ }
+ /* fall through */
+ case ROW_READ_TRY_SEMI_CONSISTENT:
row_unlock_for_mysql(prebuilt, FALSE);
+ break;
+ case ROW_READ_DID_SEMI_CONSISTENT:
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ break;
}
DBUG_VOID_RETURN;
+}
+
+/* See handler.h and row0mysql.h for docs on this function. */
+bool
+ha_innobase::was_semi_consistent_read(void)
+/*=======================================*/
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ return(prebuilt->row_read_type == ROW_READ_DID_SEMI_CONSISTENT);
+}
+
+/* See handler.h and row0mysql.h for docs on this function. */
+void
+ha_innobase::try_semi_consistent_read(bool yes)
+/*===========================================*/
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+
+ /* Row read type is set to semi consistent read if this was
+ requested by the MySQL and either innodb_locks_unsafe_for_binlog
+ option is used or this session is using READ COMMITTED isolation
+ level. */
+
+ if (yes && (srv_locks_unsafe_for_binlog
+ || prebuilt->trx->isolation_level == TRX_ISO_READ_COMMITTED)) {
+ prebuilt->row_read_type = ROW_READ_TRY_SEMI_CONSISTENT;
+ } else {
+ prebuilt->row_read_type = ROW_READ_WITH_LOCKS;
+ }
}
/**********************************************************************
@@ -3623,14 +3823,15 @@ int
ha_innobase::index_init(
/*====================*/
/* out: 0 or error number */
- uint keynr) /* in: key (index) number */
+ uint keynr, /* in: key (index) number */
+ bool sorted) /* in: 1 if result MUST be sorted according to index */
{
- int error = 0;
- DBUG_ENTER("index_init");
+ int error = 0;
+ DBUG_ENTER("index_init");
error = change_active_index(keynr);
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/**********************************************************************
@@ -3640,10 +3841,10 @@ int
ha_innobase::index_end(void)
/*========================*/
{
- int error = 0;
- DBUG_ENTER("index_end");
- active_index=MAX_KEY;
- DBUG_RETURN(error);
+ int error = 0;
+ DBUG_ENTER("index_end");
+ active_index=MAX_KEY;
+ DBUG_RETURN(error);
}
/*************************************************************************
@@ -3656,15 +3857,15 @@ convert_search_mode_to_innobase(
enum ha_rkey_function find_flag)
{
switch (find_flag) {
- case HA_READ_KEY_EXACT: return(PAGE_CUR_GE);
- /* the above does not require the index to be UNIQUE */
- case HA_READ_KEY_OR_NEXT: return(PAGE_CUR_GE);
+ case HA_READ_KEY_EXACT: return(PAGE_CUR_GE);
+ /* the above does not require the index to be UNIQUE */
+ case HA_READ_KEY_OR_NEXT: return(PAGE_CUR_GE);
case HA_READ_KEY_OR_PREV: return(PAGE_CUR_LE);
case HA_READ_AFTER_KEY: return(PAGE_CUR_G);
case HA_READ_BEFORE_KEY: return(PAGE_CUR_L);
case HA_READ_PREFIX: return(PAGE_CUR_GE);
- case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE);
- case HA_READ_PREFIX_LAST_OR_PREV:return(PAGE_CUR_LE);
+ case HA_READ_PREFIX_LAST: return(PAGE_CUR_LE);
+ case HA_READ_PREFIX_LAST_OR_PREV:return(PAGE_CUR_LE);
/* In MySQL-4.0 HA_READ_PREFIX and HA_READ_PREFIX_LAST always
pass a complete-field prefix of a key value as the search
tuple. I.e., it is not allowed that the last field would
@@ -3745,7 +3946,7 @@ ha_innobase::index_read(
or error number */
mysql_byte* buf, /* in/out: buffer for the returned
row */
- const mysql_byte* key_ptr,/* in: key value; if this is NULL
+ const mysql_byte* key_ptr,/* in: key value; if this is NULL
we position the cursor at the
start or end of index; this can
also contain an InnoDB row id, in
@@ -3760,21 +3961,21 @@ ha_innobase::index_read(
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
ulint mode;
dict_index_t* index;
- ulint match_mode = 0;
- int error;
+ ulint match_mode = 0;
+ int error;
ulint ret;
- DBUG_ENTER("index_read");
+ DBUG_ENTER("index_read");
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
- statistic_increment(current_thd->status_var.ha_read_key_count,
- &LOCK_status);
+ statistic_increment(current_thd->status_var.ha_read_key_count,
+ &LOCK_status);
if (last_query_id != user_thd->query_id) {
- prebuilt->sql_stat_start = TRUE;
- last_query_id = user_thd->query_id;
+ prebuilt->sql_stat_start = TRUE;
+ last_query_id = user_thd->query_id;
innobase_release_stat_resources(prebuilt->trx);
}
@@ -3782,7 +3983,7 @@ ha_innobase::index_read(
index = prebuilt->index;
/* Note that if the index for which the search template is built is not
- necessarily prebuilt->index, but can also be the clustered index */
+ necessarily prebuilt->index, but can also be the clustered index */
if (prebuilt->sql_stat_start) {
build_template(prebuilt, user_thd, table,
@@ -3790,7 +3991,7 @@ ha_innobase::index_read(
}
if (key_ptr) {
- /* Convert the search key value to InnoDB format into
+ /* Convert the search key value to InnoDB format into
prebuilt->search_tuple */
row_sel_convert_mysql_key_to_innobase(prebuilt->search_tuple,
@@ -3803,7 +4004,7 @@ ha_innobase::index_read(
/* We position the cursor to the last or the first entry
in the index */
- dtuple_set_n_fields(prebuilt->search_tuple, 0);
+ dtuple_set_n_fields(prebuilt->search_tuple, 0);
}
mode = convert_search_mode_to_innobase(find_flag);
@@ -3852,15 +4053,15 @@ row with the current key value or prefix
int
ha_innobase::index_read_last(
/*=========================*/
- /* out: 0, HA_ERR_KEY_NOT_FOUND, or an
+ /* out: 0, HA_ERR_KEY_NOT_FOUND, or an
error code */
- mysql_byte* buf, /* out: fetched row */
- const mysql_byte* key_ptr, /* in: key value, or a prefix of a full
+ mysql_byte* buf, /* out: fetched row */
+ const mysql_byte* key_ptr, /* in: key value, or a prefix of a full
key value */
- uint key_len) /* in: length of the key val or prefix
+ uint key_len) /* in: length of the key val or prefix
in bytes */
{
- return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
+ return(index_read(buf, key_ptr, key_len, HA_READ_PREFIX_LAST));
}
/************************************************************************
@@ -3870,19 +4071,19 @@ int
ha_innobase::change_active_index(
/*=============================*/
/* out: 0 or error code */
- uint keynr) /* in: use this index; MAX_KEY means always clustered
+ uint keynr) /* in: use this index; MAX_KEY means always clustered
index, even if it was internally generated by
InnoDB */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
KEY* key=0;
statistic_increment(current_thd->status_var.ha_read_key_count,
- &LOCK_status);
+ &LOCK_status);
DBUG_ENTER("change_active_index");
ut_ad(user_thd == current_thd);
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
active_index = keynr;
@@ -3890,19 +4091,20 @@ ha_innobase::change_active_index(
key = table->key_info + active_index;
prebuilt->index = dict_table_get_index_noninline(
- prebuilt->table,
- key->name);
- } else {
+ prebuilt->table, key->name);
+ } else {
prebuilt->index = dict_table_get_first_index_noninline(
prebuilt->table);
}
if (!prebuilt->index) {
- sql_print_error("Innodb could not find key n:o %u with name %s "
- "from dict cache for table %s",
- keynr, key ? key->name : "NULL",
- prebuilt->table->name);
- DBUG_RETURN(1);
+ sql_print_error(
+ "Innodb could not find key n:o %u with name %s "
+ "from dict cache for table %s",
+ keynr, key ? key->name : "NULL",
+ prebuilt->table->name);
+
+ DBUG_RETURN(1);
}
assert(prebuilt->search_tuple != 0);
@@ -3934,7 +4136,7 @@ ha_innobase::index_read_idx(
/* out: error number or 0 */
mysql_byte* buf, /* in/out: buffer for the returned
row */
- uint keynr, /* in: use this index */
+ uint keynr, /* in: use this index */
const mysql_byte* key, /* in: key value; if this is NULL
we position the cursor at the
start or end of index */
@@ -3958,9 +4160,9 @@ ha_innobase::general_fetch(
/*=======================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
- mysql_byte* buf, /* in/out: buffer for next row in MySQL
+ mysql_byte* buf, /* in/out: buffer for next row in MySQL
format */
- uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
+ uint direction, /* in: ROW_SEL_NEXT or ROW_SEL_PREV */
uint match_mode) /* in: 0, ROW_SEL_EXACT, or
ROW_SEL_EXACT_PREFIX */
{
@@ -3970,8 +4172,8 @@ ha_innobase::general_fetch(
DBUG_ENTER("general_fetch");
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
innodb_srv_conc_enter_innodb(prebuilt->trx);
@@ -4007,11 +4209,11 @@ ha_innobase::index_next(
/*====================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
- mysql_byte* buf) /* in/out: buffer for next row in MySQL
+ mysql_byte* buf) /* in/out: buffer for next row in MySQL
format */
{
- statistic_increment(current_thd->status_var.ha_read_next_count,
- &LOCK_status);
+ statistic_increment(current_thd->status_var.ha_read_next_count,
+ &LOCK_status);
return(general_fetch(buf, ROW_SEL_NEXT, 0));
}
@@ -4024,12 +4226,12 @@ ha_innobase::index_next_same(
/*=========================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
- mysql_byte* buf, /* in/out: buffer for the row */
+ mysql_byte* buf, /* in/out: buffer for the row */
const mysql_byte* key, /* in: key value */
- uint keylen) /* in: key value length */
+ uint keylen) /* in: key value length */
{
- statistic_increment(current_thd->status_var.ha_read_next_count,
- &LOCK_status);
+ statistic_increment(current_thd->status_var.ha_read_next_count,
+ &LOCK_status);
return(general_fetch(buf, ROW_SEL_NEXT, last_match_mode));
}
@@ -4043,11 +4245,11 @@ ha_innobase::index_prev(
/*====================*/
/* out: 0, HA_ERR_END_OF_FILE, or error
number */
- mysql_byte* buf) /* in/out: buffer for previous row in MySQL
+ mysql_byte* buf) /* in/out: buffer for previous row in MySQL
format */
{
- statistic_increment(current_thd->status_var.ha_read_prev_count,
- &LOCK_status);
+ statistic_increment(current_thd->status_var.ha_read_prev_count,
+ &LOCK_status);
return(general_fetch(buf, ROW_SEL_PREV, 0));
}
@@ -4065,19 +4267,19 @@ ha_innobase::index_first(
{
int error;
- DBUG_ENTER("index_first");
- statistic_increment(current_thd->status_var.ha_read_first_count,
- &LOCK_status);
+ DBUG_ENTER("index_first");
+ statistic_increment(current_thd->status_var.ha_read_first_count,
+ &LOCK_status);
- error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
+ error = index_read(buf, NULL, 0, HA_READ_AFTER_KEY);
- /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
+ /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/************************************************************************
@@ -4092,19 +4294,19 @@ ha_innobase::index_last(
{
int error;
- DBUG_ENTER("index_last");
- statistic_increment(current_thd->status_var.ha_read_last_count,
- &LOCK_status);
+ DBUG_ENTER("index_last");
+ statistic_increment(current_thd->status_var.ha_read_last_count,
+ &LOCK_status);
- error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
+ error = index_read(buf, NULL, 0, HA_READ_BEFORE_KEY);
- /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
+ /* MySQL does not seem to allow this to return HA_ERR_KEY_NOT_FOUND */
- if (error == HA_ERR_KEY_NOT_FOUND) {
- error = HA_ERR_END_OF_FILE;
- }
+ if (error == HA_ERR_KEY_NOT_FOUND) {
+ error = HA_ERR_END_OF_FILE;
+ }
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/********************************************************************
@@ -4129,9 +4331,16 @@ ha_innobase::rnd_init(
err = change_active_index(primary_key);
}
- start_of_scan = 1;
+ /* Don't use semi-consistent read in random row reads (by position).
+ This means we must disable semi_consistent_read if scan is false */
+
+ if (!scan) {
+ try_semi_consistent_read(0);
+ }
+
+ start_of_scan = 1;
- return(err);
+ return(err);
}
/*********************************************************************
@@ -4158,11 +4367,11 @@ ha_innobase::rnd_next(
{
int error;
- DBUG_ENTER("rnd_next");
- statistic_increment(current_thd->status_var.ha_read_rnd_next_count,
- &LOCK_status);
+ DBUG_ENTER("rnd_next");
+ statistic_increment(current_thd->status_var.ha_read_rnd_next_count,
+ &LOCK_status);
- if (start_of_scan) {
+ if (start_of_scan) {
error = index_first(buf);
if (error == HA_ERR_KEY_NOT_FOUND) {
error = HA_ERR_END_OF_FILE;
@@ -4172,7 +4381,7 @@ ha_innobase::rnd_next(
error = general_fetch(buf, ROW_SEL_NEXT, 0);
}
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/**************************************************************************
@@ -4183,7 +4392,7 @@ ha_innobase::rnd_pos(
/*=================*/
/* out: 0, HA_ERR_KEY_NOT_FOUND,
or error code */
- mysql_byte* buf, /* in/out: buffer for the row */
+ mysql_byte* buf, /* in/out: buffer for the row */
mysql_byte* pos) /* in: primary key value of the row in the
MySQL format, or the row id if the clustered
index was internally generated by InnoDB;
@@ -4197,10 +4406,10 @@ ha_innobase::rnd_pos(
DBUG_DUMP("key", (char*) pos, ref_length);
statistic_increment(current_thd->status_var.ha_read_rnd_count,
- &LOCK_status);
+ &LOCK_status);
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we
@@ -4214,12 +4423,12 @@ ha_innobase::rnd_pos(
}
if (error) {
- DBUG_PRINT("error", ("Got error: %ld", error));
+ DBUG_PRINT("error", ("Got error: %ld", error));
DBUG_RETURN(error);
}
/* Note that we assume the length of the row reference is fixed
- for the table, and it is == ref_length */
+ for the table, and it is == ref_length */
error = index_read(buf, pos, ref_length, HA_READ_KEY_EXACT);
@@ -4229,7 +4438,7 @@ ha_innobase::rnd_pos(
change_active_index(keynr);
- DBUG_RETURN(error);
+ DBUG_RETURN(error);
}
/*************************************************************************
@@ -4249,8 +4458,8 @@ ha_innobase::position(
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
uint len;
- ut_ad(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
if (prebuilt->clust_index_was_generated) {
/* No primary key was defined for the table and we
@@ -4293,30 +4502,30 @@ create_table_def(
an .ibd file for it (no .ibd extension
in the path, though); otherwise this
is NULL */
- ibool comp) /* in: TRUE=compact record format */
+ ulint flags) /* in: table flags */
{
Field* field;
dict_table_t* table;
ulint n_cols;
- int error;
- ulint col_type;
+ int error;
+ ulint col_type;
ulint col_len;
- ulint nulls_allowed;
+ ulint nulls_allowed;
ulint unsigned_type;
ulint binary_type;
ulint long_true_varchar;
ulint charset_no;
- ulint i;
+ ulint i;
- DBUG_ENTER("create_table_def");
- DBUG_PRINT("enter", ("table_name: %s", table_name));
+ DBUG_ENTER("create_table_def");
+ DBUG_PRINT("enter", ("table_name: %s", table_name));
n_cols = form->s->fields;
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
- table = dict_mem_table_create(table_name, 0, n_cols, comp);
+ table = dict_mem_table_create(table_name, 0, n_cols, flags);
if (path_of_temp_table) {
table->dir_path_of_temp_table =
@@ -4371,15 +4580,14 @@ create_table_def(
}
dict_mem_table_add_col(table,
- (char*) field->field_name,
- col_type,
- dtype_form_prtype(
- (ulint)field->type()
- | nulls_allowed | unsigned_type
- | binary_type | long_true_varchar,
- charset_no),
- col_len,
- 0);
+ (char*) field->field_name,
+ col_type,
+ dtype_form_prtype(
+ (ulint)field->type()
+ | nulls_allowed | unsigned_type
+ | binary_type | long_true_varchar,
+ charset_no),
+ col_len);
}
error = row_create_table_for_mysql(table, trx);
@@ -4403,7 +4611,7 @@ create_index(
{
Field* field;
dict_index_t* index;
- int error;
+ int error;
ulint n_fields;
KEY* key;
KEY_PART_INFO* key_part;
@@ -4411,19 +4619,19 @@ create_index(
ulint col_type;
ulint prefix_len;
ulint is_unsigned;
- ulint i;
- ulint j;
+ ulint i;
+ ulint j;
ulint* field_lengths;
- DBUG_ENTER("create_index");
+ DBUG_ENTER("create_index");
key = form->key_info + key_num;
- n_fields = key->key_parts;
+ n_fields = key->key_parts;
- ind_type = 0;
+ ind_type = 0;
- if (key_num == form->s->primary_key) {
+ if (key_num == form->s->primary_key) {
ind_type = ind_type | DICT_CLUSTERED;
}
@@ -4469,39 +4677,36 @@ create_index(
&is_unsigned, key_part->field);
if (DATA_BLOB == col_type
- || (key_part->length < field->pack_length()
- && field->type() != MYSQL_TYPE_VARCHAR)
- || (field->type() == MYSQL_TYPE_VARCHAR
- && key_part->length < field->pack_length()
- - ((Field_varstring*)field)->length_bytes)) {
+ || (key_part->length < field->pack_length()
+ && field->type() != MYSQL_TYPE_VARCHAR)
+ || (field->type() == MYSQL_TYPE_VARCHAR
+ && key_part->length < field->pack_length()
+ - ((Field_varstring*)field)->length_bytes)) {
- prefix_len = key_part->length;
+ prefix_len = key_part->length;
if (col_type == DATA_INT
- || col_type == DATA_FLOAT
- || col_type == DATA_DOUBLE
- || col_type == DATA_DECIMAL) {
- sql_print_error("MySQL is trying to create a column "
- "prefix index field, on an "
- "inappropriate data type. Table "
- "name %s, column name %s.",
- table_name,
- key_part->field->field_name);
+ || col_type == DATA_FLOAT
+ || col_type == DATA_DOUBLE
+ || col_type == DATA_DECIMAL) {
+ sql_print_error(
+ "MySQL is trying to create a column "
+ "prefix index field, on an "
+ "inappropriate data type. Table "
+ "name %s, column name %s.",
+ table_name,
+ key_part->field->field_name);
- prefix_len = 0;
+ prefix_len = 0;
}
} else {
- prefix_len = 0;
+ prefix_len = 0;
}
field_lengths[i] = key_part->length;
- /* We assume all fields should be sorted in ascending
- order, hence the '0': */
-
dict_mem_index_add_field(index,
- (char*) key_part->field->field_name,
- 0, prefix_len);
+ (char*) key_part->field->field_name, prefix_len);
}
/* Even though we've defined max_supported_key_part_length, we
@@ -4527,14 +4732,13 @@ create_clustered_index_when_no_primary(
const char* table_name) /* in: table name */
{
dict_index_t* index;
- int error;
+ int error;
/* We pass 0 as the space id, and determine at a lower level the space
id where to store the table */
index = dict_mem_index_create((char*) table_name,
- (char*) "GEN_CLUST_INDEX",
- 0, DICT_CLUSTERED, 0);
+ (char*) "GEN_CLUST_INDEX", 0, DICT_CLUSTERED, 0);
error = row_create_index_for_mysql(index, trx, NULL);
error = convert_error_code_to_mysql(error, NULL);
@@ -4565,9 +4769,10 @@ ha_innobase::create(
char name2[FN_REFLEN];
char norm_name[FN_REFLEN];
THD *thd= current_thd;
- ib_longlong auto_inc_value;
+ ib_longlong auto_inc_value;
+ ulint flags;
- DBUG_ENTER("ha_innobase::create");
+ DBUG_ENTER("ha_innobase::create");
DBUG_ASSERT(thd != NULL);
@@ -4575,13 +4780,13 @@ ha_innobase::create(
/* The limit probably should be REC_MAX_N_FIELDS - 3 = 1020,
but we play safe here */
- DBUG_RETURN(HA_ERR_TO_BIG_ROW);
+ DBUG_RETURN(HA_ERR_TO_BIG_ROW);
}
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(current_thd);
+ parent_trx = check_trx_exists(thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -4607,7 +4812,7 @@ ha_innobase::create(
srv_lower_case_table_names = FALSE;
}
- fn_format(name2, name, "", "", 2); // Remove the .frm extension
+ strcpy(name2, name);
normalize_table_name(norm_name, name2);
@@ -4619,18 +4824,24 @@ ha_innobase::create(
/* Create the table definition in InnoDB */
+ flags = 0;
+
+ if (form->s->row_type != ROW_TYPE_REDUNDANT) {
+ flags |= DICT_TF_COMPACT;
+ }
+
error = create_table_def(trx, form, norm_name,
create_info->options & HA_LEX_CREATE_TMP_TABLE ? name2 : NULL,
- form->s->row_type != ROW_TYPE_REDUNDANT);
+ flags);
- if (error) {
+ if (error) {
goto cleanup;
- }
+ }
/* Look for a primary key */
- primary_key_no= (table->s->primary_key != MAX_KEY ?
- (int) table->s->primary_key :
+ primary_key_no= (form->s->primary_key != MAX_KEY ?
+ (int) form->s->primary_key :
-1);
/* Our function row_get_mysql_key_number_for_index assumes
@@ -4647,44 +4858,33 @@ ha_innobase::create(
error = create_clustered_index_when_no_primary(trx,
norm_name);
- if (error) {
+ if (error) {
goto cleanup;
- }
+ }
}
if (primary_key_no != -1) {
/* In InnoDB the clustered index must always be created
first */
- if ((error = create_index(trx, form, norm_name,
+ if ((error = create_index(trx, form, norm_name,
(uint) primary_key_no))) {
goto cleanup;
- }
- }
+ }
+ }
for (i = 0; i < form->s->keys; i++) {
if (i != (uint) primary_key_no) {
- if ((error = create_index(trx, form, norm_name, i))) {
+ if ((error = create_index(trx, form, norm_name, i))) {
goto cleanup;
- }
- }
- }
-
- if (current_thd->query != NULL) {
- LEX_STRING q;
-
- if (thd->convert_string(&q, system_charset_info,
- current_thd->query,
- current_thd->query_length,
- current_thd->charset())) {
- error = HA_ERR_OUT_OF_MEM;
-
- goto cleanup;
+ }
}
+ }
+ if (thd->query != NULL) {
error = row_table_add_foreign_constraints(trx,
- q.str, norm_name,
+ thd->query, norm_name,
create_info->options & HA_LEX_CREATE_TMP_TABLE);
error = convert_error_code_to_mysql(error, NULL);
@@ -4694,7 +4894,7 @@ ha_innobase::create(
}
}
- innobase_commit_low(trx);
+ innobase_commit_low(trx);
row_mysql_unlock_data_dictionary(trx);
@@ -4704,7 +4904,7 @@ ha_innobase::create(
log_buffer_flush_to_disk();
- innobase_table = dict_table_get(norm_name, NULL);
+ innobase_table = dict_table_get(norm_name);
DBUG_ASSERT(innobase_table != 0);
@@ -4727,7 +4927,7 @@ ha_innobase::create(
srv_active_wake_master_thread();
- trx_free_for_mysql(trx);
+ trx_free_for_mysql(trx);
DBUG_RETURN(0);
@@ -4755,11 +4955,11 @@ ha_innobase::discard_or_import_tablespac
trx_t* trx;
int err;
- DBUG_ENTER("ha_innobase::discard_or_import_tablespace");
+ DBUG_ENTER("ha_innobase::discard_or_import_tablespace");
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
dict_table = prebuilt->table;
trx = prebuilt->trx;
@@ -4785,7 +4985,6 @@ ha_innobase::delete_all_rows(void)
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
int error;
- trx_t* trx;
THD* thd = current_thd;
DBUG_ENTER("ha_innobase::delete_all_rows");
@@ -4798,13 +4997,13 @@ ha_innobase::delete_all_rows(void)
}
/* Get the transaction associated with the current thd, or create one
- if not yet created */
+ if not yet created, and update prebuilt->trx */
- trx = check_trx_exists(thd);
+ update_thd(thd);
/* Truncate the table in InnoDB */
- error = row_truncate_table_for_mysql(prebuilt->table, trx);
+ error = row_truncate_table_for_mysql(prebuilt->table, prebuilt->trx);
if (error == DB_ERROR) {
/* Cannot truncate; resort to ha_innobase::delete_row() */
goto fallback;
@@ -4832,15 +5031,15 @@ ha_innobase::delete_table(
int error;
trx_t* parent_trx;
trx_t* trx;
- THD *thd= current_thd;
+ THD *thd= current_thd;
char norm_name[1000];
- DBUG_ENTER("ha_innobase::delete_table");
+ DBUG_ENTER("ha_innobase::delete_table");
/* Get the transaction associated with the current thd, or create one
if not yet created */
- parent_trx = check_trx_exists(current_thd);
+ parent_trx = check_trx_exists(thd);
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -4875,7 +5074,7 @@ ha_innobase::delete_table(
normalize_table_name(norm_name, name);
- /* Drop the table in InnoDB */
+ /* Drop the table in InnoDB */
error = row_drop_table_for_mysql(norm_name, trx,
thd->lex->sql_command == SQLCOM_DROP_DB);
@@ -4891,9 +5090,9 @@ ha_innobase::delete_table(
srv_active_wake_master_thread();
- innobase_commit_low(trx);
+ innobase_commit_low(trx);
- trx_free_for_mysql(trx);
+ trx_free_for_mysql(trx);
error = convert_error_code_to_mysql(error, NULL);
@@ -4903,7 +5102,7 @@ ha_innobase::delete_table(
/*********************************************************************
Removes all tables in the named database inside InnoDB. */
-int
+void
innobase_drop_database(
/*===================*/
/* out: error number */
@@ -4942,7 +5141,7 @@ innobase_drop_database(
memcpy(namebuf, ptr, len);
namebuf[len] = '/';
namebuf[len + 1] = '\0';
-#ifdef __WIN__
+#ifdef __WIN__
innobase_casedn_str(namebuf);
#endif
trx = trx_allocate_for_mysql();
@@ -4953,7 +5152,7 @@ innobase_drop_database(
trx->check_foreigns = FALSE;
}
- error = row_drop_database_for_mysql(namebuf, trx);
+ error = row_drop_database_for_mysql(namebuf, trx);
my_free(namebuf, MYF(0));
/* Flush the log to reduce probability that the .frm files and
@@ -4967,12 +5166,15 @@ innobase_drop_database(
srv_active_wake_master_thread();
- innobase_commit_low(trx);
- trx_free_for_mysql(trx);
-
+ innobase_commit_low(trx);
+ trx_free_for_mysql(trx);
+#ifdef NO_LONGER_INTERESTED_IN_DROP_DB_ERROR
error = convert_error_code_to_mysql(error, NULL);
return(error);
+#else
+ return;
+#endif
}
/*************************************************************************
@@ -4993,7 +5195,7 @@ ha_innobase::rename_table(
char norm_from[1000];
char norm_to[1000];
- DBUG_ENTER("ha_innobase::rename_table");
+ DBUG_ENTER("ha_innobase::rename_table");
/* Get the transaction associated with the current thd, or create one
if not yet created */
@@ -5028,9 +5230,9 @@ ha_innobase::rename_table(
normalize_table_name(norm_from, from);
normalize_table_name(norm_to, to);
- /* Rename the table in InnoDB */
+ /* Rename the table in InnoDB */
- error = row_rename_table_for_mysql(norm_from, norm_to, trx);
+ error = row_rename_table_for_mysql(norm_from, norm_to, trx);
/* Flush the log to reduce probability that the .frm files and
the InnoDB data dictionary get out-of-sync if the user runs
@@ -5043,8 +5245,8 @@ ha_innobase::rename_table(
srv_active_wake_master_thread();
- innobase_commit_low(trx);
- trx_free_for_mysql(trx);
+ innobase_commit_low(trx);
+ trx_free_for_mysql(trx);
error = convert_error_code_to_mysql(error, NULL);
@@ -5059,30 +5261,33 @@ ha_innobase::records_in_range(
/*==========================*/
/* out: estimated number of
rows */
- uint keynr, /* in: index number */
- key_range *min_key, /* in: start key value of the
- range, may also be 0 */
+ uint keynr, /* in: index number */
+ key_range *min_key, /* in: start key value of the
+ range, may also be 0 */
key_range *max_key) /* in: range end key val, may
- also be 0 */
+ also be 0 */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
KEY* key;
dict_index_t* index;
- mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
+ mysql_byte* key_val_buff2 = (mysql_byte*) my_malloc(
table->s->reclength
- + table->s->max_key_length + 100,
+ + table->s->max_key_length + 100,
MYF(MY_FAE));
ulint buff2_len = table->s->reclength
- + table->s->max_key_length + 100;
+ + table->s->max_key_length + 100;
dtuple_t* range_start;
dtuple_t* range_end;
ib_longlong n_rows;
ulint mode1;
ulint mode2;
- void* heap1;
- void* heap2;
+ void* heap1;
+ void* heap2;
+
+ DBUG_ENTER("records_in_range");
- DBUG_ENTER("records_in_range");
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
prebuilt->trx->op_info = (char*)"estimating records in index range";
@@ -5098,17 +5303,17 @@ ha_innobase::records_in_range(
index = dict_table_get_index_noninline(prebuilt->table, key->name);
range_start = dtuple_create_for_mysql(&heap1, key->key_parts);
- dict_index_copy_types(range_start, index, key->key_parts);
+ dict_index_copy_types(range_start, index, key->key_parts);
range_end = dtuple_create_for_mysql(&heap2, key->key_parts);
- dict_index_copy_types(range_end, index, key->key_parts);
+ dict_index_copy_types(range_end, index, key->key_parts);
row_sel_convert_mysql_key_to_innobase(
range_start, (byte*) key_val_buff,
(ulint)upd_and_key_val_buff_len,
index,
(byte*) (min_key ? min_key->key :
- (const mysql_byte*) 0),
+ (const mysql_byte*) 0),
(ulint) (min_key ? min_key->length : 0),
prebuilt->trx);
@@ -5116,21 +5321,21 @@ ha_innobase::records_in_range(
range_end, (byte*) key_val_buff2,
buff2_len, index,
(byte*) (max_key ? max_key->key :
- (const mysql_byte*) 0),
+ (const mysql_byte*) 0),
(ulint) (max_key ? max_key->length : 0),
prebuilt->trx);
mode1 = convert_search_mode_to_innobase(min_key ? min_key->flag :
- HA_READ_KEY_EXACT);
+ HA_READ_KEY_EXACT);
mode2 = convert_search_mode_to_innobase(max_key ? max_key->flag :
- HA_READ_KEY_EXACT);
+ HA_READ_KEY_EXACT);
n_rows = btr_estimate_n_rows_in_range(index, range_start,
mode1, range_end, mode2);
dtuple_free_for_mysql(heap1);
dtuple_free_for_mysql(heap2);
- my_free((gptr) key_val_buff2, MYF(0));
+ my_free((gptr) key_val_buff2, MYF(0));
prebuilt->trx->op_info = (char*)"";
@@ -5141,7 +5346,7 @@ ha_innobase::records_in_range(
Add 1 to the value to make sure MySQL does not make the assumption! */
if (n_rows == 0) {
- n_rows = 1;
+ n_rows = 1;
}
DBUG_RETURN((ha_rows) n_rows);
@@ -5161,7 +5366,7 @@ ha_innobase::estimate_rows_upper_bound(v
ulonglong estimate;
ulonglong local_data_file_length;
- DBUG_ENTER("estimate_rows_upper_bound");
+ DBUG_ENTER("estimate_rows_upper_bound");
/* We do not know if MySQL can call this function before calling
external_lock(). To be safe, update the thd of the current table
@@ -5170,7 +5375,7 @@ ha_innobase::estimate_rows_upper_bound(v
update_thd(current_thd);
prebuilt->trx->op_info = (char*)
- "calculating upper bound for table rows";
+ "calculating upper bound for table rows";
/* In case MySQL calls this in the middle of a SELECT query, release
possible adaptive hash latch to avoid deadlocks of threads */
@@ -5180,7 +5385,7 @@ ha_innobase::estimate_rows_upper_bound(v
index = dict_table_get_first_index_noninline(prebuilt->table);
local_data_file_length = ((ulonglong) index->stat_n_leaf_pages)
- * UNIV_PAGE_SIZE;
+ * UNIV_PAGE_SIZE;
/* Calculate a minimum length for a clustered index record and from
that an upper bound for the number of rows. Since we only calculate
@@ -5223,16 +5428,16 @@ double
ha_innobase::read_time(
/*===================*/
/* out: estimated time measured in disk seeks */
- uint index, /* in: key number */
+ uint index, /* in: key number */
uint ranges, /* in: how many ranges */
ha_rows rows) /* in: estimated number of rows in the ranges */
{
ha_rows total_rows;
- double time_for_scan;
+ double time_for_scan;
if (index != table->s->primary_key) {
/* Not clustered */
- return(handler::read_time(index, ranges, rows));
+ return(handler::read_time(index, ranges, rows));
}
if (rows <= 2) {
@@ -5247,7 +5452,7 @@ ha_innobase::read_time(
if ((total_rows = estimate_rows_upper_bound()) < rows) {
- return(time_for_scan);
+ return(time_for_scan);
}
return(ranges + (double) rows / (double) total_rows * time_for_scan);
@@ -5270,18 +5475,18 @@ ha_innobase::info(
ulong j;
ulong i;
char path[FN_REFLEN];
- os_file_stat_t stat_info;
+ os_file_stat_t stat_info;
- DBUG_ENTER("info");
+ DBUG_ENTER("info");
- /* If we are forcing recovery at a high level, we will suppress
+ /* If we are forcing recovery at a high level, we will suppress
statistics calculation on tables, because that may crash the
server if an index is badly corrupted. */
- if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
- DBUG_VOID_RETURN;
- }
+ DBUG_VOID_RETURN;
+ }
/* We do not know if MySQL can call this function before calling
external_lock(). To be safe, update the thd of the current table
@@ -5296,28 +5501,26 @@ ha_innobase::info(
trx_search_latch_release_if_reserved(prebuilt->trx);
- ib_table = prebuilt->table;
+ ib_table = prebuilt->table;
- if (flag & HA_STATUS_TIME) {
- /* In sql_show we call with this flag: update then statistics
- so that they are up-to-date */
+ if (flag & HA_STATUS_TIME) {
+ /* In sql_show we call with this flag: update then statistics
+ so that they are up-to-date */
- prebuilt->trx->op_info = (char*)"updating table statistics";
+ prebuilt->trx->op_info = (char*)"updating table statistics";
- dict_update_statistics(ib_table);
+ dict_update_statistics(ib_table);
prebuilt->trx->op_info = (char*)
- "returning various info to MySQL";
+ "returning various info to MySQL";
if (ib_table->space != 0) {
my_snprintf(path, sizeof(path), "%s/%s%s",
- mysql_data_home, ib_table->name,
- ".ibd");
+ mysql_data_home, ib_table->name, ".ibd");
unpack_filename(path,path);
} else {
my_snprintf(path, sizeof(path), "%s/%s%s",
- mysql_data_home, ib_table->name,
- reg_ext);
+ mysql_data_home, ib_table->name, reg_ext);
unpack_filename(path,path);
}
@@ -5326,9 +5529,9 @@ ha_innobase::info(
nor the CHECK TABLE time, nor the UPDATE or INSERT time. */
if (os_file_get_status(path,&stat_info)) {
- create_time = stat_info.ctime;
+ stats.create_time = stat_info.ctime;
}
- }
+ }
if (flag & HA_STATUS_VARIABLE) {
n_rows = ib_table->stat_n_rows;
@@ -5354,23 +5557,23 @@ ha_innobase::info(
n_rows++;
}
- records = (ha_rows)n_rows;
- deleted = 0;
- data_file_length = ((ulonglong)
+ stats.records = (ha_rows)n_rows;
+ stats.deleted = 0;
+ stats.data_file_length = ((ulonglong)
ib_table->stat_clustered_index_size)
- * UNIV_PAGE_SIZE;
- index_file_length = ((ulonglong)
+ * UNIV_PAGE_SIZE;
+ stats.index_file_length = ((ulonglong)
ib_table->stat_sum_of_other_index_sizes)
- * UNIV_PAGE_SIZE;
- delete_length = 0;
- check_time = 0;
-
- if (records == 0) {
- mean_rec_length = 0;
- } else {
- mean_rec_length = (ulong) (data_file_length / records);
- }
- }
+ * UNIV_PAGE_SIZE;
+ stats.delete_length = 0;
+ stats.check_time = 0;
+
+ if (stats.records == 0) {
+ stats.mean_rec_length = 0;
+ } else {
+ stats.mean_rec_length = (ulong) (stats.data_file_length / stats.records);
+ }
+ }
if (flag & HA_STATUS_CONST) {
index = dict_table_get_first_index_noninline(ib_table);
@@ -5388,7 +5591,7 @@ ha_innobase::info(
".frm file. Have you mixed up "
".frm files from different "
"installations? See "
-"http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n",
+"http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
ib_table->name);
break;
@@ -5397,25 +5600,25 @@ ha_innobase::info(
for (j = 0; j < table->key_info[i].key_parts; j++) {
if (j + 1 > index->n_uniq) {
- ut_print_timestamp(stderr);
+ ut_print_timestamp(stderr);
sql_print_error(
"Index %s of %s has %lu columns unique inside InnoDB, but MySQL is asking "
"statistics for %lu columns. Have you mixed up .frm files from different "
"installations? "
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n",
+"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n",
index->name,
ib_table->name,
(unsigned long)
index->n_uniq, j + 1);
- break;
+ break;
}
if (index->stat_n_diff_key_vals[j + 1] == 0) {
- rec_per_key = records;
+ rec_per_key = stats.records;
} else {
- rec_per_key = (ha_rows)(records /
- index->stat_n_diff_key_vals[j + 1]);
+ rec_per_key = (ha_rows)(stats.records /
+ index->stat_n_diff_key_vals[j + 1]);
}
/* Since MySQL seems to favor table scans
@@ -5429,7 +5632,7 @@ ha_innobase::info(
rec_per_key = 1;
}
- table->key_info[i].rec_per_key[j]=
+ table->key_info[i].rec_per_key[j]=
rec_per_key >= ~(ulong) 0 ? ~(ulong) 0 :
rec_per_key;
}
@@ -5438,13 +5641,12 @@ ha_innobase::info(
}
}
- if (flag & HA_STATUS_ERRKEY) {
+ if (flag & HA_STATUS_ERRKEY) {
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
errkey = (unsigned int) row_get_mysql_key_number_for_index(
- (dict_index_t*)
- trx_get_error_info(prebuilt->trx));
- }
+ (dict_index_t*) trx_get_error_info(prebuilt->trx));
+ }
if (flag & HA_STATUS_AUTO && table->found_next_number_field) {
longlong auto_inc;
@@ -5470,12 +5672,12 @@ ha_innobase::info(
}
}
- auto_increment_value = auto_inc;
+ stats.auto_increment_value = auto_inc;
}
prebuilt->trx->op_info = (char*)"";
- DBUG_VOID_RETURN;
+ DBUG_VOID_RETURN;
}
/**************************************************************************
@@ -5496,7 +5698,7 @@ ha_innobase::analyze(
}
/**************************************************************************
-This is mapped to "ALTER TABLE tablename TYPE=InnoDB", which rebuilds
+This is mapped to "ALTER TABLE tablename ENGINE=InnoDB", which rebuilds
the table in MySQL. */
int
@@ -5505,7 +5707,7 @@ ha_innobase::optimize(
THD* thd, /* in: connection thread handle */
HA_CHECK_OPT* check_opt) /* in: currently ignored */
{
- return(HA_ADMIN_TRY_ALTER);
+ return(HA_ADMIN_TRY_ALTER);
}
/***********************************************************************
@@ -5518,8 +5720,8 @@ ha_innobase::check(
/*===============*/
/* out: HA_ADMIN_CORRUPT or
HA_ADMIN_OK */
- THD* thd, /* in: user thread handle */
- HA_CHECK_OPT* check_opt) /* in: check options, currently
+ THD* thd, /* in: user thread handle */
+ HA_CHECK_OPT* check_opt) /* in: check options, currently
ignored */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
@@ -5527,7 +5729,7 @@ ha_innobase::check(
ut_a(prebuilt->trx && prebuilt->trx->magic_n == TRX_MAGIC_N);
ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
if (prebuilt->mysql_template == NULL) {
/* Build the template; we will use a dummy template
@@ -5542,7 +5744,7 @@ ha_innobase::check(
return(HA_ADMIN_OK);
}
- return(HA_ADMIN_CORRUPT);
+ return(HA_ADMIN_CORRUPT);
}
/*****************************************************************
@@ -5555,7 +5757,7 @@ ha_innobase::update_table_comment(
/*==============================*/
/* out: table comment + InnoDB free space +
info on foreign keys */
- const char* comment)/* in: table comment defined by user */
+ const char* comment)/* in: table comment defined by user */
{
uint length = (uint) strlen(comment);
char* str;
@@ -5586,8 +5788,8 @@ ha_innobase::update_table_comment(
rewind(srv_dict_tmpfile);
fprintf(srv_dict_tmpfile, "InnoDB free: %lu kB",
- (ulong) fsp_get_available_space_in_free_extents(
- prebuilt->table->space));
+ (ulong) fsp_get_available_space_in_free_extents(
+ prebuilt->table->space));
dict_print_info_on_foreign_keys(FALSE, srv_dict_tmpfile,
prebuilt->trx, prebuilt->table);
@@ -5617,9 +5819,9 @@ ha_innobase::update_table_comment(
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
- prebuilt->trx->op_info = (char*)"";
+ prebuilt->trx->op_info = (char*)"";
- return(str ? str : (char*) comment);
+ return(str ? str : (char*) comment);
}
/***********************************************************************
@@ -5680,7 +5882,7 @@ ha_innobase::get_foreign_key_create_info
mutex_exit_noninline(&srv_dict_tmpfile_mutex);
- return(str);
+ return(str);
}
@@ -5698,85 +5900,101 @@ ha_innobase::get_foreign_key_list(THD *t
mutex_enter_noninline(&(dict_sys->mutex));
foreign = UT_LIST_GET_FIRST(prebuilt->table->foreign_list);
- while (foreign != NULL)
- {
- uint i;
- FOREIGN_KEY_INFO f_key_info;
- LEX_STRING *name= 0;
- const char *tmp_buff;
-
- tmp_buff= foreign->id;
- i= 0;
- while (tmp_buff[i] != '/')
- i++;
- tmp_buff+= i + 1;
- f_key_info.forein_id= make_lex_string(thd, 0, tmp_buff,
- (uint) strlen(tmp_buff), 1);
- tmp_buff= foreign->referenced_table_name;
- i= 0;
- while (tmp_buff[i] != '/')
- i++;
- f_key_info.referenced_db= make_lex_string(thd, 0,
- tmp_buff, i, 1);
- tmp_buff+= i + 1;
- f_key_info.referenced_table= make_lex_string(thd, 0, tmp_buff,
- (uint) strlen(tmp_buff), 1);
-
- for (i= 0;;)
- {
- tmp_buff= foreign->foreign_col_names[i];
- name= make_lex_string(thd, name, tmp_buff, (uint) strlen(tmp_buff), 1);
- f_key_info.foreign_fields.push_back(name);
- tmp_buff= foreign->referenced_col_names[i];
- name= make_lex_string(thd, name, tmp_buff, (uint) strlen(tmp_buff), 1);
- f_key_info.referenced_fields.push_back(name);
- if (++i >= foreign->n_fields)
- break;
- }
-
- ulong length= 0;
- if (foreign->type == DICT_FOREIGN_ON_DELETE_CASCADE)
- {
- length=17;
- tmp_buff= "ON DELETE CASCADE";
- }
- else if (foreign->type == DICT_FOREIGN_ON_DELETE_SET_NULL)
- {
- length=18;
- tmp_buff= "ON DELETE SET NULL";
- }
- else if (foreign->type == DICT_FOREIGN_ON_DELETE_NO_ACTION)
- {
- length=19;
- tmp_buff= "ON DELETE NO ACTION";
- }
- else if (foreign->type == DICT_FOREIGN_ON_UPDATE_CASCADE)
- {
- length=17;
- tmp_buff= "ON UPDATE CASCADE";
- }
- else if (foreign->type == DICT_FOREIGN_ON_UPDATE_SET_NULL)
- {
- length=18;
- tmp_buff= "ON UPDATE SET NULL";
- }
- else if (foreign->type == DICT_FOREIGN_ON_UPDATE_NO_ACTION)
- {
- length=19;
- tmp_buff= "ON UPDATE NO ACTION";
- }
- f_key_info.constraint_method= make_lex_string(thd,
- f_key_info.constraint_method,
- tmp_buff, length, 1);
-
- FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *)
- thd->memdup((gptr) &f_key_info,
- sizeof(FOREIGN_KEY_INFO)));
- f_key_list->push_back(pf_key_info);
- foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
+ while (foreign != NULL) {
+ uint i;
+ FOREIGN_KEY_INFO f_key_info;
+ LEX_STRING *name= 0;
+ const char *tmp_buff;
+
+ tmp_buff= foreign->id;
+ i= 0;
+ while (tmp_buff[i] != '/')
+ i++;
+ tmp_buff+= i + 1;
+ f_key_info.forein_id= make_lex_string(thd, 0, tmp_buff,
+ (uint) strlen(tmp_buff), 1);
+ tmp_buff= foreign->referenced_table_name;
+ i= 0;
+ while (tmp_buff[i] != '/')
+ i++;
+ f_key_info.referenced_db= make_lex_string(thd, 0,
+ tmp_buff, i, 1);
+ tmp_buff+= i + 1;
+ f_key_info.referenced_table= make_lex_string(thd, 0, tmp_buff,
+ (uint) strlen(tmp_buff), 1);
+
+ for (i= 0;;) {
+ tmp_buff= foreign->foreign_col_names[i];
+ name= make_lex_string(thd, name, tmp_buff,
+ (uint) strlen(tmp_buff), 1);
+ f_key_info.foreign_fields.push_back(name);
+ tmp_buff= foreign->referenced_col_names[i];
+ name= make_lex_string(thd, name, tmp_buff,
+ (uint) strlen(tmp_buff), 1);
+ f_key_info.referenced_fields.push_back(name);
+ if (++i >= foreign->n_fields)
+ break;
+ }
+
+ ulong length;
+ if (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)
+ {
+ length=7;
+ tmp_buff= "CASCADE";
+ }
+ else if (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL)
+ {
+ length=8;
+ tmp_buff= "SET NULL";
+ }
+ else if (foreign->type & DICT_FOREIGN_ON_DELETE_NO_ACTION)
+ {
+ length=9;
+ tmp_buff= "NO ACTION";
+ }
+ else
+ {
+ length=8;
+ tmp_buff= "RESTRICT";
+ }
+ f_key_info.delete_method= make_lex_string(thd, f_key_info.delete_method,
+ tmp_buff, length, 1);
+
+
+ if (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)
+ {
+ length=7;
+ tmp_buff= "CASCADE";
+ }
+ else if (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)
+ {
+ length=8;
+ tmp_buff= "SET NULL";
+ }
+ else if (foreign->type & DICT_FOREIGN_ON_UPDATE_NO_ACTION)
+ {
+ length=9;
+ tmp_buff= "NO ACTION";
+ }
+ else
+ {
+ length=8;
+ tmp_buff= "RESTRICT";
+ }
+ f_key_info.update_method= make_lex_string(thd, f_key_info.update_method,
+ tmp_buff, length, 1);
+
+
+
+ FOREIGN_KEY_INFO *pf_key_info= ((FOREIGN_KEY_INFO *)
+ thd->memdup((gptr) &f_key_info,
+ sizeof(FOREIGN_KEY_INFO)));
+ f_key_list->push_back(pf_key_info);
+ foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
mutex_exit_noninline(&(dict_sys->mutex));
prebuilt->trx->op_info = (char*)"";
+
DBUG_RETURN(0);
}
@@ -5792,7 +6010,11 @@ ha_innobase::can_switch_engines(void)
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
bool can_switch;
- DBUG_ENTER("ha_innobase::can_switch_engines");
+ DBUG_ENTER("ha_innobase::can_switch_engines");
+
+ ut_a(prebuilt->trx ==
+ (trx_t*) current_thd->ha_data[innobase_hton->slot]);
+
prebuilt->trx->op_info =
"determining if there are foreign key constraints";
row_mysql_lock_data_dictionary(prebuilt->trx);
@@ -5834,7 +6056,7 @@ non-NULL. */
void
ha_innobase::free_foreign_key_create_info(
/*======================================*/
- char* str) /* in, own: create info string to free */
+ char* str) /* in, own: create info string to free */
{
if (str) {
my_free(str, MYF(0));
@@ -5849,8 +6071,7 @@ ha_innobase::extra(
/*===============*/
/* out: 0 or error number */
enum ha_extra_function operation)
- /* in: HA_EXTRA_RETRIEVE_ALL_COLS or some
- other flag */
+ /* in: HA_EXTRA_FLUSH or some other flag */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
@@ -5859,38 +6080,21 @@ ha_innobase::extra(
obsolete! */
switch (operation) {
- case HA_EXTRA_FLUSH:
- if (prebuilt->blob_heap) {
- row_mysql_prebuilt_free_blob_heap(prebuilt);
- }
- break;
- case HA_EXTRA_RESET:
- if (prebuilt->blob_heap) {
- row_mysql_prebuilt_free_blob_heap(prebuilt);
- }
- prebuilt->keep_other_fields_on_keyread = 0;
- prebuilt->read_just_key = 0;
- break;
- case HA_EXTRA_RESET_STATE:
- prebuilt->keep_other_fields_on_keyread = 0;
- prebuilt->read_just_key = 0;
- break;
+ case HA_EXTRA_FLUSH:
+ if (prebuilt->blob_heap) {
+ row_mysql_prebuilt_free_blob_heap(prebuilt);
+ }
+ break;
+ case HA_EXTRA_RESET_STATE:
+ prebuilt->keep_other_fields_on_keyread = 0;
+ prebuilt->read_just_key = 0;
+ break;
case HA_EXTRA_NO_KEYREAD:
- prebuilt->read_just_key = 0;
- break;
- case HA_EXTRA_RETRIEVE_ALL_COLS:
- prebuilt->hint_need_to_fetch_extra_cols
- = ROW_RETRIEVE_ALL_COLS;
+ prebuilt->read_just_key = 0;
break;
- case HA_EXTRA_RETRIEVE_PRIMARY_KEY:
- if (prebuilt->hint_need_to_fetch_extra_cols == 0) {
- prebuilt->hint_need_to_fetch_extra_cols
- = ROW_RETRIEVE_PRIMARY_KEY;
- }
+ case HA_EXTRA_KEYREAD:
+ prebuilt->read_just_key = 1;
break;
- case HA_EXTRA_KEYREAD:
- prebuilt->read_just_key = 1;
- break;
case HA_EXTRA_KEYREAD_PRESERVE_FIELDS:
prebuilt->keep_other_fields_on_keyread = 1;
break;
@@ -5901,6 +6105,18 @@ ha_innobase::extra(
return(0);
}
+int ha_innobase::reset()
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ if (prebuilt->blob_heap) {
+ row_mysql_prebuilt_free_blob_heap(prebuilt);
+ }
+ prebuilt->keep_other_fields_on_keyread = 0;
+ prebuilt->read_just_key = 0;
+ return 0;
+}
+
+
/**********************************************************************
MySQL calls this function at the start of each SQL statement inside LOCK
TABLES. Inside LOCK TABLES the ::external_lock method does not work to
@@ -5916,9 +6132,9 @@ procedure. */
int
ha_innobase::start_stmt(
/*====================*/
- /* out: 0 or error code */
- THD* thd, /* in: handle to the user thread */
- thr_lock_type lock_type)
+ /* out: 0 or error code */
+ THD* thd, /* in: handle to the user thread */
+ thr_lock_type lock_type)
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx;
@@ -5939,19 +6155,19 @@ ha_innobase::start_stmt(
prebuilt->sql_stat_start = TRUE;
prebuilt->hint_need_to_fetch_extra_cols = 0;
prebuilt->read_just_key = 0;
- prebuilt->keep_other_fields_on_keyread = FALSE;
+ prebuilt->keep_other_fields_on_keyread = FALSE;
if (!prebuilt->mysql_has_locked) {
- /* This handle is for a temporary table created inside
- this same LOCK TABLES; since MySQL does NOT call external_lock
- in this case, we must use x-row locks inside InnoDB to be
- prepared for an update of a row */
+ /* This handle is for a temporary table created inside
+ this same LOCK TABLES; since MySQL does NOT call external_lock
+ in this case, we must use x-row locks inside InnoDB to be
+ prepared for an update of a row */
- prebuilt->select_lock_type = LOCK_X;
+ prebuilt->select_lock_type = LOCK_X;
} else {
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
- && thd->lex->sql_command == SQLCOM_SELECT
- && lock_type == TL_READ) {
+ && thd->lex->sql_command == SQLCOM_SELECT
+ && lock_type == TL_READ) {
/* For other than temporary tables, we obtain
no lock for consistent read (plain SELECT). */
@@ -5964,7 +6180,7 @@ ha_innobase::start_stmt(
1) ::store_lock(),
2) ::external_lock(),
3) ::init_table_handle_for_HANDLER(), and
- 4) :.transactional_table_lock(). */
+ 4) ::transactional_table_lock(). */
prebuilt->select_lock_type =
prebuilt->stored_select_lock_type;
@@ -5974,11 +6190,11 @@ ha_innobase::start_stmt(
trx->detailed_error[0] = '\0';
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
- trx->active_trans = 1;
- } else {
+ innobase_register_trx_and_stmt(thd);
+ trx->active_trans = 1;
+ } else {
innobase_register_stmt(thd);
}
@@ -6015,14 +6231,14 @@ the SQL statement in case of an error. *
int
ha_innobase::external_lock(
/*=======================*/
- /* out: 0 */
+ /* out: 0 */
THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
+ int lock_type) /* in: lock type */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx;
- DBUG_ENTER("ha_innobase::external_lock");
+ DBUG_ENTER("ha_innobase::external_lock");
DBUG_PRINT("enter",("lock_type: %d", lock_type));
update_thd(thd);
@@ -6050,26 +6266,20 @@ ha_innobase::external_lock(
/* Set the MySQL flag to mark that there is an active
transaction */
- if (trx->active_trans == 0) {
+ if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
- trx->active_trans = 1;
- } else if (trx->n_mysql_tables_in_use == 0) {
+ innobase_register_trx_and_stmt(thd);
+ trx->active_trans = 1;
+ } else if (trx->n_mysql_tables_in_use == 0) {
innobase_register_stmt(thd);
}
trx->n_mysql_tables_in_use++;
prebuilt->mysql_has_locked = TRUE;
- if (trx->n_mysql_tables_in_use == 1) {
- trx->isolation_level = innobase_map_isolation_level(
- (enum_tx_isolation)
- thd->variables.tx_isolation);
- }
-
if (trx->isolation_level == TRX_ISO_SERIALIZABLE
- && prebuilt->select_lock_type == LOCK_NONE
- && (thd->options
+ && prebuilt->select_lock_type == LOCK_NONE
+ && (thd->options
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
/* To get serializable execution, we let InnoDB
@@ -6098,13 +6308,12 @@ ha_innobase::external_lock(
if (prebuilt->select_lock_type != LOCK_NONE) {
if (thd->in_lock_tables &&
- thd->lex->sql_command == SQLCOM_LOCK_TABLES &&
- thd->variables.innodb_table_locks &&
- (thd->options & OPTION_NOT_AUTOCOMMIT)) {
-
- ulint error;
- error = row_lock_table_for_mysql(prebuilt,
- NULL, 0);
+ thd->lex->sql_command == SQLCOM_LOCK_TABLES &&
+ thd->variables.innodb_table_locks &&
+ (thd->options & OPTION_NOT_AUTOCOMMIT)) {
+
+ ulint error = row_lock_table_for_mysql(
+ prebuilt, NULL, 0);
if (error != DB_SUCCESS) {
error = convert_error_code_to_mysql(
@@ -6113,7 +6322,7 @@ ha_innobase::external_lock(
}
}
- trx->mysql_n_tables_locked++;
+ trx->mysql_n_tables_locked++;
}
DBUG_RETURN(0);
@@ -6129,7 +6338,7 @@ ha_innobase::external_lock(
if (trx->n_mysql_tables_in_use == 0) {
- trx->mysql_n_tables_locked = 0;
+ trx->mysql_n_tables_locked = 0;
prebuilt->used_in_HANDLER = FALSE;
/* Release a possible FIFO ticket and search latch. Since we
@@ -6139,12 +6348,12 @@ ha_innobase::external_lock(
innobase_release_stat_resources(trx);
if (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
- if (trx->active_trans != 0) {
- innobase_commit(thd, TRUE);
+ if (trx->active_trans != 0) {
+ innobase_commit(thd, TRUE);
}
} else {
if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
- && trx->global_read_view) {
+ && trx->global_read_view) {
/* At low transaction isolation levels we let
each consistent read set its own snapshot */
@@ -6164,14 +6373,14 @@ user issued query LOCK TABLES..WHERE ENG
int
ha_innobase::transactional_table_lock(
/*==================================*/
- /* out: error code */
+ /* out: error code */
THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
+ int lock_type) /* in: lock type */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
trx_t* trx;
- DBUG_ENTER("ha_innobase::transactional_table_lock");
+ DBUG_ENTER("ha_innobase::transactional_table_lock");
DBUG_PRINT("enter",("lock_type: %d", lock_type));
/* We do not know if MySQL can call this function before calling
@@ -6180,14 +6389,14 @@ ha_innobase::transactional_table_lock(
update_thd(thd);
- if (prebuilt->table->ibd_file_missing && !current_thd->tablespace_op) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB error:\n"
+ if (prebuilt->table->ibd_file_missing && !current_thd->tablespace_op) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB error:\n"
"MySQL is trying to use a table handle but the .ibd file for\n"
"table %s does not exist.\n"
"Have you deleted the .ibd file from the database directory under\n"
"the MySQL datadir?"
-"See http://dev.mysql.com/doc/refman/5.0/en/innodb-troubleshooting.html\n"
+"See http://dev.mysql.com/doc/refman/5.1/en/innodb-troubleshooting.html\n"
"how you can resolve the problem.\n",
prebuilt->table->name);
DBUG_RETURN(HA_ERR_CRASHED);
@@ -6208,8 +6417,8 @@ ha_innobase::transactional_table_lock(
prebuilt->select_lock_type = LOCK_S;
prebuilt->stored_select_lock_type = LOCK_S;
} else {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB error:\n"
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB error:\n"
"MySQL is trying to set transactional table lock with corrupted lock type\n"
"to table %s, lock type %d does not exist.\n",
prebuilt->table->name, lock_type);
@@ -6219,11 +6428,11 @@ ha_innobase::transactional_table_lock(
/* MySQL is setting a new transactional table lock */
/* Set the MySQL flag to mark that there is an active transaction */
- if (trx->active_trans == 0) {
+ if (trx->active_trans == 0) {
- innobase_register_trx_and_stmt(thd);
- trx->active_trans = 1;
- }
+ innobase_register_trx_and_stmt(thd);
+ trx->active_trans = 1;
+ }
if (thd->in_lock_tables && thd->variables.innodb_table_locks) {
ulint error = DB_SUCCESS;
@@ -6251,11 +6460,15 @@ ha_innobase::transactional_table_lock(
/****************************************************************************
Here we export InnoDB status variables to MySQL. */
-void
-innodb_export_status(void)
-/*======================*/
+int
+innodb_export_status()
+/*==================*/
{
- srv_export_innodb_status();
+ if (innodb_inited) {
+ srv_export_innodb_status();
+ }
+
+ return 0;
}
/****************************************************************************
@@ -6265,23 +6478,20 @@ Monitor to the client. */
bool
innodb_show_status(
/*===============*/
- THD* thd) /* in: the MySQL query thread of the caller */
+ THD* thd, /* in: the MySQL query thread of the caller */
+ stat_print_fn *stat_print)
{
- Protocol* protocol = thd->protocol;
trx_t* trx;
static const char truncated_msg[] = "... truncated...\n";
const long MAX_STATUS_SIZE = 64000;
ulint trx_list_start = ULINT_UNDEFINED;
ulint trx_list_end = ULINT_UNDEFINED;
- DBUG_ENTER("innodb_show_status");
+ DBUG_ENTER("innodb_show_status");
- if (have_innodb != SHOW_OPTION_YES) {
- my_message(ER_NOT_SUPPORTED_YET,
- "Cannot call SHOW INNODB STATUS because skip-innodb is defined",
- MYF(0));
- DBUG_RETURN(TRUE);
- }
+ if (have_innodb != SHOW_OPTION_YES) {
+ DBUG_RETURN(FALSE);
+ }
trx = check_trx_exists(thd);
@@ -6313,11 +6523,10 @@ innodb_show_status(
/* allocate buffer for the string, and
read the contents of the temporary file */
- if (!(str = my_malloc(usable_len + 1, MYF(0))))
- {
- mutex_exit_noninline(&srv_monitor_file_mutex);
- DBUG_RETURN(TRUE);
- }
+ if (!(str = my_malloc(usable_len + 1, MYF(0)))) {
+ mutex_exit_noninline(&srv_monitor_file_mutex);
+ DBUG_RETURN(TRUE);
+ }
rewind(srv_monitor_file);
if (flen < MAX_STATUS_SIZE) {
@@ -6342,28 +6551,15 @@ innodb_show_status(
mutex_exit_noninline(&srv_monitor_file_mutex);
- List<Item> field_list;
-
- field_list.push_back(new Item_empty_string("Status", flen));
-
- if (protocol->send_fields(&field_list, Protocol::SEND_NUM_ROWS |
- Protocol::SEND_EOF)) {
- my_free(str, MYF(0));
-
- DBUG_RETURN(TRUE);
- }
-
- protocol->prepare_for_resend();
- protocol->store(str, flen, system_charset_info);
- my_free(str, MYF(0));
-
- if (protocol->write()) {
+ bool result = FALSE;
- DBUG_RETURN(TRUE);
+ if (stat_print(thd, innobase_hton_name, strlen(innobase_hton_name),
+ STRING_WITH_LEN(""), str, flen)) {
+ result= TRUE;
}
- send_eof(thd);
+ my_free(str, MYF(0));
- DBUG_RETURN(FALSE);
+ DBUG_RETURN(FALSE);
}
/****************************************************************************
@@ -6371,112 +6567,116 @@ Implements the SHOW MUTEX STATUS command
bool
innodb_mutex_show_status(
-/*===============*/
- THD* thd) /* in: the MySQL query thread of the caller */
-{
- Protocol *protocol= thd->protocol;
- List<Item> field_list;
- mutex_t* mutex;
- ulint rw_lock_count= 0;
- ulint rw_lock_count_spin_loop= 0;
- ulint rw_lock_count_spin_rounds= 0;
- ulint rw_lock_count_os_wait= 0;
- ulint rw_lock_count_os_yield= 0;
- ulonglong rw_lock_wait_time= 0;
- DBUG_ENTER("innodb_mutex_show_status");
-
- field_list.push_back(new Item_empty_string("Mutex", FN_REFLEN));
- field_list.push_back(new Item_empty_string("Module", FN_REFLEN));
- field_list.push_back(new Item_uint("Count", 21));
- field_list.push_back(new Item_uint("Spin_waits", 21));
- field_list.push_back(new Item_uint("Spin_rounds", 21));
- field_list.push_back(new Item_uint("OS_waits", 21));
- field_list.push_back(new Item_uint("OS_yields", 21));
- field_list.push_back(new Item_uint("OS_waits_time", 21));
-
- if (protocol->send_fields(&field_list,
- Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
- DBUG_RETURN(TRUE);
+/*=====================*/
+ THD* thd, /* in: the MySQL query thread of the
+ caller */
+ stat_print_fn* stat_print)
+{
+ char buf1[IO_SIZE], buf2[IO_SIZE];
+ mutex_t* mutex;
+ ulint rw_lock_count= 0;
+ ulint rw_lock_count_spin_loop= 0;
+ ulint rw_lock_count_spin_rounds= 0;
+ ulint rw_lock_count_os_wait= 0;
+ ulint rw_lock_count_os_yield= 0;
+ ulonglong rw_lock_wait_time= 0;
+ uint hton_name_len= strlen(innobase_hton_name), buf1len, buf2len;
+ DBUG_ENTER("innodb_mutex_show_status");
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
- mutex_enter(&mutex_list_mutex);
+ mutex_enter(&mutex_list_mutex);
#endif
- mutex = UT_LIST_GET_FIRST(mutex_list);
-
- while ( mutex != NULL )
- {
- if (mutex->mutex_type != 1)
- {
- if (mutex->count_using > 0)
- {
- protocol->prepare_for_resend();
- protocol->store(mutex->cmutex_name, system_charset_info);
- protocol->store(mutex->cfile_name, system_charset_info);
- protocol->store((ulonglong)mutex->count_using);
- protocol->store((ulonglong)mutex->count_spin_loop);
- protocol->store((ulonglong)mutex->count_spin_rounds);
- protocol->store((ulonglong)mutex->count_os_wait);
- protocol->store((ulonglong)mutex->count_os_yield);
- protocol->store((ulonglong)mutex->lspent_time/1000);
+ mutex = UT_LIST_GET_FIRST(mutex_list);
- if (protocol->write())
- {
+ while (mutex != NULL) {
+ if (mutex->mutex_type != 1) {
+ if (mutex->count_using > 0) {
+ buf1len= my_snprintf(buf1, sizeof(buf1),
+ "%s:%s",
+ mutex->cmutex_name, mutex->cfile_name);
+ buf2len= my_snprintf(buf2, sizeof(buf2),
+ "count=%lu, spin_waits=%lu,"
+ " spin_rounds=%lu, "
+ "os_waits=%lu, os_yields=%lu,"
+ " os_wait_times=%lu",
+ mutex->count_using,
+ mutex->count_spin_loop,
+ mutex->count_spin_rounds,
+ mutex->count_os_wait,
+ mutex->count_os_yield,
+ mutex->lspent_time/1000);
+
+ if (stat_print(thd, innobase_hton_name,
+ hton_name_len, buf1, buf1len,
+ buf2, buf2len)) {
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
- mutex_exit(&mutex_list_mutex);
+ mutex_exit(&mutex_list_mutex);
#endif
- DBUG_RETURN(1);
- }
- }
- }
- else
- {
- rw_lock_count += mutex->count_using;
- rw_lock_count_spin_loop += mutex->count_spin_loop;
- rw_lock_count_spin_rounds += mutex->count_spin_rounds;
- rw_lock_count_os_wait += mutex->count_os_wait;
- rw_lock_count_os_yield += mutex->count_os_yield;
- rw_lock_wait_time += mutex->lspent_time;
- }
-
- mutex = UT_LIST_GET_NEXT(list, mutex);
- }
+ DBUG_RETURN(1);
+ }
+ }
+ }
+ else {
+ rw_lock_count += mutex->count_using;
+ rw_lock_count_spin_loop += mutex->count_spin_loop;
+ rw_lock_count_spin_rounds += mutex->count_spin_rounds;
+ rw_lock_count_os_wait += mutex->count_os_wait;
+ rw_lock_count_os_yield += mutex->count_os_yield;
+ rw_lock_wait_time += mutex->lspent_time;
+ }
+
+ mutex = UT_LIST_GET_NEXT(list, mutex);
+ }
+
+ buf2len= my_snprintf(buf2, sizeof(buf2),
+ "count=%lu, spin_waits=%lu, spin_rounds=%lu, "
+ "os_waits=%lu, os_yields=%lu, os_wait_times=%lu",
+ rw_lock_count, rw_lock_count_spin_loop,
+ rw_lock_count_spin_rounds,
+ rw_lock_count_os_wait, rw_lock_count_os_yield,
+ rw_lock_wait_time/1000);
- protocol->prepare_for_resend();
- protocol->store("rw_lock_mutexes", system_charset_info);
- protocol->store("", system_charset_info);
- protocol->store((ulonglong)rw_lock_count);
- protocol->store((ulonglong)rw_lock_count_spin_loop);
- protocol->store((ulonglong)rw_lock_count_spin_rounds);
- protocol->store((ulonglong)rw_lock_count_os_wait);
- protocol->store((ulonglong)rw_lock_count_os_yield);
- protocol->store((ulonglong)rw_lock_wait_time/1000);
-
- if (protocol->write())
- {
- DBUG_RETURN(1);
- }
+ if (stat_print(thd, innobase_hton_name, hton_name_len,
+ STRING_WITH_LEN("rw_lock_mutexes"), buf2, buf2len)) {
+ DBUG_RETURN(1);
+ }
#ifdef MUTEX_PROTECT_TO_BE_ADDED_LATER
- mutex_exit(&mutex_list_mutex);
+ mutex_exit(&mutex_list_mutex);
#endif
- send_eof(thd);
- DBUG_RETURN(FALSE);
+
+ DBUG_RETURN(FALSE);
}
+bool innobase_show_status(THD* thd, stat_print_fn* stat_print,
+ enum ha_stat_type stat_type)
+{
+ switch (stat_type) {
+ case HA_ENGINE_STATUS:
+ return innodb_show_status(thd, stat_print);
+ case HA_ENGINE_MUTEX:
+ return innodb_mutex_show_status(thd, stat_print);
+ default:
+ return FALSE;
+ }
+}
+
+
/****************************************************************************
Handling the shared INNOBASE_SHARE structure that is needed to provide table
locking.
****************************************************************************/
-static mysql_byte* innobase_get_key(INNOBASE_SHARE *share,uint *length,
- my_bool not_used __attribute__((unused)))
+static mysql_byte* innobase_get_key(INNOBASE_SHARE* share, uint* length,
+ my_bool not_used __attribute__((unused)))
{
- *length=share->table_name_length;
- return (mysql_byte*) share->table_name;
+ *length=share->table_name_length;
+
+ return (mysql_byte*) share->table_name;
}
-static INNOBASE_SHARE *get_share(const char *table_name)
+static INNOBASE_SHARE* get_share(const char* table_name)
{
INNOBASE_SHARE *share;
pthread_mutex_lock(&innobase_share_mutex);
@@ -6511,17 +6711,18 @@ static INNOBASE_SHARE *get_share(const c
return share;
}
-static void free_share(INNOBASE_SHARE *share)
+static void free_share(INNOBASE_SHARE* share)
{
- pthread_mutex_lock(&innobase_share_mutex);
- if (!--share->use_count)
- {
- hash_delete(&innobase_open_tables, (mysql_byte*) share);
- thr_lock_delete(&share->lock);
- pthread_mutex_destroy(&share->mutex);
- my_free((gptr) share, MYF(0));
- }
- pthread_mutex_unlock(&innobase_share_mutex);
+ pthread_mutex_lock(&innobase_share_mutex);
+
+ if (!--share->use_count) {
+ hash_delete(&innobase_open_tables, (mysql_byte*) share);
+ thr_lock_delete(&share->lock);
+ pthread_mutex_destroy(&share->mutex);
+ my_free((gptr) share, MYF(0));
+ }
+
+ pthread_mutex_unlock(&innobase_share_mutex);
}
/*********************************************************************
@@ -6544,22 +6745,45 @@ ha_innobase::store_lock(
pointer to the 'lock' field
of current handle is stored
next to this array */
- enum thr_lock_type lock_type) /* in: lock type to store in
+ enum thr_lock_type lock_type) /* in: lock type to store in
'lock'; this may also be
TL_IGNORE */
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ trx_t* trx;
+
+ /* Note that trx in this function is NOT necessarily prebuilt->trx
+ because we call update_thd() later, in ::external_lock()! Failure to
+ understand this caused a serious memory corruption bug in 5.1.11. */
+
+ trx = check_trx_exists(thd);
- /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
+ /* NOTE: MySQL can call this function with lock 'type' TL_IGNORE!
Be careful to ignore TL_IGNORE if we are going to do something with
only 'real' locks! */
- if ((lock_type == TL_READ && thd->in_lock_tables) ||
- (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) ||
- lock_type == TL_READ_WITH_SHARED_LOCKS ||
- lock_type == TL_READ_NO_INSERT ||
- (thd->lex->sql_command != SQLCOM_SELECT
- && lock_type != TL_IGNORE)) {
+ /* If no MySQL table is in use, we need to set the isolation level
+ of the transaction. */
+
+ if (lock_type != TL_IGNORE
+ && trx->n_mysql_tables_in_use == 0) {
+ trx->isolation_level = innobase_map_isolation_level(
+ (enum_tx_isolation)
+ thd->variables.tx_isolation);
+ }
+
+ if (thd->lex->sql_command == SQLCOM_DROP_TABLE) {
+
+ /* MySQL calls this function in DROP TABLE though this table
+ handle may belong to another thd that is running a query. Let
+ us in that case skip any changes to the prebuilt struct. */
+
+ } else if ((lock_type == TL_READ && thd->in_lock_tables) ||
+ (lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) ||
+ lock_type == TL_READ_WITH_SHARED_LOCKS ||
+ lock_type == TL_READ_NO_INSERT ||
+ (thd->lex->sql_command != SQLCOM_SELECT
+ && lock_type != TL_IGNORE)) {
/* The OR cases above are in this order:
1) MySQL is doing LOCK TABLES ... READ LOCAL, or
@@ -6578,15 +6802,21 @@ ha_innobase::store_lock(
unexpected if an obsolete consistent read view would be
used. */
- if (srv_locks_unsafe_for_binlog &&
- prebuilt->trx->isolation_level != TRX_ISO_SERIALIZABLE &&
- (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT) &&
- (thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
- thd->lex->sql_command == SQLCOM_UPDATE ||
- thd->lex->sql_command == SQLCOM_CREATE_TABLE)) {
+ ulint isolation_level;
- /* In case we have innobase_locks_unsafe_for_binlog
- option set and isolation level of the transaction
+ isolation_level = trx->isolation_level;
+
+ if ((srv_locks_unsafe_for_binlog
+ || isolation_level == TRX_ISO_READ_COMMITTED)
+ && isolation_level != TRX_ISO_SERIALIZABLE
+ && (lock_type == TL_READ || lock_type == TL_READ_NO_INSERT)
+ && (thd->lex->sql_command == SQLCOM_INSERT_SELECT
+ || thd->lex->sql_command == SQLCOM_UPDATE
+ || thd->lex->sql_command == SQLCOM_CREATE_TABLE)) {
+
+ /* If we either have innobase_locks_unsafe_for_binlog
+ option set or this session is using READ COMMITTED
+ isolation level and isolation level of the transaction
is not set to serializable and MySQL is doing
INSERT INTO...SELECT or UPDATE ... = (SELECT ...) or
CREATE ... SELECT... without FOR UPDATE or
@@ -6649,13 +6879,13 @@ ha_innobase::store_lock(
stored function call (MySQL does have thd->in_lock_tables
TRUE there). */
- if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
- && lock_type <= TL_WRITE)
- && !(thd->in_lock_tables
- && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
- && !thd->tablespace_op
- && thd->lex->sql_command != SQLCOM_TRUNCATE
- && thd->lex->sql_command != SQLCOM_OPTIMIZE
+ if ((lock_type >= TL_WRITE_CONCURRENT_INSERT
+ && lock_type <= TL_WRITE)
+ && !(thd->in_lock_tables
+ && thd->lex->sql_command == SQLCOM_LOCK_TABLES)
+ && !thd->tablespace_op
+ && thd->lex->sql_command != SQLCOM_TRUNCATE
+ && thd->lex->sql_command != SQLCOM_OPTIMIZE
#ifdef __WIN__
/* For alter table on win32 for succesful operation
@@ -6664,13 +6894,13 @@ ha_innobase::store_lock(
TL_WRITE is lifted to TL_WRITE_ALLOW_WRITE, which causes
race condition when several clients do alter table
simultaneously (bug #17264). This fix avoids the problem. */
- && thd->lex->sql_command != SQLCOM_ALTER_TABLE
+ && thd->lex->sql_command != SQLCOM_ALTER_TABLE
#endif
- && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
+ && thd->lex->sql_command != SQLCOM_CREATE_TABLE) {
lock_type = TL_WRITE_ALLOW_WRITE;
- }
+ }
/* In queries of type INSERT INTO t1 SELECT ... FROM t2 ...
MySQL would use the lock TL_READ_NO_INSERT on t2, and that
@@ -6683,8 +6913,8 @@ ha_innobase::store_lock(
(MySQL does have thd->in_lock_tables TRUE there). */
if (lock_type == TL_READ_NO_INSERT
- && (!thd->in_lock_tables
- || thd->lex->sql_command == SQLCOM_CALL)) {
+ && (!thd->in_lock_tables
+ || thd->lex->sql_command == SQLCOM_CALL)) {
lock_type = TL_READ;
}
@@ -6710,17 +6940,18 @@ ha_innobase::innobase_read_and_init_auto
timeout */
longlong* ret) /* out: auto-inc value */
{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- longlong auto_inc;
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ longlong auto_inc;
ulint old_select_lock_type;
ibool trx_was_not_started = FALSE;
- int error;
+ int error;
- ut_a(prebuilt);
- ut_a(prebuilt->trx ==
- (trx_t*) current_thd->ha_data[innobase_hton.slot]);
+ ut_a(prebuilt);
ut_a(prebuilt->table);
+ /* Prepare prebuilt->trx in the table handle */
+ update_thd(current_thd);
+
if (prebuilt->trx->conc_state == TRX_NOT_STARTED) {
trx_was_not_started = TRUE;
}
@@ -6760,8 +6991,8 @@ ha_innobase::innobase_read_and_init_auto
goto func_exit_early;
}
- (void) extra(HA_EXTRA_KEYREAD);
- index_init(table->s->next_number_index);
+ (void) extra(HA_EXTRA_KEYREAD);
+ index_init(table->s->next_number_index, 1);
/* Starting from 5.0.9, we use a consistent read to read the auto-inc
column maximum value. This eliminates the spurious deadlocks caused
@@ -6770,12 +7001,12 @@ ha_innobase::innobase_read_and_init_auto
column, our consistent read will not return the largest value. We
accept this flaw, since the deadlocks were a bigger trouble. */
- /* Fetch all the columns in the key */
+ /* Fetch all the columns in the key */
prebuilt->hint_need_to_fetch_extra_cols = ROW_RETRIEVE_ALL_COLS;
old_select_lock_type = prebuilt->select_lock_type;
- prebuilt->select_lock_type = LOCK_NONE;
+ prebuilt->select_lock_type = LOCK_NONE;
/* Eliminate an InnoDB error print that happens when we try to SELECT
from a table when no table has been locked in ::external_lock(). */
@@ -6784,9 +7015,9 @@ ha_innobase::innobase_read_and_init_auto
error = index_last(table->record[1]);
prebuilt->trx->n_mysql_tables_in_use--;
- prebuilt->select_lock_type = old_select_lock_type;
+ prebuilt->select_lock_type = old_select_lock_type;
- if (error) {
+ if (error) {
if (error == HA_ERR_END_OF_FILE) {
/* The table was empty, initialize to 1 */
auto_inc = 1;
@@ -6796,25 +7027,31 @@ ha_innobase::innobase_read_and_init_auto
/* This should not happen in a consistent read */
sql_print_error("Consistent read of auto-inc column "
"returned %lu", (ulong) error);
- auto_inc = -1;
+ auto_inc = -1;
- goto func_exit;
- }
- } else {
+ goto func_exit;
+ }
+ } else {
/* Initialize to max(col) + 1; we use
'found_next_number_field' below because MySQL in SHOW TABLE
STATUS does not seem to set 'next_number_field'. The comment
in table.h says that 'next_number_field' is set when it is
- 'active'. */
-
- auto_inc = (longlong) table->found_next_number_field->
- val_int_offset(table->s->rec_buff_length) + 1;
- }
+ 'active'.
+ Since 5.1 MySQL enforces that we announce fields which we will
+ read; as we only do a val_*() call, dbug_tmp_use_all_columns()
+ with read_set is sufficient. */
+
+ my_bitmap_map *old_map;
+ old_map= dbug_tmp_use_all_columns(table, table->read_set);
+ auto_inc = (longlong) table->found_next_number_field->
+ val_int_offset(table->s->rec_buff_length) + 1;
+ dbug_tmp_restore_column_map(table->read_set, old_map);
+ }
dict_table_autoinc_initialize(prebuilt->table, auto_inc);
func_exit:
- (void) extra(HA_EXTRA_NO_KEYREAD);
+ (void) extra(HA_EXTRA_NO_KEYREAD);
index_end();
@@ -6833,23 +7070,30 @@ func_exit_early:
innobase_commit_low(prebuilt->trx);
}
- return(error);
+ return(error);
}
-/***********************************************************************
+/*******************************************************************************
This function initializes the auto-inc counter if it has not been
initialized yet. This function does not change the value of the auto-inc
counter if it already has been initialized. Returns the value of the
-auto-inc counter. */
+auto-inc counter in *first_value, and ULONGLONG_MAX in *nb_reserved_values (as
+we have a table-level lock). offset, increment, nb_desired_values are ignored.
+*first_value is set to -1 if error (deadlock or lock wait timeout) */
-ulonglong
-ha_innobase::get_auto_increment()
-/*=============================*/
- /* out: auto-increment column value, -1 if error
- (deadlock or lock wait timeout) */
+void ha_innobase::get_auto_increment(
+/*=================================*/
+ ulonglong offset, /* in */
+ ulonglong increment, /* in */
+ ulonglong nb_desired_values, /* in */
+ ulonglong *first_value, /* out */
+ ulonglong *nb_reserved_values) /* out */
{
- longlong nr;
- int error;
+ longlong nr;
+ int error;
+
+ /* Prepare prebuilt->trx in the table handle */
+ update_thd(current_thd);
error = innobase_read_and_init_auto_inc(&nr);
@@ -6861,10 +7105,13 @@ ha_innobase::get_auto_increment()
ut_print_timestamp(stderr);
sql_print_error("Error %lu in ::get_auto_increment()",
(ulong) error);
- return(~(ulonglong) 0);
+ *first_value= (~(ulonglong) 0);
+ return;
}
- return((ulonglong) nr);
+ *first_value= (ulonglong) nr;
+ /* table-level autoinc lock reserves up to +inf */
+ *nb_reserved_values= ULONGLONG_MAX;
}
/* See comment in handler.h */
@@ -6874,7 +7121,9 @@ ha_innobase::reset_auto_increment(ulongl
DBUG_ENTER("ha_innobase::reset_auto_increment");
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error;
+ int error;
+
+ update_thd(current_thd);
error = row_lock_table_autoinc_for_mysql(prebuilt);
@@ -6893,7 +7142,7 @@ ha_innobase::reset_auto_increment(ulongl
bool
ha_innobase::get_error_message(int error, String *buf)
{
- trx_t* trx = check_trx_exists(current_thd);
+ trx_t* trx = check_trx_exists(current_thd);
buf->copy(trx->detailed_error, strlen(trx->detailed_error),
system_charset_info);
@@ -6916,14 +7165,14 @@ ha_innobase::cmp_ref(
const mysql_byte* ref2) /* in: an (internal) primary key value in the
MySQL key value format */
{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
enum_field_types mysql_type;
Field* field;
KEY_PART_INFO* key_part;
KEY_PART_INFO* key_part_end;
uint len1;
uint len2;
- int result;
+ int result;
if (prebuilt->clust_index_was_generated) {
/* The 'ref' is an InnoDB row id */
@@ -6944,9 +7193,9 @@ ha_innobase::cmp_ref(
mysql_type = field->type();
if (mysql_type == FIELD_TYPE_TINY_BLOB
- || mysql_type == FIELD_TYPE_MEDIUM_BLOB
- || mysql_type == FIELD_TYPE_BLOB
- || mysql_type == FIELD_TYPE_LONG_BLOB) {
+ || mysql_type == FIELD_TYPE_MEDIUM_BLOB
+ || mysql_type == FIELD_TYPE_BLOB
+ || mysql_type == FIELD_TYPE_LONG_BLOB) {
/* In the MySQL key value format, a column prefix of
a BLOB is preceded by a 2-byte length field */
@@ -6957,8 +7206,8 @@ ha_innobase::cmp_ref(
ref1 += 2;
ref2 += 2;
result = ((Field_blob*)field)->cmp(
- (const char*)ref1, len1,
- (const char*)ref2, len2);
+ (const char*)ref1, len1,
+ (const char*)ref2, len2);
} else {
result = field->key_cmp(ref1, ref2);
}
@@ -6984,10 +7233,10 @@ ha_innobase::get_mysql_bin_log_name()
ulonglong
ha_innobase::get_mysql_bin_log_pos()
{
- /* trx... is ib_longlong, which is a typedef for a 64-bit integer
+ /* trx... is ib_longlong, which is a typedef for a 64-bit integer
(__int64 or longlong) so it's ok to cast it to ulonglong. */
- return(trx_sys_mysql_bin_log_pos);
+ return(trx_sys_mysql_bin_log_pos);
}
extern "C" {
@@ -7009,7 +7258,7 @@ innobase_get_at_most_n_mbchars(
ulint prefix_len, /* in: prefix length in bytes of the index
(this has to be divided by mbmaxlen to get the
number of CHARACTERS n in the prefix) */
- ulint data_len, /* in: length of the string in bytes */
+ ulint data_len, /* in: length of the string in bytes */
const char* str) /* in: character string */
{
ulint char_length; /* character length in bytes */
@@ -7088,15 +7337,15 @@ innobase_query_is_update(void)
thd = (THD *)innobase_current_thd();
if (thd->lex->sql_command == SQLCOM_REPLACE ||
- thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
- (thd->lex->sql_command == SQLCOM_LOAD &&
- thd->lex->duplicates == DUP_REPLACE)) {
+ thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
+ (thd->lex->sql_command == SQLCOM_LOAD &&
+ thd->lex->duplicates == DUP_REPLACE)) {
return(1);
}
if (thd->lex->sql_command == SQLCOM_INSERT &&
- thd->lex->duplicates == DUP_UPDATE) {
+ thd->lex->duplicates == DUP_UPDATE) {
return(1);
}
@@ -7118,39 +7367,41 @@ innobase_xa_prepare(
FALSE - the current SQL statement ended */
{
int error = 0;
- trx_t* trx = check_trx_exists(thd);
-
- if (thd->lex->sql_command != SQLCOM_XA_PREPARE) {
-
- /* For ibbackup to work the order of transactions in binlog
- and InnoDB must be the same. Consider the situation
+ trx_t* trx = check_trx_exists(thd);
- thread1> prepare; write to binlog; ...
- <context switch>
- thread2> prepare; write to binlog; commit
- thread1> ... commit
-
- To ensure this will not happen we're taking the mutex on
- prepare, and releasing it on commit.
-
- Note: only do it for normal commits, done via ha_commit_trans.
- If 2pc protocol is executed by external transaction
- coordinator, it will be just a regular MySQL client
- executing XA PREPARE and XA COMMIT commands.
- In this case we cannot know how many minutes or hours
- will be between XA PREPARE and XA COMMIT, and we don't want
- to block for undefined period of time.
- */
- pthread_mutex_lock(&prepare_commit_mutex);
- trx->active_trans = 2;
- }
+ if (thd->lex->sql_command != SQLCOM_XA_PREPARE &&
+ (all || !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))))
+ {
+
+ /* For ibbackup to work the order of transactions in binlog
+ and InnoDB must be the same. Consider the situation
+
+ thread1> prepare; write to binlog; ...
+ <context switch>
+ thread2> prepare; write to binlog; commit
+ thread1> ... commit
+
+ To ensure this will not happen we're taking the mutex on
+ prepare, and releasing it on commit.
+
+ Note: only do it for normal commits, done via ha_commit_trans.
+ If 2pc protocol is executed by external transaction
+ coordinator, it will be just a regular MySQL client
+ executing XA PREPARE and XA COMMIT commands.
+ In this case we cannot know how many minutes or hours
+ will be between XA PREPARE and XA COMMIT, and we don't want
+ to block for undefined period of time.
+ */
+ pthread_mutex_lock(&prepare_commit_mutex);
+ trx->active_trans = 2;
+ }
if (!thd->variables.innodb_support_xa) {
return(0);
}
- trx->xid=thd->transaction.xid_state.xid;
+ trx->xid=thd->transaction.xid_state.xid;
/* Release a possible FIFO ticket and search latch. Since we will
reserve the kernel mutex, we have to release the search system latch
@@ -7165,16 +7416,16 @@ innobase_xa_prepare(
}
if (all
- || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
+ || (!(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)))) {
- /* We were instructed to prepare the whole transaction, or
- this is an SQL statement end and autocommit is on */
+ /* We were instructed to prepare the whole transaction, or
+ this is an SQL statement end and autocommit is on */
- ut_ad(trx->active_trans);
+ ut_ad(trx->active_trans);
error = (int) trx_prepare_for_mysql(trx);
} else {
- /* We just mark the SQL statement ended and do not do a
+ /* We just mark the SQL statement ended and do not do a
transaction prepare */
if (trx->auto_inc_lock) {
@@ -7195,7 +7446,7 @@ innobase_xa_prepare(
srv_active_wake_master_thread();
- return error;
+ return error;
}
/***********************************************************************
@@ -7206,7 +7457,7 @@ innobase_xa_recover(
/*================*/
/* out: number of prepared transactions
stored in xid_list */
- XID* xid_list, /* in/out: prepared transactions */
+ XID* xid_list, /* in/out: prepared transactions */
uint len) /* in: number of slots in xid_list */
{
if (len == 0 || xid_list == NULL) {
@@ -7305,4 +7556,63 @@ innobase_set_cursor_view(
(cursor_view_t*) curview);
}
-#endif /* HAVE_INNOBASE_DB */
+
+bool ha_innobase::check_if_incompatible_data(
+ HA_CREATE_INFO* info,
+ uint table_changes)
+{
+ if (table_changes != IS_EQUAL_YES) {
+
+ return COMPATIBLE_DATA_NO;
+ }
+
+ /* Check that auto_increment value was not changed */
+ if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+ info->auto_increment_value != 0) {
+
+ return COMPATIBLE_DATA_NO;
+ }
+
+ /* Check that row format didn't change */
+ if ((info->used_fields & HA_CREATE_USED_AUTO) &&
+ get_row_type() != info->row_type) {
+
+ return COMPATIBLE_DATA_NO;
+ }
+
+ return COMPATIBLE_DATA_YES;
+}
+
+static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff)
+{
+ innodb_export_status();
+ var->type= SHOW_ARRAY;
+ var->value= (char *) &innodb_status_variables;
+ return 0;
+}
+
+SHOW_VAR innodb_status_variables_export[]= {
+ {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
+ {NullS, NullS, SHOW_LONG}
+};
+
+struct st_mysql_storage_engine innobase_storage_engine=
+{ MYSQL_HANDLERTON_INTERFACE_VERSION, innobase_hton};
+
+mysql_declare_plugin(innobase)
+{
+ MYSQL_STORAGE_ENGINE_PLUGIN,
+ &innobase_storage_engine,
+ innobase_hton_name,
+ "Innobase OY",
+ "Supports transactions, row-level locking, and foreign keys",
+ innobase_init, /* Plugin Init */
+ NULL, /* Plugin Deinit */
+ 0x0100 /* 1.0 */,
+ innodb_status_variables_export,/* status variables */
+ NULL, /* system variables */
+ NULL /* config options */
+}
+mysql_declare_plugin_end;
+
+#endif
| Thread |
|---|
| • bk commit into 5.1 tree (tsmith:1.2346) | tim | 21 Sep |