~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2011-02-22 06:12:02 UTC
  • mfrom: (2190.1.6 drizzle-build)
  • Revision ID: brian@tangent.org-20110222061202-k03czxykqy4x9hjs
List update, header fixes, multiple symbols, and David deletes some code.

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.
4
 
Copyright (c) 2008, 2009 Google Inc.
 
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
 
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
78
60
/* Dummy comment */
79
61
#include "srv0srv.h"
80
62
 
 
63
#include <drizzled/error.h>
 
64
#include <drizzled/errmsg_print.h>
 
65
 
81
66
#include "ut0mem.h"
82
67
#include "ut0ut.h"
83
68
#include "os0proc.h"
86
71
#include "sync0sync.h"
87
72
#include "thr0loc.h"
88
73
#include "que0que.h"
89
 
#include "srv0que.h"
90
74
#include "log0recv.h"
91
75
#include "pars0pars.h"
92
76
#include "usr0sess.h"
119
103
in microseconds, in order to reduce the lagging of the purge thread. */
120
104
UNIV_INTERN ulint       srv_dml_needed_delay = 0;
121
105
 
122
 
UNIV_INTERN ibool       srv_lock_timeout_and_monitor_active = FALSE;
 
106
UNIV_INTERN ibool       srv_lock_timeout_active = FALSE;
 
107
UNIV_INTERN ibool       srv_monitor_active = FALSE;
123
108
UNIV_INTERN ibool       srv_error_monitor_active = FALSE;
124
109
 
125
110
UNIV_INTERN const char* srv_main_thread_op_info = "";
126
111
 
127
 
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
128
 
UNIV_INTERN const char  srv_mysql50_table_name_prefix[9] = "#mysql50#";
129
 
 
130
112
/* Server parameters which are read from the initfile */
131
113
 
132
114
/* The following three are dir paths which are catenated before file
145
127
/** Whether to check file format during startup.  A value of
146
128
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE.  The default is to
147
129
set it to the highest format we support. */
148
 
UNIV_INTERN ulint       srv_check_file_format_at_startup = DICT_TF_FORMAT_MAX;
 
130
UNIV_INTERN ulint       srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX;
149
131
 
150
132
#if DICT_TF_FORMAT_51
151
133
# error "DICT_TF_FORMAT_51 must be 0!"
154
136
on duplicate key checking and foreign key checking */
155
137
UNIV_INTERN ibool       srv_locks_unsafe_for_binlog = FALSE;
156
138
 
 
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
 
157
160
UNIV_INTERN ulint       srv_n_data_files = 0;
158
161
UNIV_INTERN char**      srv_data_file_names = NULL;
159
162
/* size in database pages */
188
191
the checkpoints. */
189
192
UNIV_INTERN bool        srv_adaptive_flushing   = TRUE;
190
193
 
191
 
/* The sort order table of the MySQL latin1_swedish_ci character set
 
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
192
205
collation */
193
206
#if defined(BUILD_DRIZZLE)
194
 
UNIV_INTERN const byte  srv_latin1_ordering[256]        /* The sort order table of the latin1
 
207
const byte      srv_latin1_ordering[256]        /* The sort order table of the latin1
195
208
                                        character set. The following table is
196
209
                                        the MySQL order as of Feb 10th, 2002 */
197
210
= {
237
250
UNIV_INTERN my_bool     srv_use_sys_malloc      = TRUE;
238
251
/* requested size in kilobytes */
239
252
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;
240
255
/* previously requested size */
241
256
UNIV_INTERN ulint       srv_buf_pool_old_size;
242
257
/* current size in kilobytes */
288
303
 
289
304
UNIV_INTERN ulong       srv_max_buf_pool_modified_pct   = 75;
290
305
 
 
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
 
291
312
/* variable counts amount of data read in total (in bytes) */
292
313
UNIV_INTERN ulint srv_data_read = 0;
293
314
 
442
463
UNIV_INTERN ib_int64_t  srv_n_lock_wait_time            = 0;
443
464
UNIV_INTERN ulint               srv_n_lock_max_wait_time        = 0;
444
465
 
 
466
UNIV_INTERN ulint               srv_truncated_status_writes     = 0;
445
467
 
446
468
/*
447
469
  Set the following to 0 if you want InnoDB to write messages on
465
487
 
466
488
/* Mutex for locking srv_monitor_file */
467
489
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 protect writing the commit_id to the sys header */
 
495
UNIV_INTERN mysql_pfs_key_t     commit_id_mutex_key;
 
496
/* Key to register srv_innodb_monitor_mutex with performance schema */
 
497
UNIV_INTERN mysql_pfs_key_t     srv_innodb_monitor_mutex_key;
 
498
/* Key to register srv_monitor_file_mutex with performance schema */
 
499
UNIV_INTERN mysql_pfs_key_t     srv_monitor_file_mutex_key;
 
500
/* Key to register srv_dict_tmpfile_mutex with performance schema */
 
501
UNIV_INTERN mysql_pfs_key_t     srv_dict_tmpfile_mutex_key;
 
502
/* Key to register the mutex with performance schema */
 
503
UNIV_INTERN mysql_pfs_key_t     srv_misc_tmpfile_mutex_key;
 
504
#endif /* UNIV_PFS_MUTEX */
 
505
 
468
506
/* Temporary file for innodb monitor output */
469
507
UNIV_INTERN FILE*       srv_monitor_file;
470
508
/* Mutex for locking srv_dict_tmpfile.
698
736
/* Table for MySQL threads where they will be suspended to wait for locks */
699
737
UNIV_INTERN srv_slot_t* srv_mysql_table = NULL;
700
738
 
 
739
UNIV_INTERN os_event_t  srv_timeout_event;
 
740
 
 
741
UNIV_INTERN os_event_t  srv_monitor_event;
 
742
 
 
743
UNIV_INTERN os_event_t  srv_error_event;
 
744
 
701
745
UNIV_INTERN os_event_t  srv_lock_timeout_thread_event;
702
746
 
703
747
UNIV_INTERN srv_sys_t*  srv_sys = NULL;
707
751
UNIV_INTERN byte        srv_pad1[64];
708
752
/* mutex protecting the server, trx structs, query threads, and lock table */
709
753
UNIV_INTERN mutex_t*    kernel_mutex_temp;
 
754
/* mutex protecting the sys header for writing the commit id */
 
755
UNIV_INTERN mutex_t*    commit_id_mutex_temp;
 
756
 
710
757
/* padding to prevent other memory update hotspots from residing on
711
758
the same memory cache line */
712
759
UNIV_INTERN byte        srv_pad2[64];
725
772
static ulint    srv_meter_foreground[SRV_MASTER + 1];
726
773
#endif
727
774
 
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
 
 
735
775
/***********************************************************************
736
776
Prints counters for work done by srv_master_thread. */
737
777
static
749
789
                      srv_log_writes_and_flush);
