summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2010-11-04 17:08:28 +0200
committerMichael Widenius <monty@askmonty.org>2010-11-04 17:08:28 +0200
commit386f2806b4aecca9062fc685436f3cf47f7b747b (patch)
tree09d739e03d7203b9aab844694882c52417875513
parentb60aa0a9ea14ff2cac895ec688ea1cf80318c490 (diff)
parenta26403b28cc546ed31161a5ad171c470fec96320 (diff)
downloadmariadb-git-386f2806b4aecca9062fc685436f3cf47f7b747b.tar.gz
Automatic merge with MariaDB 5.1
-rw-r--r--client/mysqltest.cc18
-rw-r--r--mysql-test/r/warnings_debug.result10
-rw-r--r--mysql-test/t/warnings_debug.test19
-rw-r--r--sql/handler.cc6
-rw-r--r--sql/protocol.cc2
-rw-r--r--sql/sql_class.h7
-rw-r--r--sql/sql_error.cc2
-rw-r--r--storage/maria/ma_blockrec.c76
-rw-r--r--storage/maria/maria_def.h2
-rw-r--r--storage/xtradb/include/os0sync.h2
-rw-r--r--storage/xtradb/include/srv0srv.h3
-rw-r--r--storage/xtradb/log/log0log.c1
-rw-r--r--storage/xtradb/os/os0sync.c53
-rw-r--r--storage/xtradb/srv/srv0srv.c6
14 files changed, 152 insertions, 55 deletions
diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 4cc7ef813c3..be4a3e06fbb 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -1255,15 +1255,6 @@ void die(const char *fmt, ...)
DBUG_ENTER("die");
DBUG_PRINT("enter", ("start_lineno: %d", start_lineno));
- /*
- Protect against dying twice
- first time 'die' is called, try to write log files
- second time, just exit
- */
- if (dying)
- cleanup_and_exit(1);
- dying= 1;
-
/* Print the error message */
fprintf(stderr, "mysqltest: ");
if (cur_file && cur_file != file_stack)
@@ -1282,6 +1273,15 @@ void die(const char *fmt, ...)
fprintf(stderr, "\n");
fflush(stderr);
+ /*
+ Protect against dying twice
+ first time 'die' is called, try to write log files
+ second time, just exit
+ */
+ if (dying)
+ cleanup_and_exit(1);
+ dying= 1;
+
log_file.show_tail(opt_tail_lines);
/*
diff --git a/mysql-test/r/warnings_debug.result b/mysql-test/r/warnings_debug.result
new file mode 100644
index 00000000000..08908bf0437
--- /dev/null
+++ b/mysql-test/r/warnings_debug.result
@@ -0,0 +1,10 @@
+drop table if exists t1;
+create table t1 (a int primary key) engine=innodb;
+SET SESSION debug="+d,warn_during_ha_commit_trans";
+INSERT INTO t1 VALUES (1);
+Warnings:
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+SHOW WARNINGS;
+Level Code Message
+Warning 1196 Some non-transactional changed tables couldn't be rolled back
+drop table t1;
diff --git a/mysql-test/t/warnings_debug.test b/mysql-test/t/warnings_debug.test
new file mode 100644
index 00000000000..99d02330960
--- /dev/null
+++ b/mysql-test/t/warnings_debug.test
@@ -0,0 +1,19 @@
+--source include/have_innodb.inc
+--source include/have_debug.inc
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+create table t1 (a int primary key) engine=innodb;
+
+# Test that warnings produced during autocommit (after calling
+# set_ok_status()) are still reported to the client.
+SET SESSION debug="+d,warn_during_ha_commit_trans";
+INSERT INTO t1 VALUES (1);
+# The warning will be shown automatically by mysqltest; there was a bug where
+# this didn't happen because the warning was not counted when sending result
+# packet. Show the warnings manually also.
+SHOW WARNINGS;
+
+drop table t1;
diff --git a/sql/handler.cc b/sql/handler.cc
index 29aabda1343..48add3a1e53 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -1094,6 +1094,12 @@ int ha_commit_trans(THD *thd, bool all)
my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
DBUG_ENTER("ha_commit_trans");
+ /* Just a random warning to test warnings pushed during autocommit. */
+ DBUG_EXECUTE_IF("warn_during_ha_commit_trans",
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+ ER_WARNING_NOT_COMPLETE_ROLLBACK,
+ ER(ER_WARNING_NOT_COMPLETE_ROLLBACK)););
+
/*
We must not commit the normal transaction if a statement
transaction is pending. Otherwise statement transaction
diff --git a/sql/protocol.cc b/sql/protocol.cc
index 786d6ef8544..8a9d712077d 100644
--- a/sql/protocol.cc
+++ b/sql/protocol.cc
@@ -203,7 +203,7 @@ net_send_ok(THD *thd,
NET *net= &thd->net;
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
bool error= FALSE;
- DBUG_ENTER("my_ok");
+ DBUG_ENTER("net_send_ok");
if (! net->vio) // hack for re-parsing queries
{
diff --git a/sql/sql_class.h b/sql/sql_class.h
index 4682938fd6d..bb986d6377f 100644
--- a/sql/sql_class.h
+++ b/sql/sql_class.h
@@ -1224,6 +1224,13 @@ public:
return m_total_warn_count;
}
+ /* Used to count any warnings pushed after calling set_ok_status(). */
+ void increment_warning()
+ {
+ if (m_status != DA_EMPTY)
+ m_total_warn_count++;
+ }
+
Diagnostics_area() { reset_diagnostics_area(); }
private:
diff --git a/sql/sql_error.cc b/sql/sql_error.cc
index 9ea7facbe41..835e60cd6ba 100644
--- a/sql/sql_error.cc
+++ b/sql/sql_error.cc
@@ -159,6 +159,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
}
thd->warn_count[(uint) level]++;
thd->total_warn_count++;
+ /* Make sure we also count warnings pushed after calling set_ok_status(). */
+ thd->main_da.increment_warning();
DBUG_RETURN(err);
}
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index 0eab7c62796..fd02e2ac0ec 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -1993,19 +1993,6 @@ static my_bool write_tail(MARIA_HA *info,
/* Keep BLOCKUSED_USE_ORG_BITMAP */
block->used|= BLOCKUSED_USED | BLOCKUSED_TAIL;
- /* Increase data file size, if extended */
- position= (my_off_t) block->page * block_size;
- if (share->state.state.data_file_length <= position)
- {
- /*
- We are modifying a state member before writing the UNDO; this is a WAL
- violation. But for data_file_length this is ok, as long as we change
- data_file_length after writing any log record (FILE_ID/REDO/UNDO) (see
- collect_tables()).
- */
- _ma_set_share_data_file_length(share, position + block_size);
- }
-
if (block_is_read)
{
/* Current page link is last element in pinned_pages */
@@ -2021,17 +2008,33 @@ static my_bool write_tail(MARIA_HA *info,
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
res= 0;
}
- else if (!(res= pagecache_write(share->pagecache,
- &info->dfile, block->page, 0,
- row_pos.buff,share->page_type,
- PAGECACHE_LOCK_READ,
- PAGECACHE_PIN,
- PAGECACHE_WRITE_DELAY, &page_link.link,
- LSN_IMPOSSIBLE)))
+ else
{
- page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
- page_link.changed= 1;
- push_dynamic(&info->pinned_pages, (void*) &page_link);
+ if (!(res= pagecache_write(share->pagecache,
+ &info->dfile, block->page, 0,
+ row_pos.buff,share->page_type,
+ PAGECACHE_LOCK_READ,
+ PAGECACHE_PIN,
+ PAGECACHE_WRITE_DELAY, &page_link.link,
+ LSN_IMPOSSIBLE)))
+ {
+ page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
+ page_link.changed= 1;
+ push_dynamic(&info->pinned_pages, (void*) &page_link);
+ }
+
+ /* Increase data file size, if extended */
+ position= (my_off_t) block->page * block_size;
+ if (share->state.state.data_file_length <= position)
+ {
+ /*
+ We are modifying a state member before writing the UNDO; this is a WAL
+ violation. But for data_file_length this is ok, as long as we change
+ data_file_length after writing any log record (FILE_ID/REDO/UNDO) (see
+ collect_tables()).
+ */
+ _ma_set_share_data_file_length(share, position + block_size);
+ }
}
DBUG_RETURN(res);
}
@@ -2068,7 +2071,7 @@ static my_bool write_full_pages(MARIA_HA *info,
uint data_size= FULL_PAGE_SIZE(block_size);
uchar *buff= info->keyread_buff;
uint page_count, sub_blocks;
- my_off_t position;
+ my_off_t position, max_position;
DBUG_ENTER("write_full_pages");
DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu",
(ulong) length, (ulong) block->page,
@@ -2080,9 +2083,7 @@ static my_bool write_full_pages(MARIA_HA *info,
page_count= block->page_count;
sub_blocks= block->sub_blocks;
- position= (my_off_t) (page + page_count) * block_size;
- if (share->state.state.data_file_length < position)
- _ma_set_share_data_file_length(share, position);
+ max_position= (my_off_t) (page + page_count) * block_size;
/* Increase data file size, if extended */
@@ -2105,8 +2106,7 @@ static my_bool write_full_pages(MARIA_HA *info,
(ulong) block->page, (ulong) block->page_count));
position= (page + page_count + 1) * block_size;
- if (share->state.state.data_file_length < position)
- _ma_set_share_data_file_length(share, position);
+ set_if_bigger(max_position, position);
}
lsn_store(buff, lsn);
buff[PAGE_TYPE_OFFSET]= (uchar) BLOB_PAGE;
@@ -2134,6 +2134,8 @@ static my_bool write_full_pages(MARIA_HA *info,
page++;
DBUG_ASSERT(block->used & BLOCKUSED_USED);
}
+ if (share->state.state.data_file_length < max_position)
+ _ma_set_share_data_file_length(share, max_position);
DBUG_RETURN(0);
}
@@ -3121,11 +3123,6 @@ static my_bool write_block_record(MARIA_HA *info,
}
#endif
- /* Increase data file size, if extended */
- position= (my_off_t) head_block->page * block_size;
- if (share->state.state.data_file_length <= position)
- _ma_set_share_data_file_length(share, position + block_size);
-
if (head_block_is_read)
{
MARIA_PINNED_PAGE *page_link;
@@ -3154,6 +3151,11 @@ static my_bool write_block_record(MARIA_HA *info,
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link.changed= 1;
push_dynamic(&info->pinned_pages, (void*) &page_link);
+
+ /* Increase data file size, if extended */
+ position= (my_off_t) head_block->page * block_size;
+ if (share->state.state.data_file_length <= position)
+ _ma_set_share_data_file_length(share, position + block_size);
}
if (share->now_transactional && (tmp_data_used || blob_full_pages_exists))
@@ -5162,6 +5164,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
info->scan.number_of_rows= 0;
info->scan.bitmap_pos= info->scan.bitmap_end;
info->scan.bitmap_page= (pgcache_page_no_t) 0 - share->bitmap.pages_covered;
+ info->scan.max_page= share->state.state.data_file_length / share->block_size;
/*
We need to flush what's in memory (bitmap.map) to page cache otherwise, as
we are going to read bitmaps from page cache in table scan (see
@@ -5363,6 +5366,11 @@ restart_bitmap_scan:
page= (info->scan.bitmap_page + 1 +
(data - info->scan.bitmap_buff) / 6 * 16 + bit_pos - 1);
info->scan.row_base_page= ma_recordpos(page, 0);
+ if (page >= info->scan.max_page)
+ {
+ DBUG_PRINT("info", ("Found end of file"));
+ DBUG_RETURN((my_errno= HA_ERR_END_OF_FILE));
+ }
if (!(pagecache_read(share->pagecache,
&info->dfile,
page, 0, info->scan.page_buff,
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index bdc4d4c5ed2..b998ac4f3a0 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -476,7 +476,7 @@ typedef struct st_maria_block_scan
{
uchar *bitmap_buff, *bitmap_pos, *bitmap_end, *page_buff;
uchar *dir, *dir_end;
- pgcache_page_no_t bitmap_page;
+ pgcache_page_no_t bitmap_page, max_page;
ulonglong bits;
uint number_of_rows, bit_pos;
MARIA_RECORD_POS row_base_page;
diff --git a/storage/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index 0c22162b900..c230a03b6db 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -189,7 +189,7 @@ os_event_wait_low(
/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite.
+a timeout is exceeded.
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index dc455581350..8c64d5cee71 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -57,6 +57,9 @@ extern const char srv_mysql50_table_name_prefix[9];
thread starts running */
extern os_event_t srv_lock_timeout_thread_event;
+/* This event is set to tell the purge thread to shut down */
+extern os_event_t srv_purge_thread_event;
+
/* If the last data file is auto-extended, we add this many pages to it
at a time */
#define SRV_AUTO_EXTEND_INCREMENT \
diff --git a/storage/xtradb/log/log0log.c b/storage/xtradb/log/log0log.c
index fade31037b5..b9f19aeff31 100644
--- a/storage/xtradb/log/log0log.c
+++ b/storage/xtradb/log/log0log.c
@@ -3102,6 +3102,7 @@ logs_empty_and_mark_files_at_shutdown(void)
algorithm only works if the server is idle at shutdown */
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
+ os_event_set(srv_purge_thread_event);
loop:
os_thread_sleep(100000);
diff --git a/storage/xtradb/os/os0sync.c b/storage/xtradb/os/os0sync.c
index 60467242e14..f9ab58c2ee4 100644
--- a/storage/xtradb/os/os0sync.c
+++ b/storage/xtradb/os/os0sync.c
@@ -31,6 +31,9 @@ Created 9/6/1995 Heikki Tuuri
#ifdef __WIN__
#include <windows.h>
+#else
+#include <sys/time.h>
+#include <time.h>
#endif
#include "ut0mem.h"
@@ -407,14 +410,14 @@ os_event_wait_low(
/**********************************************************//**
Waits for an event object until it is in the signaled state or
-a timeout is exceeded. In Unix the timeout is always infinite.
+a timeout is exceeded.
@return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN
ulint
os_event_wait_time(
/*===============*/
os_event_t event, /*!< in: event to wait */
- ulint time) /*!< in: timeout in microseconds, or
+ ulint wtime) /*!< in: timeout in microseconds, or
OS_SYNC_INFINITE_TIME */
{
#ifdef __WIN__
@@ -422,8 +425,8 @@ os_event_wait_time(
ut_a(event);
- if (time != OS_SYNC_INFINITE_TIME) {
- err = WaitForSingleObject(event->handle, (DWORD) time / 1000);
+ if (wtime != OS_SYNC_INFINITE_TIME) {
+ err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000);
} else {
err = WaitForSingleObject(event->handle, INFINITE);
}
@@ -439,13 +442,47 @@ os_event_wait_time(
return(1000000); /* dummy value to eliminate compiler warn. */
}
#else
- UT_NOT_USED(time);
+ int err;
+ int ret = 0;
+ ulint tmp;
+ ib_int64_t old_count;
+ struct timeval tv_start;
+ struct timespec timeout;
+
+ if (wtime == OS_SYNC_INFINITE_TIME) {
+ os_event_wait(event);
+ return 0;
+ }
+
+ /* Compute the absolute point in time at which to time out. */
+ gettimeofday(&tv_start, NULL);
+ tmp = tv_start.tv_usec + wtime;
+ timeout.tv_sec = tv_start.tv_sec + (tmp / 1000000);
+ timeout.tv_nsec = (tmp % 1000000) * 1000;
+
+ os_fast_mutex_lock(&(event->os_mutex));
+ old_count = event->signal_count;
+
+ for (;;) {
+ if (event->is_set == TRUE || event->signal_count != old_count)
+ break;
+
+ err = pthread_cond_timedwait(&(event->cond_var),
+ &(event->os_mutex), &timeout);
+ if (err == ETIMEDOUT) {
+ ret = OS_SYNC_TIME_EXCEEDED;
+ break;
+ }
+ }
- /* In Posix this is just an ordinary, infinite wait */
+ os_fast_mutex_unlock(&(event->os_mutex));
- os_event_wait(event);
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+
+ os_thread_exit(NULL);
+ }
- return(0);
+ return ret;
#endif
}
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index c1d0f255c64..43799aab196 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -704,6 +704,8 @@ UNIV_INTERN srv_slot_t* srv_mysql_table = NULL;
UNIV_INTERN os_event_t srv_lock_timeout_thread_event;
+UNIV_INTERN os_event_t srv_purge_thread_event;
+
UNIV_INTERN srv_sys_t* srv_sys = NULL;
/* padding to prevent other memory update hotspots from residing on
@@ -1009,6 +1011,7 @@ srv_init(void)
}
srv_lock_timeout_thread_event = os_event_create(NULL);
+ srv_purge_thread_event = os_event_create(NULL);
for (i = 0; i < SRV_MASTER + 1; i++) {
srv_n_threads_active[i] = 0;
@@ -3337,9 +3340,10 @@ loop:
mutex_exit(&kernel_mutex);
sleep_ms = 10;
+ os_event_reset(srv_purge_thread_event);
}
- os_thread_sleep( sleep_ms * 1000 );
+ os_event_wait_time(srv_purge_thread_event, sleep_ms * 1000);
history_len = trx_sys->rseg_history_len;
if (history_len > 1000)