~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge Revision revid:marko.makela@oracle.com-20100505101406-u4low2x26q6itck0 from MySQL InnoDB

Original revid:marko.makela@oracle.com-20100505101406-u4low2x26q6itck0

Original Authors: Marko Mäkelä <marko.makela@oracle.com>
Original commit message:
Merge from mysql-5.1-innodb:

  ------------------------------------------------------------
  revno: 3446
  revision-id: marko.makela@oracle.com-20100505100507-6kcd2hf32hruxbv7
  parent: marko.makela@oracle.com-20100505095328-vetnl0flhmhao7p5
  committer: Marko Mäkelä <marko.makela@oracle.com>
  branch nick: 5.1-innodb
  timestamp: Wed 2010-05-05 13:05:07 +0300
  message:
    Add Valgrind diagnostics to track down Bug #38999.
  ------------------------------------------------------------

Show diffs side-by-side

added added

removed removed

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