Many files:

  Merge InnoDB-3.23.52d
parent 5fadf192
......@@ -17,6 +17,7 @@ Created 2/17/1996 Heikki Tuuri
#include "btr0cur.h"
#include "btr0pcur.h"
#include "btr0btr.h"
#include "ha0ha.h"
ulint btr_search_n_succ = 0;
ulint btr_search_n_hash_fail = 0;
......
......@@ -1844,8 +1844,8 @@ buf_print_io(
buf_pool->n_flush[BUF_FLUSH_SINGLE_PAGE]);
current_time = time(NULL);
time_elapsed = difftime(current_time, buf_pool->last_printout_time);
time_elapsed = 0.001 + difftime(current_time,
buf_pool->last_printout_time);
buf_pool->last_printout_time = current_time;
buf += sprintf(buf, "Pages read %lu, created %lu, written %lu\n",
......@@ -1878,6 +1878,20 @@ buf_print_io(
mutex_exit(&(buf_pool->mutex));
}
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
void
buf_refresh_io_stats(void)
/*======================*/
{
buf_pool->last_printout_time = time(NULL);
buf_pool->n_page_gets_old = buf_pool->n_page_gets;
buf_pool->n_pages_read_old = buf_pool->n_pages_read;
buf_pool->n_pages_created_old = buf_pool->n_pages_created;
buf_pool->n_pages_written_old = buf_pool->n_pages_written;
}
/*************************************************************************
Checks that all file pages in the buffer are in a replaceable state. */
......
......@@ -27,6 +27,7 @@ Created 11/5/1995 Heikki Tuuri
#include "buf0rea.h"
#include "btr0sea.h"
#include "os0file.h"
#include "log0recv.h"
/* The number of blocks from the LRU_old pointer onward, including the block
pointed to, must be 3/8 of the whole LRU list length, except that the
......@@ -204,7 +205,7 @@ buf_LRU_get_free_block(void)
loop:
mutex_enter(&(buf_pool->mutex));
if (UT_LIST_GET_LEN(buf_pool->free)
if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 10) {
ut_print_timestamp(stderr);
......@@ -216,7 +217,7 @@ loop:
ut_a(0);
} else if (UT_LIST_GET_LEN(buf_pool->free)
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 5) {
/* Over 80 % of the buffer pool is occupied by lock heaps
......@@ -232,7 +233,7 @@ loop:
srv_print_innodb_monitor = TRUE;
} else if (UT_LIST_GET_LEN(buf_pool->free)
} else if (!recv_recovery_on && UT_LIST_GET_LEN(buf_pool->free)
+ UT_LIST_GET_LEN(buf_pool->LRU) < buf_pool->max_size / 4) {
/* Switch off the InnoDB Monitor; this is a simple way
......
......@@ -85,6 +85,8 @@ else
fi
case "$target_os" in
hpux10*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX -DUNIV_HPUX10";;
hp*)
CFLAGS="$CFLAGS -DUNIV_MUST_NOT_INLINE -DUNIV_HPUX";;
irix*)
......
......@@ -463,6 +463,12 @@ buf_print_io(
/*=========*/
char* buf, /* in/out: buffer where to print */
char* buf_end);/* in: buffer end */
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
void
buf_refresh_io_stats(void);
/*======================*/
/*************************************************************************
Checks that all file pages in the buffer are in a replaceable state. */
......
......@@ -131,6 +131,14 @@ ha_print_info(
char* buf_end,/* in: buffer end */
hash_table_t* table); /* in: hash table */
/* The hash table external chain node */
typedef struct ha_node_struct ha_node_t;
struct ha_node_struct {
ha_node_t* next; /* next chain node or NULL if none */
void* data; /* pointer to the data */
ulint fold; /* fold value for the data */
};
#ifndef UNIV_NONINL
#include "ha0ha.ic"
......
......@@ -9,16 +9,6 @@ Created 8/18/1994 Heikki Tuuri
#include "ut0rnd.h"
#include "mem0mem.h"
/* The hash table external chain node */
typedef struct ha_node_struct ha_node_t;
struct ha_node_struct {
ha_node_t* next; /* next chain node or NULL if none */
void* data; /* pointer to the data */
ulint fold; /* fold value for the data */
};
/***************************************************************
Deletes a hash node. */
......
......@@ -512,6 +512,12 @@ log_print(
/*======*/
char* buf, /* in/out: buffer where to print */
char* buf_end);/* in: buffer end */
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
void
log_refresh_stats(void);
/*===================*/
extern log_t* log_sys;
......
......@@ -408,6 +408,12 @@ os_aio_print(
char* buf, /* in/out: buffer where to print */
char* buf_end);/* in: buffer end */
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
void
os_aio_refresh_stats(void);
/*======================*/
/**************************************************************************
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
......
......@@ -27,7 +27,21 @@ os_fast_mutex_trylock(
return(0);
#else
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
/* Since the hot backup version is standalone, MySQL does not redefine
pthread_mutex_trylock for HP-UX-10.20, and consequently we must invert
the return value here */
return((ulint) (1 - pthread_mutex_trylock(fast_mutex)));
#else
/* NOTE that the MySQL my_pthread.h redefines pthread_mutex_trylock
so that it returns 0 on success. In the operating system
libraries, HP-UX-10.20 follows the old Posix 1003.4a Draft 4 and
returns 1 on success (but MySQL remaps that to 0), while Linux,
FreeBSD, Solaris, AIX, Tru64 Unix, HP-UX-11.0 return 0 on success. */
return((ulint) pthread_mutex_trylock(fast_mutex));
#endif
#endif
}
......@@ -28,12 +28,30 @@ typedef void* os_thread_t;
#else
typedef pthread_t os_thread_t;
#endif
typedef unsigned long int os_thread_id_t;
#define os_thread_id_t os_thread_t
/* Define a function pointer type to use in a typecast */
typedef void* (*os_posix_f_t) (void*);
/*******************************************************************
Compares two threads or thread ids for equality */
ibool
os_thread_eq(
/*=========*/
/* out: TRUE if equal */
os_thread_t a, /* in: OS thread or thread id */
os_thread_t b); /* in: OS thread or thread id */
/********************************************************************
Converts an OS thread or thread id to a ulint. It is NOT guaranteed that
the ulint is unique for the thread though! */
ulint
os_thread_pf(
/*=========*/
/* out: unsigned long int */
os_thread_t a); /* in: thread or thread id */
/********************************************************************
Creates a new thread of execution. The execution starts from
the function given. The start function takes a void* parameter
......@@ -73,14 +91,6 @@ os_thread_t
os_thread_get_curr(void);
/*====================*/
/*********************************************************************
Converts a thread id to a ulint. */
ulint
os_thread_conv_id_to_ulint(
/*=======================*/
/* out: converted to ulint */
os_thread_id_t id); /* in: thread id */
/*********************************************************************
Waits for a thread to terminate. */
void
......
......@@ -85,7 +85,7 @@ extern ibool srv_is_being_shut_down;
/* At a shutdown the value first climbs from 0 to SRV_SHUTDOWN_CLEANUP
and then to SRV_SHUTDOWN_LAST_PHASE */
extern ulint srv_shutdown_state;
extern ulint srv_shutdown_state;
#define SRV_SHUTDOWN_CLEANUP 1
#define SRV_SHUTDOWN_LAST_PHASE 2
......
......@@ -311,7 +311,8 @@ rw_lock_x_lock_func_nowait(
&& ((rw_lock_get_writer(lock) == RW_LOCK_NOT_LOCKED)
|| ((rw_lock_get_writer(lock) == RW_LOCK_EX)
&& (lock->pass == 0)
&& (lock->writer_thread == os_thread_get_curr_id())))) {
&& os_thread_eq(lock->writer_thread,
os_thread_get_curr_id())))) {
rw_lock_set_writer(lock, RW_LOCK_EX);
lock->writer_thread = os_thread_get_curr_id();
......
......@@ -104,6 +104,10 @@ mutex_test_and_set(
ret = os_fast_mutex_trylock(&(mutex->os_fast_mutex));
if (ret == 0) {
/* We check that os_fast_mutex_trylock does not leak
and allow race conditions */
ut_a(mutex->lock_word == 0);
mutex->lock_word = 1;
}
......
......@@ -80,8 +80,8 @@ memory is read outside the allocated blocks. */
/*
#define UNIV_DEBUG
#define UNIV_MEM_DEBUG
#define UNIV_SYNC_DEBUG
#define UNIV_MEM_DEBUG
#define UNIV_IBUF_DEBUG
#define UNIV_SEARCH_DEBUG
......
......@@ -26,9 +26,11 @@ extern ulint* ut_dbg_null_ptr;
ulint dbg_i;\
\
if (!((ulint)(EXPR) + ut_dbg_zero)) {\
ut_print_timestamp(stderr);\
fprintf(stderr,\
"InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_get_curr_id(), IB__FILE__, (ulint)__LINE__);\
" InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__,\
(ulint)__LINE__);\
fprintf(stderr,\
"InnoDB: We intentionally generate a memory trap.\n");\
fprintf(stderr,\
......@@ -42,16 +44,17 @@ extern ulint* ut_dbg_null_ptr;
if (ut_dbg_stop_threads) {\
fprintf(stderr,\
"InnoDB: Thread %lu stopped in file %s line %lu\n",\
os_thread_get_curr_id(), IB__FILE__, (ulint)__LINE__);\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\
os_thread_sleep(1000000000);\
}\
}
#define ut_error {\
ulint dbg_i;\
ut_print_timestamp(stderr);\
fprintf(stderr,\
"InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_get_curr_id(), IB__FILE__, (ulint)__LINE__);\
" InnoDB: Assertion failure in thread %lu in file %s line %lu\n",\
os_thread_pf(os_thread_get_curr_id()), IB__FILE__, (ulint)__LINE__);\
fprintf(stderr,\
"InnoDB: We intentionally generate a memory trap.\n");\
fprintf(stderr,\
......
......@@ -301,6 +301,11 @@ struct lock_struct{
} un_member;
};
/* We store info on the latest deadlock error to this buffer. InnoDB
Monitor will then fetch it and print */
ibool lock_deadlock_found = FALSE;
char* lock_latest_err_buf; /* We allocate 5000 bytes for this */
/************************************************************************
Checks if a lock request results in a deadlock. */
static
......@@ -575,6 +580,8 @@ lock_sys_create(
lock_sys->rec_hash = hash_create(n_cells);
/* hash_create_mutexes(lock_sys->rec_hash, 2, SYNC_REC_LOCK); */
lock_latest_err_buf = mem_alloc(5000);
}
/*************************************************************************
......@@ -2698,6 +2705,7 @@ lock_deadlock_occurs(
trx_t* mark_trx;
ibool ret;
ulint cost = 0;
char* err_buf;
ut_ad(trx && lock);
ut_ad(mutex_own(&kernel_mutex));
......@@ -2723,6 +2731,29 @@ lock_deadlock_occurs(
index = lock->index;
table = index->table;
}
lock_deadlock_found = TRUE;
err_buf = lock_latest_err_buf + strlen(lock_latest_err_buf);
err_buf += sprintf(err_buf,
"*** (2) WAITING FOR THIS LOCK TO BE GRANTED:\n");
ut_a(err_buf <= lock_latest_err_buf + 4000);
if (lock_get_type(lock) == LOCK_REC) {
lock_rec_print(err_buf, lock);
err_buf += strlen(err_buf);
} else {
lock_table_print(err_buf, lock);
err_buf += strlen(err_buf);
}
ut_a(err_buf <= lock_latest_err_buf + 4000);
err_buf += sprintf(err_buf,
"*** WE ROLL BACK TRANSACTION (2)\n");
/*
sess_raise_error_low(trx, DB_DEADLOCK, lock->type_mode, table,
index, NULL, NULL, NULL);
......@@ -2750,6 +2781,7 @@ lock_deadlock_recursive(
lock_t* lock;
ulint bit_no;
trx_t* lock_trx;
char* err_buf;
ut_a(trx && start && wait_lock);
ut_ad(mutex_own(&kernel_mutex));
......@@ -2801,6 +2833,53 @@ lock_deadlock_recursive(
lock_trx = lock->trx;
if (lock_trx == start) {
err_buf = lock_latest_err_buf;
ut_sprintf_timestamp(err_buf);
err_buf += strlen(err_buf);
err_buf += sprintf(err_buf,
" LATEST DETECTED DEADLOCK:\n"
"*** (1) TRANSACTION:\n");
trx_print(err_buf, wait_lock->trx);
err_buf += strlen(err_buf);
err_buf += sprintf(err_buf,
"*** (1) WAITING FOR THIS LOCK TO BE GRANTED:\n");
ut_a(err_buf <= lock_latest_err_buf + 4000);
if (lock_get_type(wait_lock) == LOCK_REC) {
lock_rec_print(err_buf, wait_lock);
err_buf += strlen(err_buf);
} else {
lock_table_print(err_buf, wait_lock);
err_buf += strlen(err_buf);
}
ut_a(err_buf <= lock_latest_err_buf + 4000);
err_buf += sprintf(err_buf,
"*** (2) TRANSACTION:\n");
trx_print(err_buf, lock->trx);
err_buf += strlen(err_buf);
err_buf += sprintf(err_buf,
"*** (2) HOLDS THE LOCK(S):\n");
ut_a(err_buf <= lock_latest_err_buf + 4000);
if (lock_get_type(lock) == LOCK_REC) {
lock_rec_print(err_buf, lock);
err_buf += strlen(err_buf);
} else {
lock_table_print(err_buf, lock);
err_buf += strlen(err_buf);
}
ut_a(err_buf <= lock_latest_err_buf + 4000);
if (lock_print_waits) {
printf("Deadlock detected\n");
}
......@@ -3433,6 +3512,9 @@ lock_rec_print(
buf += sprintf(buf,
"Suppressing further record lock prints for this page\n");
mtr_commit(&mtr);
return;
}
......@@ -3505,10 +3587,6 @@ lock_print_info(
return;
}
buf += sprintf(buf, "Number of sessions %lu\n",
UT_LIST_GET_LEN(trx_sys->mysql_trx_list)
+ UT_LIST_GET_LEN(trx_sys->trx_list));
buf += sprintf(buf, "Trx id counter %lu %lu\n",
ut_dulint_get_high(trx_sys->max_trx_id),
ut_dulint_get_low(trx_sys->max_trx_id));
......@@ -3525,6 +3603,22 @@ lock_print_info(
buf += sprintf(buf,
"Total number of lock structs in row lock hash table %lu\n",
lock_get_n_rec_locks());
if (lock_deadlock_found) {
if ((ulint)(buf_end - buf)
< 100 + strlen(lock_latest_err_buf)) {
return;
}
buf += sprintf(buf, "%s", lock_latest_err_buf);
}
if (buf_end - buf < 600) {
return;
}
buf += sprintf(buf, "LIST OF TRANSACTIONS FOR EACH SESSION:\n");
/* First print info on non-active transactions */
......
......@@ -3096,8 +3096,8 @@ log_print(
current_time = time(NULL);
time_elapsed = difftime(current_time, log_sys->last_printout_time);
time_elapsed = 0.001 + difftime(current_time,
log_sys->last_printout_time);
buf += sprintf(buf,
"%lu pending log writes, %lu pending chkp writes\n"
"%lu log i/o's done, %.2f log i/o's/second\n",
......@@ -3111,3 +3111,14 @@ log_print(
mutex_exit(&(log_sys->mutex));
}
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
void
log_refresh_stats(void)
/*===================*/
{
log_sys->n_log_ios_old = log_sys->n_log_ios;
log_sys->last_printout_time = time(NULL);
}
......@@ -251,6 +251,7 @@ mem_pool_fill_free_list(
mem_area_t* area;
mem_area_t* area2;
ibool ret;
char err_buf[500];
ut_ad(mutex_own(&(pool->mutex)));
......@@ -279,15 +280,34 @@ mem_pool_fill_free_list(
area = UT_LIST_GET_FIRST(pool->free_list[i + 1]);
if (area == NULL) {
if (UT_LIST_GET_LEN(pool->free_list[i + 1]) > 0) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: mem pool free list %lu length is %lu\n"
"InnoDB: though the list is empty!\n",
i + 1, UT_LIST_GET_LEN(pool->free_list[i + 1]));
}
ret = mem_pool_fill_free_list(i + 1, pool);
if (ret == FALSE) {
return(FALSE);
}
area = UT_LIST_GET_FIRST(pool->free_list[i + 1]);
}
if (UT_LIST_GET_LEN(pool->free_list[i + 1]) == 0) {
ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
fprintf(stderr,
"InnoDB: Error: Removing element from mem pool free list %lu\n"
"InnoDB: though the list length is 0! Dump of 100 bytes around element:\n%s\n",
i + 1, err_buf);
ut_a(0);
}
UT_LIST_REMOVE(free_list, pool->free_list[i + 1], area);
area2 = (mem_area_t*)(((byte*)area) + ut_2_exp(i));
......@@ -320,6 +340,7 @@ mem_area_alloc(
mem_area_t* area;
ulint n;
ibool ret;
char err_buf[500];
n = ut_2_log(ut_max(size + MEM_AREA_EXTRA_SIZE, MEM_AREA_MIN_SIZE));
......@@ -342,7 +363,24 @@ mem_area_alloc(
area = UT_LIST_GET_FIRST(pool->free_list[n]);
}
ut_a(mem_area_get_free(area));
if (!mem_area_get_free(area)) {
ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
fprintf(stderr,
"InnoDB: Error: Removing element from mem pool free list %lu though the\n"
"InnoDB: element is not marked free! Dump of 100 bytes around element:\n%s\n",
n, err_buf);
ut_a(0);
}
if (UT_LIST_GET_LEN(pool->free_list[n]) == 0) {
ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
fprintf(stderr,
"InnoDB: Error: Removing element from mem pool free list %lu\n"
"InnoDB: though the list length is 0! Dump of 100 bytes around element:\n%s\n",
n, err_buf);
ut_a(0);
}
ut_ad(mem_area_get_size(area) == ut_2_exp(n));
mem_area_set_free(area, FALSE);
......@@ -413,6 +451,7 @@ mem_area_free(
void* new_ptr;
ulint size;
ulint n;
char err_buf[500];
if (mem_out_of_mem_err_msg_count > 0) {
/* It may be that the area was really allocated from the
......@@ -429,10 +468,18 @@ mem_area_free(
area = (mem_area_t*) (((byte*)ptr) - MEM_AREA_EXTRA_SIZE);
if (mem_area_get_free(area)) {
ut_sprintf_buf(err_buf, ((byte*)area) - 50, 100);
fprintf(stderr,
"InnoDB: Error: Freeing element to mem pool free list though the\n"
"InnoDB: element is marked free! Dump of 100 bytes around element:\n%s\n",
err_buf);
ut_a(0);
}
size = mem_area_get_size(area);
ut_ad(size != 0);
ut_a(!mem_area_get_free(area));
#ifdef UNIV_LIGHT_MEM_DEBUG
if (((byte*)area) + size < pool->buf + pool->size) {
......
......@@ -2486,7 +2486,7 @@ loop:
buf += sprintf(buf, "\n");
current_time = time(NULL);
time_elapsed = difftime(current_time, os_last_printout);
time_elapsed = 0.001 + difftime(current_time, os_last_printout);
buf += sprintf(buf,
"Pending flushes (fsync) log: %lu; buffer pool: %lu\n",
......@@ -2520,6 +2520,21 @@ loop:
os_last_printout = current_time;
}
/**************************************************************************
Refreshes the statistics used to print per-second averages. */
void
os_aio_refresh_stats(void)
/*======================*/
{
os_n_file_reads_old = os_n_file_reads;
os_n_file_writes_old = os_n_file_writes;
os_n_fsyncs_old = os_n_fsyncs;
os_bytes_read_since_printout = 0;
os_last_printout = time(NULL);
}
/**************************************************************************
Checks that all slots in the system have been freed, that is, there are
no pending io operations. */
......
......@@ -18,37 +18,63 @@ Created 9/8/1995 Heikki Tuuri
#include "srv0srv.h"
/*********************************************************************
Returns the thread identifier of current thread. */
os_thread_id_t
os_thread_get_curr_id(void)
/*=======================*/
/*******************************************************************
Compares two threads or thread ids for equality */
ibool
os_thread_eq(
/*=========*/
/* out: TRUE if equal */
os_thread_t a, /* in: OS thread or thread id */
os_thread_t b) /* in: OS thread or thread id */
{
#ifdef __WIN__
return(GetCurrentThreadId());
if (a == b) {
return(TRUE);
}
return(FALSE);
#else
pthread_t pthr;
if (pthread_equal(a, b)) {
return(TRUE);
}
pthr = pthread_self();
return(FALSE);
#endif
}
#ifdef HPUX
/* TODO: in the future we have to change os_thread_id
to pthread_t! */
/********************************************************************
Converts an OS thread or thread id to a ulint. It is NOT guaranteed that
the ulint is unique for the thread though! */
/* In HP-UX a pthread_t seems to be a struct of three fields:
field1, field2, field3, and the first probably determines (?)
the thread identity. */
ulint
os_thread_pf(
/*=========*/
os_thread_t a)
{
#ifdef UNIV_HPUX
/* In HP-UX a pthread_t is a struct of 3 fields: field1, field2,
field3. We do not know if field1 determines the thread uniquely. */
return((os_thread_id_t)(pthr.field1));
return((ulint)(a.field1));
#else
/* TODO: define os_thread_id_t in Unix as the same as pthread_t
and compare them with appropriate Posix pthread functions!
The following typecast will not work if pthread_t is not
an integer or a pointer to a unique object for the thread! */
return((os_thread_id_t)pthr);
return((ulint)a);
#endif
}
/*********************************************************************
Returns the thread identifier of current thread. Currently the thread
identifier is the thread handle itself. Note that in HP-UX pthread_t is
a struct of 3 fields. */
os_thread_id_t
os_thread_get_curr_id(void)
/*=======================*/
{
#ifdef __WIN__
return(GetCurrentThread());
#else
return(pthread_self());
#endif
}
......@@ -81,7 +107,6 @@ os_thread_create(
arg,
0, /* thread runs immediately */
thread_id);
ut_a(thread);
if (srv_set_thread_priorities) {
......@@ -118,7 +143,7 @@ Returns handle to the current thread. */
os_thread_t
os_thread_get_curr(void)
/*=======================*/
/*====================*/
{
#ifdef __WIN__
return(GetCurrentThread());
......@@ -126,18 +151,6 @@ os_thread_get_curr(void)
return(pthread_self());
#endif
}
/*********************************************************************
Converts a thread id to a ulint. */
ulint
os_thread_conv_id_to_ulint(
/*=======================*/
/* out: converted to ulint */
os_thread_id_t id) /* in: thread id */
{
return((ulint)id);
}
/*********************************************************************
Advises the os to give up remainder of the thread's time slice. */
......
......@@ -2018,7 +2018,7 @@ srv_table_reserve_slot_for_mysql(void)
fprintf(stderr,
"Slot %lu: thread id %lu, type %lu, in use %lu, susp %lu, time %lu\n",
i, (ulint)(slot->id),
i, os_thread_pf(slot->id),
slot->type, slot->in_use,
slot->suspended,
(ulint)difftime(ut_time(), slot->suspend_time));
......@@ -2162,6 +2162,34 @@ srv_release_mysql_thread_if_suspended(
/* not found */
}
/**********************************************************************
Refreshes the values used to calculate per-second averages. */
static
void
srv_refresh_innodb_monitor_stats(void)
/*==================================*/
{
mutex_enter(&srv_innodb_monitor_mutex);
srv_last_monitor_time = time(NULL);
os_aio_refresh_stats();
btr_cur_n_sea_old = btr_cur_n_sea;
btr_cur_n_non_sea_old = btr_cur_n_non_sea;
log_refresh_stats();
buf_refresh_io_stats();
srv_n_rows_inserted_old = srv_n_rows_inserted;
srv_n_rows_updated_old = srv_n_rows_updated;
srv_n_rows_deleted_old = srv_n_rows_deleted;
srv_n_rows_read_old = srv_n_rows_read;
mutex_exit(&srv_innodb_monitor_mutex);
}
/**********************************************************************
Sprintfs to a buffer the output of the InnoDB Monitor. */
......@@ -2199,7 +2227,7 @@ srv_sprintf_innodb_monitor(
"=====================================\n");
buf += sprintf(buf,
"Per second values calculated from the last %lu seconds\n",
"Per second averages calculated from the last %lu seconds\n",
(ulint)time_elapsed);
buf += sprintf(buf, "----------\n"
......@@ -2236,8 +2264,8 @@ srv_sprintf_innodb_monitor(
/ time_elapsed,
(btr_cur_n_non_sea - btr_cur_n_non_sea_old)
/ time_elapsed);
btr_cur_n_sea_old = btr_cur_n_sea;
btr_cur_n_non_sea_old = btr_cur_n_non_sea;
btr_cur_n_sea_old = btr_cur_n_sea;
btr_cur_n_non_sea_old = btr_cur_n_non_sea;
buf += sprintf(buf,"---\n"
"LOG\n"
......@@ -2279,10 +2307,10 @@ srv_sprintf_innodb_monitor(
(srv_n_rows_read - srv_n_rows_read_old)
/ time_elapsed);
srv_n_rows_inserted_old = srv_n_rows_inserted;
srv_n_rows_updated_old = srv_n_rows_updated;
srv_n_rows_deleted_old = srv_n_rows_deleted;
srv_n_rows_read_old = srv_n_rows_read;
srv_n_rows_inserted_old = srv_n_rows_inserted;
srv_n_rows_updated_old = srv_n_rows_updated;
srv_n_rows_deleted_old = srv_n_rows_deleted;
srv_n_rows_read_old = srv_n_rows_read;
buf += sprintf(buf, "----------------------------\n"
"END OF INNODB MONITOR OUTPUT\n"
......@@ -2325,7 +2353,7 @@ loop:
/* When someone is waiting for a lock, we wake up every second
and check if a timeout has passed for a lock wait */
os_thread_sleep(1000000);
os_thread_sleep(1000000);
/* In case mutex_exit is not a memory barrier, it is
theoretically possible some threads are left waiting though
......@@ -2342,9 +2370,9 @@ loop:
if (srv_print_innodb_monitor) {
buf = mem_alloc(100000);
buf = mem_alloc(100000);
srv_sprintf_innodb_monitor(buf, 100000);
srv_sprintf_innodb_monitor(buf, 100000);
printf("%s", buf);
......@@ -2485,6 +2513,13 @@ loop:
os_thread_sleep(2000000);
if (difftime(time(NULL), srv_last_monitor_time) > 60) {
/* We referesh InnoDB Monitor values so that averages are
printed from at most 60 last seconds */
srv_refresh_innodb_monitor_stats();
}
/* mem_print_new_info();
if (cnt % 10 == 0) {
......
......@@ -74,6 +74,12 @@ ulint ios;
ulint n[SRV_MAX_N_IO_THREADS + 5];
os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
/* We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
os_fast_mutex_t srv_os_test_mutex;
ibool srv_os_test_mutex_is_locked = FALSE;
#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
#define SRV_MAX_N_PENDING_SYNC_IOS 100
......@@ -1353,6 +1359,22 @@ innobase_start_or_create_for_mysql(void)
tablespace_size_in_header, sum_of_data_file_sizes);
}
/* Check that os_fast_mutexes work as exptected */
os_fast_mutex_init(&srv_os_test_mutex);
if (0 != os_fast_mutex_trylock(&srv_os_test_mutex)) {
fprintf(stderr,
"InnoDB: Error: pthread_mutex_trylock returns an unexpected value on\n"
"InnoDB: success! Cannot continue.\n");
exit(1);
}
os_fast_mutex_unlock(&srv_os_test_mutex);
os_fast_mutex_lock(&srv_os_test_mutex);
os_fast_mutex_unlock(&srv_os_test_mutex);
ut_print_timestamp(stderr);
fprintf(stderr, " InnoDB: Started\n");
......
......@@ -454,7 +454,7 @@ sync_array_cell_print(
buf += sprintf(buf,
"--Thread %lu has waited at %s line %lu for %.2f seconds the semaphore:\n",
(ulint)cell->thread, cell->file, cell->line,
os_thread_pf(cell->thread), cell->file, cell->line,
difftime(time(NULL), cell->reservation_time));
if (type == SYNC_MUTEX) {
......@@ -486,7 +486,7 @@ sync_array_cell_print(
if (rwlock->writer != RW_LOCK_NOT_LOCKED) {
buf += sprintf(buf,
"a writer (thread id %lu) has reserved it in mode",
(ulint)rwlock->writer_thread);
os_thread_pf(rwlock->writer_thread));
if (rwlock->writer == RW_LOCK_EX) {
buf += sprintf(buf, " exclusive\n");
} else {
......@@ -535,8 +535,8 @@ sync_array_find_thread(
cell = sync_array_get_nth_cell(arr, i);
if ((cell->wait_object != NULL)
&& (cell->thread == thread)) {
if (cell->wait_object != NULL
&& os_thread_eq(cell->thread, thread)) {
return(cell); /* Found */
}
......@@ -651,9 +651,9 @@ sync_array_detect_deadlock(
sync_array_cell_print(buf, cell);
printf(
"Mutex %lx owned by thread %lu file %s line %lu\n%s",
(ulint)mutex, mutex->thread_id,
mutex->file_name, mutex->line,
buf);
(ulint)mutex, os_thread_pf(mutex->thread_id),
mutex->file_name, mutex->line, buf);
return(TRUE);
}
}
......@@ -671,9 +671,9 @@ sync_array_detect_deadlock(
thread = debug->thread_id;
if (((debug->lock_type == RW_LOCK_EX)
&& (thread != cell->thread))
&& !os_thread_eq(thread, cell->thread))
|| ((debug->lock_type == RW_LOCK_WAIT_EX)
&& (thread != cell->thread))
&& !os_thread_eq(thread, cell->thread))
|| (debug->lock_type == RW_LOCK_SHARED)) {
/* The (wait) x-lock request can block infinitely
......@@ -771,7 +771,7 @@ sync_arr_cell_can_wake_up(
if (rw_lock_get_reader_count(lock) == 0
&& rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX
&& lock->writer_thread == cell->thread) {
&& os_thread_eq(lock->writer_thread, cell->thread)) {
return(TRUE);
}
......@@ -927,7 +927,7 @@ sync_array_print_long_waits(void)
&& difftime(time(NULL), cell->reservation_time) > 420) {
fprintf(stderr,
"InnoDB: Error: semaphore wait has lasted > 420 seconds\n"
"InnoDB: Error: semaphore wait has lasted > 600 seconds\n"
"InnoDB: We intentionally crash the server, because it appears to be hung.\n"
);
......@@ -1011,3 +1011,4 @@ sync_array_print_info(
sync_array_exit(arr);
}
......@@ -223,7 +223,7 @@ lock_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu spin wait rw-s-lock at %lx cfile %s cline %lu rnds %lu\n",
os_thread_get_curr_id(), (ulint)lock,
os_thread_pf(os_thread_get_curr_id()), (ulint)lock,
lock->cfile_name, lock->cline, i);
}
......@@ -253,7 +253,7 @@ lock_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu OS wait rw-s-lock at %lx cfile %s cline %lu\n",
os_thread_get_curr_id(), (ulint)lock,
os_thread_pf(os_thread_get_curr_id()), (ulint)lock,
lock->cfile_name, lock->cline);
}
......@@ -343,7 +343,8 @@ rw_lock_x_lock_low(
}
} else if ((rw_lock_get_writer(lock) == RW_LOCK_WAIT_EX)
&& (lock->writer_thread == os_thread_get_curr_id())) {
&& os_thread_eq(lock->writer_thread,
os_thread_get_curr_id())) {
if (rw_lock_get_reader_count(lock) == 0) {
......@@ -368,7 +369,8 @@ rw_lock_x_lock_low(
return(RW_LOCK_WAIT_EX);
} else if ((rw_lock_get_writer(lock) == RW_LOCK_EX)
&& (lock->writer_thread == os_thread_get_curr_id())
&& os_thread_eq(lock->writer_thread,
os_thread_get_curr_id())
&& (lock->pass == 0)
&& (pass == 0)) {
......@@ -469,7 +471,7 @@ lock_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu spin wait rw-x-lock at %lx cfile %s cline %lu rnds %lu\n",
os_thread_get_curr_id(), (ulint)lock,
os_thread_pf(os_thread_get_curr_id()), (ulint)lock,
lock->cfile_name, lock->cline, i);
}
......@@ -502,8 +504,8 @@ lock_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu OS wait for rw-x-lock at %lx cfile %s cline %lu\n",
os_thread_get_curr_id(), (ulint)lock, lock->cfile_name,
lock->cline);
os_thread_pf(os_thread_get_curr_id()), (ulint)lock,
lock->cfile_name, lock->cline);
}
rw_x_system_call_count++;
......@@ -621,7 +623,8 @@ rw_lock_remove_debug_info(
while (info != NULL) {
if ((pass == info->pass)
&& ((pass != 0)
|| (info->thread_id == os_thread_get_curr_id()))
|| os_thread_eq(info->thread_id,
os_thread_get_curr_id()))
&& (info->lock_type == lock_type)) {
/* Found! */
......@@ -676,7 +679,7 @@ rw_lock_own(
while (info != NULL) {
if ((info->thread_id == os_thread_get_curr_id())
if (os_thread_eq(info->thread_id, os_thread_get_curr_id())
&& (info->pass == 0)
&& (info->lock_type == lock_type)) {
......@@ -834,7 +837,7 @@ rw_lock_debug_print(
rwt = info->lock_type;
printf("Locked: thread %ld file %s line %ld ",
info->thread_id, info->file_name, info->line);
os_thread_pf(info->thread_id), info->file_name, info->line);
if (rwt == RW_LOCK_SHARED) {
printf("S-LOCK");
} else if (rwt == RW_LOCK_EX) {
......
......@@ -230,7 +230,6 @@ mutex_create_func(
mutex->magic_n = MUTEX_MAGIC_N;
mutex->line = 0;
mutex->file_name = "not yet reserved";
mutex->thread_id = ULINT_UNDEFINED;
mutex->level = SYNC_LEVEL_NONE;
mutex->cfile_name = cfile_name;
mutex->cline = cline;
......@@ -392,8 +391,8 @@ spin_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu spin wait mutex at %lx cfile %s cline %lu rnds %lu\n",
os_thread_get_curr_id(), (ulint)mutex, mutex->cfile_name,
mutex->cline, i);
os_thread_pf(os_thread_get_curr_id()), (ulint)mutex,
mutex->cfile_name, mutex->cline, i);
}
mutex_spin_round_count += i;
......@@ -458,7 +457,7 @@ spin_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu spin wait succeeds at 2: mutex at %lx\n",
os_thread_get_curr_id(), (ulint)mutex);
os_thread_pf(os_thread_get_curr_id()), (ulint)mutex);
}
return;
......@@ -476,8 +475,8 @@ spin_loop:
if (srv_print_latch_waits) {
printf(
"Thread %lu OS wait mutex at %lx cfile %s cline %lu rnds %lu\n",
os_thread_get_curr_id(), (ulint)mutex, mutex->cfile_name,
mutex->cline, i);
os_thread_pf(os_thread_get_curr_id()), (ulint)mutex,
mutex->cfile_name, mutex->cline, i);
}
mutex_system_call_count++;
......@@ -572,7 +571,7 @@ mutex_own(
return(FALSE);
}
if (mutex->thread_id != os_thread_get_curr_id()) {
if (!os_thread_eq(mutex->thread_id, os_thread_get_curr_id())) {
return(FALSE);
}
......@@ -611,7 +610,8 @@ mutex_list_print_info(void)
&thread_id);
printf(
"Locked mutex: addr %lx thread %ld file %s line %ld\n",
(ulint)mutex, thread_id, file_name, line);
(ulint)mutex, os_thread_pf(thread_id),
file_name, line);
}
mutex = UT_LIST_GET_NEXT(list, mutex);
......@@ -716,7 +716,7 @@ sync_thread_level_arrays_find_slot(void)
slot = sync_thread_level_arrays_get_nth(i);
if (slot->levels && (slot->id == id)) {
if (slot->levels && os_thread_eq(slot->id, id)) {
return(slot);
}
......@@ -780,7 +780,7 @@ sync_thread_levels_g(
{
char* file_name;
ulint line;
ulint thread_id;
os_thread_id_t thread_id;
sync_level_t* slot;
rw_lock_t* lock;
mutex_t* mutex;
......@@ -810,7 +810,7 @@ sync_thread_levels_g(
&file_name, &line, &thread_id);
printf("InnoDB: Locked mutex: addr %lx thread %ld file %s line %ld\n",
(ulint)mutex, thread_id,
(ulint)mutex, os_thread_pf(thread_id),
file_name, line);
} else {
printf("Not locked\n");
......
......@@ -69,8 +69,8 @@ try_again:
local = NULL;
HASH_SEARCH(hash, thr_local_hash, os_thread_conv_id_to_ulint(id),
local, local->id == id);
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
local, os_thread_eq(local->id, id));
if (local == NULL) {
mutex_exit(&thr_local_mutex);
......@@ -173,7 +173,7 @@ thr_local_create(void)
mutex_enter(&thr_local_mutex);
HASH_INSERT(thr_local_t, hash, thr_local_hash,
os_thread_conv_id_to_ulint(os_thread_get_curr_id()),
os_thread_pf(os_thread_get_curr_id()),
local);
mutex_exit(&thr_local_mutex);
......@@ -193,8 +193,8 @@ thr_local_free(
/* Look for the local struct in the hash table */
HASH_SEARCH(hash, thr_local_hash, os_thread_conv_id_to_ulint(id),
local, local->id == id);
HASH_SEARCH(hash, thr_local_hash, os_thread_pf(id),
local, os_thread_eq(local->id, id));
if (local == NULL) {
mutex_exit(&thr_local_mutex);
......@@ -202,7 +202,7 @@ thr_local_free(
}
HASH_DELETE(thr_local_t, hash, thr_local_hash,
os_thread_conv_id_to_ulint(id), local);
os_thread_pf(id), local);
mutex_exit(&thr_local_mutex);
......
......@@ -1487,7 +1487,7 @@ trx_print(
}
buf += sprintf(buf, ", OS thread id %lu",
(ulint)trx->mysql_thread_id);
os_thread_pf(trx->mysql_thread_id));
if (ut_strlen(trx->op_info) > 0) {
buf += sprintf(buf, " %s", trx->op_info);
......
......@@ -55,6 +55,7 @@ typedef byte mysql_byte;
extern "C" {
#include "../innobase/include/univ.i"
#include "../innobase/include/os0file.h"
#include "../innobase/include/os0thread.h"
#include "../innobase/include/srv0start.h"
#include "../innobase/include/srv0srv.h"
#include "../innobase/include/trx0roll.h"
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment