Skip to content

Commit a3acd72

Browse files
author
Jan Lindström
committed
Merge InnoDB fixes from 5.5 revisions 4229, 4230, 4233, 4237 and 4238 i.e.
4229: MDEV-5670: Assertion failure in file buf0lru.c line 2355 Add more status information if repeatable. 4230: MDEV-5673: Crash while parallel dropping multiple tables under heavy load Improve long semaphore wait output to include all semaphore waits and try to find out if there is a sequence of waiters. 4233: Fix compiler errors on product build. 4237: Fix too agressive long semaphore wait output and add guard against introducing compression failures on insert buffer. 4238: Fix test failure caused by simulated compression failure on IBUF_DUMMY table.
1 parent 6192f0b commit a3acd72

File tree

8 files changed

+223
-67
lines changed

8 files changed

+223
-67
lines changed

mysql-test/include/mtr_warnings.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ INSERT INTO global_suppressions VALUES
159159
("InnoDB: Error: in ALTER TABLE `test`.`t[123]`"),
160160
("InnoDB: Error: in RENAME TABLE table `test`.`t1`"),
161161
("InnoDB: Error: table `test`.`t[123]` .*does not exist in the InnoDB internal"),
162+
("InnoDB: Warning: semaphore wait:"),
162163

163164
/*
164165
BUG#32080 - Excessive warnings on Solaris: setrlimit could not

storage/innobase/btr/btr0cur.cc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ btr_cur_latch_leaves(
271271
case BTR_MODIFY_TREE:
272272
/* x-latch also brothers from left to right */
273273
left_page_no = btr_page_get_prev(page, mtr);
274+
mode = latch_mode;
274275