750
790
}
751
791
 
 
792
/* The following values give info about the activity going on in
 
793
the database. They are protected by the server mutex. The arrays
 
794
are indexed by the type of the thread. */
 
795
 
 
796
UNIV_INTERN ulint       srv_n_threads_active[SRV_MASTER + 1];
 
797
UNIV_INTERN ulint       srv_n_threads[SRV_MASTER + 1];
 
798
 
752
799
/*********************************************************************//**
753
800
Sets the info describing an i/o thread current state. */
754
801
UNIV_INTERN
868
915
 
869
916
        slot = srv_table_get_nth_slot(slot_no);
870
917
 
871
 
        type = slot->type;
 
918
        type = static_cast<srv_thread_type>(slot->type);
872
919
 
873
920
        ut_ad(type >= SRV_WORKER);
874
921
        ut_ad(type <= SRV_MASTER);
911
958
 
912
959
                slot = srv_table_get_nth_slot(i);
913
960
 
914
 
                if (slot->in_use && slot->type == type && slot->suspended) {
 
961
                if (slot->in_use &&
 
962
                    (static_cast<srv_thread_type>(slot->type) == type) &&
 
963
                    slot->suspended) {
915
964
 
916
965
                        slot->suspended = FALSE;
917
966
 
956
1005
 
957
1006
        slot = srv_table_get_nth_slot(slot_no);
958
1007
 
959
 
        type = slot->type;
 
1008
        type = static_cast<srv_thread_type>(slot->type);
960
1009
 
961
1010
        ut_ad(type >= SRV_WORKER);
962
1011
        ut_ad(type <= SRV_MASTER);
977
1026
        srv_slot_t*             slot;
978
1027
        ulint                   i;
979
1028
 
980
 
        srv_sys = mem_alloc(sizeof(srv_sys_t));
981
 
 
982
 
        kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
983
 
        mutex_create(&kernel_mutex, SYNC_KERNEL);
984
 
 
985
 
        mutex_create(&srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
986
 
 
987
 
        srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
 
1029
        srv_sys = static_cast<srv_sys_t *>(mem_alloc(sizeof(srv_sys_t)));
 
1030
 
 
1031
        kernel_mutex_temp = static_cast<ib_mutex_t *>(mem_alloc(sizeof(mutex_t)));
 
1032
        mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);
 
1033
 
 
1034
        commit_id_mutex_temp = static_cast<ib_mutex_t *>(mem_alloc(sizeof(mutex_t)));
 
1035
        mutex_create(commit_id_mutex_key, &commit_id_mutex, SYNC_COMMIT_ID_LOCK);
 
1036
 
 
1037
        mutex_create(srv_innodb_monitor_mutex_key,
 
1038
                     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
 
1039
 
 
1040
        srv_sys->threads = static_cast<srv_table_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
988
1041
 
989
1042
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
990
1043
                slot = srv_table_get_nth_slot(i);
994
1047
                ut_a(slot->event);
995
1048
        }
996
1049
 
997
 
        srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
 
1050
        srv_mysql_table = static_cast<srv_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t)));
998
1051
 
999
1052
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1000
1053
                slot = srv_mysql_table + i;
1004
1057
                ut_a(slot->event);
1005
1058
        }
1006
1059
 
 
1060
        srv_error_event = os_event_create(NULL);
 
1061
 
 
1062
        srv_timeout_event = os_event_create(NULL);
 
1063
 
 
1064
        srv_monitor_event = os_event_create(NULL);
 
1065
 
1007
1066
        srv_lock_timeout_thread_event = os_event_create(NULL);
1008
1067
 
1009
1068
        for (i = 0; i < SRV_MASTER + 1; i++) {
1030
1089
 
1031
1090
        UT_LIST_INIT(srv_conc_queue);
1032
1091
 
1033
 
        srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
 
1092
        srv_conc_slots = static_cast<srv_conc_slot_t *>(mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t)));
1034
1093
 
1035
1094
        for (i = 0; i < OS_THREAD_MAX_N; i++) {
1036
1095
                conc_slot = srv_conc_slots + i;
1063
1122
        mem_free(srv_mysql_table);
1064
1123
        srv_mysql_table = NULL;
1065
1124
 
 
1125
        mem_free(commit_id_mutex_temp);
 
1126
        commit_id_mutex_temp = NULL;
 
1127
 
1066
1128
        trx_i_s_cache_free(trx_i_s_cache);
1067
1129
}
1068
1130
 
1583
1645
                row_mysql_unfreeze_data_dictionary(trx);
1584
1646
                break;
1585
1647
        case RW_X_LATCH:
 
1648
                /* There should never be a lock wait when the
 
1649
                dictionary latch is reserved in X mode.  Dictionary
 
1650
                transactions should only acquire locks on dictionary
 
1651
                tables, not other tables. All access to dictionary
 
1652
                tables should be covered by dictionary
 
1653
                transactions. */
 
1654
                ut_print_timestamp(stderr);
 
1655
                fputs("  InnoDB: Error: dict X latch held in "
 
1656
                      "srv_suspend_mysql_thread\n", stderr);
 
1657
                /* This should never occur. This incorrect handling
 
1658
                was added in the early development of
 
1659
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1586
1660
                /* Release fast index creation latch */
1587
1661
                row_mysql_unlock_data_dictionary(trx);
1588
1662
                break;
1602
1676
                row_mysql_freeze_data_dictionary(trx);
1603
1677
                break;
1604
1678
        case RW_X_LATCH:
 
1679
                /* This should never occur. This incorrect handling
 
1680
                was added in the early development of
 
1681
                ha_innobase::add_index() in InnoDB Plugin 1.0. */
1605
1682
                row_mysql_lock_data_dictionary(trx);
1606
1683
                break;
1607
1684
        }
1638
1715
                    start_time != -1 && finish_time != -1) {
1639
1716
                        srv_n_lock_max_wait_time = diff_time;
1640
1717
                }
 
1718
 
 
1719
                /* Record the lock wait time for this thread */
 
1720
                thd_set_lock_wait_time(trx->mysql_thd, diff_time);
1641
1721
        }
1642
1722
 
1643
1723
        if (trx->was_chosen_as_deadlock_victim) {
1659
1739
 
1660
1740
                trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1661
1741
        }
 
1742
 
 
1743
        if (trx_is_interrupted(trx)) {
 
1744
 
 
1745
                trx->error_state = DB_INTERRUPTED;
 
1746
        }
1662
1747
}
1663
1748
 
1664
1749
/********************************************************************//**
1710
1795
 
1711
1796
        log_refresh_stats();
1712
1797
 
1713
 
        buf_refresh_io_stats();
 
1798
        buf_refresh_io_stats_all();
1714
1799
 
1715
1800
        srv_n_rows_inserted_old = srv_n_rows_inserted;
1716
1801
        srv_n_rows_updated_old = srv_n_rows_updated;
1721
1806
}
1722
1807
 
1723
1808
/******************************************************************//**
1724
 
Outputs to a file the output of the InnoDB Monitor. */
 
