~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-11-06 15:43:10 UTC
  • mfrom: (1908.1.1 merge)
  • Revision ID: brian@tangent.org-20101106154310-g1jpjzwbc53pfc4f
Filesort encapsulation, plus modification to copy contructor

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
4
Copyright (c) 2008, 2009 Google Inc.
5
 
Copyright (c) 2009, Percona Inc.
6
5
 
7
6
Portions of this file contain modifications contributed and copyrighted by
8
7
Google, Inc. Those modifications are gratefully acknowledged and are described
10
9
incorporated with their permission, and subject to the conditions contained in
11
10
the file COPYING.Google.
12
11
 
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
 
 
20
12
This program is free software; you can redistribute it and/or modify it under
21
13
the terms of the GNU General Public License as published by the Free Software
22
14
Foundation; version 2 of the License.
30
22
St, Fifth Floor, Boston, MA 02110-1301 USA
31
23
 
32
24
*****************************************************************************/
 
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
***********************************************************************/
33
51
 
34
52
/**************************************************//**
35
53
@file srv/srv0srv.c
68
86
#include "sync0sync.h"
69
87
#include "thr0loc.h"
70
88
#include "que0que.h"
 
89
#include "srv0que.h"
71
90
#include "log0recv.h"
72
91
#include "pars0pars.h"
73
92
#include "usr0sess.h"
100
119
in microseconds, in order to reduce the lagging of the purge thread. */
101
120
UNIV_INTERN ulint       srv_dml_needed_delay = 0;
102
121
 
103
 
UNIV_INTERN ibool       srv_lock_timeout_active = FALSE;
104
 
UNIV_INTERN ibool       srv_monitor_active = FALSE;
 
122
UNIV_INTERN ibool       srv_lock_timeout_and_monitor_active = FALSE;
105
123
UNIV_INTERN ibool       srv_error_monitor_active = FALSE;
106
124
 
107
125
UNIV_INTERN const char* srv_main_thread_op_info = "";
127
145
/** Whether to check file format during startup.  A value of
128
146
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE.  The default is to
129
147
set it to the highest format we support. */
130
 
UNIV_INTERN ulint       srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX;
 
148
UNIV_INTERN ulint       srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
131
149
 
132
150
#if DICT_TF_FORMAT_51
133
151
# error "DICT_TF_FORMAT_51 must be 0!"
136
154
on duplicate key checking and foreign key checking */
137
155
UNIV_INTERN ibool       srv_locks_unsafe_for_binlog = FALSE;
138
156
 
139
 
/* If this flag is TRUE, then we will use the native aio of the
140
 
OS (provided we compiled Innobase with it in), otherwise we will
141
 
use simulated aio we build below with threads.
142
 
Currently we support native aio on windows and linux */
143
 
UNIV_INTERN my_bool     srv_use_native_aio = TRUE;
144
 
 
145
 
#ifdef __WIN__
146
 
/* Windows native condition variables. We use runtime loading / function
147
 
pointers, because they are not available on Windows Server 2003 and
148
 
Windows XP/2000.
149
 
 
150
 
We use condition for events on Windows if possible, even if os_event
151
 
resembles Windows kernel event object well API-wise. The reason is
152
 
performance, kernel objects are heavyweights and WaitForSingleObject() is a
153
 
performance killer causing calling thread to context switch. Besides, Innodb
154
 
is preallocating large number (often millions) of os_events. With kernel event
155
 
objects it takes a big chunk out of non-paged pool, which is better suited
156
 
for tasks like IO than for storing idle event objects. */
157
 
UNIV_INTERN ibool       srv_use_native_conditions = FALSE;
158
 
#endif /* __WIN__ */
159
 
 
160
157
UNIV_INTERN ulint       srv_n_data_files = 0;
161
158
UNIV_INTERN char**      srv_data_file_names = NULL;
162
159
/* size in database pages */
191
188
the checkpoints. */
192
189
UNIV_INTERN bool        srv_adaptive_flushing   = TRUE;
193
190
 
194
 
/** Maximum number of times allowed to conditionally acquire
195
 
mutex before switching to blocking wait on the mutex */
196
 
#define MAX_MUTEX_NOWAIT        20
197
 
 
198
 
/** Check whether the number of failed nonblocking mutex
199
 
acquisition attempts exceeds maximum allowed value. If so,
200
 
srv_printf_innodb_monitor() will request mutex acquisition
201
 
with mutex_enter(), which will wait until it gets the mutex. */
202
 
#define MUTEX_NOWAIT(mutex_skipped)     ((mutex_skipped) < MAX_MUTEX_NOWAIT)
203
 
 
204
 
/** The sort order table of the MySQL latin1_swedish_ci character set
 
191
/* The sort order table of the MySQL latin1_swedish_ci character set
205
192
collation */
206
193
#if defined(BUILD_DRIZZLE)
207
194
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
250
237
UNIV_INTERN my_bool     srv_use_sys_malloc      = TRUE;
251
238
/* requested size in kilobytes */
252
239
UNIV_INTERN ulint       srv_buf_pool_size       = ULINT_MAX;
253
 
/* requested number of buffer pool instances */
254
 
UNIV_INTERN ulint       srv_buf_pool_instances  = 1;
255
240
/* previously requested size */
256
241
UNIV_INTERN ulint       srv_buf_pool_old_size;
257
242
/* current size in kilobytes */
303
288
 
304
289
UNIV_INTERN ulong       srv_max_buf_pool_modified_pct   = 75;
305
290
 
306
 
/* the number of purge threads to use from the worker pool (currently 0 or 1).*/
307
 
UNIV_INTERN ulong srv_n_purge_threads = 0;
308
 
 
309
 
/* the number of records to purge in one batch */
310
 
UNIV_INTERN ulong srv_purge_batch_size = 20;
311
 
 
312
291
/* variable counts amount of data read in total (in bytes) */
313
292
UNIV_INTERN ulint srv_data_read = 0;
314
293
 
463
442
UNIV_INTERN ib_int64_t  srv_n_lock_wait_time            = 0;
464
443
UNIV_INTERN ulint               srv_n_lock_max_wait_time        = 0;
465
444
 
