~drizzle-trunk/drizzle/development

641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1
/*****************************************************************************
2
1819.5.221 by vasil
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6749 from MySQL InnoDB
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
4
Copyright (c) 2008, 2009 Google Inc.
1819.5.180 by calvin
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6533 from MySQL InnoDB
5
Copyright (c) 2009, Percona Inc.
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
6
7
Portions of this file contain modifications contributed and copyrighted by
8
Google, Inc. Those modifications are gratefully acknowledged and are described
9
briefly in the InnoDB documentation. The contributions by Google are
10
incorporated with their permission, and subject to the conditions contained in
11
the file COPYING.Google.
12
1819.5.180 by calvin
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6533 from MySQL InnoDB
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
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
20
This program is free software; you can redistribute it and/or modify it under
21
the terms of the GNU General Public License as published by the Free Software
22
Foundation; version 2 of the License.
23
24
This program is distributed in the hope that it will be useful, but WITHOUT
25
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
26
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
27
28
You should have received a copy of the GNU General Public License along with
1802.10.2 by Monty Taylor
Update all of the copyright headers to include the correct address.
29
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
30
St, Fifth Floor, Boston, MA 02110-1301 USA
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
31
32
*****************************************************************************/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
33
34
/**************************************************//**
35
@file srv/srv0srv.c
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
36
The database server main program
37
38
NOTE: SQL Server 7 uses something which the documentation
39
calls user mode scheduled threads (UMS threads). One such
40
thread is usually allocated per processor. Win32
41
documentation does not know any UMS threads, which suggests
42
that the concept is internal to SQL Server 7. It may mean that
43
SQL Server 7 does all the scheduling of threads itself, even
44
in i/o waits. We should maybe modify InnoDB to use the same
45
technique, because thread switches within NT may be too slow.
46
47
SQL Server 7 also mentions fibers, which are cooperatively
48
scheduled threads. They can boost performance by 5 %,
49
according to the Delaney and Soukup's book.
50
51
Windows 2000 will have something called thread pooling
52
(see msdn website), which we could possibly use.
53
54
Another possibility could be to use some very fast user space
55
thread library. This might confuse NT though.
56
57
Created 10/8/1995 Heikki Tuuri
58
*******************************************************/
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
59
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
60
/* Dummy comment */
61
#include "srv0srv.h"
62
63
#include "ut0mem.h"
64
#include "ut0ut.h"
65
#include "os0proc.h"
66
#include "mem0mem.h"
67
#include "mem0pool.h"
68
#include "sync0sync.h"
69
#include "thr0loc.h"
70
#include "que0que.h"
71
#include "log0recv.h"
72
#include "pars0pars.h"
73
#include "usr0sess.h"
74
#include "lock0lock.h"
75
#include "trx0purge.h"
76
#include "ibuf0ibuf.h"
77
#include "buf0flu.h"
78
#include "buf0lru.h"
79
#include "btr0sea.h"
80
#include "dict0load.h"
81
#include "dict0boot.h"
82
#include "srv0start.h"
83
#include "row0mysql.h"
84
#include "ha_prototypes.h"
85
#include "trx0i_s.h"
1819.5.54 by stewart at flamingspork
[patch 054/129] Merge patch for revision 1845 from InnoDB SVN:
86
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
87
88
/* This is set to TRUE if the MySQL user has set it in MySQL; currently
89
affects only FOREIGN KEY definition parsing */
90
UNIV_INTERN ibool	srv_lower_case_table_names	= FALSE;
91
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
92
/* The following counter is incremented whenever there is some user activity
93
in the server */
94
UNIV_INTERN ulint	srv_activity_count	= 0;
95
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
96
/* The following is the maximum allowed duration of a lock wait. */
97
UNIV_INTERN ulint	srv_fatal_semaphore_wait_threshold = 600;
98
99
/* How much data manipulation language (DML) statements need to be delayed,
100
in microseconds, in order to reduce the lagging of the purge thread. */
101
UNIV_INTERN ulint	srv_dml_needed_delay = 0;
102
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
103
UNIV_INTERN ibool	srv_lock_timeout_active = FALSE;
104
UNIV_INTERN ibool	srv_monitor_active = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
105
UNIV_INTERN ibool	srv_error_monitor_active = FALSE;
106
107
UNIV_INTERN const char*	srv_main_thread_op_info = "";
108
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
109
/** Prefix used by MySQL to indicate pre-5.1 table name encoding */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
110
UNIV_INTERN const char	srv_mysql50_table_name_prefix[9] = "#mysql50#";
111
112
/* Server parameters which are read from the initfile */
113
114
/* The following three are dir paths which are catenated before file
115
names, where the file name itself may also contain a path */
116
117
UNIV_INTERN char*	srv_data_home	= NULL;
118
#ifdef UNIV_LOG_ARCHIVE
119
UNIV_INTERN char*	srv_arch_dir	= NULL;
120
#endif /* UNIV_LOG_ARCHIVE */
121
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
122
/** store to its own file each table created by an user; data
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
123
dictionary tables are in the system tablespace 0 */
124
UNIV_INTERN my_bool	srv_file_per_table;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
125
/** The file format to use on new *.ibd files. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
126
UNIV_INTERN ulint	srv_file_format = 0;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
127
/** Whether to check file format during startup.  A value of
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
128
DICT_TF_FORMAT_MAX + 1 means no checking ie. FALSE.  The default is to
129
set it to the highest format we support. */
1819.7.175 by Jimmy Yang, Stewart Smith
Merge Revision revid:jimmy.yang@oracle.com-20100617091353-5zga8o5hxpi0l15q from MySQL InnoDB
130
UNIV_INTERN ulint	srv_max_file_format_at_startup = DICT_TF_FORMAT_MAX;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
131
132
#if DICT_TF_FORMAT_51
133
# error "DICT_TF_FORMAT_51 must be 0!"
134
#endif
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
135
/** Place locks to records only i.e. do not use next-key locking except
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
136
on duplicate key checking and foreign key checking */
137
UNIV_INTERN ibool	srv_locks_unsafe_for_binlog = FALSE;
138
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
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
1819.9.44 by Calvin Sun, Stewart Smith
Merge Revision revid:calvin.sun@oracle.com-20100720204231-h3nw0d9q3h79krr4 from MySQL InnoDB
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
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
160
UNIV_INTERN ulint	srv_n_data_files = 0;
161
UNIV_INTERN char**	srv_data_file_names = NULL;
162
/* size in database pages */
163
UNIV_INTERN ulint*	srv_data_file_sizes = NULL;
164
165
/* if TRUE, then we auto-extend the last data file */
166
UNIV_INTERN ibool	srv_auto_extend_last_data_file	= FALSE;
167
/* if != 0, this tells the max size auto-extending may increase the
168
last data file size */
169
UNIV_INTERN ulint	srv_last_file_size_max	= 0;
170
/* If the last data file is auto-extended, we add this
171
many pages to it at a time */
937.3.4 by Stewart Smith
fix innodb_autoextend_increment for sparc
172
UNIV_INTERN unsigned int srv_auto_extend_increment = 8;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
173
UNIV_INTERN ulint*	srv_data_file_is_raw_partition = NULL;
174
175
/* If the following is TRUE we do not allow inserts etc. This protects
176
the user from forgetting the 'newraw' keyword to my.cnf */
177
178
UNIV_INTERN ibool	srv_created_new_raw	= FALSE;
179
180
UNIV_INTERN char**	srv_log_group_home_dirs = NULL;
181
182
UNIV_INTERN ulint	srv_n_log_groups	= ULINT_MAX;
183
UNIV_INTERN ulint	srv_n_log_files		= ULINT_MAX;
184
/* size in database pages */
185
UNIV_INTERN ulint	srv_log_file_size	= ULINT_MAX;
186
/* size in database pages */
187
UNIV_INTERN ulint	srv_log_buffer_size	= ULINT_MAX;
188
UNIV_INTERN ulong	srv_flush_log_at_trx_commit = 1;
189
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
190
/* Try to flush dirty pages so as to avoid IO bursts at
191
the checkpoints. */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
192
UNIV_INTERN bool	srv_adaptive_flushing	= TRUE;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
193
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
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
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
205
collation */
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
206
#if defined(BUILD_DRIZZLE)
641.1.4 by Monty Taylor
Merged in InnoDB changes.
207
UNIV_INTERN const byte	srv_latin1_ordering[256]	/* The sort order table of the latin1
208
					character set. The following table is
209
					the MySQL order as of Feb 10th, 2002 */