1809
Outputs to a file the output of the InnoDB Monitor.
 
1810
@return FALSE if not all information printed
 
1811
due to failure to obtain necessary mutex */
1725
1812
UNIV_INTERN
1726
 
void
 
1813
ibool
1727
1814
srv_printf_innodb_monitor(
1728
1815
/*======================*/
1729
1816
        FILE*   file,           /*!< in: output stream */
 
1817
        ibool   nowait,         /*!< in: whether to wait for kernel mutex */
1730
1818
        ulint*  trx_start,      /*!< out: file position of the start of
1731
1819
                                the list of active transactions */
1732
1820
        ulint*  trx_end)        /*!< out: file position of the end of
1735
1823
        double  time_elapsed;
1736
1824
        time_t  current_time;
1737
1825
        ulint   n_reserved;
 
1826
        ibool   ret;
1738
1827
 
1739
1828
        mutex_enter(&srv_innodb_monitor_mutex);
1740
1829
 
1758
1847
                "Per second averages calculated from the last %lu seconds\n",
1759
1848
                (ulong)time_elapsed);
1760
1849
 
1761
 
        fputs("----------\n"
1762
 
                "BACKGROUND THREAD\n"
1763
 
                "----------\n", file);
 
1850
        fputs("-----------------\n"
 
1851
              "BACKGROUND THREAD\n"
 
1852
              "-----------------\n", file);
1764
1853
        srv_print_master_thread_info(file);
1765
1854
 
1766
1855
        fputs("----------\n"
1784
1873
 
1785
1874
        mutex_exit(&dict_foreign_err_mutex);
1786
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
        /* Only if lock_print_info_summary proceeds correctly,
 
1877
        before we call the lock_print_info_all_transactions
 
1878
        to print all the lock information. */
 
1879
        ret = lock_print_info_summary(file, nowait);
 
1880
 
 
1881
        if (ret) {
 
1882
                if (trx_start) {
 
1883
                        long    t = ftell(file);
 
1884
                        if (t < 0) {
 
1885
                                *trx_start = ULINT_UNDEFINED;
 
1886
                        } else {
 
1887
                                *trx_start = (ulint) t;
 
1888
                        }
 
1889
                }
 
1890
                lock_print_info_all_transactions(file);
 
1891
                if (trx_end) {
 
1892
                        long    t = ftell(file);
 
1893
                        if (t < 0) {
 
1894
                                *trx_end = ULINT_UNDEFINED;
 
1895
                        } else {
 
1896
                                *trx_end = (ulint) t;
 
1897
                        }
 
1898
                }
 
1899
        }
 
1900
 
1805
1901
        fputs("--------\n"
1806
1902
              "FILE I/O\n"
1807
1903
              "--------\n", file);
1849
1945
                (ulong) srv_conc_n_waiting_threads);
1850
1946
 
1851
1947
        fprintf(file, "%lu read views open inside InnoDB\n",
1852
 
                UT_LIST_GET_LEN(trx_sys->view_list));
 
1948
                static_cast<ulint>(UT_LIST_GET_LEN(trx_sys->view_list)));
1853
1949
 
1854
1950
        n_reserved = fil_space_get_n_reserved_extents(0);
1855
1951
        if (n_reserved > 0) {
1899
1995
              "============================\n", file);
1900
1996
        mutex_exit(&srv_innodb_monitor_mutex);
1901
1997
        fflush(file);
 
1998
 
 
1999
        return(ret);
1902
2000
}
1903
2001
 
1904
2002
/******************************************************************//**
1908
2006
srv_export_innodb_status(void)
1909
2007
/*==========================*/
1910
2008
{
 
2009
        buf_pool_stat_t stat;
 
2010
        ulint           LRU_len;
 
2011
        ulint           free_len;
 
2012
        ulint           flush_list_len;
 
2013
 
 
2014
        buf_get_total_stat(&stat);
 
2015
        buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
 
2016
 
1911
2017
        mutex_enter(&srv_innodb_monitor_mutex);
1912
2018
 
1913
2019
        export_vars.innodb_data_pending_reads
1922
2028
        export_vars.innodb_data_reads = os_n_file_reads;
1923
2029
        export_vars.innodb_data_writes = os_n_file_writes;
1924
2030
        export_vars.innodb_data_written = srv_data_written;
1925
 
        export_vars.innodb_buffer_pool_read_requests = buf_pool->stat.n_page_gets;
 
2031
        export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
1926
2032
        export_vars.innodb_buffer_pool_write_requests
1927
2033
                = srv_buf_pool_write_requests;
1928
2034
        export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
1929
2035
        export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
1930
2036
        export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
1931
2037
        export_vars.innodb_buffer_pool_read_ahead
1932
 
                = buf_pool->stat.n_ra_pages_read;
 
2038
                = stat.n_ra_pages_read;
1933
2039
        export_vars.innodb_buffer_pool_read_ahead_evicted
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);
 
2040
                = stat.n_ra_pages_evicted;
 
2041
        export_vars.innodb_buffer_pool_pages_data = LRU_len;
 
2042
        export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
 
2043
        export_vars.innodb_buffer_pool_pages_free = free_len;
1941
2044
#ifdef UNIV_DEBUG
1942
2045
        export_vars.innodb_buffer_pool_pages_latched
1943
2046
                = buf_get_latched_pages_number();
1944
2047
#endif /* UNIV_DEBUG */
1945
 
        export_vars.innodb_buffer_pool_pages_total = buf_pool->curr_size;
 
2048
        export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
1946
2049
 
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);
 
2050
        export_vars.innodb_buffer_pool_pages_misc
 
2051
                = buf_pool_get_n_pages() - LRU_len - free_len;
1950
2052
#ifdef HAVE_ATOMIC_BUILTINS
1951
2053
        export_vars.innodb_have_atomic_builtins = 1;
1952
2054
#else
1962
2064
        export_vars.innodb_log_writes = srv_log_writes;
1963
2065
        export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
1964
2066
        export_vars.innodb_dblwr_writes = srv_dblwr_writes;
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;
 
2067
        export_vars.innodb_pages_created = stat.n_pages_created;
 
2068
        export_vars.innodb_pages_read = stat.n_pages_read;
 
2069
        export_vars.innodb_pages_written = stat.n_pages_written;
1968
2070
        export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
1969
2071
        export_vars.innodb_row_lock_current_waits
1970
2072
                = srv_n_lock_wait_current_count;
1981
2083
        export_vars.innodb_rows_inserted = srv_n_rows_inserted;
1982
2084
        export_vars.innodb_rows_updated = srv_n_rows_updated;
1983
2085
        export_vars.innodb_rows_deleted = srv_n_rows_deleted;
 
2086
        export_vars.innodb_truncated_status_writes = srv_truncated_status_writes;