466
 
UNIV_INTERN ulint               srv_truncated_status_writes     = 0;
467
445
 
468
446
/*
469
447
  Set the following to 0 if you want InnoDB to write messages on
487
465
 
488
466
/* Mutex for locking srv_monitor_file */
489
467
UNIV_INTERN mutex_t     srv_monitor_file_mutex;
490
 
 
491
 
#ifdef UNIV_PFS_MUTEX
492
 
/* Key to register kernel_mutex with performance schema */
493
 
UNIV_INTERN mysql_pfs_key_t     kernel_mutex_key;
494
 
/* Key to register srv_innodb_monitor_mutex with performance schema */
495
 
UNIV_INTERN mysql_pfs_key_t     srv_innodb_monitor_mutex_key;
496
 
/* Key to register srv_monitor_file_mutex with performance schema */
497
 
UNIV_INTERN mysql_pfs_key_t     srv_monitor_file_mutex_key;
498
 
/* Key to register srv_dict_tmpfile_mutex with performance schema */
499
 
UNIV_INTERN mysql_pfs_key_t     srv_dict_tmpfile_mutex_key;
500
 
/* Key to register the mutex with performance schema */
501
 
UNIV_INTERN mysql_pfs_key_t     srv_misc_tmpfile_mutex_key;
502
 
#endif /* UNIV_PFS_MUTEX */
503
 
 
504
468
/* Temporary file for innodb monitor output */
505
469
UNIV_INTERN FILE*       srv_monitor_file;
506
470
/* Mutex for locking srv_dict_tmpfile.
761
725
static ulint    srv_meter_foreground[SRV_MASTER + 1];
762
726
#endif
763
727
 
 
728
/* The following values give info about the activity going on in
 
729
the database. They are protected by the server mutex. The arrays
 
730
are indexed by the type of the thread. */
 
731
 
 
732
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
 
733
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
 
734
 
764
735
/***********************************************************************
765
736
Prints counters for work done by srv_master_thread. */
766
737
static
778
749
                      srv_log_writes_and_flush);
779
750
}
780
751
 
781
 
/* The following values give info about the activity going on in
782
 
the database. They are protected by the server mutex. The arrays
783
 
are indexed by the type of the thread. */
784
 
 
785
 
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
786
 
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
787
 
 
788
752
/*********************************************************************//**
789
753
Sets the info describing an i/o thread current state. */
790
754
UNIV_INTERN
1016
980
        srv_sys = mem_alloc(sizeof(srv_sys_t));
1017
981
 
1018
982
        kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
1019
 
        mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);
 
983
        mutex_create(&kernel_mutex, SYNC_KERNEL);
1020
984
 
1021
 
        mutex_create(srv_innodb_monitor_mutex_key,
1022
 
                     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
 
985
        mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
1023
986
 
1024
987
        srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1025
988
 
1620
1583
                row_mysql_unfreeze_data_dictionary(trx);
1621
1584
                break;
1622
1585
        case RW_X_LATCH:
1623
 
                /* There should never be a lock wait when the
1624
 
                dictionary latch is reserved in X mode.  Dictionary
1625
 
                transactions should only acquire locks on dictionary
1626
 
                tables, not other tables. All access to dictionary
1627
 
                tables should be covered by dictionary
1628
 
                transactions. */
1629
 
                ut_print_timestamp(stderr);
1630
 
                fputs("  InnoDB: Error: dict X latch held in "
1631
 
                      "srv_suspend_mysql_thread\n", stderr);
1632
 
                /* This should never occur. This incorrect handling
1633
 
                was added in the early development of
1634
 
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1635
1586
                /* Release fast index creation latch */
1636
1587
                row_mysql_unlock_data_dictionary(trx);
1637
1588
                break;
1651
1602
                row_mysql_freeze_data_dictionary(trx);
1652
1603
                break;
1653
1604
        case RW_X_LATCH:
1654
 
                /* This should never occur. This incorrect handling
1655
 
                was added in the early development of
1656
 
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1657
1605
                row_mysql_lock_data_dictionary(trx);
1658
1606
                break;
1659
1607
        }
1690
1638
                    start_time != -1 && finish_time != -1) {
1691
1639
                        srv_n_lock_max_wait_time = diff_time;
1692
1640
                }
1693
 
 
1694
 
                /* Record the lock wait time for this thread */
1695
 
                thd_set_lock_wait_time(trx->mysql_thd, diff_time);
1696
1641
        }
1697
1642
 
1698
1643
        if (trx->was_chosen_as_deadlock_victim) {
1714
1659
 
1715
1660
                trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1716
1661
        }
1717
 
 
1718
 
        if (trx_is_interrupted(trx)) {
1719
 
 
1720
 
                trx->error_state = DB_INTERRUPTED;
1721
 
        }
1722
1662
}
1723
1663
 
1724
1664
/********************************************************************//**
1770
1710
 
1771
1711
        log_refresh_stats();
1772
1712
 
1773
 
        buf_refresh_io_stats_all();
 
1713
        buf_refresh_io_stats();
1774
1714
 
1775
1715
        srv_n_rows_inserted_old = srv_n_rows_inserted;
1776
1716
        srv_n_rows_updated_old = srv_n_rows_updated;
1781
1721
}
1782
1722
 
1783
1723
/******************************************************************//**
1784
 
Outputs to a file the output of the InnoDB Monitor.
1785
 
@return FALSE if not all information printed
1786
 
due to failure to obtain necessary mutex */
 
1724
Outputs to a file the output of the InnoDB Monitor. */
1787
1725
UNIV_INTERN
1788
 
ibool
 
