Commit 08cf3b39 authored by marko's avatar marko

branches/zip: Merge revisions 6206:6350 from branches/5.1,

except r6347, r6349, r6350 which were committed separately
to both branches, and r6310, which was backported from zip to 5.1.

  ------------------------------------------------------------------------
  r6206 | jyang | 2009-11-20 09:38:43 +0200 (Fri, 20 Nov 2009) | 3 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc

  branches/5.1: Non-functional change, fix formatting.
  ------------------------------------------------------------------------
  r6230 | sunny | 2009-11-24 23:52:43 +0200 (Tue, 24 Nov 2009) | 3 lines
  Changed paths:
     M /branches/5.1/mysql-test/innodb-autoinc.result

  branches/5.1: Fix autoinc failing test results.
  (this should be skipped when merging 5.1 into zip)
  ------------------------------------------------------------------------
  r6231 | sunny | 2009-11-25 10:26:27 +0200 (Wed, 25 Nov 2009) | 7 lines
  Changed paths:
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test
     M /branches/5.1/row/row0sel.c

  branches/5.1: Fix BUG#49032 - auto_increment field does not initialize to last value in InnoDB Storage Engine.

  We use the appropriate function to read the column value for non-integer
  autoinc column types, namely float and double.

  rb://208. Approved by Marko.
  ------------------------------------------------------------------------
  r6232 | sunny | 2009-11-25 10:27:39 +0200 (Wed, 25 Nov 2009) | 2 lines
  Changed paths:
     M /branches/5.1/row/row0sel.c

  branches/5.1: This is an interim fix, fix white space errors.
  ------------------------------------------------------------------------
  r6233 | sunny | 2009-11-25 10:28:35 +0200 (Wed, 25 Nov 2009) | 2 lines
  Changed paths:
     M /branches/5.1/include/mach0data.h
     M /branches/5.1/include/mach0data.ic
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test
     M /branches/5.1/row/row0sel.c

  branches/5.1: This is an interim fix, fix tests and make read float/double arg const.
  ------------------------------------------------------------------------
  r6234 | sunny | 2009-11-25 10:29:03 +0200 (Wed, 25 Nov 2009) | 2 lines
  Changed paths:
     M /branches/5.1/row/row0sel.c

  branches/5.1: This is an interim fix, fix whitepsace issues.
  ------------------------------------------------------------------------
  r6235 | sunny | 2009-11-26 01:14:42 +0200 (Thu, 26 Nov 2009) | 9 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test

  branches/5.1: Fix Bug#47720 - REPLACE INTO Autoincrement column with negative values.

  This bug is similiar to the negative autoinc filter patch from earlier,
  with the additional handling of filtering out the negative column values
  set explicitly by the user.

  rb://184
  Approved by Heikki.
  ------------------------------------------------------------------------
  r6242 | vasil | 2009-11-27 22:07:12 +0200 (Fri, 27 Nov 2009) | 4 lines
  Changed paths:
     M /branches/5.1/export.sh

  branches/5.1:

  Minor changes to support plugin snapshots.
  ------------------------------------------------------------------------
  r6306 | calvin | 2009-12-14 15:12:46 +0200 (Mon, 14 Dec 2009) | 5 lines
  Changed paths:
     M /branches/5.1/mysql-test/innodb-autoinc.result
     M /branches/5.1/mysql-test/innodb-autoinc.test

  branches/5.1: fix bug#49267: innodb-autoinc.test fails on windows
  because of different case mode

  There is no change to the InnoDB code, only to fix test case by
  changing "T1" to "t1".
  ------------------------------------------------------------------------
  r6324 | jyang | 2009-12-17 06:54:24 +0200 (Thu, 17 Dec 2009) | 8 lines
  Changed paths:
     M /branches/5.1/handler/ha_innodb.cc
     M /branches/5.1/include/lock0lock.h
     M /branches/5.1/include/srv0srv.h
     M /branches/5.1/lock/lock0lock.c
     M /branches/5.1/log/log0log.c
     M /branches/5.1/srv/srv0srv.c
     M /branches/5.1/srv/srv0start.c

  branches/5.1: Fix bug #47814 - Diagnostics are frequently not
  printed after a long lock wait in InnoDB. Separate out the
  lock wait timeout check thread from monitor information
  printing thread.

  rb://200 Approved by Marko.
  ------------------------------------------------------------------------
