Merge with 4.0.13
This commit is contained in:
commit
40109c574a
@ -71,6 +71,22 @@ else
|
||||
make=make
|
||||
fi
|
||||
|
||||
if test -z $CXX ; then
|
||||
if test -z "$CXX" ; then
|
||||
CXX=gcc
|
||||
fi
|
||||
|
||||
# If ccache (a compiler cache which reduces build time)
|
||||
# (http://samba.org/ccache) is installed, use it.
|
||||
# We use 'grep' and hope 'grep' will work as expected
|
||||
# (returns 0 if finds lines)
|
||||
if ccache -V > /dev/null 2>&1
|
||||
then
|
||||
if ! (echo "$CC" | grep "ccache" > /dev/null)
|
||||
then
|
||||
CC="ccache $CC"
|
||||
fi
|
||||
if ! (echo "$CXX" | grep "ccache" > /dev/null)
|
||||
then
|
||||
CXX="ccache $CXX"
|
||||
fi
|
||||
fi
|
||||
|
@ -39,6 +39,7 @@ jani@hynda.mysql.fi
|
||||
jani@janikt.pp.saunalahti.fi
|
||||
jani@rhols221.adsl.netsonic.fi
|
||||
jani@rhols221.arenanet.fi
|
||||
jani@ua126d19.elisa.omakaista.fi
|
||||
jcole@abel.spaceapes.com
|
||||
jcole@main.burghcom.com
|
||||
jcole@mugatu.spaceapes.com
|
||||
|
@ -44,7 +44,7 @@
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
const char *VER= "14.0";
|
||||
const char *VER= "14.1";
|
||||
|
||||
/* Don't try to make a nice table if the data is too big */
|
||||
#define MAX_COLUMN_LENGTH 1024
|
||||
@ -2929,14 +2929,18 @@ static const char* construct_prompt()
|
||||
add_int_to_prompt(++prompt_counter);
|
||||
break;
|
||||
case 'v':
|
||||
processed_prompt.append(mysql_get_server_info(&mysql));
|
||||
if (connected)
|
||||
processed_prompt.append(mysql_get_server_info(&mysql));
|
||||
else
|
||||
processed_prompt.append("not_connected");
|
||||
break;
|
||||
case 'd':
|
||||
processed_prompt.append(current_db ? current_db : "(none)");
|
||||
break;
|
||||
case 'h':
|
||||
{
|
||||
const char *prompt=mysql_get_host_info(&mysql);
|
||||
const char *prompt;
|
||||
prompt= connected ? mysql_get_host_info(&mysql) : "not_connected";
|
||||
if (strstr(prompt, "Localhost"))
|
||||
processed_prompt.append("localhost");
|
||||
else
|
||||
@ -2948,8 +2952,13 @@ static const char* construct_prompt()
|
||||
}
|
||||
case 'p':
|
||||
#ifndef EMBEDDED_LIBRARY
|
||||
if (!connected)
|
||||
{
|
||||
processed_prompt.append("not_connected");
|
||||
break;
|
||||
}
|
||||
if (strstr(mysql_get_host_info(&mysql),"TCP/IP") ||
|
||||
! mysql.unix_socket)
|
||||
!mysql.unix_socket)
|
||||
add_int_to_prompt(mysql.port);
|
||||
else
|
||||
{
|
||||
|
@ -523,8 +523,12 @@ int dyn_string_cmp(DYNAMIC_STRING* ds, const char* fname)
|
||||
|
||||
if (!my_stat(eval_file, &stat_info, MYF(MY_WME)))
|
||||
die(NullS);
|
||||
if (!eval_result && stat_info.st_size != ds->length)
|
||||
if (!eval_result && (uint) stat_info.st_size != ds->length)
|
||||
{
|
||||
DBUG_PRINT("info",("Size differs: result size: %u file size: %u",
|
||||
ds->length, stat_info.st_size));
|
||||
DBUG_RETURN(2);
|
||||
}
|
||||
if (!(tmp = (char*) my_malloc(stat_info.st_size + 1, MYF(MY_WME))))
|
||||
die(NullS);
|
||||
|
||||
|
14
configure.in
14
configure.in
@ -359,7 +359,7 @@ then
|
||||
# we will gets some problems when linking static programs.
|
||||
# The following code is used to fix this problem.
|
||||
|
||||
if test "$CXX" = "gcc"
|
||||
if test "$CXX" = "gcc" -o "$CXX" = "ccache gcc"
|
||||
then
|
||||
if $CXX -v 2>&1 | grep 'version 3' > /dev/null 2>&1
|
||||
then
|
||||
@ -1023,8 +1023,16 @@ case $SYSTEM_TYPE in
|
||||
;;
|
||||
*freebsd*)
|
||||
echo "Adding fix for interrupted reads"
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
|
||||
CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000 -DHAVE_BROKEN_REALPATH"
|
||||
OSVERSION=`sysctl -a | grep osreldate | awk '{ print $2 }'`
|
||||
if test "$OSVERSION" -gt "480100" && \
|
||||
test "$OSVERSION" -lt "500000" || \
|
||||
test "$OSVERSION" -gt "500109"
|
||||
then
|
||||
CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000"
|
||||
else
|
||||
CFLAGS="$CFLAGS -DHAVE_BROKEN_REALPATH"
|
||||
CXXFLAGS="$CXXFLAGS -DMYSQLD_NET_RETRY_COUNT=1000000 -DHAVE_BROKEN_REALPATH"
|
||||
fi
|
||||
;;
|
||||
*netbsd*)
|
||||
echo "Adding flag -Dunix"
|
||||
|
@ -138,6 +138,11 @@ typedef uint rf_SetTimer;
|
||||
#define SIZEOF_LONG 4
|
||||
#define SIZEOF_LONG_LONG 8
|
||||
#define SIZEOF_OFF_T 8
|
||||
#ifdef _WIN64
|
||||
#define SIZEOF_CHARP 8
|
||||
#else
|
||||
#define SIZEOF_CHARP 4
|
||||
#endif
|
||||
#define HAVE_BROKEN_NETINET_INCLUDES
|
||||
#ifdef __NT__
|
||||
#define HAVE_NAMED_PIPE /* We can only create pipes on NT */
|
||||
@ -203,6 +208,7 @@ inline double ulonglong2double(ulonglong value)
|
||||
|
||||
/* Optimized store functions for Intel x86 */
|
||||
|
||||
#ifndef _WIN64
|
||||
#define sint2korr(A) (*((int16 *) (A)))
|
||||
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
|
||||
(((uint32) 255L << 24) | \
|
||||
@ -243,7 +249,7 @@ inline double ulonglong2double(ulonglong value)
|
||||
#define float8get(V,M) doubleget((V),(M))
|
||||
#define float4store(V,M) memcpy((byte*) V,(byte*) (&M),sizeof(float))
|
||||
#define float8store(V,M) doublestore((V),(M))
|
||||
|
||||
#endif /* _WIN64 */
|
||||
|
||||
#define HAVE_PERROR
|
||||
#define HAVE_VFPRINT
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 2000 MySQL AB
|
||||
/* Copyright (C) 2000-2003 MySQL AB
|
||||
|
||||
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
|
||||
@ -266,7 +266,7 @@ C_MODE_END
|
||||
# endif
|
||||
#endif /* TIME_WITH_SYS_TIME */
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#if defined(HAVE_OPENSSL) && !defined(__FreeBSD__) && !defined(NeXT)
|
||||
#if defined(HAVE_OPENSSL) && !defined(__FreeBSD__) && !defined(NeXT) && !defined(__OpenBSD__)
|
||||
#define crypt unistd_crypt
|
||||
#endif
|
||||
#include <unistd.h>
|
||||
@ -654,7 +654,15 @@ extern double my_atof(const char*);
|
||||
Max size that must be added to a so that we know Size to make
|
||||
adressable obj.
|
||||
*/
|
||||
#if SIZEOF_CHARP == 4
|
||||
typedef long my_ptrdiff_t;
|
||||
#else
|
||||
typedef long long my_ptrdiff_t;
|
||||
#endif
|
||||
|
||||
/* typedef used for length of string; Should be unsigned! */
|
||||
typedef ulong size_str;
|
||||
|
||||
#define MY_ALIGN(A,L) (((A) + (L) - 1) & ~((L) - 1))
|
||||
#define ALIGN_SIZE(A) MY_ALIGN((A),sizeof(double))
|
||||
/* Size to make adressable obj. */
|
||||
@ -869,7 +877,7 @@ typedef char bool; /* Ordinary boolean values 0 1 */
|
||||
*/
|
||||
|
||||
/* Optimized store functions for Intel x86 */
|
||||
#ifdef __i386__
|
||||
#if defined(__i386__) && !defined(_WIN64)
|
||||
#define sint2korr(A) (*((int16 *) (A)))
|
||||
#define sint3korr(A) ((int32) ((((uchar) (A)[2]) & 128) ? \
|
||||
(((uint32) 255L << 24) | \
|
||||
|
@ -10,6 +10,7 @@
|
||||
#else
|
||||
#define PROTOCOL_VERSION @PROTOCOL_VERSION@
|
||||
#define MYSQL_SERVER_VERSION "@VERSION@"
|
||||
#define MYSQL_BASE_VERSION "mysqld-@MYSQL_BASE_VERSION@"
|
||||
#ifndef MYSQL_SERVER_SUFFIX
|
||||
#define MYSQL_SERVER_SUFFIX "@MYSQL_SERVER_SUFFIX@"
|
||||
#endif
|
||||
|
@ -103,7 +103,7 @@ void init_thr_alarm(uint max_alarm);
|
||||
bool thr_alarm(thr_alarm_t *alarmed, uint sec, ALARM *buff);
|
||||
void thr_alarm_kill(pthread_t thread_id);
|
||||
void thr_end_alarm(thr_alarm_t *alarmed);
|
||||
void end_thr_alarm(void);
|
||||
void end_thr_alarm(my_bool free_structures);
|
||||
sig_handler process_alarm(int);
|
||||
#ifndef thr_got_alarm
|
||||
bool thr_got_alarm(thr_alarm_t *alrm);
|
||||
|
@ -301,6 +301,13 @@ os_aio(
|
||||
are ignored */
|
||||
void* message2);
|
||||
/****************************************************************************
|
||||
Wakes up all async i/o threads so that they know to exit themselves in
|
||||
shutdown. */
|
||||
|
||||
void
|
||||
os_aio_wake_all_threads_at_shutdown(void);
|
||||
/*=====================================*/
|
||||
/****************************************************************************
|
||||
Waits until there are no pending writes in os_aio_write_array. There can
|
||||
be other, synchronous, pending writes. */
|
||||
|
||||
|
@ -10,15 +10,16 @@ Created 9/6/1995 Heikki Tuuri
|
||||
#define os0sync_h
|
||||
|
||||
#include "univ.i"
|
||||
#include "ut0lst.h"
|
||||
|
||||
#ifdef __WIN__
|
||||
|
||||
#define os_fast_mutex_t CRITICAL_SECTION
|
||||
typedef void* os_event_t;
|
||||
|
||||
typedef HANDLE os_event_t;
|
||||
#else
|
||||
|
||||
typedef pthread_mutex_t os_fast_mutex_t;
|
||||
|
||||
typedef struct os_event_struct os_event_struct_t;
|
||||
typedef os_event_struct_t* os_event_t;
|
||||
struct os_event_struct {
|
||||
os_fast_mutex_t os_mutex; /* this mutex protects the next
|
||||
fields */
|
||||
@ -26,9 +27,9 @@ struct os_event_struct {
|
||||
not reserved */
|
||||
pthread_cond_t cond_var; /* condition variable is used in
|
||||
waiting for the event */
|
||||
UT_LIST_NODE_T(os_event_struct_t) os_event_list;
|
||||
/* list of all created events */
|
||||
};
|
||||
typedef struct os_event_struct os_event_struct_t;
|
||||
typedef os_event_struct_t* os_event_t;
|
||||
#endif
|
||||
|
||||
typedef struct os_mutex_struct os_mutex_str_t;
|
||||
@ -38,6 +39,29 @@ typedef os_mutex_str_t* os_mutex_t;
|
||||
|
||||
#define OS_SYNC_TIME_EXCEEDED 1
|
||||
|
||||
/* Mutex protecting the thread count and event and OS 'slow' mutex lists */
|
||||
extern os_mutex_t os_sync_mutex;
|
||||
|
||||
/* This is incremented by 1 in os_thread_create and decremented by 1 in
|
||||
os_thread_exit */
|
||||
extern ulint os_thread_count;
|
||||
|
||||
/* The following are approximate counters for debugging in Unix */
|
||||
extern ulint os_event_count;
|
||||
extern ulint os_mutex_count;
|
||||
|
||||
/*************************************************************
|
||||
Initializes global event and OS 'slow' mutex lists. */
|
||||
|
||||
void
|
||||
os_sync_init(void);
|
||||
/*==============*/
|
||||
/*************************************************************
|
||||
Frees created events (not in Windows) and OS 'slow' mutexes. */
|
||||
|
||||
void
|
||||
os_sync_free(void);
|
||||
/*==============*/
|
||||
/*************************************************************
|
||||
Creates an event semaphore, i.e., a semaphore which may
|
||||
just have two states: signaled and nonsignaled.
|
||||
@ -85,7 +109,10 @@ os_event_free(
|
||||
/*==========*/
|
||||
os_event_t event); /* in: event to free */
|
||||
/**************************************************************
|
||||
Waits for an event object until it is in the signaled state. */
|
||||
Waits for an event object until it is in the signaled state. If
|
||||
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
|
||||
waiting thread when the event becomes signaled (or immediately if the
|
||||
event is already in the signaled state). */
|
||||
|
||||
void
|
||||
os_event_wait(
|
||||
|
@ -41,7 +41,6 @@ typedef os_thread_t os_thread_id_t; /* In Unix we use the thread
|
||||
the thread */
|
||||
#endif
|
||||
|
||||
|
||||
/* Define a function pointer type to use in a typecast */
|
||||
typedef void* (*os_posix_f_t) (void*);
|
||||
|
||||
@ -83,12 +82,13 @@ os_thread_create(
|
||||
os_thread_id_t* thread_id); /* out: id of the created
|
||||
thread */
|
||||
/*********************************************************************
|
||||
A thread calling this function ends its execution. */
|
||||
Exits the current thread. */
|
||||
|
||||
void
|
||||
os_thread_exit(
|
||||
/*===========*/
|
||||
ulint code); /* in: exit code */
|
||||
void* exit_value); /* in: exit value; in Windows this void*
|
||||
is cast as a DWORD */
|
||||
/*********************************************************************
|
||||
Returns the thread identifier of current thread. */
|
||||
|
||||
@ -144,7 +144,6 @@ ulint
|
||||
os_thread_get_last_error(void);
|
||||
/*==========================*/
|
||||
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "os0thread.ic"
|
||||
#endif
|
||||
|
@ -212,6 +212,12 @@ void
|
||||
srv_init(void);
|
||||
/*==========*/
|
||||
/*************************************************************************
|
||||
Frees the OS fast mutex created in srv_init(). */
|
||||
|
||||
void
|
||||
srv_free(void);
|
||||
/*==========*/
|
||||
/*************************************************************************
|
||||
Initializes the synchronization primitives, memory system, and the thread
|
||||
local storage. */
|
||||
|
||||
|
@ -86,11 +86,12 @@ extern ibool srv_startup_is_before_trx_rollback_phase;
|
||||
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 */
|
||||
and then to SRV_SHUTDOWN_LAST_PHASE, and so on */
|
||||
|
||||
extern ulint srv_shutdown_state;
|
||||
|
||||
#define SRV_SHUTDOWN_CLEANUP 1
|
||||
#define SRV_SHUTDOWN_LAST_PHASE 2
|
||||
#define SRV_SHUTDOWN_CLEANUP 1
|
||||
#define SRV_SHUTDOWN_LAST_PHASE 2
|
||||
#define SRV_SHUTDOWN_EXIT_THREADS 3
|
||||
|
||||
#endif
|
||||
|
@ -187,7 +187,11 @@ management to ensure correct alignment for doubles etc. */
|
||||
/* Another basic type we use is unsigned long integer which is intended to be
|
||||
equal to the word size of the machine. */
|
||||
|
||||
#ifdef _WIN64
|
||||
typedef unsigned __int64 ulint;
|
||||
#else
|
||||
typedef unsigned long int ulint;
|
||||
#endif
|
||||
|
||||
typedef long int lint;
|
||||
|
||||
|
@ -375,7 +375,7 @@ log_pad_current_log_block(void)
|
||||
log_close();
|
||||
log_release();
|
||||
|
||||
ut_a((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
|
||||
ut_ad((ut_dulint_get_low(lsn) % OS_FILE_LOG_BLOCK_SIZE)
|
||||
== LOG_BLOCK_HDR_SIZE);
|
||||
}
|
||||
|
||||
@ -998,6 +998,8 @@ log_group_file_header_flush(
|
||||
{
|
||||
byte* buf;
|
||||
ulint dest_offset;
|
||||
|
||||
UT_NOT_USED(type);
|
||||
|
||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
||||
|
||||
@ -1068,8 +1070,8 @@ log_group_write_buf(
|
||||
ulint i;
|
||||
|
||||
ut_ad(mutex_own(&(log_sys->mutex)));
|
||||
ut_a(len % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_a(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_ad(len % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
ut_ad(ut_dulint_get_low(start_lsn) % OS_FILE_LOG_BLOCK_SIZE == 0);
|
||||
|
||||
if (new_data_offset == 0) {
|
||||
write_header = TRUE;
|
||||
@ -2901,10 +2903,9 @@ logs_empty_and_mark_files_at_shutdown(void)
|
||||
dulint lsn;
|
||||
ulint arch_log_no;
|
||||
|
||||
if (srv_print_verbose_log)
|
||||
{
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Starting shutdown...\n");
|
||||
if (srv_print_verbose_log) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Starting shutdown...\n");
|
||||
}
|
||||
/* Wait until the master thread and all other operations are idle: our
|
||||
algorithm only works if the server is idle at shutdown */
|
||||
@ -3006,15 +3007,17 @@ loop:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
/* Make some checks that the server really is quiet */
|
||||
ut_a(buf_all_freed());
|
||||
ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn));
|
||||
|
||||
fil_write_flushed_lsn_to_data_files(lsn, arch_log_no);
|
||||
|
||||
fil_flush_file_spaces(FIL_TABLESPACE);
|
||||
|
||||
if (srv_print_verbose_log)
|
||||
{
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Shutdown completed\n");
|
||||
}
|
||||
/* Make some checks that the server really is quiet */
|
||||
ut_a(buf_all_freed());
|
||||
ut_a(0 == ut_dulint_cmp(lsn, log_sys->lsn));
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
|
@ -295,7 +295,8 @@ os_file_handle_error(
|
||||
/* out: TRUE if we should retry the
|
||||
operation */
|
||||
os_file_t file, /* in: file pointer */
|
||||
char* name) /* in: name of a file or NULL */
|
||||
char* name, /* in: name of a file or NULL */
|
||||
const char* operation) /* in: type of operation */
|
||||
{
|
||||
ulint err;
|
||||
|
||||
@ -337,7 +338,8 @@ os_file_handle_error(
|
||||
if (name) {
|
||||
fprintf(stderr, "InnoDB: File name %s\n", name);
|
||||
}
|
||||
|
||||
fprintf(stderr, "InnoDB: system call %s\n", operation);
|
||||
|
||||
fprintf(stderr, "InnoDB: Cannot continue operation.\n");
|
||||
|
||||
fflush(stderr);
|
||||
@ -419,7 +421,9 @@ try_again:
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
*success = FALSE;
|
||||
|
||||
retry = os_file_handle_error(file, name);
|
||||
retry = os_file_handle_error(file, name,
|
||||
create_mode == OS_FILE_OPEN ?
|
||||
"open" : "create");
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
@ -460,7 +464,10 @@ try_again:
|
||||
if (file == -1) {
|
||||
*success = FALSE;
|
||||
|
||||
retry = os_file_handle_error(file, name);
|
||||
retry = os_file_handle_error(file, name,
|
||||
create_mode == OS_FILE_OPEN ?
|
||||
"open" : "create");
|
||||
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
@ -568,7 +575,9 @@ try_again:
|
||||
if (file == INVALID_HANDLE_VALUE) {
|
||||
*success = FALSE;
|
||||
|
||||
retry = os_file_handle_error(file, name);
|
||||
retry = os_file_handle_error(file, name,
|
||||
create_mode == OS_FILE_OPEN ?
|
||||
"open" : "create");
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
@ -615,7 +624,9 @@ try_again:
|
||||
if (file == -1) {
|
||||
*success = FALSE;
|
||||
|
||||
retry = os_file_handle_error(file, name);
|
||||
retry = os_file_handle_error(file, name,
|
||||
create_mode == OS_FILE_OPEN ?
|
||||
"open" : "create");
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
@ -649,7 +660,7 @@ os_file_close(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
os_file_handle_error(file, NULL);
|
||||
os_file_handle_error(file, NULL, "close");
|
||||
return(FALSE);
|
||||
#else
|
||||
int ret;
|
||||
@ -657,7 +668,7 @@ os_file_close(
|
||||
ret = close(file);
|
||||
|
||||
if (ret == -1) {
|
||||
os_file_handle_error(file, NULL);
|
||||
os_file_handle_error(file, NULL, "close");
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
@ -825,7 +836,7 @@ os_file_flush(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
os_file_handle_error(file, NULL);
|
||||
os_file_handle_error(file, NULL, "flush");
|
||||
|
||||
/* It is a fatal error if a file flush does not succeed, because then
|
||||
the database can get corrupt on disk */
|
||||
@ -858,7 +869,7 @@ os_file_flush(
|
||||
fprintf(stderr,
|
||||
" InnoDB: Error: the OS said file flush did not succeed\n");
|
||||
|
||||
os_file_handle_error(file, NULL);
|
||||
os_file_handle_error(file, NULL, "flush");
|
||||
|
||||
/* It is a fatal error if a file flush does not succeed, because then
|
||||
the database can get corrupt on disk */
|
||||
@ -1099,7 +1110,7 @@ try_again:
|
||||
#ifdef __WIN__
|
||||
error_handling:
|
||||
#endif
|
||||
retry = os_file_handle_error(file, NULL);
|
||||
retry = os_file_handle_error(file, NULL, "read");
|
||||
|
||||
if (retry) {
|
||||
goto try_again;
|
||||
@ -1295,7 +1306,6 @@ os_aio_array_create(
|
||||
#endif
|
||||
ut_a(n > 0);
|
||||
ut_a(n_segments > 0);
|
||||
ut_a(n % n_segments == 0);
|
||||
|
||||
array = ut_malloc(sizeof(os_aio_array_t));
|
||||
|
||||
@ -1404,6 +1414,50 @@ os_aio_init(
|
||||
pthread_sigmask(SIG_BLOCK, &sigset, NULL); */
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef WIN_ASYNC_IO
|
||||
/****************************************************************************
|
||||
Wakes up all async i/o threads in the array in Windows async i/o at
|
||||
shutdown. */
|
||||
static
|
||||
void
|
||||
os_aio_array_wake_win_aio_at_shutdown(
|
||||
/*==================================*/
|
||||
os_aio_array_t* array) /* in: aio array */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < array->n_slots; i++) {
|
||||
|
||||
os_event_set(*(array->events + i));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
Wakes up all async i/o threads so that they know to exit themselves in
|
||||
shutdown. */
|
||||
|
||||
void
|
||||
os_aio_wake_all_threads_at_shutdown(void)
|
||||
/*=====================================*/
|
||||
{
|
||||
ulint i;
|
||||
|
||||
#ifdef WIN_ASYNC_IO
|
||||
/* This code wakes up all ai/o threads in Windows native aio */
|
||||
os_aio_array_wake_win_aio_at_shutdown(os_aio_read_array);
|
||||
os_aio_array_wake_win_aio_at_shutdown(os_aio_write_array);
|
||||
os_aio_array_wake_win_aio_at_shutdown(os_aio_ibuf_array);
|
||||
os_aio_array_wake_win_aio_at_shutdown(os_aio_log_array);
|
||||
#endif
|
||||
/* This loop wakes up all simulated ai/o threads */
|
||||
|
||||
for (i = 0; i < os_aio_n_segments; i++) {
|
||||
|
||||
os_event_set(os_aio_segment_wait_events[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
Waits until there are no pending writes in os_aio_write_array. There can
|
||||
@ -1971,7 +2025,7 @@ try_again:
|
||||
|
||||
os_aio_array_free_slot(array, slot);
|
||||
|
||||
retry = os_file_handle_error(file, name);
|
||||
retry = os_file_handle_error(file, name, "aio");
|
||||
|
||||
if (retry) {
|
||||
|
||||
@ -2070,7 +2124,7 @@ os_aio_windows_handle(
|
||||
ut_a(TRUE == os_file_flush(slot->file));
|
||||
}
|
||||
} else {
|
||||
os_file_handle_error(slot->file, slot->name);
|
||||
os_file_handle_error(slot->file, slot->name, "aio");
|
||||
|
||||
ret_val = FALSE;
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ Created 9/6/1995 Heikki Tuuri
|
||||
#endif
|
||||
|
||||
#include "ut0mem.h"
|
||||
#include "srv0start.h"
|
||||
|
||||
/* Type definition for an operating system mutex struct */
|
||||
struct os_mutex_struct{
|
||||
@ -26,9 +27,75 @@ struct os_mutex_struct{
|
||||
recursively lock the mutex: we
|
||||
do not assume that the OS mutex
|
||||
supports recursive locking, though
|
||||
NT seems to do that */
|
||||
NT seems to do that */
|
||||
UT_LIST_NODE_T(os_mutex_str_t) os_mutex_list;
|
||||
/* list of all 'slow' OS mutexes created */
|
||||
};
|
||||
|
||||
/* Mutex protecting the thread count and the lists of OS mutexes
|
||||
and events */
|
||||
os_mutex_t os_sync_mutex;
|
||||
ibool os_sync_mutex_inited = FALSE;
|
||||
|
||||
/* This is incremented by 1 in os_thread_create and decremented by 1 in
|
||||
os_thread_exit */
|
||||
ulint os_thread_count = 0;
|
||||
|
||||
/* The list of all events created (not in Windows) */
|
||||
UT_LIST_BASE_NODE_T(os_event_struct_t) os_event_list;
|
||||
|
||||
/* The list of all OS 'slow' mutexes */
|
||||
UT_LIST_BASE_NODE_T(os_mutex_str_t) os_mutex_list;
|
||||
|
||||
/* The following are approximate counters for debugging in Unix */
|
||||
ulint os_event_count = 0;
|
||||
ulint os_mutex_count = 0;
|
||||
|
||||
|
||||
/*************************************************************
|
||||
Initializes global event and OS 'slow' mutex lists. */
|
||||
|
||||
void
|
||||
os_sync_init(void)
|
||||
/*==============*/
|
||||
{
|
||||
UT_LIST_INIT(os_event_list);
|
||||
UT_LIST_INIT(os_mutex_list);
|
||||
|
||||
os_sync_mutex = os_mutex_create(NULL);
|
||||
|
||||
os_sync_mutex_inited = TRUE;
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
Frees created events (not in Windows) and OS 'slow' mutexes. */
|
||||
|
||||
void
|
||||
os_sync_free(void)
|
||||
/*==============*/
|
||||
{
|
||||
os_event_t event;
|
||||
os_mutex_t mutex;
|
||||
|
||||
event = UT_LIST_GET_FIRST(os_event_list);
|
||||
|
||||
while (event) {
|
||||
|
||||
os_event_free(event);
|
||||
|
||||
event = UT_LIST_GET_FIRST(os_event_list);
|
||||
}
|
||||
|
||||
mutex = UT_LIST_GET_FIRST(os_mutex_list);
|
||||
|
||||
while (mutex) {
|
||||
|
||||
os_mutex_free(mutex);
|
||||
|
||||
mutex = UT_LIST_GET_FIRST(os_mutex_list);
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************
|
||||
Creates an event semaphore, i.e., a semaphore which may
|
||||
just have two states: signaled and nonsignaled.
|
||||
@ -43,8 +110,8 @@ os_event_create(
|
||||
the event is created without a name */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
HANDLE event;
|
||||
|
||||
os_event_t event;
|
||||
|
||||
event = CreateEvent(NULL, /* No security attributes */
|
||||
TRUE, /* Manual reset */
|
||||
FALSE, /* Initial state nonsignaled */
|
||||
@ -75,6 +142,14 @@ os_event_create(
|
||||
#endif
|
||||
event->is_set = FALSE;
|
||||
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
|
||||
UT_LIST_ADD_FIRST(os_event_list, os_event_list, event);
|
||||
|
||||
os_event_count++;
|
||||
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
return(event);
|
||||
#endif
|
||||
}
|
||||
@ -92,7 +167,7 @@ os_event_create_auto(
|
||||
the event is created without a name */
|
||||
{
|
||||
#ifdef __WIN__
|
||||
HANDLE event;
|
||||
os_event_t event;
|
||||
|
||||
event = CreateEvent(NULL, /* No security attributes */
|
||||
FALSE, /* Auto-reset */
|
||||
@ -106,6 +181,8 @@ os_event_create_auto(
|
||||
|
||||
UT_NOT_USED(name);
|
||||
|
||||
ut_a(0);
|
||||
|
||||
return(NULL);
|
||||
#endif
|
||||
}
|
||||
@ -185,12 +262,23 @@ os_event_free(
|
||||
os_fast_mutex_free(&(event->os_mutex));
|
||||
ut_a(0 == pthread_cond_destroy(&(event->cond_var)));
|
||||
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
|
||||
UT_LIST_REMOVE(os_event_list, os_event_list, event);
|
||||
|
||||
os_event_count--;
|
||||
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
ut_free(event);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**************************************************************
|
||||
Waits for an event object until it is in the signaled state. */
|
||||
Waits for an event object until it is in the signaled state. If
|
||||
srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS this also exits the
|
||||
waiting thread when the event becomes signaled (or immediately if the
|
||||
event is already in the signaled state). */
|
||||
|
||||
void
|
||||
os_event_wait(
|
||||
@ -206,12 +294,20 @@ os_event_wait(
|
||||
err = WaitForSingleObject(event, INFINITE);
|
||||
|
||||
ut_a(err == WAIT_OBJECT_0);
|
||||
|
||||
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
||||
os_thread_exit(NULL);
|
||||
}
|
||||
#else
|
||||
os_fast_mutex_lock(&(event->os_mutex));
|
||||
loop:
|
||||
if (event->is_set == TRUE) {
|
||||
os_fast_mutex_unlock(&(event->os_mutex));
|
||||
|
||||
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
||||
|
||||
os_thread_exit(NULL);
|
||||
}
|
||||
/* Ok, we may return */
|
||||
|
||||
return;
|
||||
@ -291,14 +387,17 @@ os_event_wait_multiple(
|
||||
ut_a(event_array);
|
||||
ut_a(n > 0);
|
||||
|
||||
index = WaitForMultipleObjects(n,
|
||||
event_array,
|
||||
index = WaitForMultipleObjects(n, event_array,
|
||||
FALSE, /* Wait for any 1 event */
|
||||
INFINITE); /* Infinite wait time
|
||||
limit */
|
||||
ut_a(index >= WAIT_OBJECT_0);
|
||||
ut_a(index < WAIT_OBJECT_0 + n);
|
||||
|
||||
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
||||
os_thread_exit(NULL);
|
||||
}
|
||||
|
||||
return(index - WAIT_OBJECT_0);
|
||||
#else
|
||||
ut_a(n == 0);
|
||||
@ -337,6 +436,16 @@ os_mutex_create(
|
||||
mutex_str->handle = mutex;
|
||||
mutex_str->count = 0;
|
||||
|
||||
if (os_sync_mutex_inited) {
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
}
|
||||
|
||||
UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str);
|
||||
|
||||
if (os_sync_mutex_inited) {
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
}
|
||||
|
||||
return(mutex_str);
|
||||
#else
|
||||
os_fast_mutex_t* os_mutex;
|
||||
@ -353,6 +462,16 @@ os_mutex_create(
|
||||
mutex_str->handle = os_mutex;
|
||||
mutex_str->count = 0;
|
||||
|
||||
if (os_sync_mutex_inited) {
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
}
|
||||
|
||||
UT_LIST_ADD_FIRST(os_mutex_list, os_mutex_list, mutex_str);
|
||||
|
||||
if (os_sync_mutex_inited) {
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
}
|
||||
|
||||
return(mutex_str);
|
||||
#endif
|
||||
}
|
||||
@ -424,9 +543,22 @@ os_mutex_free(
|
||||
#ifdef __WIN__
|
||||
ut_a(mutex);
|
||||
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
|
||||
UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex);
|
||||
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
ut_a(CloseHandle(mutex->handle));
|
||||
|
||||
ut_free(mutex);
|
||||
#else
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
|
||||
UT_LIST_REMOVE(os_mutex_list, os_mutex_list, mutex);
|
||||
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
os_fast_mutex_free(mutex->handle);
|
||||
ut_free(mutex->handle);
|
||||
ut_free(mutex);
|
||||
@ -451,6 +583,7 @@ os_fast_mutex_init(
|
||||
#else
|
||||
ut_a(0 == pthread_mutex_init(fast_mutex, MY_MUTEX_INIT_FAST));
|
||||
#endif
|
||||
os_mutex_count++;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -498,5 +631,6 @@ os_fast_mutex_free(
|
||||
DeleteCriticalSection((LPCRITICAL_SECTION) fast_mutex);
|
||||
#else
|
||||
ut_a(0 == pthread_mutex_destroy(fast_mutex));
|
||||
os_mutex_count--;
|
||||
#endif
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
/******************************************************
|
||||
The interface to the operating system
|
||||
process and thread control primitives
|
||||
The interface to the operating system thread control primitives
|
||||
|
||||
(c) 1995 Innobase Oy
|
||||
|
||||
@ -17,6 +16,7 @@ Created 9/8/1995 Heikki Tuuri
|
||||
#endif
|
||||
|
||||
#include "srv0srv.h"
|
||||
#include "os0sync.h"
|
||||
|
||||
/*******************************************************************
|
||||
Compares two thread ids for equality. */
|
||||
@ -102,6 +102,10 @@ os_thread_create(
|
||||
os_thread_t thread;
|
||||
ulint win_thread_id;
|
||||
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
os_thread_count++;
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
thread = CreateThread(NULL, /* no security attributes */
|
||||
0, /* default size stack */
|
||||
(LPTHREAD_START_ROUTINE)start_f,
|
||||
@ -144,6 +148,9 @@ os_thread_create(
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
os_thread_count++;
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
#if defined(UNIV_HOTBACKUP) && defined(UNIV_HPUX10)
|
||||
ret = pthread_create(&pthread, pthread_attr_default, start_f, arg);
|
||||
@ -170,6 +177,26 @@ os_thread_create(
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Exits the current thread. */
|
||||
|
||||
void
|
||||
os_thread_exit(
|
||||
/*===========*/
|
||||
void* exit_value) /* in: exit value; in Windows this void*
|
||||
is cast as a DWORD */
|
||||
{
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
os_thread_count--;
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
#ifdef __WIN__
|
||||
ExitThread((DWORD)exit_value);
|
||||
#else
|
||||
pthread_exit(exit_value);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Returns handle to the current thread. */
|
||||
|
||||
|
@ -1275,6 +1275,10 @@ row_ins_unique_report_err(
|
||||
dtuple_t* entry, /* in: index entry to insert in the index */
|
||||
dict_index_t* index) /* in: index */
|
||||
{
|
||||
#ifdef notdefined
|
||||
/* Disable reporting to test if the slowdown of REPLACE in 4.0.13 was
|
||||
caused by this! */
|
||||
|
||||
char* buf = dict_unique_err_buf;
|
||||
|
||||
/* The foreign err mutex protects also dict_unique_err_buf */
|
||||
@ -1303,6 +1307,7 @@ row_ins_unique_report_err(
|
||||
ut_a(strlen(buf) < DICT_FOREIGN_ERR_BUF_LEN);
|
||||
|
||||
mutex_exit(&dict_foreign_err_mutex);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -1705,7 +1705,17 @@ srv_init(void)
|
||||
ut_a(conc_slot->event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
Frees the OS fast mutex created in srv_init(). */
|
||||
|
||||
void
|
||||
srv_free(void)
|
||||
/*==========*/
|
||||
{
|
||||
os_fast_mutex_free(&srv_conc_mutex);
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
Initializes the synchronization primitives, memory system, and the thread
|
||||
local storage. */
|
||||
@ -1714,67 +1724,14 @@ void
|
||||
srv_general_init(void)
|
||||
/*==================*/
|
||||
{
|
||||
os_sync_init();
|
||||
sync_init();
|
||||
mem_init(srv_mem_pool_size);
|
||||
thr_local_init();
|
||||
}
|
||||
|
||||
|
||||
#if defined(__NETWARE__) || defined(SAFE_MUTEX_DETECT_DESTROY)
|
||||
/* NetWare requires some cleanup of mutexes */
|
||||
|
||||
/*************************************************************************
|
||||
Deinitializes the synchronization primitives, memory system, and the thread
|
||||
local storage. */
|
||||
|
||||
void
|
||||
srv_general_free(void)
|
||||
/*==================*/
|
||||
{
|
||||
sync_close();
|
||||
}
|
||||
#endif /* __NETWARE__ */
|
||||
|
||||
|
||||
/*======================= InnoDB Server FIFO queue =======================*/
|
||||
|
||||
#if defined(__NETWARE__) || defined(SAFE_MUTEX_DETECT_DESTROY)
|
||||
/* NetWare requires some cleanup of mutexes */
|
||||
|
||||
/*************************************************************************
|
||||
Deinitializes the server. */
|
||||
|
||||
void
|
||||
srv_free(void)
|
||||
/*==========*/
|
||||
{
|
||||
srv_conc_slot_t* conc_slot;
|
||||
srv_slot_t* slot;
|
||||
ulint i;
|
||||
|
||||
for (i = 0; i < OS_THREAD_MAX_N; i++)
|
||||
{
|
||||
slot = srv_table_get_nth_slot(i);
|
||||
os_event_free(slot->event);
|
||||
}
|
||||
|
||||
/* TODO: free(srv_sys->threads); */
|
||||
|
||||
for (i = 0; i < OS_THREAD_MAX_N; i++)
|
||||
{
|
||||
slot = srv_mysql_table + i;
|
||||
os_event_free(slot->event);
|
||||
}
|
||||
|
||||
/* TODO: free(srv_mysql_table); */
|
||||
|
||||
for (i = 0; i < OS_THREAD_MAX_N; i++)
|
||||
{
|
||||
conc_slot = srv_conc_slots + i;
|
||||
os_event_free(conc_slot->event);
|
||||
}
|
||||
}
|
||||
#endif /* __NETWARE__ */
|
||||
|
||||
/*************************************************************************
|
||||
Puts an OS thread to wait if there are too many concurrent threads
|
||||
@ -2734,6 +2691,8 @@ loop:
|
||||
|
||||
srv_error_monitor_active = FALSE;
|
||||
|
||||
os_thread_exit(NULL);
|
||||
|
||||
#ifndef __WIN__
|
||||
return(NULL);
|
||||
#else
|
||||
@ -3173,6 +3132,13 @@ suspend_thread:
|
||||
|
||||
os_event_wait(event);
|
||||
|
||||
if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
|
||||
/* This is only extra safety, the thread should exit
|
||||
already when the event wait ends */
|
||||
|
||||
os_thread_exit(NULL);
|
||||
}
|
||||
|
||||
/* When there is user activity, InnoDB will set the event and the main
|
||||
thread goes back to loop: */
|
||||
|
||||
|
@ -1481,9 +1481,7 @@ innobase_start_or_create_for_mysql(void)
|
||||
|
||||
os_fast_mutex_unlock(&srv_os_test_mutex);
|
||||
|
||||
#if defined(__NETWARE__) || defined(SAFE_MUTEX_DETECT_DESTROY)
|
||||
os_fast_mutex_free(&srv_os_test_mutex); /* all platforms? */
|
||||
#endif /* __NETWARE__ */
|
||||
os_fast_mutex_free(&srv_os_test_mutex);
|
||||
|
||||
if (srv_print_verbose_log) {
|
||||
ut_print_timestamp(stderr);
|
||||
@ -1509,6 +1507,8 @@ innobase_shutdown_for_mysql(void)
|
||||
/*=============================*/
|
||||
/* out: DB_SUCCESS or error code */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
if (!srv_was_started) {
|
||||
if (srv_is_being_started) {
|
||||
ut_print_timestamp(stderr);
|
||||
@ -1521,7 +1521,7 @@ innobase_shutdown_for_mysql(void)
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
/* Flush buffer pool to disk, write the current lsn to
|
||||
/* 1. Flush buffer pool to disk, write the current lsn to
|
||||
the tablespace header(s), and copy all log data to archive */
|
||||
|
||||
logs_empty_and_mark_files_at_shutdown();
|
||||
@ -1533,30 +1533,77 @@ innobase_shutdown_for_mysql(void)
|
||||
srv_conc_n_threads);
|
||||
}
|
||||
|
||||
#if defined(__NETWARE__) || defined(SAFE_MUTEX_DETECT_DESTROY)
|
||||
/*
|
||||
TODO: Fix this temporary solution
|
||||
We are having a race condition occure with io_handler_thread threads.
|
||||
When they yield in os_aio_simulated_handle during shutdown, this
|
||||
thread was able to free the memory early.
|
||||
*/
|
||||
os_thread_yield();
|
||||
/* 2. Make all threads created by InnoDB to exit */
|
||||
|
||||
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
|
||||
|
||||
/* All threads end up waiting for certain events. Put those events
|
||||
to the signaled state. Then the threads will exit themselves in
|
||||
os_thread_event_wait(). */
|
||||
|
||||
for (i = 0; i < 1000; i++) {
|
||||
/* NOTE: IF YOU CREATE THREADS IN INNODB, YOU MUST EXIT THEM
|
||||
HERE OR EARLIER */
|
||||
|
||||
/* 1. Let the lock timeout thread exit */
|
||||
os_event_set(srv_lock_timeout_thread_event);
|
||||
|
||||
/* 2. srv error monitor thread exits automatically, no need
|
||||
to do anything here */
|
||||
|
||||
/* 3. We wake the master thread so that it exits */
|
||||
srv_wake_master_thread();
|
||||
|
||||
/* 4. Exit the i/o threads */
|
||||
|
||||
os_aio_wake_all_threads_at_shutdown();
|
||||
|
||||
os_mutex_enter(os_sync_mutex);
|
||||
|
||||
if (os_thread_count == 0) {
|
||||
/* All the threads have exited or are just exiting;
|
||||
NOTE that the threads may not have completed their
|
||||
exit yet. Should we use pthread_join() to make sure
|
||||
they have exited? Now we just sleep 0.1 seconds and
|
||||
hope that is enough! */
|
||||
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
os_thread_sleep(100000);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
os_mutex_exit(os_sync_mutex);
|
||||
|
||||
os_thread_sleep(100000);
|
||||
}
|
||||
|
||||
if (i == 1000) {
|
||||
fprintf(stderr,
|
||||
"InnoDB: Warning: %lu threads created by InnoDB had not exited at shutdown!\n",
|
||||
os_thread_count);
|
||||
}
|
||||
|
||||
/* 3. Free all InnoDB's own mutexes */
|
||||
|
||||
sync_close();
|
||||
|
||||
/* 4. Free all OS synchronization primitives (in Windows currently
|
||||
events are not freed) */
|
||||
|
||||
/* TODO: Where should this be called? */
|
||||
srv_free();
|
||||
os_sync_free();
|
||||
|
||||
/* 5. Free all allocated memory (and the os_fast_mutex created in
|
||||
ut0mem.c */
|
||||
|
||||
/* TODO: Where should this be called? */
|
||||
srv_general_free();
|
||||
#endif
|
||||
/*
|
||||
TODO: We should exit the i/o-handler and other utility threads
|
||||
before freeing all memory. Now this can potentially cause a seg
|
||||
fault!
|
||||
*/
|
||||
#if defined(NOT_WORKING_YET) || defined(__NETWARE__) || defined(SAFE_MUTEX_DETECT_DESTROY)
|
||||
/* NetWare requires this free */
|
||||
ut_free_all_mem();
|
||||
#endif
|
||||
|
||||
if (srv_print_verbose_log) {
|
||||
ut_print_timestamp(stderr);
|
||||
fprintf(stderr, " InnoDB: Shutdown completed\n");
|
||||
}
|
||||
|
||||
return((int) DB_SUCCESS);
|
||||
}
|
||||
|
@ -235,8 +235,7 @@ mutex_create_func(
|
||||
mutex->cline = cline;
|
||||
|
||||
/* Check that lock_word is aligned; this is important on Intel */
|
||||
|
||||
ut_a(((ulint)(&(mutex->lock_word))) % 4 == 0);
|
||||
ut_ad(((ulint)(&(mutex->lock_word))) % 4 == 0);
|
||||
|
||||
/* NOTE! The very first mutexes are not put to the mutex list */
|
||||
|
||||
@ -266,11 +265,14 @@ mutex_free(
|
||||
ut_a(mutex_get_lock_word(mutex) == 0);
|
||||
ut_a(mutex_get_waiters(mutex) == 0);
|
||||
|
||||
mutex_enter(&mutex_list_mutex);
|
||||
if (mutex != &mutex_list_mutex && mutex != &sync_thread_mutex) {
|
||||
|
||||
UT_LIST_REMOVE(list, mutex_list, mutex);
|
||||
mutex_enter(&mutex_list_mutex);
|
||||
|
||||
mutex_exit(&mutex_list_mutex);
|
||||
UT_LIST_REMOVE(list, mutex_list, mutex);
|
||||
|
||||
mutex_exit(&mutex_list_mutex);
|
||||
}
|
||||
|
||||
#if !defined(_WIN32) || !defined(UNIV_CAN_USE_X86_ASSEMBLER)
|
||||
os_fast_mutex_free(&(mutex->os_fast_mutex));
|
||||
@ -1230,13 +1232,26 @@ sync_init(void)
|
||||
}
|
||||
|
||||
/**********************************************************************
|
||||
Frees the resources in synchronization data structures. */
|
||||
Frees the resources in InnoDB's own synchronization data structures. Use
|
||||
os_sync_free() after calling this. */
|
||||
|
||||
void
|
||||
sync_close(void)
|
||||
/*===========*/
|
||||
{
|
||||
mutex_t* mutex;
|
||||
|
||||
sync_array_free(sync_primary_wait_array);
|
||||
|
||||
mutex = UT_LIST_GET_FIRST(mutex_list);
|
||||
|
||||
while (mutex) {
|
||||
mutex_free(mutex);
|
||||
mutex = UT_LIST_GET_FIRST(mutex_list);
|
||||
}
|
||||
|
||||
mutex_free(&mutex_list_mutex);
|
||||
mutex_free(&sync_thread_mutex);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
@ -225,6 +225,8 @@ ut_free_all_mem(void)
|
||||
os_fast_mutex_unlock(&ut_list_mutex);
|
||||
|
||||
ut_a(ut_total_allocated_memory == 0);
|
||||
|
||||
os_fast_mutex_free(&ut_list_mutex);
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
|
@ -2066,7 +2066,7 @@ mysql_real_connect(MYSQL *mysql,const char *host, const char *user,
|
||||
net->vio = vio_new(sock, VIO_TYPE_SOCKET, TRUE);
|
||||
bzero((char*) &UNIXaddr,sizeof(UNIXaddr));
|
||||
UNIXaddr.sun_family = AF_UNIX;
|
||||
strmov(UNIXaddr.sun_path, unix_socket);
|
||||
strmake(UNIXaddr.sun_path, unix_socket, sizeof(UNIXaddr.sun_path)-1);
|
||||
if (my_connect(sock,(struct sockaddr *) &UNIXaddr, sizeof(UNIXaddr),
|
||||
mysql->options.connect_timeout))
|
||||
{
|
||||
|
@ -2,7 +2,7 @@
|
||||
.SH NAME
|
||||
mysql_fix_privilege_tables \- Fixes MySQL privilege tables.
|
||||
.SH SYNOPSIS
|
||||
mysql_fix_privilege_tables [options]
|
||||
mysql_fix_privilege_tables [mysql_root_password]
|
||||
.SH DESCRIPTION
|
||||
This scripts updates the mysql.user, mysql.db, mysql.host and the
|
||||
mysql.func tables to MySQL 3.22.14 and above.
|
||||
@ -10,10 +10,9 @@ mysql.func tables to MySQL 3.22.14 and above.
|
||||
This is needed if you want to use the new GRANT functions,
|
||||
CREATE AGGREGATE FUNCTION or want to use the more secure passwords in 3.23
|
||||
|
||||
If you get 'Access denied' errors, you should run this script again
|
||||
and give the MySQL root user password as an argument!
|
||||
If you get 'Access denied' errors, run the script again
|
||||
and give the MySQL root user password as an argument.
|
||||
|
||||
For more information start the program with '--help'.
|
||||
.SH "SEE ALSO"
|
||||
mysql (1), mysqld (1)
|
||||
.SH AUTHOR
|
||||
|
@ -13,12 +13,15 @@ DB=test
|
||||
DBPASSWD=
|
||||
VERBOSE=""
|
||||
USE_MANAGER=0
|
||||
TZ=GMT-3; export TZ # for UNIX_TIMESTAMP tests to work
|
||||
MY_TZ=GMT-3
|
||||
TZ=$MY_TZ; export TZ # for UNIX_TIMESTAMP tests to work
|
||||
|
||||
#++
|
||||
# Program Definitions
|
||||
#--
|
||||
|
||||
LC_COLLATE=C
|
||||
export LC_COLLATE
|
||||
PATH=/bin:/usr/bin:/usr/local/bin:/usr/bsd:/usr/X11R6/bin:/usr/openwin/bin:/usr/bin/X11:$PATH
|
||||
MASTER_40_ARGS="--rpl-recovery-rank=1 --init-rpl-role=master"
|
||||
|
||||
@ -1163,9 +1166,18 @@ run_testcase ()
|
||||
if [ -f $master_opt_file ] ;
|
||||
then
|
||||
EXTRA_MASTER_OPT=`$CAT $master_opt_file | $SED -e "s;\\$MYSQL_TEST_DIR;$MYSQL_TEST_DIR;"`
|
||||
case "$EXTRA_MASTER_OPT" in
|
||||
--timezone=*)
|
||||
TZ=`$ECHO "$EXTRA_MASTER_OPT" | $SED -e "s;--timezone=;;"`
|
||||
export TZ
|
||||
# Note that this must be set to space, not "" for test-reset to work
|
||||
EXTRA_MASTER_OPT=" "
|
||||
;;
|
||||
esac
|
||||
stop_master
|
||||
echo "CURRENT_TEST: $tname" >> $MASTER_MYERR
|
||||
start_master
|
||||
TZ=$MY_TZ; export TZ
|
||||
else
|
||||
if [ ! -z "$EXTRA_MASTER_OPT" ] || [ x$MASTER_RUNNING != x1 ] || [ -f $master_init_script ]
|
||||
then
|
||||
|
@ -276,3 +276,8 @@ t1 0 a 1 a A 3 NULL NULL YES BTREE
|
||||
t1 0 a 2 b A 300 NULL NULL YES BTREE
|
||||
t1 1 b 1 b A 100 NULL NULL YES BTREE
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (i int(10), index(i) );
|
||||
ALTER TABLE t1 DISABLE KEYS;
|
||||
INSERT DELAYED INTO t1 VALUES(1),(2),(3);
|
||||
ALTER TABLE t1 ENABLE KEYS;
|
||||
drop table t1;
|
||||
|
2
mysql-test/r/have_mest_timezone.require
Normal file
2
mysql-test/r/have_mest_timezone.require
Normal file
@ -0,0 +1,2 @@
|
||||
Variable_name Value
|
||||
timezone MEST
|
@ -65,3 +65,15 @@ INSERT INTO t1 (numeropost,icone,contenu,pseudo,date,signature,ip)
|
||||
SELECT 1718,icone,contenu,pseudo,date,signature,ip FROM t2
|
||||
WHERE numeropost=9 ORDER BY numreponse ASC;
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
create table t1(a int, unique(a));
|
||||
insert into t1 values(2);
|
||||
create table t2(a int);
|
||||
insert into t2 values(1),(2);
|
||||
reset master;
|
||||
insert into t1 select * from t2;
|
||||
Duplicate entry '2' for key 1
|
||||
show binlog events;
|
||||
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||
master-bin.001 4 Start 1 4 Server ver: VERSION, Binlog ver: 3
|
||||
master-bin.001 79 Query 1 79 use test; insert into t1 select * from t2
|
||||
drop table t1, t2;
|
||||
|
@ -15,4 +15,11 @@ a b c d
|
||||
0000-00-00 0000-00-00 0000-00-00 0000-00-00
|
||||
2003-03-03 2003-03-03 2003-03-03 NULL
|
||||
2003-03-03 2003-03-03 2003-03-03 NULL
|
||||
truncate table t1;
|
||||
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d);
|
||||
SELECT * from t1;
|
||||
a b c d
|
||||
NULL NULL 0000-00-00 0000-00-00
|
||||
NULL 0000-00-00 0000-00-00 0000-00-00
|
||||
NULL 2003-03-03 2003-03-03 NULL
|
||||
drop table t1;
|
||||
|
@ -13,3 +13,15 @@ show tables like 't_';
|
||||
Tables_in_test (t_)
|
||||
t3
|
||||
drop table t3;
|
||||
create table t1 (a int);
|
||||
select count(*) from T1;
|
||||
count(*)
|
||||
0
|
||||
select count(*) from t1;
|
||||
count(*)
|
||||
0
|
||||
select count(T1.a) from t1;
|
||||
Unknown table 'T1' in field list
|
||||
select count(bags.a) from t1 as Bags;
|
||||
Unknown table 'bags' in field list
|
||||
drop table t1;
|
||||
|
@ -502,6 +502,7 @@ drop table t1;
|
||||
show status like "Qcache_queries_in_cache";
|
||||
Variable_name Value
|
||||
Qcache_queries_in_cache 0
|
||||
create table t1 (a int);
|
||||
show global variables like "query_cache_min_res_unit";
|
||||
Variable_name Value
|
||||
query_cache_min_res_unit 4096
|
||||
@ -565,18 +566,57 @@ set GLOBAL query_cache_size=1000;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 0
|
||||
set GLOBAL query_cache_size=1100;
|
||||
set GLOBAL query_cache_size=1200;
|
||||
set GLOBAL query_cache_size=1300;
|
||||
set GLOBAL query_cache_size=1400;
|
||||
set GLOBAL query_cache_size=1500;
|
||||
set GLOBAL query_cache_size=1600;
|
||||
set GLOBAL query_cache_size=1700;
|
||||
set GLOBAL query_cache_size=1800;
|
||||
set GLOBAL query_cache_size=1900;
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=1024;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 1024
|
||||
query_cache_size 0
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=10240;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 0
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=20480;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 0
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=40960;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 0
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=51200;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 51200
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=61440;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 61440
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=81920;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 81920
|
||||
select * from t1;
|
||||
a
|
||||
set GLOBAL query_cache_size=102400;
|
||||
show global variables like "query_cache_size";
|
||||
Variable_name Value
|
||||
query_cache_size 102400
|
||||
select * from t1;
|
||||
a
|
||||
drop table t1;
|
||||
set GLOBAL query_cache_size=1048576;
|
||||
create table t1 (i int not null);
|
||||
create table t2 (i int not null);
|
||||
|
@ -22,10 +22,12 @@ drop table t1;
|
||||
drop table t2;
|
||||
create table t1(a int auto_increment, key(a));
|
||||
create table t2(b int auto_increment, c int, key(b));
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
insert into t1 values (10);
|
||||
insert into t1 values (null),(null),(null);
|
||||
insert into t2 values (5,0);
|
||||
insert into t2 values (null,last_insert_id());
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
select * from t1;
|
||||
a
|
||||
10
|
||||
@ -38,3 +40,31 @@ b c
|
||||
6 11
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
create table t1(a int auto_increment, key(a));
|
||||
create table t2(b int auto_increment, c int, key(b));
|
||||
insert into t1 values (10);
|
||||
insert into t1 values (null),(null),(null);
|
||||
insert into t2 values (5,0);
|
||||
insert into t2 (c) select * from t1;
|
||||
select * from t2;
|
||||
b c
|
||||
5 0
|
||||
6 10
|
||||
7 11
|
||||
8 12
|
||||
9 13
|
||||
select * from t1;
|
||||
a
|
||||
10
|
||||
11
|
||||
12
|
||||
13
|
||||
select * from t2;
|
||||
b c
|
||||
5 0
|
||||
6 10
|
||||
7 11
|
||||
8 12
|
||||
9 13
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
|
25
mysql-test/r/timezone.result
Normal file
25
mysql-test/r/timezone.result
Normal file
@ -0,0 +1,25 @@
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (ts int);
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 03:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 02:59:59'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:00:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:59:59'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01'));
|
||||
SELECT ts,from_unixtime(ts) FROM t1;
|
||||
ts from_unixtime(ts)
|
||||
1035673200 2002-10-27 01:00:00
|
||||
1035680400 2002-10-27 02:00:00
|
||||
1035684000 2002-10-27 03:00:00
|
||||
1035680400 2002-10-27 02:00:00
|
||||
1035673200 2002-10-27 01:00:00
|
||||
1035680400 2002-10-27 02:00:00
|
||||
1048986000 2003-03-30 03:00:00
|
||||
1048986000 2003-03-30 03:00:00
|
||||
1048989599 2003-03-30 03:59:59
|
||||
1048989601 2003-03-30 04:00:01
|
||||
DROP TABLE t1;
|
@ -135,3 +135,12 @@ analyze table t1;
|
||||
show keys from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Test of ALTER TABLE DELAYED
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (i int(10), index(i) );
|
||||
ALTER TABLE t1 DISABLE KEYS;
|
||||
INSERT DELAYED INTO t1 VALUES(1),(2),(3);
|
||||
ALTER TABLE t1 ENABLE KEYS;
|
||||
drop table t1;
|
||||
|
@ -71,3 +71,20 @@ WHERE numeropost=9 ORDER BY numreponse ASC;
|
||||
|
||||
DROP TABLE IF EXISTS t1,t2;
|
||||
|
||||
# Addendum by Guilhem:
|
||||
# Check if a partly-completed INSERT SELECT in a MyISAM table goes
|
||||
# into the binlog
|
||||
|
||||
create table t1(a int, unique(a));
|
||||
insert into t1 values(2);
|
||||
create table t2(a int);
|
||||
insert into t2 values(1),(2);
|
||||
reset master;
|
||||
--error 1062
|
||||
insert into t1 select * from t2;
|
||||
# The above should produce an error, but still be in the binlog;
|
||||
# verify the binlog :
|
||||
let $VERSION=`select version()`;
|
||||
--replace_result $VERSION VERSION
|
||||
show binlog events;
|
||||
drop table t1, t2;
|
||||
|
@ -10,4 +10,12 @@ create table t1 (a date, b date, c date not null, d date);
|
||||
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',';
|
||||
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' IGNORE 2 LINES;
|
||||
SELECT * from t1;
|
||||
truncate table t1;
|
||||
|
||||
load data infile '../../std_data/loaddata1.dat' into table t1 fields terminated by ',' LINES STARTING BY ',' (b,c,d);
|
||||
SELECT * from t1;
|
||||
drop table t1;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -14,3 +14,14 @@ ALTER TABLE T2 ADD new_col int not null;
|
||||
ALTER TABLE T2 RENAME T3;
|
||||
show tables like 't_';
|
||||
drop table t3;
|
||||
#
|
||||
# Test alias
|
||||
#
|
||||
create table t1 (a int);
|
||||
select count(*) from T1;
|
||||
select count(*) from t1;
|
||||
--error 1109
|
||||
select count(T1.a) from t1;
|
||||
--error 1109
|
||||
select count(bags.a) from t1 as Bags;
|
||||
drop table t1;
|
||||
|
@ -371,18 +371,35 @@ show global variables like "query_cache_min_res_unit";
|
||||
#
|
||||
# Test of query cache resizing
|
||||
#
|
||||
create table t1 (a int);
|
||||
set GLOBAL query_cache_size=1000;
|
||||
show global variables like "query_cache_size";
|
||||
set GLOBAL query_cache_size=1100;
|
||||
set GLOBAL query_cache_size=1200;
|
||||
set GLOBAL query_cache_size=1300;
|
||||
set GLOBAL query_cache_size=1400;
|
||||
set GLOBAL query_cache_size=1500;
|
||||
set GLOBAL query_cache_size=1600;
|
||||
set GLOBAL query_cache_size=1700;
|
||||
set GLOBAL query_cache_size=1800;
|
||||
set GLOBAL query_cache_size=1900;
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=1024;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=10240;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=20480;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=40960;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=51200;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=61440;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=81920;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
set GLOBAL query_cache_size=102400;
|
||||
show global variables like "query_cache_size";
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# Temporary tables
|
||||
|
@ -1,5 +1,7 @@
|
||||
-- require r/have_raid.require
|
||||
disable_query_log;
|
||||
show variables like "have_raid";
|
||||
enable_query_log;
|
||||
|
||||
#
|
||||
# Test of raided tables
|
||||
|
@ -1,5 +1,8 @@
|
||||
# See if queries that use both auto_increment and LAST_INSERT_ID()
|
||||
# are replicated well
|
||||
|
||||
# We also check how the foreign_key_check variable is replicated
|
||||
|
||||
source include/master-slave.inc;
|
||||
connection master;
|
||||
create table t1(a int auto_increment, key(a));
|
||||
@ -20,10 +23,30 @@ drop table t1;
|
||||
drop table t2;
|
||||
create table t1(a int auto_increment, key(a));
|
||||
create table t2(b int auto_increment, c int, key(b));
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
insert into t1 values (10);
|
||||
insert into t1 values (null),(null),(null);
|
||||
insert into t2 values (5,0);
|
||||
insert into t2 values (null,last_insert_id());
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
select * from t1;
|
||||
select * from t2;
|
||||
connection master;
|
||||
|
||||
# check if INSERT SELECT in auto_increment is well replicated (bug #490)
|
||||
|
||||
drop table t1;
|
||||
drop table t2;
|
||||
create table t1(a int auto_increment, key(a));
|
||||
create table t2(b int auto_increment, c int, key(b));
|
||||
insert into t1 values (10);
|
||||
insert into t1 values (null),(null),(null);
|
||||
insert into t2 values (5,0);
|
||||
insert into t2 (c) select * from t1;
|
||||
select * from t2;
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
@ -32,11 +32,33 @@ show binlog events from 79 limit 2;
|
||||
show binlog events from 79 limit 2,1;
|
||||
flush logs;
|
||||
|
||||
# We need an extra update before doing save_master_pos.
|
||||
# Otherwise, an unlikely scenario may occur:
|
||||
# * When the master's binlog_dump thread reads the end of master-bin.001,
|
||||
# it send the rotate event which is at this end, plus a fake rotate event
|
||||
# because it's starting to read a new binlog.
|
||||
# save_master_pos will record the position of the first of the two rotate
|
||||
# (because the fake one is not in the master's binlog anyway).
|
||||
# * Later the slave waits for the position of the first rotate event,
|
||||
# and it may quickly stop (in 'slave stop') without having received the fake
|
||||
# one.
|
||||
# So, depending on a few milliseconds, we end up with 2 rotate events in the
|
||||
# relay log or one, which influences the output of SHOW SLAVE STATUS, making
|
||||
# it not predictable and causing random test failures.
|
||||
# To make it predictable, we do a useless update now, but which has the interest
|
||||
# of making the slave catch both rotate events.
|
||||
|
||||
create table t5 (a int);
|
||||
drop table t5;
|
||||
|
||||
# Sync slave and force it to start on another binary log
|
||||
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
start slave;
|
||||
# Note that the above 'slave start' will cause a 3rd rotate event (a fake one)
|
||||
# to go into the relay log (the master always sends a fake one when replication
|
||||
# starts).
|
||||
slave start;
|
||||
sync_with_master;
|
||||
flush logs;
|
||||
stop slave;
|
||||
|
1
mysql-test/t/timezone-master.opt
Normal file
1
mysql-test/t/timezone-master.opt
Normal file
@ -0,0 +1 @@
|
||||
--timezone=MET
|
28
mysql-test/t/timezone.test
Normal file
28
mysql-test/t/timezone.test
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# Test of timezone handling. This script must be run with TZ=MEST
|
||||
|
||||
-- require r/have_mest_timezone.require
|
||||
disable_query_log;
|
||||
show variables like "timezone";
|
||||
enable_query_log;
|
||||
|
||||
# Initialization
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
|
||||
|
||||
CREATE TABLE t1 (ts int);
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 03:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 01:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2002-10-27 02:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 02:59:59'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:00:00'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 03:59:59'));
|
||||
INSERT INTO t1 (ts) VALUES (Unix_timestamp('2003-03-30 04:00:01'));
|
||||
|
||||
SELECT ts,from_unixtime(ts) FROM t1;
|
||||
DROP TABLE t1;
|
@ -72,6 +72,7 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args,MEM_ROOT *alloc,
|
||||
const char *dir, const char *config_file,
|
||||
const char *ext, TYPELIB *group);
|
||||
|
||||
static char *remove_end_comment(char *ptr);
|
||||
|
||||
void load_defaults(const char *conf_file, const char **groups,
|
||||
int *argc, char ***argv)
|
||||
@ -299,8 +300,9 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
|
||||
}
|
||||
if (!read_values)
|
||||
continue;
|
||||
if (!(end=value=strchr(ptr,'=')))
|
||||
end=strend(ptr); /* Option without argument */
|
||||
end= remove_end_comment(ptr);
|
||||
if ((value= strchr(ptr, '=')))
|
||||
end= value; /* Option without argument */
|
||||
for ( ; my_isspace(&my_charset_latin1,end[-1]) ; end--) ;
|
||||
if (!value)
|
||||
{
|
||||
@ -370,6 +372,29 @@ static my_bool search_default_file(DYNAMIC_ARRAY *args, MEM_ROOT *alloc,
|
||||
}
|
||||
|
||||
|
||||
static char *remove_end_comment(char *ptr)
|
||||
{
|
||||
char quote= 0;
|
||||
|
||||
for (; *ptr; ptr++)
|
||||
{
|
||||
if (*ptr == '\'' || *ptr == '\"')
|
||||
{
|
||||
if (!quote)
|
||||
quote= *ptr;
|
||||
else if (quote == *ptr)
|
||||
quote= 0;
|
||||
}
|
||||
if (!quote && *ptr == '#') /* We are not inside a comment */
|
||||
{
|
||||
*ptr= 0;
|
||||
return ptr;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
void print_defaults(const char *conf_file, const char **groups)
|
||||
{
|
||||
#ifdef __WIN__
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include <m_string.h>
|
||||
#include <queues.h>
|
||||
#include "thr_alarm.h"
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h> /* AIX needs this for fd_set */
|
||||
@ -36,21 +37,22 @@
|
||||
#define ETIME ETIMEDOUT
|
||||
#endif
|
||||
|
||||
static my_bool alarm_aborted=1;
|
||||
my_bool thr_alarm_inited=0;
|
||||
static int alarm_aborted=1; /* No alarm thread */
|
||||
my_bool thr_alarm_inited= 0;
|
||||
volatile my_bool alarm_thread_running= 0;
|
||||
|
||||
static sig_handler process_alarm_part2(int sig);
|
||||
|
||||
#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2)
|
||||
|
||||
static pthread_mutex_t LOCK_alarm;
|
||||
static pthread_cond_t COND_alarm;
|
||||
static sigset_t full_signal_set;
|
||||
static QUEUE alarm_queue;
|
||||
static uint max_used_alarms=0;
|
||||
pthread_t alarm_thread;
|
||||
|
||||
#ifdef USE_ALARM_THREAD
|
||||
static pthread_cond_t COND_alarm;
|
||||
static void *alarm_handler(void *arg);
|
||||
#define reschedule_alarms() pthread_cond_signal(&COND_alarm)
|
||||
#else
|
||||
@ -77,6 +79,7 @@ void init_thr_alarm(uint max_alarms)
|
||||
compare_ulong,NullS);
|
||||
sigfillset(&full_signal_set); /* Neaded to block signals */
|
||||
pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST);
|
||||
pthread_cond_init(&COND_alarm,NULL);
|
||||
#if THR_CLIENT_ALARM != SIGALRM || defined(USE_ALARM_THREAD)
|
||||
#if defined(HAVE_mit_thread)
|
||||
sigset(THR_CLIENT_ALARM,thread_alarm); /* int. thread system calls */
|
||||
@ -96,7 +99,6 @@ void init_thr_alarm(uint max_alarms)
|
||||
{
|
||||
pthread_attr_t thr_attr;
|
||||
pthread_attr_init(&thr_attr);
|
||||
pthread_cond_init(&COND_alarm,NULL);
|
||||
pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS);
|
||||
pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
|
||||
pthread_attr_setstacksize(&thr_attr,8196);
|
||||
@ -136,19 +138,24 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
|
||||
now=(ulong) time((time_t*) 0);
|
||||
pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask);
|
||||
pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */
|
||||
if (alarm_aborted)
|
||||
if (alarm_aborted > 0)
|
||||
{ /* No signal thread */
|
||||
DBUG_PRINT("info", ("alarm aborted"));
|
||||
*alrm= 0; /* No alarm */
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
|
||||
DBUG_RETURN(1);
|
||||
}
|
||||
if (alarm_aborted < 0)
|
||||
sec= 1; /* Abort mode */
|
||||
|
||||
if (alarm_queue.elements >= max_used_alarms)
|
||||
{
|
||||
if (alarm_queue.elements == alarm_queue.max_elements)
|
||||
{
|
||||
DBUG_PRINT("info", ("alarm queue full"));
|
||||
fprintf(stderr,"Warning: thr_alarm queue is full\n");
|
||||
*alrm= 0; /* No alarm */
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
|
||||
DBUG_RETURN(1);
|
||||
@ -163,6 +170,7 @@ bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data)
|
||||
if (!(alarm_data=(ALARM*) my_malloc(sizeof(ALARM),MYF(MY_WME))))
|
||||
{
|
||||
DBUG_PRINT("info", ("failed my_malloc()"));
|
||||
*alrm= 0; /* No alarm */
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
|
||||
DBUG_RETURN(1);
|
||||
@ -219,6 +227,7 @@ void thr_end_alarm(thr_alarm_t *alarmed)
|
||||
break;
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(!*alarmed || found);
|
||||
if (!found)
|
||||
{
|
||||
#ifdef MAIN
|
||||
@ -228,14 +237,7 @@ void thr_end_alarm(thr_alarm_t *alarmed)
|
||||
DBUG_PRINT("warning",("Didn't find alarm %lx in queue\n",
|
||||
(long) *alarmed));
|
||||
}
|
||||
if (alarm_aborted && !alarm_queue.elements)
|
||||
{
|
||||
delete_queue(&alarm_queue);
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_mutex_destroy(&LOCK_alarm);
|
||||
}
|
||||
else
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_sigmask(SIG_SETMASK,&old_mask,NULL);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -365,31 +367,66 @@ static sig_handler process_alarm_part2(int sig __attribute__((unused)))
|
||||
|
||||
|
||||
/*
|
||||
Shedule all alarms now.
|
||||
When all alarms are given, Free alarm memory and don't allow more alarms.
|
||||
Schedule all alarms now and optionally free all structures
|
||||
|
||||
SYNPOSIS
|
||||
end_thr_alarm()
|
||||
free_structures Set to 1 if we should free memory used for
|
||||
the alarm queue.
|
||||
When we call this we should KNOW that there
|
||||
is no active alarms
|
||||
IMPLEMENTATION
|
||||
Set alarm_abort to -1 which will change the behavior of alarms as follows:
|
||||
- All old alarms will be rescheduled at once
|
||||
- All new alarms will be rescheduled to one second
|
||||
*/
|
||||
|
||||
void end_thr_alarm(void)
|
||||
void end_thr_alarm(my_bool free_structures)
|
||||
{
|
||||
DBUG_ENTER("end_thr_alarm");
|
||||
if (!alarm_aborted)
|
||||
if (alarm_aborted != 1) /* If memory not freed */
|
||||
{
|
||||
my_bool deleted=0;
|
||||
pthread_mutex_lock(&LOCK_alarm);
|
||||
DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
|
||||
alarm_aborted=1; /* mark aborted */
|
||||
if (!alarm_queue.elements)
|
||||
alarm_aborted= -1; /* mark aborted */
|
||||
if (alarm_queue.elements || (alarm_thread_running && free_structures))
|
||||
{
|
||||
deleted= 1;
|
||||
delete_queue(&alarm_queue);
|
||||
if (pthread_equal(pthread_self(),alarm_thread))
|
||||
alarm(1); /* Shut down everything soon */
|
||||
else
|
||||
reschedule_alarms();
|
||||
}
|
||||
if (free_structures)
|
||||
{
|
||||
struct timespec abstime;
|
||||
/*
|
||||
The following test is just for safety, the caller should not
|
||||
depend on this
|
||||
*/
|
||||
DBUG_ASSERT(!alarm_queue.elements);
|
||||
/* Wait until alarm thread dies */
|
||||
|
||||
set_timespec(abstime, 10); /* Wait up to 10 seconds */
|
||||
while (alarm_thread_running)
|
||||
{
|
||||
int error= pthread_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime);
|
||||
if (error == ETIME || error == ETIMEDOUT)
|
||||
break; /* Don't wait forever */
|
||||
}
|
||||
if (!alarm_queue.elements)
|
||||
{
|
||||
delete_queue(&alarm_queue);
|
||||
alarm_aborted= 1;
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
if (!alarm_thread_running) /* Safety */
|
||||
{
|
||||
pthread_mutex_destroy(&LOCK_alarm);
|
||||
pthread_cond_destroy(&COND_alarm);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (pthread_equal(pthread_self(),alarm_thread))
|
||||
alarm(1); /* Shut down everything soon */
|
||||
else
|
||||
reschedule_alarms();
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
if (deleted)
|
||||
pthread_mutex_destroy(&LOCK_alarm);
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -471,6 +508,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
|
||||
puts("Starting alarm thread");
|
||||
#endif
|
||||
my_thread_init();
|
||||
alarm_thread_running= 1;
|
||||
pthread_mutex_lock(&LOCK_alarm);
|
||||
for (;;)
|
||||
{
|
||||
@ -495,7 +533,7 @@ static void *alarm_handler(void *arg __attribute__((unused)))
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (alarm_aborted)
|
||||
else if (alarm_aborted == -1)
|
||||
break;
|
||||
else if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm)))
|
||||
{
|
||||
@ -507,6 +545,8 @@ static void *alarm_handler(void *arg __attribute__((unused)))
|
||||
process_alarm(0);
|
||||
}
|
||||
bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */
|
||||
alarm_thread_running= 0;
|
||||
pthread_cond_signal(&COND_alarm);
|
||||
pthread_mutex_unlock(&LOCK_alarm);
|
||||
pthread_exit(0);
|
||||
return 0; /* Impossible */
|
||||
@ -629,7 +669,7 @@ void thr_end_alarm(thr_alarm_t *alrm_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
void end_thr_alarm(void)
|
||||
void end_thr_alarm(my_bool free_structures)
|
||||
{
|
||||
DBUG_ENTER("end_thr_alarm");
|
||||
alarm_aborted=1; /* No more alarms */
|
||||
@ -708,7 +748,7 @@ void thr_end_alarm(thr_alarm_t *alrm_ptr)
|
||||
}
|
||||
}
|
||||
|
||||
void end_thr_alarm(void)
|
||||
void end_thr_alarm(my_bool free_structures)
|
||||
{
|
||||
DBUG_ENTER("end_thr_alarm");
|
||||
alarm_aborted=1; /* No more alarms */
|
||||
@ -907,7 +947,7 @@ static void *signal_hand(void *arg __attribute__((unused)))
|
||||
case SIGHUP:
|
||||
#endif
|
||||
printf("Aborting nicely\n");
|
||||
end_thr_alarm();
|
||||
end_thr_alarm(0);
|
||||
break;
|
||||
#ifdef SIGTSTP
|
||||
case SIGTSTP:
|
||||
@ -1004,10 +1044,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused)))
|
||||
if (thread_count == 1)
|
||||
{
|
||||
printf("Calling end_thr_alarm. This should cancel the last thread\n");
|
||||
end_thr_alarm();
|
||||
end_thr_alarm(0);
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&LOCK_thread_count);
|
||||
end_thr_alarm(1);
|
||||
thr_alarm_info(&alarm_info);
|
||||
printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n",
|
||||
alarm_info.active_alarms, alarm_info.max_used_alarms,
|
||||
|
@ -2755,6 +2755,7 @@ int Field_timestamp::store(longlong nr)
|
||||
|
||||
if ((nr=fix_datetime(nr)))
|
||||
{
|
||||
long not_used;
|
||||
part1=(long) (nr/LL(1000000));
|
||||
part2=(long) (nr - (longlong) part1*LL(1000000));
|
||||
l_time.year= (int) (part1/10000L); part1%=10000L;
|
||||
@ -2763,7 +2764,7 @@ int Field_timestamp::store(longlong nr)
|
||||
l_time.hour= (int) (part2/10000L); part2%=10000L;
|
||||
l_time.minute=(int) part2 / 100;
|
||||
l_time.second=(int) part2 % 100;
|
||||
timestamp=my_gmt_sec(&l_time);
|
||||
timestamp=my_gmt_sec(&l_time, ¬_used);
|
||||
}
|
||||
else
|
||||
timestamp=0;
|
||||
|
51
sql/log.cc
51
sql/log.cc
@ -1200,6 +1200,12 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
No check for auto events flag here - this write method should
|
||||
never be called if auto-events are enabled
|
||||
*/
|
||||
|
||||
/*
|
||||
1. Write first log events which describe the 'run environment'
|
||||
of the SQL command
|
||||
*/
|
||||
|
||||
if (thd)
|
||||
{
|
||||
if (thd->last_insert_id_used)
|
||||
@ -1245,7 +1251,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
#ifdef TO_BE_REMOVED
|
||||
if (thd->variables.convert_set)
|
||||
{
|
||||
char buf[256], *p;
|
||||
@ -1257,12 +1263,39 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
goto err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
If the user has set FOREIGN_KEY_CHECKS=0 we wrap every SQL
|
||||
command in the binlog inside:
|
||||
SET FOREIGN_KEY_CHECKS=0;
|
||||
<command>;
|
||||
SET FOREIGN_KEY_CHECKS=1;
|
||||
*/
|
||||
|
||||
if (thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
|
||||
{
|
||||
Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=0", 24, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
/* Write the SQL command */
|
||||
|
||||
event_info->set_log_pos(this);
|
||||
if (event_info->write(file) ||
|
||||
file == &log_file && flush_io_cache(file))
|
||||
if (event_info->write(file))
|
||||
goto err;
|
||||
error=0;
|
||||
|
||||
/* Write log events to reset the 'run environment' of the SQL command */
|
||||
|
||||
if (thd && thd->options & OPTION_NO_FOREIGN_KEY_CHECKS)
|
||||
{
|
||||
Query_log_event e(thd, "SET FOREIGN_KEY_CHECKS=1", 24, 0);
|
||||
e.set_log_pos(this);
|
||||
if (e.write(file))
|
||||
goto err;
|
||||
}
|
||||
|
||||
/*
|
||||
Tell for transactional table handlers up to which position in the
|
||||
@ -1283,6 +1316,9 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
|
||||
if (file == &log_file) // we are writing to the real log (disk)
|
||||
{
|
||||
if (flush_io_cache(file))
|
||||
goto err;
|
||||
|
||||
if (opt_using_transactions && !my_b_tell(&thd->transaction.trans_log))
|
||||
{
|
||||
/*
|
||||
@ -1292,8 +1328,8 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
handler if the log event type is appropriate.
|
||||
*/
|
||||
|
||||
if (event_info->get_type_code() == QUERY_EVENT
|
||||
|| event_info->get_type_code() == EXEC_LOAD_EVENT)
|
||||
if (event_info->get_type_code() == QUERY_EVENT ||
|
||||
event_info->get_type_code() == EXEC_LOAD_EVENT)
|
||||
{
|
||||
error = ha_report_binlog_offset_and_commit(thd, log_file_name,
|
||||
file->pos_in_file);
|
||||
@ -1303,6 +1339,7 @@ bool MYSQL_LOG::write(Log_event* event_info)
|
||||
/* we wrote to the real log, check automatic rotation */
|
||||
should_rotate= (my_b_tell(file) >= (my_off_t) max_binlog_size);
|
||||
}
|
||||
error=0;
|
||||
|
||||
err:
|
||||
if (error)
|
||||
@ -1329,7 +1366,7 @@ err:
|
||||
Flush the transactional handler log file now that we have released
|
||||
LOCK_log; the flush is placed here to eliminate the bottleneck on the
|
||||
group commit
|
||||
*/
|
||||
*/
|
||||
|
||||
if (called_handler_commit)
|
||||
ha_commit_complete(thd);
|
||||
|
@ -461,7 +461,6 @@ bool mysql_rename_table(enum db_type base,
|
||||
const char * old_name,
|
||||
const char *new_db,
|
||||
const char * new_name);
|
||||
bool close_cached_table(THD *thd,TABLE *table);
|
||||
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
|
||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
||||
List<Alter_drop> &drop_list);
|
||||
@ -501,6 +500,7 @@ Field *find_field_in_tables(THD *thd, Item_ident *item, TABLE_LIST *tables,
|
||||
Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length,
|
||||
bool check_grant,bool allow_rowid);
|
||||
#ifdef HAVE_OPENSSL
|
||||
#include <openssl/des.h>
|
||||
struct st_des_keyblock
|
||||
{
|
||||
des_cblock key1, key2, key3;
|
||||
@ -837,7 +837,7 @@ uint calc_days_in_year(uint year);
|
||||
void get_date_from_daynr(long daynr,uint *year, uint *month,
|
||||
uint *day);
|
||||
void init_time(void);
|
||||
long my_gmt_sec(TIME *);
|
||||
long my_gmt_sec(TIME *, long *current_timezone);
|
||||
time_t str_to_timestamp(const char *str,uint length);
|
||||
bool str_to_time(const char *str,uint length,TIME *l_time);
|
||||
longlong str_to_datetime(const char *str,uint length,bool fuzzy_date);
|
||||
|
@ -566,7 +566,7 @@ static void close_connections(void)
|
||||
unix_sock= INVALID_SOCKET;
|
||||
}
|
||||
#endif
|
||||
end_thr_alarm(); // Don't allow alarms
|
||||
end_thr_alarm(0); // Abort old alarms.
|
||||
end_slave();
|
||||
|
||||
/* First signal all threads that it's time to die */
|
||||
@ -875,6 +875,7 @@ void clean_up(bool print_message)
|
||||
#endif
|
||||
(void) ha_panic(HA_PANIC_CLOSE); /* close all tables and logs */
|
||||
end_key_cache();
|
||||
end_thr_alarm(1); /* Free allocated memory */
|
||||
#ifdef USE_RAID
|
||||
end_raid();
|
||||
#endif
|
||||
@ -940,7 +941,6 @@ static void clean_up_mutexes()
|
||||
(void) pthread_mutex_destroy(&LOCK_crypt);
|
||||
(void) pthread_mutex_destroy(&LOCK_bytes_sent);
|
||||
(void) pthread_mutex_destroy(&LOCK_bytes_received);
|
||||
(void) pthread_mutex_destroy(&LOCK_timezone);
|
||||
(void) pthread_mutex_destroy(&LOCK_user_conn);
|
||||
#ifdef HAVE_REPLICATION
|
||||
(void) pthread_mutex_destroy(&LOCK_rpl_status);
|
||||
@ -1501,7 +1501,6 @@ the problem, but since we have already crashed, something is definitely wrong\n\
|
||||
and this may fail.\n\n");
|
||||
fprintf(stderr, "key_buffer_size=%lu\n", (ulong) keybuff_size);
|
||||
fprintf(stderr, "read_buffer_size=%ld\n", global_system_variables.read_buff_size);
|
||||
fprintf(stderr, "sort_buffer_size=%ld\n", thd->variables.sortbuff_size);
|
||||
fprintf(stderr, "max_used_connections=%ld\n", max_used_connections);
|
||||
fprintf(stderr, "max_connections=%ld\n", max_connections);
|
||||
fprintf(stderr, "threads_connected=%d\n", thread_count);
|
||||
@ -1509,7 +1508,7 @@ and this may fail.\n\n");
|
||||
key_buffer_size + (read_buffer_size + sort_buffer_size)*max_connections = %ld K\n\
|
||||
bytes of memory\n", ((ulong) keybuff_size +
|
||||
(global_system_variables.read_buff_size +
|
||||
thd->variables.sortbuff_size) *
|
||||
global_system_variables.sortbuff_size) *
|
||||
max_connections)/ 1024);
|
||||
fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n");
|
||||
|
||||
@ -1538,14 +1537,9 @@ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n",
|
||||
Some pointers may be invalid and cause the dump to abort...\n");
|
||||
safe_print_str("thd->query", thd->query, 1024);
|
||||
fprintf(stderr, "thd->thread_id=%ld\n", thd->thread_id);
|
||||
fprintf(stderr, "\n\
|
||||
Successfully dumped variables, if you ran with --log, take a look at the\n\
|
||||
details of what thread %ld did to cause the crash. In some cases of really\n\
|
||||
bad corruption, the values shown above may be invalid.\n\n",
|
||||
thd->thread_id);
|
||||
}
|
||||
fprintf(stderr, "\
|
||||
The manual page at http://www.mysql.com/doc/C/r/Crashing.html contains\n\
|
||||
The manual page at http://www.mysql.com/doc/en/Crashing.html contains\n\
|
||||
information that should help you find out what is causing the crash.\n");
|
||||
fflush(stderr);
|
||||
#endif /* HAVE_STACKTRACE */
|
||||
@ -1569,6 +1563,7 @@ information that should help you find out what is causing the crash.\n");
|
||||
static void init_signals(void)
|
||||
{
|
||||
sigset_t set;
|
||||
struct sigaction sa;
|
||||
DBUG_ENTER("init_signals");
|
||||
|
||||
sigset(THR_KILL_SIGNAL,end_thread_signal);
|
||||
@ -1576,7 +1571,6 @@ static void init_signals(void)
|
||||
|
||||
if (!(test_flags & TEST_NO_STACKTRACE) || (test_flags & TEST_CORE_ON_SIGNAL))
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_flags = SA_RESETHAND | SA_NODEFER;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sigprocmask(SIG_SETMASK,&sa.sa_mask,NULL);
|
||||
@ -1618,15 +1612,23 @@ static void init_signals(void)
|
||||
sigaddset(&set,SIGQUIT);
|
||||
sigaddset(&set,SIGTERM);
|
||||
sigaddset(&set,SIGHUP);
|
||||
sigset(SIGTERM, print_signal_warning); // If it's blocked by parent
|
||||
sigset(SIGHUP, print_signal_warning); // If it's blocked by parent
|
||||
|
||||
/* Fix signals if blocked by parents (can happen on Mac OS X) */
|
||||
sigemptyset(&sa.sa_mask);
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = print_signal_warning;
|
||||
sigaction(SIGTERM, &sa, (struct sigaction*) 0);
|
||||
sa.sa_flags = 0;
|
||||
sa.sa_handler = print_signal_warning;
|
||||
sigaction(SIGHUP, &sa, (struct sigaction*) 0);
|
||||
#ifdef SIGTSTP
|
||||
sigaddset(&set,SIGTSTP);
|
||||
#endif
|
||||
sigaddset(&set,THR_SERVER_ALARM);
|
||||
sigdelset(&set,THR_KILL_SIGNAL); // May be SIGINT
|
||||
sigdelset(&set,THR_CLIENT_ALARM); // For alarms
|
||||
(void) pthread_sigmask(SIG_SETMASK,&set,NULL);
|
||||
sigprocmask(SIG_SETMASK,&set,NULL);
|
||||
pthread_sigmask(SIG_SETMASK,&set,NULL);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
@ -1894,7 +1896,7 @@ extern "C" pthread_handler_decl(handle_shutdown,arg)
|
||||
#endif
|
||||
|
||||
|
||||
const char *load_default_groups[]= { "mysqld","server",0 };
|
||||
const char *load_default_groups[]= { "mysqld","server",MYSQL_BASE_VERSION,0 };
|
||||
|
||||
bool open_log(MYSQL_LOG *log, const char *hostname,
|
||||
const char *opt_name, const char *extension,
|
||||
@ -1951,19 +1953,11 @@ static int init_common_variables(const char *conf_file_name, int argc,
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_TZNAME
|
||||
#if defined(HAVE_LOCALTIME_R) && defined(_REENTRANT)
|
||||
{
|
||||
struct tm tm_tmp;
|
||||
localtime_r(&start_time,&tm_tmp);
|
||||
strmov(time_zone,tzname[tm_tmp.tm_isdst != 0 ? 1 : 0]);
|
||||
}
|
||||
#else
|
||||
{
|
||||
struct tm *start_tm;
|
||||
start_tm=localtime(&start_time);
|
||||
strmov(time_zone,tzname[start_tm->tm_isdst != 0 ? 1 : 0]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if (gethostname(glob_hostname,sizeof(glob_hostname)-4) < 0)
|
||||
@ -2075,7 +2069,6 @@ static int init_thread_environment()
|
||||
(void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_bytes_sent,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_bytes_received,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_timezone,MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_active_mi, MY_MUTEX_INIT_FAST);
|
||||
(void) pthread_mutex_init(&LOCK_global_system_variables, MY_MUTEX_INIT_FAST);
|
||||
@ -2441,14 +2434,14 @@ The server will not act as a slave.");
|
||||
if (opt_bootstrap)
|
||||
{
|
||||
int error=bootstrap(stdin);
|
||||
end_thr_alarm(); // Don't allow alarms
|
||||
end_thr_alarm(1); // Don't allow alarms
|
||||
unireg_abort(error ? 1 : 0);
|
||||
}
|
||||
if (opt_init_file)
|
||||
{
|
||||
if (read_init_file(opt_init_file))
|
||||
{
|
||||
end_thr_alarm(); // Don't allow alarms
|
||||
end_thr_alarm(1); // Don't allow alarms
|
||||
unireg_abort(1);
|
||||
}
|
||||
}
|
||||
@ -2620,9 +2613,12 @@ int main(int argc, char **argv)
|
||||
return 0;
|
||||
if (Service.IsService(argv[2]))
|
||||
{
|
||||
/* start an optional service */
|
||||
/*
|
||||
mysqld was started as
|
||||
mysqld --defaults-file=my_path\my.ini service-name
|
||||
*/
|
||||
use_opt_args=1;
|
||||
opt_argc=argc;
|
||||
opt_argc= 2; // Skip service-name
|
||||
opt_argv=argv;
|
||||
start_mode= 1;
|
||||
Service.Init(argv[2], mysql_service);
|
||||
|
@ -209,6 +209,7 @@ sys_var_thd_ulong sys_net_retry_count("net_retry_count",
|
||||
sys_var_thd_bool sys_new_mode("new", &SV::new_mode);
|
||||
sys_var_thd_ulong sys_read_buff_size("read_buffer_size",
|
||||
&SV::read_buff_size);
|
||||
sys_var_bool_ptr sys_readonly("read_only", &opt_readonly);
|
||||
sys_var_thd_ulong sys_read_rnd_buff_size("read_rnd_buffer_size",
|
||||
&SV::read_rnd_buff_size);
|
||||
#ifdef HAVE_REPLICATION
|
||||
@ -596,6 +597,7 @@ struct show_var_st init_vars[]= {
|
||||
{"protocol_version", (char*) &protocol_version, SHOW_INT},
|
||||
{sys_pseudo_thread_id.name, (char*) &sys_pseudo_thread_id, SHOW_SYS},
|
||||
{sys_read_buff_size.name, (char*) &sys_read_buff_size, SHOW_SYS},
|
||||
{sys_readonly.name, (char*) &sys_readonly, SHOW_SYS},
|
||||
{sys_read_rnd_buff_size.name,(char*) &sys_read_rnd_buff_size, SHOW_SYS},
|
||||
#ifdef HAVE_REPLICATION
|
||||
{sys_relay_log_purge.name, (char*) &sys_relay_log_purge, SHOW_SYS},
|
||||
|
27
sql/slave.cc
27
sql/slave.cc
@ -1388,9 +1388,7 @@ static bool wait_for_relay_log_space(RELAY_LOG_INFO* rli)
|
||||
while (rli->log_space_limit < rli->log_space_total &&
|
||||
!(slave_killed=io_slave_killed(thd,mi)) &&
|
||||
!rli->ignore_log_space_limit)
|
||||
{
|
||||
pthread_cond_wait(&rli->log_space_cond, &rli->log_space_lock);
|
||||
}
|
||||
thd->proc_info = save_proc_info;
|
||||
pthread_mutex_unlock(&rli->log_space_lock);
|
||||
DBUG_RETURN(slave_killed);
|
||||
@ -2101,7 +2099,11 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
||||
Log_event * ev = next_event(rli);
|
||||
DBUG_ASSERT(rli->sql_thd==thd);
|
||||
if (sql_slave_killed(thd,rli))
|
||||
{
|
||||
/* do not forget to free ev ! */
|
||||
if (ev) delete ev;
|
||||
return 1;
|
||||
}
|
||||
if (ev)
|
||||
{
|
||||
int type_code = ev->get_type_code();
|
||||
@ -2376,6 +2378,18 @@ reconnect done to recover from failed read");
|
||||
goto err;
|
||||
}
|
||||
flush_master_info(mi);
|
||||
/*
|
||||
See if the relay logs take too much space.
|
||||
We don't lock mi->rli.log_space_lock here; this dirty read saves time
|
||||
and does not introduce any problem:
|
||||
- if mi->rli.ignore_log_space_limit is 1 but becomes 0 just after (so
|
||||
the clean value is 0), then we are reading only one more event as we
|
||||
should, and we'll block only at the next event. No big deal.
|
||||
- if mi->rli.ignore_log_space_limit is 0 but becomes 1 just after (so
|
||||
the clean value is 1), then we are going into wait_for_relay_log_space()
|
||||
for no reason, but this function will do a clean read, notice the clean
|
||||
value and exit immediately.
|
||||
*/
|
||||
if (mi->rli.log_space_limit && mi->rli.log_space_limit <
|
||||
mi->rli.log_space_total &&
|
||||
!mi->rli.ignore_log_space_limit)
|
||||
@ -2489,7 +2503,9 @@ slave_begin:
|
||||
pthread_cond_broadcast(&rli->start_cond);
|
||||
|
||||
//tell the I/O thread to take relay_log_space_limit into account from now on
|
||||
pthread_mutex_lock(&rli->log_space_lock);
|
||||
rli->ignore_log_space_limit= 0;
|
||||
pthread_mutex_unlock(&rli->log_space_lock);
|
||||
|
||||
if (init_relay_log_pos(rli,
|
||||
rli->group_relay_log_name,
|
||||
@ -3221,7 +3237,12 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
|
||||
pthread_mutex_lock(&rli->log_space_lock);
|
||||
// prevent the I/O thread from blocking next times
|
||||
rli->ignore_log_space_limit= 1;
|
||||
// If the I/O thread is blocked, unblock it
|
||||
/*
|
||||
If the I/O thread is blocked, unblock it.
|
||||
Ok to broadcast after unlock, because the mutex is only destroyed in
|
||||
~st_relay_log_info(), i.e. when rli is destroyed, and rli will not be
|
||||
destroyed before we exit the present function.
|
||||
*/
|
||||
pthread_mutex_unlock(&rli->log_space_lock);
|
||||
pthread_cond_broadcast(&rli->log_space_cond);
|
||||
// Note that wait_for_update unlocks lock_log !
|
||||
|
@ -739,7 +739,7 @@ ulong Query_cache::resize(ulong query_cache_size_arg)
|
||||
query_cache_size_arg));
|
||||
free_cache(0);
|
||||
query_cache_size= query_cache_size_arg;
|
||||
DBUG_RETURN(init_cache());
|
||||
DBUG_RETURN(::query_cache_size= init_cache());
|
||||
}
|
||||
|
||||
|
||||
@ -1318,6 +1318,12 @@ ulong Query_cache::init_cache()
|
||||
mem_bin_steps = 1;
|
||||
mem_bin_size = max_mem_bin_size >> QUERY_CACHE_MEM_BIN_STEP_PWR2;
|
||||
prev_size = 0;
|
||||
if (mem_bin_size <= min_allocation_unit)
|
||||
{
|
||||
DBUG_PRINT("qcache", ("too small query cache => query cache disabled"));
|
||||
// TODO here (and above) should be warning in 4.1
|
||||
goto err;
|
||||
}
|
||||
while (mem_bin_size > min_allocation_unit)
|
||||
{
|
||||
mem_bin_num += mem_bin_count;
|
||||
@ -1344,14 +1350,6 @@ ulong Query_cache::init_cache()
|
||||
query_cache_size -= additional_data_size;
|
||||
|
||||
STRUCT_LOCK(&structure_guard_mutex);
|
||||
if (max_mem_bin_size <= min_allocation_unit)
|
||||
{
|
||||
DBUG_PRINT("qcache",
|
||||
(" max bin size (%lu) <= min_allocation_unit => cache disabled",
|
||||
max_mem_bin_size));
|
||||
STRUCT_UNLOCK(&structure_guard_mutex);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(cache = (byte *)
|
||||
my_malloc_lock(query_cache_size+additional_data_size, MYF(0))))
|
||||
|
@ -1421,6 +1421,24 @@ void select_insert::send_error(uint errcode,const char *err)
|
||||
::send_error(thd,errcode,err);
|
||||
table->file->extra(HA_EXTRA_NO_CACHE);
|
||||
table->file->activate_all_index(thd);
|
||||
/*
|
||||
If at least one row has been inserted/modified and will stay in the table
|
||||
(the table doesn't have transactions) (example: we got a duplicate key
|
||||
error while inserting into a MyISAM table) we must write to the binlog (and
|
||||
the error code will make the slave stop).
|
||||
*/
|
||||
if ((info.copied || info.deleted) && !table->file->has_transactions())
|
||||
{
|
||||
if (last_insert_id)
|
||||
thd->insert_id(last_insert_id); // For binary log
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
table->file->has_transactions());
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
}
|
||||
if (info.copied || info.deleted)
|
||||
query_cache_invalidate3(thd, table, 1);
|
||||
ha_rollback_stmt(thd);
|
||||
@ -1442,7 +1460,10 @@ bool select_insert::send_eof()
|
||||
if (info.copied || info.deleted)
|
||||
query_cache_invalidate3(thd, table, 1);
|
||||
|
||||
if (last_insert_id)
|
||||
thd->insert_id(last_insert_id); // For binary log
|
||||
/* Write to binlog before commiting transaction */
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
if (mysql_bin_log.is_open())
|
||||
{
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
@ -1467,10 +1488,7 @@ bool select_insert::send_eof()
|
||||
else
|
||||
sprintf(buff,ER(ER_INSERT_INFO),info.records,info.deleted,
|
||||
thd->cuted_fields);
|
||||
if (last_insert_id)
|
||||
thd->insert_id(last_insert_id); // For update log
|
||||
::send_ok(thd,info.copied+info.deleted,last_insert_id,buff);
|
||||
mysql_update_log.write(thd,thd->query,thd->query_length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
133
sql/sql_table.cc
133
sql/sql_table.cc
@ -1081,58 +1081,76 @@ mysql_rename_table(enum db_type base,
|
||||
}
|
||||
|
||||
/*
|
||||
close table in this thread and force close + reopen in other threads
|
||||
This assumes that the calling thread has lock on LOCK_open
|
||||
Win32 clients must also have a WRITE LOCK on the table !
|
||||
Force all other threads to stop using the table
|
||||
|
||||
SYNOPSIS
|
||||
wait_while_table_is_used()
|
||||
thd Thread handler
|
||||
table Table to remove from cache
|
||||
|
||||
NOTES
|
||||
When returning, the table will be unusable for other threads until
|
||||
the table is closed.
|
||||
|
||||
PREREQUISITES
|
||||
Lock on LOCK_open
|
||||
Win32 clients must also have a WRITE LOCK on the table !
|
||||
*/
|
||||
|
||||
static void safe_remove_from_cache(THD *thd,TABLE *table)
|
||||
static void wait_while_table_is_used(THD *thd,TABLE *table)
|
||||
{
|
||||
DBUG_ENTER("safe_remove_from_cache");
|
||||
if (table)
|
||||
{
|
||||
DBUG_PRINT("enter",("table: %s", table->real_name));
|
||||
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
|
||||
/* Mark all tables that are in use as 'old' */
|
||||
mysql_lock_abort(thd,table); // end threads waiting on lock
|
||||
DBUG_PRINT("enter",("table: %s", table->real_name));
|
||||
DBUG_ENTER("wait_while_table_is_used");
|
||||
safe_mutex_assert_owner(&LOCK_open);
|
||||
|
||||
#if defined(USING_TRANSACTIONS) || defined( __WIN__) || defined( __EMX__) || !defined(OS2)
|
||||
/* Wait until all there are no other threads that has this table open */
|
||||
while (remove_table_from_cache(thd,table->table_cache_key,
|
||||
table->real_name))
|
||||
{
|
||||
dropping_tables++;
|
||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||
dropping_tables--;
|
||||
}
|
||||
#else
|
||||
(void) remove_table_from_cache(thd,table->table_cache_key,
|
||||
table->real_name);
|
||||
#endif
|
||||
/* When lock on LOCK_open is freed other threads can continue */
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
VOID(table->file->extra(HA_EXTRA_FORCE_REOPEN)); // Close all data files
|
||||
/* Mark all tables that are in use as 'old' */
|
||||
mysql_lock_abort(thd, table); // end threads waiting on lock
|
||||
|
||||
/* Wait until all there are no other threads that has this table open */
|
||||
while (remove_table_from_cache(thd,table->table_cache_key,
|
||||
table->real_name))
|
||||
{
|
||||
dropping_tables++;
|
||||
(void) pthread_cond_wait(&COND_refresh,&LOCK_open);
|
||||
dropping_tables--;
|
||||
}
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
/*
|
||||
Close a cached table
|
||||
|
||||
bool close_cached_table(THD *thd,TABLE *table)
|
||||
SYNOPSIS
|
||||
clsoe_cached_table()
|
||||
thd Thread handler
|
||||
table Table to remove from cache
|
||||
|
||||
NOTES
|
||||
Function ends by signaling threads waiting for the table to try to
|
||||
reopen the table.
|
||||
|
||||
PREREQUISITES
|
||||
Lock on LOCK_open
|
||||
Win32 clients must also have a WRITE LOCK on the table !
|
||||
*/
|
||||
|
||||
static bool close_cached_table(THD *thd, TABLE *table)
|
||||
{
|
||||
DBUG_ENTER("close_cached_table");
|
||||
safe_mutex_assert_owner(&LOCK_open);
|
||||
|
||||
if (table)
|
||||
|
||||
wait_while_table_is_used(thd,table);
|
||||
/* Close lock if this is not got with LOCK TABLES */
|
||||
if (thd->lock)
|
||||
{
|
||||
safe_remove_from_cache(thd,table);
|
||||
/* Close lock if this is not got with LOCK TABLES */
|
||||
if (thd->lock)
|
||||
{
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0; // Start locked threads
|
||||
}
|
||||
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
|
||||
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
|
||||
mysql_unlock_tables(thd, thd->lock);
|
||||
thd->lock=0; // Start locked threads
|
||||
}
|
||||
/* Close all copies of 'table'. This also frees all LOCK TABLES lock */
|
||||
thd->open_tables=unlink_open_table(thd,thd->open_tables,table);
|
||||
|
||||
/* When lock on LOCK_open is freed other threads can continue */
|
||||
pthread_cond_broadcast(&COND_refresh);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
@ -1261,10 +1279,13 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
|
||||
|
||||
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
||||
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
close_cached_table(thd,table_list->table);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
|
||||
/* If we could open the table, close it */
|
||||
if (table_list->table)
|
||||
{
|
||||
pthread_mutex_lock(&LOCK_open);
|
||||
close_cached_table(thd, table);
|
||||
pthread_mutex_unlock(&LOCK_open);
|
||||
}
|
||||
if (lock_and_wait_for_table_name(thd,table_list))
|
||||
{
|
||||
error= -1;
|
||||
@ -1794,11 +1815,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
else
|
||||
{
|
||||
*fn_ext(new_name)=0;
|
||||
close_cached_table(thd,table);
|
||||
close_cached_table(thd, table);
|
||||
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_name))
|
||||
error= -1;
|
||||
}
|
||||
VOID(pthread_cond_broadcast(&COND_refresh));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
}
|
||||
if (!error)
|
||||
@ -1807,12 +1827,18 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
case LEAVE_AS_IS:
|
||||
break;
|
||||
case ENABLE:
|
||||
safe_remove_from_cache(thd,table);
|
||||
error= table->file->activate_all_index(thd);
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
wait_while_table_is_used(thd, table);
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
error= table->file->activate_all_index(thd);
|
||||
/* COND_refresh will be signaled in close_thread_tables() */
|
||||
break;
|
||||
case DISABLE:
|
||||
safe_remove_from_cache(thd,table);
|
||||
VOID(pthread_mutex_lock(&LOCK_open));
|
||||
wait_while_table_is_used(thd, table);
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
table->file->deactivate_non_unique_index(HA_POS_ERROR);
|
||||
/* COND_refresh will be signaled in close_thread_tables() */
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2247,7 +2273,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
close the original table at before doing the rename
|
||||
*/
|
||||
table_name=thd->strdup(table_name); // must be saved
|
||||
if (close_cached_table(thd,table))
|
||||
if (close_cached_table(thd, table))
|
||||
{ // Aborted
|
||||
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
@ -2281,7 +2307,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
This shouldn't happen. We solve this the safe way by
|
||||
closing the locked table.
|
||||
*/
|
||||
close_cached_table(thd,table);
|
||||
if (table)
|
||||
close_cached_table(thd,table);
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
goto err;
|
||||
}
|
||||
@ -2291,7 +2318,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
Not table locking or alter table with rename
|
||||
free locks and remove old table
|
||||
*/
|
||||
close_cached_table(thd,table);
|
||||
if (table)
|
||||
close_cached_table(thd,table);
|
||||
VOID(quick_rm_table(old_db_type,db,old_name));
|
||||
}
|
||||
else
|
||||
@ -2311,7 +2339,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (close_data_tables(thd,db,table_name) ||
|
||||
reopen_tables(thd,1,0))
|
||||
{ // This shouldn't happen
|
||||
close_cached_table(thd,table); // Remove lock for table
|
||||
if (table)
|
||||
close_cached_table(thd,table); // Remove lock for table
|
||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||
goto err;
|
||||
}
|
||||
|
@ -200,7 +200,6 @@ int mysql_update(THD *thd,
|
||||
*/
|
||||
uint length;
|
||||
SORT_FIELD *sortorder;
|
||||
List<Item> fields;
|
||||
ha_rows examined_rows;
|
||||
|
||||
table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE),
|
||||
|
@ -4324,6 +4324,7 @@ keyword:
|
||||
| SHARE_SYM {}
|
||||
| SHUTDOWN {}
|
||||
| SLAVE {}
|
||||
| SOUNDS_SYM {}
|
||||
| SQL_CACHE_SYM {}
|
||||
| SQL_BUFFER_RESULT {}
|
||||
| SQL_NO_CACHE_SYM {}
|
||||
@ -4348,8 +4349,8 @@ keyword:
|
||||
| VARIABLES {}
|
||||
| VALUE_SYM {}
|
||||
| WORK_SYM {}
|
||||
| X509_SYM {}
|
||||
| YEAR_SYM {}
|
||||
| SOUNDS_SYM {}
|
||||
;
|
||||
|
||||
/* Option functions */
|
||||
|
56
sql/time.cc
56
sql/time.cc
@ -28,7 +28,6 @@ uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037
|
||||
/* Currently only my_time_zone is inited */
|
||||
|
||||
static long my_time_zone=0;
|
||||
pthread_mutex_t LOCK_timezone;
|
||||
|
||||
void init_time(void)
|
||||
{
|
||||
@ -39,14 +38,14 @@ void init_time(void)
|
||||
seconds= (time_t) time((time_t*) 0);
|
||||
localtime_r(&seconds,&tm_tmp);
|
||||
l_time= &tm_tmp;
|
||||
my_time_zone=0;
|
||||
my_time_zone= 3600; /* Comp. for -3600 in my_gmt_sec */
|
||||
my_time.year= (uint) l_time->tm_year+1900;
|
||||
my_time.month= (uint) l_time->tm_mon+1;
|
||||
my_time.day= (uint) l_time->tm_mday;
|
||||
my_time.hour= (uint) l_time->tm_hour;
|
||||
my_time.minute= (uint) l_time->tm_min;
|
||||
my_time.second= (uint) l_time->tm_sec;
|
||||
VOID(my_gmt_sec(&my_time)); /* Init my_time_zone */
|
||||
my_time.second= (uint) l_time->tm_sec;
|
||||
my_gmt_sec(&my_time, &my_time_zone); /* Init my_time_zone */
|
||||
}
|
||||
|
||||
/*
|
||||
@ -57,26 +56,39 @@ void init_time(void)
|
||||
|
||||
*/
|
||||
|
||||
long my_gmt_sec(TIME *t)
|
||||
long my_gmt_sec(TIME *t, long *my_timezone)
|
||||
{
|
||||
uint loop;
|
||||
time_t tmp;
|
||||
struct tm *l_time,tm_tmp;
|
||||
long diff;
|
||||
long diff, current_timezone;
|
||||
|
||||
if (t->hour >= 24)
|
||||
{ /* Fix for time-loop */
|
||||
t->day+=t->hour/24;
|
||||
t->hour%=24;
|
||||
}
|
||||
pthread_mutex_lock(&LOCK_timezone);
|
||||
tmp=(time_t) ((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) -
|
||||
(long) days_at_timestart)*86400L + (long) t->hour*3600L +
|
||||
(long) (t->minute*60 + t->second)) + (time_t) my_time_zone;
|
||||
|
||||
/*
|
||||
Calculate the gmt time based on current time and timezone
|
||||
The -1 on the end is to ensure that if have a date that exists twice
|
||||
(like 2002-10-27 02:00:0 MET), we will find the initial date.
|
||||
|
||||
By doing -3600 we will have to call localtime_r() several times, but
|
||||
I couldn't come up with a better way to get a repeatable result :(
|
||||
|
||||
We can't use mktime() as it's buggy on many platforms and not thread safe.
|
||||
*/
|
||||
tmp=(time_t) (((calc_daynr((uint) t->year,(uint) t->month,(uint) t->day) -
|
||||
(long) days_at_timestart)*86400L + (long) t->hour*3600L +
|
||||
(long) (t->minute*60 + t->second)) + (time_t) my_time_zone -
|
||||
3600);
|
||||
current_timezone= my_time_zone;
|
||||
|
||||
localtime_r(&tmp,&tm_tmp);
|
||||
l_time=&tm_tmp;
|
||||
for (loop=0;
|
||||
loop < 3 &&
|
||||
loop < 2 &&
|
||||
(t->hour != (uint) l_time->tm_hour ||
|
||||
t->minute != (uint) l_time->tm_min);
|
||||
loop++)
|
||||
@ -89,14 +101,16 @@ long my_gmt_sec(TIME *t)
|
||||
days= -1;
|
||||
diff=(3600L*(long) (days*24+((int) t->hour - (int) l_time->tm_hour)) +
|
||||
(long) (60*((int) t->minute - (int) l_time->tm_min)));
|
||||
my_time_zone+=diff;
|
||||
tmp+=(time_t) diff;
|
||||
current_timezone+= diff+3600; // Compensate for -3600 above
|
||||
tmp+= (time_t) diff;
|
||||
localtime_r(&tmp,&tm_tmp);
|
||||
l_time=&tm_tmp;
|
||||
}
|
||||
/* Fix that if we are in the not existing daylight saving time hour
|
||||
we move the start of the next real hour */
|
||||
if (loop == 3 && t->hour != (uint) l_time->tm_hour)
|
||||
/*
|
||||
Fix that if we are in the not existing daylight saving time hour
|
||||
we move the start of the next real hour
|
||||
*/
|
||||
if (loop == 2 && t->hour != (uint) l_time->tm_hour)
|
||||
{
|
||||
int days= t->day - l_time->tm_mday;
|
||||
if (days < -1)
|
||||
@ -108,11 +122,9 @@ long my_gmt_sec(TIME *t)
|
||||
if (diff == 3600)
|
||||
tmp+=3600 - t->minute*60 - t->second; // Move to next hour
|
||||
else if (diff == -3600)
|
||||
tmp-=t->minute*60 + t->second; // Move to next hour
|
||||
tmp-=t->minute*60 + t->second; // Move to previous hour
|
||||
}
|
||||
if ((my_time_zone >=0 ? my_time_zone: -my_time_zone) > 3600L*12)
|
||||
my_time_zone=0; /* Wrong date */
|
||||
pthread_mutex_unlock(&LOCK_timezone);
|
||||
*my_timezone= current_timezone;
|
||||
return (long) tmp;
|
||||
} /* my_gmt_sec */
|
||||
|
||||
@ -428,6 +440,8 @@ str_to_TIME(const char *str, uint length, TIME *l_time,bool fuzzy_date)
|
||||
time_t str_to_timestamp(const char *str,uint length)
|
||||
{
|
||||
TIME l_time;
|
||||
long not_used;
|
||||
|
||||
if (str_to_TIME(str,length,&l_time,0) == TIMESTAMP_NONE)
|
||||
return(0);
|
||||
if (l_time.year >= TIMESTAMP_MAX_YEAR || l_time.year < 1900+YY_PART_YEAR)
|
||||
@ -435,7 +449,7 @@ time_t str_to_timestamp(const char *str,uint length)
|
||||
current_thd->cuted_fields++;
|
||||
return(0);
|
||||
}
|
||||
return(my_gmt_sec(&l_time));
|
||||
return(my_gmt_sec(&l_time, ¬_used));
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user