1726
void
1789
1727
srv_printf_innodb_monitor(
1790
1728
/*======================*/
1791
1729
        FILE*   file,           /*!< in: output stream */
1792
 
        ibool   nowait,         /*!< in: whether to wait for kernel mutex */
1793
1730
        ulint*  trx_start,      /*!< out: file position of the start of
1794
1731
                                the list of active transactions */
1795
1732
        ulint*  trx_end)        /*!< out: file position of the end of
1798
1735
        double  time_elapsed;
1799
1736
        time_t  current_time;
1800
1737
        ulint   n_reserved;
1801
 
        ibool   ret;
1802
1738
 
1803
1739
        mutex_enter(&srv_innodb_monitor_mutex);
1804
1740
 
1822
1758
                "Per second averages calculated from the last %lu seconds\n",
1823
1759
                (ulong)time_elapsed);
1824
1760
 
1825
 
        fputs("-----------------\n"
1826
 
              "BACKGROUND THREAD\n"
1827
 
              "-----------------\n", file);
 
1761
        fputs("----------\n"
 
1762
                "BACKGROUND THREAD\n"
 
1763
                "----------\n", file);
1828
1764
        srv_print_master_thread_info(file);
1829
1765
 
1830
1766
        fputs("----------\n"
1848
1784
 
1849
1785
        mutex_exit(&dict_foreign_err_mutex);
1850
1786
 
1851
 
        /* Only if lock_print_info_summary proceeds correctly,
1852
 
        before we call the lock_print_info_all_transactions
1853
 
        to print all the lock information. */
1854
 
        ret = lock_print_info_summary(file, nowait);
1855
 
 
1856
 
        if (ret) {
1857
 
                if (trx_start) {
1858
 
                        long    t = ftell(file);
1859
 
                        if (t < 0) {
1860
 
                                *trx_start = ULINT_UNDEFINED;
1861
 
                        } else {
1862
 
                                *trx_start = (ulint) t;
1863
 
                        }
1864
 
                }
1865
 
                lock_print_info_all_transactions(file);
1866
 
                if (trx_end) {
1867
 
                        long    t = ftell(file);
1868
 
                        if (t < 0) {
1869
 
                                *trx_end = ULINT_UNDEFINED;
1870
 
                        } else {
1871
 
                                *trx_end = (ulint) t;
1872
 
                        }
1873
 
                }
1874
 
        }
1875
 
 
 
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
        }
1876
1805
        fputs("--------\n"
1877
1806
              "FILE I/O\n"
1878
1807
              "--------\n", file);
1970
1899
              "============================\n", file);
1971
1900
        mutex_exit(&srv_innodb_monitor_mutex);
1972
1901
        fflush(file);
1973
 
 
1974
 
        return(ret);
1975
1902
}
1976
1903
 
1977
1904
/******************************************************************//**
1981
1908
srv_export_innodb_status(void)
1982
1909
/*==========================*/
1983
1910
{
1984
 
        buf_pool_stat_t stat;
1985
 
        ulint           LRU_len;
1986
 
        ulint           free_len;
1987
 
        ulint           flush_list_len;
1988
 
 
1989
 
        buf_get_total_stat(&stat);
1990
 
        buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
1991
 
 
1992
1911
        mutex_enter(&srv_innodb_monitor_mutex);
1993
1912
 
1994
1913
        export_vars.innodb_data_pending_reads
2003
1922
        export_vars.innodb_data_reads = os_n_file_reads;
2004
1923
        export_vars.innodb_data_writes = os_n_file_writes;
2005
1924
        export_vars.innodb_data_written = srv_data_written;
2006
 
        export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
 
1925
        export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
2007
1926
        export_vars.innodb_buffer_pool_write_requests
2008
1927
                = srv_buf_pool_write_requests;
2009
1928
        export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
2010
1929
        export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
2011
1930
        export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
2012
1931
        export_vars.innodb_buffer_pool_read_ahead
2013
 
                = stat.n_ra_pages_read;
 
1932
                = buf_pool->stat.n_ra_pages_read;
2014
1933
        export_vars.innodb_buffer_pool_read_ahead_evicted
2015
 
                = stat.n_ra_pages_evicted;
2016
 
        export_vars.innodb_buffer_pool_pages_data = LRU_len;
2017
 
        export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
2018
 
        export_vars.innodb_buffer_pool_pages_free = free_len;
 
1934
                = buf_pool->stat.n_ra_pages_evicted;
 
1935
        export_vars.innodb_buffer_pool_pages_data
 
1936
                = UT_LIST_GET_LEN(buf_pool->LRU);
 
1937
        export_vars.innodb_buffer_pool_pages_dirty
 
1938
                = UT_LIST_GET_LEN(buf_pool->flush_list);
 
1939
        export_vars.innodb_buffer_pool_pages_free
 
1940
                = UT_LIST_GET_LEN(buf_pool->free);
2019
1941
#ifdef UNIV_DEBUG
2020
1942
        export_vars.innodb_buffer_pool_pages_latched
2021
1943
                = buf_get_latched_pages_number();
2022
1944
#endif /* UNIV_DEBUG */
2023
 
        export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
 
1945
        export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
2024
1946
 
2025
 
        export_vars.innodb_buffer_pool_pages_misc
2026
 
                = buf_pool_get_n_pages() - LRU_len - free_len;
 
1947
        export_vars.innodb_buffer_pool_pages_misc = buf_pool->curr_size
 
1948
                - UT_LIST_GET_LEN(buf_pool->LRU)
 
1949
                - UT_LIST_GET_LEN(buf_pool->free);
2027
1950
#ifdef HAVE_ATOMIC_BUILTINS
2028
1951
        export_vars.innodb_have_atomic_builtins = 1;
2029
1952
#else
2039
1962
        export_vars.innodb_log_writes = srv_log_writes;
2040
1963
        export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
2041
1964
        export_vars.innodb_dblwr_writes = srv_dblwr_writes;
2042
 
        export_vars.innodb_pages_created = stat.n_pages_created;
2043
 
        export_vars.innodb_pages_read = stat.n_pages_read;
2044
 
        export_vars.innodb_pages_written = stat.n_pages_written;
 
1965
        export_vars.innodb_pages_created = buf_pool->stat.n_pages_created;
 
1966
        export_vars.innodb_pages_read = buf_pool->stat.n_pages_read;
 
1967
        export_vars.innodb_pages_written = buf_pool->stat.n_pages_written;
2045
1968
        export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
2046
1969
        export_vars.innodb_row_lock_current_waits
2047
1970
                = srv_n_lock_wait_current_count;
2058
1981
        export_vars.innodb_rows_inserted = srv_n_rows_inserted;
2059
1982
        export_vars.innodb_rows_updated = srv_n_rows_updated;
2060
1983
        export_vars.innodb_rows_deleted = srv_n_rows_deleted;
2061
 
        export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
2062
1984
 
2063
1985
        mutex_exit(&srv_innodb_monitor_mutex);
2064
1986
}
2065
1987
 
