~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/srv/srv0srv.c

Merge Stewart - update to innodb 1.0.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
4
Copyright (c) 2008, 2009 Google Inc.
 
5
Copyright (c) 2009, Percona Inc.
5
6
 
6
7
Portions of this file contain modifications contributed and copyrighted by
7
8
Google, Inc. Those modifications are gratefully acknowledged and are described
9
10
incorporated with their permission, and subject to the conditions contained in
10
11
the file COPYING.Google.
11
12
 
 
13
Portions of this file contain modifications contributed and copyrighted
 
14
by Percona Inc.. Those modifications are
 
15
gratefully acknowledged and are described briefly in the InnoDB
 
16
documentation. The contributions by Percona Inc. are incorporated with
 
17
their permission, and subject to the conditions contained in the file
 
18
COPYING.Percona.
 
19
 
12
20
This program is free software; you can redistribute it and/or modify it under
13
21
the terms of the GNU General Public License as published by the Free Software
14
22
Foundation; version 2 of the License.
22
30
St, Fifth Floor, Boston, MA 02110-1301 USA
23
31
 
24
32
*****************************************************************************/
25
 
/***********************************************************************
26
 
 
27
 
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
28
 
Copyright (c) 2009, Percona Inc.
29
 
 
30
 
Portions of this file contain modifications contributed and copyrighted
31
 
by Percona Inc.. Those modifications are
32
 
gratefully acknowledged and are described briefly in the InnoDB
33
 
documentation. The contributions by Percona Inc. are incorporated with
34
 
their permission, and subject to the conditions contained in the file
35
 
COPYING.Percona.
36
 
 
37
 
This program is free software; you can redistribute it and/or modify it
38
 
under the terms of the GNU General Public License as published by the
39
 
Free Software Foundation; version 2 of the License.
40
 
 
41
 
This program is distributed in the hope that it will be useful, but
42
 
WITHOUT ANY WARRANTY; without even the implied warranty of
43
 
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
44
 
Public License for more details.
45
 
 
46
 
You should have received a copy of the GNU General Public License along
47
 
with this program; if not, write to the Free Software Foundation, Inc.,
48
 
51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
49
 
 
50
 
***********************************************************************/
51
33
 
52
34
/**************************************************//**
53
35
@file srv/srv0srv.c
119
101
in microseconds, in order to reduce the lagging of the purge thread. */
120
102
UNIV_INTERN ulint       srv_dml_needed_delay = 0;
121
103
 
122
 
UNIV_INTERN ibool       srv_lock_timeout_and_monitor_active = FALSE;
 
104
UNIV_INTERN ibool       srv_lock_timeout_active = FALSE;
 
105
UNIV_INTERN ibool       srv_monitor_active = FALSE;
123
106
UNIV_INTERN ibool       srv_error_monitor_active = FALSE;
124
107
 
125
108
UNIV_INTERN const char* srv_main_thread_op_info = "";
188
171
the checkpoints. */
189
172
UNIV_INTERN bool        srv_adaptive_flushing   = TRUE;
190
173
 
191
 
/* The sort order table of the MySQL latin1_swedish_ci character set
 
174
/** Maximum number of times allowed to conditionally acquire
 
175
mutex before switching to blocking wait on the mutex */
 
176
#define MAX_MUTEX_NOWAIT        20
 
177
 
 
178
/** Check whether the number of failed nonblocking mutex
 
179
acquisition attempts exceeds maximum allowed value. If so,
 
180
srv_printf_innodb_monitor() will request mutex acquisition
 
181
with mutex_enter(), which will wait until it gets the mutex. */
 
182
#define MUTEX_NOWAIT(mutex_skipped)     ((mutex_skipped) < MAX_MUTEX_NOWAIT)
 
183
 
 
184
/** The sort order table of the MySQL latin1_swedish_ci character set
192
185
collation */
193
186
#if defined(BUILD_DRIZZLE)
194
187
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
1659
1652
 
1660
1653
                trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1661
1654
        }
 
1655
 
 
1656
        if (trx_is_interrupted(trx)) {
 
1657
 
 
1658
                trx->error_state = DB_INTERRUPTED;
 
1659
        }
1662
1660
}
1663
1661
 