1984
2087
 
1985
2088
        mutex_exit(&srv_innodb_monitor_mutex);
1986
2089
}
1987
2090
 
1988
2091
/*********************************************************************//**
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.
 
2092
A thread which prints the info output by various InnoDB monitors.
1991
2093
@return a dummy parameter */
1992
2094
UNIV_INTERN
1993
2095
os_thread_ret_t
1994
 
srv_lock_timeout_and_monitor_thread(
1995
 
/*================================*/
1996
 
        void*   arg __attribute__((unused)))
 
2096
srv_monitor_thread(
 
2097
/*===============*/
 
2098
        void*   /*arg __attribute__((unused))*/)
1997
2099
                        /*!< in: a dummy parameter required by
1998
2100
                        os_thread_create */
1999
2101
{
2000
 
        srv_slot_t*     slot;
 
2102
        ib_int64_t      sig_count;
2001
2103
        double          time_elapsed;
2002
2104
        time_t          current_time;
2003
2105
        time_t          last_table_monitor_time;
2004
2106
        time_t          last_tablespace_monitor_time;
2005
2107
        time_t          last_monitor_time;
2006
 
        ibool           some_waits;
2007
 
        double          wait_time;
2008
 
        ulint           i;
 
2108
        ulint           mutex_skipped;
 
2109
        ibool           last_srv_print_monitor;
2009
2110
 
2010
2111
#ifdef UNIV_DEBUG_THREAD_CREATION
2011
2112
        fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2012
2113
                os_thread_pf(os_thread_get_curr_id()));
2013
2114
#endif
2014
 
        UT_NOT_USED(arg);
2015
 
        srv_last_monitor_time = time(NULL);
2016
 
        last_table_monitor_time = time(NULL);
2017
 
        last_tablespace_monitor_time = time(NULL);
2018
 
        last_monitor_time = time(NULL);
 
2115
 
 
2116
#ifdef UNIV_PFS_THREAD
 
2117
        pfs_register_thread(srv_monitor_thread_key);
 
2118
#endif
 
2119
 
 
2120
        srv_last_monitor_time = ut_time();
 
2121
        last_table_monitor_time = ut_time();
 
2122
        last_tablespace_monitor_time = ut_time();
 
2123
        last_monitor_time = ut_time();
 
2124
        mutex_skipped = 0;
 
2125
        last_srv_print_monitor = srv_print_innodb_monitor;
2019
2126
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);
2026
 
 
2027
 
        current_time = time(NULL);
 
2127
        srv_monitor_active = TRUE;
 
2128
 
 
2129
        /* Wake up every 5 seconds to see if we need to print
 
2130
        monitor information or if signalled at shutdown. */
 
2131
 
 
2132
        sig_count = os_event_reset(srv_monitor_event);
 
2133
 
 
2134
        os_event_wait_time_low(srv_monitor_event, 5000000, sig_count);
 
2135
 
 
2136
        current_time = ut_time();
2028
2137
 
2029
2138
        time_elapsed = difftime(current_time, last_monitor_time);
2030
2139
 
2031
2140
        if (time_elapsed > 15) {
2032
 
                last_monitor_time = time(NULL);
 
2141
                last_monitor_time = ut_time();
2033
2142
 
2034
2143
                if (srv_print_innodb_monitor) {
2035
 
                        srv_printf_innodb_monitor(stderr, NULL, NULL);
 
2144
                        /* Reset mutex_skipped counter everytime
 
2145
                        srv_print_innodb_monitor changes. This is to
 
2146
                        ensure we will not be blocked by kernel_mutex
 
2147
                        for short duration information printing,
 
2148
                        such as requested by sync_array_print_long_waits() */
 
2149
                        if (!last_srv_print_monitor) {
 
2150
                                mutex_skipped = 0;
 
2151
                                last_srv_print_monitor = TRUE;
 
2152
                        }
 
2153
 
 
2154
                        if (!srv_printf_innodb_monitor(stderr,
 
2155
                                                MUTEX_NOWAIT(mutex_skipped),
 
2156
                                                NULL, NULL)) {
 
2157
                                mutex_skipped++;
 
2158
                        } else {
 
2159
                                /* Reset the counter */
 
2160
                                mutex_skipped = 0;
 
2161
                        }
 
2162
                } else {
 
2163
                        last_srv_print_monitor = FALSE;
2036
2164
                }
2037
2165
 
 
2166
 
2038
2167
                if (srv_innodb_status) {
2039
2168
                        mutex_enter(&srv_monitor_file_mutex);
2040
2169
                        rewind(srv_monitor_file);
2041
 
                        srv_printf_innodb_monitor(srv_monitor_file, NULL,
2042
 
                                                  NULL);
 
2170
                        if (!srv_printf_innodb_monitor(srv_monitor_file,
 
2171
                                                MUTEX_NOWAIT(mutex_skipped),
 
2172
                                                NULL, NULL)) {
 
2173
                                mutex_skipped++;
 
2174
                        } else {
 
2175
                                mutex_skipped = 0;
 
2176
                        }
 
2177
 
2043
2178
                        os_file_set_eof(srv_monitor_file);
2044
2179
                        mutex_exit(&srv_monitor_file_mutex);
2045
2180
                }
2047
2182
                if (srv_print_innodb_tablespace_monitor
2048
2183
                    && difftime(current_time,
2049
2184
                                last_tablespace_monitor_time) > 60) {
2050
 
                        last_tablespace_monitor_time = time(NULL);
 
2185
                        last_tablespace_monitor_time = ut_time();
2051
2186
 
2052
2187
                        fputs("========================"
2053
2188
                              "========================\n",
2073
2208
                if (srv_print_innodb_table_monitor
2074
2209
                    && difftime(current_time, last_table_monitor_time) > 60) {
2075
2210
 
2076
 
                        last_table_monitor_time = time(NULL);
 
2211
                        last_table_monitor_time = ut_time();
2077
2212
 
2078
2213
                        fputs("===========================================\n",
2079
2214
                              stderr);
2092
2227
                }
2093
2228
        }
2094
2229
 
 
2230
        if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
 
2231
                goto exit_func;
 
2232
        }
 
2233
 
 
2234
        if (srv_print_innodb_monitor
 
2235
            || srv_print_innodb_lock_monitor
 
2236
            || srv_print_innodb_tablespace_monitor
 
2237
            || srv_print_innodb_table_monitor) {
 
2238
                goto loop;
 
2239
        }
 
2240
 
 
2241
        srv_monitor_active = FALSE;
 
2242
 
 
2243
        goto loop;
 
2244
 
 
2245
exit_func:
 
2246
        srv_monitor_active = FALSE;
 
2247
 
 
2248
        /* We count the number of threads in os_thread_exit(). A created
 
2249
        thread should always use that to exit and not use return() to exit. */
 
2250
 
 
2251
        os_thread_exit(NULL);
 
2252
 
 
2253
        OS_THREAD_DUMMY_RETURN;
 
2254
}
 