2066
1988
/*********************************************************************//**
2067
 
A thread which prints the info output by various InnoDB monitors.
 
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.
2068
1991
@return a dummy parameter */
2069
1992
UNIV_INTERN
2070
1993
os_thread_ret_t
2071
 
srv_monitor_thread(
2072
 
/*===============*/
 
1994
srv_lock_timeout_and_monitor_thread(
 
1995
/*================================*/
2073
1996
        void*   arg __attribute__((unused)))
2074
1997
                        /*!< in: a dummy parameter required by
2075
1998
                        os_thread_create */
2076
1999
{
 
2000
        srv_slot_t*     slot;
2077
2001
        double          time_elapsed;
2078
2002
        time_t          current_time;
2079
2003
        time_t          last_table_monitor_time;
2080
2004
        time_t          last_tablespace_monitor_time;
2081
2005
        time_t          last_monitor_time;
2082
 
        ulint           mutex_skipped;
2083
 
        ibool           last_srv_print_monitor;
 
2006
        ibool           some_waits;
 
2007
        double          wait_time;
 
2008
        ulint           i;
2084
2009
 
2085
2010
#ifdef UNIV_DEBUG_THREAD_CREATION
2086
2011
        fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2087
2012
                os_thread_pf(os_thread_get_curr_id()));
2088
2013
#endif
2089
 
 
2090
 
#ifdef UNIV_PFS_THREAD
2091
 
        pfs_register_thread(srv_monitor_thread_key);
2092
 
#endif
2093
 
 
2094
2014
        UT_NOT_USED(arg);
2095
2015
        srv_last_monitor_time = time(NULL);
2096
2016
        last_table_monitor_time = time(NULL);
2097
2017
        last_tablespace_monitor_time = time(NULL);
2098
2018
        last_monitor_time = time(NULL);
2099
 
        mutex_skipped = 0;
2100
 
        last_srv_print_monitor = srv_print_innodb_monitor;
2101
2019
loop:
2102
 
        srv_monitor_active = TRUE;
2103
 
 
2104
 
        /* Wake up every 5 seconds to see if we need to print
2105
 
        monitor information. */
2106
 
 
2107
 
        os_thread_sleep(5000000);
 
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);
2108
2026
 
2109
2027
        current_time = time(NULL);
2110
2028
 
2114
2032
                last_monitor_time = time(NULL);
2115
2033
 
2116
2034
                if (srv_print_innodb_monitor) {
2117
 
                        /* Reset mutex_skipped counter everytime
2118
 
                        srv_print_innodb_monitor changes. This is to
2119
 
                        ensure we will not be blocked by kernel_mutex
2120
 
                        for short duration information printing,
2121
 
                        such as requested by sync_array_print_long_waits() */
2122
 
                        if (!last_srv_print_monitor) {
2123
 
                                mutex_skipped = 0;
2124
 
                                last_srv_print_monitor = TRUE;
2125
 
                        }
2126
 
 
2127
 
                        if (!srv_printf_innodb_monitor(stderr,
2128
 
                                                MUTEX_NOWAIT(mutex_skipped),
2129
 
                                                NULL, NULL)) {
2130
 
                                mutex_skipped++;
2131
 
                        } else {
2132
 
                                /* Reset the counter */
2133
 
                                mutex_skipped = 0;
2134
 
                        }
2135
 
                } else {
2136
 
                        last_srv_print_monitor = FALSE;
 
2035
                        srv_printf_innodb_monitor(stderr, NULL, NULL);
2137
2036
                }
2138
2037
 
2139
 
 
2140
2038
                if (srv_innodb_status) {
2141
2039
                        mutex_enter(&srv_monitor_file_mutex);
2142
2040
                        rewind(srv_monitor_file);
2143
 
                        if (!srv_printf_innodb_monitor(srv_monitor_file,
2144
 
                                                MUTEX_NOWAIT(mutex_skipped),
2145
 
                                                NULL, NULL)) {
2146
 
                                mutex_skipped++;
2147
 
                        } else {
2148
 
                                mutex_skipped = 0;
2149
 
                        }
2150
 
 
 
2041
                        srv_printf_innodb_monitor(srv_monitor_file, NULL,
 
2042
                                                  NULL);
2151
2043
                        os_file_set_eof(srv_monitor_file);
2152
2044
                        mutex_exit(&srv_monitor_file_mutex);
2153
2045
                }
2200
2092
                }
2201
2093
        }
2202
2094
 
2203
 
        if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2204
 
                goto exit_func;
2205
 
        }
2206
 
 
2207
 
        if (srv_print_innodb_monitor
2208
 
            || srv_print_innodb_lock_monitor
2209
 
            || srv_print_innodb_tablespace_monitor
2210
 
            || srv_print_innodb_table_monitor) {
2211
 
                goto loop;
2212
 
        }
2213
 
 
2214
 
        srv_monitor_active = FALSE;
2215
 
 
2216
 
        goto loop;
2217
 
 
2218
 
exit_func:
2219
 
        srv_monitor_active = FALSE;
2220
 
 
2221
 
        /* We count the number of threads in os_thread_exit(). A created
2222
 
        thread should always use that to exit and not use return() to exit. */
2223
 
 
2224
 
        os_thread_exit(NULL);
2225
 
 
2226
 
        OS_THREAD_DUMMY_RETURN;
2227
 
}
2228
 
 
2229
 
/*********************************************************************//**
2230
 
A thread which wakes up threads whose lock wait may have lasted too long.
2231
 
@return a dummy parameter */
2232
 
UNIV_INTERN
2233
 
os_thread_ret_t
2234
 
srv_lock_timeout_thread(
2235
 
/*====================*/
2236
 
        void*   arg __attribute__((unused)))
