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 < 0 || 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 < 0 || 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 @@ -2397,11 +2431,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 @@ -2497,6 +2539,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 @@ -2511,6 +2560,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 @@ -2823,6 +2878,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 @@ -2840,6 +2900,9 @@
121 #ifndef UNIV_LOG_DEBUG
122 ut_ad(!ibuf_inside() || ibuf_page(space, zip_size, offset, 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 @@ -2913,7 +2976,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 @@ -3216,6 +3279,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 @@ -3230,6 +3300,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 @@ -3255,13 +3331,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 @@ -3285,6 +3365,7 @@
186 unsigned access_time;
193 @@ -3362,13 +3443,17 @@
194 #ifdef UNIV_DEBUG_FILE_ACCESSES
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 @@ -3378,6 +3463,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 @@ -3400,6 +3488,7 @@
223 buf_pool_t* buf_pool;
229 ut_ad(mtr->state == MTR_ACTIVE);
230 @@ -3486,6 +3575,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 @@ -4395,7 +4395,7 @@
342 node->name, node->handle, buf,
343 offset_low, offset_high,
349 node->size += n_pages;
350 @@ -4722,7 +4722,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 @@ -4747,8 +4747,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 @@ -4918,7 +4919,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 @@ -1526,6 +1526,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 @@ -1580,6 +1590,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 @@ -9200,6 +9236,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 @@ -1044,10 +1055,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 TRUE if the MySQL user has set it in MySQL */
656 extern ibool 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 @@ -3692,6 +3698,8 @@
709 ut_ad(mutex_own(&kernel_mutex));
711 @@ -3747,6 +3755,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 @@ -2177,13 +2179,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 @@ -2204,6 +2211,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 @@ -2217,6 +2233,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 @@ -2253,6 +2276,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 @@ -2393,7 +2423,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 @@ -2468,7 +2499,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 @@ -2597,7 +2628,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 @@ -3619,7 +3650,8 @@
828 ulint offset_high, /*!< in: most significant 32 bits of
830 - ulint len) /*!< in: length of the block to read or write */
831 + ulint len, /*!< in: length of the block to read or write */
834 os_aio_slot_t* slot = NULL;
836 @@ -3991,10 +4023,11 @@
837 (can be used to identify a completed
838 aio operation); ignored if mode is
840 - void* message2)/*!< in: message for the aio handler
841 + void* message2,/*!< in: message for the aio handler
842 (can be used to identify a completed
843 aio operation); ignored if mode is
847 os_aio_array_t* array;
849 @@ -4035,8 +4068,8 @@
850 wait in the Windows case. */
852 if (type == OS_FILE_READ) {
853 - return(os_file_read(file, buf, offset,
855 + return(os_file_read_trx(file, buf, offset,
856 + offset_high, n, trx));
859 ut_a(type == OS_FILE_WRITE);
860 @@ -4074,8 +4107,13 @@
864 + if (trx && type == OS_FILE_READ)
869 slot = os_aio_array_reserve_slot(type, array, message1, message2, file,
870 - name, buf, offset, offset_high, n);
871 + name, buf, offset, offset_high, n, trx);
872 if (type == OS_FILE_READ) {
873 if (srv_use_native_aio) {
875 diff -ruN a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
876 --- a/storage/innobase/srv/srv0srv.c 2010-12-03 17:32:15.648024399 +0900
877 +++ b/storage/innobase/srv/srv0srv.c 2010-12-03 17:45:05.067023254 +0900
879 #include "mysql/plugin.h"
880 #include "mysql/service_thd_wait.h"
882 +/* prototypes for new functions added to ha_innodb.cc */
883 +ibool innobase_get_slow_log();
885 /* This is set to TRUE if the MySQL user has set it in MySQL; currently
886 affects only FOREIGN KEY definition parsing */
887 UNIV_INTERN ibool srv_lower_case_table_names = FALSE;
888 @@ -1219,6 +1222,10 @@
889 ibool has_slept = FALSE;
890 srv_conc_slot_t* slot = NULL;
892 + ib_uint64_t start_time = 0L;
893 + ib_uint64_t finish_time = 0L;
897 if (trx->mysql_thd != NULL
898 && thd_is_replication_slave_thread(trx->mysql_thd)) {
899 @@ -1295,6 +1302,7 @@
901 if (SRV_THREAD_SLEEP_DELAY > 0) {
902 os_thread_sleep(SRV_THREAD_SLEEP_DELAY);
903 + trx->innodb_que_wait_timer += SRV_THREAD_SLEEP_DELAY;
907 @@ -1350,6 +1358,13 @@
908 /* Go to wait for the event; when a thread leaves InnoDB it will
909 release this thread */
911 + if (innobase_get_slow_log() && trx->take_stats) {
912 + ut_usectime(&sec, &ms);
913 + start_time = (ib_uint64_t)sec * 1000000 + ms;
918 trx->op_info = "waiting in InnoDB queue";
920 thd_wait_begin(trx->mysql_thd, THD_WAIT_ROW_TABLE_LOCK);
921 @@ -1358,6 +1373,12 @@
925 + if (innobase_get_slow_log() && trx->take_stats && start_time) {
926 + ut_usectime(&sec, &ms);
927 + finish_time = (ib_uint64_t)sec * 1000000 + ms;
928 + trx->innodb_que_wait_timer += (ulint)(finish_time - start_time);
931 os_fast_mutex_lock(&srv_conc_mutex);
933 srv_conc_n_waiting_threads--;
934 diff -ruN a/storage/innobase/trx/trx0trx.c b/storage/innobase/trx/trx0trx.c
935 --- a/storage/innobase/trx/trx0trx.c 2010-12-03 15:41:52.053955669 +0900
936 +++ b/storage/innobase/trx/trx0trx.c 2010-12-03 17:42:42.127023410 +0900
938 trx->global_read_view = NULL;
939 trx->read_view = NULL;
943 + trx->io_reads_wait_timer = 0;
944 + trx->lock_que_wait_timer = 0;
945 + trx->innodb_que_wait_timer = 0;
946 + trx->distinct_page_access = 0;
947 + trx->distinct_page_access_hash = NULL;
948 + trx->take_stats = FALSE;
950 /* Set X/Open XA transaction identification to NULL */
951 memset(&trx->xid, 0, sizeof(trx->xid));
952 trx->xid.formatID = -1;
955 trx->mysql_process_no = os_proc_get_number();
957 + if (innobase_get_slow_log() && trx->take_stats) {
958 + trx->distinct_page_access_hash = mem_alloc(DPAH_SIZE);
959 + memset(trx->distinct_page_access_hash, 0, DPAH_SIZE);
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);
977 UT_LIST_REMOVE(mysql_trx_list, trx_sys->mysql_trx_list, trx);
979 /*====================*/
980 trx_t* trx) /*!< in, own: trx object */
982 + if (trx->distinct_page_access_hash)
984 + mem_free(trx->distinct_page_access_hash);
985 + trx->distinct_page_access_hash= NULL;
988 mutex_enter(&kernel_mutex);
991 @@ -1091,6 +1117,9 @@
992 trx_t* trx) /*!< in: transaction */
999 ut_ad(mutex_own(&kernel_mutex));
1000 ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
1001 @@ -1105,6 +1134,11 @@
1002 thr = UT_LIST_GET_FIRST(trx->wait_thrs);
1005 + if (innobase_get_slow_log() && trx->take_stats) {
1006 + ut_usectime(&sec, &ms);
1007 + now = (ib_uint64_t)sec * 1000000 + ms;
1008 + trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
1010 trx->que_state = TRX_QUE_RUNNING;
1013 @@ -1118,6 +1152,9 @@
1014 trx_t* trx) /*!< in: transaction in the TRX_QUE_LOCK_WAIT state */
1021 ut_ad(mutex_own(&kernel_mutex));
1022 ut_ad(trx->que_state == TRX_QUE_LOCK_WAIT);
1023 @@ -1132,6 +1169,11 @@
1024 thr = UT_LIST_GET_FIRST(trx->wait_thrs);
1027 + if (innobase_get_slow_log() && trx->take_stats) {
1028 + ut_usectime(&sec, &ms);
1029 + now = (ib_uint64_t)sec * 1000000 + ms;
1030 + trx->lock_que_wait_timer += (ulint)(now - trx->lock_que_wait_ustarted);
1032 trx->que_state = TRX_QUE_RUNNING;