2255
 
 
2256
/*********************************************************************//**
 
2257
A thread which wakes up threads whose lock wait may have lasted too long.
 
2258
@return a dummy parameter */
 
2259
UNIV_INTERN
 
2260
os_thread_ret_t
 
2261
srv_lock_timeout_thread(
 
2262
/*====================*/
 
2263
        void*   /*arg __attribute__((unused))*/)
 
2264
                        /* in: a dummy parameter required by
 
2265
                        os_thread_create */
 
2266
{
 
2267
        srv_slot_t*     slot;
 
2268
        ibool           some_waits;
 
2269
        double          wait_time;
 
2270
        ulint           i;
 
2271
        ib_int64_t      sig_count;
 
2272
 
 
2273
#ifdef UNIV_PFS_THREAD
 
2274
        pfs_register_thread(srv_lock_timeout_thread_key);
 
2275
#endif
 
2276
 
 
2277
loop:
 
2278
 
 
2279
        /* When someone is waiting for a lock, we wake up every second
 
2280
        and check if a timeout has passed for a lock wait */
 
2281
 
 
2282
        sig_count = os_event_reset(srv_timeout_event);
 
2283
 
 
2284
        os_event_wait_time_low(srv_timeout_event, 1000000, sig_count);
 
2285
 
 
2286
        srv_lock_timeout_active = TRUE;
 
2287
 
2095
2288
        mutex_enter(&kernel_mutex);
2096
2289
 
2097
2290
        some_waits = FALSE;
2115
2308
                        lock_wait_timeout = thd_lock_wait_timeout(
2116
2309
                                trx->mysql_thd);
2117
2310
 
2118
 
                        if (lock_wait_timeout < 100000000
2119
 
                            && (wait_time > (double) lock_wait_timeout
2120
 
                                || wait_time < 0)) {
 
2311
                        if (trx_is_interrupted(trx)
 
2312
                            || (lock_wait_timeout < 100000000
 
2313
                                && (wait_time > (double) lock_wait_timeout
 
2314
                                    || wait_time < 0))) {
2121
2315
 
2122
2316
                                /* Timeout exceeded or a wrap-around in system
2123
2317
                                time counter: cancel the lock request queued
2142
2336
                goto exit_func;
2143
2337
        }
2144
2338
 
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) {
 
2339
        if (some_waits) {
2149
2340
                goto loop;
2150
2341
        }
2151
2342
 
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;
 
2343
        srv_lock_timeout_active = FALSE;
2156
2344
 
2157
2345
#if 0
2158
2346
        /* The following synchronisation is disabled, since
2162
2350
        goto loop;
2163
2351
 
2164
2352
exit_func:
2165
 
        srv_lock_timeout_and_monitor_active = FALSE;
 
2353
        srv_lock_timeout_active = FALSE;
2166
2354
 
2167
2355
        /* We count the number of threads in os_thread_exit(). A created
2168
2356
        thread should always use that to exit and not use return() to exit. */
2180
2368
os_thread_ret_t
2181
2369
srv_error_monitor_thread(
2182
2370
/*=====================*/
2183
 
        void*   arg __attribute__((unused)))
 
2371
        void*   /*arg __attribute__((unused))*/)
2184
2372
                        /*!< in: a dummy parameter required by
2185
2373
                        os_thread_create */
2186
2374
{
2188
2376
        ulint           fatal_cnt       = 0;
2189
2377
        ib_uint64_t     old_lsn;
2190
2378
        ib_uint64_t     new_lsn;
 
2379
        ib_int64_t      sig_count;
2191
2380
 
2192
2381
        old_lsn = srv_start_lsn;
2193
2382
 
2195
2384
        fprintf(stderr, "Error monitor thread starts, id %lu\n",
2196
2385
                os_thread_pf(os_thread_get_curr_id()));
2197
2386
#endif
 
2387
 
 
2388
#ifdef UNIV_PFS_THREAD
 
2389
        pfs_register_thread(srv_error_monitor_thread_key);
 
2390
#endif
 
2391
 
2198
2392
loop:
2199
2393
        srv_error_monitor_active = TRUE;
2200
2394
 
2204
2398
        new_lsn = log_get_lsn();
2205
2399
 
2206
2400
        if (new_lsn < old_lsn) {
2207
 
                ut_print_timestamp(stderr);
2208
 
                fprintf(stderr,
2209
 
                        "  InnoDB: Error: old log sequence number %"PRIu64""
2210
 
                        " was greater\n"
2211
 
                        "InnoDB: than the new log sequence number %"PRIu64"!\n"
2212
 
                        "InnoDB: Please submit a bug report"
2213
 
                        " to http://bugs.mysql.com\n",
2214
 
                        old_lsn, new_lsn);
 
2401
          drizzled::errmsg_printf(drizzled::error::INFO,
 
2402
                                  "InnoDB: Error: old log sequence number %"PRIu64" was greater than the new log sequence number %"PRIu64"!"
 
2403
                                  "InnoDB: Please submit a bug report to http://bugs.launchpad.net/drizzle",
 
2404
                                  old_lsn, new_lsn);
2215
2405
        }
2216
2406
 
2217
2407
        old_lsn = new_lsn;
2258
2448
 
2259
2449
        fflush(stderr);
2260
2450
 
2261
 
        os_thread_sleep(1000000);
 
2451
        sig_count = os_event_reset(srv_error_event);
 
2452
 
 
2453
        os_event_wait_time_low(srv_error_event, 1000000, sig_count);
2262
2454
 
2263
2455
        if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
2264
2456
 
2275
2467
        OS_THREAD_DUMMY_RETURN;
2276
2468
}
2277
2469
 
 
2470
/**********************************************************************//**
 
2471
Check whether any background thread is active.
 
2472
@return FALSE if all are are suspended or have exited. */
 
2473
UNIV_INTERN
 
2474
ibool
 
2475
srv_is_any_background_thread_active(void)
 
2476
/*=====================================*/
 
2477
{
 
2478
        ulint   i;
 
2479
        ibool   ret = FALSE;
 
2480
 
 
2481
        mutex_enter(&kernel_mutex);
 
2482
 
 
2483
        for (i = SRV_COM; i <= SRV_MASTER; ++i) {
 
2484
                if (srv_n_threads_active[i] != 0) {
 
2485
                        ret = TRUE;
 
2486
                        break;
 
2487
                }
 
2488
        }
 
2489
 
 
2490
        mutex_exit(&kernel_mutex);
 
2491
 
 
2492
        return(ret);
 
2493
}
 
2494
 
2278
2495
/*******************************************************************//**
2279
2496
Tells the InnoDB server that there has been activity in the database
2280
2497
and wakes up the master thread if it is suspended (not sleeping). Used
2281
2498
in the MySQL interface. Note that there is a small chance that the master
2282
 
thread stays suspended (we do not protect our operation with the kernel
2283
 
mutex, for performace reasons). */
 
2499
thread stays suspended (we do not protect our operation with the
 
2500
srv_sys_t->mutex, for performance reasons). */
2284
2501
UNIV_INTERN
2285
2502
void
2286
2503
srv_active_wake_master_thread(void)
2299
2516
}
2300
2517
 
2301
2518
/*******************************************************************//**
 
2519
Tells the purge thread that there has been activity in the database
 
2520
and wakes up the purge thread if it is suspended (not sleeping).  Note
 
2521
that there is a small chance that the purge thread stays suspended
 
2522
(we do not protect our operation with the kernel mutex, for
 
2523
performace reasons). */
 
2524
UNIV_INTERN
 
2525
void
 
2526
srv_wake_purge_thread_if_not_active(void)
 
2527
/*=====================================*/
 
2528
{
 
2529
        ut_ad(!mutex_own(&kernel_mutex));
 
2530
 
 
2531
        if (srv_n_purge_threads > 0
 
2532
            && srv_n_threads_active[SRV_WORKER] == 0) {
 
2533
 
 
2534
                mutex_enter(&kernel_mutex);
 
2535
 
 
2536
                srv_release_threads(SRV_WORKER, 1);
 
2537
 
 
2538
                mutex_exit(&kernel_mutex);
 
2539
        }
 
2540
}
 
2541
 
 
2542
/*******************************************************************//**
2302
2543
Wakes up the master thread if it is suspended or being suspended. */
2303
2544
UNIV_INTERN
2304
2545
void
2314
2555
        mutex_exit(&kernel_mutex);
2315
2556
}
2316
2557
 
 
2558
/*******************************************************************//**
 
2559
Wakes up the purge thread if it's not already awake. */
 