210
= {
211
  0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07
212
, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F
213
, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
214
, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F
215
, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27
216
, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F
217
, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37
218
, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F
219
, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
220
, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
221
, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
222
, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F
223
, 0x60, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47
224
, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F
225
, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57
226
, 0x58, 0x59, 0x5A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F
227
, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87
228
, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F
229
, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97
230
, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F
231
, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7
232
, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF
233
, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7
234
, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF
235
, 0x41, 0x41, 0x41, 0x41, 0x5C, 0x5B, 0x5C, 0x43
236
, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49
237
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xD7
238
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xDF
239
, 0x41, 0x41, 0x41, 0x41, 0x5C, 0x5B, 0x5C, 0x43
240
, 0x45, 0x45, 0x45, 0x45, 0x49, 0x49, 0x49, 0x49
241
, 0x44, 0x4E, 0x4F, 0x4F, 0x4F, 0x4F, 0x5D, 0xF7
242
, 0xD8, 0x55, 0x55, 0x55, 0x59, 0x59, 0xDE, 0xFF
243
};
1114.1.1 by Monty Taylor
Merged InnoDB Plugin 1.0.4
244
#else
245
UNIV_INTERN const byte*        srv_latin1_ordering;
246
#endif /* BUILD_DRIZZLE */
641.1.4 by Monty Taylor
Merged in InnoDB changes.
247
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
248
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
249
/* use os/external memory allocator */
250
UNIV_INTERN my_bool	srv_use_sys_malloc	= TRUE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
251
/* requested size in kilobytes */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
252
UNIV_INTERN ulint	srv_buf_pool_size	= ULINT_MAX;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
253
/* requested number of buffer pool instances */
254
UNIV_INTERN ulint       srv_buf_pool_instances  = 1;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
255
/* previously requested size */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
256
UNIV_INTERN ulint	srv_buf_pool_old_size;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
257
/* current size in kilobytes */
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
258
UNIV_INTERN ulint	srv_buf_pool_curr_size	= 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
259
/* size in bytes */
260
UNIV_INTERN ulint	srv_mem_pool_size	= ULINT_MAX;
261
UNIV_INTERN ulint	srv_lock_table_size	= ULINT_MAX;
262
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
263
/* This parameter is deprecated. Use srv_n_io_[read|write]_threads
264
instead. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
265
UNIV_INTERN ulint	srv_n_file_io_threads	= ULINT_MAX;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
266
UNIV_INTERN ulint	srv_n_read_io_threads	= ULINT_MAX;
267
UNIV_INTERN ulint	srv_n_write_io_threads	= ULINT_MAX;
268
269
/* User settable value of the number of pages that must be present
270
in the buffer cache and accessed sequentially for InnoDB to trigger a
271
readahead request. */
272
UNIV_INTERN ulong	srv_read_ahead_threshold	= 56;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
273
274
#ifdef UNIV_LOG_ARCHIVE
275
UNIV_INTERN ibool		srv_log_archive_on	= FALSE;
276
UNIV_INTERN ibool		srv_archive_recovery	= 0;
277
UNIV_INTERN ib_uint64_t	srv_archive_recovery_limit_lsn;
278
#endif /* UNIV_LOG_ARCHIVE */
279
280
/* This parameter is used to throttle the number of insert buffers that are
281
merged in a batch. By increasing this parameter on a faster disk you can
282
possibly reduce the number of I/O operations performed to complete the
283
merge operation. The value of this parameter is used as is by the
284
background loop when the system is idle (low load), on a busy system
285
the parameter is scaled down by a factor of 4, this is to avoid putting
286
a heavier load on the I/O sub system. */
287
288
UNIV_INTERN ulong	srv_insert_buffer_batch_size = 20;
289
290
UNIV_INTERN char*	srv_file_flush_method_str = NULL;
291
UNIV_INTERN ulint	srv_unix_file_flush_method = SRV_UNIX_FSYNC;
292
UNIV_INTERN ulint	srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
293
294
UNIV_INTERN ulint	srv_max_n_open_files	  = 300;
295
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
296
/* Number of IO operations per second the server can do */
297
UNIV_INTERN ulong	srv_io_capacity         = 200;
298
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
299
/* The InnoDB main thread tries to keep the ratio of modified pages
300
in the buffer pool to all database pages in the buffer pool smaller than
301
the following number. But it is not guaranteed that the value stays below
302
that during a time of heavy update/insert activity. */
303
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
304
UNIV_INTERN ulong	srv_max_buf_pool_modified_pct	= 75;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
305
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
306
/* the number of purge threads to use from the worker pool (currently 0 or 1).*/
1819.7.97 by Calvin Sun
Merge Revision revid:calvin.sun@oracle.com-20100507214030-cap6783iuooqrxkx from MySQL InnoDB
307
UNIV_INTERN ulong srv_n_purge_threads = 0;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
308
309
/* the number of records to purge in one batch */
1819.7.97 by Calvin Sun
Merge Revision revid:calvin.sun@oracle.com-20100507214030-cap6783iuooqrxkx from MySQL InnoDB
310
UNIV_INTERN ulong srv_purge_batch_size = 20;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
311
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
312
/* variable counts amount of data read in total (in bytes) */
313
UNIV_INTERN ulint srv_data_read = 0;
314
315
/* here we count the amount of data written in total (in bytes) */
316
UNIV_INTERN ulint srv_data_written = 0;
317
318
/* the number of the log write requests done */
319
UNIV_INTERN ulint srv_log_write_requests = 0;
320
321
/* the number of physical writes to the log performed */
322
UNIV_INTERN ulint srv_log_writes = 0;
323
324
/* amount of data written to the log files in bytes */
325
UNIV_INTERN ulint srv_os_log_written = 0;
326
327
/* amount of writes being done to the log files */
328
UNIV_INTERN ulint srv_os_log_pending_writes = 0;
329
330
/* we increase this counter, when there we don't have enough space in the
331
log buffer and have to flush it */
332
UNIV_INTERN ulint srv_log_waits = 0;
333
334
/* this variable counts the amount of times, when the doublewrite buffer
335
was flushed */
336
UNIV_INTERN ulint srv_dblwr_writes = 0;
337
338
/* here we store the number of pages that have been flushed to the
339
doublewrite buffer */
340
UNIV_INTERN ulint srv_dblwr_pages_written = 0;
341
342
/* in this variable we store the number of write requests issued */
343
UNIV_INTERN ulint srv_buf_pool_write_requests = 0;
344
345
/* here we store the number of times when we had to wait for a free page
346
in the buffer pool. It happens when the buffer pool is full and we need
347
to make a flush, in order to be able to read or create a page. */
348
UNIV_INTERN ulint srv_buf_pool_wait_free = 0;
349
350
/* variable to count the number of pages that were written from buffer
351
pool to the disk */
352
UNIV_INTERN ulint srv_buf_pool_flushed = 0;
353
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
354
/** Number of buffer pool reads that led to the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
355
reading of a disk page */
356
UNIV_INTERN ulint srv_buf_pool_reads = 0;
357
358
/* structure to pass status variables to MySQL */
359
UNIV_INTERN export_struc export_vars;
360
361
/* If the following is != 0 we do not allow inserts etc. This protects
362
the user from forgetting the innodb_force_recovery keyword to my.cnf */
363
364
UNIV_INTERN ulint	srv_force_recovery	= 0;
365
/*-----------------------*/
366
/* We are prepared for a situation that we have this many threads waiting for
367
a semaphore inside InnoDB. innobase_start_or_create_for_mysql() sets the
368
value. */
369
370
UNIV_INTERN ulint	srv_max_n_threads	= 0;
371
372
/* The following controls how many threads we let inside InnoDB concurrently:
373
threads waiting for locks are not counted into the number because otherwise
374
we could get a deadlock. MySQL creates a thread for each user session, and
375
semaphore contention and convoy problems can occur withput this restriction.
376
Value 10 should be good if there are less than 4 processors + 4 disks in the
377
computer. Bigger computers need bigger values. Value 0 will disable the
378
concurrency check. */
379
380
UNIV_INTERN ulong	srv_thread_concurrency	= 0;
381
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
382
/* this mutex protects srv_conc data structures */
383
UNIV_INTERN os_fast_mutex_t	srv_conc_mutex;
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
384
/* number of transactions that have declared_to_be_inside_innodb set.
385
It used to be a non-error for this value to drop below zero temporarily.
386
This is no longer true. We'll, however, keep the lint datatype to add
387
assertions to catch any corner cases that we may have missed. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
388
UNIV_INTERN lint	srv_conc_n_threads	= 0;
389
/* number of OS threads waiting in the FIFO for a permission to enter
390
InnoDB */
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
391
UNIV_INTERN ulint	srv_conc_n_waiting_threads = 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
392
393
typedef struct srv_conc_slot_struct	srv_conc_slot_t;
394
struct srv_conc_slot_struct{
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
395
	os_event_t			event;		/*!< event to wait */
396
	ibool				reserved;	/*!< TRUE if slot
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
397
							reserved */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
398
	ibool				wait_ended;	/*!< TRUE when another
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
399
							thread has already set
400
							the event and the
401
							thread in this slot is
402
							free to proceed; but
403
							reserved may still be
404
							TRUE at that point */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
405
	UT_LIST_NODE_T(srv_conc_slot_t)	srv_conc_queue;	/*!< queue node */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
406
};
407
408
/* queue of threads waiting to get in */
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
409
UNIV_INTERN UT_LIST_BASE_NODE_T(srv_conc_slot_t)	srv_conc_queue;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
410
/* array of wait slots */
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
411
UNIV_INTERN srv_conc_slot_t* srv_conc_slots;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
412
413
/* Number of times a thread is allowed to enter InnoDB within the same
414
SQL query after it has once got the ticket at srv_conc_enter_innodb */
415
#define SRV_FREE_TICKETS_TO_ENTER srv_n_free_tickets_to_enter
416
#define SRV_THREAD_SLEEP_DELAY srv_thread_sleep_delay
417
/*-----------------------*/
418
/* If the following is set to 1 then we do not run purge and insert buffer
419
merge to completion before shutdown. If it is set to 2, do not even flush the
420
buffer pool to data files at the shutdown: we effectively 'crash'
421
InnoDB (but lose no committed transactions). */
422
UNIV_INTERN ulint	srv_fast_shutdown	= 0;
423
424
/* Generate a innodb_status.<pid> file */
425
UNIV_INTERN ibool	srv_innodb_status	= FALSE;
426
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
427
/* When estimating number of different key values in an index, sample
428
this many index pages */
641.3.9 by Monty Taylor
More removal of my_malloc.
429
UNIV_INTERN ib_uint64_t	srv_stats_sample_pages = 8;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
430
431
UNIV_INTERN ibool	srv_use_doublewrite_buf	= TRUE;
432
UNIV_INTERN ibool	srv_use_checksums = TRUE;
433
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
434
UNIV_INTERN ulong	srv_replication_delay		= 0;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
435
436
/*-------------------------------------------*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
437
UNIV_INTERN ulong	srv_n_spin_wait_rounds	= 30;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
438
UNIV_INTERN ulong	srv_n_free_tickets_to_enter = 500;
439
UNIV_INTERN ulong	srv_thread_sleep_delay = 10000;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
440
UNIV_INTERN ulong	srv_spin_wait_delay	= 6;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
441
UNIV_INTERN ibool	srv_priority_boost	= TRUE;
442
443
#ifdef UNIV_DEBUG
444
UNIV_INTERN ibool	srv_print_thread_releases	= FALSE;
445
UNIV_INTERN ibool	srv_print_lock_waits		= FALSE;
446
UNIV_INTERN ibool	srv_print_buf_io		= FALSE;
447
UNIV_INTERN ibool	srv_print_log_io		= FALSE;
448
UNIV_INTERN ibool	srv_print_latch_waits		= FALSE;
449
#endif /* UNIV_DEBUG */
450
451
UNIV_INTERN ulint		srv_n_rows_inserted		= 0;
452
UNIV_INTERN ulint		srv_n_rows_updated		= 0;
453
UNIV_INTERN ulint		srv_n_rows_deleted		= 0;
454
UNIV_INTERN ulint		srv_n_rows_read			= 0;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
455
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
456
static ulint	srv_n_rows_inserted_old		= 0;
457
static ulint	srv_n_rows_updated_old		= 0;
458
static ulint	srv_n_rows_deleted_old		= 0;
459
static ulint	srv_n_rows_read_old		= 0;
460
461
UNIV_INTERN ulint		srv_n_lock_wait_count		= 0;
462
UNIV_INTERN ulint		srv_n_lock_wait_current_count	= 0;
463
UNIV_INTERN ib_int64_t	srv_n_lock_wait_time		= 0;
464
UNIV_INTERN ulint		srv_n_lock_max_wait_time	= 0;
465
466
467
/*
468
  Set the following to 0 if you want InnoDB to write messages on
469
  stderr on startup/shutdown
470
*/
471
UNIV_INTERN ibool	srv_print_verbose_log		= TRUE;
472
UNIV_INTERN ibool	srv_print_innodb_monitor	= FALSE;
473
UNIV_INTERN ibool	srv_print_innodb_lock_monitor	= FALSE;
474
UNIV_INTERN ibool	srv_print_innodb_tablespace_monitor = FALSE;
475
UNIV_INTERN ibool	srv_print_innodb_table_monitor = FALSE;
476
477
/* Array of English strings describing the current state of an
478
i/o handler thread */
479
480
UNIV_INTERN const char* srv_io_thread_op_info[SRV_MAX_N_IO_THREADS];
481
UNIV_INTERN const char* srv_io_thread_function[SRV_MAX_N_IO_THREADS];
482
483
UNIV_INTERN time_t	srv_last_monitor_time;
484
485
UNIV_INTERN mutex_t	srv_innodb_monitor_mutex;
486
487
/* Mutex for locking srv_monitor_file */
488
UNIV_INTERN mutex_t	srv_monitor_file_mutex;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
489
490
#ifdef UNIV_PFS_MUTEX
491
/* Key to register kernel_mutex with performance schema */
492
UNIV_INTERN mysql_pfs_key_t	kernel_mutex_key;
493
/* Key to register srv_innodb_monitor_mutex with performance schema */
494
UNIV_INTERN mysql_pfs_key_t	srv_innodb_monitor_mutex_key;
495
/* Key to register srv_monitor_file_mutex with performance schema */
496
UNIV_INTERN mysql_pfs_key_t	srv_monitor_file_mutex_key;
497
/* Key to register srv_dict_tmpfile_mutex with performance schema */
498
UNIV_INTERN mysql_pfs_key_t	srv_dict_tmpfile_mutex_key;
499
/* Key to register the mutex with performance schema */
500
UNIV_INTERN mysql_pfs_key_t	srv_misc_tmpfile_mutex_key;
501
#endif /* UNIV_PFS_MUTEX */
502
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
503
/* Temporary file for innodb monitor output */
504
UNIV_INTERN FILE*	srv_monitor_file;
505
/* Mutex for locking srv_dict_tmpfile.
506
This mutex has a very high rank; threads reserving it should not
507
be holding any InnoDB latches. */
508
UNIV_INTERN mutex_t	srv_dict_tmpfile_mutex;
509
/* Temporary file for output from the data dictionary */
510
UNIV_INTERN FILE*	srv_dict_tmpfile;
511
/* Mutex for locking srv_misc_tmpfile.
512
This mutex has a very low rank; threads reserving it should not
513
acquire any further latches or sleep before releasing this one. */
514
UNIV_INTERN mutex_t	srv_misc_tmpfile_mutex;
515
/* Temporary file for miscellanous diagnostic output */
516
UNIV_INTERN FILE*	srv_misc_tmpfile;
517
518
UNIV_INTERN ulint	srv_main_thread_process_no	= 0;
519
UNIV_INTERN ulint	srv_main_thread_id		= 0;
520
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
521
/* The following count work done by srv_master_thread. */
522
523
/* Iterations by the 'once per second' loop. */
524
static ulint   srv_main_1_second_loops		= 0;
525
/* Calls to sleep by the 'once per second' loop. */
526
static ulint   srv_main_sleeps			= 0;
527
/* Iterations by the 'once per 10 seconds' loop. */
528
static ulint   srv_main_10_second_loops		= 0;
529
/* Iterations of the loop bounded by the 'background_loop' label. */
530
static ulint   srv_main_background_loops	= 0;
531
/* Iterations of the loop bounded by the 'flush_loop' label. */
532
static ulint   srv_main_flush_loops		= 0;
533
/* Log writes involving flush. */
534
static ulint   srv_log_writes_and_flush		= 0;
535
536
/* This is only ever touched by the master thread. It records the
537
time when the last flush of log file has happened. The master
538
thread ensures that we flush the log files at least once per
539
second. */
540
static time_t	srv_last_log_flush_time;
541
542
/* The master thread performs various tasks based on the current
543
state of IO activity and the level of IO utilization is past
544
intervals. Following macros define thresholds for these conditions. */
545
#define SRV_PEND_IO_THRESHOLD	(PCT_IO(3))
546
#define SRV_RECENT_IO_ACTIVITY	(PCT_IO(5))
547
#define SRV_PAST_IO_ACTIVITY	(PCT_IO(200))
548
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
549
/*
550
	IMPLEMENTATION OF THE SERVER MAIN PROGRAM
551
	=========================================
552
553
There is the following analogue between this database
554
server and an operating system kernel:
555
556
DB concept			equivalent OS concept
557
----------			---------------------
558
transaction		--	process;
559
560
query thread		--	thread;
561
562
lock			--	semaphore;
563
564
transaction set to
565
the rollback state	--	kill signal delivered to a process;
566
567
kernel			--	kernel;
568
569
query thread execution:
570
(a) without kernel mutex
571
reserved		--	process executing in user mode;
572
(b) with kernel mutex reserved
573
			--	process executing in kernel mode;
574
575
The server is controlled by a master thread which runs at
576
a priority higher than normal, that is, higher than user threads.
577
It sleeps most of the time, and wakes up, say, every 300 milliseconds,
578
to check whether there is anything happening in the server which
579
requires intervention of the master thread. Such situations may be,
580
for example, when flushing of dirty blocks is needed in the buffer
581
pool or old version of database rows have to be cleaned away.
582
583
The threads which we call user threads serve the queries of
584
the clients and input from the console of the server.
585
They run at normal priority. The server may have several
586
communications endpoints. A dedicated set of user threads waits
587
at each of these endpoints ready to receive a client request.
588
Each request is taken by a single user thread, which then starts
589
processing and, when the result is ready, sends it to the client
590
and returns to wait at the same endpoint the thread started from.
591
592
So, we do not have dedicated communication threads listening at
593
the endpoints and dealing the jobs to dedicated worker threads.
594
Our architecture saves one thread swithch per request, compared
595
to the solution with dedicated communication threads
596
which amounts to 15 microseconds on 100 MHz Pentium
597
running NT. If the client
598
is communicating over a network, this saving is negligible, but
599
if the client resides in the same machine, maybe in an SMP machine
600
on a different processor from the server thread, the saving
601
can be important as the threads can communicate over shared
602
memory with an overhead of a few microseconds.
603
604
We may later implement a dedicated communication thread solution
605
for those endpoints which communicate over a network.
606
607
Our solution with user threads has two problems: for each endpoint
608
there has to be a number of listening threads. If there are many
609
communication endpoints, it may be difficult to set the right number
610
of concurrent threads in the system, as many of the threads
611
may always be waiting at less busy endpoints. Another problem
612
is queuing of the messages, as the server internally does not
613
offer any queue for jobs.
614
615
Another group of user threads is intended for splitting the
616
queries and processing them in parallel. Let us call these
617
parallel communication threads. These threads are waiting for
618
parallelized tasks, suspended on event semaphores.
619
620
A single user thread waits for input from the console,
621
like a command to shut the database.
622
623
Utility threads are a different group of threads which takes
624
care of the buffer pool flushing and other, mainly background
625
operations, in the server.
626
Some of these utility threads always run at a lower than normal
627
priority, so that they are always in background. Some of them
628
may dynamically boost their priority by the pri_adjust function,
629
even to higher than normal priority, if their task becomes urgent.
630
The running of utilities is controlled by high- and low-water marks
631
of urgency. The urgency may be measured by the number of dirty blocks
632
in the buffer pool, in the case of the flush thread, for example.
633
When the high-water mark is exceeded, an utility starts running, until
634
the urgency drops under the low-water mark. Then the utility thread
635
suspend itself to wait for an event. The master thread is
636
responsible of signaling this event when the utility thread is
637
again needed.
638
639
For each individual type of utility, some threads always remain
640
at lower than normal priority. This is because pri_adjust is implemented
641
so that the threads at normal or higher priority control their
642
share of running time by calling sleep. Thus, if the load of the
643
system sudenly drops, these threads cannot necessarily utilize
644
the system fully. The background priority threads make up for this,
645
starting to run when the load drops.
646
647
When there is no activity in the system, also the master thread
648
suspends itself to wait for an event making
649
the server totally silent. The responsibility to signal this
650
event is on the user thread which again receives a message
651
from a client.
652
653
There is still one complication in our server design. If a
654
background utility thread obtains a resource (e.g., mutex) needed by a user
655
thread, and there is also some other user activity in the system,
656
the user thread may have to wait indefinitely long for the
657
resource, as the OS does not schedule a background thread if
658
there is some other runnable user thread. This problem is called
659
priority inversion in real-time programming.
660
661
One solution to the priority inversion problem would be to
662
keep record of which thread owns which resource and
663
in the above case boost the priority of the background thread
664
so that it will be scheduled and it can release the resource.
665
This solution is called priority inheritance in real-time programming.
666
A drawback of this solution is that the overhead of acquiring a mutex
667
increases slightly, maybe 0.2 microseconds on a 100 MHz Pentium, because
668
the thread has to call os_thread_get_curr_id.
669
This may be compared to 0.5 microsecond overhead for a mutex lock-unlock
670
pair. Note that the thread
671
cannot store the information in the resource, say mutex, itself,
672
because competing threads could wipe out the information if it is
673
stored before acquiring the mutex, and if it stored afterwards,
674
the information is outdated for the time of one machine instruction,
675
at least. (To be precise, the information could be stored to
676
lock_word in mutex if the machine supports atomic swap.)
677
678
The above solution with priority inheritance may become actual in the
679
future, but at the moment we plan to implement a more coarse solution,
680
which could be called a global priority inheritance. If a thread
681
has to wait for a long time, say 300 milliseconds, for a resource,
682
we just guess that it may be waiting for a resource owned by a background
683
thread, and boost the the priority of all runnable background threads
684
to the normal level. The background threads then themselves adjust
685
their fixed priority back to background after releasing all resources
686
they had (or, at some fixed points in their program code).
687
688
What is the performance of the global priority inheritance solution?
689
We may weigh the length of the wait time 300 milliseconds, during
690
which the system processes some other thread
691
to the cost of boosting the priority of each runnable background
692
thread, rescheduling it, and lowering the priority again.
693
On 100 MHz Pentium + NT this overhead may be of the order 100
694
microseconds per thread. So, if the number of runnable background
695
threads is not very big, say < 100, the cost is tolerable.
696
Utility threads probably will access resources used by
697
user threads not very often, so collisions of user threads
698
to preempted utility threads should not happen very often.
699
700
The thread table contains
701
information of the current status of each thread existing in the system,
702
and also the event semaphores used in suspending the master thread
703
and utility and parallel communication threads when they have nothing to do.
704
The thread table can be seen as an analogue to the process table
705
in a traditional Unix implementation.
706
707
The thread table is also used in the global priority inheritance
708
scheme. This brings in one additional complication: threads accessing
709
the thread table must have at least normal fixed priority,
710
because the priority inheritance solution does not work if a background
711
thread is preempted while possessing the mutex protecting the thread table.
712
So, if a thread accesses the thread table, its priority has to be
713
boosted at least to normal. This priority requirement can be seen similar to
714
the privileged mode used when processing the kernel calls in traditional
715
Unix.*/
716
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
717
/* Thread slot in the thread table */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
718
struct srv_slot_struct{
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
719
	os_thread_id_t	id;		/*!< thread id */
720
	os_thread_t	handle;		/*!< thread handle */
721
	unsigned	type:3;		/*!< thread type: user, utility etc. */
722
	unsigned	in_use:1;	/*!< TRUE if this slot is in use */
723
	unsigned	suspended:1;	/*!< TRUE if the thread is waiting
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
724
					for the event of this slot */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
725
	ib_time_t	suspend_time;	/*!< time when the thread was
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
726
					suspended */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
727
	os_event_t	event;		/*!< event used in suspending the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
728
					thread when it has nothing to do */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
729
	que_thr_t*	thr;		/*!< suspended query thread (only
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
730
					used for MySQL threads) */
731
};
732
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
733
/* Table for MySQL threads where they will be suspended to wait for locks */
734
UNIV_INTERN srv_slot_t*	srv_mysql_table = NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
735
736
UNIV_INTERN os_event_t	srv_lock_timeout_thread_event;
737
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
738
UNIV_INTERN srv_sys_t*	srv_sys	= NULL;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
739
740
/* padding to prevent other memory update hotspots from residing on
741
the same memory cache line */
742
UNIV_INTERN byte	srv_pad1[64];
743
/* mutex protecting the server, trx structs, query threads, and lock table */
744
UNIV_INTERN mutex_t*	kernel_mutex_temp;
745
/* padding to prevent other memory update hotspots from residing on
746
the same memory cache line */
747
UNIV_INTERN byte	srv_pad2[64];
748
749
#if 0
750
/* The following three values measure the urgency of the jobs of
751
buffer, version, and insert threads. They may vary from 0 - 1000.
752
The server mutex protects all these variables. The low-water values
753
tell that the server can acquiesce the utility when the value
754
drops below this low-water mark. */
755
756
static ulint	srv_meter[SRV_MASTER + 1];
757
static ulint	srv_meter_low_water[SRV_MASTER + 1];
758
static ulint	srv_meter_high_water[SRV_MASTER + 1];
759
static ulint	srv_meter_high_water2[SRV_MASTER + 1];
760
static ulint	srv_meter_foreground[SRV_MASTER + 1];
761
#endif
762
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
763
/***********************************************************************
764
Prints counters for work done by srv_master_thread. */
765
static
766
void
767
srv_print_master_thread_info(
768
/*=========================*/
769
	FILE  *file)    /* in: output stream */