1664
1662
/********************************************************************//**
1721
1719
}
1722
1720
 
1723
1721
/******************************************************************//**
1724
 
Outputs to a file the output of the InnoDB Monitor. */
 
1722
Outputs to a file the output of the InnoDB Monitor.
 
1723
@return FALSE if not all information printed
 
1724
due to failure to obtain necessary mutex */
1725
1725
UNIV_INTERN
1726
 
void
 
1726
ibool
1727
1727
srv_printf_innodb_monitor(
1728
1728
/*======================*/
1729
1729
        FILE*   file,           /*!< in: output stream */
 
1730
        ibool   nowait,         /*!< in: whether to wait for kernel mutex */
1730
1731
        ulint*  trx_start,      /*!< out: file position of the start of
1731
1732
                                the list of active transactions */
1732
1733
        ulint*  trx_end)        /*!< out: file position of the end of
1735
1736
        double  time_elapsed;
1736
1737
        time_t  current_time;
1737
1738
        ulint   n_reserved;
 
1739
        ibool   ret;
1738
1740
 
1739
1741
        mutex_enter(&srv_innodb_monitor_mutex);
1740
1742
 
1758
1760
                "Per second averages calculated from the last %lu seconds\n",
1759
1761
                (ulong)time_elapsed);
1760
1762
 
1761
 
        fputs("----------\n"
1762
 
                "BACKGROUND THREAD\n"
1763
 
                "----------\n", file);
 
1763
        fputs("-----------------\n"
 
1764
              "BACKGROUND THREAD\n"
 
1765
              "-----------------\n", file);
1764
1766
        srv_print_master_thread_info(file);
1765
1767
 
1766
1768
        fputs("----------\n"
1784
1786
 
1785
1787
        mutex_exit(&dict_foreign_err_mutex);
1786
1788
 
1787
 
        lock_print_info_summary(file);
1788
 
        if (trx_start) {
1789
 
                long    t = ftell(file);
1790
 
                if (t < 0) {
1791
 
                        *trx_start = ULINT_UNDEFINED;
1792
 
                } else {
1793
 
                        *trx_start = (ulint) t;
1794
 
                }
1795
 
        }
1796
 
        lock_print_info_all_transactions(file);
1797
 
        if (trx_end) {
1798
 
                long    t = ftell(file);
1799
 
                if (t < 0) {
1800
 
                        *trx_end = ULINT_UNDEFINED;
1801
 
                } else {
1802
 
                        *trx_end = (ulint) t;
1803
 
                }
1804
 
        }
 
1789
        /* Only if lock_print_info_summary proceeds correctly,
 
1790
        before we call the lock_print_info_all_transactions
 
1791
        to print all the lock information. */
 
1792
        ret = lock_print_info_summary(file, nowait);
 
1793
 
 
1794
        if (ret) {
 
1795
                if (trx_start) {
 
1796
                        long    t = ftell(file);
 
1797
                        if (t < 0) {
 
1798
                                *trx_start = ULINT_UNDEFINED;
 
1799
                        } else {
 
1800
                                *trx_start = (ulint) t;
 
1801
                        }
 
1802
                }
 
1803
                lock_print_info_all_transactions(file);
 
1804
                if (trx_end) {
 
1805
                        long    t = ftell(file);
 
1806
                        if (t < 0) {
 
1807
                                *trx_end = ULINT_UNDEFINED;
 
1808
                        } else {
 
1809
                                *trx_end = (ulint) t;
 
1810
                        }
 
1811
                }
 
1812
        }
 
1813
 
1805
1814
        fputs("--------\n"
1806
1815
              "FILE I/O\n"
1807
1816
              "--------\n", file);
1899
1908
              "============================\n", file);
1900
1909
        mutex_exit(&srv_innodb_monitor_mutex);
1901
1910
        fflush(file);
 
1911
 
 
1912
        return(ret);
1902
1913
}
1903
1914
 
1904
1915
/******************************************************************//**
1986
1997
}
1987
1998
 
1988
1999
/*********************************************************************//**
1989
 
A thread which wakes up threads whose lock wait may have lasted too long.
1990
 
This also prints the info output by various InnoDB monitors.
 
2000
A thread which prints the info output by various InnoDB monitors.
1991
2001
@return a dummy parameter */
1992
2002
UNIV_INTERN
1993
2003
os_thread_ret_t
1994
 
