summaryrefslogtreecommitdiff
path: root/storage/xtradb
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2012-01-13 15:50:02 +0100
committerSergei Golubchik <sergii@pisem.net>2012-01-13 15:50:02 +0100
commit4f435bddfd44d40999f88685c61cc04e319d8d6c (patch)
treef9d0655a0d901b87f918a736741144b502cba3f6 /storage/xtradb
parent8c2bcdf85ff753bceeb5b235f3605e348e6f9e1d (diff)
parent6ca4ca7d37fed3b3da18666768de6a2f8c34bc7b (diff)
downloadmariadb-git-4f435bddfd44d40999f88685c61cc04e319d8d6c.tar.gz
5.3 merge
Diffstat (limited to 'storage/xtradb')
-rw-r--r--storage/xtradb/fil/fil0fil.c10
-rw-r--r--storage/xtradb/handler/ha_innodb.cc24
-rw-r--r--storage/xtradb/include/srv0srv.h2
-rw-r--r--storage/xtradb/os/os0file.c56
-rw-r--r--storage/xtradb/row/row0ins.c2
-rw-r--r--storage/xtradb/srv/srv0srv.c2
6 files changed, 64 insertions, 32 deletions
diff --git a/storage/xtradb/fil/fil0fil.c b/storage/xtradb/fil/fil0fil.c
index c3d85a77f3c..41b61be0b5b 100644
--- a/storage/xtradb/fil/fil0fil.c
+++ b/storage/xtradb/fil/fil0fil.c
@@ -3486,7 +3486,7 @@ skip_info:
}
if (page_is_corrupt) {
- fprintf(stderr, " [errp:%lld]", offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
+ fprintf(stderr, " [errp:%ld]", (long)(offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)));
/* cannot treat corrupt page */
goto skip_write;
@@ -3499,8 +3499,8 @@ skip_info:
if (offset / (zip_size ? zip_size : UNIV_PAGE_SIZE) == root_page[i]) {
if (fil_page_get_type(page) != FIL_PAGE_INDEX) {
file_is_corrupt = TRUE;
- fprintf(stderr, " [etyp:%lld]",
- offset / (zip_size ? zip_size : UNIV_PAGE_SIZE));
+ fprintf(stderr, " [etyp:%ld]",
+ (long)(offset / (zip_size ? zip_size : UNIV_PAGE_SIZE)));
goto skip_write;
}
/* this is index root page */
@@ -3729,7 +3729,6 @@ func_exit:
ulint page_no;
ulint zip_size;
ulint height;
- ulint root_height = 0;
rec_t* node_ptr;
dict_table_t* table;
dict_index_t* index;
@@ -3768,7 +3767,6 @@ func_exit:
if (height == ULINT_UNDEFINED) {
height = btr_page_get_level(page, &mtr);
- root_height = height;
}
if (height == 0) {
@@ -4159,7 +4157,7 @@ fil_load_single_table_tablespace(
size = (((ib_uint64_t)size_high) << 32) + (ib_uint64_t)size_low;
#ifndef UNIV_HOTBACKUP
- if (size < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
+ if (size < (ib_uint64_t)FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Error: the size of single-table tablespace"
" file %s\n"
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index f3f2100389c..b706523596f 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -3127,7 +3127,7 @@ innobase_commit_low(
#ifdef MYSQL_SERVER
THD *thd=current_thd;
- if (thd && thd->slave_thread) {
+ if (thd && thd_is_replication_slave_thread(thd)) {
/* Update the replication position info inside InnoDB.
In embedded server, does nothing. */
const char *log_file_name, *group_relay_log_name;
@@ -6023,14 +6023,15 @@ calc_row_difference(
/* The field has changed */
ufield = uvect->fields + n_changed;
+ UNIV_MEM_INVALID(ufield, sizeof *ufield);
/* Let us use a dummy dfield to make the conversion
from the MySQL column format to the InnoDB format */
- dict_col_copy_type(prebuilt->table->cols + innodb_idx,
- dfield_get_type(&dfield));
-
if (n_len != UNIV_SQL_NULL) {
+ dict_col_copy_type(prebuilt->table->cols + innodb_idx,
+ dfield_get_type(&dfield));
+
buf = row_mysql_store_col_in_innobase_format(
&dfield,
(byte*)buf,
@@ -6038,7 +6039,7 @@ calc_row_difference(
new_mysql_row_col,
col_pack_len,
dict_table_is_comp(prebuilt->table));
- dfield_copy_data(&ufield->new_val, &dfield);
+ dfield_copy(&ufield->new_val, &dfield);
} else {
dfield_set_null(&ufield->new_val);
}
@@ -11561,7 +11562,7 @@ ha_innobase::check_if_incompatible_data(
if (info_row_type == ROW_TYPE_DEFAULT)
info_row_type = ROW_TYPE_COMPACT;
if ((info->used_fields & HA_CREATE_USED_ROW_FORMAT) &&
- get_row_type() != ((info->row_type == ROW_TYPE_DEFAULT)
+ row_type != ((info->row_type == ROW_TYPE_DEFAULT)
? ROW_TYPE_COMPACT : info->row_type)) {
DBUG_PRINT("info", ("get_row_type()=%d != info->row_type=%d -> "
@@ -12370,15 +12371,12 @@ static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter,
NULL, NULL, 500L, 1L, ~0L, 0);
#ifdef EXTENDED_FOR_KILLIDLE
-#define TMP_STR "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB."
+#define kill_idle_help_text "If non-zero value, the idle session with transaction which is idle over the value in seconds is killed by InnoDB."
#else
-#define TMP_STR "No effect for this build."
+#define kill_idle_help_text "No effect for this build."
#endif
-static MYSQL_SYSVAR_ULONG(kill_idle_transaction, srv_kill_idle_transaction,
- PLUGIN_VAR_RQCMDARG,
- TMP_STR,
- NULL, NULL, 0, 0, LONG_MAX, 0);
-#undef TMP_STR
+static MYSQL_SYSVAR_LONGLONG(kill_idle_transaction, srv_kill_idle_transaction,
+ PLUGIN_VAR_RQCMDARG, kill_idle_help_text, NULL, NULL, 0, 0, LONG_MAX, 0);
static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads,
PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR,
diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h
index 0c864a265e0..6f985eacdf3 100644
--- a/storage/xtradb/include/srv0srv.h
+++ b/storage/xtradb/include/srv0srv.h
@@ -299,7 +299,7 @@ extern ibool srv_print_latch_waits;
extern ulint srv_activity_count;
extern ulint srv_fatal_semaphore_wait_threshold;
extern ulint srv_dml_needed_delay;
-extern ulong srv_kill_idle_transaction;
+extern long long srv_kill_idle_transaction;
extern mutex_t* kernel_mutex_temp;/* mutex protecting the server, trx structs,
query threads, and lock table: we allocate
diff --git a/storage/xtradb/os/os0file.c b/storage/xtradb/os/os0file.c
index 8fe8bab5d9a..ea7abb2549e 100644
--- a/storage/xtradb/os/os0file.c
+++ b/storage/xtradb/os/os0file.c
@@ -334,6 +334,8 @@ os_aio_validate_skip(void)
#ifdef _WIN32
/** IO completion port used by background io threads */
static HANDLE completion_port;
+/** IO completion port used by background io READ threads */
+static HANDLE read_completion_port;
/** Thread local storage index for the per-thread event used for synchronous IO */
static DWORD tls_sync_io = TLS_OUT_OF_INDEXES;
#endif
@@ -3518,9 +3520,10 @@ os_aio_init(
os_last_printout = time(NULL);
#ifdef _WIN32
- ut_a(completion_port == 0);
+ ut_a(completion_port == 0 && read_completion_port == 0);
completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
- ut_a(completion_port);
+ read_completion_port = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
+ ut_a(completion_port && read_completion_port);
#endif
return(TRUE);
@@ -3571,6 +3574,7 @@ os_aio_array_wake_win_aio_at_shutdown(
if(completion_port)
{
PostQueuedCompletionStatus(completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
+ PostQueuedCompletionStatus(read_completion_port, 0, IOCP_SHUTDOWN_KEY, NULL);
}
}
#endif
@@ -4244,6 +4248,9 @@ err_exit:
}
#ifdef WIN_ASYNC_IO
+#define READ_SEGMENT(x) (x < srv_n_read_io_threads)
+#define WRITE_SEGMENT(x) !READ_SEGMENT(x)
+
/**********************************************************************//**
This function is only used in Windows asynchronous i/o.
Waits for an aio operation to complete. This function is used to wait the
@@ -4282,18 +4289,45 @@ os_aio_windows_handle(
DWORD len;
BOOL retry = FALSE;
ULONG_PTR key;
+ HANDLE port = READ_SEGMENT(segment)? read_completion_port : completion_port;
- ret = GetQueuedCompletionStatus(completion_port, &len, &key,
- (OVERLAPPED **)&slot, INFINITE);
+ for(;;) {
+ ret = GetQueuedCompletionStatus(port, &len, &key,
+ (OVERLAPPED **)&slot, INFINITE);
- /* If shutdown key was received, repost the shutdown message and exit */
- if (ret && (key == IOCP_SHUTDOWN_KEY)) {
- PostQueuedCompletionStatus(completion_port, 0, key, NULL);
- os_thread_exit(NULL);
- }
+ /* If shutdown key was received, repost the shutdown message and exit */
+ if (ret && (key == IOCP_SHUTDOWN_KEY)) {
+ PostQueuedCompletionStatus(port, 0, key, NULL);
+ os_thread_exit(NULL);
+ }
+
+ if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
+ os_thread_exit(NULL);
+ }
- if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) {
- os_thread_exit(NULL);
+ if(WRITE_SEGMENT(segment)&& slot->type == OS_FILE_READ) {
+ /*
+ Redirect read completions to the dedicated completion port
+ and thread. We need to split read and write threads. If we do not
+ do that, and just allow all io threads process all IO, it is possible
+ to get stuck in a deadlock in buffer pool code,
+
+ Currently, the problem is solved this way - "write io" threads
+ always get all completion notifications, from both async reads and
+ writes. Write completion is handled in the same thread that gets it.
+ Read completion is forwarded via PostQueueCompletionStatus())
+ to the second completion port dedicated solely to reads. One of the
+ "read io" threads waiting on this port will finally handle the IO.
+
+ Forwarding IO completion this way costs a context switch , and this
+ seems tolerable since asynchronous reads are by far less frequent.
+ */
+ ut_a(PostQueuedCompletionStatus(read_completion_port, len, key,
+ &slot->control));
+ }
+ else {
+ break;
+ }
}
*message1 = slot->message1;
diff --git a/storage/xtradb/row/row0ins.c b/storage/xtradb/row/row0ins.c
index da035421ab9..9bda27e4b1f 100644
--- a/storage/xtradb/row/row0ins.c
+++ b/storage/xtradb/row/row0ins.c
@@ -496,6 +496,8 @@ row_ins_cascade_calc_update_vec(
ufield->field_no
= dict_table_get_nth_col_pos(
table, dict_col_get_no(col));
+
+ ufield->orig_len = 0;
ufield->exp = NULL;
ufield->new_val = parent_ufield->new_val;
diff --git a/storage/xtradb/srv/srv0srv.c b/storage/xtradb/srv/srv0srv.c
index 589f632ff5b..0c07d75b39a 100644
--- a/storage/xtradb/srv/srv0srv.c
+++ b/storage/xtradb/srv/srv0srv.c
@@ -104,7 +104,7 @@ UNIV_INTERN ulint srv_activity_count = 0;
UNIV_INTERN ulint srv_fatal_semaphore_wait_threshold = 600;
/**/
-UNIV_INTERN ulong srv_kill_idle_transaction = 0;
+UNIV_INTERN long long srv_kill_idle_transaction = 0;
/* How much data manipulation language (DML) statements need to be delayed,
in microseconds, in order to reduce the lagging of the purge thread. */