770
{
771
	fprintf(file, "srv_master_thread loops: %lu 1_second, %lu sleeps, "
772
		"%lu 10_second, %lu background, %lu flush\n",
773
		srv_main_1_second_loops, srv_main_sleeps,
774
		srv_main_10_second_loops, srv_main_background_loops,
775
		srv_main_flush_loops);
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
776
	fprintf(file, "srv_master_thread log flush and writes: %lu\n",
777
		      srv_log_writes_and_flush);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
778
}
779
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
780
/* The following values give info about the activity going on in
781
the database. They are protected by the server mutex. The arrays
782
are indexed by the type of the thread. */
783
784
UNIV_INTERN ulint	srv_n_threads_active[SRV_MASTER + 1];
785
UNIV_INTERN ulint	srv_n_threads[SRV_MASTER + 1];
786
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
787
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
788
Sets the info describing an i/o thread current state. */
789
UNIV_INTERN
790
void
791
srv_set_io_thread_op_info(
792
/*======================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
793
	ulint		i,	/*!< in: the 'segment' of the i/o thread */
794
	const char*	str)	/*!< in: constant char string describing the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
795
				state */
796
{
797
	ut_a(i < SRV_MAX_N_IO_THREADS);
798
799
	srv_io_thread_op_info[i] = str;
800
}
801
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
802
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
803
Accessor function to get pointer to n'th slot in the server thread
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
804
table.
805
@return	pointer to the slot */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
806
static
807
srv_slot_t*
808
srv_table_get_nth_slot(
809
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
810
	ulint	index)		/*!< in: index of the slot */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
811
{
812
	ut_a(index < OS_THREAD_MAX_N);
813
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
814
	return(srv_sys->threads + index);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
815
}
816
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
817
/*********************************************************************//**
818
Gets the number of threads in the system.
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
819
@return	sum of srv_n_threads[] */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
820
UNIV_INTERN
821
ulint
822
srv_get_n_threads(void)
823
/*===================*/
824
{
825
	ulint	i;
826
	ulint	n_threads	= 0;
827
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
828
	mutex_enter(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
829
830
	for (i = SRV_COM; i < SRV_MASTER + 1; i++) {
831
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
832
		n_threads += srv_n_threads[i];
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
833
	}
834
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
835
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
836
837
	return(n_threads);
838
}
839
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
840
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
841
Reserves a slot in the thread table for the current thread. Also creates the
842
thread local storage struct for the current thread. NOTE! The server mutex
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
843
has to be reserved by the caller!
844
@return	reserved slot index */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
845
static
846
ulint
847
srv_table_reserve_slot(
848
/*===================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
849
	enum srv_thread_type	type)	/*!< in: type of the thread */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
850
{
851
	srv_slot_t*	slot;
852
	ulint		i;
853
854
	ut_a(type > 0);
855
	ut_a(type <= SRV_MASTER);
856
857
	i = 0;
858
	slot = srv_table_get_nth_slot(i);
859
860
	while (slot->in_use) {
861
		i++;
862
		slot = srv_table_get_nth_slot(i);
863
	}
864
865
	ut_a(slot->in_use == FALSE);
866
867
	slot->in_use = TRUE;
868
	slot->suspended = FALSE;
869
	slot->type = type;
870
	slot->id = os_thread_get_curr_id();
871
	slot->handle = os_thread_get_curr();
872
873
	thr_local_create();
874
875
	thr_local_set_slot_no(os_thread_get_curr_id(), i);
876
877
	return(i);
878
}
879
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
880
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
881
Suspends the calling thread to wait for the event in its thread slot.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
882
NOTE! The server mutex has to be reserved by the caller!
883
@return	event for the calling thread to wait */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
884
static
885
os_event_t
886
srv_suspend_thread(void)
887
/*====================*/
888
{
889
	srv_slot_t*		slot;
890
	os_event_t		event;
891
	ulint			slot_no;
892
	enum srv_thread_type	type;
893
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
894
	ut_ad(mutex_own(&kernel_mutex));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
895
896
	slot_no = thr_local_get_slot_no(os_thread_get_curr_id());
897
898
	if (srv_print_thread_releases) {
899
		fprintf(stderr,
900
			"Suspending thread %lu to slot %lu\n",
901
			(ulong) os_thread_get_curr_id(), (ulong) slot_no);
902
	}
903
904
	slot = srv_table_get_nth_slot(slot_no);
905
906
	type = slot->type;
907
908
	ut_ad(type >= SRV_WORKER);
909
	ut_ad(type <= SRV_MASTER);
910
911
	event = slot->event;
912
913
	slot->suspended = TRUE;
914
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
915
	ut_ad(srv_n_threads_active[type] > 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
916
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
917
	srv_n_threads_active[type]--;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
918
919
	os_event_reset(event);
920
921
	return(event);
922
}
923
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
924
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
925
Releases threads of the type given from suspension in the thread table.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
926
NOTE! The server mutex has to be reserved by the caller!
927
@return number of threads released: this may be less than n if not
928
enough threads were suspended at the moment */
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
929
UNIV_INTERN
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
930
ulint
931
srv_release_threads(
932
/*================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
933
	enum srv_thread_type	type,	/*!< in: thread type */
934
	ulint			n)	/*!< in: number of threads to release */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
935
{
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
936
	srv_slot_t*	slot;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
937
	ulint		i;
938
	ulint		count	= 0;
939
940
	ut_ad(type >= SRV_WORKER);
941
	ut_ad(type <= SRV_MASTER);
942
	ut_ad(n > 0);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
943
	ut_ad(mutex_own(&kernel_mutex));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
944
945
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
946
947
		slot = srv_table_get_nth_slot(i);
948
949
		if (slot->in_use && slot->type == type && slot->suspended) {
950
951
			slot->suspended = FALSE;
952
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
953
			srv_n_threads_active[type]++;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
954
955
			os_event_set(slot->event);
956
957
			if (srv_print_thread_releases) {
958
				fprintf(stderr,
959
					"Releasing thread %lu type %lu"
960
					" from slot %lu\n",
961
					(ulong) slot->id, (ulong) type,
962
					(ulong) i);
963
			}
964
965
			count++;
966
967
			if (count == n) {
968
				break;
969
			}
970
		}
971
	}
972
973
	return(count);
974
}
975
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
976
/*********************************************************************//**
977
Returns the calling thread type.
978
@return	SRV_COM, ... */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
979
UNIV_INTERN
980
enum srv_thread_type
981
srv_get_thread_type(void)
982
/*=====================*/
983
{
984
	ulint			slot_no;
985
	srv_slot_t*		slot;
986
	enum srv_thread_type	type;
987
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
988
	mutex_enter(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
989
990
	slot_no = thr_local_get_slot_no(os_thread_get_curr_id());
991
992
	slot = srv_table_get_nth_slot(slot_no);
993
994
	type = slot->type;
995
996
	ut_ad(type >= SRV_WORKER);
997
	ut_ad(type <= SRV_MASTER);
998
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
999
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1000
1001
	return(type);
1002
}
1003
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1004
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1005
Initializes the server. */
1006
UNIV_INTERN
1007
void
1008
srv_init(void)
1009
/*==========*/
1010
{
1011
	srv_conc_slot_t*	conc_slot;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1012
	srv_slot_t*		slot;
1013
	ulint			i;
1014
1015
	srv_sys = mem_alloc(sizeof(srv_sys_t));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1016
1017
	kernel_mutex_temp = mem_alloc(sizeof(mutex_t));
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1018
	mutex_create(kernel_mutex_key, &kernel_mutex, SYNC_KERNEL);
1019
1020
	mutex_create(srv_innodb_monitor_mutex_key,
1021
		     &srv_innodb_monitor_mutex, SYNC_NO_ORDER_CHECK);
1022
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1023
	srv_sys->threads = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1024
1025
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
1026
		slot = srv_table_get_nth_slot(i);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1027
		slot->in_use = FALSE;
1028
		slot->type=0;	/* Avoid purify errors */
1029
		slot->event = os_event_create(NULL);
1030
		ut_a(slot->event);
1031
	}
1032
1033
	srv_mysql_table = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_slot_t));
1034
1035
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
1036
		slot = srv_mysql_table + i;
1037
		slot->in_use = FALSE;
1038
		slot->type = 0;
1039
		slot->event = os_event_create(NULL);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1040
		ut_a(slot->event);
1041
	}
1042
1043
	srv_lock_timeout_thread_event = os_event_create(NULL);
1044
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1045
	for (i = 0; i < SRV_MASTER + 1; i++) {
1046
		srv_n_threads_active[i] = 0;
1047
		srv_n_threads[i] = 0;
1048
#if 0
1049
		srv_meter[i] = 30;
1050
		srv_meter_low_water[i] = 50;
1051
		srv_meter_high_water[i] = 100;
1052
		srv_meter_high_water2[i] = 200;
1053
		srv_meter_foreground[i] = 250;
1054
#endif
1055
	}
1056
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1057
	UT_LIST_INIT(srv_sys->tasks);
1058
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1059
	/* Create dummy indexes for infimum and supremum records */
1060
1061
	dict_ind_init();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1062
1063
	/* Init the server concurrency restriction data structures */
1064
1065
	os_fast_mutex_init(&srv_conc_mutex);
1066
1067
	UT_LIST_INIT(srv_conc_queue);
1068
1069
	srv_conc_slots = mem_alloc(OS_THREAD_MAX_N * sizeof(srv_conc_slot_t));
1070
1071
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
1072
		conc_slot = srv_conc_slots + i;
1073
		conc_slot->reserved = FALSE;
1074
		conc_slot->event = os_event_create(NULL);
1075
		ut_a(conc_slot->event);
1076
	}
1077
1078
	/* Initialize some INFORMATION SCHEMA internal structures */
1079
	trx_i_s_cache_init(trx_i_s_cache);