2237
 
                        /* in: a dummy parameter required by
2238
 
                        os_thread_create */
2239
 
{
2240
 
        srv_slot_t*     slot;
2241
 
        ibool           some_waits;
2242
 
        double          wait_time;
2243
 
        ulint           i;
2244
 
 
2245
 
#ifdef UNIV_PFS_THREAD
2246
 
        pfs_register_thread(srv_lock_timeout_thread_key);
2247
 
#endif
2248
 
 
2249
 
loop:
2250
 
        /* When someone is waiting for a lock, we wake up every second
2251
 
        and check if a timeout has passed for a lock wait */
2252
 
 
2253
 
        os_thread_sleep(1000000);
2254
 
 
2255
 
        srv_lock_timeout_active = TRUE;
2256
 
 
2257
2095
        mutex_enter(&kernel_mutex);
2258
2096
 
2259
2097
        some_waits = FALSE;
2277
2115
                        lock_wait_timeout = thd_lock_wait_timeout(
2278
2116
                                trx->mysql_thd);
2279
2117
 
2280
 
                        if (trx_is_interrupted(trx)
2281
 
                            || (lock_wait_timeout < 100000000
2282
 
                                && (wait_time > (double) lock_wait_timeout
2283
 
                                    || wait_time < 0))) {
 
2118
                        if (lock_wait_timeout < 100000000
 
2119
                            && (wait_time > (double) lock_wait_timeout
 
2120
                                || wait_time < 0)) {
2284
2121
 
2285
2122
                                /* Timeout exceeded or a wrap-around in system
2286
2123
                                time counter: cancel the lock request queued
2305
2142
                goto exit_func;
2306
2143
        }
2307
2144
 
2308
 
        if (some_waits) {
 
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) {
2309
2149
                goto loop;
2310
2150
        }
2311
2151
 
2312
 
        srv_lock_timeout_active = FALSE;
 
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;
2313
2156
 
2314
2157
#if 0
2315
2158
        /* The following synchronisation is disabled, since
2319
2162
        goto loop;
2320
2163
 
2321
2164
exit_func:
2322
 
        srv_lock_timeout_active = FALSE;
 
2165
        srv_lock_timeout_and_monitor_active = FALSE;
2323
2166
 
2324
2167
        /* We count the number of threads in os_thread_exit(). A created
2325
2168
        thread should always use that to exit and not use return() to exit. */
2352
2195
        fprintf(stderr, "Error monitor thread starts, id %lu\n",
2353
2196
                os_thread_pf(os_thread_get_curr_id()));
2354
2197
#endif
2355
 
 
2356
 
#ifdef UNIV_PFS_THREAD
2357
 
        pfs_register_thread(srv_error_monitor_thread_key);
2358
 
#endif
2359
 
 
2360
2198
loop:
2361
2199
        srv_error_monitor_active = TRUE;
2362
2200
 
2437
2275
        OS_THREAD_DUMMY_RETURN;
2438
2276
}
2439
2277
 
2440
 
/**********************************************************************//**
2441
 
Check whether any background thread is active.
2442
 
@return FALSE if all are are suspended or have exited. */
2443
 
UNIV_INTERN
2444
 
ibool
2445
 
srv_is_any_background_thread_active(void)
2446
 
/*=====================================*/
2447
 
{
2448
 
        ulint   i;
2449
 
        ibool   ret = FALSE;
2450
 
 
2451
 
        mutex_enter(&kernel_mutex);
2452
 
 
2453
 
        for (i = SRV_COM; i <= SRV_MASTER; ++i) {
2454
 
                if (srv_n_threads_active[i] != 0) {
2455
 
                        ret = TRUE;
2456
 
                        break;
2457
 
                }
2458
 
        }
2459
 
 
2460
 
        mutex_exit(&kernel_mutex);
2461
 
 
2462
 
        return(ret);
2463
 
}
2464
 
 
2465
2278
/*******************************************************************//**
2466
2279
Tells the InnoDB server that there has been activity in the database
2467
2280
and wakes up the master thread if it is suspended (not sleeping). Used
2468
2281
in the MySQL interface. Note that there is a small chance that the master
2469
 
thread stays suspended (we do not protect our operation with the
2470
 
srv_sys_t->mutex, for performance reasons). */
 
2282
thread stays suspended (we do not protect our operation with the kernel
 
2283
mutex, for performace reasons). */
2471
2284
UNIV_INTERN
2472
2285
void
2473
2286
srv_active_wake_master_thread(void)
2486
2299
}
2487
2300
 
2488
2301
/*******************************************************************//**
2489
 
Tells the purge thread that there has been activity in the database
2490
 
and wakes up the purge thread if it is suspended (not sleeping).  Note
2491
 
that there is a small chance that the purge thread stays suspended
2492
 
(we do not protect our operation with the kernel mutex, for
2493
 
performace reasons). */
2494
 
UNIV_INTERN
2495
 
void
2496
 
srv_wake_purge_thread_if_not_active(void)
2497
 
/*=====================================*/
2498
 
{
2499
 
        ut_ad(!mutex_own(&kernel_mutex));
2500
 
 
2501
 
        if (srv_n_purge_threads > 0
2502
 
            && srv_n_threads_active[SRV_WORKER] == 0) {
2503
 
 
2504
 
                mutex_enter(&kernel_mutex);
2505
 
 
2506
 
                srv_release_threads(SRV_WORKER, 1);
2507
 
 
2508
 
                mutex_exit(&kernel_mutex);
2509
 
        }
2510
 
}
2511
 
 
2512
 
/*******************************************************************//**
2513
2302
Wakes up the master thread if it is suspended or being suspended. */
2514
2303
UNIV_INTERN
2515
2304
void
2525
2314
        mutex_exit(&kernel_mutex);
2526
2315
}
2527
2316
 
2528
 
/*******************************************************************//**
2529
 
Wakes up the purge thread if it's not already awake. */
2530
 
UNIV_INTERN
2531
 
void
2532
 
srv_wake_purge_thread(void)
2533
 
/*=======================*/
2534
 
