1 # name : innodb_extend_slow.patch
2 # introduced : 11 or before
3 # maintainer : Yasufumi
6 # Any small change to this file in the main branch
7 # should be done or reviewed by the maintainer!
8 diff -ruN a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
9 --- a/storage/innobase/buf/buf0buf.c 2010-12-03 15:49:59.175955882 +0900
10 +++ b/storage/innobase/buf/buf0buf.c 2010-12-03 17:42:42.074307123 +0900
12 #include "dict0dict.h"
17 +/* prototypes for new functions added to ha_innodb.cc */
18 +trx_t* innobase_get_trx();
20 +inline void _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
23 + ulint block_hash_byte;
24 + byte block_hash_offset;
28 + if (!innobase_get_slow_log() || !trx || !trx->take_stats)
31 + if (!trx->distinct_page_access_hash) {
32 + trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
33 + memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
36 + block_hash = ut_hash_ulint((block->page.space << 20) + block->page.space +
37 + block->page.offset, DPAH_SIZE << 3);
38 + block_hash_byte = block_hash >> 3;
39 + block_hash_offset = (byte) block_hash & 0x07;
40 + if (block_hash_byte >= DPAH_SIZE)
41 + fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %d !!!\n", block_hash_byte, block_hash_offset);
42 + if (block_hash_offset > 7)
43 + fprintf(stderr, "!!! block_hash_byte = %lu block_hash_offset = %d !!!\n", block_hash_byte, block_hash_offset);
44 + if ((trx->distinct_page_access_hash[block_hash_byte] & ((byte) 0x01 << block_hash_offset)) == 0)
45 + trx->distinct_page_access++;
46 + trx->distinct_page_access_hash[block_hash_byte] |= (byte) 0x01 << block_hash_offset;
51 IMPLEMENTATION OF THE BUFFER POOL
52 @@ -2399,11 +2433,19 @@
59 + ib_uint64_t start_time;
60 + ib_uint64_t finish_time;
61 buf_pool_t* buf_pool = buf_pool_get(space, offset);
63 #ifndef UNIV_LOG_DEBUG
64 ut_ad(!ibuf_inside());
66 + if (innobase_get_slow_log()) {
67 + trx = innobase_get_trx();
69 buf_pool->stat.n_page_gets++;
73 //buf_pool_mutex_exit(buf_pool);
74 rw_lock_s_unlock(&buf_pool->page_hash_latch);
76 - buf_read_page(space, zip_size, offset);
77 + buf_read_page(space, zip_size, offset, trx);
79 #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
80 ut_a(++buf_dbg_counter % 37 || buf_validate());
81 @@ -2498,6 +2540,13 @@
82 /* Let us wait until the read operation
85 + if (innobase_get_slow_log() && trx && trx->take_stats)
87 + ut_usectime(&sec, &ms);
88 + start_time = (ib_uint64_t)sec * 1000000 + ms;
93 enum buf_io_fix io_fix;
95 @@ -2512,6 +2561,12 @@
99 + if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
101 + ut_usectime(&sec, &ms);
102 + finish_time = (ib_uint64_t)sec * 1000000 + ms;
103 + trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
107 #ifdef UNIV_IBUF_COUNT_DEBUG
108 @@ -2824,6 +2879,11 @@
111 mutex_t* block_mutex = NULL;
115 + ib_uint64_t start_time;
116 + ib_uint64_t finish_time;
117 buf_pool_t* buf_pool = buf_pool_get(space, offset);
120 @@ -2842,6 +2902,9 @@
121 ut_ad(!ibuf_inside() || ibuf_page_low(space, zip_size, offset,
122 FALSE, file, line, NULL));
124 + if (innobase_get_slow_log()) {
125 + trx = innobase_get_trx();
127 buf_pool->stat.n_page_gets++;
128 fold = buf_page_address_fold(space, offset);
130 @@ -2915,7 +2978,7 @@
134 - if (buf_read_page(space, zip_size, offset)) {
135 + if (buf_read_page(space, zip_size, offset, trx)) {
137 } else if (retries < BUF_PAGE_READ_MAX_RETRIES) {
139 @@ -3220,6 +3283,13 @@
140 /* Let us wait until the read operation
143 + if (innobase_get_slow_log() && trx && trx->take_stats)
145 + ut_usectime(&sec, &ms);
146 + start_time = (ib_uint64_t)sec * 1000000 + ms;
151 enum buf_io_fix io_fix;
153 @@ -3234,6 +3304,12 @@
157 + if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
159 + ut_usectime(&sec, &ms);
160 + finish_time = (ib_uint64_t)sec * 1000000 + ms;
161 + trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
165 fix_type = MTR_MEMO_BUF_FIX;
166 @@ -3259,13 +3335,17 @@
167 /* In the case of a first access, try to apply linear
170 - buf_read_ahead_linear(space, zip_size, offset);
171 + buf_read_ahead_linear(space, zip_size, offset, trx);
174 #ifdef UNIV_IBUF_COUNT_DEBUG
175 ut_a(ibuf_count_get(buf_block_get_space(block),
176 buf_block_get_page_no(block)) == 0);
178 + if (innobase_get_slow_log()) {
179 + _increment_page_get_statistics(block, trx);
185 @@ -3289,6 +3369,7 @@
186 unsigned access_time;
193 @@ -3366,13 +3447,17 @@
194 #if defined UNIV_DEBUG_FILE_ACCESSES || defined UNIV_DEBUG
195 ut_a(block->page.file_page_was_freed == FALSE);
197 + if (innobase_get_slow_log()) {
198 + trx = innobase_get_trx();
201 if (UNIV_UNLIKELY(!access_time)) {
202 /* In the case of a first access, try to apply linear
205 buf_read_ahead_linear(buf_block_get_space(block),
206 buf_block_get_zip_size(block),
207 - buf_block_get_page_no(block));
208 + buf_block_get_page_no(block), trx);
211 #ifdef UNIV_IBUF_COUNT_DEBUG
212 @@ -3382,6 +3467,9 @@
213 buf_pool = buf_pool_from_block(block);
214 buf_pool->stat.n_page_gets++;
216 + if (innobase_get_slow_log()) {
217 + _increment_page_get_statistics(block, trx);
222 @@ -3404,6 +3492,7 @@
223 buf_pool_t* buf_pool;
229 ut_ad(mtr->state == MTR_ACTIVE);
230 @@ -3490,6 +3579,11 @@
232 buf_pool->stat.n_page_gets++;
234 + if (innobase_get_slow_log()) {
235 + trx = innobase_get_trx();
236 + _increment_page_get_statistics(block, trx);
242 diff -ruN a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c
243 --- a/storage/innobase/buf/buf0rea.c 2010-12-03 17:32:15.617037263 +0900
244 +++ b/storage/innobase/buf/buf0rea.c 2010-12-03 17:42:42.075297193 +0900
246 treat the tablespace as dropped; this is a timestamp we
247 use to stop dangling page reads from a tablespace
248 which we have DISCARDed + IMPORTed back */
249 - ulint offset) /*!< in: page number */
250 + ulint offset, /*!< in: page number */
255 @@ -179,15 +180,15 @@
257 thd_wait_begin(NULL, THD_WAIT_DISKIO);
259 - *err = fil_io(OS_FILE_READ | wake_later,
260 + *err = _fil_io(OS_FILE_READ | wake_later,
261 sync, space, zip_size, offset, 0, zip_size,
262 - bpage->zip.data, bpage);
263 + bpage->zip.data, bpage, trx);
265 ut_a(buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE);
267 - *err = fil_io(OS_FILE_READ | wake_later,
268 + *err = _fil_io(OS_FILE_READ | wake_later,
269 sync, space, 0, offset, 0, UNIV_PAGE_SIZE,
270 - ((buf_block_t*) bpage)->frame, bpage);
271 + ((buf_block_t*) bpage)->frame, bpage, trx);
274 ut_a(*err == DB_SUCCESS);
277 ulint space, /*!< in: space id */
278 ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
279 - ulint offset) /*!< in: page number */
280 + ulint offset, /*!< in: page number */
283 buf_pool_t* buf_pool = buf_pool_get(space, offset);
284 ib_int64_t tablespace_version;
287 count = buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
289 - tablespace_version, offset);
290 + tablespace_version, offset, trx);
291 srv_buf_pool_reads += count;
292 if (err == DB_TABLESPACE_DELETED) {
293 ut_print_timestamp(stderr);
295 /*==================*/
296 ulint space, /*!< in: space id */
297 ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
298 - ulint offset) /*!< in: page number of a page; NOTE: the current thread
299 + ulint offset, /*!< in: page number of a page; NOTE: the current thread
300 must want access to this page (see NOTE 3 above) */
303 buf_pool_t* buf_pool = buf_pool_get(space, offset);
304 ib_int64_t tablespace_version;
306 count += buf_read_page_low(
308 ibuf_mode | OS_AIO_SIMULATED_WAKE_LATER,
309 - space, zip_size, FALSE, tablespace_version, i);
310 + space, zip_size, FALSE, tablespace_version, i, trx);
311 if (err == DB_TABLESPACE_DELETED) {
312 ut_print_timestamp(stderr);
315 buf_read_page_low(&err, sync && (i + 1 == n_stored),
316 BUF_READ_ANY_PAGE, space_ids[i],
317 zip_size, TRUE, space_versions[i],
319 + page_nos[i], NULL);
321 if (UNIV_UNLIKELY(err == DB_TABLESPACE_DELETED)) {
323 @@ -736,12 +739,12 @@
324 if ((i + 1 == n_stored) && sync) {
325 buf_read_page_low(&err, TRUE, BUF_READ_ANY_PAGE, space,
326 zip_size, TRUE, tablespace_version,
328 + page_nos[i], NULL);
330 buf_read_page_low(&err, FALSE, BUF_READ_ANY_PAGE
331 | OS_AIO_SIMULATED_WAKE_LATER,
332 space, zip_size, TRUE,
333 - tablespace_version, page_nos[i]);
334 + tablespace_version, page_nos[i], NULL);
338 diff -ruN a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
339 --- a/storage/innobase/fil/fil0fil.c 2010-12-03 15:53:54.610037199 +0900
340 +++ b/storage/innobase/fil/fil0fil.c 2010-12-03 17:42:42.079064198 +0900
341 @@ -4423,7 +4423,7 @@
342 node->name, node->handle, buf,
343 offset_low, offset_high,
349 node->size += n_pages;
350 @@ -4750,7 +4750,7 @@
351 i/o on a tablespace which does not exist */
357 ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
358 ORed to OS_FILE_LOG, if a log i/o
359 @@ -4775,8 +4775,9 @@
360 void* buf, /*!< in/out: buffer where to store read data
361 or from where to write; in aio this must be
362 appropriately aligned */
363 - void* message) /*!< in: message for aio handler if non-sync
364 + void* message, /*!< in: message for aio handler if non-sync
365 aio used, else ignored */
370 @@ -4946,7 +4947,7 @@
372 /* Queue the aio request */
373 ret = os_aio(type, mode | wake_later, node->name, node->handle, buf,
374 - offset_low, offset_high, len, node, message);
375 + offset_low, offset_high, len, node, message, trx);
379 diff -ruN a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
380 --- a/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:36:44.293955189 +0900
381 +++ b/storage/innobase/handler/ha_innodb.cc 2010-12-03 17:42:42.090024586 +0900
382 @@ -1546,6 +1546,16 @@
383 trx->check_unique_secondary = !thd_test_options(
384 thd, OPTION_RELAXED_UNIQUE_CHECKS);
386 +#ifdef EXTENDED_SLOWLOG
387 + if (thd_log_slow_verbosity(thd) & SLOG_V_INNODB) {
388 + trx->take_stats = TRUE;
390 + trx->take_stats = FALSE;
393 + trx->take_stats = FALSE;
399 @@ -1600,6 +1610,32 @@
403 +/*************************************************************************
404 +Gets current trx. */
409 + THD *thd=current_thd;
410 + if (likely(thd != 0)) {
411 + trx_t*& trx = thd_to_trx(thd);
420 +innobase_get_slow_log()
422 +#ifdef EXTENDED_SLOWLOG
423 + return((ibool) thd_opt_slow_log());
429 /*********************************************************************//**
430 Note that a transaction has been registered with MySQL.
431 @return true if transaction is registered with MySQL 2PC coordinator */
432 @@ -9284,6 +9320,25 @@
433 statement has ended */
435 if (trx->n_mysql_tables_in_use == 0) {
436 +#ifdef EXTENDED_SLOWLOG
437 + increment_thd_innodb_stats(thd,
438 + (unsigned long long) trx->id,
441 + trx->io_reads_wait_timer,
442 + trx->lock_que_wait_timer,
443 + trx->innodb_que_wait_timer,
444 + trx->distinct_page_access);
448 + trx->io_reads_wait_timer = 0;
449 + trx->lock_que_wait_timer = 0;
450 + trx->innodb_que_wait_timer = 0;
451 + trx->distinct_page_access = 0;
452 + if (trx->distinct_page_access_hash)
453 + memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
456 trx->mysql_n_tables_locked = 0;
457 prebuilt->used_in_HANDLER = FALSE;
458 diff -ruN a/storage/innobase/include/buf0rea.h b/storage/innobase/include/buf0rea.h
459 --- a/storage/innobase/include/buf0rea.h 2010-12-03 15:18:48.891024406 +0900
460 +++ b/storage/innobase/include/buf0rea.h 2010-12-03 17:42:42.096026873 +0900
465 +#include "trx0types.h"
466 #include "buf0types.h"
468 /********************************************************************//**
471 ulint space, /*!< in: space id */
472 ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
473 - ulint offset);/*!< in: page number */
474 + ulint offset, /*!< in: page number */
476 /********************************************************************//**
477 Applies linear read-ahead if in the buf_pool the page is a border page of
478 a linear read-ahead area and all the pages in the area have been accessed.
480 /*==================*/
481 ulint space, /*!< in: space id */
482 ulint zip_size,/*!< in: compressed page size in bytes, or 0 */
483 - ulint offset);/*!< in: page number of a page; NOTE: the current thread
484 + ulint offset, /*!< in: page number of a page; NOTE: the current thread
485 must want access to this page (see NOTE 3 above) */
487 /********************************************************************//**
488 Issues read requests for pages which the ibuf module wants to read in, in
489 order to contract the insert buffer tree. Technically, this function is like
490 diff -ruN a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
491 --- a/storage/innobase/include/fil0fil.h 2010-12-03 15:09:51.290958543 +0900
492 +++ b/storage/innobase/include/fil0fil.h 2010-12-03 17:42:42.097027548 +0900
494 Reads or writes data. This operation is asynchronous (aio).
495 @return DB_SUCCESS, or DB_TABLESPACE_DELETED if we are trying to do
496 i/o on a tablespace which does not exist */
497 +#define fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message) \
498 + _fil_io(type, sync, space_id, zip_size, block_offset, byte_offset, len, buf, message, NULL)
505 ulint type, /*!< in: OS_FILE_READ or OS_FILE_WRITE,
506 ORed to OS_FILE_LOG, if a log i/o
508 void* buf, /*!< in/out: buffer where to store read data
509 or from where to write; in aio this must be
510 appropriately aligned */
511 - void* message); /*!< in: message for aio handler if non-sync
512 + void* message, /*!< in: message for aio handler if non-sync
513 aio used, else ignored */
515 /**********************************************************************//**
516 Waits for an aio operation to complete. This function is used to write the
517 handler for completed requests. The aio array of pending requests is divided
518 diff -ruN a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h
519 --- a/storage/innobase/include/os0file.h 2010-11-03 07:01:13.000000000 +0900
520 +++ b/storage/innobase/include/os0file.h 2010-12-03 17:42:42.100023783 +0900
525 +#include "trx0types.h"
529 @@ -277,13 +278,17 @@
530 pfs_os_file_close_func(file, __FILE__, __LINE__)
532 # define os_aio(type, mode, name, file, buf, offset, offset_high, \
533 - n, message1, message2) \
534 + n, message1, message2, trx) \
535 pfs_os_aio_func(type, mode, name, file, buf, offset, \
536 - offset_high, n, message1, message2, \
537 + offset_high, n, message1, message2, trx, \
540 # define os_file_read(file, buf, offset, offset_high, n) \
541 - pfs_os_file_read_func(file, buf, offset, offset_high, n, \
542 + pfs_os_file_read_func(file, buf, offset, offset_high, n, NULL, \
543 + __FILE__, __LINE__)
545 +# define os_file_read_trx(file, buf, offset, offset_high, n, trx) \
546 + pfs_os_file_read_func(file, buf, offset, offset_high, n, trx, \
549 # define os_file_read_no_error_handling(file, buf, offset, \
550 @@ -319,12 +324,15 @@
551 # define os_file_close(file) os_file_close_func(file)
553 # define os_aio(type, mode, name, file, buf, offset, offset_high, \
554 - n, message1, message2) \
555 + n, message1, message2, trx) \
556 os_aio_func(type, mode, name, file, buf, offset, offset_high, n,\
557 - message1, message2)
558 + message1, message2, trx)
560 # define os_file_read(file, buf, offset, offset_high, n) \
561 - os_file_read_func(file, buf, offset, offset_high, n)
562 + os_file_read_func(file, buf, offset, offset_high, n, NULL)
564 +# define os_file_read_trx(file, buf, offset, offset_high, n, trx) \
565 + os_file_read_func(file, buf, offset, offset_high, n, trx)
567 # define os_file_read_no_error_handling(file, buf, offset, \
570 ulint offset_high,/*!< in: most significant 32 bits of
572 ulint n, /*!< in: number of bytes to read */
574 const char* src_file,/*!< in: file name where func invoked */
575 ulint src_line);/*!< in: line where the func invoked */
578 (can be used to identify a completed
579 aio operation); ignored if mode is
582 const char* src_file,/*!< in: file name where func invoked */
583 ulint src_line);/*!< in: line where the func invoked */
584 /*******************************************************************//**
586 offset where to read */
587 ulint offset_high,/*!< in: most significant 32 bits of
589 - ulint n); /*!< in: number of bytes to read */
590 + ulint n, /*!< in: number of bytes to read */
592 /*******************************************************************//**
593 Rewind file to its start, read at most size - 1 bytes from it to str, and
594 NUL-terminate str. All errors are silently ignored. This function is
595 @@ -1046,10 +1057,11 @@
596 (can be used to identify a completed
597 aio operation); ignored if mode is
599 - void* message2);/*!< in: message for the aio handler
600 + void* message2,/*!< in: message for the aio handler
601 (can be used to identify a completed
602 aio operation); ignored if mode is
605 /************************************************************************//**
606 Wakes up all async i/o threads so that they know to exit themselves in
608 diff -ruN a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic
609 --- a/storage/innobase/include/os0file.ic 2010-11-03 07:01:13.000000000 +0900
610 +++ b/storage/innobase/include/os0file.ic 2010-12-03 17:42:42.102024458 +0900
612 (can be used to identify a completed
613 aio operation); ignored if mode is
616 const char* src_file,/*!< in: file name where func invoked */
617 ulint src_line)/*!< in: line where the func invoked */
622 result = os_aio_func(type, mode, name, file, buf, offset, offset_high,
623 - n, message1, message2);
624 + n, message1, message2, trx);
626 register_pfs_file_io_end(locker, n);
629 ulint offset_high,/*!< in: most significant 32 bits of
631 ulint n, /*!< in: number of bytes to read */
633 const char* src_file,/*!< in: file name where func invoked */
634 ulint src_line)/*!< in: line where the func invoked */
637 register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ,
640 - result = os_file_read_func(file, buf, offset, offset_high, n);
641 + result = os_file_read_func(file, buf, offset, offset_high, n, trx);
643 register_pfs_file_io_end(locker, n);
645 diff -ruN a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
646 --- a/storage/innobase/include/srv0srv.h 2010-12-03 17:32:15.634987408 +0900
647 +++ b/storage/innobase/include/srv0srv.h 2010-12-03 17:42:42.104028644 +0900
649 #define SRV_AUTO_EXTEND_INCREMENT \
650 (srv_auto_extend_increment * ((1024 * 1024) / UNIV_PAGE_SIZE))
652 +/* prototypes for new functions added to ha_innodb.cc */
653 +ibool innobase_get_slow_log();
655 /* This is set to the MySQL server value for this variable. */
656 extern uint srv_lower_case_table_names;
658 diff -ruN a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
659 --- a/storage/innobase/include/trx0trx.h 2010-12-03 15:41:52.049372966 +0900
660 +++ b/storage/innobase/include/trx0trx.h 2010-12-03 17:42:42.107024532 +0900
662 /*------------------------------*/
663 char detailed_error[256]; /*!< detailed error message for last
665 + /*------------------------------*/
667 + ib_uint64_t io_read;
668 + ulint io_reads_wait_timer;
669 + ib_uint64_t lock_que_wait_ustarted;
670 + ulint lock_que_wait_timer;
671 + ulint innodb_que_wait_timer;
672 + ulint distinct_page_access;
673 +#define DPAH_SIZE 8192
674 + byte* distinct_page_access_hash;
678 #define TRX_MAX_N_THREADS 32 /* maximum number of
679 diff -ruN a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
680 --- a/storage/innobase/lock/lock0lock.c 2010-12-03 15:09:51.297986437 +0900
681 +++ b/storage/innobase/lock/lock0lock.c 2010-12-03 17:42:42.111024587 +0900
682 @@ -1755,6 +1755,8 @@
689 ut_ad(mutex_own(&kernel_mutex));
691 @@ -1813,6 +1815,10 @@
692 trx->que_state = TRX_QUE_LOCK_WAIT;
693 trx->was_chosen_as_deadlock_victim = FALSE;
694 trx->wait_started = time(NULL);
695 + if (innobase_get_slow_log() && trx->take_stats) {
696 + ut_usectime(&sec, &ms);
697 + trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
700 ut_a(que_thr_stop(thr));
702 @@ -3764,6 +3770,8 @@
709 ut_ad(mutex_own(&kernel_mutex));
711 @@ -3819,6 +3827,10 @@
715 + if (innobase_get_slow_log() && trx->take_stats) {
716 + ut_usectime(&sec, &ms);
717 + trx->lock_que_wait_ustarted = (ib_uint64_t)sec * 1000000 + ms;
719 trx->que_state = TRX_QUE_LOCK_WAIT;
720 trx->was_chosen_as_deadlock_victim = FALSE;
721 trx->wait_started = time(NULL);
722 diff -ruN a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c
723 --- a/storage/innobase/os/os0file.c 2010-12-03 17:32:15.644024974 +0900
724 +++ b/storage/innobase/os/os0file.c 2010-12-03 17:42:42.117023467 +0900
726 #include "srv0start.h"
729 +#include "trx0sys.h"
730 +#include "trx0trx.h"
731 #include "log0recv.h"
732 #ifndef UNIV_HOTBACKUP
733 # include "os0sync.h"
734 @@ -2202,13 +2204,18 @@
735 ulint n, /*!< in: number of bytes to read */
736 ulint offset, /*!< in: least significant 32 bits of file
737 offset from where to read */
738 - ulint offset_high) /*!< in: most significant 32 bits of
739 + ulint offset_high, /*!< in: most significant 32 bits of
744 #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
746 #endif /* HAVE_PREAD && !HAVE_BROKEN_PREAD */
749 + ib_uint64_t start_time;
750 + ib_uint64_t finish_time;
752 ut_a((offset & 0xFFFFFFFFUL) == offset);
754 @@ -2229,6 +2236,15 @@
758 + if (innobase_get_slow_log() && trx && trx->take_stats)
762 + ut_usectime(&sec, &ms);
763 + start_time = (ib_uint64_t)sec * 1000000 + ms;
767 #if defined(HAVE_PREAD) && !defined(HAVE_BROKEN_PREAD)
768 os_mutex_enter(os_file_count_mutex);
769 os_file_n_pending_preads++;
770 @@ -2242,6 +2258,13 @@
771 os_n_pending_reads--;
772 os_mutex_exit(os_file_count_mutex);
774 + if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
776 + ut_usectime(&sec, &ms);
777 + finish_time = (ib_uint64_t)sec * 1000000 + ms;
778 + trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
784 @@ -2278,6 +2301,13 @@
785 os_n_pending_reads--;
786 os_mutex_exit(os_file_count_mutex);
788 + if (innobase_get_slow_log() && trx && trx->take_stats && start_time)
790 + ut_usectime(&sec, &ms);
791 + finish_time = (ib_uint64_t)sec * 1000000 + ms;
792 + trx->io_reads_wait_timer += (ulint)(finish_time - start_time);
798 @@ -2418,7 +2448,8 @@
799 offset where to read */
800 ulint offset_high, /*!< in: most significant 32 bits of
802 - ulint n) /*!< in: number of bytes to read */
803 + ulint n, /*!< in: number of bytes to read */
808 @@ -2493,7 +2524,7 @@
809 os_bytes_read_since_printout += n;
812 - ret = os_file_pread(file, buf, n, offset, offset_high);
813 + ret = os_file_pread(file, buf, n, offset, offset_high, trx);
815 if ((ulint)ret == n) {
817 @@ -2622,7 +2653,7 @@
818 os_bytes_read_since_printout += n;
821 - ret = os_file_pread(file, buf, n, offset, offset_high);
822 + ret = os_file_pread(file, buf, n, offset, offset_high, NULL);
824 if ((ulint)ret == n) {
826 @@ -4016,10 +4047,11 @@
827 (can be used to identify a completed
828 aio operation); ignored if mode is
830 - void* message2)/*!< in: message for the aio handler
831 + void* message2,/*!< in: message for the aio handler
832 (can be used to identify a completed
833 aio operation); ignored if mode is
837 os_aio_array_t* array;
839 @@ -4060,8 +4092,8 @@
840 wait in the Windows case. */
842 if (type == OS_FILE_READ) {
843 - return(os_file_read(file, buf, offset,
845 + return(os_file_read_trx(file, buf, offset,
846 + offset_high, n, trx));
849 ut_a(type == OS_FILE_WRITE);
850 @@ -4099,6 +4131,11 @@
854 + if (trx && type == OS_FILE_READ)
859 slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
860 name, buf, offset, offset_high, n);
861 if (type == OS_FILE_READ) {
862 diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
863 --- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:32:15.648024399 +0900
864 +++ b/storage/innobase/srv/srv0srv.c 2010-12-03 17:45:05.067023254 +0900
866 #include "mysql/plugin.h"
867 #include "mysql/service_thd_wait.h"
869 +/* prototypes for new functions added to ha_innodb.cc */
870 +ibool innobase_get_slow_log();
872 /* This is set to the MySQL server value for this variable. It is only
873 needed for FOREIGN KEY definition parsing since FOREIGN KEY names are not
874 stored in the server metadata. The server stores and enforces it for
875 @@ -1259,6 +1262,10 @@
876 ibool has_slept = FALSE;
877 srv_conc_slot_t* slot = NULL;
879 + ib_uint64_t start_time = 0L;
880 + ib_uint64_t finish_time = 0L;
884 if (trx->mysql_thd != NULL
885 && thd_is_replication_slave_thread(trx->mysql_thd)) {
886 @@ -1335,6 +1342,7 @@
888 if (SRV_THREAD_SLEEP_DELAY > 0) {
889 os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
890 + trx->innodb_que_wait_timer += SRV_THREAD_SLEEP_DELAY;
894 @@ -1390,6 +1398,13 @@
895 /* Go to wait for the event; when a thread leaves InnoDB it will
896 release this thread */
898 + if (innobase_get_slow_log() && trx->take_stats) {
899 + ut_usectime(&sec, &ms);
900 + start_time = (ib_uint64_t)sec * 1000000 + ms;
905 trx->op_info = "waiting in InnoDB queue";
907 thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
908 @@ -1398,6 +1413,12 @@
912 + if (innobase_get_slow_log() && trx->take_stats && start_time) {
913 + ut_usectime(&sec, &ms);
914 + finish_time = (ib_uint64_t)sec * 1000000 + ms;
915 + trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
918 os_fast_mutex_lock(&srv_conc_mutex);
920 srv_conc_n_waiting_threads--;
921 diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
922 --- a/storage/innobase/trx/trx0trx.c 2010-12-03 15:41:52.053955669 +0900
923 +++ b/storage/innobase/trx/trx0trx.c 2010-12-03 17:42:42.127023410 +0900
925 trx->global_read_view = NULL;
926 trx->read_view = NULL;
930 + trx->io_reads_wait_timer = 0;
931 + trx->lock_que_wait_timer = 0;
932 + trx->innodb_que_wait_timer = 0;
933 + trx->distinct_page_access = 0;
934 + trx->distinct_page_access_hash = NULL;
935 + trx->take_stats = FALSE;
937 /* Set X/Open XA transaction identification to NULL */
938 memset(&trx->xid, 0, sizeof(trx->xid));
939 trx->xid.formatID = -1;
942 trx->mysql_process_no = os_proc_get_number();
944 + if (innobase_get_slow_log() && trx->take_stats) {
945 + trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
946 + memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
954 trx_t* trx) /*!< in, own: trx object */
956 + if (trx->distinct_page_access_hash)
958 + mem_free(trx->distinct_page_access_hash);
959 + trx->distinct_page_access_hash= NULL;
962 mutex_enter(&kernel_mutex);
964 UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx);
966 /*====================*/
967 trx_t* trx) /*!< in, own: trx object */
969 + if (trx->distinct_page_access_hash)
971 + mem_free(trx->distinct_page_access_hash);
972 + trx->distinct_page_access_hash= NULL;
975 mutex_enter(&kernel_mutex);
978 @@ -1153,6 +1179,9 @@
979 trx_t* trx) /*!< in: transaction */
986 ut_ad(mutex_own(&kernel_mutex));
987 ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
988 @@ -1167,6 +1196,11 @@
989 thr = UT_LIST_GET_FIRST(trx->wait_thrs);
992 + if (innobase_get_slow_log() && trx->take_stats) {
993 + ut_usectime(&sec, &ms);
994 + now = (ib_uint64_t)sec * 1000000 + ms;
995 + trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
997 trx->que_state = TRX_QUE_RUNNING;
1000 @@ -1180,6 +1214,9 @@
1001 trx_t* trx) /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
1008 ut_ad(mutex_own(&kernel_mutex));
1009 ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
1010 @@ -1194,6 +1231,11 @@
1011 thr = UT_LIST_GET_FIRST(trx->wait_thrs);
1014 + if (innobase_get_slow_log() && trx->take_stats) {
1015 + ut_usectime(&sec, &ms);
1016 + now = (ib_uint64_t)sec * 1000000 + ms;
1017 + trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
1019 trx->que_state = TRX_QUE_RUNNING;