1080
}
1081
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1082
/*********************************************************************//**
1819.5.106 by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN:
1083
Frees the data structures created in srv_init(). */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1084
UNIV_INTERN
1085
void
1086
srv_free(void)
1087
/*==========*/
1088
{
1089
	os_fast_mutex_free(&srv_conc_mutex);
1819.5.106 by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN:
1090
	mem_free(srv_conc_slots);
1091
	srv_conc_slots = NULL;
1092
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1093
	mem_free(srv_sys->threads);
1819.5.106 by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN:
1094
	mem_free(srv_sys);
1095
	srv_sys = NULL;
1096
1097
	mem_free(kernel_mutex_temp);
1098
	kernel_mutex_temp = NULL;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1099
	mem_free(srv_mysql_table);
1100
	srv_mysql_table = NULL;
1819.5.106 by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN:
1101
1102
	trx_i_s_cache_free(trx_i_s_cache);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1103
}
1104
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1105
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1106
Initializes the synchronization primitives, memory system, and the thread
1107
local storage. */
1108
UNIV_INTERN
1109
void
1110
srv_general_init(void)
1111
/*==================*/
1112
{
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1113
	ut_mem_init();
1819.5.106 by stewart at flamingspork
[patch 106/129] Merge patch for revision 1915 from InnoDB SVN:
1114
	/* Reset the system variables in the recovery module. */
1115
	recv_sys_var_init();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1116
	os_sync_init();
1117
	sync_init();
1118
	mem_init(srv_mem_pool_size);
1119
	thr_local_init();
1120
}
1121
1122
/*======================= InnoDB Server FIFO queue =======================*/
1123
1124
/* Maximum allowable purge history length.  <=0 means 'infinite'. */
1125
UNIV_INTERN ulong	srv_max_purge_lag		= 0;
1126
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1127
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1128
Puts an OS thread to wait if there are too many concurrent threads
1129
(>= srv_thread_concurrency) inside InnoDB. The threads wait in a FIFO queue. */
1130
UNIV_INTERN
1131
void
1132
srv_conc_enter_innodb(
1133
/*==================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1134
	trx_t*	trx)	/*!< in: transaction object associated with the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1135
			thread */
1136
{
1137
	ibool			has_slept = FALSE;
1138
	srv_conc_slot_t*	slot	  = NULL;
1139
	ulint			i;
1140
1141
	if (trx->mysql_thd != NULL
1142
	    && thd_is_replication_slave_thread(trx->mysql_thd)) {
1143
1144
		UT_WAIT_FOR(srv_conc_n_threads
1145
			    < (lint)srv_thread_concurrency,
1146
			    srv_replication_delay * 1000);
1147
1148
		return;
1149
	}
1150
1151
	/* If trx has 'free tickets' to enter the engine left, then use one
1152
	such ticket */
1153
1154
	if (trx->n_tickets_to_enter_innodb > 0) {
1155
		trx->n_tickets_to_enter_innodb--;
1156
1157
		return;
1158
	}
1159
1160
	os_fast_mutex_lock(&srv_conc_mutex);
1161
retry:
1162
	if (trx->declared_to_be_inside_innodb) {
1163
		ut_print_timestamp(stderr);
1164
		fputs("  InnoDB: Error: trying to declare trx"
1165
		      " to enter InnoDB, but\n"
1166
		      "InnoDB: it already is declared.\n", stderr);
1167
		trx_print(stderr, trx, 0);
1168
		putc('\n', stderr);
1169
		os_fast_mutex_unlock(&srv_conc_mutex);
1170
1171
		return;
1172
	}
1173
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1174
	ut_ad(srv_conc_n_threads >= 0);
1175
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1176
	if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
1177
1178
		srv_conc_n_threads++;
1179
		trx->declared_to_be_inside_innodb = TRUE;
1180
		trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
1181
1182
		os_fast_mutex_unlock(&srv_conc_mutex);
1183
1184
		return;
1185
	}
1186
1187
	/* If the transaction is not holding resources, let it sleep
1188
	for SRV_THREAD_SLEEP_DELAY microseconds, and try again then */
1189
1190
	if (!has_slept && !trx->has_search_latch
1191
	    && NULL == UT_LIST_GET_FIRST(trx->trx_locks)) {
1192
1193
		has_slept = TRUE; /* We let it sleep only once to avoid
1194
				  starvation */
1195
1196
		srv_conc_n_waiting_threads++;
1197
1198
		os_fast_mutex_unlock(&srv_conc_mutex);
1199
1200
		trx->op_info = "sleeping before joining InnoDB queue";
1201
1202
		/* Peter Zaitsev suggested that we take the sleep away
1203
		altogether. But the sleep may be good in pathological
1204
		situations of lots of thread switches. Simply put some
1205
		threads aside for a while to reduce the number of thread
1206
		switches. */
1207
		if (SRV_THREAD_SLEEP_DELAY > 0) {
1208
			os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
1209
		}
1210
1211
		trx->op_info = "";
1212
1213
		os_fast_mutex_lock(&srv_conc_mutex);
1214
1215
		srv_conc_n_waiting_threads--;
1216
1217
		goto retry;
1218
	}
1219
1220
	/* Too many threads inside: put the current thread to a queue */
1221
1222
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
1223
		slot = srv_conc_slots + i;
1224
1225
		if (!slot->reserved) {
1226
1227
			break;
1228
		}
1229
	}
1230
1231
	if (i == OS_THREAD_MAX_N) {
1232
		/* Could not find a free wait slot, we must let the
1233
		thread enter */
1234
1235
		srv_conc_n_threads++;
1236
		trx->declared_to_be_inside_innodb = TRUE;
1237
		trx->n_tickets_to_enter_innodb = 0;
1238
1239
		os_fast_mutex_unlock(&srv_conc_mutex);
1240
1241
		return;
1242
	}
1243
1244
	/* Release possible search system latch this thread has */
1245
	if (trx->has_search_latch) {
1246
		trx_search_latch_release_if_reserved(trx);
1247
	}
1248
1249
	/* Add to the queue */
1250
	slot->reserved = TRUE;
1251
	slot->wait_ended = FALSE;
1252
1253
	UT_LIST_ADD_LAST(srv_conc_queue, srv_conc_queue, slot);
1254
1255
	os_event_reset(slot->event);
1256
1257
	srv_conc_n_waiting_threads++;
1258
1259
	os_fast_mutex_unlock(&srv_conc_mutex);
1260
1261
	/* Go to wait for the event; when a thread leaves InnoDB it will
1262
	release this thread */
1263
1264
	trx->op_info = "waiting in InnoDB queue";
1265
1266
	os_event_wait(slot->event);
1267
1268
	trx->op_info = "";
1269
1270
	os_fast_mutex_lock(&srv_conc_mutex);
1271
1272
	srv_conc_n_waiting_threads--;
1273
1274
	/* NOTE that the thread which released this thread already
1275
	incremented the thread counter on behalf of this thread */
1276
1277
	slot->reserved = FALSE;
1278
1279
	UT_LIST_REMOVE(srv_conc_queue, srv_conc_queue, slot);
1280
1281
	trx->declared_to_be_inside_innodb = TRUE;
1282
	trx->n_tickets_to_enter_innodb = SRV_FREE_TICKETS_TO_ENTER;
1283
1284
	os_fast_mutex_unlock(&srv_conc_mutex);