{
2535
 
        ut_ad(!mutex_own(&kernel_mutex));
2536
 
 
2537
 
        if (srv_n_purge_threads > 0) {
2538
 
 
2539
 
                mutex_enter(&kernel_mutex);
2540
 
 
2541
 
                srv_release_threads(SRV_WORKER, 1);
2542
 
 
2543
 
                mutex_exit(&kernel_mutex);
2544
 
        }
2545
 
}
2546
 
 
2547
2317
/**********************************************************************
2548
2318
The master thread is tasked to ensure that flush of log file happens
2549
2319
once every second in the background. This is to ensure that not more
2564
2334
        }
2565
2335
}
2566
2336
 
2567
 
/********************************************************************//**
2568
 
Do a full purge, reconfigure the purge sub-system if a dynamic
2569
 
change is detected. */
2570
 
static
2571
 
void
2572
 
srv_master_do_purge(void)
2573
 
/*=====================*/
2574
 
{
2575
 
        ulint   n_pages_purged;
2576
 
 
2577
 
        ut_ad(!mutex_own(&kernel_mutex));
2578
 
 
2579
 
        ut_a(srv_n_purge_threads == 0);
2580
 
 
2581
 
        do {
2582
 
                /* Check for shutdown and change in purge config. */
2583
 
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2584
 
                        /* Nothing to purge. */
2585
 
                        n_pages_purged = 0;
2586
 
                } else {
2587
 
                        n_pages_purged = trx_purge(srv_purge_batch_size);
2588
 
                }
2589
 
 
2590
 
                srv_sync_log_buffer_in_background();
2591
 
 
2592
 
        } while (n_pages_purged > 0);
2593
 
}
2594
 
 
2595
2337
/*********************************************************************//**
2596
2338
The master thread controlling the server.
2597
2339
@return a dummy parameter */
2603
2345
                        /*!< in: a dummy parameter required by
2604
2346
                        os_thread_create */
2605
2347
{
2606
 
        buf_pool_stat_t buf_stat;
2607
2348
        os_event_t      event;
2608
2349
        ulint           old_activity_count;
2609
2350
        ulint           n_pages_purged  = 0;
2615
2356
        ulint           n_ios_old;
2616
2357
        ulint           n_ios_very_old;
2617
2358
        ulint           n_pend_ios;
2618
 
        ulint           next_itr_time;
 
2359
        ibool           skip_sleep      = FALSE;
2619
2360
        ulint           i;
2620
2361
 
2621
2362
#ifdef UNIV_DEBUG_THREAD_CREATION
2622
2363
        fprintf(stderr, "Master thread starts, id %lu\n",
2623
2364
                os_thread_pf(os_thread_get_curr_id()));
2624
2365
#endif
2625
 
 
2626
 
#ifdef UNIV_PFS_THREAD
2627
 
        pfs_register_thread(srv_master_thread_key);
2628
 
#endif
2629
 
 
2630
2366
        srv_main_thread_process_no = os_proc_get_number();
2631
2367
        srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2632
2368
 
2645
2381
 
2646
2382
        srv_main_thread_op_info = "reserving kernel mutex";
2647
2383
 
2648
 
        buf_get_total_stat(&buf_stat);
2649
 
        n_ios_very_old = log_sys->n_log_ios + buf_stat.n_pages_read
2650
 
                + buf_stat.n_pages_written;
 
2384
        n_ios_very_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
 
2385
                + buf_pool->stat.n_pages_written;
2651
2386
        mutex_enter(&kernel_mutex);
2652
2387
 
2653
2388
        /* Store the user activity counter at the start of this loop */
2664
2399
        when there is database activity */
2665
2400
 
2666
2401
        srv_last_log_flush_time = time(NULL);
2667
 
 
2668
 
        /* Sleep for 1 second on entrying the for loop below the first time. */
2669
 
        next_itr_time = ut_time_ms() + 1000;
 
2402
        skip_sleep = FALSE;
2670
2403
 
2671
2404
        for (i = 0; i < 10; i++) {
2672
 
                ulint   cur_time = ut_time_ms();
2673
 
 
2674
 
                buf_get_total_stat(&buf_stat);
2675
 
 
2676
 
                n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2677
 
                        + buf_stat.n_pages_written;
2678
 
 
 
2405
                n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
 
2406
                        + buf_pool->stat.n_pages_written;
2679
2407
                srv_main_thread_op_info = "sleeping";
2680
2408
                srv_main_1_second_loops++;
2681
2409
 
2682
 
                if (next_itr_time > cur_time) {
 
2410
                if (!skip_sleep) {
2683
2411
 
2684
 
                        /* Get sleep interval in micro seconds. We use
2685
 
                        ut_min() to avoid long sleep in case of
2686
 
                        wrap around. */
2687
 
                        os_thread_sleep(ut_min(1000000,
2688
 
                                        (next_itr_time - cur_time)
2689
 
                                         * 1000));
 
2412
                        os_thread_sleep(1000000);
2690
2413
                        srv_main_sleeps++;
2691
2414
                }
2692
2415
 
2693
 
                /* Each iteration should happen at 1 second interval. */
2694
 
                next_itr_time = ut_time_ms() + 1000;
 
2416
                skip_sleep = FALSE;
2695
2417
 
2696
2418
                /* ALTER TABLE in MySQL requires on Unix that the table handler
2697
2419
                can drop tables lazily after there no longer are SELECT
2715
2437
                log_free_check();
2716
2438
 
2717
2439
                /* If i/os during one second sleep were less than 5% of
2718
 
                capacity, we assume that there is free disk i/o capacity
2719
 
                available, and it makes sense to do an insert buffer merge. */
 
2440
                capacity, we assume that there is free disk i/o capacity
 
2441
                available, and it makes sense to do an insert buffer merge. */
2720
2442
 
2721
 
                buf_get_total_stat(&buf_stat);
2722
2443
                n_pend_ios = buf_get_n_pending_ios()
2723
2444
                        + log_sys->n_pending_writes;
2724
 
                n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2725
 
                        + buf_stat.n_pages_written;
 
2445
                n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
 
2446
                        + buf_pool->stat.n_pages_written;
2726
2447
                if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2727
2448
                    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
2728
2449
                        srv_main_thread_op_info = "doing insert buffer merge";
2740
2461
 
2741
2462
                        srv_main_thread_op_info =
2742
2463
                                "flushing buffer pool pages";
2743
 
                        n_pages_flushed = buf_flush_list(
2744
 
                                PCT_IO(100), IB_ULONGLONG_MAX);
2745
 
 
 
2464
                        n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2465
                                                          PCT_IO(100),
 
2466
                                                          IB_ULONGLONG_MAX);
 
2467
 
 
2468
                        /* If we had to do the flush, it may have taken
 
2469
                        even more than 1 second, and also, there may be more
 
2470
                        to flush. Do not sleep 1 second during the next
 
2471
                        iteration of this loop. */
 
2472
 
 
2473
                        skip_sleep = TRUE;
2746
2474
                } else if (srv_adaptive_flushing) {
2747
2475
 
2748
2476
                        /* Try to keep the rate of flushing of dirty
2755
2483
                                        "flushing buffer pool pages";
2756
2484
                                n_flush = ut_min(PCT_IO(100), n_flush);
2757
2485
                                n_pages_flushed =
2758
 
                                        buf_flush_list(
 
2486
                                        buf_flush_batch(
 
2487
                                                BUF_FLUSH_LIST,
2759
2488
                                                n_flush,
2760
2489
                                                IB_ULONGLONG_MAX);
 
2490
                                skip_sleep = TRUE;
2761
2491
                        }
2762
2492
                }
2763
2493
 
2787
2517
        loop above requests writes for that case. The writes done here
2788
2518
        are not required, and may be disabled. */
2789
2519
 
2790
 
        buf_get_total_stat(&buf_stat);
2791
2520
        n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
2792
 
        n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2793
 
                + buf_stat.n_pages_written;
 
2521
        n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
 
2522
                + buf_pool->stat.n_pages_written;
2794
2523
 
2795
2524
        srv_main_10_second_loops++;
2796
2525
        if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2797
2526
            && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
2798
2527
 
2799
2528
                srv_main_thread_op_info = "flushing buffer pool pages";
2800
 
                buf_flush_list(PCT_IO(100), IB_ULONGLONG_MAX);
 
2529
                buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
 
2530
                                IB_ULONGLONG_MAX);
2801
2531
 
2802
2532
                /* Flush logs if needed */
2803
2533
                srv_sync_log_buffer_in_background();
2812
2542
        /* Flush logs if needed */
2813
2543
        srv_sync_log_buffer_in_background();
2814
2544
 
2815
 
        if (srv_n_purge_threads == 0) {
2816
 
                srv_main_thread_op_info = "master purging";
2817
 
 
2818
 
                srv_master_do_purge();
 
2545
        /* We run a full purge every 10 seconds, even if the server
 
2546
        were active */
 
2547
        do {
2819
2548
 
2820
2549
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2821
2550
 
2822
2551
                        goto background_loop;
2823
2552
                }
2824
 
        }
 
2553
 
 
2554
                srv_main_thread_op_info = "purging";
 
2555
                n_pages_purged = trx_purge();
 
2556
 
 
2557
                /* Flush logs if needed */
 
2558
                srv_sync_log_buffer_in_background();
 
2559
 
 
2560
        } while (n_pages_purged);