2560
UNIV_INTERN
 
2561
void
 
2562
srv_wake_purge_thread(void)
 
2563
/*=======================*/
 
2564
{
 
2565
        ut_ad(!mutex_own(&kernel_mutex));
 
2566
 
 
2567
        if (srv_n_purge_threads > 0) {
 
2568
 
 
2569
                mutex_enter(&kernel_mutex);
 
2570
 
 
2571
                srv_release_threads(SRV_WORKER, 1);
 
2572
 
 
2573
                mutex_exit(&kernel_mutex);
 
2574
        }
 
2575
}
 
2576
 
2317
2577
/**********************************************************************
2318
2578
The master thread is tasked to ensure that flush of log file happens
2319
2579
once every second in the background. This is to ensure that not more
2334
2594
        }
2335
2595
}
2336
2596
 
 
2597
/********************************************************************//**
 
2598
Do a full purge, reconfigure the purge sub-system if a dynamic
 
2599
change is detected. */
 
2600
static
 
2601
void
 
2602
srv_master_do_purge(void)
 
2603
/*=====================*/
 
2604
{
 
2605
        ulint   n_pages_purged;
 
2606
 
 
2607
        ut_ad(!mutex_own(&kernel_mutex));
 
2608
 
 
2609
        ut_a(srv_n_purge_threads == 0);
 
2610
 
 
2611
        do {
 
2612
                /* Check for shutdown and change in purge config. */
 
2613
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
 
2614
                        /* Nothing to purge. */
 
2615
                        n_pages_purged = 0;
 
2616
                } else {
 
2617
                        n_pages_purged = trx_purge(srv_purge_batch_size);
 
2618
                }
 
2619
 
 
2620
                srv_sync_log_buffer_in_background();
 
2621
 
 
2622
        } while (n_pages_purged > 0);
 
2623
}
 
2624
 
2337
2625
/*********************************************************************//**
2338
2626
The master thread controlling the server.
2339
2627
@return a dummy parameter */
2341
2629
os_thread_ret_t
2342
2630
srv_master_thread(
2343
2631
/*==============*/
2344
 
        void*   arg __attribute__((unused)))
 
2632
        void*   /*arg __attribute__((unused))*/)
2345
2633
                        /*!< in: a dummy parameter required by
2346
2634
                        os_thread_create */