1285
}
1286
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1287
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1288
This lets a thread enter InnoDB regardless of the number of threads inside
1289
InnoDB. This must be called when a thread ends a lock wait. */
1290
UNIV_INTERN
1291
void
1292
srv_conc_force_enter_innodb(
1293
/*========================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1294
	trx_t*	trx)	/*!< in: transaction object associated with the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1295
			thread */
1296
{
1297
	if (UNIV_LIKELY(!srv_thread_concurrency)) {
1298
1299
		return;
1300
	}
1301
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1302
	ut_ad(srv_conc_n_threads >= 0);
1303
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1304
	os_fast_mutex_lock(&srv_conc_mutex);
1305
1306
	srv_conc_n_threads++;
1307
	trx->declared_to_be_inside_innodb = TRUE;
1308
	trx->n_tickets_to_enter_innodb = 1;
1309
1310
	os_fast_mutex_unlock(&srv_conc_mutex);
1311
}
1312
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1313
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1314
This must be called when a thread exits InnoDB in a lock wait or at the
1315
end of an SQL statement. */
1316
UNIV_INTERN
1317
void
1318
srv_conc_force_exit_innodb(
1319
/*=======================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1320
	trx_t*	trx)	/*!< in: transaction object associated with the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1321
			thread */
1322
{
1323
	srv_conc_slot_t*	slot	= NULL;
1324
1325
	if (trx->mysql_thd != NULL
1326
	    && thd_is_replication_slave_thread(trx->mysql_thd)) {
1327
1328
		return;
1329
	}
1330
1331
	if (trx->declared_to_be_inside_innodb == FALSE) {
1332
1333
		return;
1334
	}
1335
1336
	os_fast_mutex_lock(&srv_conc_mutex);
1337
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1338
	ut_ad(srv_conc_n_threads > 0);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1339
	srv_conc_n_threads--;
1340
	trx->declared_to_be_inside_innodb = FALSE;
1341
	trx->n_tickets_to_enter_innodb = 0;
1342
1343
	if (srv_conc_n_threads < (lint)srv_thread_concurrency) {
1344
		/* Look for a slot where a thread is waiting and no other
1345
		thread has yet released the thread */
1346
1347
		slot = UT_LIST_GET_FIRST(srv_conc_queue);
1348
1349
		while (slot && slot->wait_ended == TRUE) {
1350
			slot = UT_LIST_GET_NEXT(srv_conc_queue, slot);
1351
		}
1352
1353
		if (slot != NULL) {
1354
			slot->wait_ended = TRUE;
1355
1356
			/* We increment the count on behalf of the released
1357
			thread */
1358
1359
			srv_conc_n_threads++;
1360
		}
1361
	}
1362
1363
	os_fast_mutex_unlock(&srv_conc_mutex);
1364
1365
	if (slot != NULL) {
1366
		os_event_set(slot->event);
1367
	}
1368
}
1369
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1370
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1371
This must be called when a thread exits InnoDB. */
1372
UNIV_INTERN
1373
void
1374
srv_conc_exit_innodb(
1375
/*=================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1376
	trx_t*	trx)	/*!< in: transaction object associated with the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1377
			thread */
1378
{
1379
	if (trx->n_tickets_to_enter_innodb > 0) {
1380
		/* We will pretend the thread is still inside InnoDB though it
1381
		now leaves the InnoDB engine. In this way we save
1382
		a lot of semaphore operations. srv_conc_force_exit_innodb is
1383
		used to declare the thread definitely outside InnoDB. It
1384
		should be called when there is a lock wait or an SQL statement
1385
		ends. */
1386
1387
		return;
1388
	}
1389
1390
	srv_conc_force_exit_innodb(trx);
1391
}
1392
1393
/*========================================================================*/
1394
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1395
/*********************************************************************//**
1396
Normalizes init parameter values to use units we use inside InnoDB.
1397
@return	DB_SUCCESS or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1398
static
1399
ulint
1400
srv_normalize_init_values(void)
1401
/*===========================*/
1402
{
1403
	ulint	n;
1404
	ulint	i;
1405
1406
	n = srv_n_data_files;
1407
1408
	for (i = 0; i < n; i++) {
1409
		srv_data_file_sizes[i] = srv_data_file_sizes[i]
1410
			* ((1024 * 1024) / UNIV_PAGE_SIZE);
1411
	}
1412
1413
	srv_last_file_size_max = srv_last_file_size_max
1414
		* ((1024 * 1024) / UNIV_PAGE_SIZE);
1415
1416
	srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE;
1417
1418
	srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
1419
1420
	srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
1421
1422
	return(DB_SUCCESS);
1423
}
1424
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1425
/*********************************************************************//**
1426
Boots the InnoDB server.
1427
@return	DB_SUCCESS or error code */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1428
UNIV_INTERN
1429
ulint
1430
srv_boot(void)
1431
/*==========*/
1432
{
1433
	ulint	err;
1434
1435
	/* Transform the init parameter values given by MySQL to
1436
	use units we use inside InnoDB: */
1437
1438
	err = srv_normalize_init_values();
1439
1440
	if (err != DB_SUCCESS) {
1441
		return(err);
1442
	}
1443
1444
	/* Initialize synchronization primitives, memory management, and thread
1445
	local storage */
1446
1447
	srv_general_init();
1448
1449
	/* Initialize this module */
1450
1451
	srv_init();
1452
1453
	return(DB_SUCCESS);
1454
}
1455
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1456
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1457
Reserves a slot in the thread table for the current MySQL OS thread.
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1458
NOTE! The kernel mutex has to be reserved by the caller!
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1459
@return	reserved slot */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1460
static
1461
srv_slot_t*
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1462
srv_table_reserve_slot_for_mysql(void)
1463
/*==================================*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1464
{
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1465
	srv_slot_t*	slot;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1466
	ulint		i;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1467
1468
	ut_ad(mutex_own(&kernel_mutex));
1469
1470
	i = 0;
1471
	slot = srv_mysql_table + i;
1472
1473
	while (slot->in_use) {
1474
		i++;
1475
1476
		if (i >= OS_THREAD_MAX_N) {
1477
1478
			ut_print_timestamp(stderr);
1479
1480
			fprintf(stderr,
1481
				"  InnoDB: There appear to be %lu MySQL"
1482
				" threads currently waiting\n"
1483
				"InnoDB: inside InnoDB, which is the"
1484
				" upper limit. Cannot continue operation.\n"
1485
				"InnoDB: We intentionally generate"
1486
				" a seg fault to print a stack trace\n"
1487
				"InnoDB: on Linux. But first we print"
1488
				" a list of waiting threads.\n", (ulong) i);
1489
1490
			for (i = 0; i < OS_THREAD_MAX_N; i++) {
1491
1492
				slot = srv_mysql_table + i;
1493
1494
				fprintf(stderr,
1495
					"Slot %lu: thread id %lu, type %lu,"
1496
					" in use %lu, susp %lu, time %lu\n",
1497
					(ulong) i,
1498
					(ulong) os_thread_pf(slot->id),
1499
					(ulong) slot->type,
1500
					(ulong) slot->in_use,
1501
					(ulong) slot->suspended,
1502
					(ulong) difftime(ut_time(),
1503
							 slot->suspend_time));
1504
			}
1505
1506
			ut_error;
1507
		}
1508
1509
		slot = srv_mysql_table + i;
1510
	}
1511
1512
	ut_a(slot->in_use == FALSE);
1513
1514
	slot->in_use = TRUE;
1515
	slot->id = os_thread_get_curr_id();
1516
	slot->handle = os_thread_get_curr();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1517
1518
	return(slot);
1519
}
1520
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1521
/***************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1522
Puts a MySQL OS thread to wait for a lock to be released. If an error
1523
occurs during the wait trx->error_state associated with thr is
1524
!= DB_SUCCESS when we return. DB_LOCK_WAIT_TIMEOUT and DB_DEADLOCK
1525
are possible errors. DB_DEADLOCK is returned if selective deadlock
1526
resolution chose this transaction as a victim. */
1527
UNIV_INTERN
1528
void
1529
srv_suspend_mysql_thread(
1530
/*=====================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1531
	que_thr_t*	thr)	/*!< in: query thread associated with the MySQL
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1532
				OS thread */
1533
{
1534
	srv_slot_t*	slot;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1535
	os_event_t	event;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1536
	double		wait_time;
1537
	trx_t*		trx;
1538
	ulint		had_dict_lock;
1539
	ibool		was_declared_inside_innodb	= FALSE;
1540
	ib_int64_t	start_time			= 0;
1541
	ib_int64_t	finish_time;
1542
	ulint		diff_time;
1543
	ulint		sec;
1544
	ulint		ms;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1545
	ulong		lock_wait_timeout;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1546
1547
	ut_ad(!mutex_own(&kernel_mutex));
1548
1549
	trx = thr_get_trx(thr);
1550
1551
	os_event_set(srv_lock_timeout_thread_event);
1552
1553
	mutex_enter(&kernel_mutex);
1554
1555
	trx->error_state = DB_SUCCESS;
1556
1557
	if (thr->state == QUE_THR_RUNNING) {
1558
1559
		ut_ad(thr->is_active == TRUE);
1560
1561
		/* The lock has already been released or this transaction
1562
		was chosen as a deadlock victim: no need to suspend */
1563
1564
		if (trx->was_chosen_as_deadlock_victim) {
1565
1566
			trx->error_state = DB_DEADLOCK;
1567
			trx->was_chosen_as_deadlock_victim = FALSE;
1568
		}
1569
1570
		mutex_exit(&kernel_mutex);
1571
1572
		return;
1573
	}
1574
1575
	ut_ad(thr->is_active == FALSE);
1576
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1577
	slot = srv_table_reserve_slot_for_mysql();
1578
1579
	event = slot->event;
1580
1581
	slot->thr = thr;
1582
1583
	os_event_reset(event);
1584
1585
	slot->suspend_time = ut_time();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1586
1587
	if (thr->lock_state == QUE_THR_LOCK_ROW) {
1588
		srv_n_lock_wait_count++;
1589
		srv_n_lock_wait_current_count++;
1590
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1591
		if (ut_usectime(&sec, &ms) == -1) {
1592
			start_time = -1;
1593
		} else {
1594
			start_time = (ib_int64_t) sec * 1000000 + ms;
1595
		}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1596
	}
1597
	/* Wake the lock timeout monitor thread, if it is suspended */
1598
1599
	os_event_set(srv_lock_timeout_thread_event);
1600
1601
	mutex_exit(&kernel_mutex);
1602
1603
	if (trx->declared_to_be_inside_innodb) {
1604
1605
		was_declared_inside_innodb = TRUE;
1606
1607
		/* We must declare this OS thread to exit InnoDB, since a
1608
		possible other thread holding a lock which this thread waits
1609
		for must be allowed to enter, sooner or later */
1610
1611
		srv_conc_force_exit_innodb(trx);
1612
	}
1613
1614
	had_dict_lock = trx->dict_operation_lock_mode;
1615
1616
	switch (had_dict_lock) {
1617
	case RW_S_LATCH:
1618
		/* Release foreign key check latch */
1619
		row_mysql_unfreeze_data_dictionary(trx);
1620
		break;
1621
	case RW_X_LATCH:
1622
		/* Release fast index creation latch */
1623
		row_mysql_unlock_data_dictionary(trx);
1624
		break;
1625
	}
1626
1627
	ut_a(trx->dict_operation_lock_mode == 0);
1628
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1629
	/* Suspend this thread and wait for the event. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1630
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1631
	os_event_wait(event);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1632
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
1633
	/* After resuming, reacquire the data dictionary latch if
1634
	necessary. */
1635
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1636
	switch (had_dict_lock) {
1637
	case RW_S_LATCH:
1638
		row_mysql_freeze_data_dictionary(trx);
1639
		break;
1640
	case RW_X_LATCH:
1641
		row_mysql_lock_data_dictionary(trx);
1642
		break;
1643
	}
1644
1645
	if (was_declared_inside_innodb) {
1646
1647
		/* Return back inside InnoDB */
1648
1649
		srv_conc_force_enter_innodb(trx);
1650
	}
1651
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1652
	mutex_enter(&kernel_mutex);
1653
1654
	/* Release the slot for others to use */
1655
1656
	slot->in_use = FALSE;
1657
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1658
	wait_time = ut_difftime(ut_time(), slot->suspend_time);
1659
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1660
	if (thr->lock_state == QUE_THR_LOCK_ROW) {
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1661
		if (ut_usectime(&sec, &ms) == -1) {
1662
			finish_time = -1;
1663
		} else {
1664
			finish_time = (ib_int64_t) sec * 1000000 + ms;
1665
		}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1666
1667
		diff_time = (ulint) (finish_time - start_time);
1668
1669
		srv_n_lock_wait_current_count--;
1670
		srv_n_lock_wait_time = srv_n_lock_wait_time + diff_time;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1671
		if (diff_time > srv_n_lock_max_wait_time &&
1672
		    /* only update the variable if we successfully
1673
		    retrieved the start and finish times. See Bug#36819. */
1674
		    start_time != -1 && finish_time != -1) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1675
			srv_n_lock_max_wait_time = diff_time;
1676
		}
1819.9.62 by Jimmy Yang, Stewart Smith
Merge Revision revid:jimmy.yang@oracle.com-20100817081924-i5vfwmvsszboeb0o from MySQL InnoDB
1677
1678
		/* Record the lock wait time for this thread */
1679
		thd_set_lock_wait_time(trx->mysql_thd, diff_time);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1680
	}
1681
1682
	if (trx->was_chosen_as_deadlock_victim) {
1683
1684
		trx->error_state = DB_DEADLOCK;
1685
		trx->was_chosen_as_deadlock_victim = FALSE;
1686
	}
1687
1688
	mutex_exit(&kernel_mutex);
1689
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
1690
	/* InnoDB system transactions (such as the purge, and
1691
	incomplete transactions that are being rolled back after crash
1692
	recovery) will use the global value of
1693
	innodb_lock_wait_timeout, because trx->mysql_thd == NULL. */
1694
	lock_wait_timeout = thd_lock_wait_timeout(trx->mysql_thd);
1695
1819.7.118 by Vasil Dimov
Merge Revision revid:vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh from MySQL InnoDB
1696
	if (lock_wait_timeout < 100000000
1697
	    && wait_time > (double) lock_wait_timeout) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1698
1699
		trx->error_state = DB_LOCK_WAIT_TIMEOUT;
1700
	}
1819.7.118 by Vasil Dimov
Merge Revision revid:vasil.dimov@oracle.com-20100513074652-0cvlhgkesgbb2bfh from MySQL InnoDB
1701
1702
	if (trx_is_interrupted(trx)) {
1703
1704
		trx->error_state = DB_INTERRUPTED;
1705
	}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1706
}
1707
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1708
/********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1709
Releases a MySQL OS thread waiting for a lock to be released, if the
1710
thread is already suspended. */
1711
UNIV_INTERN
1712
void
1713
srv_release_mysql_thread_if_suspended(
1714
/*==================================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1715
	que_thr_t*	thr)	/*!< in: query thread associated with the
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1716
				MySQL OS thread	 */
1717
{
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1718
	srv_slot_t*	slot;
1719
	ulint		i;
1720
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1721
	ut_ad(mutex_own(&kernel_mutex));
1722
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
1723
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
1724
1725
		slot = srv_mysql_table + i;
1726
1727
		if (slot->in_use && slot->thr == thr) {
1728
			/* Found */
1729
1730
			os_event_set(slot->event);
1731
1732
			return;
1733
		}
1734
	}
1735
1736
	/* not found */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1737
}
1738
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1739
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1740
Refreshes the values used to calculate per-second averages. */
1741
static
1742
void
1743
srv_refresh_innodb_monitor_stats(void)
1744
/*==================================*/
1745
{
1746
	mutex_enter(&srv_innodb_monitor_mutex);
1747
1748
	srv_last_monitor_time = time(NULL);
1749
1750
	os_aio_refresh_stats();
1751
1752
	btr_cur_n_sea_old = btr_cur_n_sea;
1753
	btr_cur_n_non_sea_old = btr_cur_n_non_sea;
1754
1755
	log_refresh_stats();
1756
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1757
	buf_refresh_io_stats_all();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1758
1759
	srv_n_rows_inserted_old = srv_n_rows_inserted;
1760
	srv_n_rows_updated_old = srv_n_rows_updated;
1761
	srv_n_rows_deleted_old = srv_n_rows_deleted;
1762
	srv_n_rows_read_old = srv_n_rows_read;
1763
1764
	mutex_exit(&srv_innodb_monitor_mutex);
1765
}
1766
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1767
/******************************************************************//**
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
1768
Outputs to a file the output of the InnoDB Monitor.
1769
@return FALSE if not all information printed
1770
due to failure to obtain necessary mutex */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1771
UNIV_INTERN
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
1772
ibool
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1773
srv_printf_innodb_monitor(
1774
/*======================*/
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1775
	FILE*	file,		/*!< in: output stream */
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
1776
	ibool	nowait,		/*!< in: whether to wait for kernel mutex */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1777
	ulint*	trx_start,	/*!< out: file position of the start of
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1778
				the list of active transactions */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1779
	ulint*	trx_end)	/*!< out: file position of the end of
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1780
				the list of active transactions */
1781
{
1782
	double	time_elapsed;
1783
	time_t	current_time;
1784
	ulint	n_reserved;
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
1785
	ibool	ret;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1786
1787
	mutex_enter(&srv_innodb_monitor_mutex);
1788
1789
	current_time = time(NULL);
1790
1791
	/* We add 0.001 seconds to time_elapsed to prevent division
1792
	by zero if two users happen to call SHOW INNODB STATUS at the same
1793
	time */
1794
1795
	time_elapsed = difftime(current_time, srv_last_monitor_time)
1796
		+ 0.001;
1797
1798
	srv_last_monitor_time = time(NULL);
1799
1800
	fputs("\n=====================================\n", file);
1801
1802
	ut_print_timestamp(file);
1803
	fprintf(file,
1804
		" INNODB MONITOR OUTPUT\n"
1805
		"=====================================\n"
1806
		"Per second averages calculated from the last %lu seconds\n",
1807
		(ulong)time_elapsed);
1808
1819.5.224 by calvin
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6767 from MySQL InnoDB
1809
	fputs("-----------------\n"
1810
	      "BACKGROUND THREAD\n"
1811
	      "-----------------\n", file);
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1812
	srv_print_master_thread_info(file);
1813
1814
	fputs("----------\n"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1815
	      "SEMAPHORES\n"
1816
	      "----------\n", file);
1817
	sync_print(file);
1818
1819
	/* Conceptually, srv_innodb_monitor_mutex has a very high latching
1820
	order level in sync0sync.h, while dict_foreign_err_mutex has a very
1821
	low level 135. Therefore we can reserve the latter mutex here without
1822
	a danger of a deadlock of threads. */
1823
1824
	mutex_enter(&dict_foreign_err_mutex);
1825
1826
	if (ftell(dict_foreign_err_file) != 0L) {
1827
		fputs("------------------------\n"
1828
		      "LATEST FOREIGN KEY ERROR\n"
1829
		      "------------------------\n", file);
1830
		ut_copy_file(file, dict_foreign_err_file);
1831
	}
1832
1833
	mutex_exit(&dict_foreign_err_mutex);
1834
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
1835
	/* Only if lock_print_info_summary proceeds correctly,
1836
	before we call the lock_print_info_all_transactions
1837
	to print all the lock information. */
1838
	ret = lock_print_info_summary(file, nowait);
1839
1840
	if (ret) {
1841
		if (trx_start) {
1842
			long	t = ftell(file);
1843
			if (t < 0) {
1844
				*trx_start = ULINT_UNDEFINED;
1845
			} else {
1846
				*trx_start = (ulint) t;
1847
			}
1848
		}
1849
		lock_print_info_all_transactions(file);
1850
		if (trx_end) {
1851
			long	t = ftell(file);
1852
			if (t < 0) {
1853
				*trx_end = ULINT_UNDEFINED;
1854
			} else {
1855
				*trx_end = (ulint) t;
1856
			}
1857
		}
1858
	}
1859
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1860
	fputs("--------\n"
1861
	      "FILE I/O\n"
1862
	      "--------\n", file);
1863
	os_aio_print(file);
1864
1865
	fputs("-------------------------------------\n"
1866
	      "INSERT BUFFER AND ADAPTIVE HASH INDEX\n"
1867
	      "-------------------------------------\n", file);
1868
	ibuf_print(file);
1869
1870
	ha_print_info(file, btr_search_sys->hash_index);
1871
1872
	fprintf(file,
1873
		"%.2f hash searches/s, %.2f non-hash searches/s\n",
1874
		(btr_cur_n_sea - btr_cur_n_sea_old)
1875
		/ time_elapsed,
1876
		(btr_cur_n_non_sea - btr_cur_n_non_sea_old)
1877
		/ time_elapsed);
1878
	btr_cur_n_sea_old = btr_cur_n_sea;
1879
	btr_cur_n_non_sea_old = btr_cur_n_non_sea;
1880
1881
	fputs("---\n"
1882
	      "LOG\n"
1883
	      "---\n", file);
1884
	log_print(file);
1885
1886
	fputs("----------------------\n"
1887
	      "BUFFER POOL AND MEMORY\n"
1888
	      "----------------------\n", file);
1889
	fprintf(file,
1890
		"Total memory allocated " ULINTPF
1891
		"; in additional pool allocated " ULINTPF "\n",
1892
		ut_total_allocated_memory,
1893
		mem_pool_get_reserved(mem_comm_pool));
1894
	fprintf(file, "Dictionary memory allocated " ULINTPF "\n",
1895
		dict_sys->size);
1896
1897
	buf_print_io(file);
1898
1899
	fputs("--------------\n"
1900
	      "ROW OPERATIONS\n"
1901
	      "--------------\n", file);
1902
	fprintf(file, "%ld queries inside InnoDB, %lu queries in queue\n",
1903
		(long) srv_conc_n_threads,
1904
		(ulong) srv_conc_n_waiting_threads);
1905
1906
	fprintf(file, "%lu read views open inside InnoDB\n",
1907
		UT_LIST_GET_LEN(trx_sys->view_list));
1908
1909
	n_reserved = fil_space_get_n_reserved_extents(0);
1910
	if (n_reserved > 0) {
1911
		fprintf(file,
1912
			"%lu tablespace extents now reserved for"
1913
			" B-tree split operations\n",
1914
			(ulong) n_reserved);
1915
	}
1916
1917
#ifdef UNIV_LINUX
1918
	fprintf(file, "Main thread process no. %lu, id %lu, state: %s\n",
1919
		(ulong) srv_main_thread_process_no,
1920
		(ulong) srv_main_thread_id,
1921
		srv_main_thread_op_info);
1922
#else
1923
	fprintf(file, "Main thread id %lu, state: %s\n",
1924
		(ulong) srv_main_thread_id,
1925
		srv_main_thread_op_info);
1926
#endif
1927
	fprintf(file,
1928
		"Number of rows inserted " ULINTPF
1929
		", updated " ULINTPF ", deleted " ULINTPF
1930
		", read " ULINTPF "\n",
1931
		srv_n_rows_inserted,
1932
		srv_n_rows_updated,
1933
		srv_n_rows_deleted,
1934
		srv_n_rows_read);
1935
	fprintf(file,
1936
		"%.2f inserts/s, %.2f updates/s,"
1937
		" %.2f deletes/s, %.2f reads/s\n",
1938
		(srv_n_rows_inserted - srv_n_rows_inserted_old)
1939
		/ time_elapsed,
1940
		(srv_n_rows_updated - srv_n_rows_updated_old)
1941
		/ time_elapsed,
1942
		(srv_n_rows_deleted - srv_n_rows_deleted_old)
1943
		/ time_elapsed,
1944
		(srv_n_rows_read - srv_n_rows_read_old)
1945
		/ time_elapsed);
1946
1947
	srv_n_rows_inserted_old = srv_n_rows_inserted;
1948
	srv_n_rows_updated_old = srv_n_rows_updated;
1949
	srv_n_rows_deleted_old = srv_n_rows_deleted;
1950
	srv_n_rows_read_old = srv_n_rows_read;
1951
1952
	fputs("----------------------------\n"
1953
	      "END OF INNODB MONITOR OUTPUT\n"
1954
	      "============================\n", file);
1955
	mutex_exit(&srv_innodb_monitor_mutex);
1956
	fflush(file);
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
1957
1958
	return(ret);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1959
}
1960
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1961
/******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1962
Function to pass InnoDB status variables to MySQL */
1963
UNIV_INTERN
1964
void
1965
srv_export_innodb_status(void)
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
1966
/*==========================*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1967
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1968
	buf_pool_stat_t	stat;
1969
	ulint		LRU_len;
1970
	ulint		free_len;
1971
	ulint		flush_list_len;
1972
1973
	buf_get_total_stat(&stat);
1974
	buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len);
1975
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1976
	mutex_enter(&srv_innodb_monitor_mutex);
1977
1978
	export_vars.innodb_data_pending_reads
1979
		= os_n_pending_reads;
1980
	export_vars.innodb_data_pending_writes
1981
		= os_n_pending_writes;
1982
	export_vars.innodb_data_pending_fsyncs
1983
		= fil_n_pending_log_flushes
1984
		+ fil_n_pending_tablespace_flushes;
1985
	export_vars.innodb_data_fsyncs = os_n_fsyncs;
1986
	export_vars.innodb_data_read = srv_data_read;
1987
	export_vars.innodb_data_reads = os_n_file_reads;
1988
	export_vars.innodb_data_writes = os_n_file_writes;
1989
	export_vars.innodb_data_written = srv_data_written;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1990
	export_vars.innodb_buffer_pool_read_requests = stat.n_page_gets;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
1991
	export_vars.innodb_buffer_pool_write_requests
1992
		= srv_buf_pool_write_requests;
1993
	export_vars.innodb_buffer_pool_wait_free = srv_buf_pool_wait_free;
1994
	export_vars.innodb_buffer_pool_pages_flushed = srv_buf_pool_flushed;
1995
	export_vars.innodb_buffer_pool_reads = srv_buf_pool_reads;
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
1996
	export_vars.innodb_buffer_pool_read_ahead
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1997
		= stat.n_ra_pages_read;
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
1998
	export_vars.innodb_buffer_pool_read_ahead_evicted
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
1999
		= stat.n_ra_pages_evicted;
2000
	export_vars.innodb_buffer_pool_pages_data = LRU_len;
2001
	export_vars.innodb_buffer_pool_pages_dirty = flush_list_len;
2002
	export_vars.innodb_buffer_pool_pages_free = free_len;
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2003
#ifdef UNIV_DEBUG
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2004
	export_vars.innodb_buffer_pool_pages_latched
2005
		= buf_get_latched_pages_number();
641.2.1 by Monty Taylor
InnoDB Plugin 1.0.2
2006
#endif /* UNIV_DEBUG */
1819.7.74 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100430105456-733h2ir5s9ezm0dx from MySQL InnoDB
2007
	export_vars.innodb_buffer_pool_pages_total = buf_pool_get_n_pages();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2008
1819.7.75 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100430110021-j59l8mzkhxb33z05 from MySQL InnoDB
2009
	export_vars.innodb_buffer_pool_pages_misc
1819.7.76 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100430113812-56x04cowg2g5ka3p from MySQL InnoDB
2010
	       	= buf_pool_get_n_pages() - LRU_len - free_len;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2011
#ifdef HAVE_ATOMIC_BUILTINS
641.2.2 by Monty Taylor
InnoDB Plugin 1.0.3
2012
	export_vars.innodb_have_atomic_builtins = 1;
2013
#else
2014
	export_vars.innodb_have_atomic_builtins = 0;
2015
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2016
	export_vars.innodb_page_size = UNIV_PAGE_SIZE;
2017
	export_vars.innodb_log_waits = srv_log_waits;
2018
	export_vars.innodb_os_log_written = srv_os_log_written;
2019
	export_vars.innodb_os_log_fsyncs = fil_n_log_flushes;
2020
	export_vars.innodb_os_log_pending_fsyncs = fil_n_pending_log_flushes;
2021
	export_vars.innodb_os_log_pending_writes = srv_os_log_pending_writes;
2022
	export_vars.innodb_log_write_requests = srv_log_write_requests;
2023
	export_vars.innodb_log_writes = srv_log_writes;
2024
	export_vars.innodb_dblwr_pages_written = srv_dblwr_pages_written;
2025
	export_vars.innodb_dblwr_writes = srv_dblwr_writes;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2026
	export_vars.innodb_pages_created = stat.n_pages_created;
2027
	export_vars.innodb_pages_read = stat.n_pages_read;
2028
	export_vars.innodb_pages_written = stat.n_pages_written;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2029
	export_vars.innodb_row_lock_waits = srv_n_lock_wait_count;
2030
	export_vars.innodb_row_lock_current_waits
2031
		= srv_n_lock_wait_current_count;
2032
	export_vars.innodb_row_lock_time = srv_n_lock_wait_time / 1000;
2033
	if (srv_n_lock_wait_count > 0) {
2034
		export_vars.innodb_row_lock_time_avg = (ulint)
2035
			(srv_n_lock_wait_time / 1000 / srv_n_lock_wait_count);
2036
	} else {
2037
		export_vars.innodb_row_lock_time_avg = 0;
2038
	}
2039
	export_vars.innodb_row_lock_time_max
2040
		= srv_n_lock_max_wait_time / 1000;
2041
	export_vars.innodb_rows_read = srv_n_rows_read;
2042
	export_vars.innodb_rows_inserted = srv_n_rows_inserted;
2043
	export_vars.innodb_rows_updated = srv_n_rows_updated;
2044
	export_vars.innodb_rows_deleted = srv_n_rows_deleted;
2045
2046
	mutex_exit(&srv_innodb_monitor_mutex);
2047
}
2048
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2049
/*********************************************************************//**
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2050
A thread which prints the info output by various InnoDB monitors.
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2051
@return	a dummy parameter */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2052
UNIV_INTERN
2053
os_thread_ret_t
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2054
srv_monitor_thread(
2055
/*===============*/
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2056
	void*	arg __attribute__((unused)))
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2057
			/*!< in: a dummy parameter required by
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2058
			os_thread_create */
2059
{
2060
	double		time_elapsed;
2061
	time_t		current_time;
2062
	time_t		last_table_monitor_time;
2063
	time_t		last_tablespace_monitor_time;
2064
	time_t		last_monitor_time;
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2065
	ulint		mutex_skipped;
2066
	ibool		last_srv_print_monitor;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2067
2068
#ifdef UNIV_DEBUG_THREAD_CREATION
2069
	fprintf(stderr, "Lock timeout thread starts, id %lu\n",
2070
		os_thread_pf(os_thread_get_curr_id()));
2071
#endif
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2072
2073
#ifdef UNIV_PFS_THREAD
2074
	pfs_register_thread(srv_monitor_thread_key);
2075
#endif
2076
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2077
	UT_NOT_USED(arg);
2078
	srv_last_monitor_time = time(NULL);
2079
	last_table_monitor_time = time(NULL);
2080
	last_tablespace_monitor_time = time(NULL);
2081
	last_monitor_time = time(NULL);
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2082
	mutex_skipped = 0;
2083
	last_srv_print_monitor = srv_print_innodb_monitor;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2084
loop:
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2085
	srv_monitor_active = TRUE;
2086
2087
	/* Wake up every 5 seconds to see if we need to print
2088
	monitor information. */
2089
2090
	os_thread_sleep(5000000);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2091
2092
	current_time = time(NULL);
2093
2094
	time_elapsed = difftime(current_time, last_monitor_time);
2095
2096
	if (time_elapsed > 15) {
2097
		last_monitor_time = time(NULL);
2098
2099
		if (srv_print_innodb_monitor) {
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2100
			/* Reset mutex_skipped counter everytime
2101
			srv_print_innodb_monitor changes. This is to
2102
			ensure we will not be blocked by kernel_mutex
2103
			for short duration information printing,
2104
			such as requested by sync_array_print_long_waits() */
2105
			if (!last_srv_print_monitor) {
2106
				mutex_skipped = 0;
2107
				last_srv_print_monitor = TRUE;
2108
			}
2109
2110
			if (!srv_printf_innodb_monitor(stderr,
2111
						MUTEX_NOWAIT(mutex_skipped),
2112
						NULL, NULL)) {
2113
				mutex_skipped++;
2114
			} else {
2115
				/* Reset the counter */
2116
				mutex_skipped = 0;
2117
			}
2118
		} else {
2119
			last_srv_print_monitor = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2120
		}
2121
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2122
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2123
		if (srv_innodb_status) {
2124
			mutex_enter(&srv_monitor_file_mutex);
2125
			rewind(srv_monitor_file);
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2126
			if (!srv_printf_innodb_monitor(srv_monitor_file,
2127
						MUTEX_NOWAIT(mutex_skipped),
2128
						NULL, NULL)) {
2129
				mutex_skipped++;
2130
			} else {
2131
				mutex_skipped = 0;
2132
			}
2133
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2134
			os_file_set_eof(srv_monitor_file);
2135
			mutex_exit(&srv_monitor_file_mutex);
2136
		}
2137
2138
		if (srv_print_innodb_tablespace_monitor
2139
		    && difftime(current_time,
2140
				last_tablespace_monitor_time) > 60) {
2141
			last_tablespace_monitor_time = time(NULL);
2142
2143
			fputs("========================"
2144
			      "========================\n",
2145
			      stderr);
2146
2147
			ut_print_timestamp(stderr);
2148
2149
			fputs(" INNODB TABLESPACE MONITOR OUTPUT\n"
2150
			      "========================"
2151
			      "========================\n",
2152
			      stderr);
2153
2154
			fsp_print(0);
2155
			fputs("Validating tablespace\n", stderr);
2156
			fsp_validate(0);
2157
			fputs("Validation ok\n"
2158
			      "---------------------------------------\n"
2159
			      "END OF INNODB TABLESPACE MONITOR OUTPUT\n"
2160
			      "=======================================\n",
2161
			      stderr);
2162
		}
2163
2164
		if (srv_print_innodb_table_monitor
2165
		    && difftime(current_time, last_table_monitor_time) > 60) {
2166
2167
			last_table_monitor_time = time(NULL);
2168
2169
			fputs("===========================================\n",
2170
			      stderr);
2171
2172
			ut_print_timestamp(stderr);
2173
2174
			fputs(" INNODB TABLE MONITOR OUTPUT\n"
2175
			      "===========================================\n",
2176
			      stderr);
2177
			dict_print();
2178
2179
			fputs("-----------------------------------\n"
2180
			      "END OF INNODB TABLE MONITOR OUTPUT\n"
2181
			      "==================================\n",
2182
			      stderr);
2183
		}
2184
	}
2185
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2186
	if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2187
		goto exit_func;
2188
	}
2189
2190
	if (srv_print_innodb_monitor
2191
	    || srv_print_innodb_lock_monitor
2192
	    || srv_print_innodb_tablespace_monitor
2193
	    || srv_print_innodb_table_monitor) {
2194
		goto loop;
2195
	}
2196
2197
	srv_monitor_active = FALSE;
2198
2199
	goto loop;
2200
2201
exit_func:
2202
	srv_monitor_active = FALSE;
2203
2204
	/* We count the number of threads in os_thread_exit(). A created
2205
	thread should always use that to exit and not use return() to exit. */
2206
2207
	os_thread_exit(NULL);
2208
2209
	OS_THREAD_DUMMY_RETURN;
2210
}
2211
2212
/*********************************************************************//**
2213
A thread which wakes up threads whose lock wait may have lasted too long.
2214
@return	a dummy parameter */
2215
UNIV_INTERN
2216
os_thread_ret_t
2217
srv_lock_timeout_thread(
2218
/*====================*/
2219
	void*	arg __attribute__((unused)))