2825
2561
 
2826
2562
        srv_main_thread_op_info = "flushing buffer pool pages";
2827
2563
 
2833
2569
                (> 70 %), we assume we can afford reserving the disk(s) for
2834
2570
                the time it requires to flush 100 pages */
2835
2571
 
2836
 
                n_pages_flushed = buf_flush_list(
2837
 
                        PCT_IO(100), IB_ULONGLONG_MAX);
 
2572
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2573
                                                  PCT_IO(100),
 
2574
                                                  IB_ULONGLONG_MAX);
2838
2575
        } else {
2839
2576
                /* Otherwise, we only flush a small number of pages so that
2840
2577
                we do not unnecessarily use much disk i/o capacity from
2841
2578
                other work */
2842
2579
 
2843
 
                n_pages_flushed = buf_flush_list(
2844
 
                          PCT_IO(10), IB_ULONGLONG_MAX);
 
2580
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2581
                                                  PCT_IO(10),
 
2582
                                                  IB_ULONGLONG_MAX);
2845
2583
        }
2846
2584
 
2847
2585
        srv_main_thread_op_info = "making checkpoint";
2888
2626
                os_thread_sleep(100000);
2889
2627
        }
2890
2628
 
2891
 
        if (srv_n_purge_threads == 0) {
2892
 
                srv_main_thread_op_info = "master purging";
2893
 
 
2894
 
                srv_master_do_purge();
2895
 
        }
 
2629
        srv_main_thread_op_info = "purging";
 
2630
 
 
2631
        /* Run a full purge */
 
2632
        do {
 
2633
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
 
2634
 
 
2635
                        break;
 
2636
                }
 
2637
 
 
2638
                srv_main_thread_op_info = "purging";
 
2639
                n_pages_purged = trx_purge();
 
2640
 
 
2641
                /* Flush logs if needed */
 
2642
                srv_sync_log_buffer_in_background();
 
2643
 
 
2644
        } while (n_pages_purged);
2896
2645
 
2897
2646
        srv_main_thread_op_info = "reserving kernel mutex";
2898
2647
 
2910
2659
        } else {
2911
2660
                /* This should do an amount of IO similar to the number of
2912
2661
                dirty pages that will be flushed in the call to
2913
 
                buf_flush_list below. Otherwise, the system favors
 
2662
                buf_flush_batch below. Otherwise, the system favors
2914
2663
                clean pages over cleanup throughput. */
2915
2664
                n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2916
2665
                                                           PCT_IO(100));
2929
2678
        srv_main_thread_op_info = "flushing buffer pool pages";
2930
2679
        srv_main_flush_loops++;
2931
2680
        if (srv_fast_shutdown < 2) {
2932
 
                n_pages_flushed = buf_flush_list(
2933
 
                          PCT_IO(100), IB_ULONGLONG_MAX);
 
2681
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
 
2682
                                                  PCT_IO(100),
 
2683
                                                  IB_ULONGLONG_MAX);