2347
2635
{
 
2636
        buf_pool_stat_t buf_stat;
2348
2637
        os_event_t      event;
2349
2638
        ulint           old_activity_count;
2350
2639
        ulint           n_pages_purged  = 0;
2356
2645
        ulint           n_ios_old;
2357
2646
        ulint           n_ios_very_old;
2358
2647
        ulint           n_pend_ios;
2359
 
        ibool           skip_sleep      = FALSE;
 
2648
        ulint           next_itr_time;
2360
2649
        ulint           i;
2361
2650
 
2362
2651
#ifdef UNIV_DEBUG_THREAD_CREATION
2363
2652
        fprintf(stderr, "Master thread starts, id %lu\n",
2364
2653
                os_thread_pf(os_thread_get_curr_id()));
2365
2654
#endif
 
2655
 
 
2656
#ifdef UNIV_PFS_THREAD
 
2657
        pfs_register_thread(srv_master_thread_key);
 
2658
#endif
 
2659
 
2366
2660
        srv_main_thread_process_no = os_proc_get_number();
2367
2661
        srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2368
2662
 
2381
2675
 
2382
2676
        srv_main_thread_op_info = "reserving kernel mutex";
2383
2677
 
2384
 
        n_ios_very_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
2385
 
                + buf_pool->stat.n_pages_written;
 
2678
        buf_get_total_stat(&buf_stat);
 
2679
        n_ios_very_old = log_sys->n_log_ios + buf_stat.n_pages_read
 
2680
                + buf_stat.n_pages_written;
2386
2681
        mutex_enter(&kernel_mutex);
2387
2682
 
2388
2683
        /* Store the user activity counter at the start of this loop */
2399
2694
        when there is database activity */
2400
2695
 
2401
2696
        srv_last_log_flush_time = time(NULL);
2402
 
        skip_sleep = FALSE;
 
2697
 
 
2698
        /* Sleep for 1 second on entrying the for loop below the first time. */
 
2699
        next_itr_time = ut_time_ms() + 1000;
2403
2700
 
2404
2701
        for (i = 0; i < 10; i++) {
2405
 
                n_ios_old = log_sys->n_log_ios + buf_pool->stat.n_pages_read
2406
 
                        + buf_pool->stat.n_pages_written;
2407
 
                srv_main_thread_op_info = "sleeping";
2408
 
                srv_main_1_second_loops++;
2409
 
 
2410
 
                if (!skip_sleep) {
2411
 
 
2412
 
                        os_thread_sleep(1000000);
2413
 
                        srv_main_sleeps++;
2414
 
                }
2415
 
 
2416
 
                skip_sleep = FALSE;
 
2702
                ulint   cur_time = ut_time_ms();
2417
2703
 
2418
2704
                /* ALTER TABLE in MySQL requires on Unix that the table handler
2419
2705
                can drop tables lazily after there no longer are SELECT
2430
2716
                        goto background_loop;
2431
2717
                }
2432
2718
 
 
2719
                buf_get_total_stat(&buf_stat);
 
2720
 
 
2721
                n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
 
2722
                        + buf_stat.n_pages_written;
 
2723
 
 
2724
                srv_main_thread_op_info = "sleeping";
 
2725
                srv_main_1_second_loops++;
 
2726
 
 
2727
                if (next_itr_time > cur_time
 
2728
                    && srv_shutdown_state == SRV_SHUTDOWN_NONE) {
 
2729
 
 
2730
                        /* Get sleep interval in micro seconds. We use
 
2731
                        ut_min() to avoid long sleep in case of
 
2732
                        wrap around. */
 
2733
                        os_thread_sleep(ut_min(1000000,
 
2734
                                        (next_itr_time - cur_time)
 
2735
                                         * 1000));
 
2736
                        srv_main_sleeps++;
 
2737
                }
 
2738
 
 
2739
                /* Each iteration should happen at 1 second interval. */
 
2740
                next_itr_time = ut_time_ms() + 1000;
 
2741
 
2433
2742
                /* Flush logs if needed */
2434
2743
                srv_sync_log_buffer_in_background();
2435
2744
 
2437
2746
                log_free_check();
2438
2747
 
2439
2748
                /* If i/os during one second sleep were less than 5% of
2440
 
                capacity, we assume that there is free disk i/o capacity
2441
 
                available, and it makes sense to do an insert buffer merge. */
 
2749
                capacity, we assume that there is free disk i/o capacity
 
2750
                available, and it makes sense to do an insert buffer merge. */
2442
2751
 
 
2752
                buf_get_total_stat(&buf_stat);
2443
2753
                n_pend_ios = buf_get_n_pending_ios()
2444
2754
                        + log_sys->n_pending_writes;
2445
 
                n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
2446
 
                        + buf_pool->stat.n_pages_written;
 
2755
                n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
 
2756
                        + buf_stat.n_pages_written;
2447
2757
                if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2448
2758
                    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
2449
2759
                        srv_main_thread_op_info = "doing insert buffer merge";
2461
2771
 
2462
2772
                        srv_main_thread_op_info =
2463
2773
                                "flushing buffer pool pages";
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;
 
2774
                        n_pages_flushed = buf_flush_list(
 
2775
                                PCT_IO(100), IB_ULONGLONG_MAX);
 
2776
 
2474
2777
                } else if (srv_adaptive_flushing) {
2475
2778
 
2476
2779
                        /* Try to keep the rate of flushing of dirty
2483
2786
                                        "flushing buffer pool pages";
2484
2787
                                n_flush = ut_min(PCT_IO(100), n_flush);
2485
2788
                                n_pages_flushed =
2486
 
                                        buf_flush_batch(
2487
 
                                                BUF_FLUSH_LIST,
 
2789
                                        buf_flush_list(
2488
2790
                                                n_flush,
2489
2791
                                                IB_ULONGLONG_MAX);
2490
 
                                skip_sleep = TRUE;
2491
2792
                        }
2492
2793
                }
2493
2794
 
2517
2818
        loop above requests writes for that case. The writes done here
2518
2819
        are not required, and may be disabled. */
2519
2820
 
 
2821
        buf_get_total_stat(&buf_stat);
2520
2822
        n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
2521
 
        n_ios = log_sys->n_log_ios + buf_pool->stat.n_pages_read
2522
 
                + buf_pool->stat.n_pages_written;
 
2823
        n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
 
2824
                + buf_stat.n_pages_written;
2523
2825
 
2524
2826
        srv_main_10_second_loops++;
2525
2827
        if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2526
2828
            && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
2527
2829
 
2528
2830
                srv_main_thread_op_info = "flushing buffer pool pages";
2529
 
                buf_flush_batch(BUF_FLUSH_LIST, PCT_IO(100),
2530
 
                                IB_ULONGLONG_MAX);
 
2831
                buf_flush_list(PCT_IO(100), IB_ULONGLONG_MAX);
2531
2832
 
2532
2833
                /* Flush logs if needed */
2533
2834
                srv_sync_log_buffer_in_background();
2542
2843
        /* Flush logs if needed */
2543
2844
        srv_sync_log_buffer_in_background();
2544
2845
 
2545
 
        /* We run a full purge every 10 seconds, even if the server
2546
 
        were active */
2547
 
        do {
 
2846
        if (srv_n_purge_threads == 0) {
 
2847
                srv_main_thread_op_info = "master purging";
 
2848
 
 
2849
                srv_master_do_purge();
2548
2850
 
2549
2851
                if (srv_fast_shutdown && srv_shutdown_state > 0) {
2550
2852
 
2551
2853
                        goto background_loop;
2552
2854
                }
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);
 
2855
        }
2561
2856
 
2562
2857
        srv_main_thread_op_info = "flushing buffer pool pages";
2563
2858
 
2569
2864
                (> 70 %), we assume we can afford reserving the disk(s) for
2570
2865
                the time it requires to flush 100 pages */
2571
2866
 
2572
 
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
2573
 
                                                  PCT_IO(100),
2574
 
                                                  IB_ULONGLONG_MAX);
 
2867
                n_pages_flushed = buf_flush_list(
 
2868
                        PCT_IO(100), IB_ULONGLONG_MAX);
2575
2869
        } else {
2576
2870
                /* Otherwise, we only flush a small number of pages so that
2577
2871
                we do not unnecessarily use much disk i/o capacity from
2578
2872
                other work */
2579
2873
 
2580
 
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
2581
 
                                                  PCT_IO(10),
2582
 
                                                  IB_ULONGLONG_MAX);
 
2874
                n_pages_flushed = buf_flush_list(
 
2875
                          PCT_IO(10), IB_ULONGLONG_MAX);
2583
2876
        }
2584
2877
 
2585
2878
        srv_main_thread_op_info = "making checkpoint";
2623
2916
                MySQL tries to drop a table while there are still open handles
2624
2917
                to it and we had to put it to the background drop queue.) */
2625
2918
 
2626
 
                os_thread_sleep(100000);
2627
 
        }
2628
 
 
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;
 
2919
                if (srv_shutdown_state == SRV_SHUTDOWN_NONE) {
 
2920
                        os_thread_sleep(100000);
2636
2921
                }
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);
 
2922
        }
 
2923
 
 
2924
        if (srv_n_purge_threads == 0) {
 
2925
                srv_main_thread_op_info = "master purging";
 
2926
 
 
2927
                srv_master_do_purge();
 
2928
        }
2645
2929
 
2646
2930
        srv_main_thread_op_info = "reserving kernel mutex";
2647
2931
 
2659
2943
        } else {
2660
2944
                /* This should do an amount of IO similar to the number of
2661
2945
                dirty pages that will be flushed in the call to
2662
 
                buf_flush_batch below. Otherwise, the system favors
 
2946
                buf_flush_list below. Otherwise, the system favors
2663
2947
                clean pages over cleanup throughput. */
2664
2948
                n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2665
2949
                                                           PCT_IO(100));