2220
			/* in: a dummy parameter required by
2221
			os_thread_create */
2222
{
2223
	srv_slot_t*	slot;
2224
	ibool		some_waits;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2225
	double		wait_time;
2226
	ulint		i;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2227
2228
#ifdef UNIV_PFS_THREAD
2229
	pfs_register_thread(srv_lock_timeout_thread_key);
2230
#endif
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2231
2232
loop:
2233
	/* When someone is waiting for a lock, we wake up every second
2234
	and check if a timeout has passed for a lock wait */
2235
2236
	os_thread_sleep(1000000);
2237
2238
	srv_lock_timeout_active = TRUE;
2239
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2240
	mutex_enter(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2241
2242
	some_waits = FALSE;
2243
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2244
	/* Check of all slots if a thread is waiting there, and if it
2245
	has exceeded the time limit */
2246
2247
	for (i = 0; i < OS_THREAD_MAX_N; i++) {
2248
2249
		slot = srv_mysql_table + i;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2250
2251
		if (slot->in_use) {
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2252
			trx_t*	trx;
2253
			ulong	lock_wait_timeout;
2254
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2255
			some_waits = TRUE;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2256
2257
			wait_time = ut_difftime(ut_time(), slot->suspend_time);
2258
2259
			trx = thr_get_trx(slot->thr);
2260
			lock_wait_timeout = thd_lock_wait_timeout(
2261
				trx->mysql_thd);
2262
2263
			if (trx_is_interrupted(trx)
2264
			    || (lock_wait_timeout < 100000000
2265
				&& (wait_time > (double) lock_wait_timeout
2266
				    || wait_time < 0))) {
2267
2268
				/* Timeout exceeded or a wrap-around in system
2269
				time counter: cancel the lock request queued
2270
				by the transaction and release possible
2271
				other transactions waiting behind; it is
2272
				possible that the lock has already been
2273
				granted: in that case do nothing */
2274
2275
				if (trx->wait_lock) {
2276
					lock_cancel_waiting_and_release(
2277
						trx->wait_lock);
2278
				}
2279
			}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2280
		}
2281
	}
2282
2283
	os_event_reset(srv_lock_timeout_thread_event);
2284
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2285
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2286
2287
	if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
2288
		goto exit_func;
2289
	}
2290
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2291
	if (some_waits) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2292
		goto loop;
2293
	}
2294
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2295
	srv_lock_timeout_active = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2296
2297
#if 0
2298
	/* The following synchronisation is disabled, since
2299
	the InnoDB monitor output is to be updated every 15 seconds. */
2300
	os_event_wait(srv_lock_timeout_thread_event);
2301
#endif
2302
	goto loop;
2303
2304
exit_func:
1819.5.161 by marko
Merge Revision revid:svn-v4:16c675df-0fcb-4bc9-8058-dcc011a37293:branches/zip:6352 from MySQL InnoDB
2305
	srv_lock_timeout_active = FALSE;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2306
2307
	/* We count the number of threads in os_thread_exit(). A created
2308
	thread should always use that to exit and not use return() to exit. */
2309
2310
	os_thread_exit(NULL);
2311
2312
	OS_THREAD_DUMMY_RETURN;
2313
}
2314
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2315
/*********************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2316
A thread which prints warnings about semaphore waits which have lasted
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2317
too long. These can be used to track bugs which cause hangs.
2318
@return	a dummy parameter */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2319
UNIV_INTERN
2320
os_thread_ret_t
2321
srv_error_monitor_thread(
2322
/*=====================*/
2323
	void*	arg __attribute__((unused)))
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2324
			/*!< in: a dummy parameter required by
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2325
			os_thread_create */