275276
if (left_page_no != FIL_NULL) {
276277
get_block = btr_block_get(

storage/innobase/buf/buf0lru.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,24 @@ buf_LRU_block_remove_hashed(
22632263
" in the hash table\n",
22642264
(ulong) bpage->space,
22652265
(ulong) bpage->offset);
2266+
#ifdef UNIV_DEBUG
2267+
fprintf(stderr,
2268+
"InnoDB: in_page_hash %lu in_zip_hash %lu\n"
2269+
" in_free_list %lu in_flush_list %lu in_LRU_list %lu\n"
2270+
" zip.data %p zip_size %lu page_state %d\n",
2271+
bpage->in_page_hash, bpage->in_zip_hash,
2272+
bpage->in_free_list, bpage->in_flush_list,
2273+
bpage->in_LRU_list, bpage->zip.data,
2274+
buf_page_get_zip_size(bpage),
2275+
buf_page_get_state(bpage));
2276+
#else
2277+
fprintf(stderr,
2278+
"InnoDB: zip.data %p zip_size %lu page_state %d\n",
2279+
bpage->zip.data,
2280+
buf_page_get_zip_size(bpage),
2281+
buf_page_get_state(bpage));
2282+
#endif
2283+
22662284
if (hashed_bpage) {
22672285
fprintf(stderr,
22682286
"InnoDB: In hash table we find block"

storage/innobase/page/page0zip.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1314,8 +1314,10 @@ page_zip_compress(
13141314
records. */
13151315

13161316
if (srv_simulate_comp_failures
1317+
&& !dict_index_is_ibuf(index)
13171318
&& page_get_n_recs(page) >= 2
1318-
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)) {
1319+
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)
1320+
&& strcasecmp(index->table_name, "IBUF_DUMMY") != 0) {
13191321

13201322
#ifdef UNIV_DEBUG
13211323
fprintf(stderr,

storage/innobase/sync/sync0arr.cc

Lines changed: 87 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,33 @@ sync_array_get_nth_cell(
181181
return(arr->array + n);
182182
}
183183

184+
/******************************************************************//**
185+
Looks for a cell with the given thread id.
186+
@return pointer to cell or NULL if not found */
187+
static
188+
sync_cell_t*
189+
sync_array_find_thread(
190+
/*===================*/
191+
sync_array_t* arr, /*!< in: wait array */
192+
os_thread_id_t thread) /*!< in: thread id */
193+
{
194+
ulint i;
195+
sync_cell_t* cell;
196+
197+
for (i = 0; i < arr->n_cells; i++) {
198+
199+
cell = sync_array_get_nth_cell(arr, i);
200+
201+
if (cell->wait_object != NULL
202+
&& os_thread_eq(cell->thread, thread)) {
203+
204+
return(cell); /* Found */
205+
}
206+
}
207+
208+
return(NULL); /* Not found */
209+
}
210+
184211
/******************************************************************//**
185212
Reserves the mutex semaphore protecting a sync array. */
186213
static
@@ -432,8 +459,10 @@ static
432459
void
433460
sync_array_cell_print(
434461
/*==================*/
435-
FILE* file, /*!< in: file where to print */
436-
sync_cell_t* cell) /*!< in: sync cell */
462+
FILE* file, /*!< in: file where to print */
463+
sync_cell_t* cell, /*!< in: sync cell */
464+
os_thread_id_t* reserver) /*!< out: write reserver or
465+
0 */
437466
{
438467
ib_mutex_t* mutex;
439468
rw_lock_t* rwlock;
@@ -494,6 +523,7 @@ sync_array_cell_print(
494523
writer == RW_LOCK_EX
495524
? " exclusive\n"
496525
: " wait exclusive\n");
526+
*reserver = rwlock->writer_thread;
497527
}
498528

499529
fprintf(file,
@@ -519,32 +549,6 @@ sync_array_cell_print(
519549
}
520550

521551
#ifdef UNIV_SYNC_DEBUG
522-
/******************************************************************//**
523-
Looks for a cell with the given thread id.
524-
@return pointer to cell or NULL if not found */
525-
static
526-
sync_cell_t*
527-
sync_array_find_thread(
528-
/*===================*/
529-
sync_array_t* arr, /*!< in: wait array */
530-
os_thread_id_t thread) /*!< in: thread id */
531-
{
532-
ulint i;
533-
sync_cell_t* cell;
534-
535-
for (i = 0; i < arr->n_cells; i++) {
536-
537-
cell = sync_array_get_nth_cell(arr, i);
538-
539-
if (cell->wait_object != NULL
540-
&& os_thread_eq(cell->thread, thread)) {
541-
542-
return(cell); /* Found */
543-
}
544-
}
545-
546-
return(NULL); /* Not found */
547-
}
548552

549553
/******************************************************************//**
550554
Recursion step for deadlock detection.
@@ -606,6 +610,7 @@ sync_array_detect_deadlock(
606610
os_thread_id_t thread;
607611
ibool ret;
608612
rw_lock_debug_t*debug;
613+
os_thread_id_t reserver=0;
609614

610615
ut_a(arr);
611616
ut_a(start);
@@ -641,10 +646,10 @@ sync_array_detect_deadlock(
641646
depth);
642647
if (ret) {
643648
fprintf(stderr,
644-
"Mutex %p owned by thread %lu file %s line %lu\n",
649+
"Mutex %p owned by thread %lu file %s line %lu\n",
645650
mutex, (ulong) os_thread_pf(mutex->thread_id),
646651
mutex->file_name, (ulong) mutex->line);
647-
sync_array_cell_print(stderr, cell);
652+
sync_array_cell_print(stderr, cell, &reserver);
648653

649654
return(TRUE);
650655
}
@@ -682,7 +687,7 @@ sync_array_detect_deadlock(
682687
print:
683688
fprintf(stderr, "rw-lock %p ",
684689
(void*) lock);
685-
sync_array_cell_print(stderr, cell);
690+
sync_array_cell_print(stderr, cell, &reserver);
686691
rw_lock_debug_print(stderr, debug);
687692
return(TRUE);
688693
}
@@ -925,6 +930,7 @@ sync_array_print_long_waits_low(
925930
double diff;
926931
sync_cell_t* cell;
927932
void* wait_object;
933+
os_thread_id_t reserver=0;
928934

929935
cell = sync_array_get_nth_cell(arr, i);
930936

@@ -940,7 +946,7 @@ sync_array_print_long_waits_low(
940946
if (diff > SYNC_ARRAY_TIMEOUT) {
941947
fputs("InnoDB: Warning: a long semaphore wait:\n",
942948
stderr);
943-
sync_array_cell_print(stderr, cell);
949+
sync_array_cell_print(stderr, cell, &reserver);
944950
*noticed = TRUE;
945951
}
946952

@@ -955,6 +961,53 @@ sync_array_print_long_waits_low(
955961
}
956962
}
957963

964+
/* We found a long semaphore wait, wait all threads that are
965+
waiting for a semaphore. */
966+
if (*noticed) {
967+
for (i = 0; i < arr->n_cells; i++) {
968+
void* wait_object;
969+
os_thread_id_t reserver=0;
970+
sync_cell_t* cell;
971+
ulint loop = 0;
972+
973+
cell = sync_array_get_nth_cell(arr, i);
974+
975+
wait_object = cell->wait_object;
976+
977+
if (wait_object == NULL || !cell->waiting) {
978+
979+
continue;
980+
}
981+
982+
fputs("InnoDB: Warning: semaphore wait:\n",
983+
stderr);
984+
sync_array_cell_print(stderr, cell, &reserver);
985+
986+
/* Try to output cell information for writer recursive way */
987+
while (reserver != 0) {
988+
sync_cell_t* reserver_wait;
989+
990+
reserver_wait = sync_array_find_thread(arr, reserver);
991+
992+
if (reserver_wait &&
993+
reserver_wait->wait_object != NULL &&
994+
reserver_wait->waiting) {
995+
fputs("InnoDB: Warning: Writer thread is waiting this semaphore:\n",
996+
stderr);
997+
sync_array_cell_print(stderr, reserver_wait, &reserver);
998+
} else {
999+
reserver = 0;
1000+
}
1001+
1002+
/* This is protection against loop */
1003+
if (loop > 100) {
1004+
fputs("InnoDB: Warning: Too many waiting threads.\n", stderr);
1005+
break;
1006+
}
1007+
}
1008+
}
1009+
}
1010+
9581011
#undef SYNC_ARRAY_TIMEOUT
9591012

9601013
return(fatal);
@@ -1034,6 +1087,7 @@ sync_array_print_info_low(
10341087
{
10351088
ulint i;
10361089
ulint count = 0;
1090+
os_thread_id_t r = 0;
10371091

10381092
fprintf(file,
10391093
"OS WAIT ARRAY INFO: reservation count %ld\n",
@@ -1046,7 +1100,7 @@ sync_array_print_info_low(
10461100

10471101
if (cell->wait_object != NULL) {
10481102
count++;
1049-
sync_array_cell_print(file, cell);
1103+
sync_array_cell_print(file, cell, &r);
10501104
}
10511105
}
10521106
}

storage/xtradb/buf/buf0lru.cc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2429,6 +2429,25 @@ buf_LRU_block_remove_hashed(
24292429
" in the hash table\n",
24302430
(ulong) bpage->space,
24312431
(ulong) bpage->offset);
2432+
2433+
#ifdef UNIV_DEBUG
2434+
fprintf(stderr,
2435+
"InnoDB: in_page_hash %lu in_zip_hash %lu\n"
2436+
" in_free_list %lu in_flush_list %lu in_LRU_list %lu\n"
2437+
" zip.data %p zip_size %lu page_state %d\n",
2438+
bpage->in_page_hash, bpage->in_zip_hash,
2439+
bpage->in_free_list, bpage->in_flush_list,
2440+
bpage->in_LRU_list, bpage->zip.data,
2441+
buf_page_get_zip_size(bpage),
2442+
buf_page_get_state(bpage));
2443+
#else
2444+
fprintf(stderr,
2445+
"InnoDB: zip.data %p zip_size %lu page_state %d\n",
2446+
bpage->zip.data,
2447+
buf_page_get_zip_size(bpage),
2448+
buf_page_get_state(bpage));
2449+
#endif
2450+
24322451
if (hashed_bpage) {
24332452
fprintf(stderr,
24342453
"InnoDB: In hash table we find block"
@@ -2439,6 +2458,9 @@ buf_LRU_block_remove_hashed(
24392458
(const void*) bpage);
24402459
}
24412460

2461+
ut_a(buf_page_get_io_fix(bpage) == BUF_IO_NONE);
2462+
ut_a(bpage->buf_fix_count == 0);
2463+
24422464
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
24432465
mutex_exit(buf_page_get_mutex(bpage));
24442466
rw_lock_x_unlock(hash_lock);

storage/xtradb/page/page0zip.cc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,8 +1319,10 @@ page_zip_compress(
13191319
records. */
13201320

13211321
if (srv_simulate_comp_failures
1322+
&& !dict_index_is_ibuf(index)
13221323
&& page_get_n_recs(page) >= 2
1323-
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)) {
1324+
&& ((ulint)(rand() % 100) < srv_simulate_comp_failures)
1325+
&& strcasecmp(index->table_name, "IBUF_DUMMY") != 0) {
13241326

13251327
#ifdef UNIV_DEBUG
13261328
fprintf(stderr,

0 commit comments

Comments
 (0)