summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMikael Ronstrom <mikael@dator8>2011-01-12 14:43:03 +0100
committerMikael Ronstrom <mikael@dator8>2011-01-12 14:43:03 +0100
commit773267552f6c701cf3210f908a3608ad0da1087f (patch)
tree2572fe5a1f81ea6ca0b1fa3d47f468b568ff5503 /storage
parent7dae4282d4d5ec2ec8d17f600e87918e0a0aea00 (diff)
parentbbf40ba3c5cac76b4efd2dc177b9ffaff1ce9266 (diff)
downloadmariadb-git-773267552f6c701cf3210f908a3608ad0da1087f.tar.gz
merge
Diffstat (limited to 'storage')
-rw-r--r--storage/heap/heapdef.h7
-rw-r--r--storage/heap/hp_block.c2
-rw-r--r--storage/heap/hp_create.c4
-rw-r--r--storage/heap/hp_open.c2
-rw-r--r--storage/heap/hp_static.c4
-rw-r--r--storage/heap/hp_test2.c8
-rw-r--r--storage/innobase/CMakeLists.txt9
-rw-r--r--storage/innobase/btr/btr0btr.c2
-rw-r--r--storage/innobase/btr/btr0cur.c156
-rw-r--r--storage/innobase/buf/buf0buf.c353
-rw-r--r--storage/innobase/buf/buf0flu.c32
-rw-r--r--storage/innobase/buf/buf0lru.c16
-rw-r--r--storage/innobase/dict/dict0dict.c73
-rw-r--r--storage/innobase/dict/dict0load.c25
-rw-r--r--storage/innobase/dict/dict0mem.c56
-rw-r--r--storage/innobase/fil/fil0fil.c36
-rw-r--r--storage/innobase/fsp/fsp0fsp.c2
-rw-r--r--storage/innobase/handler/ha_innodb.cc238
-rw-r--r--storage/innobase/handler/i_s.cc12
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.c112
-rw-r--r--storage/innobase/include/btr0cur.h42
-rw-r--r--storage/innobase/include/buf0buf.h70
-rw-r--r--storage/innobase/include/data0data.h11
-rw-r--r--storage/innobase/include/data0data.ic22
-rw-r--r--storage/innobase/include/dict0mem.h24
-rw-r--r--storage/innobase/include/ibuf0ibuf.h47
-rw-r--r--storage/innobase/include/mem0mem.ic12
-rw-r--r--storage/innobase/include/mtr0mtr.ic2
-rw-r--r--storage/innobase/include/os0file.h2
-rw-r--r--storage/innobase/include/row0upd.h14
-rw-r--r--storage/innobase/include/srv0srv.h12
-rw-r--r--storage/innobase/include/sync0rw.h1
-rw-r--r--storage/innobase/include/trx0i_s.h3
-rw-r--r--storage/innobase/include/univ.i23
-rw-r--r--storage/innobase/include/ut0ut.h26
-rw-r--r--storage/innobase/log/log0recv.c2
-rw-r--r--storage/innobase/os/os0file.c43
-rw-r--r--storage/innobase/row/row0ins.c2
-rw-r--r--storage/innobase/row/row0mysql.c4
-rw-r--r--storage/innobase/row/row0purge.c2
-rw-r--r--storage/innobase/row/row0umod.c13
-rw-r--r--storage/innobase/row/row0upd.c321
-rw-r--r--storage/innobase/srv/srv0srv.c44
-rw-r--r--storage/innobase/srv/srv0start.c393
-rw-r--r--storage/innobase/sync/sync0arr.c28
-rw-r--r--storage/innobase/trx/trx0i_s.c5
-rw-r--r--storage/innobase/trx/trx0sys.c4
-rw-r--r--storage/innobase/ut/ut0dbg.c2
-rw-r--r--storage/myisam/ha_myisam.cc7
-rw-r--r--storage/myisam/mi_check.c6
-rw-r--r--storage/myisam/mi_close.c2
-rw-r--r--storage/myisam/mi_delete.c3
-rw-r--r--storage/myisam/mi_delete_all.c2
-rw-r--r--storage/myisam/mi_dynrec.c5
-rw-r--r--storage/myisam/mi_log.c4
-rw-r--r--storage/myisam/mi_open.c6
-rw-r--r--storage/myisam/mi_static.c2
-rw-r--r--storage/myisam/mi_statrec.c3
-rw-r--r--storage/myisam/mi_update.c2
-rw-r--r--storage/myisam/mi_write.c4
-rw-r--r--storage/myisam/myisamdef.h16
-rw-r--r--storage/myisam/sort.c2
-rw-r--r--storage/myisammrg/myrg_def.h2
63 files changed, 1571 insertions, 818 deletions
diff --git a/storage/heap/heapdef.h b/storage/heap/heapdef.h
index bc3c6bf7239..87866678c2f 100644
--- a/storage/heap/heapdef.h
+++ b/storage/heap/heapdef.h
@@ -17,9 +17,7 @@
#include <my_base.h> /* This includes global */
C_MODE_START
-#ifdef THREAD
#include <my_pthread.h>
-#endif
#include "heap.h" /* Structs & some defines */
#include "my_tree.h"
@@ -102,14 +100,11 @@ extern void hp_clear(HP_SHARE *info);
extern void hp_clear_keys(HP_SHARE *info);
extern uint hp_rb_pack_key(HP_KEYDEF *keydef, uchar *key, const uchar *old,
key_part_map keypart_map);
-#ifdef THREAD
+
extern mysql_mutex_t THR_LOCK_heap;
-#endif
#ifdef HAVE_PSI_INTERFACE
-#ifdef THREAD
extern PSI_mutex_key hp_key_mutex_HP_SHARE_intern_lock;
-#endif /* THREAD */
void init_heap_psi_keys();
#endif /* HAVE_PSI_INTERFACE */
diff --git a/storage/heap/hp_block.c b/storage/heap/hp_block.c
index 7f6cc1ef90a..41391fba060 100644
--- a/storage/heap/hp_block.c
+++ b/storage/heap/hp_block.c
@@ -86,7 +86,6 @@ int hp_get_new_block(HP_BLOCK *block, size_t *alloc_length)
}
else
{
- dont_break(); /* Dont allow SIGHUP or SIGINT */
if ((uint) i == block->levels)
{
/* Adding a new level on top of the existing ones. */
@@ -117,7 +116,6 @@ int hp_get_new_block(HP_BLOCK *block, size_t *alloc_length)
allocated bytes. Use it as a leaf block.
*/
block->level_info[0].last_blocks= root;
- allow_break(); /* Allow SIGHUP & SIGINT */
}
return 0;
}
diff --git a/storage/heap/hp_create.c b/storage/heap/hp_create.c
index bbf649c5e46..67fe0b3136f 100644
--- a/storage/heap/hp_create.c
+++ b/storage/heap/hp_create.c
@@ -192,11 +192,9 @@ int heap_create(const char *name, HP_CREATE_INFO *create_info,
my_free(share);
goto err;
}
-#ifdef THREAD
thr_lock_init(&share->lock);
mysql_mutex_init(hp_key_mutex_HP_SHARE_intern_lock,
&share->intern_lock, MY_MUTEX_INIT_FAST);
-#endif
if (!create_info->internal_table)
{
share->open_list.data= (void*) share;
@@ -301,10 +299,8 @@ void hp_free(HP_SHARE *share)
if (share->open_list.data) /* If not internal table */
heap_share_list= list_delete(heap_share_list, &share->open_list);
hp_clear(share); /* Remove blocks from memory */
-#ifdef THREAD
thr_lock_delete(&share->lock);
mysql_mutex_destroy(&share->intern_lock);
-#endif
my_free(share->name);
my_free(share);
return;
diff --git a/storage/heap/hp_open.c b/storage/heap/hp_open.c
index 12d9bfe1ed3..5ac4da22e0a 100644
--- a/storage/heap/hp_open.c
+++ b/storage/heap/hp_open.c
@@ -37,9 +37,7 @@ HP_INFO *heap_open_from_share(HP_SHARE *share, int mode)
DBUG_RETURN(0);
}
share->open_count++;
-#ifdef THREAD
thr_lock_data_init(&share->lock,&info->lock,NULL);
-#endif
info->s= share;
info->lastkey= (uchar*) (info + 1);
info->recbuf= (uchar*) (info->lastkey + share->max_key_length);
diff --git a/storage/heap/hp_static.c b/storage/heap/hp_static.c
index e1ca7d1f445..a58ecb8b754 100644
--- a/storage/heap/hp_static.c
+++ b/storage/heap/hp_static.c
@@ -25,7 +25,6 @@
LIST *heap_open_list=0,*heap_share_list=0;
#ifdef HAVE_PSI_INTERFACE
-#ifdef THREAD
PSI_mutex_key hp_key_mutex_HP_SHARE_intern_lock;
static PSI_mutex_info all_heap_mutexes[]=
@@ -36,11 +35,9 @@ static PSI_mutex_info all_heap_mutexes[]=
THR_LOCK_heap is part of mysys, not storage/heap.
*/
};
-#endif /* THREAD */
void init_heap_psi_keys()
{
-#ifdef THREAD
const char* category= "memory";
int count;
@@ -49,7 +46,6 @@ void init_heap_psi_keys()
count= array_elements(all_heap_mutexes);
PSI_server->register_mutex(category, all_heap_mutexes, count);
-#endif /* THREAD */
}
#endif /* HAVE_PSI_INTERFACE */
diff --git a/storage/heap/hp_test2.c b/storage/heap/hp_test2.c
index 3ee903be7ed..af388867c3c 100644
--- a/storage/heap/hp_test2.c
+++ b/storage/heap/hp_test2.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2000-2003, 2006 MySQL AB
+/* Copyright (C) 2000, 2011, Oracle and/or its affiliates. All rights
+ reserved
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -656,11 +657,6 @@ static int rnd(int max_value)
static sig_handler endprog(int sig_number __attribute__((unused)))
{
-#ifndef THREAD
- if (my_dont_interrupt)
- my_remember_signal(sig_number,endprog);
- else
-#endif
{
hp_panic(HA_PANIC_CLOSE);
my_end(1);
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index fa45cc96687..4bbda0d2477 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -40,10 +40,9 @@ IF(UNIX)
ENDIF()
ENDIF()
-# Enable InnoDB's UNIV_DEBUG if MySQL's WITH_DEBUG is defined
-IF(WITH_DEBUG)
- ADD_DEFINITIONS("-DUNIV_DEBUG")
-ENDIF()
+# Enable InnoDB's UNIV_DEBUG for debug builds
+SET(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DUNIV_DEBUG")
+SET(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DUNIV_DEBUG")
IF(NOT MSVC)
# either define HAVE_IB_GCC_ATOMIC_BUILTINS or not
@@ -190,7 +189,7 @@ IF(SIZEOF_PTHREAD_T)
ENDIF()
IF(MSVC)
- ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DHAVE_IB_PAUSE_INSTRUCTION)
+ ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS)
ENDIF()
diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c
index 06cfdf5a798..ff82372b52b 100644
--- a/storage/innobase/btr/btr0btr.c
+++ b/storage/innobase/btr/btr0btr.c
@@ -664,7 +664,7 @@ btr_page_get_father_node_ptr_func(
" to fix the\n"
"InnoDB: corruption. If the crash happens at "
"the database startup, see\n"
- "InnoDB: " REFMAN "forcing-recovery.html about\n"
+ "InnoDB: " REFMAN "forcing-innodb-recovery.html about\n"
"InnoDB: forcing recovery. "
"Then dump + drop + reimport.\n", stderr);
diff --git a/storage/innobase/btr/btr0cur.c b/storage/innobase/btr/btr0cur.c
index 27f05da6f28..a5ed1964b2e 100644
--- a/storage/innobase/btr/btr0cur.c
+++ b/storage/innobase/btr/btr0cur.c
@@ -1874,7 +1874,8 @@ btr_cur_update_in_place(
NOT call it if index is secondary */
if (!dict_index_is_clust(index)
- || row_upd_changes_ord_field_binary(NULL, index, update)) {
+ || row_upd_changes_ord_field_binary(NULL, NULL,
+ index, update)) {
/* Remove possible hash index pointer to this record */
btr_search_update_hash_on_delete(cursor);
@@ -2626,27 +2627,24 @@ ulint
btr_cur_del_mark_set_clust_rec(
/*===========================*/
ulint flags, /*!< in: undo logging and locking flags */
- btr_cur_t* cursor, /*!< in: cursor */
+ buf_block_t* block, /*!< in/out: buffer block of the record */
+ rec_t* rec, /*!< in/out: record */
+ dict_index_t* index, /*!< in: clustered index of the record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec) */
ibool val, /*!< in: value to set */
que_thr_t* thr, /*!< in: query thread */
mtr_t* mtr) /*!< in: mtr */
{
- dict_index_t* index;
- buf_block_t* block;
roll_ptr_t roll_ptr;
ulint err;
- rec_t* rec;
page_zip_des_t* page_zip;
trx_t* trx;
- mem_heap_t* heap = NULL;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets = offsets_;
- rec_offs_init(offsets_);
- rec = btr_cur_get_rec(cursor);
- index = cursor->index;
+ ut_ad(dict_index_is_clust(index));
+ ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!!page_rec_is_comp(rec) == dict_table_is_comp(index->table));
- offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
+ ut_ad(buf_block_get_frame(block) == page_align(rec));
+ ut_ad(page_is_leaf(page_align(rec)));
#ifdef UNIV_DEBUG
if (btr_cur_print_record_ops && thr) {
@@ -2658,13 +2656,12 @@ btr_cur_del_mark_set_clust_rec(
ut_ad(dict_index_is_clust(index));
ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
- err = lock_clust_rec_modify_check_and_lock(flags,
- btr_cur_get_block(cursor),
+ err = lock_clust_rec_modify_check_and_lock(flags, block,
rec, index, offsets, thr);
if (err != DB_SUCCESS) {
- goto func_exit;
+ return(err);
}
err = trx_undo_report_row_operation(flags, TRX_UNDO_MODIFY_OP, thr,
@@ -2672,11 +2669,9 @@ btr_cur_del_mark_set_clust_rec(
&roll_ptr);
if (err != DB_SUCCESS) {
- goto func_exit;
+ return(err);
}
- block = btr_cur_get_block(cursor);
-
if (block->is_hashed) {
rw_lock_x_lock(&btr_search_latch);
}
@@ -2699,10 +2694,6 @@ btr_cur_del_mark_set_clust_rec(
btr_cur_del_mark_set_clust_rec_log(flags, rec, index, val, trx,
roll_ptr, mtr);
-func_exit:
- if (UNIV_LIKELY_NULL(heap)) {
- mem_heap_free(heap);
- }
return(err);
}
@@ -3754,107 +3745,35 @@ btr_cur_set_ownership_of_extern_field(
}
/*******************************************************************//**
-Marks not updated extern fields as not-owned by this record. The ownership
-is transferred to the updated record which is inserted elsewhere in the
+Marks non-updated off-page fields as disowned by this record. The ownership
+must be transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed
-to free the field.
-@return TRUE if BLOB ownership was transferred */
+to free the field. */
UNIV_INTERN
-ibool
-btr_cur_mark_extern_inherited_fields(
-/*=================================*/
+void
+btr_cur_disown_inherited_fields(
+/*============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
- mtr_t* mtr) /*!< in: mtr, or NULL if not logged */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
{
- ulint n;
- ulint j;
ulint i;
- ibool change_ownership = FALSE;
- ut_ad(rec_offs_validate(rec, NULL, offsets));
+ ut_ad(rec_offs_validate(rec, index, offsets));
ut_ad(!rec_offs_comp(offsets) || !rec_get_node_ptr_flag(rec));
+ ut_ad(rec_offs_any_extern(offsets));
+ ut_ad(mtr);
- if (!rec_offs_any_extern(offsets)) {
-
- return(FALSE);
- }
-
- n = rec_offs_n_fields(offsets);
-
- for (i = 0; i < n; i++) {
- if (rec_offs_nth_extern(offsets, i)) {
-
- /* Check it is not in updated fields */
-
- if (update) {
- for (j = 0; j < upd_get_n_fields(update);
- j++) {
- if (upd_get_nth_field(update, j)
- ->field_no == i) {
-
- goto updated;
- }
- }
- }
-
+ for (i = 0; i < rec_offs_n_fields(offsets); i++) {
+ if (rec_offs_nth_extern(offsets, i)
+ && !upd_get_field_by_field_no(update, i)) {
btr_cur_set_ownership_of_extern_field(
page_zip, rec, index, offsets, i, FALSE, mtr);
-
- change_ownership = TRUE;
-updated:
- ;
- }
- }
-
- return(change_ownership);
-}
-
-/*******************************************************************//**
-The complement of the previous function: in an update entry may inherit
-some externally stored fields from a record. We must mark them as inherited
-in entry, so that they are not freed in a rollback. */
-UNIV_INTERN
-void
-btr_cur_mark_dtuple_inherited_extern(
-/*=================================*/
- dtuple_t* entry, /*!< in/out: updated entry to be
- inserted to clustered index */
- const upd_t* update) /*!< in: update vector */
-{
- ulint i;
-
- for (i = 0; i < dtuple_get_n_fields(entry); i++) {
-
- dfield_t* dfield = dtuple_get_nth_field(entry, i);
- byte* data;
- ulint len;
- ulint j;
-
- if (!dfield_is_ext(dfield)) {
- continue;
- }
-
- /* Check if it is in updated fields */
-
- for (j = 0; j < upd_get_n_fields(update); j++) {
- if (upd_get_nth_field(update, j)->field_no == i) {
-
- goto is_updated;
- }
}
-
- data = dfield_get_data(dfield);
- len = dfield_get_len(dfield);
- data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN]
- |= BTR_EXTERN_INHERITED_FLAG;
-
-is_updated:
- ;
}
}
@@ -3894,29 +3813,6 @@ btr_cur_unmark_extern_fields(
}
/*******************************************************************//**
-Marks all extern fields in a dtuple as owned by the record. */
-UNIV_INTERN
-void
-btr_cur_unmark_dtuple_extern_fields(
-/*================================*/
- dtuple_t* entry) /*!< in/out: clustered index entry */
-{
- ulint i;
-
- for (i = 0; i < dtuple_get_n_fields(entry); i++) {
- dfield_t* dfield = dtuple_get_nth_field(entry, i);
-
- if (dfield_is_ext(dfield)) {
- byte* data = dfield_get_data(dfield);
- ulint len = dfield_get_len(dfield);
-
- data[len - BTR_EXTERN_FIELD_REF_SIZE + BTR_EXTERN_LEN]
- &= ~BTR_EXTERN_OWNER_FLAG;
- }
- }
-}
-
-/*******************************************************************//**
Flags the data tuple fields that are marked as extern storage in the
update vector. We use this function to remember which fields we must
mark as extern storage in a record inserted for an update.
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index 0fd518ac6a4..af4b747eb30 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -536,7 +536,7 @@ buf_page_is_corrupted(
"you may have copied the InnoDB\n"
"InnoDB: tablespace but not the InnoDB "
"log files. See\n"
- "InnoDB: " REFMAN "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: for more information.\n",
(ulong) mach_read_from_4(read_buf
+ FIL_PAGE_OFFSET),
@@ -2742,7 +2742,8 @@ buf_page_get_gen(
ut_ad(zip_size == fil_space_get_zip_size(space));
ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
- ut_ad(!ibuf_inside(mtr) || ibuf_page(space, zip_size, offset, NULL));
+ ut_ad(!ibuf_inside(mtr) || ibuf_page_low(space, zip_size, offset,
+ FALSE, file, line, NULL));
#endif
buf_pool->stat.n_page_gets++;
fold = buf_page_address_fold(space, offset);
@@ -4036,7 +4037,7 @@ corrupt:
"InnoDB: TABLE to scan your"
" table for corruption.\n"
"InnoDB: See also "
- REFMAN "forcing-recovery.html\n"
+ REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) {
@@ -4791,23 +4792,203 @@ buf_get_modified_ratio_pct(void)
return(ratio);
}
+/*******************************************************************//**
+Aggregates a pool stats information with the total buffer pool stats */
+static
+void
+buf_stats_aggregate_pool_info(
+/*==========================*/
+ buf_pool_info_t* total_info, /*!< in/out: the buffer pool
+ info to store aggregated
+ result */
+ const buf_pool_info_t* pool_info) /*!< in: individual buffer pool
+ stats info */
+{
+ ut_a(total_info && pool_info);
+
+ /* Nothing to copy if total_info is the same as pool_info */
+ if (total_info == pool_info) {
+ return;
+ }
+
+ total_info->pool_size += pool_info->pool_size;
+ total_info->lru_len += pool_info->lru_len;
+ total_info->old_lru_len += pool_info->old_lru_len;
+ total_info->free_list_len += pool_info->free_list_len;
+ total_info->flush_list_len += pool_info->flush_list_len;
+ total_info->n_pend_unzip += pool_info->n_pend_unzip;
+ total_info->n_pend_reads += pool_info->n_pend_reads;
+ total_info->n_pending_flush_lru += pool_info->n_pending_flush_lru;
+ total_info->n_pending_flush_list += pool_info->n_pending_flush_list;
+ total_info->n_pending_flush_single_page +=
+ pool_info->n_pending_flush_single_page;
+ total_info->n_pages_made_young += pool_info->n_pages_made_young;
+ total_info->n_pages_not_made_young += pool_info->n_pages_not_made_young;
+ total_info->n_pages_read += pool_info->n_pages_read;
+ total_info->n_pages_created += pool_info->n_pages_created;
+ total_info->n_pages_written += pool_info->n_pages_written;
+ total_info->n_page_gets += pool_info->n_page_gets;
+ total_info->n_ra_pages_read += pool_info->n_ra_pages_read;
+ total_info->n_ra_pages_evicted += pool_info->n_ra_pages_evicted;
+ total_info->page_made_young_rate += pool_info->page_made_young_rate;
+ total_info->page_not_made_young_rate +=
+ pool_info->page_not_made_young_rate;
+ total_info->pages_read_rate += pool_info->pages_read_rate;
+ total_info->pages_created_rate += pool_info->pages_created_rate;
+ total_info->pages_written_rate += pool_info->pages_written_rate;
+ total_info->n_page_get_delta += pool_info->n_page_get_delta;
+ total_info->page_read_delta += pool_info->page_read_delta;
+ total_info->young_making_delta += pool_info->young_making_delta;
+ total_info->not_young_making_delta += pool_info->not_young_making_delta;
+ total_info->pages_readahead_rate += pool_info->pages_readahead_rate;
+ total_info->pages_evicted_rate += pool_info->pages_evicted_rate;
+ total_info->unzip_lru_len += pool_info->unzip_lru_len;
+ total_info->io_sum += pool_info->io_sum;
+ total_info->io_cur += pool_info->io_cur;
+ total_info->unzip_sum += pool_info->unzip_sum;
+ total_info->unzip_cur += pool_info->unzip_cur;
+}
+/*******************************************************************//**
+Collect buffer pool stats information for a buffer pool. Also
+record aggregated stats if there are more than one buffer pool
+in the server */
+static
+void
+buf_stats_get_pool_info(
+/*====================*/
+ buf_pool_t* buf_pool, /*!< in: buffer pool */
+ ulint pool_id, /*!< in: buffer pool ID */
+ buf_pool_info_t* all_pool_info) /*!< in/out: buffer pool info
+ to fill */
+{
+ buf_pool_info_t* pool_info;
+ time_t current_time;
+ double time_elapsed;
+
+ /* Find appropriate pool_info to store stats for this buffer pool */
+ pool_info = &all_pool_info[pool_id];
+
+ buf_pool_mutex_enter(buf_pool);
+ buf_flush_list_mutex_enter(buf_pool);
+
+ pool_info->pool_unique_id = pool_id;
+
+ pool_info->pool_size = buf_pool->curr_size;
+
+ pool_info->lru_len = UT_LIST_GET_LEN(buf_pool->LRU);
+
+ pool_info->old_lru_len = buf_pool->LRU_old_len;
+
+ pool_info->free_list_len = UT_LIST_GET_LEN(buf_pool->free);
+
+ pool_info->flush_list_len = UT_LIST_GET_LEN(buf_pool->flush_list);
+
+ pool_info->n_pend_unzip = UT_LIST_GET_LEN(buf_pool->unzip_LRU);
+
+ pool_info->n_pend_reads = buf_pool->n_pend_reads;
+
+ pool_info->n_pending_flush_lru =
+ (buf_pool->n_flush[BUF_FLUSH_LRU]
+ + buf_pool->init_flush[BUF_FLUSH_LRU]);
+
+ pool_info->n_pending_flush_list =
+ (buf_pool->n_flush[BUF_FLUSH_LIST]
+ + buf_pool->init_flush[BUF_FLUSH_LIST]);
+
+ pool_info->n_pending_flush_single_page =
+ buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE];
+
+ buf_flush_list_mutex_exit(buf_pool);
+
+ current_time = time(NULL);
+ time_elapsed = 0.001 + difftime(current_time,
+ buf_pool->last_printout_time);
+
+ pool_info->n_pages_made_young = buf_pool->stat.n_pages_made_young;
+
+ pool_info->n_pages_not_made_young =
+ buf_pool->stat.n_pages_not_made_young;
+
+ pool_info->n_pages_read = buf_pool->stat.n_pages_read;
+
+ pool_info->n_pages_created = buf_pool->stat.n_pages_created;
+
+ pool_info->n_pages_written = buf_pool->stat.n_pages_written;
+
+ pool_info->n_page_gets = buf_pool->stat.n_page_gets;
+
+ pool_info->n_ra_pages_read = buf_pool->stat.n_ra_pages_read;
+
+ pool_info->n_ra_pages_evicted = buf_pool->stat.n_ra_pages_evicted;
+
+ pool_info->page_made_young_rate =
+ (buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young) / time_elapsed;
+
+ pool_info->page_not_made_young_rate =
+ (buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young) / time_elapsed;
+
+ pool_info->pages_read_rate =
+ (buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read) / time_elapsed;
+
+ pool_info->pages_created_rate =
+ (buf_pool->stat.n_pages_created
+ - buf_pool->old_stat.n_pages_created) / time_elapsed;
+
+ pool_info->pages_written_rate =
+ (buf_pool->stat.n_pages_written
+ - buf_pool->old_stat.n_pages_written) / time_elapsed;
+
+ pool_info->n_page_get_delta = buf_pool->stat.n_page_gets
+ - buf_pool->old_stat.n_page_gets;
+
+ if (pool_info->n_page_get_delta) {
+ pool_info->page_read_delta = buf_pool->stat.n_pages_read
+ - buf_pool->old_stat.n_pages_read;
+
+ pool_info->young_making_delta =
+ buf_pool->stat.n_pages_made_young
+ - buf_pool->old_stat.n_pages_made_young;
+
+ pool_info->not_young_making_delta =
+ buf_pool->stat.n_pages_not_made_young
+ - buf_pool->old_stat.n_pages_not_made_young;
+ }
+
+ pool_info->pages_readahead_rate =
+ (buf_pool->stat.n_ra_pages_read
+ - buf_pool->old_stat.n_ra_pages_read) / time_elapsed;
+
+ pool_info->pages_evicted_rate =
+ (buf_pool->stat.n_ra_pages_evicted
+ - buf_pool->old_stat.n_ra_pages_evicted) / time_elapsed;
+
+ pool_info->unzip_lru_len = UT_LIST_GET_LEN(buf_pool->unzip_LRU);
+
+ pool_info->io_sum = buf_LRU_stat_sum.io;
+
+ pool_info->io_cur = buf_LRU_stat_cur.io;
+
+ pool_info->unzip_sum = buf_LRU_stat_sum.unzip;
+
+ pool_info->unzip_cur = buf_LRU_stat_cur.unzip;
+
+ buf_refresh_io_stats(buf_pool);
+ buf_pool_mutex_exit(buf_pool);
+}
+
/*********************************************************************//**
Prints info of the buffer i/o. */
UNIV_INTERN
void
buf_print_io_instance(
/*==================*/
- buf_pool_t* buf_pool, /*!< in: buffer pool instance */
+ buf_pool_info_t*pool_info, /*!< in: buffer pool info */
FILE* file) /*!< in/out: buffer where to print */
{
- time_t current_time;
- double time_elapsed;
- ulint n_gets_diff;
-
- ut_ad(buf_pool);
-
- buf_pool_mutex_enter(buf_pool);
- buf_flush_list_mutex_enter(buf_pool);
+ ut_ad(pool_info);
fprintf(file,
"Buffer pool size %lu\n"
@@ -4817,70 +4998,42 @@ buf_print_io_instance(
"Modified db pages %lu\n"
"Pending reads %lu\n"
"Pending writes: LRU %lu, flush list %lu, single page %lu\n",
- (ulong) buf_pool->curr_size,
- (ulong) UT_LIST_GET_LEN(buf_pool->free),
- (ulong) UT_LIST_GET_LEN(buf_pool->LRU),
- (ulong) buf_pool->LRU_old_len,
- (ulong) UT_LIST_GET_LEN(buf_pool->flush_list),
- (ulong) buf_pool->n_pend_reads,
- (ulong) buf_pool->n_flush[BUF_FLUSH_LRU]
- + buf_pool->init_flush[BUF_FLUSH_LRU],
- (ulong) buf_pool->n_flush[BUF_FLUSH_LIST]
- + buf_pool->init_flush[BUF_FLUSH_LIST],
- (ulong) buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
-
- buf_flush_list_mutex_exit(buf_pool);
-
- current_time = time(NULL);
- time_elapsed = 0.001 + difftime(current_time,
- buf_pool->last_printout_time);
+ pool_info->pool_size,
+ pool_info->free_list_len,
+ pool_info->lru_len,
+ pool_info->old_lru_len,
+ pool_info->flush_list_len,
+ pool_info->n_pend_reads,
+ pool_info->n_pending_flush_lru,
+ pool_info->n_pending_flush_list,
+ pool_info->n_pending_flush_single_page);
fprintf(file,
"Pages made young %lu, not young %lu\n"
"%.2f youngs/s, %.2f non-youngs/s\n"
"Pages read %lu, created %lu, written %lu\n"
"%.2f reads/s, %.2f creates/s, %.2f writes/s\n",
- (ulong) buf_pool->stat.n_pages_made_young,
- (ulong) buf_pool->stat.n_pages_not_made_young,
- (buf_pool->stat.n_pages_made_young
- - buf_pool->old_stat.n_pages_made_young)
- / time_elapsed,
- (buf_pool->stat.n_pages_not_made_young
- - buf_pool->old_stat.n_pages_not_made_young)
- / time_elapsed,
- (ulong) buf_pool->stat.n_pages_read,
- (ulong) buf_pool->stat.n_pages_created,
- (ulong) buf_pool->stat.n_pages_written,
- (buf_pool->stat.n_pages_read
- - buf_pool->old_stat.n_pages_read)
- / time_elapsed,
- (buf_pool->stat.n_pages_created
- - buf_pool->old_stat.n_pages_created)
- / time_elapsed,
- (buf_pool->stat.n_pages_written
- - buf_pool->old_stat.n_pages_written)
- / time_elapsed);
-
- n_gets_diff = buf_pool->stat.n_page_gets
- - buf_pool->old_stat.n_page_gets;
-
- if (n_gets_diff) {
+ pool_info->n_pages_made_young,
+ pool_info->n_pages_not_made_young,
+ pool_info->page_made_young_rate,
+ pool_info->page_not_made_young_rate,
+ pool_info->n_pages_read,
+ pool_info->n_pages_created,
+ pool_info->n_pages_written,
+ pool_info->pages_read_rate,
+ pool_info->pages_created_rate,
+ pool_info->pages_written_rate);
+
+ if (pool_info->n_page_get_delta) {
fprintf(file,
"Buffer pool hit rate %lu / 1000,"
" young-making rate %lu / 1000 not %lu / 1000\n",
- (ulong)
- (1000 - ((1000 * (buf_pool->stat.n_pages_read
- - buf_pool->old_stat.n_pages_read))
- / (buf_pool->stat.n_page_gets
- - buf_pool->old_stat.n_page_gets))),
- (ulong)
- (1000 * (buf_pool->stat.n_pages_made_young
- - buf_pool->old_stat.n_pages_made_young)
- / n_gets_diff),
- (ulong)
- (1000 * (buf_pool->stat.n_pages_not_made_young
- - buf_pool->old_stat.n_pages_not_made_young)
- / n_gets_diff));
+ (ulong) (1000 - (1000 * pool_info->page_read_delta
+ / pool_info->n_page_get_delta)),
+ (ulong) (1000 * pool_info->young_making_delta
+ / pool_info->n_page_get_delta),
+ (ulong) (1000 * pool_info->not_young_making_delta
+ / pool_info->n_page_get_delta));
} else {
fputs("No buffer pool page gets since the last printout\n",
file);
@@ -4889,25 +5042,17 @@ buf_print_io_instance(
/* Statistics about read ahead algorithm */
fprintf(file, "Pages read ahead %.2f/s,"
" evicted without access %.2f/s\n",
- (buf_pool->stat.n_ra_pages_read
- - buf_pool->old_stat.n_ra_pages_read)
- / time_elapsed,
- (buf_pool->stat.n_ra_pages_evicted
- - buf_pool->old_stat.n_ra_pages_evicted)
- / time_elapsed);
+ pool_info->pages_readahead_rate,
+ pool_info->pages_evicted_rate);
/* Print some values to help us with visualizing what is
happening with LRU eviction. */
fprintf(file,
"LRU len: %lu, unzip_LRU len: %lu\n"
"I/O sum[%lu]:cur[%lu], unzip sum[%lu]:cur[%lu]\n",
- UT_LIST_GET_LEN(buf_pool->LRU),
- UT_LIST_GET_LEN(buf_pool->unzip_LRU),
- buf_LRU_stat_sum.io, buf_LRU_stat_cur.io,
- buf_LRU_stat_sum.unzip, buf_LRU_stat_cur.unzip);
-
- buf_refresh_io_stats(buf_pool);
- buf_pool_mutex_exit(buf_pool);
+ pool_info->lru_len, pool_info->unzip_lru_len,
+ pool_info->io_sum, pool_info->io_cur,
+ pool_info->unzip_sum, pool_info->unzip_cur);
}
/*********************************************************************//**
@@ -4918,14 +5063,58 @@ buf_print_io(
/*=========*/
FILE* file) /*!< in/out: buffer where to print */
{
- ulint i;
+ ulint i;
+ buf_pool_info_t* pool_info;
+ buf_pool_info_t* pool_info_total;
+
+ /* If srv_buf_pool_instances is greater than 1, allocate
+ one extra buf_pool_info_t, the last one stores
+ aggregated/total values from all pools */
+ if (srv_buf_pool_instances > 1) {
+ pool_info = (buf_pool_info_t*) mem_zalloc((
+ srv_buf_pool_instances + 1) * sizeof *pool_info);
+
+ pool_info_total = &pool_info[srv_buf_pool_instances];
+ } else {
+ ut_a(srv_buf_pool_instances == 1);
+ pool_info_total = pool_info = (buf_pool_info_t*) mem_zalloc(
+ sizeof *pool_info)
+ }
for (i = 0; i < srv_buf_pool_instances; i++) {
buf_pool_t* buf_pool;
buf_pool = buf_pool_from_array(i);
- buf_print_io_instance(buf_pool, file);
+
+ /* Fetch individual buffer pool info and calculate
+ aggregated stats along the way */
+ buf_stats_get_pool_info(buf_pool, i, pool_info);
+
+ /* If we have more than one buffer pool, store
+ the aggregated stats */
+ if (srv_buf_pool_instances > 1) {
+ buf_stats_aggregate_pool_info(pool_info_total,
+ &pool_info[i]);
+ }
}
+
+ /* Print the aggreate buffer pool info */
+ buf_print_io_instance(pool_info_total, file);
+
+ /* If there are more than one buffer pool, print each individual pool
+ info */
+ if (srv_buf_pool_instances > 1) {
+ fputs("----------------------\n"
+ "INDIVIDUAL BUFFER POOL INFO\n"
+ "----------------------\n", file);
+
+ for (i = 0; i < srv_buf_pool_instances; i++) {
+ fprintf(file, "---BUFFER POOL %lu\n", i);
+ buf_print_io_instance(&pool_info[i], file);
+ }
+ }
+
+ mem_free(pool_info);
}
/**********************************************************************//**
diff --git a/storage/innobase/buf/buf0flu.c b/storage/innobase/buf/buf0flu.c
index 5b0617f17b1..07a32e55f97 100644
--- a/storage/innobase/buf/buf0flu.c
+++ b/storage/innobase/buf/buf0flu.c
@@ -88,6 +88,34 @@ ibool
buf_flush_validate_low(
/*===================*/
buf_pool_t* buf_pool); /*!< in: Buffer pool instance */
+
+/******************************************************************//**
+Validates the flush list some of the time.
+@return TRUE if ok or the check was skipped */
+static
+ibool
+buf_flush_validate_skip(
+/*====================*/
+ buf_pool_t* buf_pool) /*!< in: Buffer pool instance */
+{
+/** Try buf_flush_validate_low() every this many times */
+# define BUF_FLUSH_VALIDATE_SKIP 23
+
+ /** The buf_flush_validate_low() call skip counter.
+ Use a signed type because of the race condition below. */
+ static int buf_flush_validate_count = BUF_FLUSH_VALIDATE_SKIP;
+
+ /* There is a race condition below, but it does not matter,
+ because this call is only for heuristic purposes. We want to
+ reduce the call frequency of the costly buf_flush_validate_low()
+ check in debug builds. */
+ if (--buf_flush_validate_count > 0) {
+ return(TRUE);
+ }
+
+ buf_flush_validate_count = BUF_FLUSH_VALIDATE_SKIP;
+ return(buf_flush_validate_low(buf_pool));
+}
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
/******************************************************************//**
@@ -293,7 +321,7 @@ buf_flush_insert_into_flush_list(
}
#endif /* UNIV_DEBUG_VALGRIND */
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- ut_a(buf_flush_validate_low(buf_pool));
+ ut_a(buf_flush_validate_skip(buf_pool));
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
buf_flush_list_mutex_exit(buf_pool);
@@ -515,7 +543,7 @@ buf_flush_remove(
bpage->oldest_modification = 0;
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
- ut_a(buf_flush_validate_low(buf_pool));
+ ut_a(buf_flush_validate_skip(buf_pool));
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
buf_flush_list_mutex_exit(buf_pool);
diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c
index 8ad5f2dad83..d819782ac9d 100644
--- a/storage/innobase/buf/buf0lru.c
+++ b/storage/innobase/buf/buf0lru.c
@@ -2076,6 +2076,7 @@ buf_LRU_stat_update(void)
buf_LRU_stat_t* item;
buf_pool_t* buf_pool;
ibool evict_started = FALSE;
+ buf_LRU_stat_t cur_stat;
/* If we haven't started eviction yet then don't update stats. */
for (i = 0; i < srv_buf_pool_instances; i++) {
@@ -2097,12 +2098,19 @@ buf_LRU_stat_update(void)
buf_LRU_stat_arr_ind++;
buf_LRU_stat_arr_ind %= BUF_LRU_STAT_N_INTERVAL;
- /* Add the current value and subtract the obsolete entry. */
- buf_LRU_stat_sum.io += buf_LRU_stat_cur.io - item->io;
- buf_LRU_stat_sum.unzip += buf_LRU_stat_cur.unzip - item->unzip;
+ /* Add the current value and subtract the obsolete entry.
+ Since buf_LRU_stat_cur is not protected by any mutex,
+ it can be changing between adding to buf_LRU_stat_sum
+ and copying to item. Assign it to local variables to make
+ sure the same value assign to the buf_LRU_stat_sum
+ and item */
+ cur_stat = buf_LRU_stat_cur;
+
+ buf_LRU_stat_sum.io += cur_stat.io - item->io;
+ buf_LRU_stat_sum.unzip += cur_stat.unzip - item->unzip;
/* Put current entry in the array. */
- memcpy(item, &buf_LRU_stat_cur, sizeof *item);
+ memcpy(item, &cur_stat, sizeof *item);
func_exit:
/* Clear the current entry. */
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index 0d15ad8b716..ee862d8c709 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -52,8 +52,9 @@ UNIV_INTERN dict_index_t* dict_ind_compact;
#include "que0que.h"
#include "rem0cmp.h"
#include "row0merge.h"
+#include "srv0srv.h" /* srv_lower_case_table_names */
#include "m_ctype.h" /* my_isspace() */
-#include "ha_prototypes.h" /* innobase_strcasecmp() */
+#include "ha_prototypes.h" /* innobase_strcasecmp(), innobase_casedn_str()*/
#include <ctype.h>
@@ -74,6 +75,7 @@ UNIV_INTERN rw_lock_t dict_operation_lock;
#ifdef UNIV_PFS_RWLOCK
UNIV_INTERN mysql_pfs_key_t dict_operation_lock_key;
UNIV_INTERN mysql_pfs_key_t index_tree_rw_lock_key;
+UNIV_INTERN mysql_pfs_key_t dict_table_stats_latch_key;
#endif /* UNIV_PFS_RWLOCK */
#ifdef UNIV_PFS_MUTEX
@@ -714,7 +716,7 @@ dict_init(void)
&dict_foreign_err_mutex, SYNC_ANY_LATCH);
for (i = 0; i < DICT_TABLE_STATS_LATCHES_SIZE; i++) {
- rw_lock_create(PFS_NOT_INSTRUMENTED,
+ rw_lock_create(dict_table_stats_latch_key,
&dict_table_stats_latches[i], SYNC_INDEX_TREE);
}
}
@@ -1080,13 +1082,13 @@ dict_table_rename_in_cache(
/* Allocate a longer name buffer;
TODO: store buf len to save memory */
- foreign->foreign_table_name
- = mem_heap_alloc(foreign->heap,
- ut_strlen(table->name) + 1);
+ foreign->foreign_table_name = mem_heap_strdup(
+ foreign->heap, table->name);
+ dict_mem_foreign_table_name_lookup_set(foreign, TRUE);
+ } else {
+ strcpy(foreign->foreign_table_name, table->name);
+ dict_mem_foreign_table_name_lookup_set(foreign, FALSE);
}
-
- strcpy(foreign->foreign_table_name, table->name);
-
if (strchr(foreign->id, '/')) {
ulint db_len;
char* old_id;
@@ -1152,12 +1154,14 @@ dict_table_rename_in_cache(
/* Allocate a longer name buffer;
TODO: store buf len to save memory */
- foreign->referenced_table_name = mem_heap_alloc(
- foreign->heap, strlen(table->name) + 1);
+ foreign->referenced_table_name = mem_heap_strdup(
+ foreign->heap, table->name);
+ dict_mem_referenced_table_name_lookup_set(foreign, TRUE);
+ } else {
+ /* Use the same buffer */
+ strcpy(foreign->referenced_table_name, table->name);
+ dict_mem_referenced_table_name_lookup_set(foreign, FALSE);
}
-
- strcpy(foreign->referenced_table_name, table->name);
-
foreign = UT_LIST_GET_NEXT(referenced_list, foreign);
}
@@ -2583,10 +2587,10 @@ dict_foreign_add_to_cache(
ut_ad(mutex_own(&(dict_sys->mutex)));
for_table = dict_table_check_if_in_cache_low(
- foreign->foreign_table_name);
+ foreign->foreign_table_name_lookup);
ref_table = dict_table_check_if_in_cache_low(
- foreign->referenced_table_name);
+ foreign->referenced_table_name_lookup);
ut_a(for_table || ref_table);
if (for_table) {
@@ -2703,7 +2707,7 @@ dict_scan_to(
quote = '\0';
} else if (quote) {
/* Within quotes: do nothing. */
- } else if (*ptr == '`' || *ptr == '"') {
+ } else if (*ptr == '`' || *ptr == '"' || *ptr == '\'') {
/* Starting quote: remember the quote character. */
quote = *ptr;
} else {
@@ -3015,19 +3019,25 @@ dict_scan_table_name(
memcpy(ref, database_name, database_name_len);
ref[database_name_len] = '/';
memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
-#ifndef __WIN__
- if (srv_lower_case_table_names) {
-#endif /* !__WIN__ */
- /* The table name is always put to lower case on Windows. */
+
+ /* Values; 0 = Store and compare as given; case sensitive
+ 1 = Store and compare in lower; case insensitive
+ 2 = Store as given, compare in lower; case semi-sensitive */
+ if (srv_lower_case_table_names == 2) {
innobase_casedn_str(ref);
-#ifndef __WIN__
+ *table = dict_table_get_low(ref);
+ memcpy(ref, database_name, database_name_len);
+ ref[database_name_len] = '/';
+ memcpy(ref + database_name_len + 1, table_name, table_name_len + 1);
+ } else {
+ if (srv_lower_case_table_names == 1) {
+ innobase_casedn_str(ref);
+ }
+ *table = dict_table_get_low(ref);
}
-#endif /* !__WIN__ */
*success = TRUE;
*ref_name = ref;
- *table = dict_table_get_low(ref);
-
return(ptr);
}
@@ -3516,8 +3526,10 @@ col_loop1:
}
foreign->foreign_table = table;
- foreign->foreign_table_name = mem_heap_strdup(foreign->heap,
- table->name);
+ foreign->foreign_table_name = mem_heap_strdup(
+ foreign->heap, table->name);
+ dict_mem_foreign_table_name_lookup_set(foreign, TRUE);
+
foreign->foreign_index = index;
foreign->n_fields = (unsigned int) i;
foreign->foreign_col_names = mem_heap_alloc(foreign->heap,
@@ -3774,8 +3786,9 @@ try_find_index:
foreign->referenced_index = index;
foreign->referenced_table = referenced_table;
- foreign->referenced_table_name
- = mem_heap_strdup(foreign->heap, referenced_table_name);
+ foreign->referenced_table_name = mem_heap_strdup(
+ foreign->heap, referenced_table_name);
+ dict_mem_referenced_table_name_lookup_set(foreign, TRUE);
foreign->referenced_col_names = mem_heap_alloc(foreign->heap,
i * sizeof(void*));
@@ -4586,8 +4599,8 @@ dict_print_info_on_foreign_key_in_create_format(
fputs(") REFERENCES ", file);
- if (dict_tables_have_same_db(foreign->foreign_table_name,
- foreign->referenced_table_name)) {
+ if (dict_tables_have_same_db(foreign->foreign_table_name_lookup,
+ foreign->referenced_table_name_lookup)) {
/* Do not print the database name of the referenced table */
ut_print_name(file, trx, TRUE,
dict_remove_db_name(
diff --git a/storage/innobase/dict/dict0load.c b/storage/innobase/dict/dict0load.c
index 5b01669af29..3252e85b358 100644
--- a/storage/innobase/dict/dict0load.c
+++ b/storage/innobase/dict/dict0load.c
@@ -40,6 +40,7 @@ Created 4/24/1996 Heikki Tuuri
#include "rem0cmp.h"
#include "srv0start.h"
#include "srv0srv.h"
+#include "ha_prototypes.h" /* innobase_casedn_str() */
/** Following are six InnoDB system tables */
@@ -435,10 +436,12 @@ dict_process_sys_fields_rec(
return(err_msg);
}
+
+#ifdef FOREIGN_NOT_USED
/********************************************************************//**
This function parses a SYS_FOREIGN record and populate a dict_foreign_t
structure with the information from the record. For detail information
-about SYS_FOREIGN fields, please refer to dict_load_foreign() function
+about SYS_FOREIGN fields, please refer to dict_load_foreign() function.
@return error message, or NULL on success */
UNIV_INTERN
const char*
@@ -466,6 +469,11 @@ dict_process_sys_foreign_rec(
err_len:
return("incorrect column length in SYS_FOREIGN");
}
+
+ /* This recieves a dict_foreign_t* that points to a stack variable.
+ So mem_heap_free(foreign->heap) is not used as elsewhere.
+ Since the heap used here is freed elsewhere, foreign->heap
+ is not assigned. */
foreign->id = mem_heap_strdupl(heap, (const char*) field, len);
rec_get_nth_field_offs_old(rec, 1/*DB_TRX_ID*/, &len);
@@ -477,6 +485,9 @@ err_len:
goto err_len;
}
+ /* The _lookup versions of the referenced and foreign table names
+ are not assigned since they are not used in this dict_foreign_t */
+
field = rec_get_nth_field_old(rec, 3/*FOR_NAME*/, &len);
if (UNIV_UNLIKELY(len < 1 || len == UNIV_SQL_NULL)) {
goto err_len;
@@ -502,6 +513,9 @@ err_len:
return(NULL);
}
+#endif /* FOREIGN_NOT_USED */
+
+#ifdef FOREIGN_NOT_USED
/********************************************************************//**
This function parses a SYS_FOREIGN_COLS record and extract necessary
information from the record and return to caller.
@@ -565,6 +579,8 @@ err_len:
return(NULL);
}
+#endif /* FOREIGN_NOT_USED */
+
/********************************************************************//**
Determine the flags of a table described in SYS_TABLES.
@return compressed page size in kilobytes; or 0 if the tablespace is
@@ -2057,12 +2073,15 @@ dict_load_foreign(
foreign->id = mem_heap_strdup(foreign->heap, id);
field = rec_get_nth_field_old(rec, 3, &len);
+
foreign->foreign_table_name = mem_heap_strdupl(
foreign->heap, (char*) field, len);
+ dict_mem_foreign_table_name_lookup_set(foreign, TRUE);
field = rec_get_nth_field_old(rec, 4, &len);
foreign->referenced_table_name = mem_heap_strdupl(
foreign->heap, (char*) field, len);
+ dict_mem_referenced_table_name_lookup_set(foreign, TRUE);
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -2070,7 +2089,7 @@ dict_load_foreign(
dict_load_foreign_cols(id, foreign);
ref_table = dict_table_check_if_in_cache_low(
- foreign->referenced_table_name);
+ foreign->referenced_table_name_lookup);
/* We could possibly wind up in a deep recursive calls if
we call dict_table_get_low() again here if there
@@ -2103,7 +2122,7 @@ dict_load_foreign(
have to load it so that we are able to make type comparisons
in the next function call. */
- for_table = dict_table_get_low(foreign->foreign_table_name);
+ for_table = dict_table_get_low(foreign->foreign_table_name_lookup);
if (for_table && ref_table && check_recursive) {
/* This is to record the longest chain of ancesters
diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c
index bbb8f810f44..8d3d78f3900 100644
--- a/storage/innobase/dict/dict0mem.c
+++ b/storage/innobase/dict/dict0mem.c
@@ -33,6 +33,8 @@ Created 1/8/1996 Heikki Tuuri
#include "data0type.h"
#include "mach0data.h"
#include "dict0dict.h"
+#include "srv0srv.h" /* srv_lower_case_table_names */
+#include "ha_prototypes.h" /* innobase_casedn_str()*/
#ifndef UNIV_HOTBACKUP
# include "lock0lock.h"
#endif /* !UNIV_HOTBACKUP */
@@ -288,6 +290,60 @@ dict_mem_foreign_create(void)
}
/**********************************************************************//**
+Sets the foreign_table_name_lookup pointer based on the value of
+srv_lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup
+will point to foreign_table_name. If 2, then another string is allocated
+of the heap and set to lower case. */
+UNIV_INTERN
+void
+dict_mem_foreign_table_name_lookup_set(
+/*===================================*/
+ dict_foreign_t* foreign, /*!< in/out: foreign struct */
+ ibool do_alloc) /*!< in: is an alloc needed */
+{
+ if (srv_lower_case_table_names == 2) {
+ if (do_alloc) {
+ foreign->foreign_table_name_lookup = mem_heap_alloc(
+ foreign->heap,
+ strlen(foreign->foreign_table_name) + 1);
+ }
+ strcpy(foreign->foreign_table_name_lookup,
+ foreign->foreign_table_name);
+ innobase_casedn_str(foreign->foreign_table_name_lookup);
+ } else {
+ foreign->foreign_table_name_lookup
+ = foreign->foreign_table_name;
+ }
+}
+
+/**********************************************************************//**
+Sets the referenced_table_name_lookup pointer based on the value of
+srv_lower_case_table_names. If that is 0 or 1,
+referenced_table_name_lookup will point to referenced_table_name. If 2,
+then another string is allocated of the heap and set to lower case. */
+UNIV_INTERN
+void
+dict_mem_referenced_table_name_lookup_set(
+/*======================================*/
+ dict_foreign_t* foreign, /*!< in/out: foreign struct */
+ ibool do_alloc) /*!< in: is an alloc needed */
+{
+ if (srv_lower_case_table_names == 2) {
+ if (do_alloc) {
+ foreign->referenced_table_name_lookup = mem_heap_alloc(
+ foreign->heap,
+ strlen(foreign->referenced_table_name) + 1);
+ }
+ strcpy(foreign->referenced_table_name_lookup,
+ foreign->referenced_table_name);
+ innobase_casedn_str(foreign->referenced_table_name_lookup);
+ } else {
+ foreign->referenced_table_name_lookup
+ = foreign->referenced_table_name;
+ }
+}
+
+/**********************************************************************//**
Adds a field definition to an index. NOTE: does not take a copy
of the column name if the field is a column. The memory occupied
by the column name may be released only after publishing the index. */
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 7f1551b6bb7..6c50b853187 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -299,6 +299,34 @@ struct fil_system_struct {
initialized. */
static fil_system_t* fil_system = NULL;
+#ifdef UNIV_DEBUG
+/** Try fil_validate() every this many times */
+# define FIL_VALIDATE_SKIP 17
+
+/******************************************************************//**
+Checks the consistency of the tablespace cache some of the time.
+@return TRUE if ok or the check was skipped */
+static
+ibool
+fil_validate_skip(void)
+/*===================*/
+{
+ /** The fil_validate() call skip counter. Use a signed type
+ because of the race condition below. */
+ static int fil_validate_count = FIL_VALIDATE_SKIP;
+
+ /* There is a race condition below, but it does not matter,
+ because this call is only for heuristic purposes. We want to
+ reduce the call frequency of the costly fil_validate() check
+ in debug builds. */
+ if (--fil_validate_count > 0) {
+ return(TRUE);
+ }
+
+ fil_validate_count = FIL_VALIDATE_SKIP;
+ return(fil_validate());
+}
+#endif /* UNIV_DEBUG */
/********************************************************************//**
NOTE: you must call fil_mutex_enter_and_prepare_for_io() first!
@@ -4307,7 +4335,7 @@ fil_io(
#if (1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE
# error "(1 << UNIV_PAGE_SIZE_SHIFT) != UNIV_PAGE_SIZE"
#endif
- ut_ad(fil_validate());
+ ut_ad(fil_validate_skip());
#ifndef UNIV_HOTBACKUP
# ifndef UNIV_LOG_DEBUG
/* ibuf bitmap pages must be read in the sync aio mode: */
@@ -4464,7 +4492,7 @@ fil_io(
mutex_exit(&fil_system->mutex);
- ut_ad(fil_validate());
+ ut_ad(fil_validate_skip());
}
return(DB_SUCCESS);
@@ -4488,7 +4516,7 @@ fil_aio_wait(
void* message;
ulint type;
- ut_ad(fil_validate());
+ ut_ad(fil_validate_skip());
if (srv_use_native_aio) {
srv_set_io_thread_op_info(segment, "native aio handle");
@@ -4519,7 +4547,7 @@ fil_aio_wait(
mutex_exit(&fil_system->mutex);
- ut_ad(fil_validate());
+ ut_ad(fil_validate_skip());
/* Do the i/o handling */
/* IMPORTANT: since i/o handling for reads will read also the insert
diff --git a/storage/innobase/fsp/fsp0fsp.c b/storage/innobase/fsp/fsp0fsp.c
index ffe2b21b80c..5bf5411bc6a 100644
--- a/storage/innobase/fsp/fsp0fsp.c
+++ b/storage/innobase/fsp/fsp0fsp.c
@@ -3321,7 +3321,7 @@ fseg_free_page_low(
"InnoDB: database!\n", (ulong) page);
crash:
fputs("InnoDB: Please refer to\n"
- "InnoDB: " REFMAN "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
ut_error;
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 824f12b97b7..ae782426e61 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -285,7 +285,8 @@ static PSI_rwlock_info all_innodb_rwlocks[] = {
{&checkpoint_lock_key, "checkpoint_lock", 0},
{&trx_i_s_cache_lock_key, "trx_i_s_cache_lock", 0},
{&trx_purge_latch_key, "trx_purge_latch", 0},
- {&index_tree_rw_lock_key, "index_tree_rw_lock", 0}
+ {&index_tree_rw_lock_key, "index_tree_rw_lock", 0},
+ {&dict_table_stats_latch_key, "dict_table_stats", 0}
};
# endif /* UNIV_PFS_RWLOCK */
@@ -2164,13 +2165,13 @@ innobase_init(
ut_a(DATA_MYSQL_TRUE_VARCHAR == (ulint)MYSQL_TYPE_VARCHAR);
-#ifdef UNIV_DEBUG
+#ifndef DBUG_OFF
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)
+ sizeof test_tablename, true)
|| strncmp(test_tablename,
srv_mysql50_table_name_prefix,
sizeof srv_mysql50_table_name_prefix)
@@ -2180,7 +2181,7 @@ innobase_init(
sql_print_error("tablename encoding has been changed");
goto error;
}
-#endif /* UNIV_DEBUG */
+#endif /* DBUG_OFF */
/* Check that values don't overflow on 32-bit systems. */
if (sizeof(ulint) == 4) {
@@ -3638,6 +3639,7 @@ ha_innobase::open(
UT_NOT_USED(test_if_locked);
thd = ha_thd();
+ srv_lower_case_table_names = lower_case_table_names;
/* Under some cases MySQL seems to call this function while
holding btr_search_latch. This breaks the latching order as
@@ -6497,10 +6499,11 @@ create_clustered_index_when_no_primary(
/*****************************************************************//**
Return a display name for the row format
@return row format name */
-
-const char *get_row_format_name(
-/*============================*/
-enum row_type row_format) /*!< in: Row Format */
+UNIV_INTERN
+const char*
+get_row_format_name(
+/*================*/
+ enum row_type row_format) /*!< in: Row Format */
{
switch (row_format) {
case ROW_TYPE_COMPACT:
@@ -6515,12 +6518,38 @@ enum row_type row_format) /*!< in: Row Format */
return("DEFAULT");
case ROW_TYPE_FIXED:
return("FIXED");
- default:
+ case ROW_TYPE_PAGE:
+ case ROW_TYPE_NOT_USED:
break;
}
return("NOT USED");
}
+/** If file-per-table is missing, issue warning and set ret false */
+#define CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE \
+ if (!srv_file_per_table) { \
+ push_warning_printf( \
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN, \
+ ER_ILLEGAL_HA_CREATE_OPTION, \
+ "InnoDB: ROW_FORMAT=%s requires" \
+ " innodb_file_per_table.", \
+ get_row_format_name(row_format)); \
+ ret = FALSE; \
+ }
+
+/** If file-format is Antelope, issue warning and set ret false */
+#define CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE \
+ if (srv_file_format < DICT_TF_FORMAT_ZIP) { \
+ push_warning_printf( \
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN, \
+ ER_ILLEGAL_HA_CREATE_OPTION, \
+ "InnoDB: ROW_FORMAT=%s requires" \
+ " innodb_file_format > Antelope.", \
+ get_row_format_name(row_format)); \
+ ret = FALSE; \
+ }
+
+
/*****************************************************************//**
Validates the create options. We may build on this function
in future. For now, it checks two specifiers:
@@ -6538,7 +6567,7 @@ create_options_are_valid(
{
ibool kbs_specified = FALSE;
ibool ret = TRUE;
- enum row_type row_type = form->s->row_type;
+ enum row_type row_format = form->s->row_type;
ut_ad(thd != NULL);
@@ -6547,23 +6576,6 @@ create_options_are_valid(
return(TRUE);
}
- /* Check for a valid Innodb ROW_FORMAT specifier. For example,
- ROW_TYPE_FIXED can be sent to Innodb */
- switch (row_type) {
- case ROW_TYPE_COMPACT:
- case ROW_TYPE_COMPRESSED:
- case ROW_TYPE_DYNAMIC:
- case ROW_TYPE_REDUNDANT:
- case ROW_TYPE_DEFAULT:
- break;
- default:
- push_warning(
- thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: invalid ROW_FORMAT specifier.");
- ret = FALSE;
- }
-
ut_ad(form != NULL);
ut_ad(create_info != NULL);
@@ -6576,7 +6588,23 @@ create_options_are_valid(
case 4:
case 8:
case 16:
- /* Valid value. */
+ /* Valid KEY_BLOCK_SIZE, check its dependencies. */
+ if (!srv_file_per_table) {
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: KEY_BLOCK_SIZE requires"
+ " innodb_file_per_table.");
+ ret = FALSE;
+ }
+ if (srv_file_format < DICT_TF_FORMAT_ZIP) {
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION,
+ "InnoDB: KEY_BLOCK_SIZE requires"
+ " innodb_file_format > Antelope.");
+ ret = FALSE;
+ }
break;
default:
push_warning_printf(
@@ -6586,72 +6614,43 @@ create_options_are_valid(
" Valid values are [1, 2, 4, 8, 16]",
create_info->key_block_size);
ret = FALSE;
+ break;
}
}
- /* If KEY_BLOCK_SIZE was specified, check for its
- dependencies. */
- if (kbs_specified && !srv_file_per_table) {
- push_warning(
- thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: KEY_BLOCK_SIZE requires"
- " innodb_file_per_table.");
- ret = FALSE;
- }
-
- if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning(
- thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: KEY_BLOCK_SIZE requires"
- " innodb_file_format > Antelope.");
- ret = FALSE;
- }
-
- switch (row_type) {
+ /* Check for a valid Innodb ROW_FORMAT specifier and
+ other incompatibilities. */
+ switch (row_format) {
case ROW_TYPE_COMPRESSED:
- case ROW_TYPE_DYNAMIC:
- /* These two ROW_FORMATs require srv_file_per_table
- and srv_file_format > Antelope */
- if (!srv_file_per_table) {
- push_warning_printf(
- thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s requires"
- " innodb_file_per_table.",
- get_row_format_name(row_type));
- ret = FALSE;
- }
-
- if (srv_file_format < DICT_TF_FORMAT_ZIP) {
- push_warning_printf(
- thd, MYSQL_ERROR::WARN_LEVEL_WARN,
- ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ROW_FORMAT=%s requires"
- " innodb_file_format > Antelope.",
- get_row_format_name(row_type));
- ret = FALSE;
- }
- default:
+ CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE;
+ CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE;
break;
- }
-
- switch (row_type) {
- case ROW_TYPE_REDUNDANT:
- case ROW_TYPE_COMPACT:
case ROW_TYPE_DYNAMIC:
- /* KEY_BLOCK_SIZE is only allowed with Compressed or Default */
+ CHECK_ERROR_ROW_TYPE_NEEDS_FILE_PER_TABLE;
+ CHECK_ERROR_ROW_TYPE_NEEDS_GT_ANTELOPE;
+ /* fall through since dynamic also shuns KBS */
+ case ROW_TYPE_COMPACT:
+ case ROW_TYPE_REDUNDANT:
if (kbs_specified) {
push_warning_printf(
thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: cannot specify ROW_FORMAT = %s"
" with KEY_BLOCK_SIZE.",
- get_row_format_name(row_type));
- ret = FALSE;
+ get_row_format_name(row_format));
+ ret = FALSE;
}
- default:
+ break;
+ case ROW_TYPE_DEFAULT:
+ break;
+ case ROW_TYPE_FIXED:
+ case ROW_TYPE_PAGE:
+ case ROW_TYPE_NOT_USED:
+ push_warning(
+ thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_ILLEGAL_HA_CREATE_OPTION, \
+ "InnoDB: invalid ROW_FORMAT specifier.");
+ ret = FALSE;
break;
}
@@ -6702,7 +6701,7 @@ ha_innobase::create(
const ulint file_format = srv_file_format;
const char* stmt;
size_t stmt_len;
- enum row_type row_type;
+ enum row_type row_format;
DBUG_ENTER("ha_innobase::create");
@@ -6752,11 +6751,7 @@ ha_innobase::create(
trx = innobase_trx_allocate(thd);
- if (lower_case_table_names) {
- srv_lower_case_table_names = TRUE;
- } else {
- srv_lower_case_table_names = FALSE;
- }
+ srv_lower_case_table_names = lower_case_table_names;
strcpy(name2, name);
@@ -6820,20 +6815,19 @@ ha_innobase::create(
push_warning_printf(
thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
- "InnoDB: ignoring"
- " KEY_BLOCK_SIZE=%lu.",
+ "InnoDB: ignoring KEY_BLOCK_SIZE=%lu.",
create_info->key_block_size);
}
}
- row_type = form->s->row_type;
+ row_format = form->s->row_type;
if (flags) {
/* if ROW_FORMAT is set to default,
automatically change it to COMPRESSED.*/
- if (row_type == ROW_TYPE_DEFAULT) {
- row_type = ROW_TYPE_COMPRESSED;
- } else if (row_type != ROW_TYPE_COMPRESSED) {
+ if (row_format == ROW_TYPE_DEFAULT) {
+ row_format = ROW_TYPE_COMPRESSED;
+ } else if (row_format != ROW_TYPE_COMPRESSED) {
/* ROW_FORMAT other than COMPRESSED
ignores KEY_BLOCK_SIZE. It does not
make sense to reject conflicting
@@ -6850,7 +6844,7 @@ ha_innobase::create(
}
} else {
/* flags == 0 means no KEY_BLOCK_SIZE.*/
- if (row_type == ROW_TYPE_COMPRESSED) {
+ if (row_format == ROW_TYPE_COMPRESSED) {
/* ROW_FORMAT=COMPRESSED without
KEY_BLOCK_SIZE implies half the
maximum KEY_BLOCK_SIZE. */
@@ -6865,7 +6859,7 @@ ha_innobase::create(
}
}
- switch (row_type) {
+ switch (row_format) {
case ROW_TYPE_REDUNDANT:
break;
case ROW_TYPE_COMPRESSED:
@@ -6876,25 +6870,25 @@ ha_innobase::create(
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s requires"
" innodb_file_per_table.",
- get_row_format_name(row_type));
+ get_row_format_name(row_format));
} else if (file_format < DICT_TF_FORMAT_ZIP) {
push_warning_printf(
thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
"InnoDB: ROW_FORMAT=%s requires"
" innodb_file_format > Antelope.",
- get_row_format_name(row_type));
+ get_row_format_name(row_format));
} else {
flags |= DICT_TF_COMPACT
- | (DICT_TF_FORMAT_ZIP
- << DICT_TF_FORMAT_SHIFT);
+ | (DICT_TF_FORMAT_ZIP
+ << DICT_TF_FORMAT_SHIFT);
break;
}
/* fall through */
case ROW_TYPE_NOT_USED:
case ROW_TYPE_FIXED:
- default:
+ case ROW_TYPE_PAGE:
push_warning(
thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_ILLEGAL_HA_CREATE_OPTION,
@@ -7035,23 +7029,25 @@ ha_innobase::create(
setup at this stage and so we use thd. */
/* We need to copy the AUTOINC value from the old table if
- this is an ALTER TABLE or CREATE INDEX because CREATE INDEX
- does a table copy too. */
+ this is an ALTER|OPTIMIZE TABLE or CREATE INDEX because CREATE INDEX
+ does a table copy too. If query was one of :
+
+ CREATE TABLE ...AUTO_INCREMENT = x; or
+ ALTER TABLE...AUTO_INCREMENT = x; or
+ OPTIMIZE TABLE t; or
+ CREATE INDEX x on t(...);
+
+ Find out a table definition from the dictionary and get
+ the current value of the auto increment field. Set a new
+ value to the auto increment field if the value is greater
+ than the maximum value in the column. */
if (((create_info->used_fields & HA_CREATE_USED_AUTO)
|| thd_sql_command(thd) == SQLCOM_ALTER_TABLE
+ || thd_sql_command(thd) == SQLCOM_OPTIMIZE
|| thd_sql_command(thd) == SQLCOM_CREATE_INDEX)
&& create_info->auto_increment_value > 0) {
- /* Query was one of :
- CREATE TABLE ...AUTO_INCREMENT = x; or
- ALTER TABLE...AUTO_INCREMENT = x; or
- CREATE INDEX x on t(...);
- Find out a table definition from the dictionary and get
- the current value of the auto increment field. Set a new
- value to the auto increment field if the value is greater
- than the maximum value in the column. */
-
auto_inc_value = create_info->auto_increment_value;
dict_table_autoinc_lock(innobase_table);
@@ -7180,11 +7176,7 @@ ha_innobase::delete_table(
trx = innobase_trx_allocate(thd);
- if (lower_case_table_names) {
- srv_lower_case_table_names = TRUE;
- } else {
- srv_lower_case_table_names = FALSE;
- }
+ srv_lower_case_table_names = lower_case_table_names;
name_len = strlen(name);
@@ -7307,11 +7299,7 @@ innobase_rename_table(
char* norm_to;
char* norm_from;
- if (lower_case_table_names) {
- srv_lower_case_table_names = TRUE;
- } else {
- srv_lower_case_table_names = FALSE;
- }
+ srv_lower_case_table_names = lower_case_table_names;
// Magic number 64 arbitrary
norm_to = (char*) my_malloc(strlen(to) + 64, MYF(0));
@@ -7848,14 +7836,14 @@ ha_innobase::info_low(
are asked by MySQL to avoid locking. Another reason to
avoid the call is that it uses quite a lot of CPU.
See Bug#38185. */
- if (flag & HA_STATUS_NO_LOCK ||
- !(flag & HA_STATUS_VARIABLE_EXTRA)) {
+ if (flag & HA_STATUS_NO_LOCK
+ || !(flag & HA_STATUS_VARIABLE_EXTRA)) {
/* We do not update delete_length if no
locking is requested so the "old" value can
remain. delete_length is initialized to 0 in
the ha_statistics' constructor. Also we only
- need delete_length to be set when
- HA_STATUS_VARIABLE_EXTRA is set */
+ need delete_length to be set when
+ HA_STATUS_VARIABLE_EXTRA is set */
} else if (UNIV_UNLIKELY
(srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
/* Avoid accessing the tablespace if
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 9f0e465a4d9..709274bab16 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -495,8 +495,16 @@ fill_innodb_trx_from_cache(
row->trx_mysql_thread_id));
/* trx_query */
- OK(field_store_string(fields[IDX_TRX_QUERY],
- row->trx_query));
+ if (row->trx_query) {
+ /* store will do appropriate character set
+ conversion check */
+ fields[IDX_TRX_QUERY]->store(
+ row->trx_query, strlen(row->trx_query),
+ row->trx_query_cs);
+ fields[IDX_TRX_QUERY]->set_notnull();
+ } else {
+ fields[IDX_TRX_QUERY]->set_null();
+ }
/* trx_operation_state */
OK(field_store_string(fields[IDX_TRX_OPERATION_STATE],
diff --git a/storage/innobase/ibuf/ibuf0ibuf.c b/storage/innobase/ibuf/ibuf0ibuf.c
index aab0084c214..41eba7cb9f3 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.c
+++ b/storage/innobase/ibuf/ibuf0ibuf.c
@@ -645,22 +645,49 @@ ibuf_parse_bitmap_init(
return(ptr);
}
#ifndef UNIV_HOTBACKUP
+# ifdef UNIV_DEBUG
+/** Gets the desired bits for a given page from a bitmap page.
+@param page in: bitmap page
+@param offset in: page whose bits to get
+@param zs in: compressed page size in bytes; 0 for uncompressed pages
+@param bit in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ...
+@param mtr in: mini-transaction holding an x-latch on the bitmap page
+@return value of bits */
+# define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
+ ibuf_bitmap_page_get_bits_low(page, offset, zs, \
+ MTR_MEMO_PAGE_X_FIX, mtr, bit)
+# else /* UNIV_DEBUG */
+/** Gets the desired bits for a given page from a bitmap page.
+@param page in: bitmap page
+@param offset in: page whose bits to get
+@param zs in: compressed page size in bytes; 0 for uncompressed pages
+@param bit in: IBUF_BITMAP_FREE, IBUF_BITMAP_BUFFERED, ...
+@param mtr in: mini-transaction holding an x-latch on the bitmap page
+@return value of bits */
+# define ibuf_bitmap_page_get_bits(page, offset, zs, bit, mtr) \
+ ibuf_bitmap_page_get_bits_low(page, offset, zs, bit)
+# endif /* UNIV_DEBUG */
+
/********************************************************************//**
Gets the desired bits for a given page from a bitmap page.
@return value of bits */
UNIV_INLINE
ulint
-ibuf_bitmap_page_get_bits(
-/*======================*/
+ibuf_bitmap_page_get_bits_low(
+/*==========================*/
const page_t* page, /*!< in: bitmap page */
ulint page_no,/*!< in: page whose bits to get */
ulint zip_size,/*!< in: compressed page size in bytes;
0 for uncompressed pages */
- ulint bit, /*!< in: IBUF_BITMAP_FREE,
+#ifdef UNIV_DEBUG
+ ulint latch_type,
+ /*!< in: MTR_MEMO_PAGE_X_FIX,
+ MTR_MEMO_BUF_FIX, ... */
+ mtr_t* mtr, /*!< in: mini-transaction holding latch_type
+ on the bitmap page */
+#endif /* UNIV_DEBUG */
+ ulint bit) /*!< in: IBUF_BITMAP_FREE,
IBUF_BITMAP_BUFFERED, ... */
- mtr_t* mtr __attribute__((unused)))
- /*!< in: mtr containing an
- x-latch to the bitmap page */
{
ulint byte_offset;
ulint bit_offset;
@@ -672,7 +699,7 @@ ibuf_bitmap_page_get_bits(
# error "IBUF_BITS_PER_PAGE % 2 != 0"
#endif
ut_ad(ut_is_2pow(zip_size));
- ut_ad(mtr_memo_contains_page(mtr, page, MTR_MEMO_PAGE_X_FIX));
+ ut_ad(mtr_memo_contains_page(mtr, page, latch_type));
if (!zip_size) {
bit_offset = (page_no % UNIV_PAGE_SIZE) * IBUF_BITS_PER_PAGE
@@ -1098,21 +1125,29 @@ Must not be called when recv_no_ibuf_operations==TRUE.
@return TRUE if level 2 or level 3 page */
UNIV_INTERN
ibool
-ibuf_page(
-/*======*/
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint page_no,/*!< in: page number */
- mtr_t* mtr) /*!< in: mtr which will contain an x-latch to the
- bitmap page if the page is not one of the fixed
- address ibuf pages, or NULL, in which case a new
- transaction is created. */
+ibuf_page_low(
+/*==========*/
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number */
+#ifdef UNIV_DEBUG
+ ibool x_latch,/*!< in: FALSE if relaxed check
+ (avoid latching the bitmap page) */
+#endif /* UNIV_DEBUG */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mtr which will contain an
+ x-latch to the bitmap page if the page
+ is not one of the fixed address ibuf
+ pages, or NULL, in which case a new
+ transaction is created. */
{
ibool ret;
mtr_t local_mtr;
page_t* bitmap_page;
ut_ad(!recv_no_ibuf_operations);
+ ut_ad(x_latch || mtr == NULL);
if (ibuf_fixed_addr_page(space, zip_size, page_no)) {
@@ -1124,12 +1159,55 @@ ibuf_page(
ut_ad(fil_space_get_type(IBUF_SPACE_ID) == FIL_TABLESPACE);
+#ifdef UNIV_DEBUG
+ if (!x_latch) {
+ mtr_start(&local_mtr);
+
+ /* Get the bitmap page without a page latch, so that
+ we will not be violating the latching order when
+ another bitmap page has already been latched by this
+ thread. The page will be buffer-fixed, and thus it
+ cannot be removed or relocated while we are looking at
+ it. The contents of the page could change, but the
+ IBUF_BITMAP_IBUF bit that we are interested in should
+ not be modified by any other thread. Nobody should be
+ calling ibuf_add_free_page() or ibuf_remove_free_page()
+ while the page is linked to the insert buffer b-tree. */
+
+ bitmap_page = buf_block_get_frame(
+ buf_page_get_gen(
+ space, zip_size,
+ ibuf_bitmap_page_no_calc(zip_size, page_no),
+ RW_NO_LATCH, NULL, BUF_GET_NO_LATCH,
+ file, line, &local_mtr));
+# ifdef UNIV_SYNC_DEBUG
+ /* This is for tracking Bug #58212. This check and message can
+ be removed once it has been established that our assumptions
+ about this condition are correct. The bug was only a one-time
+ occurrence, unable to repeat since then. */
+ void* latch = sync_thread_levels_contains(SYNC_IBUF_BITMAP);
+ if (latch) {
+ fprintf(stderr, "Bug#58212 UNIV_SYNC_DEBUG"
+ " levels %p (%u,%u)\n",
+ latch, (unsigned) space, (unsigned) page_no);
+ }
+# endif /* UNIV_SYNC_DEBUG */
+ ret = ibuf_bitmap_page_get_bits_low(
+ bitmap_page, page_no, zip_size,
+ MTR_MEMO_BUF_FIX, &local_mtr, IBUF_BITMAP_IBUF);
+
+ mtr_commit(&local_mtr);
+ return(ret);
+ }
+#endif /* UNIV_DEBUG */
+
if (mtr == NULL) {
mtr = &local_mtr;
mtr_start(mtr);
}
- bitmap_page = ibuf_bitmap_get_map_page(space, page_no, zip_size, mtr);
+ bitmap_page = ibuf_bitmap_get_map_page_func(space, page_no, zip_size,
+ file, line, mtr);
ret = ibuf_bitmap_page_get_bits(bitmap_page, page_no, zip_size,
IBUF_BITMAP_IBUF, mtr);
diff --git a/storage/innobase/include/btr0cur.h b/storage/innobase/include/btr0cur.h
index 9865ebfbfc2..cb65c6bfab7 100644
--- a/storage/innobase/include/btr0cur.h
+++ b/storage/innobase/include/btr0cur.h
@@ -333,10 +333,14 @@ ulint
btr_cur_del_mark_set_clust_rec(
/*===========================*/
ulint flags, /*!< in: undo logging and locking flags */
- btr_cur_t* cursor, /*!< in: cursor */
+ buf_block_t* block, /*!< in/out: buffer block of the record */
+ rec_t* rec, /*!< in/out: record */
+ dict_index_t* index, /*!< in: clustered index of the record */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec) */
ibool val, /*!< in: value to set */
que_thr_t* thr, /*!< in: query thread */
- mtr_t* mtr); /*!< in: mtr */
+ mtr_t* mtr) /*!< in: mtr */
+ __attribute__((nonnull));
/***********************************************************//**
Sets a secondary index record delete mark to TRUE or FALSE.
@return DB_SUCCESS, DB_LOCK_WAIT, or error number */
@@ -469,40 +473,22 @@ btr_estimate_number_of_different_key_vals(
/*======================================*/
dict_index_t* index); /*!< in: index */
/*******************************************************************//**
-Marks not updated extern fields as not-owned by this record. The ownership
-is transferred to the updated record which is inserted elsewhere in the
+Marks non-updated off-page fields as disowned by this record. The ownership
+must be transferred to the updated record which is inserted elsewhere in the
index tree. In purge only the owner of externally stored field is allowed
-to free the field.
-@return TRUE if BLOB ownership was transferred */
+to free the field. */
UNIV_INTERN
-ibool
-btr_cur_mark_extern_inherited_fields(
-/*=================================*/
+void
+btr_cur_disown_inherited_fields(
+/*============================*/
page_zip_des_t* page_zip,/*!< in/out: compressed page whose uncompressed
part will be updated, or NULL */
rec_t* rec, /*!< in/out: record in a clustered index */
dict_index_t* index, /*!< in: index of the page */
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
const upd_t* update, /*!< in: update vector */
- mtr_t* mtr); /*!< in: mtr, or NULL if not logged */
-/*******************************************************************//**
-The complement of the previous function: in an update entry may inherit
-some externally stored fields from a record. We must mark them as inherited
-in entry, so that they are not freed in a rollback. */
-UNIV_INTERN
-void
-btr_cur_mark_dtuple_inherited_extern(
-/*=================================*/
- dtuple_t* entry, /*!< in/out: updated entry to be
- inserted to clustered index */
- const upd_t* update); /*!< in: update vector */
-/*******************************************************************//**
-Marks all extern fields in a dtuple as owned by the record. */
-UNIV_INTERN
-void
-btr_cur_unmark_dtuple_extern_fields(
-/*================================*/
- dtuple_t* entry); /*!< in/out: clustered index entry */
+ mtr_t* mtr) /*!< in/out: mini-transaction */
+ __attribute__((nonnull(2,3,4,5,6)));
/*******************************************************************//**
Stores the fields in big_rec_vec to the tablespace and puts pointers to
them in rec. The extern flags in rec will have to be set beforehand.
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index a42eba57fd2..46cae25f0f5 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -116,6 +116,76 @@ enum buf_page_state {
before putting to the free list */
};
+
+/** This structure defines information we will fetch from each buffer pool. It
+will be used to print table IO stats */
+struct buf_pool_info_struct{
+ /* General buffer pool info */
+ ulint pool_unique_id; /*!< Buffer Pool ID */
+ ulint pool_size; /*!< Buffer Pool size in pages */
+ ulint lru_len; /*!< Length of buf_pool->LRU */
+ ulint old_lru_len; /*!< buf_pool->LRU_old_len */
+ ulint free_list_len; /*!< Length of buf_pool->free list */
+ ulint flush_list_len; /*!< Length of buf_pool->flush_list */
+ ulint n_pend_unzip; /*!< buf_pool->n_pend_unzip, pages
+ pending decompress */
+ ulint n_pend_reads; /*!< buf_pool->n_pend_reads, pages
+ pending read */
+ ulint n_pending_flush_lru; /*!< Pages pending flush in LRU */
+ ulint n_pending_flush_list; /*!< Pages pending flush in FLUSH
+ LIST */
+ ulint n_pending_flush_single_page;/*!< Pages pending flush in
+ BUF_FLUSH_SINGLE_PAGE list */
+ ulint n_pages_made_young; /*!< number of pages made young */
+ ulint n_pages_not_made_young; /*!< number of pages not made young */
+ ulint n_pages_read; /*!< buf_pool->n_pages_read */
+ ulint n_pages_created; /*!< buf_pool->n_pages_created */
+ ulint n_pages_written; /*!< buf_pool->n_pages_written */
+ ulint n_page_gets; /*!< buf_pool->n_page_gets */
+ ulint n_ra_pages_read; /*!< buf_pool->n_ra_pages_read, number
+ of pages readahead */
+ ulint n_ra_pages_evicted; /*!< buf_pool->n_ra_pages_evicted,
+ number of readahead pages evicted
+ without access */
+ ulint n_page_get_delta; /*!< num of buffer pool page gets since
+ last printout */
+
+ /* Buffer pool access stats */
+ double page_made_young_rate; /*!< page made young rate in pages
+ per second */
+ double page_not_made_young_rate;/*!< page not made young rate
+ in pages per second */
+ double pages_read_rate; /*!< num of pages read per second */
+ double pages_created_rate; /*!< num of pages create per second */
+ double pages_written_rate; /*!< num of pages written per second */
+ ulint page_read_delta; /*!< num of pages read since last
+ printout */
+ ulint young_making_delta; /*!< num of pages made young since
+ last printout */
+ ulint not_young_making_delta; /*!< num of pages not make young since
+ last printout */
+
+ /* Statistics about read ahead algorithm. */
+ double pages_readahead_rate; /*!< readahead rate in pages per
+ second */
+ double pages_evicted_rate; /*!< rate of readahead page evicted
+ without access, in pages per second */
+
+ /* Stats about LRU eviction */
+ ulint unzip_lru_len; /*!< length of buf_pool->unzip_LRU
+ list */
+ /* Counters for LRU policy */
+ ulint io_sum; /*!< buf_LRU_stat_sum.io */
+ ulint io_cur; /*!< buf_LRU_stat_cur.io, num of IO
+ for current interval */
+ ulint unzip_sum; /*!< buf_LRU_stat_sum.unzip */
+ ulint unzip_cur; /*!< buf_LRU_stat_cur.unzip, num
+ pages decompressed in current
+ interval */
+};
+
+typedef struct buf_pool_info_struct buf_pool_info_t;
+
#ifndef UNIV_HOTBACKUP
/********************************************************************//**
Acquire mutex on all buffer pool instances */
diff --git a/storage/innobase/include/data0data.h b/storage/innobase/include/data0data.h
index 11e4027777a..f7bdd29ed90 100644
--- a/storage/innobase/include/data0data.h
+++ b/storage/innobase/include/data0data.h
@@ -154,14 +154,19 @@ dfield_dup(
dfield_t* field, /*!< in/out: data field */
mem_heap_t* heap); /*!< in: memory heap where allocated */
/*********************************************************************//**
-Tests if data length and content is equal for two dfields.
-@return TRUE if equal */
+Tests if two data fields are equal.
+If len==0, tests the data length and content for equality.
+If len>0, tests the first len bytes of the content for equality.
+@return TRUE if both fields are NULL or if they are equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
const dfield_t* field1, /*!< in: field */
- const dfield_t* field2);/*!< in: field */
+ const dfield_t* field2, /*!< in: field */
+ ulint len) /*!< in: maximum prefix to compare,
+ or 0 to compare the whole field length */
+ __attribute__((nonnull, warn_unused_result));
/*********************************************************************//**
Tests if dfield data length and content is equal to the given.
@return TRUE if equal */
diff --git a/storage/innobase/include/data0data.ic b/storage/innobase/include/data0data.ic
index 2e3adf4b707..5c0f8039c80 100644
--- a/storage/innobase/include/data0data.ic
+++ b/storage/innobase/include/data0data.ic
@@ -229,20 +229,30 @@ dfield_dup(
}
/*********************************************************************//**
-Tests if data length and content is equal for two dfields.
-@return TRUE if equal */
+Tests if two data fields are equal.
+If len==0, tests the data length and content for equality.
+If len>0, tests the first len bytes of the content for equality.
+@return TRUE if both fields are NULL or if they are equal */
UNIV_INLINE
ibool
dfield_datas_are_binary_equal(
/*==========================*/
const dfield_t* field1, /*!< in: field */
- const dfield_t* field2) /*!< in: field */
+ const dfield_t* field2, /*!< in: field */
+ ulint len) /*!< in: maximum prefix to compare,
+ or 0 to compare the whole field length */
{
- ulint len;
+ ulint len2 = len;
- len = field1->len;
+ if (field1->len == UNIV_SQL_NULL || len == 0 || field1->len < len) {
+ len = field1->len;
+ }
+
+ if (field2->len == UNIV_SQL_NULL || len2 == 0 || field2->len < len2) {
+ len2 = field2->len;
+ }
- return(len == field2->len
+ return(len == len2
&& (len == UNIV_SQL_NULL
|| !memcmp(field1->data, field2->data, len)));
}
diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h
index d448e57e395..7526e4dc8dc 100644
--- a/storage/innobase/include/dict0mem.h
+++ b/storage/innobase/include/dict0mem.h
@@ -238,6 +238,26 @@ dict_foreign_t*
dict_mem_foreign_create(void);
/*=========================*/
+/**********************************************************************//**
+Sets the foreign_table_name_lookup pointer based on the value of
+srv_lower_case_table_names. */
+UNIV_INTERN
+void
+dict_mem_foreign_table_name_lookup_set(
+/*===================================*/
+ dict_foreign_t* foreign, /*!< in/out: foreign struct */
+ ibool do_alloc); /*!< in: is an alloc needed */
+
+/**********************************************************************//**
+Sets the reference_table_name_lookup pointer based on the value of
+srv_lower_case_table_names. */
+UNIV_INTERN
+void
+dict_mem_referenced_table_name_lookup_set(
+/*======================================*/
+ dict_foreign_t* foreign, /*!< in/out: foreign struct */
+ ibool do_alloc); /*!< in: is an alloc needed */
+
/** Data structure for a column in a table */
struct dict_col_struct{
/*----------------------*/
@@ -393,10 +413,14 @@ struct dict_foreign_struct{
unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
or DICT_FOREIGN_ON_DELETE_SET_NULL */
char* foreign_table_name;/*!< foreign table name */
+ char* foreign_table_name_lookup;
+ /*!< foreign table name used for dict lookup */
dict_table_t* foreign_table; /*!< table where the foreign key is */
const char** foreign_col_names;/*!< names of the columns in the
foreign key */
char* referenced_table_name;/*!< referenced table name */
+ char* referenced_table_name_lookup;
+ /*!< referenced table name for dict lookup*/
dict_table_t* referenced_table;/*!< table where the referenced key
is */
const char** referenced_col_names;/*!< names of the referenced
diff --git a/storage/innobase/include/ibuf0ibuf.h b/storage/innobase/include/ibuf0ibuf.h
index 66b06575b0d..464571d1ff8 100644
--- a/storage/innobase/include/ibuf0ibuf.h
+++ b/storage/innobase/include/ibuf0ibuf.h
@@ -253,15 +253,44 @@ Must not be called when recv_no_ibuf_operations==TRUE.
@return TRUE if level 2 or level 3 page */
UNIV_INTERN
ibool
-ibuf_page(
-/*======*/
- ulint space, /*!< in: space id */
- ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
- ulint page_no,/*!< in: page number */
- mtr_t* mtr); /*!< in: mtr which will contain an x-latch to the
- bitmap page if the page is not one of the fixed
- address ibuf pages, or NULL, in which case a new
- transaction is created. */
+ibuf_page_low(
+/*==========*/
+ ulint space, /*!< in: space id */
+ ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
+ ulint page_no,/*!< in: page number */
+#ifdef UNIV_DEBUG
+ ibool x_latch,/*!< in: FALSE if relaxed check
+ (avoid latching the bitmap page) */
+#endif /* UNIV_DEBUG */
+ const char* file, /*!< in: file name */
+ ulint line, /*!< in: line where called */
+ mtr_t* mtr) /*!< in: mtr which will contain an
+ x-latch to the bitmap page if the page
+ is not one of the fixed address ibuf
+ pages, or NULL, in which case a new
+ transaction is created. */
+ __attribute__((warn_unused_result));
+#ifdef UNIV_DEBUG
+/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of
+pages. Must not be called when recv_no_ibuf_operations==TRUE.
+@param space tablespace identifier
+@param zip_size compressed page size in bytes, or 0
+@param page_no page number
+@param mtr mini-transaction or NULL
+@return TRUE if level 2 or level 3 page */
+# define ibuf_page(space, zip_size, page_no, mtr) \
+ ibuf_page_low(space, zip_size, page_no, TRUE, __FILE__, __LINE__, mtr)
+#else /* UVIV_DEBUG */
+/** Checks if a page is a level 2 or 3 page in the ibuf hierarchy of
+pages. Must not be called when recv_no_ibuf_operations==TRUE.
+@param space tablespace identifier
+@param zip_size compressed page size in bytes, or 0
+@param page_no page number
+@param mtr mini-transaction or NULL
+@return TRUE if level 2 or level 3 page */
+# define ibuf_page(space, zip_size, page_no, mtr) \
+ ibuf_page_low(space, zip_size, page_no, __FILE__, __LINE__, mtr)
+#endif /* UVIV_DEBUG */
/***********************************************************************//**
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
diff --git a/storage/innobase/include/mem0mem.ic b/storage/innobase/include/mem0mem.ic
index cbce2edc661..d214c3fe6c9 100644
--- a/storage/innobase/include/mem0mem.ic
+++ b/storage/innobase/include/mem0mem.ic
@@ -350,27 +350,27 @@ mem_heap_get_top(
ulint n) /*!< in: size of the topmost element */
{
mem_block_t* block;
- void* buf;
+ byte* buf;
ut_ad(mem_heap_check(heap));
block = UT_LIST_GET_LAST(heap->base);
- buf = (byte*)block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n);
+ buf = (byte*) block + mem_block_get_free(block) - MEM_SPACE_NEEDED(n);
#ifdef UNIV_MEM_DEBUG
- ut_ad(mem_block_get_start(block) <=(ulint)((byte*)buf - (byte*)block));
+ ut_ad(mem_block_get_start(block) <= (ulint) (buf - (byte*) block));
/* In the debug version, advance buf to point at the storage which
was given to the caller in the allocation*/
- buf = (byte*)buf + MEM_FIELD_HEADER_SIZE;
+ buf += MEM_FIELD_HEADER_SIZE;
/* Check that the field lengths agree */
- ut_ad(n == (ulint)mem_field_header_get_len(buf));
+ ut_ad(n == mem_field_header_get_len(buf));
#endif
- return(buf);
+ return((void*) buf);
}
/*****************************************************************//**
diff --git a/storage/innobase/include/mtr0mtr.ic b/storage/innobase/include/mtr0mtr.ic
index fd72b3b75e6..9baf2ae1d48 100644
--- a/storage/innobase/include/mtr0mtr.ic
+++ b/storage/innobase/include/mtr0mtr.ic
@@ -161,7 +161,7 @@ mtr_memo_contains(
while (offset > 0) {
offset -= sizeof(mtr_memo_slot_t);
- slot = dyn_array_get_element(memo, offset);
+ slot = (mtr_memo_slot_t*) dyn_array_get_element(memo, offset);
if ((object == slot->object) && (type == slot->type)) {
diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
index 6d95b280330..fb13120a481 100644
--- a/storage/innobase/include/os0file.h
+++ b/storage/innobase/include/os0file.h
@@ -373,6 +373,7 @@ typedef HANDLE os_file_dir_t; /*!< directory stream */
typedef DIR* os_file_dir_t; /*!< directory stream */
#endif
+#ifdef __WIN__
/***********************************************************************//**
Gets the operating system version. Currently works only on Windows.
@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA,
@@ -381,6 +382,7 @@ UNIV_INTERN
ulint
os_get_os_version(void);
/*===================*/
+#endif /* __WIN__ */
#ifndef UNIV_HOTBACKUP
/****************************************************************//**
Creates the seek mutexes used in positioned reads and writes. */
diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h
index 051beb09277..9c2e003c609 100644
--- a/storage/innobase/include/row0upd.h
+++ b/storage/innobase/include/row0upd.h
@@ -286,10 +286,13 @@ row_upd_changes_ord_field_binary(
row and the data values in update are not
known when this function is called, e.g., at
compile time */
+ const row_ext_t*ext, /*!< NULL, or prefixes of the externally
+ stored columns in the old row */
dict_index_t* index, /*!< in: index of the record */
- const upd_t* update);/*!< in: update vector for the row; NOTE: the
+ const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
+ __attribute__((nonnull(3,4), warn_unused_result));
/***********************************************************//**
Checks if an update vector changes an ordering field of an index record.
This function is fast if the update vector is short or the number of ordering
@@ -462,11 +465,16 @@ struct upd_node_struct{
#define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be
inserted, old record is already delete
marked */
-#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered
+#define UPD_NODE_INSERT_BLOB 4 /* clustered index record should be
+ inserted, old record is already
+ delete-marked; non-updated BLOBs
+ should be inherited by the new record
+ and disowned by the old record */
+#define UPD_NODE_UPDATE_ALL_SEC 5 /* an ordering field of the clustered
index record was changed, or this is
a delete operation: should update
all the secondary index records */
-#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be
+#define UPD_NODE_UPDATE_SOME_SEC 6 /* secondary index entries should be
looked at and updated if an ordering
field changed */
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 98b07f5e893..612ff4c6e54 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -71,8 +71,8 @@ at a time */
#define SRV_AUTO_EXTEND_INCREMENT \
(srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
-/* This is set to TRUE if the MySQL user has set it in MySQL */
-extern ibool srv_lower_case_table_names;
+/* This is set to the MySQL server value for this variable. */
+extern uint srv_lower_case_table_names;
/* Mutex for locking srv_monitor_file */
extern mutex_t srv_monitor_file_mutex;
@@ -476,6 +476,14 @@ enum srv_thread_type
srv_get_thread_type(void);
/*=====================*/
/*********************************************************************//**
+Check whether thread type has reserved a slot.
+@return slot number or UNDEFINED if not found*/
+UNIV_INTERN
+ulint
+srv_thread_has_reserved_slot(
+/*=========================*/
+ enum srv_thread_type type); /*!< in: thread type to check */
+/*********************************************************************//**
Sets the info describing an i/o thread current state. */
UNIV_INTERN
void
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index 70471186f6d..5988fdfb382 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -122,6 +122,7 @@ extern mysql_pfs_key_t checkpoint_lock_key;
extern mysql_pfs_key_t trx_i_s_cache_lock_key;
extern mysql_pfs_key_t trx_purge_latch_key;
extern mysql_pfs_key_t index_tree_rw_lock_key;
+extern mysql_pfs_key_t dict_table_stats_latch_key;
#endif /* UNIV_PFS_RWLOCK */
diff --git a/storage/innobase/include/trx0i_s.h b/storage/innobase/include/trx0i_s.h
index 8f8b7367fb0..73896a3cb76 100644
--- a/storage/innobase/include/trx0i_s.h
+++ b/storage/innobase/include/trx0i_s.h
@@ -140,6 +140,9 @@ struct i_s_trx_row_struct {
ulint trx_mysql_thread_id; /*!< thd_get_thread_id() */
const char* trx_query; /*!< MySQL statement being
executed in the transaction */
+ struct charset_info_st* trx_query_cs;
+ /*!< charset encode the MySQL
+ statement */
const char* trx_operation_state; /*!< trx_struct::op_info */
ulint trx_tables_in_use;/*!< n_mysql_tables_in_use in
trx_struct */
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 9cf823c2ff3..4470d221da9 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -44,9 +44,14 @@ Created 1/20/1994 Heikki Tuuri
#include "hb_univ.i"
#endif /* UNIV_HOTBACKUP */
+/* aux macros to convert M into "123" (string) if M is defined like
+#define M 123 */
+#define _IB_TO_STR(s) #s
+#define IB_TO_STR(s) _IB_TO_STR(s)
+
#define INNODB_VERSION_MAJOR 1
#define INNODB_VERSION_MINOR 1
-#define INNODB_VERSION_BUGFIX 4
+#define INNODB_VERSION_BUGFIX 5
/* The following is the InnoDB version as shown in
SELECT plugin_version FROM information_schema.plugins;
@@ -57,16 +62,14 @@ component, i.e. we show M.N.P as M.N */
#define INNODB_VERSION_SHORT \
(INNODB_VERSION_MAJOR << 8 | INNODB_VERSION_MINOR)
-/* auxiliary macros to help creating the version as string */
-#define __INNODB_VERSION(a, b, c) (#a "." #b "." #c)
-#define _INNODB_VERSION(a, b, c) __INNODB_VERSION(a, b, c)
-
#define INNODB_VERSION_STR \
- _INNODB_VERSION(INNODB_VERSION_MAJOR, \
- INNODB_VERSION_MINOR, \
- INNODB_VERSION_BUGFIX)
+ IB_TO_STR(INNODB_VERSION_MAJOR) "." \
+ IB_TO_STR(INNODB_VERSION_MINOR) "." \
+ IB_TO_STR(INNODB_VERSION_BUGFIX)
-#define REFMAN "http://dev.mysql.com/doc/refman/5.1/en/"
+#define REFMAN "http://dev.mysql.com/doc/refman/" \
+ IB_TO_STR(MYSQL_MAJOR_VERSION) "." \
+ IB_TO_STR(MYSQL_MINOR_VERSION) "/en/"
#ifdef MYSQL_DYNAMIC_PLUGIN
/* In the dynamic plugin, redefine some externally visible symbols
@@ -250,7 +253,7 @@ easy way to get it to work. See http://bugs.mysql.com/bug.php?id=52263. */
# define UNIV_INTERN
#endif
-#if (!defined(UNIV_DEBUG) && !defined(UNIV_MUST_NOT_INLINE))
+#ifndef UNIV_MUST_NOT_INLINE
/* Definition for inline version */
#ifdef __WIN__
diff --git a/storage/innobase/include/ut0ut.h b/storage/innobase/include/ut0ut.h
index dd59b3eba46..cd5c7ca99f1 100644
--- a/storage/innobase/include/ut0ut.h
+++ b/storage/innobase/include/ut0ut.h
@@ -55,24 +55,24 @@ Created 1/20/1994 Heikki Tuuri
typedef time_t ib_time_t;
#ifndef UNIV_HOTBACKUP
-#if defined(HAVE_IB_PAUSE_INSTRUCTION)
-# ifdef WIN32
- /* In the Win32 API, the x86 PAUSE instruction is executed by calling
- the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
- independent way by using YieldProcessor.*/
-# define UT_RELAX_CPU() YieldProcessor()
-# else
- /* According to the gcc info page, asm volatile means that the
- instruction has important side-effects and must not be removed.
- Also asm volatile may trigger a memory barrier (spilling all registers
- to memory). */
-# define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
-# endif
+#if defined(HAVE_PAUSE_INSTRUCTION)
+ /* According to the gcc info page, asm volatile means that the
+ instruction has important side-effects and must not be removed.
+ Also asm volatile may trigger a memory barrier (spilling all registers
+ to memory). */
+# define UT_RELAX_CPU() __asm__ __volatile__ ("pause")
+#elif defined(HAVE_FAKE_PAUSE_INSTRUCTION)
+# define UT_RELAX_CPU() __asm__ __volatile__ ("rep; nop")
#elif defined(HAVE_ATOMIC_BUILTINS)
# define UT_RELAX_CPU() do { \
volatile lint volatile_var; \
os_compare_and_swap_lint(&volatile_var, 0, 1); \
} while (0)
+#elif defined(HAVE_WINDOWS_ATOMICS)
+ /* In the Win32 API, the x86 PAUSE instruction is executed by calling
+ the YieldProcessor macro defined in WinNT.h. It is a CPU architecture-
+ independent way by using YieldProcessor. */
+# define UT_RELAX_CPU() YieldProcessor()
#else
# define UT_RELAX_CPU() ((void)0) /* avoid warning for an empty statement */
#endif
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index 5d5caf1b48a..f9e0fecb6c6 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -2199,7 +2199,7 @@ recv_report_corrupt_log(
"InnoDB: far enough in recovery! Please run CHECK TABLE\n"
"InnoDB: on your InnoDB tables to check that they are ok!\n"
"InnoDB: If mysqld crashes after this recovery, look at\n"
- "InnoDB: " REFMAN "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
fflush(stderr);
diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
index 93d2f72746d..74dbac3bc96 100644
--- a/storage/innobase/os/os0file.c
+++ b/storage/innobase/os/os0file.c
@@ -302,6 +302,36 @@ UNIV_INTERN ulint os_n_pending_writes = 0;
/** Number of pending read operations */
UNIV_INTERN ulint os_n_pending_reads = 0;
+#ifdef UNIV_DEBUG
+/**********************************************************************//**
+Validates the consistency the aio system some of the time.
+@return TRUE if ok or the check was skipped */
+UNIV_INTERN
+ibool
+os_aio_validate_skip(void)
+/*======================*/
+{
+/** Try os_aio_validate() every this many times */
+# define OS_AIO_VALIDATE_SKIP 13
+
+ /** The os_aio_validate() call skip counter.
+ Use a signed type because of the race condition below. */
+ static int os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
+
+ /* There is a race condition below, but it does not matter,
+ because this call is only for heuristic purposes. We want to
+ reduce the call frequency of the costly os_aio_validate()
+ check in debug builds. */
+ if (--os_aio_validate_count > 0) {
+ return(TRUE);
+ }
+
+ os_aio_validate_count = OS_AIO_VALIDATE_SKIP;
+ return(os_aio_validate());
+}
+#endif /* UNIV_DEBUG */
+
+#ifdef __WIN__
/***********************************************************************//**
Gets the operating system version. Currently works only on Windows.
@return OS_WIN95, OS_WIN31, OS_WINNT, OS_WIN2000, OS_WINXP, OS_WINVISTA,
@@ -311,7 +341,6 @@ ulint
os_get_os_version(void)
/*===================*/
{
-#ifdef __WIN__
OSVERSIONINFO os_info;
os_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
@@ -340,12 +369,8 @@ os_get_os_version(void)
ut_error;
return(0);
}
-#else
- ut_error;
-
- return(0);
-#endif
}
+#endif /* __WIN__ */
/***********************************************************************//**
Retrieves the last error number if an error occurs in a file io function.
@@ -4008,7 +4033,7 @@ os_aio_func(
ut_ad(n > 0);
ut_ad(n % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_ad(offset % OS_FILE_LOG_BLOCK_SIZE == 0);
- ut_ad(os_aio_validate());
+ ut_ad(os_aio_validate_skip());
#ifdef WIN_ASYNC_IO
ut_ad((n & 0xFFFFFFFFUL) == n);
#endif
@@ -4210,7 +4235,7 @@ os_aio_windows_handle(
/* NOTE! We only access constant fields in os_aio_array. Therefore
we do not have to acquire the protecting mutex yet */
- ut_ad(os_aio_validate());
+ ut_ad(os_aio_validate_skip());
ut_ad(segment < array->n_segments);
n = array->n_slots / array->n_segments;
@@ -4630,7 +4655,7 @@ restart:
srv_set_io_thread_op_info(global_segment,
"looking for i/o requests (a)");
- ut_ad(os_aio_validate());
+ ut_ad(os_aio_validate_skip());
ut_ad(segment < array->n_segments);
n = array->n_slots / array->n_segments;
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index 09ae80adff4..dbfba358f9f 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -1525,7 +1525,7 @@ row_ins_check_foreign_constraints(
if (foreign->foreign_index == index) {
if (foreign->referenced_table == NULL) {
- dict_table_get(foreign->referenced_table_name,
+ dict_table_get(foreign->referenced_table_name_lookup,
FALSE);
}
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 709750fc4e7..63f30276df6 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -632,7 +632,7 @@ handle_new_error:
"InnoDB: If the mysqld server crashes"
" after the startup or when\n"
"InnoDB: you dump the tables, look at\n"
- "InnoDB: " REFMAN "forcing-recovery.html"
+ "InnoDB: " REFMAN "forcing-innodb-recovery.html"
" for help.\n", stderr);
break;
case DB_FOREIGN_EXCEED_MAX_CASCADE:
@@ -3163,7 +3163,7 @@ check_next_foreign:
if (foreign && trx->check_foreigns
&& !(drop_db && dict_tables_have_same_db(
- name, foreign->foreign_table_name))) {
+ name, foreign->foreign_table_name_lookup))) {
FILE* ef = dict_foreign_err_file;
/* We only allow dropping a referenced table if
diff --git a/storage/innobase/row/row0purge.c b/storage/innobase/row/row0purge.c
index 031b5258e98..08abc8a3e59 100644
--- a/storage/innobase/row/row0purge.c
+++ b/storage/innobase/row/row0purge.c
@@ -515,7 +515,7 @@ row_purge_upd_exist_or_extern(
while (node->index != NULL) {
index = node->index;
- if (row_upd_changes_ord_field_binary(NULL, node->index,
+ if (row_upd_changes_ord_field_binary(NULL, NULL, node->index,
node->update)) {
/* Build the older version of the index entry */
entry = row_build_index_entry(node->row, NULL,
diff --git a/storage/innobase/row/row0umod.c b/storage/innobase/row/row0umod.c
index aef653b3150..0d4c42b958c 100644
--- a/storage/innobase/row/row0umod.c
+++ b/storage/innobase/row/row0umod.c
@@ -693,19 +693,18 @@ row_undo_mod_upd_exist_sec(
while (node->index != NULL) {
index = node->index;
- if (row_upd_changes_ord_field_binary(node->row, node->index,
- node->update)) {
+ if (row_upd_changes_ord_field_binary(
+ node->row, node->ext, node->index, node->update)) {
/* Build the newest version of the index entry */
entry = row_build_index_entry(node->row, node->ext,
index, heap);
if (UNIV_UNLIKELY(!entry)) {
/* The server must have crashed in
- row_upd_clust_rec_by_insert(), in
- row_ins_index_entry_low() before
- btr_store_big_rec_extern_fields()
- has written the externally stored columns
- (BLOBs) of the new clustered index entry. */
+ row_upd_clust_rec_by_insert() before
+ the updated externally stored columns (BLOBs)
+ of the new clustered index entry were
+ written. */
/* The table must be in DYNAMIC or COMPRESSED
format. REDUNDANT and COMPACT formats
diff --git a/storage/innobase/row/row0upd.c b/storage/innobase/row/row0upd.c
index 81750938f58..03ed40c6647 100644
--- a/storage/innobase/row/row0upd.c
+++ b/storage/innobase/row/row0upd.c
@@ -238,7 +238,7 @@ row_upd_check_references_constraints(
foreign->n_fields))) {
if (foreign->foreign_table == NULL) {
- dict_table_get(foreign->foreign_table_name,
+ dict_table_get(foreign->foreign_table_name_lookup,
FALSE);
}
@@ -1198,20 +1198,21 @@ row_upd_changes_ord_field_binary(
row and the data values in update are not
known when this function is called, e.g., at
compile time */
+ const row_ext_t*ext, /*!< NULL, or prefixes of the externally
+ stored columns in the old row */
dict_index_t* index, /*!< in: index of the record */
const upd_t* update) /*!< in: update vector for the row; NOTE: the
field numbers in this MUST be clustered index
positions! */
{
- ulint n_unique;
- ulint n_upd_fields;
- ulint i, j;
- dict_index_t* clust_index;
+ ulint n_unique;
+ ulint i;
+ const dict_index_t* clust_index;
- ut_ad(update && index);
+ ut_ad(update);
+ ut_ad(index);
n_unique = dict_index_get_n_unique(index);
- n_upd_fields = upd_get_n_fields(update);
clust_index = dict_table_get_first_index(index->table);
@@ -1219,33 +1220,72 @@ row_upd_changes_ord_field_binary(
const dict_field_t* ind_field;
const dict_col_t* col;
- ulint col_pos;
ulint col_no;
+ const upd_field_t* upd_field;
+ const dfield_t* dfield;
+ dfield_t dfield_ext;
+ ulint dfield_len;
+ const byte* buf;
ind_field = dict_index_get_nth_field(index, i);
col = dict_field_get_col(ind_field);
- col_pos = dict_col_get_clust_pos(col, clust_index);
col_no = dict_col_get_no(col);
- for (j = 0; j < n_upd_fields; j++) {
+ upd_field = upd_get_field_by_field_no(
+ update, dict_col_get_clust_pos(col, clust_index));
- const upd_field_t* upd_field
- = upd_get_nth_field(update, j);
+ if (upd_field == NULL) {
+ continue;
+ }
- /* Note that if the index field is a column prefix
- then it may be that row does not contain an externally
- stored part of the column value, and we cannot compare
- the datas */
+ if (row == NULL) {
+ ut_ad(ext == NULL);
+ return(TRUE);
+ }
- if (col_pos == upd_field->field_no
- && (row == NULL
- || ind_field->prefix_len > 0
- || !dfield_datas_are_binary_equal(
- dtuple_get_nth_field(row, col_no),
- &(upd_field->new_val)))) {
+ dfield = dtuple_get_nth_field(row, col_no);
- return(TRUE);
+ /* This treatment of column prefix indexes is loosely
+ based on row_build_index_entry(). */
+
+ if (UNIV_LIKELY(ind_field->prefix_len == 0)
+ || dfield_is_null(dfield)) {
+ /* do nothing special */
+ } else if (UNIV_LIKELY_NULL(ext)) {
+ /* See if the column is stored externally. */
+ buf = row_ext_lookup(ext, col_no, &dfield_len);
+
+ ut_ad(col->ord_part);
+
+ if (UNIV_LIKELY_NULL(buf)) {
+ if (UNIV_UNLIKELY(buf == field_ref_zero)) {
+ /* This should never happen, but
+ we try to fail safe here. */
+ ut_ad(0);
+ return(TRUE);
+ }
+
+ goto copy_dfield;
}
+ } else if (dfield_is_ext(dfield)) {
+ dfield_len = dfield_get_len(dfield);
+ ut_a(dfield_len > BTR_EXTERN_FIELD_REF_SIZE);
+ dfield_len -= BTR_EXTERN_FIELD_REF_SIZE;
+ ut_a(dict_index_is_clust(index)
+ || ind_field->prefix_len <= dfield_len);
+ buf = dfield_get_data(dfield);
+copy_dfield:
+ ut_a(dfield_len > 0);
+ dfield_copy(&dfield_ext, dfield);
+ dfield_set_data(&dfield_ext, buf, dfield_len);
+ dfield = &dfield_ext;
+ }
+
+ if (!dfield_datas_are_binary_equal(
+ dfield, &upd_field->new_val,
+ ind_field->prefix_len)) {
+
+ return(TRUE);
}
}
@@ -1329,7 +1369,7 @@ row_upd_changes_first_fields_binary(
if (col_pos == upd_field->field_no
&& !dfield_datas_are_binary_equal(
dtuple_get_nth_field(entry, i),
- &(upd_field->new_val))) {
+ &upd_field->new_val, 0)) {
return(TRUE);
}
@@ -1596,14 +1636,99 @@ row_upd_sec_step(
ut_ad(!dict_index_is_clust(node->index));
if (node->state == UPD_NODE_UPDATE_ALL_SEC
- || row_upd_changes_ord_field_binary(node->row, node->index,
- node->update)) {
+ || row_upd_changes_ord_field_binary(node->row, node->ext,
+ node->index, node->update)) {
return(row_upd_sec_index_entry(node, thr));
}
return(DB_SUCCESS);
}
+#ifdef UNIV_DEBUG
+# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \
+ row_upd_clust_rec_by_insert_inherit_func(rec,offsets,entry,update)
+#else /* UNIV_DEBUG */
+# define row_upd_clust_rec_by_insert_inherit(rec,offsets,entry,update) \
+ row_upd_clust_rec_by_insert_inherit_func(entry,update)
+#endif /* UNIV_DEBUG */
+/*******************************************************************//**
+Mark non-updated off-page columns inherited when the primary key is
+updated. We must mark them as inherited in entry, so that they are not
+freed in a rollback. A limited version of this function used to be
+called btr_cur_mark_dtuple_inherited_extern().
+@return TRUE if any columns were inherited */
+static __attribute__((warn_unused_result))
+ibool
+row_upd_clust_rec_by_insert_inherit_func(
+/*=====================================*/
+#ifdef UNIV_DEBUG
+ const rec_t* rec, /*!< in: old record, or NULL */
+ const ulint* offsets,/*!< in: rec_get_offsets(rec), or NULL */
+#endif /* UNIV_DEBUG */
+ dtuple_t* entry, /*!< in/out: updated entry to be
+ inserted into the clustered index */
+ const upd_t* update) /*!< in: update vector */
+{
+ ibool inherit = FALSE;
+ ulint i;
+
+ ut_ad(!rec == !offsets);
+ ut_ad(!rec || rec_offs_any_extern(offsets));
+
+ for (i = 0; i < dtuple_get_n_fields(entry); i++) {
+ dfield_t* dfield = dtuple_get_nth_field(entry, i);
+ byte* data;
+ ulint len;
+
+ ut_ad(!offsets
+ || !rec_offs_nth_extern(offsets, i)
+ == !dfield_is_ext(dfield)
+ || upd_get_field_by_field_no(update, i));
+ if (!dfield_is_ext(dfield)
+ || upd_get_field_by_field_no(update, i)) {
+ continue;
+ }
+
+#ifdef UNIV_DEBUG
+ if (UNIV_LIKELY(rec != NULL)) {
+ const byte* rec_data
+ = rec_get_nth_field(rec, offsets, i, &len);
+ ut_ad(len == dfield_get_len(dfield));
+ ut_ad(len != UNIV_SQL_NULL);
+ ut_ad(len >= BTR_EXTERN_FIELD_REF_SIZE);
+
+ rec_data += len - BTR_EXTERN_FIELD_REF_SIZE;
+
+ /* The pointer must not be zero. */
+ ut_ad(memcmp(rec_data, field_ref_zero,
+ BTR_EXTERN_FIELD_REF_SIZE));
+ /* The BLOB must be owned. */
+ ut_ad(!(rec_data[BTR_EXTERN_LEN]
+ & BTR_EXTERN_OWNER_FLAG));
+ }
+#endif /* UNIV_DEBUG */
+
+ len = dfield_get_len(dfield);
+ ut_a(len != UNIV_SQL_NULL);
+ ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
+ data = dfield_get_data(dfield);
+ data += len - BTR_EXTERN_FIELD_REF_SIZE;
+ /* The pointer must not be zero. */
+ ut_a(memcmp(data, field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE));
+ /* The BLOB must be owned. */
+ ut_a(!(data[BTR_EXTERN_LEN] & BTR_EXTERN_OWNER_FLAG));
+
+ data[BTR_EXTERN_LEN] |= BTR_EXTERN_INHERITED_FLAG;
+ /* The BTR_EXTERN_INHERITED_FLAG only matters in
+ rollback. Purge will always free the extern fields of
+ a delete-marked row. */
+
+ inherit = TRUE;
+ }
+
+ return(inherit);
+}
+
/***********************************************************//**
Marks the clustered index record deleted and inserts the updated version
of the record to the index. This function should be used when the ordering
@@ -1622,14 +1747,16 @@ row_upd_clust_rec_by_insert(
a foreign key constraint */
mtr_t* mtr) /*!< in/out: mtr; gets committed here */
{
- mem_heap_t* heap = NULL;
+ mem_heap_t* heap;
btr_pcur_t* pcur;
btr_cur_t* btr_cur;
trx_t* trx;
dict_table_t* table;
dtuple_t* entry;
ulint err;
- ibool change_ownership = FALSE;
+ ibool change_ownership = FALSE;
+ rec_t* rec;
+ ulint* offsets = NULL;
ut_ad(node);
ut_ad(dict_index_is_clust(index));
@@ -1639,34 +1766,64 @@ row_upd_clust_rec_by_insert(
pcur = node->pcur;
btr_cur = btr_pcur_get_btr_cur(pcur);
- if (node->state != UPD_NODE_INSERT_CLUSTERED) {
- rec_t* rec;
- dict_index_t* index;
- ulint offsets_[REC_OFFS_NORMAL_SIZE];
- ulint* offsets;
- rec_offs_init(offsets_);
+ heap = mem_heap_create(1000);
+
+ entry = row_build_index_entry(node->upd_row, node->upd_ext,
+ index, heap);
+ ut_a(entry);
- err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
- btr_cur, TRUE, thr, mtr);
+ row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);
+
+ switch (node->state) {
+ default:
+ ut_error;
+ case UPD_NODE_INSERT_BLOB:
+ /* A lock wait occurred in row_ins_index_entry() in
+ the previous invocation of this function. Mark the
+ off-page columns in the entry inherited. */
+
+ change_ownership = row_upd_clust_rec_by_insert_inherit(
+ NULL, NULL, entry, node->update);
+ ut_a(change_ownership);
+ /* fall through */
+ case UPD_NODE_INSERT_CLUSTERED:
+ /* A lock wait occurred in row_ins_index_entry() in
+ the previous invocation of this function. */
+ break;
+ case UPD_NODE_UPDATE_CLUSTERED:
+ /* This is the first invocation of the function where
+ we update the primary key. Delete-mark the old record
+ in the clustered index and prepare to insert a new entry. */
+ rec = btr_cur_get_rec(btr_cur);
+ offsets = rec_get_offsets(rec, index, NULL,
+ ULINT_UNDEFINED, &heap);
+ ut_ad(page_rec_is_user_rec(rec));
+
+ err = btr_cur_del_mark_set_clust_rec(
+ BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur),
+ rec, index, offsets, TRUE, thr, mtr);
if (err != DB_SUCCESS) {
+err_exit:
mtr_commit(mtr);
+ mem_heap_free(heap);
return(err);
}
- /* Mark as not-owned the externally stored fields which the new
- row inherits from the delete marked record: purge should not
- free those externally stored fields even if the delete marked
- record is removed from the index tree, or updated. */
+ /* If the the new row inherits externally stored
+ fields (off-page columns a.k.a. BLOBs) from the
+ delete-marked old record, mark them disowned by the
+ old record and owned by the new entry. */
- rec = btr_cur_get_rec(btr_cur);
- index = dict_table_get_first_index(table);
- offsets = rec_get_offsets(rec, index, offsets_,
- ULINT_UNDEFINED, &heap);
- change_ownership = btr_cur_mark_extern_inherited_fields(
- btr_cur_get_page_zip(btr_cur),
- rec, index, offsets, node->update, mtr);
- if (referenced) {
+ if (rec_offs_any_extern(offsets)) {
+ change_ownership = row_upd_clust_rec_by_insert_inherit(
+ rec, offsets, entry, node->update);
+
+ if (change_ownership) {
+ btr_pcur_store_position(pcur, mtr);
+ }
+ }
+ if (referenced) {
/* NOTE that the following call loses
the position of pcur ! */
@@ -1674,48 +1831,49 @@ row_upd_clust_rec_by_insert(
node, pcur, table, index, offsets, thr, mtr);
if (err != DB_SUCCESS) {
-
- mtr_commit(mtr);
-
- if (UNIV_LIKELY_NULL(heap)) {
- mem_heap_free(heap);
- }
-
- return(err);
+ goto err_exit;
}
}
}
mtr_commit(mtr);
- if (!heap) {
- heap = mem_heap_create(500);
- }
- node->state = UPD_NODE_INSERT_CLUSTERED;
+ err = row_ins_index_entry(index, entry,
+ node->upd_ext ? node->upd_ext->n_ext : 0,
+ TRUE, thr);
+ node->state = change_ownership
+ ? UPD_NODE_INSERT_BLOB
+ : UPD_NODE_INSERT_CLUSTERED;
- entry = row_build_index_entry(node->upd_row, node->upd_ext,
- index, heap);
- ut_a(entry);
+ if (err == DB_SUCCESS && change_ownership) {
+ /* Mark the non-updated fields disowned by the old record. */
- row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);
+ /* NOTE: this transaction has an x-lock on the record
+ and therefore other transactions cannot modify the
+ record when we have no latch on the page. In addition,
+ we assume that other query threads of the same
+ transaction do not modify the record in the meantime.
+ Therefore we can assert that the restoration of the
+ cursor succeeds. */
- if (change_ownership) {
- /* If we return from a lock wait, for example, we may have
- extern fields marked as not-owned in entry (marked in the
- if-branch above). We must unmark them, take the ownership
- back. */
+ mtr_start(mtr);
+
+ if (!btr_pcur_restore_position(BTR_MODIFY_LEAF, pcur, mtr)) {
+ ut_error;
+ }
- btr_cur_unmark_dtuple_extern_fields(entry);
+ rec = btr_cur_get_rec(btr_cur);
+ offsets = rec_get_offsets(rec, index, offsets,
+ ULINT_UNDEFINED, &heap);
+ ut_ad(page_rec_is_user_rec(rec));
- /* We must mark non-updated extern fields in entry as
- inherited, so that a possible rollback will not free them. */
+ btr_cur_disown_inherited_fields(
+ btr_cur_get_page_zip(btr_cur),
+ rec, index, offsets, node->update, mtr);
- btr_cur_mark_dtuple_inherited_extern(entry, node->update);
+ mtr_commit(mtr);
}
- err = row_ins_index_entry(index, entry,
- node->upd_ext ? node->upd_ext->n_ext : 0,
- TRUE, thr);
mem_heap_free(heap);
return(err);
@@ -1860,8 +2018,9 @@ row_upd_del_mark_clust_rec(
/* Mark the clustered index record deleted; we do not have to check
locks, because we assume that we have an x-lock on the record */
- err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
- btr_cur, TRUE, thr, mtr);
+ err = btr_cur_del_mark_set_clust_rec(
+ BTR_NO_LOCKING_FLAG, btr_cur_get_block(btr_cur),
+ btr_cur_get_rec(btr_cur), index, offsets, TRUE, thr, mtr);
if (err == DB_SUCCESS && referenced) {
/* NOTE that the following call loses the position of pcur ! */
@@ -2006,7 +2165,8 @@ exit_func:
row_upd_store_row(node);
- if (row_upd_changes_ord_field_binary(node->row, index, node->update)) {
+ if (row_upd_changes_ord_field_binary(node->row, node->ext, index,
+ node->update)) {
/* Update causes an ordering field (ordering fields within
the B-tree) of the clustered index record to change: perform
@@ -2076,7 +2236,8 @@ row_upd(
}
if (node->state == UPD_NODE_UPDATE_CLUSTERED
- || node->state == UPD_NODE_INSERT_CLUSTERED) {
+ || node->state == UPD_NODE_INSERT_CLUSTERED
+ || node->state == UPD_NODE_INSERT_BLOB) {
log_free_check();
err = row_upd_clust_step(node, thr);
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 14fe7e57859..e19e75f27a5 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -87,9 +87,11 @@ Created 10/8/1995 Heikki Tuuri
#include "mysql/plugin.h"
#include "mysql/service_thd_wait.h"
-/* This is set to TRUE if the MySQL user has set it in MySQL; currently
-affects only FOREIGN KEY definition parsing */
-UNIV_INTERN ibool srv_lower_case_table_names = FALSE;
+/* This is set to the MySQL server value for this variable. It is only
+needed for FOREIGN KEY definition parsing since FOREIGN KEY names are not
+stored in the server metadata. The server stores and enforces it for
+regular database and table names.*/
+UNIV_INTERN uint srv_lower_case_table_names = 0;
/* The following counter is incremented whenever there is some user activity
in the server */
@@ -831,6 +833,7 @@ srv_table_reserve_slot(
ut_a(type > 0);
ut_a(type <= SRV_MASTER);
+ ut_ad(mutex_own(&kernel_mutex));
i = 0;
slot = srv_table_get_nth_slot(i);
@@ -980,6 +983,37 @@ srv_get_thread_type(void)
}
/*********************************************************************//**
+Check whether thread type has reserved a slot. Return the first slot that
+is found. This works because we currently have only 1 thread of each type.
+@return slot number or ULINT_UNDEFINED if not found*/
+UNIV_INTERN
+ulint
+srv_thread_has_reserved_slot(
+/*=========================*/
+ enum srv_thread_type type) /*!< in: thread type to check */
+{
+ ulint i;
+ ulint slot_no = ULINT_UNDEFINED;
+
+ mutex_enter(&kernel_mutex);
+
+ for (i = 0; i < OS_THREAD_MAX_N; i++) {
+ srv_slot_t* slot;
+
+ slot = srv_table_get_nth_slot(i);
+
+ if (slot->in_use && slot->type == type) {
+ slot_no = i;
+ break;
+ }
+ }
+
+ mutex_exit(&kernel_mutex);
+
+ return(slot_no);
+}
+
+/*********************************************************************//**
Initializes the server. */
UNIV_INTERN
void
@@ -2627,10 +2661,10 @@ srv_master_thread(
srv_main_thread_process_no = os_proc_get_number();
srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
- srv_table_reserve_slot(SRV_MASTER);
-
mutex_enter(&kernel_mutex);
+ srv_table_reserve_slot(SRV_MASTER);
+
srv_n_threads_active[SRV_MASTER]++;
mutex_exit(&kernel_mutex);
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index d7ea3d5d3da..acb448a1a67 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -1026,26 +1026,35 @@ innobase_start_or_create_for_mysql(void)
on Mac OS X 10.3 or later. */
struct utsname utsname;
if (uname(&utsname)) {
- fputs("InnoDB: cannot determine Mac OS X version!\n", stderr);
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: cannot determine Mac OS X version!\n", stderr);
} else {
srv_have_fullfsync = strcmp(utsname.release, "7.") >= 0;
}
if (!srv_have_fullfsync) {
- fputs("InnoDB: On Mac OS X, fsync() may be"
- " broken on internal drives,\n"
- "InnoDB: making transactions unsafe!\n", stderr);
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: On Mac OS X, fsync() may be "
+ "broken on internal drives,\n", stderr);
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: making transactions unsafe!\n", stderr);
}
# endif /* F_FULLFSYNC */
#endif /* HAVE_DARWIN_THREADS */
if (sizeof(ulint) != sizeof(void*)) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: size of InnoDB's ulint is %lu,"
- " but size of void* is %lu.\n"
- "InnoDB: The sizes should be the same"
- " so that on a 64-bit platform you can\n"
- "InnoDB: allocate more than 4 GB of memory.",
- (ulong)sizeof(ulint), (ulong)sizeof(void*));
+ " InnoDB: Error: size of InnoDB's ulint is %lu, "
+ "but size of void*\n", (ulong) sizeof(ulint));
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: is %lu. The sizes should be the same "
+ "so that on a 64-bit\n",
+ (ulong) sizeof(void*));
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: platforms you can allocate more than 4 GB "
+ "of memory.\n");
}
/* System tables are created in tablespace 0. Thus, we must
@@ -1054,53 +1063,68 @@ innobase_start_or_create_for_mysql(void)
innodb_file_per_table) until this function has returned. */
srv_file_per_table = FALSE;
#ifdef UNIV_DEBUG
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!\n");
+ " InnoDB: !!!!!!!! UNIV_DEBUG switched on !!!!!!!!!\n");
#endif
#ifdef UNIV_IBUF_DEBUG
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n"
+ " InnoDB: !!!!!!!! UNIV_IBUF_DEBUG switched on !!!!!!!!!\n");
# ifdef UNIV_IBUF_COUNT_DEBUG
- "InnoDB: !!!!!!!! UNIV_IBUF_COUNT_DEBUG switched on !!!!!!!!!\n"
- "InnoDB: Crash recovery will fail with UNIV_IBUF_COUNT_DEBUG\n"
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: !!!!!!!! UNIV_IBUF_COUNT_DEBUG switched on "
+ "!!!!!!!!!\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Crash recovery will fail with UNIV_IBUF_COUNT_DEBUG\n");
# endif
- );
#endif
#ifdef UNIV_SYNC_DEBUG
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n");
+ " InnoDB: !!!!!!!! UNIV_SYNC_DEBUG switched on !!!!!!!!!\n");
#endif
#ifdef UNIV_SEARCH_DEBUG
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
+ " InnoDB: !!!!!!!! UNIV_SEARCH_DEBUG switched on !!!!!!!!!\n");
#endif
#ifdef UNIV_LOG_LSN_DEBUG
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n");
+ " InnoDB: !!!!!!!! UNIV_LOG_LSN_DEBUG switched on !!!!!!!!!\n");
#endif /* UNIV_LOG_LSN_DEBUG */
#ifdef UNIV_MEM_DEBUG
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
+ " InnoDB: !!!!!!!! UNIV_MEM_DEBUG switched on !!!!!!!!!\n");
#endif
if (UNIV_LIKELY(srv_use_sys_malloc)) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: The InnoDB memory heap is disabled\n");
+ " InnoDB: The InnoDB memory heap is disabled\n");
}
- fputs("InnoDB: " IB_ATOMICS_STARTUP_MSG
- "\nInnoDB: Compressed tables use zlib " ZLIB_VERSION
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: " IB_ATOMICS_STARTUP_MSG "\n", stderr);
+
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Compressed tables use zlib " ZLIB_VERSION
#ifdef UNIV_ZIP_DEBUG
" with validation"
#endif /* UNIV_ZIP_DEBUG */
+ "\n" , stderr);
#ifdef UNIV_ZIP_COPY
- " and extra copying"
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: and extra copying\n", stderr);
#endif /* UNIV_ZIP_COPY */
- "\n" , stderr);
/* Since InnoDB does not currently clean up all its internal data
structures in MySQL Embedded Server Library server_end(), we
@@ -1108,13 +1132,17 @@ innobase_start_or_create_for_mysql(void)
second time during the process lifetime. */
if (srv_start_has_been_called) {
- fprintf(stderr,
- "InnoDB: Error: startup called second time"
- " during the process lifetime.\n"
- "InnoDB: In the MySQL Embedded Server Library"
- " you cannot call server_init()\n"
- "InnoDB: more than once during"
- " the process lifetime.\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Error: startup called second time "
+ "during the process\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: lifetime. In the MySQL Embedded "
+ "Server Library you\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: cannot call server_init() more "
+ "than once during the\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: process lifetime.\n");
}
srv_start_has_been_called = TRUE;
@@ -1158,7 +1186,7 @@ innobase_start_or_create_for_mysql(void)
if (srv_use_native_aio) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Using Linux native AIO\n");
+ " InnoDB: Using Linux native AIO\n");
}
#else
/* Currently native AIO is supported only on windows and linux
@@ -1203,8 +1231,9 @@ innobase_start_or_create_for_mysql(void)
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
#endif
} else {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Unrecognized value %s for"
+ " InnoDB: Unrecognized value %s for"
" innodb_flush_method\n",
srv_file_flush_method_str);
return(DB_ERROR);
@@ -1285,7 +1314,8 @@ innobase_start_or_create_for_mysql(void)
we'll emit a message telling the user that this parameter
is now deprecated. */
if (srv_n_file_io_threads != 4) {
- fprintf(stderr, "InnoDB: Warning:"
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Warning:"
" innodb_file_io_threads is deprecated."
" Please use innodb_read_io_threads and"
" innodb_write_io_threads instead\n");
@@ -1316,7 +1346,7 @@ innobase_start_or_create_for_mysql(void)
/* Print time to initialize the buffer pool */
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Initializing buffer pool, size =");
+ " InnoDB: Initializing buffer pool, size =");
if (srv_buf_pool_size >= 1024 * 1024 * 1024) {
fprintf(stderr,
@@ -1332,11 +1362,12 @@ innobase_start_or_create_for_mysql(void)
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: Completed initialization of buffer pool\n");
+ " InnoDB: Completed initialization of buffer pool\n");
if (err != DB_SUCCESS) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Fatal error: cannot allocate the memory"
+ " InnoDB: Fatal error: cannot allocate memory"
" for the buffer pool\n");
return(DB_ERROR);
@@ -1348,7 +1379,8 @@ innobase_start_or_create_for_mysql(void)
if (srv_buf_pool_size <= 5 * 1024 * 1024) {
- fprintf(stderr, "InnoDB: Warning: Small buffer pool size "
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Warning: Small buffer pool size "
"(%luM), the flst_validate() debug function "
"can cause a deadlock if the buffer pool fills up.\n",
srv_buf_pool_size / 1024 / 1024);
@@ -1370,18 +1402,19 @@ innobase_start_or_create_for_mysql(void)
#ifdef UNIV_LOG_ARCHIVE
if (0 != ut_strcmp(srv_log_group_home_dirs[0], srv_arch_dir)) {
- fprintf(stderr,
- "InnoDB: Error: you must set the log group"
- " home dir in my.cnf the\n"
- "InnoDB: same as log arch dir.\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Error: you must set the log group home dir in my.cnf\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: the same as log arch dir.\n");
return(DB_ERROR);
}
#endif /* UNIV_LOG_ARCHIVE */
if (srv_n_log_files * srv_log_file_size >= 262144) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: combined size of log files"
+ " InnoDB: Error: combined size of log files"
" must be < 4 GB\n");
return(DB_ERROR);
@@ -1392,10 +1425,13 @@ innobase_start_or_create_for_mysql(void)
for (i = 0; i < srv_n_data_files; i++) {
#ifndef __WIN__
if (sizeof(off_t) < 5 && srv_data_file_sizes[i] >= 262144) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: file size must be < 4 GB"
+ " with this MySQL binary\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: file size must be < 4 GB"
- " with this MySQL binary\n"
- "InnoDB: and operating system combination,"
+ " InnoDB: and operating system combination,"
" in some OS's < 2 GB\n");
return(DB_ERROR);
@@ -1405,8 +1441,9 @@ innobase_start_or_create_for_mysql(void)
}
if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: tablespace size must be"
+ " InnoDB: Error: tablespace size must be"
" at least 10 MB\n");
return(DB_ERROR);
@@ -1419,19 +1456,32 @@ innobase_start_or_create_for_mysql(void)
&min_flushed_lsn, &max_flushed_lsn,
&sum_of_new_sizes);
if (err != DB_SUCCESS) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Could not open or create data files.\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: If you tried to add new data files,"
+ " and it failed here,\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: you should now edit innodb_data_file_path"
+ " in my.cnf back\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Could not open or create data files.\n"
- "InnoDB: If you tried to add new data files,"
- " and it failed here,\n"
- "InnoDB: you should now edit innodb_data_file_path"
- " in my.cnf back\n"
- "InnoDB: to what it was, and remove the"
- " new ibdata files InnoDB created\n"
- "InnoDB: in this failed attempt. InnoDB only wrote"
- " those files full of\n"
- "InnoDB: zeros, but did not yet use them in any way."
- " But be careful: do not\n"
- "InnoDB: remove old data files"
+ " InnoDB: to what it was, and remove the"
+ " new ibdata files InnoDB created\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: in this failed attempt. InnoDB only wrote"
+ " those files full of\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: zeros, but did not yet use them in any way."
+ " But be careful: do not\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: remove old data files"
" which contain your precious data!\n");
return((int) err);
@@ -1457,18 +1507,29 @@ innobase_start_or_create_for_mysql(void)
}
if ((log_opened && create_new_db)
|| (log_opened && log_created)) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: all log files must be"
+ " created at the same time.\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: All log files must be"
+ " created also in database creation.\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: If you want bigger or smaller"
+ " log files, shut down the\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: database and make sure there"
+ " were no errors in shutdown.\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Then delete the existing log files."
+ " Edit the .cnf file\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: all log files must be"
- " created at the same time.\n"
- "InnoDB: All log files must be"
- " created also in database creation.\n"
- "InnoDB: If you want bigger or smaller"
- " log files, shut down the\n"
- "InnoDB: database and make sure there"
- " were no errors in shutdown.\n"
- "InnoDB: Then delete the existing log files."
- " Edit the .cnf file\n"
- "InnoDB: and start the database again.\n");
+ " InnoDB: and start the database again.\n");
return(DB_ERROR);
}
@@ -1489,27 +1550,41 @@ innobase_start_or_create_for_mysql(void)
|| max_arch_log_no != min_arch_log_no
#endif /* UNIV_LOG_ARCHIVE */
) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Cannot initialize created"
+ " log files because\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: data files were not in sync"
+ " with each other\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Cannot initialize created"
- " log files because\n"
- "InnoDB: data files were not in sync"
- " with each other\n"
- "InnoDB: or the data files are corrupt.\n");
+ " InnoDB: or the data files are corrupt.\n");
return(DB_ERROR);
}
if (max_flushed_lsn < (ib_uint64_t) 1000) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Cannot initialize created"
+ " log files because\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Cannot initialize created"
- " log files because\n"
- "InnoDB: data files are corrupt,"
- " or new data files were\n"
- "InnoDB: created when the database"
- " was started previous\n"
- "InnoDB: time but the database"
- " was not shut down\n"
- "InnoDB: normally after that.\n");
+ " InnoDB: data files are corrupt,"
+ " or new data files were\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: created when the database"
+ " was started previous\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: time but the database"
+ " was not shut down\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: normally after that.\n");
return(DB_ERROR);
}
@@ -1548,8 +1623,9 @@ innobase_start_or_create_for_mysql(void)
#ifdef UNIV_LOG_ARCHIVE
} else if (srv_archive_recovery) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Starting archive"
+ " InnoDB: Starting archive"
" recovery from a backup...\n");
err = recv_recovery_from_archive_start(
min_flushed_lsn, srv_archive_recovery_limit_lsn,
@@ -1757,6 +1833,24 @@ innobase_start_or_create_for_mysql(void)
os_thread_create(&srv_purge_thread, NULL, NULL);
}
+ /* Wait for the purge and master thread to startup. */
+
+ while (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
+ if (srv_thread_has_reserved_slot(SRV_MASTER) == ULINT_UNDEFINED
+ || (srv_n_purge_threads == 1
+ && srv_thread_has_reserved_slot(SRV_WORKER)
+ == ULINT_UNDEFINED)) {
+
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: "
+ "Waiting for the background threads to "
+ "start\n");
+ os_thread_sleep(1000000);
+ } else {
+ break;
+ }
+ }
+
#ifdef UNIV_DEBUG
/* buf_debug_prints = TRUE; */
#endif /* UNIV_DEBUG */
@@ -1771,11 +1865,14 @@ innobase_start_or_create_for_mysql(void)
if (!srv_auto_extend_last_data_file
&& sum_of_data_file_sizes != tablespace_size_in_header) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Error: tablespace size"
+ " stored in header is %lu pages, but\n",
+ (ulong) tablespace_size_in_header);
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: tablespace size"
- " stored in header is %lu pages, but\n"
"InnoDB: the sum of data file sizes is %lu pages\n",
- (ulong) tablespace_size_in_header,
(ulong) sum_of_data_file_sizes);
if (srv_force_recovery == 0
@@ -1783,16 +1880,25 @@ innobase_start_or_create_for_mysql(void)
/* This is a fatal error, the tail of a tablespace is
missing */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Cannot start InnoDB."
+ " The tail of the system tablespace is\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: missing. Have you edited"
+ " innodb_data_file_path in my.cnf in an\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Cannot start InnoDB."
- " The tail of the system tablespace is\n"
- "InnoDB: missing. Have you edited"
- " innodb_data_file_path in my.cnf in an\n"
- "InnoDB: inappropriate way, removing"
- " ibdata files from there?\n"
- "InnoDB: You can set innodb_force_recovery=1"
- " in my.cnf to force\n"
- "InnoDB: a startup if you are trying"
+ " InnoDB: inappropriate way, removing"
+ " ibdata files from there?\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: You can set innodb_force_recovery=1"
+ " in my.cnf to force\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: a startup if you are trying"
" to recover a badly corrupt database.\n");
return(DB_ERROR);
@@ -1802,26 +1908,38 @@ innobase_start_or_create_for_mysql(void)
if (srv_auto_extend_last_data_file
&& sum_of_data_file_sizes < tablespace_size_in_header) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: tablespace size stored in header"
- " is %lu pages, but\n"
- "InnoDB: the sum of data file sizes"
+ " InnoDB: Error: tablespace size stored in header"
+ " is %lu pages, but\n",
+ (ulong) tablespace_size_in_header);
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: the sum of data file sizes"
" is only %lu pages\n",
- (ulong) tablespace_size_in_header,
(ulong) sum_of_data_file_sizes);
if (srv_force_recovery == 0) {
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Cannot start InnoDB. The tail of"
+ " the system tablespace is\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: missing. Have you edited"
+ " innodb_data_file_path in my.cnf in an\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: inappropriate way, removing"
+ " ibdata files from there?\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: You can set innodb_force_recovery=1"
+ " in my.cnf to force\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Cannot start InnoDB. The tail of"
- " the system tablespace is\n"
- "InnoDB: missing. Have you edited"
- " innodb_data_file_path in my.cnf in an\n"
- "InnoDB: inappropriate way, removing"
- " ibdata files from there?\n"
- "InnoDB: You can set innodb_force_recovery=1"
- " in my.cnf to force\n"
- "InnoDB: a startup if you are trying to"
+ " InnoDB: a startup if you are trying to"
" recover a badly corrupt database.\n");
return(DB_ERROR);
@@ -1832,10 +1950,13 @@ innobase_start_or_create_for_mysql(void)
os_fast_mutex_init(&srv_os_test_mutex);
if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Error: pthread_mutex_trylock returns"
- " an unexpected value on\n"
- "InnoDB: success! Cannot continue.\n");
+ " InnoDB: Error: pthread_mutex_trylock returns"
+ " an unexpected value on\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: success! Cannot continue.\n");
exit(1);
}
@@ -1850,14 +1971,15 @@ innobase_start_or_create_for_mysql(void)
if (srv_print_verbose_log) {
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: %s started; "
+ " InnoDB: %s started; "
"log sequence number %llu\n",
INNODB_VERSION_STR, srv_start_lsn);
}
if (srv_force_recovery > 0) {
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: !!! innodb_force_recovery"
+ " InnoDB: !!! innodb_force_recovery"
" is set to %lu !!!\n",
(ulong) srv_force_recovery);
}
@@ -1878,12 +2000,17 @@ innobase_start_or_create_for_mysql(void)
4.1.1. It is essential that the insert buffer is emptied
here! */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: You are upgrading to an"
+ " InnoDB version which allows multiple\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: tablespaces. Wait that purge"
+ " and insert buffer merge run to\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: You are upgrading to an"
- " InnoDB version which allows multiple\n"
- "InnoDB: tablespaces. Wait that purge"
- " and insert buffer merge run to\n"
- "InnoDB: completion...\n");
+ " InnoDB: completion...\n");
for (;;) {
os_thread_sleep(1000000);
@@ -1895,21 +2022,29 @@ innobase_start_or_create_for_mysql(void)
break;
}
}
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: Full purge and insert buffer merge"
+ " InnoDB: Full purge and insert buffer merge"
" completed.\n");
trx_sys_mark_upgraded_to_multiple_tablespaces();
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: You have now successfully upgraded"
+ " to the multiple tablespaces\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: format. You should NOT DOWNGRADE"
+ " to an earlier version of\n");
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: InnoDB! But if you absolutely need to"
+ " downgrade, see\n");
+ ut_print_timestamp(stderr);
fprintf(stderr,
- "InnoDB: You have now successfully upgraded"
- " to the multiple tablespaces\n"
- "InnoDB: format. You should NOT DOWNGRADE"
- " to an earlier version of\n"
- "InnoDB: InnoDB! But if you absolutely need to"
- " downgrade, see\n"
- "InnoDB: " REFMAN "multiple-tablespaces.html\n"
- "InnoDB: for instructions.\n");
+ " InnoDB: " REFMAN "multiple-tablespaces.html\n"
+ " InnoDB: for instructions.\n");
}
if (srv_force_recovery == 0) {
diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
index 753ebd958ac..ce9d42c4921 100644
--- a/storage/innobase/sync/sync0arr.c
+++ b/storage/innobase/sync/sync0arr.c
@@ -590,9 +590,6 @@ sync_array_deadlock_step(
ulint depth) /*!< in: recursion depth */
{
sync_cell_t* new;
- ibool ret;
-
- depth++;
if (pass != 0) {
/* If pass != 0, then we do not know which threads are
@@ -604,7 +601,7 @@ sync_array_deadlock_step(
new = sync_array_find_thread(arr, thread);
- if (new == start) {
+ if (UNIV_UNLIKELY(new == start)) {
/* Stop running of other threads */
ut_dbg_stop_threads = TRUE;
@@ -616,11 +613,7 @@ sync_array_deadlock_step(
return(TRUE);
} else if (new) {
- ret = sync_array_detect_deadlock(arr, start, new, depth);
-
- if (ret) {
- return(TRUE);
- }
+ return(sync_array_detect_deadlock(arr, start, new, depth + 1));
}
return(FALSE);
}
@@ -930,12 +923,25 @@ sync_array_print_long_waits(void)
ulint fatal_timeout = srv_fatal_semaphore_wait_threshold;
ibool fatal = FALSE;
+#ifdef UNIV_DEBUG_VALGRIND
+ /* Increase the timeouts if running under valgrind because it executes
+ extremely slowly. UNIV_DEBUG_VALGRIND does not necessary mean that
+ we are running under valgrind but we have no better way to tell.
+ See Bug#58432 innodb.innodb_bug56143 fails under valgrind
+ for an example */
+# define SYNC_ARRAY_TIMEOUT 2400
+ fatal_timeout *= 10;
+#else
+# define SYNC_ARRAY_TIMEOUT 240
+#endif
+
for (i = 0; i < sync_primary_wait_array->n_cells; i++) {
cell = sync_array_get_nth_cell(sync_primary_wait_array, i);
if (cell->wait_object != NULL && cell->waiting
- && difftime(time(NULL), cell->reservation_time) > 240) {
+ && difftime(time(NULL), cell->reservation_time)
+ > SYNC_ARRAY_TIMEOUT) {
fputs("InnoDB: Warning: a long semaphore wait:\n",
stderr);
sync_array_cell_print(stderr, cell);
@@ -977,6 +983,8 @@ sync_array_print_long_waits(void)
" to the standard error stream\n");
}
+#undef SYNC_ARRAY_TIMEOUT
+
return(fatal);
}
diff --git a/storage/innobase/trx/trx0i_s.c b/storage/innobase/trx/trx0i_s.c
index 8b11e706180..aff49e20726 100644
--- a/storage/innobase/trx/trx0i_s.c
+++ b/storage/innobase/trx/trx0i_s.c
@@ -442,7 +442,7 @@ i_s_locks_row_validate(
/* record lock */
ut_ad(!strcmp("RECORD", row->lock_type));
ut_ad(row->lock_index != NULL);
- ut_ad(row->lock_data != NULL);
+ /* row->lock_data == NULL if buf_page_try_get() == NULL */
ut_ad(row->lock_page != ULINT_UNDEFINED);
ut_ad(row->lock_rec != ULINT_UNDEFINED);
}
@@ -508,7 +508,6 @@ fill_trx_row(
stmt = innobase_get_stmt(trx->mysql_thd, &stmt_len);
if (stmt != NULL) {
-
char query[TRX_I_S_TRX_QUERY_MAX_LEN + 1];
if (stmt_len > TRX_I_S_TRX_QUERY_MAX_LEN) {
@@ -522,6 +521,8 @@ fill_trx_row(
cache->storage, stmt, stmt_len + 1,
MAX_ALLOWED_FOR_STORAGE(cache));
+ row->trx_query_cs = innobase_get_charset(trx->mysql_thd);
+
if (row->trx_query == NULL) {
return(FALSE);
diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c
index 26498a1b712..101f225a06f 100644
--- a/storage/innobase/trx/trx0sys.c
+++ b/storage/innobase/trx/trx0sys.c
@@ -1160,7 +1160,7 @@ trx_sys_file_format_max_check(
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: highest supported file format is %s.\n",
+ " InnoDB: highest supported file format is %s.\n",
trx_sys_file_format_id_to_name(DICT_TF_FORMAT_MAX));
if (format_id > DICT_TF_FORMAT_MAX) {
@@ -1169,7 +1169,7 @@ trx_sys_file_format_max_check(
ut_print_timestamp(stderr);
fprintf(stderr,
- " InnoDB: %s: the system tablespace is in a file "
+ " InnoDB: %s: the system tablespace is in a file "
"format that this version doesn't support - %s\n",
((max_format_id <= DICT_TF_FORMAT_MAX)
? "Error" : "Warning"),
diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c
index e79217d5b86..42ad8c03762 100644
--- a/storage/innobase/ut/ut0dbg.c
+++ b/storage/innobase/ut/ut0dbg.c
@@ -74,7 +74,7 @@ ut_dbg_assertion_failed(
" or crashes, even\n"
"InnoDB: immediately after the mysqld startup, there may be\n"
"InnoDB: corruption in the InnoDB tablespace. Please refer to\n"
- "InnoDB: " REFMAN "forcing-recovery.html\n"
+ "InnoDB: " REFMAN "forcing-innodb-recovery.html\n"
"InnoDB: about forcing recovery.\n", stderr);
#if defined(UNIV_SYNC_DEBUG) || !defined(UT_DBG_USE_ABORT)
ut_dbg_stop_threads = TRUE;
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index c4bb6d7dbd4..c7b6b2239ce 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -168,10 +168,9 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
Also we likely need to lock mutex here (in both cases with protocol and
push_warning).
*/
-#ifdef THREAD
if (param->need_print_msg_lock)
mysql_mutex_lock(&param->print_msg_mutex);
-#endif
+
protocol->prepare_for_resend();
protocol->store(name, length, system_charset_info);
protocol->store(param->op_name, system_charset_info);
@@ -180,10 +179,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type,
if (protocol->write())
sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n",
msgbuf);
-#ifdef THREAD
+
if (param->need_print_msg_lock)
mysql_mutex_unlock(&param->print_msg_mutex);
-#endif
+
return;
}
diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c
index 79a8105f823..5d8a7c3daef 100644
--- a/storage/myisam/mi_check.c
+++ b/storage/myisam/mi_check.c
@@ -99,9 +99,7 @@ void myisamchk_init(MI_CHECK *param)
param->max_record_length= LONGLONG_MAX;
param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE;
param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL;
-#ifdef THREAD
param->need_print_msg_lock= 0;
-#endif
}
/* Check the status flags for the table */
@@ -2631,9 +2629,6 @@ err:
int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info,
const char * name, int rep_quick)
{
-#ifndef THREAD
- return mi_repair_by_sort(param, info, name, rep_quick);
-#else
int got_error;
uint i,key, total_key_length, istep;
ulong rec_length;
@@ -3122,7 +3117,6 @@ err:
share->pack.header_length=0;
}
DBUG_RETURN(got_error);
-#endif /* THREAD */
}
/* Read next record and return next key */
diff --git a/storage/myisam/mi_close.c b/storage/myisam/mi_close.c
index 51408ab191c..105ee3810cd 100644
--- a/storage/myisam/mi_close.c
+++ b/storage/myisam/mi_close.c
@@ -91,7 +91,6 @@ int mi_close(register MI_INFO *info)
my_free(share->decode_trees);
my_free(share->decode_tables);
}
-#ifdef THREAD
thr_lock_delete(&share->lock);
mysql_mutex_destroy(&share->intern_lock);
{
@@ -102,7 +101,6 @@ int mi_close(register MI_INFO *info)
mysql_rwlock_destroy(&share->key_root_lock[i]);
}
}
-#endif
my_free(info->s);
}
mysql_mutex_unlock(&THR_LOCK_myisam);
diff --git a/storage/myisam/mi_delete.c b/storage/myisam/mi_delete.c
index 9314148cd8c..5fa7cba7d5e 100644
--- a/storage/myisam/mi_delete.c
+++ b/storage/myisam/mi_delete.c
@@ -102,7 +102,7 @@ int mi_delete(MI_INFO *info,const uchar *record)
mi_sizestore(lastpos,info->lastpos);
myisam_log_command(MI_LOG_DELETE,info,(uchar*) lastpos,sizeof(lastpos),0);
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
- allow_break(); /* Allow SIGHUP & SIGINT */
+
if (info->invalidator != 0)
{
DBUG_PRINT("info", ("invalidator... '%s' (delete)", info->filename));
@@ -122,7 +122,6 @@ err:
}
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
- allow_break(); /* Allow SIGHUP & SIGINT */
my_errno=save_errno;
if (save_errno == HA_ERR_KEY_NOT_FOUND)
{
diff --git a/storage/myisam/mi_delete_all.c b/storage/myisam/mi_delete_all.c
index 7a2e24189e6..cc610b73839 100644
--- a/storage/myisam/mi_delete_all.c
+++ b/storage/myisam/mi_delete_all.c
@@ -66,7 +66,6 @@ int mi_delete_all_rows(MI_INFO *info)
if (share->file_map)
mi_dynmap_file(info, (my_off_t) 0);
#endif
- allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
err:
@@ -74,7 +73,6 @@ err:
int save_errno=my_errno;
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
info->update|=HA_STATE_WRITTEN; /* Buffer changed */
- allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(my_errno=save_errno);
}
} /* mi_delete */
diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c
index f429edd2759..8b407a36d6f 100644
--- a/storage/myisam/mi_dynrec.c
+++ b/storage/myisam/mi_dynrec.c
@@ -39,13 +39,11 @@ static int delete_dynamic_record(MI_INFO *info,my_off_t filepos,
static int _mi_cmp_buffer(File file, const uchar *buff, my_off_t filepos,
uint length);
-#ifdef THREAD
/* Play it safe; We have a small stack when using threads */
#undef my_alloca
#undef my_afree
#define my_alloca(A) my_malloc((A),MYF(0))
#define my_afree(A) my_free((A))
-#endif
/* Interface function from MI_INFO */
@@ -1579,9 +1577,6 @@ int _mi_cmp_dynamic_record(register MI_INFO *info, register const uchar *record)
MI_BLOCK_INFO block_info;
DBUG_ENTER("_mi_cmp_dynamic_record");
- /* We are going to do changes; dont let anybody disturb */
- dont_break(); /* Dont allow SIGHUP or SIGINT */
-
if (info->opt_flag & WRITE_CACHE_USED)
{
info->update&= ~(HA_STATE_WRITE_AT_END | HA_STATE_EXTEND_BLOCK);
diff --git a/storage/myisam/mi_log.c b/storage/myisam/mi_log.c
index 5af4a057a95..4b207f48e1c 100644
--- a/storage/myisam/mi_log.c
+++ b/storage/myisam/mi_log.c
@@ -24,11 +24,7 @@
#endif
#undef GETPID /* For HPUX */
-#ifdef THREAD
#define GETPID() (log_type == 1 ? (long) myisam_pid : (long) my_thread_dbug_id())
-#else
-#define GETPID() myisam_pid
-#endif
/* Activate logging if flag is 1 and reset logging if flag is 0 */
diff --git a/storage/myisam/mi_open.c b/storage/myisam/mi_open.c
index e3c29909067..6efcfd8862f 100644
--- a/storage/myisam/mi_open.c
+++ b/storage/myisam/mi_open.c
@@ -286,9 +286,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
&share->state.key_root,keys*sizeof(my_off_t),
&share->state.key_del,
(share->state.header.max_block_size_index*sizeof(my_off_t)),
-#ifdef THREAD
&share->key_root_lock, sizeof(mysql_rwlock_t)*keys,
-#endif
&share->mmap_lock, sizeof(mysql_rwlock_t),
NullS))
goto err;
@@ -498,7 +496,6 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
my_afree(disk_cache);
mi_setup_functions(share);
share->is_log_table= FALSE;
-#ifdef THREAD
thr_lock_init(&share->lock);
mysql_mutex_init(mi_key_mutex_MYISAM_SHARE_intern_lock,
&share->intern_lock, MY_MUTEX_INIT_FAST);
@@ -528,7 +525,6 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
share->lock.check_status=mi_check_status;
}
}
-#endif
/*
Memory mapping can only be requested after initializing intern_lock.
*/
@@ -625,9 +621,7 @@ MI_INFO *mi_open(const char *name, int mode, uint open_flags)
bzero(info.rec_buff, mi_get_rec_buff_len(&info, info.rec_buff));
*m_info=info;
-#ifdef THREAD
thr_lock_data_init(&share->lock,&m_info->lock,(void*) m_info);
-#endif
m_info->open_list.data=(void*) m_info;
myisam_open_list=list_add(myisam_open_list,&m_info->open_list);
diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c
index 55967fc9001..711287ca16f 100644
--- a/storage/myisam/mi_static.c
+++ b/storage/myisam/mi_static.c
@@ -32,7 +32,7 @@ File myisam_log_file= -1;
uint myisam_quick_table_bits=9;
ulong myisam_block_size= MI_KEY_BLOCK_LENGTH; /* Best by test */
my_bool myisam_flush=0, myisam_delay_key_write=0, myisam_single_user=0;
-#if defined(THREAD) && !defined(DONT_USE_RW_LOCKS)
+#if !defined(DONT_USE_RW_LOCKS)
ulong myisam_concurrent_insert= 2;
#else
ulong myisam_concurrent_insert= 0;
diff --git a/storage/myisam/mi_statrec.c b/storage/myisam/mi_statrec.c
index f83afa3c886..bf791726aa9 100644
--- a/storage/myisam/mi_statrec.c
+++ b/storage/myisam/mi_statrec.c
@@ -114,9 +114,6 @@ int _mi_cmp_static_record(register MI_INFO *info, register const uchar *old)
{
DBUG_ENTER("_mi_cmp_static_record");
- /* We are going to do changes; dont let anybody disturb */
- dont_break(); /* Dont allow SIGHUP or SIGINT */
-
if (info->opt_flag & WRITE_CACHE_USED)
{
if (flush_io_cache(&info->rec_cache))
diff --git a/storage/myisam/mi_update.c b/storage/myisam/mi_update.c
index b538bcd0bb1..a9aad421235 100644
--- a/storage/myisam/mi_update.c
+++ b/storage/myisam/mi_update.c
@@ -179,7 +179,6 @@ int mi_update(register MI_INFO *info, const uchar *oldrec, uchar *newrec)
there is no index change there could be data change.
*/
(void) _mi_writeinfo(info, WRITEINFO_UPDATE_KEYFILE);
- allow_break(); /* Allow SIGHUP & SIGINT */
if (info->invalidator != 0)
{
DBUG_PRINT("info", ("invalidator... '%s' (update)", info->filename));
@@ -230,7 +229,6 @@ err:
err_end:
myisam_log_record(MI_LOG_UPDATE,info,newrec,info->lastpos,my_errno);
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
- allow_break(); /* Allow SIGHUP & SIGINT */
if (save_errno == HA_ERR_KEY_NOT_FOUND)
{
mi_print_error(info->s, HA_ERR_CRASHED);
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index bd56bb04f65..f3fbb7206e2 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -60,7 +60,7 @@ int mi_write(MI_INFO *info, uchar *record)
}
if (_mi_readinfo(info,F_WRLCK,1))
DBUG_RETURN(my_errno);
- dont_break(); /* Dont allow SIGHUP or SIGINT */
+
filepos= ((share->state.dellink != HA_OFFSET_ERROR &&
!info->append_insert_at_end) ?
share->state.dellink :
@@ -169,7 +169,6 @@ int mi_write(MI_INFO *info, uchar *record)
if (share->is_log_table)
mi_update_status((void*) info);
- allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(0);
err:
@@ -228,7 +227,6 @@ err2:
save_errno=my_errno;
myisam_log_record(MI_LOG_WRITE,info,record,filepos,my_errno);
(void) _mi_writeinfo(info,WRITEINFO_UPDATE_KEYFILE);
- allow_break(); /* Allow SIGHUP & SIGINT */
DBUG_RETURN(my_errno=save_errno);
} /* mi_write */
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index c7f0cb27a40..133d0cec9eb 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -18,12 +18,8 @@
#include "myisam.h" /* Structs & some defines */
#include "myisampack.h" /* packing of keys */
#include <my_tree.h>
-#ifdef THREAD
#include <my_pthread.h>
#include <thr_lock.h>
-#else
-#include <my_no_pthread.h>
-#endif
#include <mysql/psi/mysql_file.h>
/* undef map from my_nosys; We need test-if-disk full */
@@ -211,11 +207,10 @@ typedef struct st_mi_isam_share { /* Shared between opens */
not_flushed,
temporary,delay_key_write,
concurrent_insert;
-#ifdef THREAD
+
THR_LOCK lock;
mysql_mutex_t intern_lock; /* Locking for use with _locking */
mysql_rwlock_t *key_root_lock;
-#endif
my_off_t mmaped_length;
uint nonmmaped_inserts; /* counter of writing in non-mmaped
area */
@@ -298,9 +293,7 @@ struct st_myisam_info {
#ifdef __WIN__
my_bool owned_by_merge; /* This MyISAM table is part of a merge union */
#endif
-#ifdef THREAD
THR_LOCK_DATA lock;
-#endif
uchar *rtree_recursion_state; /* For RTREE */
int rtree_recursion_depth;
};
@@ -461,10 +454,9 @@ typedef struct st_mi_sort_param
#define MI_UNIQUE_HASH_TYPE HA_KEYTYPE_ULONG_INT
#define mi_unique_store(A,B) mi_int4store((A),(B))
-#ifdef THREAD
extern mysql_mutex_t THR_LOCK_myisam;
-#endif
-#if !defined(THREAD) || defined(DONT_USE_RW_LOCKS)
+
+#if defined(DONT_USE_RW_LOCKS)
#define mysql_rwlock_wrlock(A) {}
#define mysql_rwlock_rdlock(A) {}
#define mysql_rwlock_unlock(A) {}
@@ -774,9 +766,7 @@ void mi_check_print_info(MI_CHECK *param, const char *fmt,...);
int flush_pending_blocks(MI_SORT_PARAM *param);
int sort_ft_buf_flush(MI_SORT_PARAM *sort_param);
int thr_write_keys(MI_SORT_PARAM *sort_param);
-#ifdef THREAD
pthread_handler_t thr_find_all_keys(void *arg);
-#endif
int flush_blocks(MI_CHECK *param, KEY_CACHE *key_cache, File file);
int sort_write_record(MI_SORT_PARAM *sort_param);
diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c
index 9532b9f0474..6630b99dd9c 100644
--- a/storage/myisam/sort.c
+++ b/storage/myisam/sort.c
@@ -302,7 +302,6 @@ static ha_rows find_all_keys(MI_SORT_PARAM *info, uint keys,
} /* find_all_keys */
-#ifdef THREAD
/* Search after all keys and place them in a temp. file */
pthread_handler_t thr_find_all_keys(void *arg)
@@ -637,7 +636,6 @@ int thr_write_keys(MI_SORT_PARAM *sort_param)
my_free(mergebuf);
DBUG_RETURN(got_error);
}
-#endif /* THREAD */
/* Write all keys in memory to file for later merge */
diff --git a/storage/myisammrg/myrg_def.h b/storage/myisammrg/myrg_def.h
index b916243be21..9bc0881b212 100644
--- a/storage/myisammrg/myrg_def.h
+++ b/storage/myisammrg/myrg_def.h
@@ -23,9 +23,7 @@
extern LIST *myrg_open_list;
-#ifdef THREAD
extern mysql_mutex_t THR_LOCK_open;
-#endif
int _myrg_init_queue(MYRG_INFO *info,int inx,enum ha_rkey_function search_flag);
int _myrg_mi_read_record(MI_INFO *info, uchar *buf);