2326
{
2327
	/* number of successive fatal timeouts observed */
2328
	ulint		fatal_cnt	= 0;
2329
	ib_uint64_t	old_lsn;
2330
	ib_uint64_t	new_lsn;
2331
2332
	old_lsn = srv_start_lsn;
2333
2334
#ifdef UNIV_DEBUG_THREAD_CREATION
2335
	fprintf(stderr, "Error monitor thread starts, id %lu\n",
2336
		os_thread_pf(os_thread_get_curr_id()));
2337
#endif
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2338
2339
#ifdef UNIV_PFS_THREAD
2340
	pfs_register_thread(srv_error_monitor_thread_key);
2341
#endif
2342
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2343
loop:
2344
	srv_error_monitor_active = TRUE;
2345
2346
	/* Try to track a strange bug reported by Harald Fuchs and others,
2347
	where the lsn seems to decrease at times */
2348
2349
	new_lsn = log_get_lsn();
2350
2351
	if (new_lsn < old_lsn) {
2352
		ut_print_timestamp(stderr);
2353
		fprintf(stderr,
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2354
			"  InnoDB: Error: old log sequence number %"PRIu64""
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2355
			" was greater\n"
641.1.4 by Monty Taylor
Merged in InnoDB changes.
2356
			"InnoDB: than the new log sequence number %"PRIu64"!\n"
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2357
			"InnoDB: Please submit a bug report"
2358
			" to http://bugs.mysql.com\n",
2359
			old_lsn, new_lsn);
2360
	}
2361
2362
	old_lsn = new_lsn;
2363
2364
	if (difftime(time(NULL), srv_last_monitor_time) > 60) {
2365
		/* We referesh InnoDB Monitor values so that averages are
2366
		printed from at most 60 last seconds */
2367
2368
		srv_refresh_innodb_monitor_stats();
2369
	}
2370
2371
	/* Update the statistics collected for deciding LRU
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2372
	eviction policy. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2373
	buf_LRU_stat_update();
2374
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2375
	/* Update the statistics collected for flush rate policy. */
2376
	buf_flush_stat_update();
2377
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2378
	/* In case mutex_exit is not a memory barrier, it is
2379
	theoretically possible some threads are left waiting though
2380
	the semaphore is already released. Wake up those threads: */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2381
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2382
	sync_arr_wake_threads_if_sema_free();
2383
2384
	if (sync_array_print_long_waits()) {
2385
		fatal_cnt++;
2386
		if (fatal_cnt > 10) {
2387
2388
			fprintf(stderr,
2389
				"InnoDB: Error: semaphore wait has lasted"
2390
				" > %lu seconds\n"
2391
				"InnoDB: We intentionally crash the server,"
2392
				" because it appears to be hung.\n",
2393
				(ulong) srv_fatal_semaphore_wait_threshold);
2394
2395
			ut_error;
2396
		}
2397
	} else {
2398
		fatal_cnt = 0;
2399
	}
2400
2401
	/* Flush stderr so that a database user gets the output
2402
	to possible MySQL error file */
2403
2404
	fflush(stderr);
2405
2406
	os_thread_sleep(1000000);
2407
2408
	if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) {
2409
2410
		goto loop;
2411
	}
2412
2413
	srv_error_monitor_active = FALSE;
2414
2415
	/* We count the number of threads in os_thread_exit(). A created
2416
	thread should always use that to exit and not use return() to exit. */
2417
2418
	os_thread_exit(NULL);
2419
2420
	OS_THREAD_DUMMY_RETURN;
2421
}
2422
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2423
/**********************************************************************//**
1819.7.98 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100510031717-vw5a99w2v7rot6f9 from MySQL InnoDB
2424
Check whether any background thread is active.
2425
@return FALSE if all are are suspended or have exited. */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2426
UNIV_INTERN
2427
ibool
1819.7.98 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100510031717-vw5a99w2v7rot6f9 from MySQL InnoDB
2428
srv_is_any_background_thread_active(void)
2429
/*=====================================*/
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2430
{
1819.7.98 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100510031717-vw5a99w2v7rot6f9 from MySQL InnoDB
2431
	ulint	i;
2432
	ibool	ret = FALSE;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2433
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2434
	mutex_enter(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2435
1819.7.98 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100510031717-vw5a99w2v7rot6f9 from MySQL InnoDB
2436
	for (i = SRV_COM; i <= SRV_MASTER; ++i) {
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2437
		if (srv_n_threads_active[i] != 0) {
1819.7.98 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100510031717-vw5a99w2v7rot6f9 from MySQL InnoDB
2438
			ret = TRUE;
2439
			break;
2440
		}
2441
	}
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2442
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2443
	mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2444
2445
	return(ret);
2446
}
2447
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2448
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2449
Tells the InnoDB server that there has been activity in the database
2450
and wakes up the master thread if it is suspended (not sleeping). Used
2451
in the MySQL interface. Note that there is a small chance that the master
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2452
thread stays suspended (we do not protect our operation with the
2453
srv_sys_t->mutex, for performance reasons). */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2454
UNIV_INTERN
2455
void
2456
srv_active_wake_master_thread(void)
2457
/*===============================*/
2458
{
1819.7.173 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100617010613-ihrj0lulityr0n4c from MySQL InnoDB
2459
	srv_activity_count++;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2460
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2461
	if (srv_n_threads_active[SRV_MASTER] == 0) {
2462
2463
		mutex_enter(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2464
2465
		srv_release_threads(SRV_MASTER, 1);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2466
2467
		mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2468
	}
2469
}
2470
2471
/*******************************************************************//**
2472
Tells the purge thread that there has been activity in the database
2473
and wakes up the purge thread if it is suspended (not sleeping).  Note
2474
that there is a small chance that the purge thread stays suspended
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2475
(we do not protect our operation with the kernel mutex, for
2476
performace reasons). */
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2477
UNIV_INTERN
2478
void
2479
srv_wake_purge_thread_if_not_active(void)
2480
/*=====================================*/
2481
{
2482
	ut_ad(!mutex_own(&kernel_mutex));
2483
2484
	if (srv_n_purge_threads > 0
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2485
	    && srv_n_threads_active[SRV_WORKER] == 0) {
2486
2487
		mutex_enter(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2488
2489
		srv_release_threads(SRV_WORKER, 1);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2490
2491
		mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2492
	}
2493
}
2494
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2495
/*******************************************************************//**
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2496
Wakes up the master thread if it is suspended or being suspended. */
2497
UNIV_INTERN
2498
void
2499
srv_wake_master_thread(void)
2500
/*========================*/
2501
{
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2502
	srv_activity_count++;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2503
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2504
	mutex_enter(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2505
2506
	srv_release_threads(SRV_MASTER, 1);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2507
2508
	mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2509
}
2510
2511
/*******************************************************************//**
2512
Wakes up the purge thread if it's not already awake. */
2513
UNIV_INTERN
2514
void
2515
srv_wake_purge_thread(void)
2516
/*=======================*/
2517
{
2518
	ut_ad(!mutex_own(&kernel_mutex));
2519
2520
	if (srv_n_purge_threads > 0) {
2521
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2522
		mutex_enter(&kernel_mutex);
2523
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2524
		srv_release_threads(SRV_WORKER, 1);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2525
2526
		mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2527
	}
2528
}
2529
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2530
/**********************************************************************
2531
The master thread is tasked to ensure that flush of log file happens
2532
once every second in the background. This is to ensure that not more
2533
than one second of trxs are lost in case of crash when
2534
innodb_flush_logs_at_trx_commit != 1 */
2535
static
2536
void
2537
srv_sync_log_buffer_in_background(void)
2538
/*===================================*/
2539
{
2540
	time_t	current_time = time(NULL);
2541
2542
	srv_main_thread_op_info = "flushing log";
2543
	if (difftime(current_time, srv_last_log_flush_time) >= 1) {
2544
		log_buffer_sync_in_background(TRUE);
2545
		srv_last_log_flush_time = current_time;
2546
		srv_log_writes_and_flush++;
2547
	}
2548
}
2549
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2550
/********************************************************************//**
2551
Do a full purge, reconfigure the purge sub-system if a dynamic
2552
change is detected. */
2553
static
2554
void
2555
srv_master_do_purge(void)
2556
/*=====================*/
2557
{
2558
	ulint	n_pages_purged;
2559
2560
	ut_ad(!mutex_own(&kernel_mutex));
2561
2562
	ut_a(srv_n_purge_threads == 0);
2563
2564
	do {
2565
		/* Check for shutdown and change in purge config. */
2566
		if (srv_fast_shutdown && srv_shutdown_state > 0) {
2567
			/* Nothing to purge. */
2568
			n_pages_purged = 0;
2569
		} else {
2570
			n_pages_purged = trx_purge(srv_purge_batch_size);
2571
		}
2572
2573
		srv_sync_log_buffer_in_background();
2574
2575
	} while (n_pages_purged > 0);
2576
}
2577
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2578
/*********************************************************************//**
2579
The master thread controlling the server.
2580
@return	a dummy parameter */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2581
UNIV_INTERN
2582
os_thread_ret_t
2583
srv_master_thread(
2584
/*==============*/
2585
	void*	arg __attribute__((unused)))
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2586
			/*!< in: a dummy parameter required by
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2587
			os_thread_create */
2588
{
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2589
	buf_pool_stat_t buf_stat;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2590
	os_event_t	event;
2591
	ulint		old_activity_count;
2592
	ulint		n_pages_purged	= 0;
2593
	ulint		n_bytes_merged;
2594
	ulint		n_pages_flushed;
2595
	ulint		n_bytes_archived;
2596
	ulint		n_tables_to_drop;
2597
	ulint		n_ios;
2598
	ulint		n_ios_old;
2599
	ulint		n_ios_very_old;
2600
	ulint		n_pend_ios;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2601
	ulint		next_itr_time;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2602
	ulint		i;
2603
2604
#ifdef UNIV_DEBUG_THREAD_CREATION
2605
	fprintf(stderr, "Master thread starts, id %lu\n",
2606
		os_thread_pf(os_thread_get_curr_id()));
2607
#endif
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2608
2609
#ifdef UNIV_PFS_THREAD
2610
	pfs_register_thread(srv_master_thread_key);
2611
#endif
2612
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2613
	srv_main_thread_process_no = os_proc_get_number();
2614
	srv_main_thread_id = os_thread_pf(os_thread_get_curr_id());
2615
2616
	srv_table_reserve_slot(SRV_MASTER);
2617
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2618
	mutex_enter(&kernel_mutex);
2619
2620
	srv_n_threads_active[SRV_MASTER]++;
2621
2622
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2623
2624
loop:
2625
	/*****************************************************************/
2626
	/* ---- When there is database activity by users, we cycle in this
2627
	loop */
2628
2629
	srv_main_thread_op_info = "reserving kernel mutex";
2630
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2631
	buf_get_total_stat(&buf_stat);
2632
	n_ios_very_old = log_sys->n_log_ios + buf_stat.n_pages_read
2633
		+ buf_stat.n_pages_written;
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2634
	mutex_enter(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2635
2636
	/* Store the user activity counter at the start of this loop */
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2637
	old_activity_count = srv_activity_count;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2638
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2639
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2640
2641
	if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) {
2642
2643
		goto suspend_thread;
2644
	}
2645
2646
	/* ---- We run the following loop approximately once per second
2647
	when there is database activity */
2648
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2649
	srv_last_log_flush_time = time(NULL);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2650
	next_itr_time = ut_time_ms();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2651
2652
	for (i = 0; i < 10; i++) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2653
		ulint	cur_time = ut_time_ms();
2654
2655
		buf_get_total_stat(&buf_stat);
2656
2657
		n_ios_old = log_sys->n_log_ios + buf_stat.n_pages_read
2658
			+ buf_stat.n_pages_written;
2659
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2660
		srv_main_thread_op_info = "sleeping";
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2661
		srv_main_1_second_loops++;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2662
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2663
		if (next_itr_time > cur_time) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2664
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2665
			/* Get sleep interval in micro seconds. We use
2666
			ut_min() to avoid long sleep in case of
2667
			wrap around. */
2668
			os_thread_sleep(ut_min(1000000,
2669
					(next_itr_time - cur_time)
2670
					 * 1000));
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2671
			srv_main_sleeps++;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2672
		}
2673
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2674
		/* Each iteration should happen at 1 second interval. */
2675
		next_itr_time = ut_time_ms() + 1000;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2676
2677
		/* ALTER TABLE in MySQL requires on Unix that the table handler
2678
		can drop tables lazily after there no longer are SELECT
2679
		queries to them. */
2680
2681
		srv_main_thread_op_info = "doing background drop tables";
2682
2683
		row_drop_tables_for_mysql_in_background();
2684
2685
		srv_main_thread_op_info = "";
2686
2687
		if (srv_fast_shutdown && srv_shutdown_state > 0) {
2688
2689
			goto background_loop;
2690
		}
2691
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2692
		/* Flush logs if needed */
2693
		srv_sync_log_buffer_in_background();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2694
2695
		srv_main_thread_op_info = "making checkpoint";
2696
		log_free_check();
2697
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2698
		/* If i/os during one second sleep were less than 5% of
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2699
		capacity, we assume that there is free disk i/o capacity
2700
		available, and it makes sense to do an insert buffer merge. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2701
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2702
		buf_get_total_stat(&buf_stat);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2703
		n_pend_ios = buf_get_n_pending_ios()
2704
			+ log_sys->n_pending_writes;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2705
		n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2706
			+ buf_stat.n_pages_written;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2707
		if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2708
		    && (n_ios - n_ios_old < SRV_RECENT_IO_ACTIVITY)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2709
			srv_main_thread_op_info = "doing insert buffer merge";
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2710
			ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
2711
2712
			/* Flush logs if needed */
2713
			srv_sync_log_buffer_in_background();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2714
		}
2715
2716
		if (UNIV_UNLIKELY(buf_get_modified_ratio_pct()
2717
				  > srv_max_buf_pool_modified_pct)) {
2718
2719
			/* Try to keep the number of modified pages in the
2720
			buffer pool under the limit wished by the user */
2721
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
2722
			srv_main_thread_op_info =
2723
				"flushing buffer pool pages";
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2724
			n_pages_flushed = buf_flush_list(
2725
				PCT_IO(100), IB_ULONGLONG_MAX);
2726
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2727
		} else if (srv_adaptive_flushing) {
2728
2729
			/* Try to keep the rate of flushing of dirty
2730
			pages such that redo log generation does not
2731
			produce bursts of IO at checkpoint time. */
2732
			ulint n_flush = buf_flush_get_desired_flush_rate();
2733
2734
			if (n_flush) {
1819.5.19 by stewart at flamingspork
[patch 019/129] Merge patch for revision 1805 from InnoDB SVN:
2735
				srv_main_thread_op_info =
2736
					"flushing buffer pool pages";
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2737
				n_flush = ut_min(PCT_IO(100), n_flush);
2738
				n_pages_flushed =
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2739
					buf_flush_list(
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2740
						n_flush,
2741
						IB_ULONGLONG_MAX);
2742
			}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2743
		}
2744
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2745
		if (srv_activity_count == old_activity_count) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2746
2747
			/* There is no user activity at the moment, go to
2748
			the background loop */
2749
2750
			goto background_loop;
2751
		}
2752
	}
2753
2754
	/* ---- We perform the following code approximately once per
2755
	10 seconds when there is database activity */
2756
2757
#ifdef MEM_PERIODIC_CHECK
2758
	/* Check magic numbers of every allocated mem block once in 10
2759
	seconds */
2760
	mem_validate_all_blocks();
2761
#endif
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2762
	/* If i/os during the 10 second period were less than 200% of
2763
	capacity, we assume that there is free disk i/o capacity
2764
	available, and it makes sense to flush srv_io_capacity pages.
2765
2766
	Note that this is done regardless of the fraction of dirty
2767
	pages relative to the max requested by the user. The one second
2768
	loop above requests writes for that case. The writes done here
2769
	are not required, and may be disabled. */
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2770
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2771
	buf_get_total_stat(&buf_stat);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2772
	n_pend_ios = buf_get_n_pending_ios() + log_sys->n_pending_writes;
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2773
	n_ios = log_sys->n_log_ios + buf_stat.n_pages_read
2774
		+ buf_stat.n_pages_written;
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2775
2776
	srv_main_10_second_loops++;
2777
	if (n_pend_ios < SRV_PEND_IO_THRESHOLD
2778
	    && (n_ios - n_ios_very_old < SRV_PAST_IO_ACTIVITY)) {
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2779
2780
		srv_main_thread_op_info = "flushing buffer pool pages";
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2781
		buf_flush_list(PCT_IO(100), IB_ULONGLONG_MAX);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2782
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2783
		/* Flush logs if needed */
2784
		srv_sync_log_buffer_in_background();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2785
	}
2786
2787
	/* We run a batch of insert buffer merge every 10 seconds,
2788
	even if the server were active */
2789
2790
	srv_main_thread_op_info = "doing insert buffer merge";
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2791
	ibuf_contract_for_n_pages(FALSE, PCT_IO(5));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2792
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2793
	/* Flush logs if needed */
2794
	srv_sync_log_buffer_in_background();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2795
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2796
	if (srv_n_purge_threads == 0) {
2797
		srv_main_thread_op_info = "master purging";
2798
2799
		srv_master_do_purge();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2800
2801
		if (srv_fast_shutdown && srv_shutdown_state > 0) {
2802
2803
			goto background_loop;
2804
		}
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2805
	}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2806
2807
	srv_main_thread_op_info = "flushing buffer pool pages";
2808
2809
	/* Flush a few oldest pages to make a new checkpoint younger */
2810
2811
	if (buf_get_modified_ratio_pct() > 70) {
2812
2813
		/* If there are lots of modified pages in the buffer pool
2814
		(> 70 %), we assume we can afford reserving the disk(s) for
2815
		the time it requires to flush 100 pages */
2816
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2817
		n_pages_flushed = buf_flush_list(
2818
			PCT_IO(100), IB_ULONGLONG_MAX);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2819
	} else {
2820
		/* Otherwise, we only flush a small number of pages so that
2821
		we do not unnecessarily use much disk i/o capacity from
2822
		other work */
2823
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2824
		n_pages_flushed = buf_flush_list(
2825
			  PCT_IO(10), IB_ULONGLONG_MAX);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2826
	}
2827
2828
	srv_main_thread_op_info = "making checkpoint";
2829
2830
	/* Make a new checkpoint about once in 10 seconds */
2831
2832
	log_checkpoint(TRUE, FALSE);
2833
2834
	srv_main_thread_op_info = "reserving kernel mutex";
2835
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2836
	mutex_enter(&kernel_mutex);
2837
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2838
	/* ---- When there is database activity, we jump from here back to
2839
	the start of loop */
2840
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2841
	if (srv_activity_count != old_activity_count) {
2842
		mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2843
		goto loop;
2844
	}
2845
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2846
	mutex_exit(&kernel_mutex);
2847
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2848
	/* If the database is quiet, we enter the background loop */
2849
2850
	/*****************************************************************/
2851
background_loop:
2852
	/* ---- In this loop we run background operations when the server
2853
	is quiet from user activity. Also in the case of a shutdown, we
2854
	loop here, flushing the buffer pool to the data files. */
2855
2856
	/* The server has been quiet for a while: start running background
2857
	operations */
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2858
	srv_main_background_loops++;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2859
	srv_main_thread_op_info = "doing background drop tables";
2860
2861
	n_tables_to_drop = row_drop_tables_for_mysql_in_background();
2862
2863
	if (n_tables_to_drop > 0) {
2864
		/* Do not monopolize the CPU even if there are tables waiting
2865
		in the background drop queue. (It is essentially a bug if
2866
		MySQL tries to drop a table while there are still open handles
2867
		to it and we had to put it to the background drop queue.) */
2868
2869
		os_thread_sleep(100000);
2870
	}
2871
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2872
	if (srv_n_purge_threads == 0) {
2873
		srv_main_thread_op_info = "master purging";
2874
2875
		srv_master_do_purge();
2876
	}
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2877
2878
	srv_main_thread_op_info = "reserving kernel mutex";
2879
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2880
	mutex_enter(&kernel_mutex);
2881
	if (srv_activity_count != old_activity_count) {
2882
		mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2883
		goto loop;
2884
	}
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2885
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2886
2887
	srv_main_thread_op_info = "doing insert buffer merge";
2888
2889
	if (srv_fast_shutdown && srv_shutdown_state > 0) {
2890
		n_bytes_merged = 0;
2891
	} else {
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2892
		/* This should do an amount of IO similar to the number of
2893
		dirty pages that will be flushed in the call to
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2894
		buf_flush_list below. Otherwise, the system favors
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2895
		clean pages over cleanup throughput. */
2896
		n_bytes_merged = ibuf_contract_for_n_pages(FALSE,
2897
							   PCT_IO(100));
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2898
	}
2899
2900
	srv_main_thread_op_info = "reserving kernel mutex";
2901
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2902
	mutex_enter(&kernel_mutex);
2903
	if (srv_activity_count != old_activity_count) {
2904
		mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2905
		goto loop;
2906
	}
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2907
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2908
2909
flush_loop:
2910
	srv_main_thread_op_info = "flushing buffer pool pages";
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2911
	srv_main_flush_loops++;
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2912
	if (srv_fast_shutdown < 2) {
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2913
		n_pages_flushed = buf_flush_list(
2914
			  PCT_IO(100), IB_ULONGLONG_MAX);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2915
	} else {
2916
		/* In the fastest shutdown we do not flush the buffer pool
2917
		to data files: we set n_pages_flushed to 0 artificially. */
2918
2919
		n_pages_flushed = 0;
2920
	}
2921
2922
	srv_main_thread_op_info = "reserving kernel mutex";
2923
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2924
	mutex_enter(&kernel_mutex);
2925
	if (srv_activity_count != old_activity_count) {
2926
		mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2927
		goto loop;
2928
	}
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2929
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2930
2931
	srv_main_thread_op_info = "waiting for buffer pool flush to end";
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
2932
	buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2933
641.2.3 by Monty Taylor
InnoDB Plugin 1.0.4
2934
	/* Flush logs if needed */
2935
	srv_sync_log_buffer_in_background();
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2936
2937
	srv_main_thread_op_info = "making checkpoint";
2938
2939
	log_checkpoint(TRUE, FALSE);
2940
2941
	if (buf_get_modified_ratio_pct() > srv_max_buf_pool_modified_pct) {
2942
2943
		/* Try to keep the number of modified pages in the
2944
		buffer pool under the limit wished by the user */
2945
2946
		goto flush_loop;
2947
	}
2948
2949
	srv_main_thread_op_info = "reserving kernel mutex";
2950
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2951
	mutex_enter(&kernel_mutex);
2952
	if (srv_activity_count != old_activity_count) {
2953
		mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2954
		goto loop;
2955
	}
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
2956
	mutex_exit(&kernel_mutex);
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
2957
	/*
2958
	srv_main_thread_op_info = "archiving log (if log archive is on)";
2959
2960
	log_archive_do(FALSE, &n_bytes_archived);
2961
	*/
2962
	n_bytes_archived = 0;
2963
2964
	/* Keep looping in the background loop if still work to do */
2965
2966
	if (srv_fast_shutdown && srv_shutdown_state > 0) {
2967
		if (n_tables_to_drop + n_pages_flushed
2968
		    + n_bytes_archived != 0) {
2969
2970
			/* If we are doing a fast shutdown (= the default)
2971
			we do not do purge or insert buffer merge. But we
2972
			flush the buffer pool completely to disk.
2973
			In a 'very fast' shutdown we do not flush the buffer
2974
			pool to data files: we have set n_pages_flushed to
2975
			0 artificially. */
2976
2977
			goto background_loop;
2978
		}
2979
	} else if (n_tables_to_drop
2980
		   + n_pages_purged + n_bytes_merged + n_pages_flushed
2981
		   + n_bytes_archived != 0) {
2982
		/* In a 'slow' shutdown we run purge and the insert buffer
2983
		merge to completion */
2984
2985
		goto background_loop;
2986
	}
2987
2988
	/* There is no work for background operations either: suspend
2989
	master thread to wait for more server activity */
2990
2991
suspend_thread:
2992
	srv_main_thread_op_info = "suspending";
2993
2994
	mutex_enter(&kernel_mutex);
2995
2996
	if (row_get_background_drop_list_len_low() > 0) {
2997
		mutex_exit(&kernel_mutex);
2998
2999
		goto loop;
3000
	}
3001
3002
	event = srv_suspend_thread();
3003
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3004
	mutex_exit(&kernel_mutex);
3005
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3006
	/* DO NOT CHANGE THIS STRING. innobase_start_or_create_for_mysql()
3007
	waits for database activity to die down when converting < 4.1.x
3008
	databases, and relies on this string being exactly as it is. InnoDB
3009
	manual also mentions this string in several places. */
3010
	srv_main_thread_op_info = "waiting for server activity";
3011
3012
	os_event_wait(event);
3013
3014
	if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
3015
		/* This is only extra safety, the thread should exit
3016
		already when the event wait ends */
3017
3018
		os_thread_exit(NULL);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3019
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3020
	}
