1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

merge with 3.23.44

This commit is contained in:
monty@hundin.mysql.fi
2001-11-04 16:14:09 +02:00
115 changed files with 3377 additions and 1379 deletions

View File

@ -24,7 +24,7 @@ thread library. This might confuse NT though.
Created 10/8/1995 Heikki Tuuri
*******************************************************/
/* Dummy comment */
#include "srv0srv.h"
#include "ut0mem.h"
@ -48,11 +48,15 @@ Created 10/8/1995 Heikki Tuuri
#include "buf0flu.h"
#include "btr0sea.h"
#include "dict0load.h"
#include "srv0start.h"
/* The following counter is incremented whenever there is some user activity
in the server */
ulint srv_activity_count = 0;
ibool srv_lock_timeout_and_monitor_active = FALSE;
ibool srv_error_monitor_active = FALSE;
char* srv_main_thread_op_info = "";
/* Server parameters which are read from the initfile */
@ -106,9 +110,48 @@ char* srv_unix_file_flush_method_str = NULL;
ulint srv_unix_file_flush_method = 0;
/* If the following is != 0 we do not allow inserts etc. This protects
the user from forgetting innodb_force_recovery keyword to my.cnf */
the user from forgetting the innodb_force_recovery keyword to my.cnf */
ulint srv_force_recovery = 0;
/*-----------------------*/
/* The following controls how many threads we let inside InnoDB concurrently:
threads waiting for locks are not counted into the number because otherwise
we could get a deadlock. MySQL creates a thread for each user session, and
semaphore contention and convoy problems can occur withput this restriction.
Value 10 should be good if there are less than 4 processors + 4 disks in the
computer. Bigger computers need bigger values. */
ulint srv_thread_concurrency = 4;
os_fast_mutex_t srv_conc_mutex; /* this mutex protects srv_conc data
structures */
ulint srv_conc_n_threads = 0; /* number of OS threads currently
inside InnoDB */
typedef struct srv_conc_slot_struct srv_conc_slot_t;
struct srv_conc_slot_struct{
os_event_t event; /* event to wait */
ibool reserved; /* TRUE if slot
reserved */
ibool wait_ended; /* TRUE when another
thread has already set
the event and the
thread in this slot is
free to proceed; but
reserved may still be
TRUE at that point */
UT_LIST_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue node */
};
UT_LIST_BASE_NODE_T(srv_conc_slot_t) srv_conc_queue; /* queue of threads
waiting to get in */
srv_conc_slot_t srv_conc_slots[OS_THREAD_MAX_N]; /* array of wait
slots */
/*-----------------------*/
/* If the following is set TRUE then we do not run purge and insert buffer
merge to completion before shutdown */
ibool srv_fast_shutdown = FALSE;
ibool srv_use_doublewrite_buf = TRUE;
@ -1512,8 +1555,9 @@ void
srv_init(void)
/*==========*/
{
srv_slot_t* slot;
ulint i;
srv_conc_slot_t* conc_slot;
srv_slot_t* slot;
ulint i;
srv_sys = mem_alloc(sizeof(srv_sys_t));
@ -1556,6 +1600,19 @@ srv_init(void)
ut_a(srv_sys->operational);
UT_LIST_INIT(srv_sys->tasks);
/* Init the server concurrency restriction data structures */
os_fast_mutex_init(&srv_conc_mutex);
UT_LIST_INIT(srv_conc_queue);
for (i = 0; i < OS_THREAD_MAX_N; i++) {
conc_slot = srv_conc_slots + i;
conc_slot->reserved = FALSE;
conc_slot->event = os_event_create(NULL);
ut_a(conc_slot->event);
}
}
/*************************************************************************
@ -1571,6 +1628,140 @@ srv_general_init(void)
thr_local_init();
}
/*************************************************************************
Puts an OS thread to wait if there are too many concurrent threads
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
void
srv_conc_enter_innodb(
/*==================*/
trx_t* trx) /* in: transaction object associated with the
thread */
{
srv_conc_slot_t* slot;
ulint i;
os_fast_mutex_lock(&srv_conc_mutex);
if (srv_conc_n_threads < srv_thread_concurrency) {
srv_conc_n_threads++;
os_fast_mutex_unlock(&srv_conc_mutex);
return;
}
/* Too many threads inside: put to the current thread to a queue */
for (i = 0; i < OS_THREAD_MAX_N; i++) {
slot = srv_conc_slots + i;
if (!slot->reserved) {
break;
}
}
if (i == OS_THREAD_MAX_N) {
/* Could not find a free wait slot, we must let the
thread enter */
srv_conc_n_threads++;
os_fast_mutex_unlock(&srv_conc_mutex);
return;
}
/* Release possible search system latch this thread has */
if (trx->has_search_latch) {
trx_search_latch_release_if_reserved(trx);
}
/* Add to the queue */
slot->reserved = TRUE;
slot->wait_ended = FALSE;
UT_LIST_ADD_LAST(srv_conc_queue, srv_conc_queue, slot);
os_event_reset(slot->event);
os_fast_mutex_unlock(&srv_conc_mutex);
/* Go to wait for the event; when a thread leaves InnoDB it will
release this thread */
os_event_wait(slot->event);
os_fast_mutex_lock(&srv_conc_mutex);
/* NOTE that the thread which released this thread already
incremented the thread counter on behalf of this thread */
slot->reserved = FALSE;
UT_LIST_REMOVE(srv_conc_queue, srv_conc_queue, slot);
os_fast_mutex_unlock(&srv_conc_mutex);
}
/*************************************************************************
This lets a thread enter InnoDB regardless of the number of threads inside
InnoDB. This must be called when a thread ends a lock wait. */
void
srv_conc_force_enter_innodb(void)
/*=============================*/
{
os_fast_mutex_lock(&srv_conc_mutex);
srv_conc_n_threads++;
os_fast_mutex_unlock(&srv_conc_mutex);
}
/*************************************************************************
This must be called when a thread exits InnoDB. This must also be called
when a thread goes to wait for a lock. */
void
srv_conc_exit_innodb(void)
/*======================*/
{
srv_conc_slot_t* slot = NULL;
os_fast_mutex_lock(&srv_conc_mutex);
ut_a(srv_conc_n_threads > 0);
srv_conc_n_threads--;
if (srv_conc_n_threads < srv_thread_concurrency) {
/* Look for a slot where a thread is waiting and no other
thread has yet released the thread */
slot = UT_LIST_GET_FIRST(srv_conc_queue);
while (slot && slot->wait_ended == TRUE) {
slot = UT_LIST_GET_NEXT(srv_conc_queue, slot);
}
if (slot != NULL) {
slot->wait_ended = TRUE;
/* We increment the count on behalf of the released
thread */
srv_conc_n_threads++;
}
}
os_fast_mutex_unlock(&srv_conc_mutex);
if (slot != NULL) {
os_event_set(slot->event);
}
}
/*************************************************************************
Normalizes init parameter values to use units we use inside InnoDB. */
static
@ -1713,10 +1904,20 @@ srv_suspend_mysql_thread(
mutex_exit(&kernel_mutex);
/* We must declare this OS thread to exit InnoDB, since a possible
other thread holding a lock which this thread waits for must be
allowed to enter, sooner or later */
srv_conc_exit_innodb();
/* Wait for the release */
os_event_wait(event);
/* Return back inside InnoDB */
srv_conc_force_enter_innodb();
mutex_enter(&kernel_mutex);
/* Release the slot for others to use */
@ -1792,6 +1993,8 @@ srv_lock_timeout_and_monitor_thread(
UT_NOT_USED(arg);
last_monitor_time = time(NULL);
loop:
srv_lock_timeout_and_monitor_active = TRUE;
/* When someone is waiting for a lock, we wake up every second
and check if a timeout has passed for a lock wait */
@ -1809,9 +2012,9 @@ loop:
if (time_elapsed > 15) {
last_monitor_time = time(NULL);
if (srv_print_innodb_monitor) {
last_monitor_time = time(NULL);
printf("=====================================\n");
ut_print_timestamp(stdout);
@ -1849,8 +2052,9 @@ loop:
printf("--------------\n"
"ROW OPERATIONS\n"
"--------------\n");
printf("InnoDB main thread state: %s\n",
srv_main_thread_op_info);
printf(
"%lu queries inside InnoDB; main thread: %s\n",
srv_conc_n_threads, srv_main_thread_op_info);
printf(
"Number of rows inserted %lu, updated %lu, deleted %lu, read %lu\n",
srv_n_rows_inserted,
@ -1934,7 +2138,7 @@ loop:
(wait_time > (double) srv_lock_wait_timeout
|| wait_time < 0)) {
/* Timeout exceeded or a wrap over in system
/* Timeout exceeded or a wrap-around in system
time counter: cancel the lock request queued
by the transaction and release possible
other transactions waiting behind */
@ -1949,6 +2153,10 @@ loop:
mutex_exit(&kernel_mutex);
if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
goto exit_func;
}
if (some_waits || srv_print_innodb_monitor
|| srv_print_innodb_lock_monitor
|| srv_print_innodb_tablespace_monitor
@ -1958,11 +2166,16 @@ loop:
/* No one was waiting for a lock and no monitor was active:
suspend this thread */
srv_lock_timeout_and_monitor_active = FALSE;
os_event_wait(srv_lock_timeout_thread_event);
goto loop;
exit_func:
srv_lock_timeout_and_monitor_active = FALSE;
#ifndef __WIN__
return(NULL);
#else
@ -1987,11 +2200,18 @@ srv_error_monitor_thread(
{
UT_NOT_USED(arg);
loop:
srv_error_monitor_active = TRUE;
os_thread_sleep(10000000);
sync_array_print_long_waits();
goto loop;
if (srv_shutdown_state < SRV_SHUTDOWN_LAST_PHASE) {
goto loop;
}
srv_error_monitor_active = FALSE;
#ifndef __WIN__
return(NULL);
@ -2079,13 +2299,12 @@ loop:
for (i = 0; i < 10; i++) {
n_ios_old = log_sys->n_log_ios + buf_pool->n_pages_read
+ buf_pool->n_pages_written;
srv_main_thread_op_info = "sleeping";
os_thread_sleep(1000000);
if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
goto loop;
goto suspend_thread;
}
/* We flush the log once in a second even if no commit
@ -2112,6 +2331,11 @@ loop:
log_flush_up_to(ut_dulint_max, LOG_WAIT_ONE_GROUP);
}
if (srv_fast_shutdown && srv_shutdown_state > 0) {
goto background_loop;
}
if (srv_activity_count == old_activity_count) {
if (srv_print_thread_releases) {
@ -2160,6 +2384,11 @@ loop:
while (n_pages_purged) {
if (srv_fast_shutdown && srv_shutdown_state > 0) {
goto background_loop;
}
srv_main_thread_op_info = "purging";
n_pages_purged = trx_purge();
@ -2247,7 +2476,12 @@ background_loop:
log_archive_do(FALSE, &n_bytes_archived);
if (n_pages_purged + n_bytes_merged + n_pages_flushed
if (srv_fast_shutdown && srv_shutdown_state > 0) {
if (n_pages_flushed + n_bytes_archived != 0) {
goto background_loop;
}
} else if (n_pages_purged + n_bytes_merged + n_pages_flushed
+ n_bytes_archived != 0) {
goto background_loop;
}
@ -2261,6 +2495,7 @@ background_loop:
/* There is no work for background operations either: suspend
master thread to wait for more server activity */
suspend_thread:
srv_main_thread_op_info = "suspending";
mutex_enter(&kernel_mutex);