From d08e5cfad2161784bb40682a81a161f768a3ff22 Mon Sep 17 00:00:00 2001 From: unknown Date: Thu, 2 Dec 2010 09:48:30 +0100 Subject: [PATCH 1/7] Fix problems seen in Buildbot: - Make sure creation of t1 is replicated before trying to create trigger on it on slave - Use safe #ifdef for declaration as for definition to avoid warning about unused static function. --- mysql-test/extra/rpl_tests/rpl_auto_increment.test | 1 + sql/set_var.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/mysql-test/extra/rpl_tests/rpl_auto_increment.test b/mysql-test/extra/rpl_tests/rpl_auto_increment.test index 06e3a154bc3..8d2f6c32233 100644 --- a/mysql-test/extra/rpl_tests/rpl_auto_increment.test +++ b/mysql-test/extra/rpl_tests/rpl_auto_increment.test @@ -251,6 +251,7 @@ connection master; CREATE TABLE t1(s VARCHAR(10)) ENGINE=myisam; # -slave.opt has --replicate-ignore-table=test.t_ignored1 CREATE TABLE t_ignored1(id INT AUTO_INCREMENT PRIMARY KEY) ENGINE=myisam; +sync_slave_with_master; connection slave; diff --git a/sql/set_var.cc b/sql/set_var.cc index 3270976e6a0..b9bd68747d3 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -128,7 +128,9 @@ static void fix_net_write_timeout(THD *thd, enum_var_type type); static void fix_net_retry_count(THD *thd, enum_var_type type); static void fix_max_join_size(THD *thd, enum_var_type type); static void fix_query_cache_size(THD *thd, enum_var_type type); +#ifdef HAVE_QUERY_CACHE static void fix_query_cache_min_res_unit(THD *thd, enum_var_type type); +#endif static void fix_myisam_max_sort_file_size(THD *thd, enum_var_type type); static void fix_max_binlog_size(THD *thd, enum_var_type type); static void fix_max_relay_log_size(THD *thd, enum_var_type type); From d0ad135b6093998217a2fb255d6ee7a36e1ef4e8 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Fri, 3 Dec 2010 23:19:13 +0200 Subject: [PATCH 2/7] Fixed compiler warnings. Fixed timing test failures. Fixed a failure in the Aria engines page cache and log handler (found with maria.maria-big test) - This could cause a core dump when deleting big blobs. - Added test to end_pagecache() to verify that page cache was correctly used. - inc_counter_for_resize_op and dec_counter_for_resize_op are called same number of times. - All page cache blocks was properly deallocated (empty) mysql-test/suite/innodb/t/innodb_bug38231.test: Fixed timing issue (code comment says it all) mysql-test/suite/innodb_plugin/t/innodb_bug38231.test: Fixed timing issue (code comment says it all) sql/debug_sync.cc: Fixed compiler warning storage/maria/ma_loghandler.c: Fixed bug found by maria.maria-big test: - Fixed race condition between update thread logging a very big blog and checkpoint thread. storage/maria/ma_pagecache.c: Added assert to ensure mutex was properly locked. Added test to end_pagecache() to verify that page cache was correctly used. - inc_counter_for_resize_op and dec_counter_for_resize_op are called same number of times. - All page cache blocks was properly deallocated (empty) In pagecache_delete_internal(), properly reset counters and pins if functions aborts. Added missing inc_counter_for_resize_op() to pagecache_wait_lock(). Added missing dec_counter_for_resize_op() to pagecache_delete() --- .../suite/innodb/t/innodb_bug38231.test | 5 ++ .../innodb_plugin/t/innodb_bug38231.test | 6 ++- sql/debug_sync.cc | 1 + storage/maria/ma_loghandler.c | 21 +++++--- storage/maria/ma_pagecache.c | 51 ++++++++++++++++++- 5 files changed, 76 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/innodb/t/innodb_bug38231.test b/mysql-test/suite/innodb/t/innodb_bug38231.test index 1611cb56203..5021f23d07e 100644 --- a/mysql-test/suite/innodb/t/innodb_bug38231.test +++ b/mysql-test/suite/innodb/t/innodb_bug38231.test @@ -76,6 +76,11 @@ UNLOCK TABLES; UNLOCK TABLES; -- connection con3 +# +# We may get a timeout error here if the tables are locked in a different +# order than expected. This is ok as the purpose of this patch is to ensure +# we don't get a crash in the previous unlock tables. +-- error 0, 1205 -- reap UNLOCK TABLES; diff --git a/mysql-test/suite/innodb_plugin/t/innodb_bug38231.test b/mysql-test/suite/innodb_plugin/t/innodb_bug38231.test index 05e39cc16ea..23d8061c9da 100644 --- a/mysql-test/suite/innodb_plugin/t/innodb_bug38231.test +++ b/mysql-test/suite/innodb_plugin/t/innodb_bug38231.test @@ -72,8 +72,12 @@ UNLOCK TABLES; # clean up -- connection con2 --- reap +# +# We may get a timeout error here if the tables are locked in a different +# order than expected. This is ok as the purpose of this patch is to ensure +# we don't get a crash in the previous unlock tables. -- error 0, 1205 +-- reap UNLOCK TABLES; -- connection con3 diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 23a649a89fa..c9c580c6442 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1719,6 +1719,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) if (action->execute) { const char *old_proc_info; + LINT_INIT(old_proc_info); action->execute--; diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 423cd2f0dd7..7c6521e167a 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007 MySQL AB & Sanja Belkin +/* Copyright (C) 2007 MySQL AB & Sanja Belkin. 2010 Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2526,11 +2526,10 @@ static my_bool translog_buffer_flush(struct st_translog_buffer *buffer) { /* some other flush in progress */ translog_wait_for_closing(buffer); + if (buffer->file != file || buffer->offset != offset || buffer->ver != ver) + DBUG_RETURN(0); /* some the thread flushed the buffer already */ } - if (buffer->file != file || buffer->offset != offset || buffer->ver != ver) - DBUG_RETURN(0); /* some the thread flushed the buffer already */ - if (buffer->overlay && translog_prev_buffer_flush_wait(buffer)) DBUG_RETURN(0); /* some the thread flushed the buffer already */ @@ -7648,18 +7647,28 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn) struct st_translog_buffer *buffer= log_descriptor.bc.buffer; lsn= log_descriptor.bc.buffer->last_lsn; /* fix lsn if it was horizon */ DBUG_PRINT("info", ("LSN to flush fixed to last lsn: (%lu,0x%lx)", - LSN_IN_PARTS(log_descriptor.bc.buffer->last_lsn))); + LSN_IN_PARTS(lsn))); last_buffer_no= log_descriptor.bc.buffer_no; log_descriptor.is_everything_flushed= 1; translog_force_current_buffer_to_finish(); translog_buffer_unlock(buffer); } - else + else if (log_descriptor.bc.buffer->prev_last_lsn != LSN_IMPOSSIBLE) { + /* fix lsn if it was horizon */ + lsn= log_descriptor.bc.buffer->prev_last_lsn; + DBUG_PRINT("info", ("LSN to flush fixed to prev last lsn: (%lu,0x%lx)", + LSN_IN_PARTS(lsn))); last_buffer_no= ((log_descriptor.bc.buffer_no + TRANSLOG_BUFFERS_NO -1) % TRANSLOG_BUFFERS_NO); translog_unlock(); } + else if (log_descriptor.bc.buffer->last_lsn == LSN_IMPOSSIBLE) + { + DBUG_PRINT("info", ("There is no LSNs yet generated => do nothing")); + translog_unlock(); + goto out; + } sent_to_disk= translog_get_sent_to_disk(); if (cmp_translog_addr(lsn, sent_to_disk) > 0) { diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 1bb82ba92cd..8b731f40cd0 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -1025,6 +1025,7 @@ finish: */ static inline void inc_counter_for_resize_op(PAGECACHE *pagecache) { + safe_mutex_assert_owner(&pagecache->cache_lock); pagecache->cnt_for_resize_op++; } @@ -1037,6 +1038,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) { #ifdef THREAD struct st_my_thread_var *last_thread; + safe_mutex_assert_owner(&pagecache->cache_lock); if (!--pagecache->cnt_for_resize_op && (last_thread= pagecache->resize_queue.last_thread)) { @@ -1084,6 +1086,37 @@ void change_pagecache_param(PAGECACHE *pagecache, uint division_limit, } +/* + Check that pagecache was used and cleaned up properly. +*/ + +#ifndef DBUG_OFF +void check_pagecache_is_cleaned_up(PAGECACHE *pagecache) +{ + DBUG_ENTER("check_pagecache_is_cleaned_up"); + /* + Ensure we called inc_counter_for_resize_op and dec_counter_for_resize_op + the same number of times. (If not, a resize() could never happen. + */ + DBUG_ASSERT(pagecache->cnt_for_resize_op == 0); + + if (pagecache->disk_blocks > 0) + { + if (pagecache->block_mem) + { + uint i; + for (i=0 ; i < pagecache->blocks_used ; i++) + { + DBUG_ASSERT(pagecache->block_root[i].status == 0); + DBUG_ASSERT(pagecache->block_root[i].type == PAGECACHE_EMPTY_PAGE); + } + } + } + DBUG_VOID_RETURN; +} +#endif + + /* Removes page cache from memory. Does NOT flush pages to disk. @@ -1106,6 +1139,10 @@ void end_pagecache(PAGECACHE *pagecache, my_bool cleanup) if (pagecache->disk_blocks > 0) { +#ifndef DBUG_OFF + check_pagecache_is_cleaned_up(pagecache); +#endif + if (pagecache->block_mem) { my_large_free(pagecache->block_mem, MYF(0)); @@ -2250,6 +2287,7 @@ static my_bool pagecache_wait_lock(PAGECACHE *pagecache, &pagecache->cache_lock); } while(thread->next); + inc_counter_for_resize_op(pagecache); #else DBUG_ASSERT(0); #endif @@ -3457,7 +3495,7 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, { /* this call is just 'hint' for the cache to free the page so we will - not interferes with flushing process but gust return success + not interferes with flushing process but must return success */ goto out; } @@ -3527,8 +3565,17 @@ static my_bool pagecache_delete_internal(PAGECACHE *pagecache, page_link->requests--; /* See NOTE for pagecache_unlock about registering requests. */ free_block(pagecache, block); + dec_counter_for_resize_op(pagecache); + return 0; out: + /* Cache is locked, so we can relese page before freeing it */ + if (make_lock_and_pin(pagecache, block, + PAGECACHE_LOCK_WRITE_UNLOCK, + PAGECACHE_UNPIN, FALSE)) + DBUG_ASSERT(0); + page_link->requests--; + unreg_request(pagecache, block, 1); dec_counter_for_resize_op(pagecache); return error; } @@ -3695,6 +3742,7 @@ restart: if (!page_link) { DBUG_PRINT("info", ("There is no such page in the cache")); + dec_counter_for_resize_op(pagecache); pagecache_pthread_mutex_unlock(&pagecache->cache_lock); DBUG_RETURN(0); } @@ -3707,6 +3755,7 @@ restart: "reassigned" : "in switch"))); PCBLOCK_INFO(block); page_link->requests--; + dec_counter_for_resize_op(pagecache); goto end; } /* See NOTE for pagecache_unlock about registering requests. */ From 8938ed57a4c533f3e56c5ac5ef5889c7944f7e22 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 4 Dec 2010 12:21:24 +0200 Subject: [PATCH 3/7] Fixed compiler warning Added missing inc_counter_for_resize_op(pagecache). (caused maria.maria-preload.test to fail) storage/maria/ma_loghandler.c: Fixed compiler warning storage/maria/ma_pagecache.c: Added missing inc_counter_for_resize_op(pagecache). (caused maria.maria-preload.test to fail) --- storage/maria/ma_loghandler.c | 1 + storage/maria/ma_pagecache.c | 3 +++ 2 files changed, 4 insertions(+) diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c index 7c6521e167a..a29c42cae68 100644 --- a/storage/maria/ma_loghandler.c +++ b/storage/maria/ma_loghandler.c @@ -7579,6 +7579,7 @@ my_bool translog_flush(TRANSLOG_ADDRESS lsn) DBUG_ASSERT(translog_status == TRANSLOG_OK || translog_status == TRANSLOG_READONLY); LINT_INIT(sent_to_disk); + LINT_INIT(last_buffer_no); pthread_mutex_lock(&log_descriptor.log_flush_lock); DBUG_PRINT("info", ("Everything is flushed up to (%lu,0x%lx)", diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 8b731f40cd0..83785e6a1af 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -1046,6 +1046,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) ("thread %ld", last_thread->next->id)); pagecache_pthread_cond_signal(&last_thread->next->suspend); } + DBUG_ASSERT((longlong) pagecache->cnt_for_resize_op >= 0); #else pagecache->cnt_for_resize_op--; #endif @@ -3626,6 +3627,8 @@ my_bool pagecache_delete_by_link(PAGECACHE *pagecache, */ DBUG_ASSERT((block->status & (PCBLOCK_IN_SWITCH | PCBLOCK_REASSIGNED)) == 0); + + inc_counter_for_resize_op(pagecache); /* make_lock_and_pin() can't fail here, because we are keeping pin on the block and it can't be evicted (which is cause of lock fail and retry) From 6426564753a8a023085307a53476e6a5bc7fc03c Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 4 Dec 2010 12:35:41 +0200 Subject: [PATCH 4/7] Fixed compiler warnings but calling field->store(longlong, unsigned_flag) with proper arguments. --- storage/oqgraph/ha_oqgraph.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/oqgraph/ha_oqgraph.cc b/storage/oqgraph/ha_oqgraph.cc index e0c66134858..cf9ef3d8997 100644 --- a/storage/oqgraph/ha_oqgraph.cc +++ b/storage/oqgraph/ha_oqgraph.cc @@ -748,19 +748,19 @@ int ha_oqgraph::fill_record(byte *record, const open_query::row &row) if (row.latch_indicator) { field[0]->set_notnull(); - field[0]->store((longlong) row.latch); + field[0]->store((longlong) row.latch, 0); } if (row.orig_indicator) { field[1]->set_notnull(); - field[1]->store((longlong) row.orig); + field[1]->store((longlong) row.orig, 0); } if (row.dest_indicator) { field[2]->set_notnull(); - field[2]->store((longlong) row.dest); + field[2]->store((longlong) row.dest, 0); } if (row.weight_indicator) @@ -772,13 +772,13 @@ int ha_oqgraph::fill_record(byte *record, const open_query::row &row) if (row.seq_indicator) { field[4]->set_notnull(); - field[4]->store((longlong) row.seq); + field[4]->store((longlong) row.seq, 0); } if (row.link_indicator) { field[5]->set_notnull(); - field[5]->store((longlong) row.link); + field[5]->store((longlong) row.link, 0); } if (ptrdiff) From 9baab6f5e3f4d0743f54ee4f58f8d42e5f00a0fb Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 4 Dec 2010 12:54:35 +0200 Subject: [PATCH 5/7] Fixed (wrong) compiler warning --- storage/maria/ma_pagecache.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 83785e6a1af..6ad63272a1e 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -1046,7 +1046,7 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) ("thread %ld", last_thread->next->id)); pagecache_pthread_cond_signal(&last_thread->next->suspend); } - DBUG_ASSERT((longlong) pagecache->cnt_for_resize_op >= 0); + DBUG_ASSERT(((longlong) pagecache->cnt_for_resize_op) >= 0); #else pagecache->cnt_for_resize_op--; #endif From 6a5570789eeefa570883b0399a48f7bb5f1dc358 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Sat, 4 Dec 2010 13:15:16 +0200 Subject: [PATCH 6/7] Removed assert as gcc on gentoo couldn't compile it without a warning :( (Not critical, we will just catch the error later) --- storage/maria/ma_pagecache.c | 1 - 1 file changed, 1 deletion(-) diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index 6ad63272a1e..8105c6f752d 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -1046,7 +1046,6 @@ static inline void dec_counter_for_resize_op(PAGECACHE *pagecache) ("thread %ld", last_thread->next->id)); pagecache_pthread_cond_signal(&last_thread->next->suspend); } - DBUG_ASSERT(((longlong) pagecache->cnt_for_resize_op) >= 0); #else pagecache->cnt_for_resize_op--; #endif From 6120fbace42f07a497e61035c6700bbba460d840 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 4 Dec 2010 18:31:11 +0200 Subject: [PATCH 7/7] Aria unit tests fixed to have correct pagecache shutdown. The Aria multithread test unlocked. storage/maria/unittest/ma_pagecache_consist.c: Fixed pagecache shutdown. storage/maria/unittest/ma_pagecache_rwconsist.c: Fixed pagecache shutdown. storage/maria/unittest/ma_test_loghandler_multithread-t.c: The Aria multithread test unlocked. storage/maria/unittest/ma_test_loghandler_pagecache-t.c: Fixed pagecache shutdown. --- storage/maria/unittest/ma_pagecache_consist.c | 1 + storage/maria/unittest/ma_pagecache_rwconsist.c | 1 + storage/maria/unittest/ma_test_loghandler_multithread-t.c | 5 ----- storage/maria/unittest/ma_test_loghandler_pagecache-t.c | 2 +- 4 files changed, 3 insertions(+), 6 deletions(-) diff --git a/storage/maria/unittest/ma_pagecache_consist.c b/storage/maria/unittest/ma_pagecache_consist.c index 7dbdba433c6..0a9e5737c7e 100644 --- a/storage/maria/unittest/ma_pagecache_consist.c +++ b/storage/maria/unittest/ma_pagecache_consist.c @@ -476,6 +476,7 @@ int main(int argc __attribute__((unused)), pthread_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info", ("thread ended")); + flush_pagecache_blocks(&pagecache, &file1, FLUSH_IGNORE_CHANGED); end_pagecache(&pagecache, 1); DBUG_PRINT("info", ("Page cache ended")); diff --git a/storage/maria/unittest/ma_pagecache_rwconsist.c b/storage/maria/unittest/ma_pagecache_rwconsist.c index a1a22b5e18d..ff386c48414 100644 --- a/storage/maria/unittest/ma_pagecache_rwconsist.c +++ b/storage/maria/unittest/ma_pagecache_rwconsist.c @@ -341,6 +341,7 @@ int main(int argc __attribute__((unused)), pthread_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info", ("thread ended")); + flush_pagecache_blocks(&pagecache, &file1, FLUSH_IGNORE_CHANGED); end_pagecache(&pagecache, 1); DBUG_PRINT("info", ("Page cache ended")); diff --git a/storage/maria/unittest/ma_test_loghandler_multithread-t.c b/storage/maria/unittest/ma_test_loghandler_multithread-t.c index 354f5d12e08..dbf47ad2ee1 100644 --- a/storage/maria/unittest/ma_test_loghandler_multithread-t.c +++ b/storage/maria/unittest/ma_test_loghandler_multithread-t.c @@ -269,11 +269,6 @@ int main(int argc __attribute__((unused)), int *param, error; int rc; - /* Disabled until Sanja tests */ - plan(1); - ok(1, "disabled"); - exit(0); - plan(WRITERS + FLUSHERS + ITERATIONS * WRITERS * 3 + FLUSH_ITERATIONS * FLUSHERS ); diff --git a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c index bfbba5407c1..a32cf32c787 100644 --- a/storage/maria/unittest/ma_test_loghandler_pagecache-t.c +++ b/storage/maria/unittest/ma_test_loghandler_pagecache-t.c @@ -168,7 +168,7 @@ int main(int argc __attribute__((unused)), char *argv[]) PAGECACHE_PIN_LEFT_UNPINNED, PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE); - flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE); + flush_pagecache_blocks(&pagecache, &file1, FLUSH_RELEASE); } my_close(file1.file, MYF(MY_WME)); if ((file1.file= my_open(first_translog_file, O_RDONLY, MYF(MY_WME))) < 0)