3021
3022
	/* When there is user activity, InnoDB will set the event and the
3023
	main thread goes back to loop. */
3024
3025
	goto loop;
3026
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
3027
971.4.1 by Monty Taylor
GCC on Solaris build fixes.
3028
#if (!defined(__SUNPRO_C) && !defined(__SUNPRO_CC))
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3029
	OS_THREAD_DUMMY_RETURN;	/* Not reached, avoid compiler warning */
779.3.18 by Monty Taylor
Cleaned up warnings up through innodb.
3030
#endif
641.1.2 by Monty Taylor
Imported 1.0.1 with clean - with no changes.
3031
}
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3032
3033
/*********************************************************************//**
3034
Asynchronous purge thread.
3035
@return	a dummy parameter */
3036
UNIV_INTERN
3037
os_thread_ret_t
3038
srv_purge_thread(
3039
/*=============*/
3040
	void*	arg __attribute__((unused)))	/*!< in: a dummy parameter
3041
						required by os_thread_create */
3042
{
3043
	srv_slot_t*	slot;
3044
	ulint		slot_no = ULINT_UNDEFINED;
3045
	ulint		n_total_purged = ULINT_UNDEFINED;
3046
3047
	ut_a(srv_n_purge_threads == 1);
3048
3049
#ifdef UNIV_DEBUG_THREAD_CREATION
3050
	fprintf(stderr, "InnoDB: Purge thread running, id %lu\n",
3051
		os_thread_pf(os_thread_get_curr_id()));
3052
#endif /* UNIV_DEBUG_THREAD_CREATION */
3053
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3054
	mutex_enter(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3055
3056
	slot_no = srv_table_reserve_slot(SRV_WORKER);
3057
1819.9.46 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100721214151-r4dy4ozdeng56laq from MySQL InnoDB
3058
	slot = srv_table_get_nth_slot(slot_no);
3059
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3060
	++srv_n_threads_active[SRV_WORKER];
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3061
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3062
	mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3063
3064
	while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) {
3065
3066
		ulint	n_pages_purged;
3067
3068
		/* If there are very few records to purge or the last
3069
		purge didn't purge any records then wait for activity.
3070
	        We peek at the history len without holding any mutex
3071
		because in the worst case we will end up waiting for
3072
		the next purge event. */
3073
		if (trx_sys->rseg_history_len < srv_purge_batch_size
3074
		    || n_total_purged == 0) {
3075
3076
			os_event_t	event;
3077
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3078
			mutex_enter(&kernel_mutex);
3079
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3080
			event = srv_suspend_thread();
3081
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3082
			mutex_exit(&kernel_mutex);
3083
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3084
			os_event_wait(event);
3085
		}
3086
3087
		/* Check for shutdown and whether we should do purge at all. */
3088
		if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND
3089
		    || srv_shutdown_state != 0
3090
		    || srv_fast_shutdown) {
3091
3092
			break;
3093
		}
3094
3095
		n_total_purged = 0;
3096
3097
		/* Purge until there are no more records to purge and there is
3098
		no change in configuration or server state. */
3099
		do {
3100
			n_pages_purged = trx_purge(srv_purge_batch_size);
3101
3102
			n_total_purged += n_pages_purged;
3103
3104
		} while (n_pages_purged > 0 && !srv_fast_shutdown);
3105
3106
		srv_sync_log_buffer_in_background();
3107
	}
3108
1819.7.119 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100512205843-8e85wyl5ya3egxuo from MySQL InnoDB
3109
	mutex_enter(&kernel_mutex);
3110
1819.9.46 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100721214151-r4dy4ozdeng56laq from MySQL InnoDB
3111
	ut_ad(srv_table_get_nth_slot(slot_no) == slot);
3112
1819.7.101 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100511025711-ur7bbef75eh9bsk6 from MySQL InnoDB
3113
	/* Decrement the active count. */
3114
	srv_suspend_thread();
3115
1819.9.46 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100721214151-r4dy4ozdeng56laq from MySQL InnoDB
3116
	slot->in_use = FALSE;
1819.7.119 by Sunny Bains
Merge Revision revid:sunny.bains@oracle.com-20100512205843-8e85wyl5ya3egxuo from MySQL InnoDB
3117
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3118
	/* Free the thread local memory. */
3119
	thr_local_free(os_thread_get_curr_id());
3120
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3121
	mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3122
3123
#ifdef UNIV_DEBUG_THREAD_CREATION
3124
	fprintf(stderr, "InnoDB: Purge thread exiting, id %lu\n",
3125
		os_thread_pf(os_thread_get_curr_id()));
3126
#endif /* UNIV_DEBUG_THREAD_CREATION */
3127
3128
	/* We count the number of threads in os_thread_exit(). A created
3129
	thread should always use that to exit and not use return() to exit. */
3130
	os_thread_exit(NULL);
3131
3132
	OS_THREAD_DUMMY_RETURN;	/* Not reached, avoid compiler warning */
3133
}
3134
3135
/**********************************************************************//**
3136
Enqueues a task to server task queue and releases a worker thread, if there
3137
is a suspended one. */
3138
UNIV_INTERN
3139
void
3140
srv_que_task_enqueue_low(
3141
/*=====================*/
3142
	que_thr_t*	thr)	/*!< in: query thread */
3143
{
3144
	ut_ad(thr);
3145
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3146
	mutex_enter(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3147
3148
	UT_LIST_ADD_LAST(queue, srv_sys->tasks, thr);
3149
3150
	srv_release_threads(SRV_WORKER, 1);
1819.7.108 by Sunny Bains, Stewart Smith
Merge Revision revid:sunny.bains@oracle.com-20100512011810-oevtsyyudf6wusbi from MySQL InnoDB
3151
3152
	mutex_exit(&kernel_mutex);
1819.7.68 by Stewart Smith
Merge initial InnoDB+ import.
3153
}