srv_lock_timeout_and_monitor_thread(
1995
 
/*================================*/
 
2004
srv_monitor_thread(
 
2005
/*===============*/
1996
2006
        void*   arg __attribute__((unused)))
1997
2007
                        /*!< in: a dummy parameter required by
1998
2008
                        os_thread_create */
1999
2009
{
2000
 
        srv_slot_t*     slot;
2001
2010
        double          time_elapsed;
2002
2011
        time_t          current_time;
2003
2012
        time_t          last_table_monitor_time;
2004
2013
        time_t          last_tablespace_monitor_time;
2005
2014
        time_t          last_monitor_time;
2006
 
        ibool           some_waits;
2007
 
        double          wait_time;
2008
 
        ulint           i;
 
2015
        ulint           mutex_skipped;
 
2016
        ibool           last_srv_print_monitor;
2009
2017
 
2010
2018
#ifdef UNIV_DEBUG_THREAD_CREATION
2011
2019
        fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2016
2024
        last_table_monitor_time = time(NULL);
2017
2025
        last_tablespace_monitor_time = time(NULL);
2018
2026
        last_monitor_time = time(NULL);
 
2027
        mutex_skipped = 0;
 
2028
        last_srv_print_monitor = srv_print_innodb_monitor;
2019
2029
loop:
2020
 
        srv_lock_timeout_and_monitor_active = TRUE;
2021
 
 
2022
 
        /* When someone is waiting for a lock, we wake up every second
2023
 
        and check if a timeout has passed for a lock wait */
2024
 
 
2025
 
        os_thread_sleep(1000000);
 
2030
        srv_monitor_active = TRUE;
 
2031
 
 
2032
        /* Wake up every 5 seconds to see if we need to print
 
2033
        monitor information. */
 
2034
 
 
2035
        os_thread_sleep(5000000);
2026
2036
 
2027
2037
        current_time = time(NULL);
2028
2038
 
2032
2042
                last_monitor_time = time(NULL);
2033
2043
 
2034
2044
                if (srv_print_innodb_monitor) {
2035
 
                        srv_printf_innodb_monitor(stderr, NULL, NULL);
 
2045
                        /* Reset mutex_skipped counter everytime
 
2046
                        srv_print_innodb_monitor changes. This is to
 
2047
                        ensure we will not be blocked by kernel_mutex
 
2048
                        for short duration information printing,
 
2049
                        such as requested by sync_array_print_long_waits() */
 
2050
                        if (!last_srv_print_monitor) {
 
2051
                                mutex_skipped = 0;
 
2052
                                last_srv_print_monitor = TRUE;
 
2053
                        }
 
2054
 
 
2055
                        if (!srv_printf_innodb_monitor(stderr,
 
2056
                                                MUTEX_NOWAIT(mutex_skipped),
 
2057
                                                NULL, NULL)) {
 
2058
                                mutex_skipped++;
 
2059
                        } else {
 
2060
                                /* Reset the counter */
 
2061
                                mutex_skipped = 0;
 
2062
                        }
 
2063
                } else {
 
2064
                        last_srv_print_monitor = FALSE;
2036
2065
                }
2037
2066
 
 
2067
 
2038
2068
                if (srv_innodb_status) {
2039
2069
                        mutex_enter(&srv_monitor_file_mutex);
2040
2070
                        rewind(srv_monitor_file);
2041
 
                        srv_printf_innodb_monitor(srv_monitor_file, NULL,
2042
 
                                                  NULL);
 
2071
                        if (!srv_printf_innodb_monitor(srv_monitor_file,
 
2072
                                                MUTEX_NOWAIT(mutex_skipped),
 
2073
                                                NULL, NULL)) {
 
2074
                                mutex_skipped++;
 
2075
                        } else {
 
2076
                                mutex_skipped = 0;
 
2077
                        }
 
2078
 
2043
2079
                        os_file_set_eof(srv_monitor_file);
2044
2080
                        mutex_exit(&srv_monitor_file_mutex);
2045
2081
                }
2092
2128
                }
2093
2129
        }
2094
2130
 
 
2131
        if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
 
2132
                goto exit_func;
 
2133
        }
 