2934
2684
        } else {
2935
2685
                /* In the fastest shutdown we do not flush the buffer pool
2936
2686
                to data files: we set n_pages_flushed to 0 artificially. */
2948
2698
        mutex_exit(&kernel_mutex);
2949
2699
 
2950
2700
        srv_main_thread_op_info = "waiting for buffer pool flush to end";
2951
 
        buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
 
2701
        buf_flush_wait_batch_end(BUF_FLUSH_LIST);
2952
2702
 
2953
2703
        /* Flush logs if needed */
2954
2704
        srv_sync_log_buffer_in_background();
3035
2785
                already when the event wait ends */
3036
2786
 
3037
2787
                os_thread_exit(NULL);
3038
 
 
3039
2788
        }
3040
2789
 
3041
2790
        /* When there is user activity, InnoDB will set the event and the
3048
2797
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3049
2798
#endif
3050
2799
}
3051
 
 
3052
 
/*********************************************************************//**
3053
 
Asynchronous purge thread.
3054
 
@return a dummy parameter */
3055
 
UNIV_INTERN
3056
 
os_thread_ret_t
3057
 
srv_purge_thread(
3058
 
/*=============*/
3059
 
        void*   arg __attribute__((unused)))    /*!< in: a dummy parameter
3060
 
                                                required by os_thread_create */
3061
 
{
3062
 
        srv_slot_t*     slot;
3063
 
        ulint           slot_no = ULINT_UNDEFINED;
3064
 
        ulint           n_total_purged = ULINT_UNDEFINED;
3065
 
 
3066
 
        ut_a(srv_n_purge_threads == 1);
3067
 
 
3068
 
#ifdef UNIV_DEBUG_THREAD_CREATION
3069
 
        fprintf(stderr, "InnoDB: Purge thread running, id %lu\n",
3070
 
                os_thread_pf(os_thread_get_curr_id()));
3071
 
#endif /* UNIV_DEBUG_THREAD_CREATION */
3072
 
 
3073
 
        mutex_enter(&kernel_mutex);
3074
 
 
3075
 
        slot_no = srv_table_reserve_slot(SRV_WORKER);
3076
 
 
3077
 
        slot = srv_table_get_nth_slot(slot_no);
3078
 
 
3079
 
        ++srv_n_threads_active[SRV_WORKER];
3080
 
 
3081
 
        mutex_exit(&kernel_mutex);
3082
 
 
3083
 
        while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
3084
 
 
3085
 
                ulint   n_pages_purged;
3086
 
 
3087
 
                /* If there are very few records to purge or the last
3088
 
                purge didn't purge any records then wait for activity.
3089
 
                We peek at the history len without holding any mutex
3090
 
                because in the worst case we will end up waiting for
3091
 
                the next purge event. */
3092
 
                if (trx_sys->rseg_history_len < srv_purge_batch_size
3093
 
                    || n_total_purged == 0) {
3094
 
 
3095
 
                        os_event_t      event;
3096
 
 
3097
 
                        mutex_enter(&kernel_mutex);
3098
 
 
3099
 
                        event = srv_suspend_thread();
3100
 
 
3101
 
                        mutex_exit(&kernel_mutex);
3102
 
 
3103
 
                        os_event_wait(event);
3104
 
                }
3105
 
 
3106
 
                /* Check for shutdown and whether we should do purge at all. */
3107
 
                if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
3108
 
                    || srv_shutdown_state != 0
3109
 
                    || srv_fast_shutdown) {
3110
 
 
3111
 
                        break;
3112
 
                }
3113
 
 
3114
 
                n_total_purged = 0;
3115
 
 
3116
 
                /* Purge until there are no more records to purge and there is
3117
 
                no change in configuration or server state. */
3118
 
                do {
3119
 
                        n_pages_purged = trx_purge(srv_purge_batch_size);
3120
 
 
3121
 
                        n_total_purged += n_pages_purged;
3122
 
 
3123
 
                } while (n_pages_purged > 0 && !srv_fast_shutdown);
3124
 
 
3125
 
                srv_sync_log_buffer_in_background();
3126
 
        }
3127
 
 
3128
 
        mutex_enter(&kernel_mutex);
3129
 
 
3130
 
        ut_ad(srv_table_get_nth_slot(slot_no) == slot);
3131
 
 
3132
 
        /* Decrement the active count. */
3133
 
        srv_suspend_thread();
3134
 
 
3135
 
        slot->in_use = FALSE;
3136
 
 
3137
 
        /* Free the thread local memory. */
3138
 
        thr_local_free(os_thread_get_curr_id());
3139
 
 
3140
 
        mutex_exit(&kernel_mutex);
3141
 
 
3142
 
#ifdef UNIV_DEBUG_THREAD_CREATION
3143
 
        fprintf(stderr, "InnoDB: Purge thread exiting, id %lu\n",
3144
 
                os_thread_pf(os_thread_get_curr_id()));
3145
 
#endif /* UNIV_DEBUG_THREAD_CREATION */
3146
 
 
3147
 
        /* We count the number of threads in os_thread_exit(). A created
3148
 
        thread should always use that to exit and not use return() to exit. */
3149
 
        os_thread_exit(NULL);
3150
 
 
3151
 
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
3152
 
}
3153
 
 
3154
 
/**********************************************************************//**
3155
 
Enqueues a task to server task queue and releases a worker thread, if there
3156
 
is a suspended one. */
3157
 
UNIV_INTERN
3158
 
void
3159
 
srv_que_task_enqueue_low(
3160
 
/*=====================*/
3161
 
        que_thr_t*      thr)    /*!< in: query thread */
3162
 
{
3163
 
        ut_ad(thr);
3164
 
 
3165
 
        mutex_enter(&kernel_mutex);
3166
 
 
3167
 
        UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
3168
 
 
3169
 
        srv_release_threads(SRV_WORKER, 1);
3170
 
 
3171
 
        mutex_exit(&kernel_mutex);
3172
 
}