2678
2962
        srv_main_thread_op_info = "flushing buffer pool pages";
2679
2963
        srv_main_flush_loops++;
2680
2964
        if (srv_fast_shutdown < 2) {
2681
 
                n_pages_flushed = buf_flush_batch(BUF_FLUSH_LIST,
2682
 
                                                  PCT_IO(100),
2683
 
                                                  IB_ULONGLONG_MAX);
 
2965
                n_pages_flushed = buf_flush_list(
 
2966
                          PCT_IO(100), IB_ULONGLONG_MAX);
2684
2967
        } else {
2685
2968
                /* In the fastest shutdown we do not flush the buffer pool
2686
2969
                to data files: we set n_pages_flushed to 0 artificially. */
2698
2981
        mutex_exit(&kernel_mutex);
2699
2982
 
2700
2983
        srv_main_thread_op_info = "waiting for buffer pool flush to end";
2701
 
        buf_flush_wait_batch_end(BUF_FLUSH_LIST);
 
2984
        buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
2702
2985
 
2703
2986
        /* Flush logs if needed */
2704
2987
        srv_sync_log_buffer_in_background();
2785
3068
                already when the event wait ends */
2786
3069
 
2787
3070
                os_thread_exit(NULL);
 
3071
 
2788
3072
        }
2789
3073
 
2790
3074
        /* When there is user activity, InnoDB will set the event and the
2793
3077
        goto loop;
2794
3078
 
2795
3079
 
2796
 
#if (!defined(__SUNPRO_C) && !defined(__SUNPRO_CC))
 
3080
#if !defined(__SUNPRO_C)
2797
3081
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
2798
3082
#endif
2799
3083
}
 
3084
 
 
3085
/*********************************************************************//**
 
3086
Asynchronous purge thread.
 
3087
@return a dummy parameter */
 
3088
UNIV_INTERN
 
3089
os_thread_ret_t
 
3090
srv_purge_thread(
 
3091
/*=============*/
 
3092
        void*   /*arg __attribute__((unused))*/)        /*!< in: a dummy parameter
 
3093
                                                required by os_thread_create */
 
3094
{
 
3095
        srv_slot_t*     slot;
 
3096
        ulint           slot_no = ULINT_UNDEFINED;
 
3097
        ulint           n_total_purged = ULINT_UNDEFINED;
 
3098
 
 
3099
        ut_a(srv_n_purge_threads == 1);
 
3100
 
 
3101
#ifdef UNIV_DEBUG_THREAD_CREATION
 
3102
        fprintf(stderr, "InnoDB: Purge thread running, id %lu\n",
 
3103
                os_thread_pf(os_thread_get_curr_id()));
 
3104
#endif /* UNIV_DEBUG_THREAD_CREATION */
 
3105
 
 
3106
        mutex_enter(&kernel_mutex);
 
3107
 
 
3108
        slot_no = srv_table_reserve_slot(SRV_WORKER);
 
3109
 
 
3110
        slot = srv_table_get_nth_slot(slot_no);
 
3111
 
 
3112
        ++srv_n_threads_active[SRV_WORKER];
 
3113
 
 
3114
        mutex_exit(&kernel_mutex);
 
3115
 
 
3116
        while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
 
3117
 
 
3118
                ulint   n_pages_purged;
 
3119
 
 
3120
                /* If there are very few records to purge or the last
 
3121
                purge didn't purge any records then wait for activity.
 
3122
                We peek at the history len without holding any mutex
 
3123
                because in the worst case we will end up waiting for
 
3124
                the next purge event. */
 
3125
                if (trx_sys->rseg_history_len < srv_purge_batch_size
 
3126
                    || n_total_purged == 0) {
 
3127
 
 
3128
                        os_event_t      event;
 
3129
 
 
3130
                        mutex_enter(&kernel_mutex);
 
3131
 
 
3132
                        event = srv_suspend_thread();
 
3133
 
 
3134
                        mutex_exit(&kernel_mutex);
 
3135
 
 
3136
                        os_event_wait(event);
 
3137
                }
 
3138
 
 
3139
                /* Check for shutdown and whether we should do purge at all. */
 
3140
                if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
 
3141
                    || srv_shutdown_state != 0
 
3142
                    || srv_fast_shutdown) {
 
3143
 
 
3144
                        break;
 
3145
                }
 
3146
 
 
3147
                n_total_purged = 0;
 
3148
 
 
3149
                /* Purge until there are no more records to purge and there is
 
3150
                no change in configuration or server state. */
 
3151
                do {
 
3152
                        n_pages_purged = trx_purge(srv_purge_batch_size);
 
3153
 
 
3154
                        n_total_purged += n_pages_purged;
 
3155
 
 
3156
                } while (n_pages_purged > 0 && !srv_fast_shutdown);
 
3157
 
 
3158
                srv_sync_log_buffer_in_background();
 
3159
        }
 
3160
 
 
3161
        mutex_enter(&kernel_mutex);
 
3162
 
 
3163
        ut_ad(srv_table_get_nth_slot(slot_no) == slot);
 
3164
 
 
3165
        /* Decrement the active count. */
 
3166
        srv_suspend_thread();
 
3167
 
 
3168
        slot->in_use = FALSE;
 
3169
 
 
3170
        /* Free the thread local memory. */
 
3171
        thr_local_free(os_thread_get_curr_id());
 
3172
 
 
3173
        mutex_exit(&kernel_mutex);
 
3174
 
 
3175
#ifdef UNIV_DEBUG_THREAD_CREATION
 
3176
        fprintf(stderr, "InnoDB: Purge thread exiting, id %lu\n",
 
3177
                os_thread_pf(os_thread_get_curr_id()));
 
3178
#endif /* UNIV_DEBUG_THREAD_CREATION */
 
3179
 
 
3180
        /* We count the number of threads in os_thread_exit(). A created
 
3181
        thread should always use that to exit and not use return() to exit. */
 
3182
        os_thread_exit(NULL);
 
3183
 
 
3184
        OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */
 
3185
}
 
3186
 
 
3187
/**********************************************************************//**
 
3188
Enqueues a task to server task queue and releases a worker thread, if there
 
3189
is a suspended one. */
 
3190
UNIV_INTERN
 
3191
void
 
3192
srv_que_task_enqueue_low(
 
3193
/*=====================*/
 
3194
        que_thr_t*      thr)    /*!< in: query thread */
 
3195
{
 
3196
        ut_ad(thr);
 
3197
 
 
3198
        mutex_enter(&kernel_mutex);
 
3199
 
 
3200
        UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
 
3201
 
 
3202
        srv_release_threads(SRV_WORKER, 1);
 
3203
 
 
3204
        mutex_exit(&kernel_mutex);
 
3205
}