2134
 
 
2135
        if (srv_print_innodb_monitor
 
2136
            || srv_print_innodb_lock_monitor
 
2137
            || srv_print_innodb_tablespace_monitor
 
2138
            || srv_print_innodb_table_monitor) {
 
2139
                goto loop;
 
2140
        }
 
2141
 
 
2142
        srv_monitor_active = FALSE;
 
2143
 
 
2144
        goto loop;
 
2145
 
 
2146
exit_func:
 
2147
        srv_monitor_active = FALSE;
 
2148
 
 
2149
        /* We count the number of threads in os_thread_exit(). A created
 
2150
        thread should always use that to exit and not use return() to exit. */
 
2151
 
 
2152
        os_thread_exit(NULL);
 
2153
 
 
2154
        OS_THREAD_DUMMY_RETURN;
 
2155
}
 
2156
 
 
2157
/*********************************************************************//**
 
2158
A thread which wakes up threads whose lock wait may have lasted too long.
 
2159
@return a dummy parameter */
 
2160
UNIV_INTERN
 
2161
os_thread_ret_t
 
2162
srv_lock_timeout_thread(
 
2163
/*====================*/
 
2164
        void*   arg __attribute__((unused)))
 
2165
                        /* in: a dummy parameter required by
 
2166
                        os_thread_create */
 
2167
{
 
2168
        srv_slot_t*     slot;
 
2169
        ibool           some_waits;
 
2170
        double          wait_time;
 
2171
        ulint           i;
 
2172
 
 
2173
loop:
 
2174
        /* When someone is waiting for a lock, we wake up every second
 
2175
        and check if a timeout has passed for a lock wait */
 
2176
 
 
2177
        os_thread_sleep(1000000);
 
2178
 
 
2179
        srv_lock_timeout_active = TRUE;
 
2180
 
2095
2181
        mutex_enter(&kernel_mutex);
2096
2182
 
2097
2183
        some_waits = FALSE;
2115
2201
                        lock_wait_timeout = thd_lock_wait_timeout(
2116
2202
                                trx->mysql_thd);
2117
2203
 
2118
 
                        if (lock_wait_timeout < 100000000
2119
 
                            && (wait_time > (double) lock_wait_timeout
2120
 
                                || wait_time < 0)) {
 
2204
                        if (trx_is_interrupted(trx)
 
2205
                            || (lock_wait_timeout < 100000000
 
2206
                                && (wait_time > (double) lock_wait_timeout
 
2207
                                    || wait_time < 0))) {
2121
2208
 
2122
2209
                                /* Timeout exceeded or a wrap-around in system
2123
2210
                                time counter: cancel the lock request queued
2142
2229
                goto exit_func;
2143
2230
        }
2144
2231
 
2145
 
        if (some_waits || srv_print_innodb_monitor
2146
 
            || srv_print_innodb_lock_monitor
2147
 
            || srv_print_innodb_tablespace_monitor
2148
 
            || srv_print_innodb_table_monitor) {
 
2232
        if (some_waits) {
2149
2233
                goto loop;
2150
2234
        }
2151
2235
 
2152
 
        /* No one was waiting for a lock and no monitor was active:
2153
 
        suspend this thread */
2154
 
 
2155
 
        srv_lock_timeout_and_monitor_active = FALSE;
 
2236
        srv_lock_timeout_active = FALSE;
2156
2237
 
2157
2238
#if 0
2158
2239
        /* The following synchronisation is disabled, since
2162
2243
        goto loop;
2163
2244
 
2164
2245
exit_func:
2165
 
        srv_lock_timeout_and_monitor_active = FALSE;
 
2246
        srv_lock_timeout_active = FALSE;
2166
2247
 
2167
2248
        /* We count the number of threads in os_thread_exit(). A created
2168
2249
        thread should always use that to exit and not use return() to exit. */
2487
2568
                                                BUF_FLUSH_LIST,
2488
2569
                                                n_flush,
2489
2570
                                                IB_ULONGLONG_MAX);
2490
 
                                skip_sleep = TRUE;
 
2571
 
 
2572
                                if (n_flush == PCT_IO(100)) {
 
2573
                                        skip_sleep = TRUE;
 
2574
                                }
2491
2575
                        }
2492
2576
                }
2493
2577