parent b117b57a
...@@ -4463,24 +4463,29 @@ ha_innobase::write_row( ...@@ -4463,24 +4463,29 @@ ha_innobase::write_row(
update the table upper limit. Note: last_value update the table upper limit. Note: last_value
will be 0 if get_auto_increment() was not called.*/ will be 0 if get_auto_increment() was not called.*/
if (auto_inc <= col_max_value if (auto_inc >= prebuilt->autoinc_last_value) {
&& auto_inc >= prebuilt->autoinc_last_value) {
set_max_autoinc: set_max_autoinc:
ut_a(prebuilt->autoinc_increment > 0); /* This should filter out the negative
values set explicitly by the user. */
if (auto_inc <= col_max_value) {
ut_a(prebuilt->autoinc_increment > 0);
ulonglong need; ulonglong need;
ulonglong offset; ulonglong offset;
offset = prebuilt->autoinc_offset; offset = prebuilt->autoinc_offset;
need = prebuilt->autoinc_increment; need = prebuilt->autoinc_increment;
auto_inc = innobase_next_autoinc( auto_inc = innobase_next_autoinc(
auto_inc, need, offset, col_max_value); auto_inc,
need, offset, col_max_value);
err = innobase_set_max_autoinc(auto_inc); err = innobase_set_max_autoinc(
auto_inc);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
error = err; error = err;
}
} }
} }
break; break;
...@@ -8191,8 +8196,8 @@ innodb_show_status( ...@@ -8191,8 +8196,8 @@ innodb_show_status(
mutex_enter(&srv_monitor_file_mutex); mutex_enter(&srv_monitor_file_mutex);
rewind(srv_monitor_file); rewind(srv_monitor_file);
srv_printf_innodb_monitor(srv_monitor_file, srv_printf_innodb_monitor(srv_monitor_file, FALSE,
&trx_list_start, &trx_list_end); &trx_list_start, &trx_list_end);
flen = ftell(srv_monitor_file); flen = ftell(srv_monitor_file);
os_file_set_eof(srv_monitor_file); os_file_set_eof(srv_monitor_file);
......
...@@ -613,13 +613,16 @@ lock_rec_print( ...@@ -613,13 +613,16 @@ lock_rec_print(
FILE* file, /*!< in: file where to print */ FILE* file, /*!< in: file where to print */
const lock_t* lock); /*!< in: record type lock */ const lock_t* lock); /*!< in: record type lock */
/*********************************************************************//** /*********************************************************************//**
Prints info of locks for all transactions. */ Prints info of locks for all transactions.
@return FALSE if not able to obtain kernel mutex
and exits without printing info */
UNIV_INTERN UNIV_INTERN
void ibool
lock_print_info_summary( lock_print_info_summary(
/*====================*/ /*====================*/
FILE* file); /*!< in: file where to print */ FILE* file, /*!< in: file where to print */
/*********************************************************************//** ibool nowait);/*!< in: whether to wait for the kernel mutex */
/*************************************************************************
Prints info of locks for each transaction. */ Prints info of locks for each transaction. */
UNIV_INTERN UNIV_INTERN
void void
......
...@@ -227,7 +227,8 @@ extern ibool srv_print_innodb_tablespace_monitor; ...@@ -227,7 +227,8 @@ extern ibool srv_print_innodb_tablespace_monitor;
extern ibool srv_print_verbose_log; extern ibool srv_print_verbose_log;
extern ibool srv_print_innodb_table_monitor; extern ibool srv_print_innodb_table_monitor;
extern ibool srv_lock_timeout_and_monitor_active; extern ibool srv_lock_timeout_active;
extern ibool srv_monitor_active;
extern ibool srv_error_monitor_active; extern ibool srv_error_monitor_active;
extern ulong srv_n_spin_wait_rounds; extern ulong srv_n_spin_wait_rounds;
...@@ -540,15 +541,23 @@ srv_release_mysql_thread_if_suspended( ...@@ -540,15 +541,23 @@ srv_release_mysql_thread_if_suspended(
MySQL OS thread */ MySQL OS thread */
/*********************************************************************//** /*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long. A thread which wakes up threads whose lock wait may have lasted too long.
This also prints the info output by various InnoDB monitors.
@return a dummy parameter */ @return a dummy parameter */
UNIV_INTERN UNIV_INTERN
os_thread_ret_t os_thread_ret_t
srv_lock_timeout_and_monitor_thread( srv_lock_timeout_thread(
/*================================*/ /*====================*/
void* arg); /*!< in: a dummy parameter required by void* arg); /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
/*********************************************************************//** /*********************************************************************//**
A thread which prints the info output by various InnoDB monitors.
@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_monitor_thread(
/*===============*/
void* arg); /*!< in: a dummy parameter required by
os_thread_create */
/*************************************************************************
A thread which prints warnings about semaphore waits which have lasted A thread which prints warnings about semaphore waits which have lasted
too long. These can be used to track bugs which cause hangs. too long. These can be used to track bugs which cause hangs.
@return a dummy parameter */ @return a dummy parameter */
...@@ -559,12 +568,15 @@ srv_error_monitor_thread( ...@@ -559,12 +568,15 @@ srv_error_monitor_thread(
void* arg); /*!< in: a dummy parameter required by void* arg); /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
/******************************************************************//** /******************************************************************//**
Outputs to a file the output of the InnoDB Monitor. */ Outputs to a file the output of the InnoDB Monitor.
@return FALSE if not all information printed
due to failure to obtain necessary mutex */
UNIV_INTERN UNIV_INTERN
void ibool
srv_printf_innodb_monitor( srv_printf_innodb_monitor(
/*======================*/ /*======================*/
FILE* file, /*!< in: output stream */ FILE* file, /*!< in: output stream */
ibool nowait, /*!< in: whether to wait for kernel mutex */
ulint* trx_start, /*!< out: file position of the start of ulint* trx_start, /*!< out: file position of the start of
the list of active transactions */ the list of active transactions */
ulint* trx_end); /*!< out: file position of the end of ulint* trx_end); /*!< out: file position of the end of
......
...@@ -4317,14 +4317,26 @@ lock_get_n_rec_locks(void) ...@@ -4317,14 +4317,26 @@ lock_get_n_rec_locks(void)
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */ #endif /* PRINT_NUM_OF_LOCK_STRUCTS */
/*********************************************************************//** /*********************************************************************//**
Prints info of locks for all transactions. */ Prints info of locks for all transactions.
@return FALSE if not able to obtain kernel mutex
and exits without printing info */
UNIV_INTERN UNIV_INTERN
void ibool
lock_print_info_summary( lock_print_info_summary(
/*====================*/ /*====================*/
FILE* file) /*!< in: file where to print */ FILE* file, /*!< in: file where to print */
ibool nowait) /*!< in: whether to wait for the kernel mutex */
{ {
lock_mutex_enter_kernel(); /* if nowait is FALSE, wait on the kernel mutex,
otherwise return immediately if fail to obtain the
mutex. */
if (!nowait) {
lock_mutex_enter_kernel();
} else if (mutex_enter_nowait(&kernel_mutex)) {
fputs("FAIL TO OBTAIN KERNEL MUTEX, "
"SKIP LOCK INFO PRINTING\n", file);
return(FALSE);
}
if (lock_deadlock_found) { if (lock_deadlock_found) {
fputs("------------------------\n" fputs("------------------------\n"
...@@ -4356,6 +4368,7 @@ lock_print_info_summary( ...@@ -4356,6 +4368,7 @@ lock_print_info_summary(
"Total number of lock structs in row lock hash table %lu\n", "Total number of lock structs in row lock hash table %lu\n",
(ulong) lock_get_n_rec_locks()); (ulong) lock_get_n_rec_locks());
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */ #endif /* PRINT_NUM_OF_LOCK_STRUCTS */
return(TRUE);
} }
/*********************************************************************//** /*********************************************************************//**
......
...@@ -3095,7 +3095,7 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3095,7 +3095,7 @@ logs_empty_and_mark_files_at_shutdown(void)
if (srv_fast_shutdown < 2 if (srv_fast_shutdown < 2
&& (srv_error_monitor_active && (srv_error_monitor_active
|| srv_lock_timeout_and_monitor_active)) { || srv_lock_timeout_active || srv_monitor_active)) {
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
......
...@@ -1111,18 +1111,82 @@ c1 c2 ...@@ -1111,18 +1111,82 @@ c1 c2
3 innodb 3 innodb
4 NULL 4 NULL
DROP TABLE t1; DROP TABLE t1;
CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
CREATE INDEX i1 on T1(c2); CREATE INDEX i1 on t1(c2);
SHOW CREATE TABLE T1; SHOW CREATE TABLE t1;
Table Create Table Table Create Table
T1 CREATE TABLE `T1` ( t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT, `c1` int(11) NOT NULL AUTO_INCREMENT,
`c2` int(11) DEFAULT NULL, `c2` int(11) DEFAULT NULL,
PRIMARY KEY (`c1`), PRIMARY KEY (`c1`),
KEY `i1` (`c2`) KEY `i1` (`c2`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1 ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=latin1
INSERT INTO T1 (c2) values (0); INSERT INTO t1 (c2) values (0);
SELECT * FROM T1; SELECT * FROM t1;
c1 c2 c1 c2
10 0 10 0
DROP TABLE T1; DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
INSERT INTO t1(C2) VALUES ('innodb');
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`C1` double NOT NULL AUTO_INCREMENT,
`C2` char(10) DEFAULT NULL,
PRIMARY KEY (`C1`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
DROP TABLE t1;
CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
INSERT INTO t1(C2) VALUES ('innodb');
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`C1` float NOT NULL AUTO_INCREMENT,
`C2` char(10) DEFAULT NULL,
PRIMARY KEY (`C1`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
DROP TABLE t1;
DROP TABLE IF EXISTS t1;
Warnings:
Note 1051 Unknown table 't1'
CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 SET c1 = 1;
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1
INSERT INTO t1 SET c1 = 2;
INSERT INTO t1 SET c1 = -1;
SELECT * FROM t1;
c1
-1
1
2
INSERT INTO t1 SET c1 = -1;
Got one of the listed errors
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
REPLACE INTO t1 VALUES (-1);
SELECT * FROM t1;
c1
-1
1
2
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`c1` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`c1`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1
DROP TABLE t1;
...@@ -610,9 +610,46 @@ DROP TABLE t1; ...@@ -610,9 +610,46 @@ DROP TABLE t1;
# 47125: auto_increment start value is ignored if an index is created # 47125: auto_increment start value is ignored if an index is created
# and engine=innodb # and engine=innodb
# #
CREATE TABLE T1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB; CREATE TABLE t1 (c1 INT AUTO_INCREMENT, c2 INT, PRIMARY KEY(c1)) AUTO_INCREMENT=10 ENGINE=InnoDB;
CREATE INDEX i1 on T1(c2); CREATE INDEX i1 on t1(c2);
SHOW CREATE TABLE T1; SHOW CREATE TABLE t1;
INSERT INTO T1 (c2) values (0); INSERT INTO t1 (c2) values (0);
SELECT * FROM T1; SELECT * FROM t1;
DROP TABLE T1; DROP TABLE t1;
##
# 49032: Use the correct function to read the AUTOINC column value
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1(C1 DOUBLE AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
# Restart the server
-- source include/restart_mysqld.inc
INSERT INTO t1(C2) VALUES ('innodb');
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t1(C1 FLOAT AUTO_INCREMENT KEY, C2 CHAR(10)) ENGINE=InnoDB;
INSERT INTO t1(C1, C2) VALUES (1, 'innodb'), (3, 'innodb');
# Restart the server
-- source include/restart_mysqld.inc
INSERT INTO t1(C2) VALUES ('innodb');
SHOW CREATE TABLE t1;
DROP TABLE t1;
##
# 47720: REPLACE INTO Autoincrement column with negative values
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT AUTO_INCREMENT PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 SET c1 = 1;
SHOW CREATE TABLE t1;
INSERT INTO t1 SET c1 = 2;
INSERT INTO t1 SET c1 = -1;
SELECT * FROM t1;
-- error ER_DUP_ENTRY,1062
INSERT INTO t1 SET c1 = -1;
SHOW CREATE TABLE t1;
REPLACE INTO t1 VALUES (-1);
SELECT * FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
...@@ -4612,6 +4612,7 @@ row_search_autoinc_read_column( ...@@ -4612,6 +4612,7 @@ row_search_autoinc_read_column(
dict_index_t* index, /*!< in: index to read from */ dict_index_t* index, /*!< in: index to read from */
const rec_t* rec, /*!< in: current rec */ const rec_t* rec, /*!< in: current rec */
ulint col_no, /*!< in: column number */ ulint col_no, /*!< in: column number */
ulint mtype, /*!< in: column main type */
ibool unsigned_type) /*!< in: signed or unsigned flag */ ibool unsigned_type) /*!< in: signed or unsigned flag */
{ {
ulint len; ulint len;
...@@ -4628,10 +4629,26 @@ row_search_autoinc_read_column( ...@@ -4628,10 +4629,26 @@ row_search_autoinc_read_column(
data = rec_get_nth_field(rec, offsets, col_no, &len); data = rec_get_nth_field(rec, offsets, col_no, &len);
ut_a(len != UNIV_SQL_NULL); ut_a(len != UNIV_SQL_NULL);
ut_a(len <= sizeof value);
/* we assume AUTOINC value cannot be negative */ switch (mtype) {
value = mach_read_int_type(data, len, unsigned_type); case DATA_INT:
ut_a(len <= sizeof value);
value = mach_read_int_type(data, len, unsigned_type);
break;
case DATA_FLOAT:
ut_a(len == sizeof(float));
value = mach_float_read(data);
break;
case DATA_DOUBLE:
ut_a(len == sizeof(double));
value = mach_double_read(data);
break;
default:
ut_error;
}
if (UNIV_LIKELY_NULL(heap)) { if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap); mem_heap_free(heap);
...@@ -4717,7 +4734,8 @@ row_search_max_autoinc( ...@@ -4717,7 +4734,8 @@ row_search_max_autoinc(
dfield->col->prtype & DATA_UNSIGNED); dfield->col->prtype & DATA_UNSIGNED);
*value = row_search_autoinc_read_column( *value = row_search_autoinc_read_column(
index, rec, i, unsigned_type); index, rec, i,
dfield->col->mtype, unsigned_type);
} }
} }
......
...@@ -119,7 +119,8 @@ UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600; ...@@ -119,7 +119,8 @@ UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600;
in microseconds, in order to reduce the lagging of the purge thread. */ in microseconds, in order to reduce the lagging of the purge thread. */
UNIV_INTERN ulint srv_dml_needed_delay = 0; UNIV_INTERN ulint srv_dml_needed_delay = 0;
UNIV_INTERN ibool srv_lock_timeout_and_monitor_active = FALSE; UNIV_INTERN ibool srv_lock_timeout_active = FALSE;
UNIV_INTERN ibool srv_monitor_active = FALSE;
UNIV_INTERN ibool srv_error_monitor_active = FALSE; UNIV_INTERN ibool srv_error_monitor_active = FALSE;
UNIV_INTERN const char* srv_main_thread_op_info = ""; UNIV_INTERN const char* srv_main_thread_op_info = "";
...@@ -188,7 +189,17 @@ UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1; ...@@ -188,7 +189,17 @@ UNIV_INTERN ulong srv_flush_log_at_trx_commit = 1;
the checkpoints. */ the checkpoints. */
UNIV_INTERN char srv_adaptive_flushing = TRUE; UNIV_INTERN char srv_adaptive_flushing = TRUE;
/* The sort order table of the MySQL latin1_swedish_ci character set /** Maximum number of times allowed to conditionally acquire
mutex before switching to blocking wait on the mutex */
#define MAX_MUTEX_NOWAIT 20
/** Check whether the number of failed nonblocking mutex
acquisition attempts exceeds maximum allowed value. If so,
srv_printf_innodb_monitor() will request mutex acquisition
with mutex_enter(), which will wait until it gets the mutex. */
#define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT)
/** The sort order table of the MySQL latin1_swedish_ci character set
collation */ collation */
UNIV_INTERN const byte* srv_latin1_ordering; UNIV_INTERN const byte* srv_latin1_ordering;
...@@ -1683,12 +1694,15 @@ srv_refresh_innodb_monitor_stats(void) ...@@ -1683,12 +1694,15 @@ srv_refresh_innodb_monitor_stats(void)
} }
/******************************************************************//** /******************************************************************//**
Outputs to a file the output of the InnoDB Monitor. */ Outputs to a file the output of the InnoDB Monitor.
@return FALSE if not all information printed
due to failure to obtain necessary mutex */
UNIV_INTERN UNIV_INTERN
void ibool
srv_printf_innodb_monitor( srv_printf_innodb_monitor(
/*======================*/ /*======================*/
FILE* file, /*!< in: output stream */ FILE* file, /*!< in: output stream */
ibool nowait, /*!< in: whether to wait for kernel mutex */
ulint* trx_start, /*!< out: file position of the start of ulint* trx_start, /*!< out: file position of the start of
the list of active transactions */ the list of active transactions */
ulint* trx_end) /*!< out: file position of the end of ulint* trx_end) /*!< out: file position of the end of
...@@ -1697,6 +1711,7 @@ srv_printf_innodb_monitor( ...@@ -1697,6 +1711,7 @@ srv_printf_innodb_monitor(
double time_elapsed; double time_elapsed;
time_t current_time; time_t current_time;
ulint n_reserved; ulint n_reserved;
ibool ret;
mutex_enter(&srv_innodb_monitor_mutex); mutex_enter(&srv_innodb_monitor_mutex);
...@@ -1746,24 +1761,31 @@ srv_printf_innodb_monitor( ...@@ -1746,24 +1761,31 @@ srv_printf_innodb_monitor(
mutex_exit(&dict_foreign_err_mutex); mutex_exit(&dict_foreign_err_mutex);
lock_print_info_summary(file); /* Only if lock_print_info_summary proceeds correctly,
if (trx_start) { before we call the lock_print_info_all_transactions
long t = ftell(file); to print all the lock information. */
if (t < 0) { ret = lock_print_info_summary(file, nowait);
*trx_start = ULINT_UNDEFINED;
} else { if (ret) {
*trx_start = (ulint) t; if (trx_start) {
long t = ftell(file);
if (t < 0) {
*trx_start = ULINT_UNDEFINED;
} else {
*trx_start = (ulint) t;
}
} }
} lock_print_info_all_transactions(file);
lock_print_info_all_transactions(file); if (trx_end) {
if (trx_end) { long t = ftell(file);
long t = ftell(file); if (t < 0) {
if (t < 0) { *trx_end = ULINT_UNDEFINED;
*trx_end = ULINT_UNDEFINED; } else {
} else { *trx_end = (ulint) t;
*trx_end = (ulint) t; }
} }
} }
fputs("--------\n" fputs("--------\n"
"FILE I/O\n" "FILE I/O\n"
"--------\n", file); "--------\n", file);
...@@ -1861,6 +1883,8 @@ srv_printf_innodb_monitor( ...@@ -1861,6 +1883,8 @@ srv_printf_innodb_monitor(
"============================\n", file); "============================\n", file);
mutex_exit(&srv_innodb_monitor_mutex); mutex_exit(&srv_innodb_monitor_mutex);
fflush(file); fflush(file);
return(ret);
} }
/******************************************************************//** /******************************************************************//**
...@@ -1948,26 +1972,23 @@ srv_export_innodb_status(void) ...@@ -1948,26 +1972,23 @@ srv_export_innodb_status(void)
} }
/*********************************************************************//** /*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long. A thread which prints the info output by various InnoDB monitors.
This also prints the info output by various InnoDB monitors.
@return a dummy parameter */ @return a dummy parameter */
UNIV_INTERN UNIV_INTERN
os_thread_ret_t os_thread_ret_t
srv_lock_timeout_and_monitor_thread( srv_monitor_thread(
/*================================*/ /*===============*/
void* arg __attribute__((unused))) void* arg __attribute__((unused)))
/*!< in: a dummy parameter required by /*!< in: a dummy parameter required by
os_thread_create */ os_thread_create */
{ {
srv_slot_t* slot;
double time_elapsed; double time_elapsed;
time_t current_time; time_t current_time;
time_t last_table_monitor_time; time_t last_table_monitor_time;
time_t last_tablespace_monitor_time; time_t last_tablespace_monitor_time;
time_t last_monitor_time; time_t last_monitor_time;
ibool some_waits; ulint mutex_skipped;
double wait_time; ibool last_srv_print_monitor;
ulint i;
#ifdef UNIV_DEBUG_THREAD_CREATION #ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Lock timeout thread starts, id %lu\n", fprintf(stderr, "Lock timeout thread starts, id %lu\n",
...@@ -1978,13 +1999,15 @@ srv_lock_timeout_and_monitor_thread( ...@@ -1978,13 +1999,15 @@ srv_lock_timeout_and_monitor_thread(
last_table_monitor_time = time(NULL); last_table_monitor_time = time(NULL);
last_tablespace_monitor_time = time(NULL); last_tablespace_monitor_time = time(NULL);
last_monitor_time = time(NULL); last_monitor_time = time(NULL);
mutex_skipped = 0;
last_srv_print_monitor = srv_print_innodb_monitor;
loop: loop:
srv_lock_timeout_and_monitor_active = TRUE; srv_monitor_active = TRUE;
/* When someone is waiting for a lock, we wake up every second /* Wake up every 5 seconds to see if we need to print
and check if a timeout has passed for a lock wait */ monitor information. */
os_thread_sleep(1000000); os_thread_sleep(5000000);
current_time = time(NULL); current_time = time(NULL);
...@@ -1994,14 +2017,40 @@ srv_lock_timeout_and_monitor_thread( ...@@ -1994,14 +2017,40 @@ srv_lock_timeout_and_monitor_thread(
last_monitor_time = time(NULL); last_monitor_time = time(NULL);
if (srv_print_innodb_monitor) { if (srv_print_innodb_monitor) {
srv_printf_innodb_monitor(stderr, NULL, NULL); /* Reset mutex_skipped counter everytime
srv_print_innodb_monitor changes. This is to
ensure we will not be blocked by kernel_mutex
for short duration information printing,
such as requested by sync_array_print_long_waits() */
if (!last_srv_print_monitor) {
mutex_skipped = 0;
last_srv_print_monitor = TRUE;
}
if (!srv_printf_innodb_monitor(stderr,
MUTEX_NOWAIT(mutex_skipped),
NULL, NULL)) {
mutex_skipped++;
} else {
/* Reset the counter */
mutex_skipped = 0;
}
} else {
last_srv_print_monitor = FALSE;
} }
if (srv_innodb_status) { if (srv_innodb_status) {
mutex_enter(&srv_monitor_file_mutex); mutex_enter(&srv_monitor_file_mutex);
rewind(srv_monitor_file); rewind(srv_monitor_file);
srv_printf_innodb_monitor(srv_monitor_file, NULL, if (!srv_printf_innodb_monitor(srv_monitor_file,
NULL); MUTEX_NOWAIT(mutex_skipped),
NULL, NULL)) {
mutex_skipped++;
} else {
mutex_skipped = 0;
}
os_file_set_eof(srv_monitor_file); os_file_set_eof(srv_monitor_file);
mutex_exit(&srv_monitor_file_mutex); mutex_exit(&srv_monitor_file_mutex);
} }
...@@ -2054,6 +2103,56 @@ srv_lock_timeout_and_monitor_thread( ...@@ -2054,6 +2103,56 @@ srv_lock_timeout_and_monitor_thread(
} }
} }
if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
goto exit_func;
}
if (srv_print_innodb_monitor
|| srv_print_innodb_lock_monitor
|| srv_print_innodb_tablespace_monitor
|| srv_print_innodb_table_monitor) {
goto loop;
}
srv_monitor_active = FALSE;
goto loop;
exit_func:
srv_monitor_active = FALSE;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
os_thread_exit(NULL);
OS_THREAD_DUMMY_RETURN;
}
/*********************************************************************//**
A thread which wakes up threads whose lock wait may have lasted too long.
@return a dummy parameter */
UNIV_INTERN
os_thread_ret_t
srv_lock_timeout_thread(
/*====================*/
void* arg __attribute__((unused)))
/* in: a dummy parameter required by
os_thread_create */
{
srv_slot_t* slot;
ibool some_waits;
double wait_time;
ulint i;
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);
srv_lock_timeout_active = TRUE;
mutex_enter(&kernel_mutex); mutex_enter(&kernel_mutex);
some_waits = FALSE; some_waits = FALSE;
...@@ -2104,17 +2203,11 @@ srv_lock_timeout_and_monitor_thread( ...@@ -2104,17 +2203,11 @@ srv_lock_timeout_and_monitor_thread(
goto exit_func; goto exit_func;
} }
if (some_waits || srv_print_innodb_monitor if (some_waits) {
|| srv_print_innodb_lock_monitor
|| srv_print_innodb_tablespace_monitor
|| srv_print_innodb_table_monitor) {
goto loop; goto loop;
} }
/* No one was waiting for a lock and no monitor was active: srv_lock_timeout_active = FALSE;
suspend this thread */
srv_lock_timeout_and_monitor_active = FALSE;
#if 0 #if 0
/* The following synchronisation is disabled, since /* The following synchronisation is disabled, since
...@@ -2124,7 +2217,7 @@ srv_lock_timeout_and_monitor_thread( ...@@ -2124,7 +2217,7 @@ srv_lock_timeout_and_monitor_thread(
goto loop; goto loop;
exit_func: exit_func:
srv_lock_timeout_and_monitor_active = FALSE; srv_lock_timeout_active = FALSE;
/* We count the number of threads in os_thread_exit(). A created /* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */ thread should always use that to exit and not use return() to exit. */
......
...@@ -144,9 +144,9 @@ static mutex_t ios_mutex; ...@@ -144,9 +144,9 @@ static mutex_t ios_mutex;
static ulint ios; static ulint ios;
/** io_handler_thread parameters for thread identification */ /** io_handler_thread parameters for thread identification */
static ulint n[SRV_MAX_N_IO_THREADS + 5]; static ulint n[SRV_MAX_N_IO_THREADS + 6];
/** io_handler_thread identifiers */ /** io_handler_thread identifiers */
static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5]; static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
/** We use this mutex to test the return value of pthread_mutex_trylock /** 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. */ on successful locking. HP-UX does NOT return 0, though Linux et al do. */
...@@ -1671,15 +1671,18 @@ innobase_start_or_create_for_mysql(void) ...@@ -1671,15 +1671,18 @@ innobase_start_or_create_for_mysql(void)
/* fprintf(stderr, "Max allowed record size %lu\n", /* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */ page_get_free_space_of_empty() / 2); */
/* Create the thread which watches the timeouts for lock waits /* Create the thread which watches the timeouts for lock waits */
and prints InnoDB monitor info */ os_thread_create(&srv_lock_timeout_thread, NULL,
os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
thread_ids + 2 + SRV_MAX_N_IO_THREADS); thread_ids + 2 + SRV_MAX_N_IO_THREADS);
/* Create the thread which warns of long semaphore waits */ /* Create the thread which warns of long semaphore waits */
os_thread_create(&srv_error_monitor_thread, NULL, os_thread_create(&srv_error_monitor_thread, NULL,
thread_ids + 3 + SRV_MAX_N_IO_THREADS); thread_ids + 3 + SRV_MAX_N_IO_THREADS);
/* Create the thread which prints InnoDB monitor info */
os_thread_create(&srv_monitor_thread, NULL,
thread_ids + 4 + SRV_MAX_N_IO_THREADS);
srv_is_being_started = FALSE; srv_is_being_started = FALSE;
if (trx_doublewrite == NULL) { if (trx_doublewrite == NULL) {
......
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