Commit 386f2806 authored by Michael Widenius's avatar Michael Widenius

Automatic merge with MariaDB 5.1

parents b60aa0a9 a26403b2
...@@ -1255,15 +1255,6 @@ void die(const char *fmt, ...) ...@@ -1255,15 +1255,6 @@ void die(const char *fmt, ...)
DBUG_ENTER("die"); DBUG_ENTER("die");
DBUG_PRINT("enter", ("start_lineno: %d", start_lineno)); 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 */ /* Print the error message */
fprintf(stderr, "mysqltest: "); fprintf(stderr, "mysqltest: ");
if (cur_file && cur_file != file_stack) if (cur_file && cur_file != file_stack)
...@@ -1282,6 +1273,15 @@ void die(const char *fmt, ...) ...@@ -1282,6 +1273,15 @@ void die(const char *fmt, ...)
fprintf(stderr, "\n"); fprintf(stderr, "\n");
fflush(stderr); 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); log_file.show_tail(opt_tail_lines);
/* /*
......
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;
--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;
...@@ -1094,6 +1094,12 @@ int ha_commit_trans(THD *thd, bool all) ...@@ -1094,6 +1094,12 @@ int ha_commit_trans(THD *thd, bool all)
my_xid xid= thd->transaction.xid_state.xid.get_my_xid(); my_xid xid= thd->transaction.xid_state.xid.get_my_xid();
DBUG_ENTER("ha_commit_trans"); 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 We must not commit the normal transaction if a statement
transaction is pending. Otherwise statement transaction transaction is pending. Otherwise statement transaction
......
...@@ -203,7 +203,7 @@ net_send_ok(THD *thd, ...@@ -203,7 +203,7 @@ net_send_ok(THD *thd,
NET *net= &thd->net; NET *net= &thd->net;
uchar buff[MYSQL_ERRMSG_SIZE+10],*pos; uchar buff[MYSQL_ERRMSG_SIZE+10],*pos;
bool error= FALSE; bool error= FALSE;
DBUG_ENTER("my_ok"); DBUG_ENTER("net_send_ok");
if (! net->vio) // hack for re-parsing queries if (! net->vio) // hack for re-parsing queries
{ {
......
...@@ -1224,6 +1224,13 @@ class Diagnostics_area ...@@ -1224,6 +1224,13 @@ class Diagnostics_area
return m_total_warn_count; 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(); } Diagnostics_area() { reset_diagnostics_area(); }
private: private:
......
...@@ -159,6 +159,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, ...@@ -159,6 +159,8 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
} }
thd->warn_count[(uint) level]++; thd->warn_count[(uint) level]++;
thd->total_warn_count++; thd->total_warn_count++;
/* Make sure we also count warnings pushed after calling set_ok_status(). */
thd->main_da.increment_warning();
DBUG_RETURN(err); DBUG_RETURN(err);
} }
......
...@@ -1993,19 +1993,6 @@ static my_bool write_tail(MARIA_HA *info, ...@@ -1993,19 +1993,6 @@ static my_bool write_tail(MARIA_HA *info,
/* Keep BLOCKUSED_USE_ORG_BITMAP */ /* Keep BLOCKUSED_USE_ORG_BITMAP */
block->used|= BLOCKUSED_USED | BLOCKUSED_TAIL; 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) if (block_is_read)
{ {
/* Current page link is last element in pinned_pages */ /* Current page link is last element in pinned_pages */
...@@ -2021,17 +2008,33 @@ static my_bool write_tail(MARIA_HA *info, ...@@ -2021,17 +2008,33 @@ static my_bool write_tail(MARIA_HA *info,
page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK; page_link->unlock= PAGECACHE_LOCK_READ_UNLOCK;
res= 0; res= 0;
} }
else if (!(res= pagecache_write(share->pagecache, else
&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; if (!(res= pagecache_write(share->pagecache,
page_link.changed= 1; &info->dfile, block->page, 0,
push_dynamic(&info->pinned_pages, (void*) &page_link); 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); DBUG_RETURN(res);
} }
...@@ -2068,7 +2071,7 @@ static my_bool write_full_pages(MARIA_HA *info, ...@@ -2068,7 +2071,7 @@ static my_bool write_full_pages(MARIA_HA *info,
uint data_size= FULL_PAGE_SIZE(block_size); uint data_size= FULL_PAGE_SIZE(block_size);
uchar *buff= info->keyread_buff; uchar *buff= info->keyread_buff;
uint page_count, sub_blocks; uint page_count, sub_blocks;
my_off_t position; my_off_t position, max_position;
DBUG_ENTER("write_full_pages"); DBUG_ENTER("write_full_pages");
DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu", DBUG_PRINT("enter", ("length: %lu page: %lu page_count: %lu",
(ulong) length, (ulong) block->page, (ulong) length, (ulong) block->page,
...@@ -2080,9 +2083,7 @@ static my_bool write_full_pages(MARIA_HA *info, ...@@ -2080,9 +2083,7 @@ static my_bool write_full_pages(MARIA_HA *info,
page_count= block->page_count; page_count= block->page_count;
sub_blocks= block->sub_blocks; sub_blocks= block->sub_blocks;
position= (my_off_t) (page + page_count) * block_size; max_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);
/* Increase data file size, if extended */ /* Increase data file size, if extended */
...@@ -2105,8 +2106,7 @@ static my_bool write_full_pages(MARIA_HA *info, ...@@ -2105,8 +2106,7 @@ static my_bool write_full_pages(MARIA_HA *info,
(ulong) block->page, (ulong) block->page_count)); (ulong) block->page, (ulong) block->page_count));
position= (page + page_count + 1) * block_size; position= (page + page_count + 1) * block_size;
if (share->state.state.data_file_length < position) set_if_bigger(max_position, position);
_ma_set_share_data_file_length(share, position);
} }
lsn_store(buff, lsn); lsn_store(buff, lsn);
buff[PAGE_TYPE_OFFSET]= (uchar) BLOB_PAGE; buff[PAGE_TYPE_OFFSET]= (uchar) BLOB_PAGE;
...@@ -2134,6 +2134,8 @@ static my_bool write_full_pages(MARIA_HA *info, ...@@ -2134,6 +2134,8 @@ static my_bool write_full_pages(MARIA_HA *info,
page++; page++;
DBUG_ASSERT(block->used & BLOCKUSED_USED); 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); DBUG_RETURN(0);
} }
...@@ -3121,11 +3123,6 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -3121,11 +3123,6 @@ static my_bool write_block_record(MARIA_HA *info,
} }
#endif #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) if (head_block_is_read)
{ {
MARIA_PINNED_PAGE *page_link; MARIA_PINNED_PAGE *page_link;
...@@ -3154,6 +3151,11 @@ static my_bool write_block_record(MARIA_HA *info, ...@@ -3154,6 +3151,11 @@ static my_bool write_block_record(MARIA_HA *info,
page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK; page_link.unlock= PAGECACHE_LOCK_READ_UNLOCK;
page_link.changed= 1; page_link.changed= 1;
push_dynamic(&info->pinned_pages, (void*) &page_link); 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)) 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) ...@@ -5162,6 +5164,7 @@ my_bool _ma_scan_init_block_record(MARIA_HA *info)
info->scan.number_of_rows= 0; info->scan.number_of_rows= 0;
info->scan.bitmap_pos= info->scan.bitmap_end; info->scan.bitmap_pos= info->scan.bitmap_end;
info->scan.bitmap_page= (pgcache_page_no_t) 0 - share->bitmap.pages_covered; 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 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 we are going to read bitmaps from page cache in table scan (see
...@@ -5363,6 +5366,11 @@ int _ma_scan_block_record(MARIA_HA *info, uchar *record, ...@@ -5363,6 +5366,11 @@ int _ma_scan_block_record(MARIA_HA *info, uchar *record,
page= (info->scan.bitmap_page + 1 + page= (info->scan.bitmap_page + 1 +
(data - info->scan.bitmap_buff) / 6 * 16 + bit_pos - 1); (data - info->scan.bitmap_buff) / 6 * 16 + bit_pos - 1);
info->scan.row_base_page= ma_recordpos(page, 0); 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, if (!(pagecache_read(share->pagecache,
&info->dfile, &info->dfile,
page, 0, info->scan.page_buff, page, 0, info->scan.page_buff,
......
...@@ -476,7 +476,7 @@ typedef struct st_maria_block_scan ...@@ -476,7 +476,7 @@ typedef struct st_maria_block_scan
{ {
uchar *bitmap_buff, *bitmap_pos, *bitmap_end, *page_buff; uchar *bitmap_buff, *bitmap_pos, *bitmap_end, *page_buff;
uchar *dir, *dir_end; uchar *dir, *dir_end;
pgcache_page_no_t bitmap_page; pgcache_page_no_t bitmap_page, max_page;
ulonglong bits; ulonglong bits;
uint number_of_rows, bit_pos; uint number_of_rows, bit_pos;
MARIA_RECORD_POS row_base_page; MARIA_RECORD_POS row_base_page;
......
...@@ -189,7 +189,7 @@ os_event_wait_low( ...@@ -189,7 +189,7 @@ os_event_wait_low(
/**********************************************************//** /**********************************************************//**
Waits for an event object until it is in the signaled state or 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 */ @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN UNIV_INTERN
ulint ulint
......
...@@ -57,6 +57,9 @@ extern const char srv_mysql50_table_name_prefix[9]; ...@@ -57,6 +57,9 @@ extern const char srv_mysql50_table_name_prefix[9];
thread starts running */ thread starts running */
extern os_event_t srv_lock_timeout_thread_event; 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 /* If the last data file is auto-extended, we add this many pages to it
at a time */ at a time */
#define SRV_AUTO_EXTEND_INCREMENT \ #define SRV_AUTO_EXTEND_INCREMENT \
......
...@@ -3102,6 +3102,7 @@ logs_empty_and_mark_files_at_shutdown(void) ...@@ -3102,6 +3102,7 @@ logs_empty_and_mark_files_at_shutdown(void)
algorithm only works if the server is idle at shutdown */ algorithm only works if the server is idle at shutdown */
srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; srv_shutdown_state = SRV_SHUTDOWN_CLEANUP;
os_event_set(srv_purge_thread_event);
loop: loop:
os_thread_sleep(100000); os_thread_sleep(100000);
......
...@@ -31,6 +31,9 @@ Created 9/6/1995 Heikki Tuuri ...@@ -31,6 +31,9 @@ Created 9/6/1995 Heikki Tuuri
#ifdef __WIN__ #ifdef __WIN__
#include <windows.h> #include <windows.h>
#else
#include <sys/time.h>
#include <time.h>
#endif #endif
#include "ut0mem.h" #include "ut0mem.h"
...@@ -407,14 +410,14 @@ os_event_wait_low( ...@@ -407,14 +410,14 @@ os_event_wait_low(
/**********************************************************//** /**********************************************************//**
Waits for an event object until it is in the signaled state or 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 */ @return 0 if success, OS_SYNC_TIME_EXCEEDED if timeout was exceeded */
UNIV_INTERN UNIV_INTERN
ulint ulint
os_event_wait_time( os_event_wait_time(
/*===============*/ /*===============*/
os_event_t event, /*!< in: event to wait */ 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 */ OS_SYNC_INFINITE_TIME */
{ {
#ifdef __WIN__ #ifdef __WIN__
...@@ -422,8 +425,8 @@ os_event_wait_time( ...@@ -422,8 +425,8 @@ os_event_wait_time(
ut_a(event); ut_a(event);
if (time != OS_SYNC_INFINITE_TIME) { if (wtime != OS_SYNC_INFINITE_TIME) {
err = WaitForSingleObject(event->handle, (DWORD) time / 1000); err = WaitForSingleObject(event->handle, (DWORD) wtime / 1000);
} else { } else {
err = WaitForSingleObject(event->handle, INFINITE); err = WaitForSingleObject(event->handle, INFINITE);
} }
...@@ -439,13 +442,47 @@ os_event_wait_time( ...@@ -439,13 +442,47 @@ os_event_wait_time(
return(1000000); /* dummy value to eliminate compiler warn. */ return(1000000); /* dummy value to eliminate compiler warn. */
} }
#else #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 #endif
} }
......
...@@ -704,6 +704,8 @@ UNIV_INTERN srv_slot_t* srv_mysql_table = NULL; ...@@ -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_lock_timeout_thread_event;
UNIV_INTERN os_event_t srv_purge_thread_event;
UNIV_INTERN srv_sys_t* srv_sys = NULL; UNIV_INTERN srv_sys_t* srv_sys = NULL;
/* padding to prevent other memory update hotspots from residing on /* padding to prevent other memory update hotspots from residing on
...@@ -1009,6 +1011,7 @@ srv_init(void) ...@@ -1009,6 +1011,7 @@ srv_init(void)
} }
srv_lock_timeout_thread_event = os_event_create(NULL); 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++) { for (i = 0; i < SRV_MASTER + 1; i++) {
srv_n_threads_active[i] = 0; srv_n_threads_active[i] = 0;
...@@ -3337,9 +3340,10 @@ srv_purge_thread( ...@@ -3337,9 +3340,10 @@ srv_purge_thread(
mutex_exit(&kernel_mutex); mutex_exit(&kernel_mutex);
sleep_ms = 10; 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; history_len = trx_sys->rseg_history_len;
if (history_len > 1000) if (history_len > 1000)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment