summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2010-03-15 12:51:23 +0100
committerSergei Golubchik <sergii@pisem.net>2010-03-15 12:51:23 +0100
commitf09ca00e088b316441bb76e97ba097bc9f3da7d3 (patch)
tree1a557d74018ed9cd073b5aa960bd62421962e73d /storage
parent2ceaffc4672c62a772890da7761d11f13d3f5ee4 (diff)
parent71b3e46b0160936596195682a731703900fb4fff (diff)
downloadmariadb-git-f09ca00e088b316441bb76e97ba097bc9f3da7d3.tar.gz
merged
Diffstat (limited to 'storage')
-rw-r--r--storage/archive/ha_archive.cc2
-rw-r--r--storage/federatedx/ha_federatedx.cc2
-rw-r--r--storage/ibmdb2i/db2i_constraints.cc28
-rw-r--r--storage/ibmdb2i/ha_ibmdb2i.cc2
-rw-r--r--storage/innobase/fil/fil0fil.c29
-rw-r--r--storage/innobase/handler/ha_innodb.cc241
-rw-r--r--storage/innobase/handler/ha_innodb.h3
-rw-r--r--storage/innobase/include/fil0fil.h10
-rw-r--r--storage/innobase/include/lock0lock.h9
-rw-r--r--storage/innobase/include/mtr0mtr.h6
-rw-r--r--storage/innobase/include/srv0srv.h26
-rw-r--r--storage/innobase/lock/lock0lock.c22
-rw-r--r--storage/innobase/log/log0log.c2
-rw-r--r--storage/innobase/log/log0recv.c7
-rw-r--r--storage/innobase/row/row0mysql.c32
-rw-r--r--storage/innobase/srv/srv0srv.c175
-rw-r--r--storage/innobase/srv/srv0start.c15
-rw-r--r--storage/innodb_plugin/CMakeLists.txt2
-rw-r--r--storage/innodb_plugin/handler/ha_innodb.cc3
-rw-r--r--storage/maria/ha_maria.cc2
-rw-r--r--storage/maria/ma_delete.c2
-rw-r--r--storage/maria/ma_key_recover.h1
-rw-r--r--storage/maria/ma_loghandler.c1
-rw-r--r--storage/maria/ma_page.c24
-rw-r--r--storage/maria/ma_rkey.c3
-rw-r--r--storage/maria/ma_search.c103
-rw-r--r--storage/maria/ma_write.c6
-rw-r--r--storage/maria/maria_def.h7
-rw-r--r--storage/myisam/ft_stopwords.c2
-rw-r--r--storage/myisam/mi_create.c7
-rw-r--r--storage/myisam/mi_packrec.c41
-rw-r--r--storage/myisam/mi_static.c2
-rw-r--r--storage/myisam/mi_write.c7
-rw-r--r--storage/myisam/myisamdef.h1
-rw-r--r--storage/myisammrg/ha_myisammrg.cc2
-rw-r--r--storage/xtradb/btr/btr0cur.c2
36 files changed, 544 insertions, 285 deletions
diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc
index 5b67782a868..ad54782996c 100644
--- a/storage/archive/ha_archive.cc
+++ b/storage/archive/ha_archive.cc
@@ -1490,7 +1490,7 @@ int ha_archive::info(uint flag)
stats.create_time= (ulong) file_stat.st_ctime;
stats.update_time= (ulong) file_stat.st_mtime;
stats.mean_rec_length= stats.records ?
- stats.data_file_length / stats.records : table->s->reclength;
+ ulong(stats.data_file_length / stats.records) : table->s->reclength;
stats.max_data_file_length= MAX_FILE_SIZE;
}
stats.delete_length= 0;
diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc
index e06f39c073f..2c74b2f6675 100644
--- a/storage/federatedx/ha_federatedx.cc
+++ b/storage/federatedx/ha_federatedx.cc
@@ -1783,7 +1783,7 @@ int ha_federatedx::open(const char *name, int mode, uint test_if_locked)
int ha_federatedx::close(void)
{
- int retval, error;
+ int retval= 0, error;
THD *thd= current_thd;
DBUG_ENTER("ha_federatedx::close");
diff --git a/storage/ibmdb2i/db2i_constraints.cc b/storage/ibmdb2i/db2i_constraints.cc
index 9a96eda1173..1fde0dd3d14 100644
--- a/storage/ibmdb2i/db2i_constraints.cc
+++ b/storage/ibmdb2i/db2i_constraints.cc
@@ -329,7 +329,7 @@ char* ha_ibmdb2i::get_foreign_key_create_info(void)
/* Process the constraint name. */
- info.strncat(STRING_WITH_LEN(" CONSTRAINT "));
+ info.strncat(STRING_WITH_LEN(",\n CONSTRAINT "));
convNameForCreateInfo(thd, info,
FKCstDef->CstName.Name, FKCstDef->CstName.Len);
@@ -398,7 +398,6 @@ char* ha_ibmdb2i::get_foreign_key_create_info(void)
if ((i+1) < cstCnt)
{
- info.strcat(',');
tempPtr = (char*)cstHdr + cstHdr->CstLen;
cstHdr = (constraint_hdr_t*)(tempPtr);
}
@@ -671,28 +670,3 @@ uint ha_ibmdb2i::referenced_by_foreign_key(void)
}
DBUG_RETURN(count);
}
-
-
-bool ha_ibmdb2i::check_if_incompatible_data(HA_CREATE_INFO *info,
- uint table_changes)
-{
- DBUG_ENTER("ha_ibmdb2i::check_if_incompatible_data");
- uint i;
- /* Check that auto_increment value and field definitions were
- not changed. */
- if ((info->used_fields & HA_CREATE_USED_AUTO &&
- info->auto_increment_value != 0) ||
- table_changes != IS_EQUAL_YES)
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- /* Check if any fields were renamed. */
- for (i= 0; i < table->s->fields; i++)
- {
- Field *field= table->field[i];
- if (field->flags & FIELD_IS_RENAMED)
- {
- DBUG_PRINT("info", ("Field has been renamed, copy table"));
- DBUG_RETURN(COMPATIBLE_DATA_NO);
- }
- }
- DBUG_RETURN(COMPATIBLE_DATA_YES);
-}
diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc
index 0fc2d1e83dc..39096be7848 100644
--- a/storage/ibmdb2i/ha_ibmdb2i.cc
+++ b/storage/ibmdb2i/ha_ibmdb2i.cc
@@ -284,7 +284,7 @@ static int ibmdb2i_init_func(void *p)
was_ILE_inited = false;
ibmdb2i_hton= (handlerton *)p;
VOID(pthread_mutex_init(&ibmdb2i_mutex,MY_MUTEX_INIT_FAST));
- (void) hash_init(&ibmdb2i_open_tables,system_charset_info,32,0,0,
+ (void) hash_init(&ibmdb2i_open_tables,table_alias_charset,32,0,0,
(hash_get_key) ibmdb2i_get_key,0,0);
ibmdb2i_hton->state= SHOW_OPTION_YES;
diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c
index 42e5166c9e4..3810fefd3cb 100644
--- a/storage/innobase/fil/fil0fil.c
+++ b/storage/innobase/fil/fil0fil.c
@@ -1740,6 +1740,8 @@ fil_op_write_log(
MLOG_FILE_DELETE, or
MLOG_FILE_RENAME */
ulint space_id, /* in: space id */
+ ulint log_flags, /* in: redo log flags (stored
+ in the page number field) */
const char* name, /* in: table name in the familiar
'databasename/tablename' format, or
the file path in the case of
@@ -1760,8 +1762,8 @@ fil_op_write_log(
return;
}
- log_ptr = mlog_write_initial_log_record_for_file_op(type, space_id, 0,
- log_ptr, mtr);
+ log_ptr = mlog_write_initial_log_record_for_file_op(
+ type, space_id, log_flags, log_ptr, mtr);
/* Let us store the strings as null-terminated for easier readability
and handling */
@@ -1810,11 +1812,11 @@ fil_op_log_parse_or_replay(
not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */
- ibool do_replay, /* in: TRUE if we want to replay the
- operation, and not just parse the log record */
- ulint space_id) /* in: if do_replay is TRUE, the space id of
- the tablespace in question; otherwise
- ignored */
+ ulint space_id, /* in: the space id of the tablespace in
+ question, or 0 if the log record should
+ only be parsed but not replayed */
+ ulint log_flags) /* in: redo log flags
+ (stored in the page number parameter) */
{
ulint name_len;
ulint new_name_len;
@@ -1868,7 +1870,7 @@ fil_op_log_parse_or_replay(
printf("new name %s\n", new_name);
}
*/
- if (do_replay == FALSE) {
+ if (!space_id) {
return(ptr);
}
@@ -1917,6 +1919,8 @@ fil_op_log_parse_or_replay(
} else if (fil_get_space_id_for_table(name)
!= ULINT_UNDEFINED) {
/* Do nothing */
+ } else if (log_flags & MLOG_FILE_FLAG_TEMP) {
+ /* Temporary table, do nothing */
} else {
/* Create the database directory for name, if it does
not exist yet */
@@ -2078,7 +2082,7 @@ try_again:
to write any log record */
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_DELETE, id, path, NULL, &mtr);
+ fil_op_write_log(MLOG_FILE_DELETE, id, 0, path, NULL, &mtr);
mtr_commit(&mtr);
#endif
mem_free(path);
@@ -2349,7 +2353,7 @@ retry:
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_RENAME, id, old_name, new_name,
+ fil_op_write_log(MLOG_FILE_RENAME, id, 0, old_name, new_name,
&mtr);
mtr_commit(&mtr);
}
@@ -2525,8 +2529,9 @@ error_exit2:
mtr_start(&mtr);
- fil_op_write_log(MLOG_FILE_CREATE, *space_id, tablename,
- NULL, &mtr);
+ fil_op_write_log(MLOG_FILE_CREATE, *space_id,
+ is_temp ? MLOG_FILE_FLAG_TEMP : 0,
+ tablename, NULL, &mtr);
mtr_commit(&mtr);
}
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index e2a76758888..08b4d39052a 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -40,12 +40,6 @@ have disabled the InnoDB inlining in this file. */
#include "ha_innodb.h"
#include <mysql/plugin.h>
-#ifndef MYSQL_SERVER
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
-is defined the same in both builds: the MySQL server and the InnoDB plugin. */
-extern pthread_mutex_t LOCK_thread_count;
-#endif /* MYSQL_SERVER */
-
/** to protect innobase_open_files */
static pthread_mutex_t innobase_share_mutex;
/** to force correct commit order in binlog */
@@ -2592,57 +2586,150 @@ normalize_table_name(
}
/************************************************************************
+Get the upper limit of the MySQL integral and floating-point type. */
+static
+ulonglong
+innobase_get_int_col_max_value(
+/*===========================*/
+ /* out: maximum allowed value for the field */
+ const Field* field) /* in: MySQL field */
+{
+ ulonglong max_value = 0;
+
+ switch(field->key_type()) {
+ /* TINY */
+ case HA_KEYTYPE_BINARY:
+ max_value = 0xFFULL;
+ break;
+ case HA_KEYTYPE_INT8:
+ max_value = 0x7FULL;
+ break;
+ /* SHORT */
+ case HA_KEYTYPE_USHORT_INT:
+ max_value = 0xFFFFULL;
+ break;
+ case HA_KEYTYPE_SHORT_INT:
+ max_value = 0x7FFFULL;
+ break;
+ /* MEDIUM */
+ case HA_KEYTYPE_UINT24:
+ max_value = 0xFFFFFFULL;
+ break;
+ case HA_KEYTYPE_INT24:
+ max_value = 0x7FFFFFULL;
+ break;
+ /* LONG */
+ case HA_KEYTYPE_ULONG_INT:
+ max_value = 0xFFFFFFFFULL;
+ break;
+ case HA_KEYTYPE_LONG_INT:
+ max_value = 0x7FFFFFFFULL;
+ break;
+ /* BIG */
+ case HA_KEYTYPE_ULONGLONG:
+ max_value = 0xFFFFFFFFFFFFFFFFULL;
+ break;
+ case HA_KEYTYPE_LONGLONG:
+ max_value = 0x7FFFFFFFFFFFFFFFULL;
+ break;
+ case HA_KEYTYPE_FLOAT:
+ /* We use the maximum as per IEEE754-2008 standard, 2^24 */
+ max_value = 0x1000000ULL;
+ break;
+ case HA_KEYTYPE_DOUBLE:
+ /* We use the maximum as per IEEE754-2008 standard, 2^53 */
+ max_value = 0x20000000000000ULL;
+ break;
+ default:
+ ut_error;
+ }
+
+ return(max_value);
+}
+
+/************************************************************************
Set the autoinc column max value. This should only be called once from
ha_innobase::open(). Therefore there's no need for a covering lock. */
-ulong
+void
ha_innobase::innobase_initialize_autoinc()
/*======================================*/
{
- dict_index_t* index;
ulonglong auto_inc;
- const char* col_name;
- ulint error = DB_SUCCESS;
- dict_table_t* innodb_table = prebuilt->table;
-
- col_name = table->found_next_number_field->field_name;
- index = innobase_get_index(table->s->next_number_index);
-
- /* Execute SELECT MAX(col_name) FROM TABLE; */
- error = row_search_max_autoinc(index, col_name, &auto_inc);
+ const Field* field = table->found_next_number_field;
- if (error == DB_SUCCESS) {
+ if (field != NULL) {
+ auto_inc = innobase_get_int_col_max_value(field);
+ } else {
+ /* We have no idea what's been passed in to us as the
+ autoinc column. We set it to the MAX_INT of our table
+ autoinc type. */
+ auto_inc = 0xFFFFFFFFFFFFFFFFULL;
- /* At the this stage we dont' know the increment
- or the offset, so use default inrement of 1. */
- ++auto_inc;
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: Unable to determine the AUTOINC "
+ "column name\n");
+ }
- dict_table_autoinc_initialize(innodb_table, auto_inc);
+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
+ /* If the recovery level is set so high that writes
+ are disabled we force the AUTOINC counter to the MAX
+ value effectively disabling writes to the table.
+ Secondly, we avoid reading the table in case the read
+ results in failure due to a corrupted table/index.
+
+ We will not return an error to the client, so that the
+ tables can be dumped with minimal hassle. If an error
+ were returned in this case, the first attempt to read
+ the table would fail and subsequent SELECTs would succeed. */
+ } else if (field == NULL) {
+ my_error(ER_AUTOINC_READ_FAILED, MYF(0));
+ } else {
+ dict_index_t* index;
+ const char* col_name;
+ ulonglong read_auto_inc;
+ ulint err;
- } else if (error == DB_RECORD_NOT_FOUND) {
- ut_print_timestamp(stderr);
- fprintf(stderr, " InnoDB: MySQL and InnoDB data "
- "dictionaries are out of sync.\n"
- "InnoDB: Unable to find the AUTOINC column %s in the "
- "InnoDB table %s.\n"
- "InnoDB: We set the next AUTOINC column value to the "
- "maximum possible value,\n"
- "InnoDB: in effect disabling the AUTOINC next value "
- "generation.\n"
- "InnoDB: You can either set the next AUTOINC value "
- "explicitly using ALTER TABLE\n"
- "InnoDB: or fix the data dictionary by recreating "
- "the table.\n",
- col_name, index->table->name);
+ update_thd(ha_thd());
+ col_name = field->field_name;
+ index = innobase_get_index(table->s->next_number_index);
- auto_inc = 0xFFFFFFFFFFFFFFFFULL;
+ /* Execute SELECT MAX(col_name) FROM TABLE; */
+ err = row_search_max_autoinc(index, col_name, &read_auto_inc);
- dict_table_autoinc_initialize(innodb_table, auto_inc);
+ switch (err) {
+ case DB_SUCCESS:
+ /* At the this stage we do not know the increment
+ or the offset, so use a default increment of 1. */
+ auto_inc = read_auto_inc + 1;
+ break;
- error = DB_SUCCESS;
- } /* else other errors are still fatal */
+ case DB_RECORD_NOT_FOUND:
+ ut_print_timestamp(stderr);
+ fprintf(stderr, " InnoDB: MySQL and InnoDB data "
+ "dictionaries are out of sync.\n"
+ "InnoDB: Unable to find the AUTOINC column "
+ "%s in the InnoDB table %s.\n"
+ "InnoDB: We set the next AUTOINC column "
+ "value to the maximum possible value,\n"
+ "InnoDB: in effect disabling the AUTOINC "
+ "next value generation.\n"
+ "InnoDB: You can either set the next "
+ "AUTOINC value explicitly using ALTER TABLE\n"
+ "InnoDB: or fix the data dictionary by "
+ "recreating the table.\n",
+ col_name, index->table->name);
+
+ my_error(ER_AUTOINC_READ_FAILED, MYF(0));
+ break;
+ default:
+ /* row_search_max_autoinc() should only return
+ one of DB_SUCCESS or DB_RECORD_NOT_FOUND. */
+ ut_error;
+ }
+ }
- return(ulong(error));
+ dict_table_autoinc_initialize(prebuilt->table, auto_inc);
}
/*********************************************************************
@@ -2840,8 +2927,6 @@ retry:
/* Only if the table has an AUTOINC column. */
if (prebuilt->table != NULL && table->found_next_number_field != NULL) {
- ulint error;
-
dict_table_autoinc_lock(prebuilt->table);
/* Since a table can already be "open" in InnoDB's internal
@@ -2850,8 +2935,7 @@ retry:
autoinc value from a previous MySQL open. */
if (dict_table_autoinc_read(prebuilt->table) == 0) {
- error = innobase_initialize_autoinc();
- ut_a(error == DB_SUCCESS);
+ innobase_initialize_autoinc();
}
dict_table_autoinc_unlock(prebuilt->table);
@@ -3672,67 +3756,6 @@ skip_field:
}
/************************************************************************
-Get the upper limit of the MySQL integral and floating-point type. */
-
-ulonglong
-ha_innobase::innobase_get_int_col_max_value(
-/*========================================*/
- const Field* field)
-{
- ulonglong max_value = 0;
-
- switch(field->key_type()) {
- /* TINY */
- case HA_KEYTYPE_BINARY:
- max_value = 0xFFULL;
- break;
- case HA_KEYTYPE_INT8:
- max_value = 0x7FULL;
- break;
- /* SHORT */
- case HA_KEYTYPE_USHORT_INT:
- max_value = 0xFFFFULL;
- break;
- case HA_KEYTYPE_SHORT_INT:
- max_value = 0x7FFFULL;
- break;
- /* MEDIUM */
- case HA_KEYTYPE_UINT24:
- max_value = 0xFFFFFFULL;
- break;
- case HA_KEYTYPE_INT24:
- max_value = 0x7FFFFFULL;
- break;
- /* LONG */
- case HA_KEYTYPE_ULONG_INT:
- max_value = 0xFFFFFFFFULL;
- break;
- case HA_KEYTYPE_LONG_INT:
- max_value = 0x7FFFFFFFULL;
- break;
- /* BIG */
- case HA_KEYTYPE_ULONGLONG:
- max_value = 0xFFFFFFFFFFFFFFFFULL;
- break;
- case HA_KEYTYPE_LONGLONG:
- max_value = 0x7FFFFFFFFFFFFFFFULL;
- break;
- case HA_KEYTYPE_FLOAT:
- /* We use the maximum as per IEEE754-2008 standard, 2^24 */
- max_value = 0x1000000ULL;
- break;
- case HA_KEYTYPE_DOUBLE:
- /* We use the maximum as per IEEE754-2008 standard, 2^53 */
- max_value = 0x20000000000000ULL;
- break;
- default:
- ut_error;
- }
-
- return(max_value);
-}
-
-/************************************************************************
This special handling is really to overcome the limitations of MySQL's
binlogging. We need to eliminate the non-determinism that will arise in
INSERT ... SELECT type of statements, since MySQL binlog only stores the
@@ -7421,8 +7444,8 @@ innodb_show_status(
mutex_enter_noninline(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
- srv_printf_innodb_monitor(srv_monitor_file,
- &trx_list_start, &trx_list_end);
+ srv_printf_innodb_monitor(srv_monitor_file, FALSE,
+ &trx_list_start, &trx_list_end);
flen = ftell(srv_monitor_file);
os_file_set_eof(srv_monitor_file);
diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h
index 6d66b6456fb..bed064d9d84 100644
--- a/storage/innobase/handler/ha_innodb.h
+++ b/storage/innobase/handler/ha_innodb.h
@@ -78,9 +78,8 @@ class ha_innobase: public handler
ulong innobase_reset_autoinc(ulonglong auto_inc);
ulong innobase_get_autoinc(ulonglong* value);
ulong innobase_update_autoinc(ulonglong auto_inc);
- ulong innobase_initialize_autoinc();
+ void innobase_initialize_autoinc();
dict_index_t* innobase_get_index(uint keynr);
- ulonglong innobase_get_int_col_max_value(const Field* field);
/* Init values for the class: */
public:
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 6b8fd4b03d5..251d6c22547 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -330,11 +330,11 @@ fil_op_log_parse_or_replay(
not fir completely between ptr and end_ptr */
byte* end_ptr, /* in: buffer end */
ulint type, /* in: the type of this log record */
- ibool do_replay, /* in: TRUE if we want to replay the
- operation, and not just parse the log record */
- ulint space_id); /* in: if do_replay is TRUE, the space id of
- the tablespace in question; otherwise
- ignored */
+ ulint space_id, /* in: the space id of the tablespace in
+ question, or 0 if the log record should
+ only be parsed but not replayed */
+ ulint log_flags); /* in: redo log flags
+ (stored in the page number parameter) */
/***********************************************************************
Deletes a single-table tablespace. The tablespace must be cached in the
memory cache. */
diff --git a/storage/innobase/include/lock0lock.h b/storage/innobase/include/lock0lock.h
index 635724bf5a1..beaf17eda01 100644
--- a/storage/innobase/include/lock0lock.h
+++ b/storage/innobase/include/lock0lock.h
@@ -579,10 +579,15 @@ lock_rec_print(
/*************************************************************************
Prints info of locks for all transactions. */
-void
+ibool
lock_print_info_summary(
/*====================*/
- FILE* file); /* in: file where to print */
+ /* out: FALSE if not able to obtain
+ kernel mutex and exits without
+ printing info */
+ FILE* file, /* in: file where to print */
+ ibool nowait);/* in: whether to wait for the kernel
+ mutex */
/*************************************************************************
Prints info of locks for each transaction. */
diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h
index 2a160d27e0c..a6e2976830b 100644
--- a/storage/innobase/include/mtr0mtr.h
+++ b/storage/innobase/include/mtr0mtr.h
@@ -134,6 +134,12 @@ flag value must give the length also! */
#define MLOG_BIGGEST_TYPE ((byte)46) /* biggest value (used in
asserts) */
+/* Flags for MLOG_FILE operations (stored in the page number
+parameter, called log_flags in the functions). The page number
+parameter was initially written as 0. */
+#define MLOG_FILE_FLAG_TEMP 1 /* identifies TEMPORARY TABLE in
+ MLOG_FILE_CREATE */
+
/*******************************************************************
Starts a mini-transaction and creates a mini-transaction handle
and buffer in the memory buffer given by the caller. */
diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h
index 67144a41d3d..3dd4bb961f9 100644
--- a/storage/innobase/include/srv0srv.h
+++ b/storage/innobase/include/srv0srv.h
@@ -146,7 +146,8 @@ extern ibool srv_print_innodb_tablespace_monitor;
extern ibool srv_print_verbose_log;
extern ibool srv_print_innodb_table_monitor;
-extern ibool srv_lock_timeout_and_monitor_active;
+extern ibool srv_lock_timeout_active;
+extern ibool srv_monitor_active;
extern ibool srv_error_monitor_active;
extern ulong srv_n_spin_wait_rounds;
@@ -427,12 +428,21 @@ srv_release_mysql_thread_if_suspended(
que_thr_t* thr); /* in: query thread associated with the
MySQL OS thread */
/*************************************************************************
-A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+A thread which wakes up threads whose lock wait may have lasted too
+long. */
os_thread_ret_t
-srv_lock_timeout_and_monitor_thread(
-/*================================*/
+srv_lock_timeout_thread(
+/*====================*/
+ /* out: a dummy parameter */
+ void* arg); /* in: a dummy parameter required by
+ os_thread_create */
+/*************************************************************************
+A thread which prints the info output by various InnoDB monitors. */
+
+os_thread_ret_t
+srv_monitor_thread(
+/*===============*/
/* out: a dummy parameter */
void* arg); /* in: a dummy parameter required by
os_thread_create */
@@ -449,10 +459,14 @@ srv_error_monitor_thread(
/**********************************************************************
Outputs to a file the output of the InnoDB Monitor. */
-void
+ibool
srv_printf_innodb_monitor(
/*======================*/
+ /* out: FALSE if not all information printed
+ due to failure to obtain necessary mutex */
FILE* file, /* in: output stream */
+ ibool nowait, /* in: whether to wait for kernel
+ mutex. */
ulint* trx_start, /* out: file position of the start of
the list of active transactions */
ulint* trx_end); /* out: file position of the end of
diff --git a/storage/innobase/lock/lock0lock.c b/storage/innobase/lock/lock0lock.c
index 80aef45ea35..4cc10931060 100644
--- a/storage/innobase/lock/lock0lock.c
+++ b/storage/innobase/lock/lock0lock.c
@@ -4192,12 +4192,27 @@ lock_get_n_rec_locks(void)
/*************************************************************************
Prints info of locks for all transactions. */
-void
+ibool
lock_print_info_summary(
/*====================*/
- FILE* file) /* in: file where to print */
+ /* out: FALSE if not able to obtain
+ kernel mutex and exit without
+ printing lock info */
+ FILE* file, /* in: file where to print */
+ ibool nowait) /* in: whether to wait for the kernel
+ mutex */
{
- lock_mutex_enter_kernel();
+
+ /* if nowait is FALSE, wait on the kernel mutex,
+ otherwise return immediately if fail to obtain the
+ mutex. */
+ if (!nowait) {
+ lock_mutex_enter_kernel();
+ } else if (mutex_enter_nowait(&kernel_mutex)) {
+ fputs("FAIL TO OBTAIN KERNEL MUTEX, "
+ "SKIP LOCK INFO PRINTING\n", file);
+ return(FALSE);
+ }
if (lock_deadlock_found) {
fputs("------------------------\n"
@@ -4231,6 +4246,7 @@ lock_print_info_summary(
"Total number of lock structs in row lock hash table %lu\n",
(ulong) lock_get_n_rec_locks());
#endif /* PRINT_NUM_OF_LOCK_STRUCTS */
+ return(TRUE);
}
/*************************************************************************
diff --git a/storage/innobase/log/log0log.c b/storage/innobase/log/log0log.c
index b10c348b24d..3300997112b 100644
--- a/storage/innobase/log/log0log.c
+++ b/storage/innobase/log/log0log.c
@@ -3045,7 +3045,7 @@ loop:
if (srv_fast_shutdown < 2
&& (srv_error_monitor_active
- || srv_lock_timeout_and_monitor_active)) {
+ || srv_lock_timeout_active || srv_monitor_active)) {
mutex_exit(&kernel_mutex);
diff --git a/storage/innobase/log/log0recv.c b/storage/innobase/log/log0recv.c
index aef58b7b576..5d309768064 100644
--- a/storage/innobase/log/log0recv.c
+++ b/storage/innobase/log/log0recv.c
@@ -939,8 +939,7 @@ recv_parse_or_apply_log_rec_body(
case MLOG_FILE_CREATE:
case MLOG_FILE_RENAME:
case MLOG_FILE_DELETE:
- ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, FALSE,
- ULINT_UNDEFINED);
+ ptr = fil_op_log_parse_or_replay(ptr, end_ptr, type, 0, 0);
break;
default:
ptr = NULL;
@@ -1938,8 +1937,8 @@ loop:
point to the datadir we should use there */
if (NULL == fil_op_log_parse_or_replay(
- body, end_ptr, type, TRUE,
- space)) {
+ body, end_ptr, type,
+ space, page_no)) {
fprintf(stderr,
"InnoDB: Error: file op"
" log record of type %lu"
diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c
index 4fcb1fbf9f2..f7156403247 100644
--- a/storage/innobase/row/row0mysql.c
+++ b/storage/innobase/row/row0mysql.c
@@ -3245,19 +3245,13 @@ check_next_foreign:
"END;\n"
, FALSE, trx);
- if (err != DB_SUCCESS) {
- ut_a(err == DB_OUT_OF_FILE_SPACE);
-
- err = DB_MUST_GET_MORE_FILE_SPACE;
-
- row_mysql_handle_errors(&err, trx, NULL, NULL);
-
- ut_error;
- } else {
+ switch (err) {
ibool is_path;
const char* name_or_path;
mem_heap_t* heap;
+ case DB_SUCCESS:
+
heap = mem_heap_create(200);
/* Clone the name, in case it has been allocated
@@ -3322,7 +3316,27 @@ check_next_foreign:
}
mem_heap_free(heap);
+ break;
+
+ case DB_TOO_MANY_CONCURRENT_TRXS:
+ /* Cannot even find a free slot for the
+ the undo log. We can directly exit here
+ and return the DB_TOO_MANY_CONCURRENT_TRXS
+ error. */
+ break;
+
+ case DB_OUT_OF_FILE_SPACE:
+ err = DB_MUST_GET_MORE_FILE_SPACE;
+
+ row_mysql_handle_errors(&err, trx, NULL, NULL);
+
+ /* Fall through to raise error */
+
+ default:
+ /* No other possible error returns */
+ ut_error;
}
+
funct_exit:
trx_commit_for_mysql(trx);
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 71e74ab848b..26ea7958d0d 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -64,7 +64,8 @@ ulint srv_fatal_semaphore_wait_threshold = 600;
in microseconds, in order to reduce the lagging of the purge thread. */
ulint srv_dml_needed_delay = 0;
-ibool srv_lock_timeout_and_monitor_active = FALSE;
+ibool srv_lock_timeout_active = FALSE;
+ibool srv_monitor_active = FALSE;
ibool srv_error_monitor_active = FALSE;
const char* srv_main_thread_op_info = "";
@@ -122,6 +123,16 @@ ulint srv_log_file_size = ULINT_MAX; /* size in database pages */
ulint srv_log_buffer_size = ULINT_MAX; /* size in database pages */
ulong srv_flush_log_at_trx_commit = 1;
+/* Maximum number of times allowed to conditionally acquire
+mutex before switching to blocking wait on the mutex */
+#define MAX_MUTEX_NOWAIT 20
+
+/* Check whether the number of failed nonblocking mutex
+acquisition attempts exceeds maximum allowed value. If so,
+srv_printf_innodb_monitor() will request mutex acquisition
+with mutex_enter(), which will wait until it gets the mutex. */
+#define MUTEX_NOWAIT(mutex_skipped) ((mutex_skipped) < MAX_MUTEX_NOWAIT)
+
byte srv_latin1_ordering[256] /* The sort order table of the latin1
character set. The following table is
the MySQL order as of Feb 10th, 2002 */
@@ -1626,10 +1637,13 @@ srv_refresh_innodb_monitor_stats(void)
/**********************************************************************
Outputs to a file the output of the InnoDB Monitor. */
-void
+ibool
srv_printf_innodb_monitor(
/*======================*/
+ /* out: FALSE if not all information printed
+ due to failure to obtain necessary mutex */
FILE* file, /* in: output stream */
+ ibool nowait, /* in: whether to wait for the mutex. */
ulint* trx_start, /* out: file position of the start of
the list of active transactions */
ulint* trx_end) /* out: file position of the end of
@@ -1638,6 +1652,7 @@ srv_printf_innodb_monitor(
double time_elapsed;
time_t current_time;
ulint n_reserved;
+ ibool ret;
mutex_enter(&srv_innodb_monitor_mutex);
@@ -1682,24 +1697,31 @@ srv_printf_innodb_monitor(
mutex_exit(&dict_foreign_err_mutex);
- lock_print_info_summary(file);
- if (trx_start) {
- long t = ftell(file);
- if (t < 0) {
- *trx_start = ULINT_UNDEFINED;
- } else {
- *trx_start = (ulint) t;
+ /* Only if lock_print_info_summary proceeds correctly,
+ before we call the lock_print_info_all_transactions
+ to print all the lock information. */
+ ret = lock_print_info_summary(file, nowait);
+
+ if (ret) {
+ if (trx_start) {
+ long t = ftell(file);
+ if (t < 0) {
+ *trx_start = ULINT_UNDEFINED;
+ } else {
+ *trx_start = (ulint) t;
+ }
}
- }
- lock_print_info_all_transactions(file);
- if (trx_end) {
- long t = ftell(file);
- if (t < 0) {
- *trx_end = ULINT_UNDEFINED;
- } else {
- *trx_end = (ulint) t;
+ lock_print_info_all_transactions(file);
+ if (trx_end) {
+ long t = ftell(file);
+ if (t < 0) {
+ *trx_end = ULINT_UNDEFINED;
+ } else {
+ *trx_end = (ulint) t;
+ }
}
}
+
fputs("--------\n"
"FILE I/O\n"
"--------\n", file);
@@ -1804,6 +1826,8 @@ srv_printf_innodb_monitor(
"============================\n", file);
mutex_exit(&srv_innodb_monitor_mutex);
fflush(file);
+
+ return(ret);
}
/**********************************************************************
@@ -1883,26 +1907,23 @@ srv_export_innodb_status(void)
}
/*************************************************************************
-A thread which wakes up threads whose lock wait may have lasted too long.
-This also prints the info output by various InnoDB monitors. */
+A thread prints the info output by various InnoDB monitors. */
os_thread_ret_t
-srv_lock_timeout_and_monitor_thread(
-/*================================*/
+srv_monitor_thread(
+/*===============*/
/* out: a dummy parameter */
void* arg __attribute__((unused)))
/* in: a dummy parameter required by
os_thread_create */
{
- srv_slot_t* slot;
double time_elapsed;
time_t current_time;
time_t last_table_monitor_time;
time_t last_tablespace_monitor_time;
time_t last_monitor_time;
- ibool some_waits;
- double wait_time;
- ulint i;
+ ulint mutex_skipped;
+ ibool last_srv_print_monitor;
#ifdef UNIV_DEBUG_THREAD_CREATION
fprintf(stderr, "Lock timeout thread starts, id %lu\n",
@@ -1913,13 +1934,15 @@ srv_lock_timeout_and_monitor_thread(
last_table_monitor_time = time(NULL);
last_tablespace_monitor_time = time(NULL);
last_monitor_time = time(NULL);
+ mutex_skipped = 0;
+ last_srv_print_monitor = srv_print_innodb_monitor;
loop:
- srv_lock_timeout_and_monitor_active = TRUE;
+ srv_monitor_active = TRUE;
- /* When someone is waiting for a lock, we wake up every second
- and check if a timeout has passed for a lock wait */
+ /* Wake up every 5 seconds to see if we need to print
+ monitor information. */
- os_thread_sleep(1000000);
+ os_thread_sleep(5000000);
current_time = time(NULL);
@@ -1929,14 +1952,40 @@ loop:
last_monitor_time = time(NULL);
if (srv_print_innodb_monitor) {
- srv_printf_innodb_monitor(stderr, NULL, NULL);
+ /* Reset mutex_skipped counter everytime
+ srv_print_innodb_monitor changes. This is to
+ ensure we will not be blocked by kernel_mutex
+ for short duration information printing,
+ such as requested by sync_array_print_long_waits() */
+ if (!last_srv_print_monitor) {
+ mutex_skipped = 0;
+ last_srv_print_monitor = TRUE;
+ }
+
+ if (!srv_printf_innodb_monitor(stderr,
+ MUTEX_NOWAIT(mutex_skipped),
+ NULL, NULL)) {
+ mutex_skipped++;
+ } else {
+ /* Reset the counter */
+ mutex_skipped = 0;
+ }
+ } else {
+ last_srv_print_monitor = FALSE;
}
+
if (srv_innodb_status) {
mutex_enter(&srv_monitor_file_mutex);
rewind(srv_monitor_file);
- srv_printf_innodb_monitor(srv_monitor_file, NULL,
- NULL);
+ if (!srv_printf_innodb_monitor(srv_monitor_file,
+ MUTEX_NOWAIT(mutex_skipped),
+ NULL, NULL)) {
+ mutex_skipped++;
+ } else {
+ mutex_skipped = 0;
+ }
+
os_file_set_eof(srv_monitor_file);
mutex_exit(&srv_monitor_file_mutex);
}
@@ -1989,6 +2038,56 @@ loop:
}
}
+ if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) {
+ goto exit_func;
+ }
+
+ if (srv_print_innodb_monitor
+ || srv_print_innodb_lock_monitor
+ || srv_print_innodb_tablespace_monitor
+ || srv_print_innodb_table_monitor) {
+ goto loop;
+ }
+
+ srv_monitor_active = FALSE;
+
+ goto loop;
+
+exit_func:
+ srv_monitor_active = FALSE;
+
+ /* We count the number of threads in os_thread_exit(). A created
+ thread should always use that to exit and not use return() to exit. */
+
+ os_thread_exit(NULL);
+
+ OS_THREAD_DUMMY_RETURN;
+}
+
+/*************************************************************************
+A thread which wakes up threads whose lock wait may have lasted too long. */
+
+os_thread_ret_t
+srv_lock_timeout_thread(
+/*====================*/
+ /* out: a dummy parameter */
+ void* arg __attribute__((unused)))
+ /* in: a dummy parameter required by
+ os_thread_create */
+{
+ srv_slot_t* slot;
+ ibool some_waits;
+ double wait_time;
+ ulint i;
+
+loop:
+ /* When someone is waiting for a lock, we wake up every second
+ and check if a timeout has passed for a lock wait */
+
+ os_thread_sleep(1000000);
+
+ srv_lock_timeout_active = TRUE;
+
mutex_enter(&kernel_mutex);
some_waits = FALSE;
@@ -2033,17 +2132,11 @@ loop:
goto exit_func;
}
- if (some_waits || srv_print_innodb_monitor
- || srv_print_innodb_lock_monitor
- || srv_print_innodb_tablespace_monitor
- || srv_print_innodb_table_monitor) {
+ if (some_waits) {
goto loop;
}
- /* No one was waiting for a lock and no monitor was active:
- suspend this thread */
-
- srv_lock_timeout_and_monitor_active = FALSE;
+ srv_lock_timeout_active = FALSE;
#if 0
/* The following synchronisation is disabled, since
@@ -2053,7 +2146,7 @@ loop:
goto loop;
exit_func:
- srv_lock_timeout_and_monitor_active = FALSE;
+ srv_lock_timeout_active = FALSE;
/* We count the number of threads in os_thread_exit(). A created
thread should always use that to exit and not use return() to exit. */
diff --git a/storage/innobase/srv/srv0start.c b/storage/innobase/srv/srv0start.c
index 4f261d1171b..d117ff16608 100644
--- a/storage/innobase/srv/srv0start.c
+++ b/storage/innobase/srv/srv0start.c
@@ -87,8 +87,8 @@ static os_file_t files[1000];
static mutex_t ios_mutex;
static ulint ios;
-static ulint n[SRV_MAX_N_IO_THREADS + 5];
-static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 5];
+static ulint n[SRV_MAX_N_IO_THREADS + 6];
+static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
/* We use this mutex to test the return value of pthread_mutex_trylock
on successful locking. HP-UX does NOT return 0, though Linux et al do. */
@@ -1596,15 +1596,20 @@ innobase_start_or_create_for_mysql(void)
/* fprintf(stderr, "Max allowed record size %lu\n",
page_get_free_space_of_empty() / 2); */
- /* Create the thread which watches the timeouts for lock waits
- and prints InnoDB monitor info */
+ /* Create the thread which watches the timeouts for lock
+ waits */
- os_thread_create(&srv_lock_timeout_and_monitor_thread, NULL,
+ os_thread_create(&srv_lock_timeout_thread, NULL,
thread_ids + 2 + SRV_MAX_N_IO_THREADS);
/* Create the thread which warns of long semaphore waits */
os_thread_create(&srv_error_monitor_thread, NULL,
thread_ids + 3 + SRV_MAX_N_IO_THREADS);
+
+ /* Create the thread which prints InnoDB monitor info */
+ os_thread_create(&srv_monitor_thread, NULL,
+ thread_ids + 4 + SRV_MAX_N_IO_THREADS);
+
srv_was_started = TRUE;
srv_is_being_started = FALSE;
diff --git a/storage/innodb_plugin/CMakeLists.txt b/storage/innodb_plugin/CMakeLists.txt
index 7900d1629dd..36e157ae736 100644
--- a/storage/innodb_plugin/CMakeLists.txt
+++ b/storage/innodb_plugin/CMakeLists.txt
@@ -83,4 +83,4 @@ SET(INNODB_PLUGIN_SOURCES btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c btr/btr0sea
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS -DIB_HAVE_PAUSE_INSTRUCTION)
#Disable storage engine, as we are using XtraDB
-#MYSQL_STORAGE_ENGINE(INNOBASE)
+#MYSQL_STORAGE_ENGINE(INNODB_PLUGIN)
diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc
index b51e9186fe4..47b8203091c 100644
--- a/storage/innodb_plugin/handler/ha_innodb.cc
+++ b/storage/innodb_plugin/handler/ha_innodb.cc
@@ -110,9 +110,6 @@ extern "C" {
# ifndef MYSQL_PLUGIN_IMPORT
# define MYSQL_PLUGIN_IMPORT /* nothing */
# endif /* MYSQL_PLUGIN_IMPORT */
-/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t
-is defined the same in both builds: the MySQL server and the InnoDB plugin. */
-extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count;
#if MYSQL_VERSION_ID < 50124
/* this is defined in mysql_priv.h inside #ifdef MYSQL_SERVER
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 4da650a5f00..459edc45a94 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -3316,11 +3316,11 @@ static struct st_mysql_sys_var* system_variables[]= {
MYSQL_SYSVAR(force_start_after_recovery_failures),
MYSQL_SYSVAR(group_commit),
MYSQL_SYSVAR(group_commit_interval),
- MYSQL_SYSVAR(page_checksum),
MYSQL_SYSVAR(log_dir_path),
MYSQL_SYSVAR(log_file_size),
MYSQL_SYSVAR(log_purge_type),
MYSQL_SYSVAR(max_sort_file_size),
+ MYSQL_SYSVAR(page_checksum),
MYSQL_SYSVAR(pagecache_age_threshold),
MYSQL_SYSVAR(pagecache_buffer_size),
MYSQL_SYSVAR(pagecache_division_limit),
diff --git a/storage/maria/ma_delete.c b/storage/maria/ma_delete.c
index 5b0a2ac8884..0e9e5caafbf 100644
--- a/storage/maria/ma_delete.c
+++ b/storage/maria/ma_delete.c
@@ -169,6 +169,8 @@ my_bool _ma_ck_delete(MARIA_HA *info, MARIA_KEY *key)
MARIA_KEY org_key;
DBUG_ENTER("_ma_ck_delete");
+ LINT_INIT_STRUCT(org_key);
+
save_key_data= key->data;
if (share->now_transactional)
{
diff --git a/storage/maria/ma_key_recover.h b/storage/maria/ma_key_recover.h
index 4b4198f3008..b580433c99a 100644
--- a/storage/maria/ma_key_recover.h
+++ b/storage/maria/ma_key_recover.h
@@ -63,7 +63,6 @@ extern my_bool write_hook_for_undo_key_insert(enum translog_record_type type,
extern my_bool write_hook_for_undo_key_delete(enum translog_record_type type,
TRN *trn, MARIA_HA *tbl_info,
LSN *lsn, void *hook_arg);
-void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
my_bool _ma_log_prefix(MARIA_PAGE *page, uint changed_length, int move_length);
my_bool _ma_log_suffix(MARIA_PAGE *page, uint org_length,
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index 73a2737b223..476b091594e 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -1457,6 +1457,7 @@ LSN translog_get_file_max_lsn_stored(uint32 file)
{
LOGHANDLER_FILE_INFO info;
+ LINT_INIT_STRUCT(info);
File fd= open_logfile_by_number_no_cache(file);
if ((fd < 0) ||
(translog_read_file_header(&info, fd) | my_close(fd, MYF(MY_WME))))
diff --git a/storage/maria/ma_page.c b/storage/maria/ma_page.c
index 54361b8ee3b..acbee2a6f07 100644
--- a/storage/maria/ma_page.c
+++ b/storage/maria/ma_page.c
@@ -64,6 +64,15 @@ void _ma_page_setup(MARIA_PAGE *page, MARIA_HA *info,
share->base.key_reflength : 0);
}
+#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
+void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
+{
+ uint length= page->size;
+ DBUG_ASSERT(length <= block_size - KEYPAGE_CHECKSUM_SIZE);
+ bzero(page->buff + length, share->block_size - length);
+}
+#endif
+
/**
Fetch a key-page in memory
@@ -102,8 +111,10 @@ my_bool _ma_fetch_keypage(MARIA_PAGE *page, MARIA_HA *info,
if (lock != PAGECACHE_LOCK_LEFT_UNLOCKED)
{
- DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE);
- page_link.unlock= PAGECACHE_LOCK_WRITE_UNLOCK;
+ DBUG_ASSERT(lock == PAGECACHE_LOCK_WRITE || PAGECACHE_LOCK_READ);
+ page_link.unlock= (lock == PAGECACHE_LOCK_WRITE ?
+ PAGECACHE_LOCK_WRITE_UNLOCK :
+ PAGECACHE_LOCK_READ_UNLOCK);
page_link.changed= 0;
push_dynamic(&info->pinned_pages, (void*) &page_link);
page->link_offset= info->pinned_pages.elements-1;
@@ -209,14 +220,7 @@ my_bool _ma_write_keypage(MARIA_PAGE *page, enum pagecache_page_lock lock,
}
#endif
-#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
- {
- uint length= page->size;
- DBUG_ASSERT(length <= block_size - KEYPAGE_CHECKSUM_SIZE);
- bzero(buff + length, block_size - length);
- }
-#endif
-
+ page_cleanup(share, page);
res= pagecache_write(share->pagecache,
&share->kfile,
(pgcache_page_no_t) (page->pos / block_size),
diff --git a/storage/maria/ma_rkey.c b/storage/maria/ma_rkey.c
index 9e529aca666..daf1fd5a60c 100644
--- a/storage/maria/ma_rkey.c
+++ b/storage/maria/ma_rkey.c
@@ -82,6 +82,9 @@ int maria_rkey(MARIA_HA *info, uchar *buf, int inx, const uchar *key_data,
rw_rdlock(&keyinfo->root_lock);
nextflag= maria_read_vec[search_flag] | key.flag;
+ if (search_flag != HA_READ_KEY_EXACT ||
+ ((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME))
+ nextflag|= SEARCH_SAVE_BUFF;
switch (keyinfo->key_alg) {
#ifdef HAVE_RTREE_KEYS
diff --git a/storage/maria/ma_search.c b/storage/maria/ma_search.c
index 77d9f22184d..d48749b1629 100644
--- a/storage/maria/ma_search.c
+++ b/storage/maria/ma_search.c
@@ -18,6 +18,10 @@
#include "ma_fulltext.h"
#include "m_ctype.h"
+static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
+ uint32 nextflag, register my_off_t pos,
+ MARIA_PINNED_PAGE **res_page_link,
+ uchar **res_page_buff);
static my_bool _ma_get_prev_key(MARIA_KEY *key, MARIA_PAGE *ma_page,
uchar *keypos);
@@ -57,7 +61,51 @@ int _ma_check_index(MARIA_HA *info, int inx)
*/
int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
- register my_off_t pos)
+ my_off_t pos)
+{
+ int error;
+ MARIA_PINNED_PAGE *page_link;
+ uchar *page_buff;
+
+ info->page_changed= 1; /* If page not saved */
+ if (!(error= _ma_search_no_save(info, key, nextflag, pos, &page_link,
+ &page_buff)))
+ {
+ if (nextflag & SEARCH_SAVE_BUFF)
+ {
+ bmove512(info->keyread_buff, page_buff, info->s->block_size);
+
+ /* Save position for a possible read next / previous */
+ info->int_keypos= info->keyread_buff + (ulonglong) info->int_keypos;
+ info->int_maxpos= info->keyread_buff + (ulonglong) info->int_maxpos;
+ info->int_keytree_version= key->keyinfo->version;
+ info->last_search_keypage= info->last_keypage;
+ info->page_changed= 0;
+ info->keyread_buff_used= 0;
+ }
+ }
+ _ma_unpin_all_pages(info, LSN_IMPOSSIBLE);
+ return (error);
+}
+
+/**
+ @breif Search after row by a key
+
+ ret_page_link Will contain pointer to page where we found key
+
+ @note
+ Position to row is stored in info->lastpos
+
+ @return
+ @retval 0 ok (key found)
+ @retval -1 Not found
+ @retval 1 If one should continue search on higher level
+*/
+
+static int _ma_search_no_save(register MARIA_HA *info, MARIA_KEY *key,
+ uint32 nextflag, register my_off_t pos,
+ MARIA_PINNED_PAGE **res_page_link,
+ uchar **res_page_buff)
{
my_bool last_key_not_used;
int error,flag;
@@ -66,6 +114,7 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
uchar lastkey[MARIA_MAX_KEY_BUFF];
MARIA_KEYDEF *keyinfo= key->keyinfo;
MARIA_PAGE page;
+ MARIA_PINNED_PAGE *page_link;
DBUG_ENTER("_ma_search");
DBUG_PRINT("enter",("pos: %lu nextflag: %u lastpos: %lu",
(ulong) pos, nextflag, (ulong) info->cur_row.lastpos));
@@ -81,10 +130,11 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
}
if (_ma_fetch_keypage(&page, info, keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED,
- DFLT_INIT_HITS, info->keyread_buff,
- test(!(nextflag & SEARCH_SAVE_BUFF))))
+ PAGECACHE_LOCK_READ, DFLT_INIT_HITS, 0, 0))
goto err;
+ page_link= dynamic_element(&info->pinned_pages,
+ info->pinned_pages.elements-1,
+ MARIA_PINNED_PAGE*);
DBUG_DUMP("page", page.buff, page.size);
flag= (*keyinfo->bin_search)(key, &page, nextflag, &keypos, lastkey,
@@ -98,8 +148,9 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
if (flag)
{
- if ((error= _ma_search(info, key, nextflag,
- _ma_kpos(nod_flag,keypos))) <= 0)
+ if ((error= _ma_search_no_save(info, key, nextflag,
+ _ma_kpos(nod_flag,keypos),
+ res_page_link, res_page_buff)) <= 0)
DBUG_RETURN(error);
if (flag >0)
@@ -118,26 +169,15 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
((keyinfo->flag & (HA_NOSAME | HA_NULL_PART)) != HA_NOSAME ||
(key->flag & SEARCH_PART_KEY) || info->s->base.born_transactional))
{
- if ((error= _ma_search(info, key, (nextflag | SEARCH_FIND) &
- ~(SEARCH_BIGGER | SEARCH_SMALLER | SEARCH_LAST),
- _ma_kpos(nod_flag,keypos))) >= 0 ||
+ if ((error= _ma_search_no_save(info, key, (nextflag | SEARCH_FIND) &
+ ~(SEARCH_BIGGER | SEARCH_SMALLER |
+ SEARCH_LAST),
+ _ma_kpos(nod_flag,keypos),
+ res_page_link, res_page_buff)) >= 0 ||
my_errno != HA_ERR_KEY_NOT_FOUND)
DBUG_RETURN(error);
- info->last_keypage= HA_OFFSET_ERROR; /* Buffer not in mem */
}
}
- if (pos != info->last_keypage)
- {
- uchar *old_buff= page.buff;
- if (_ma_fetch_keypage(&page, info, keyinfo, pos,
- PAGECACHE_LOCK_LEFT_UNLOCKED,DFLT_INIT_HITS,
- info->keyread_buff,
- test(!(nextflag & SEARCH_SAVE_BUFF))))
- goto err;
- /* Restore position if page buffer moved */
- keypos= page.buff + (keypos - old_buff);
- maxpos= page.buff + (maxpos - old_buff);
- }
info->last_key.keyinfo= keyinfo;
if ((nextflag & (SEARCH_SMALLER | SEARCH_LAST)) && flag != 0)
@@ -172,16 +212,15 @@ int _ma_search(register MARIA_HA *info, MARIA_KEY *key, uint32 nextflag,
}
info->cur_row.lastpos= _ma_row_pos_from_key(&info->last_key);
info->cur_row.trid= _ma_trid_from_key(&info->last_key);
- /* Save position for a possible read next / previous */
- info->int_keypos= info->keyread_buff + (keypos - page.buff);
- info->int_maxpos= info->keyread_buff + (maxpos - page.buff);
- info->int_nod_flag=nod_flag;
- info->int_keytree_version=keyinfo->version;
- info->last_search_keypage=info->last_keypage;
- info->page_changed=0;
- /* Set marker that buffer was used (Marker for mi_search_next()) */
- info->keyread_buff_used= (info->keyread_buff != page.buff);
+ /* Store offset to key */
+ info->int_keypos= (uchar*) (keypos - page.buff);
+ info->int_maxpos= (uchar*) (maxpos - page.buff);
+ info->int_nod_flag= nod_flag;
+ info->last_keypage= pos;
+ *res_page_link= page_link;
+ *res_page_buff= page.buff;
+
DBUG_PRINT("exit",("found key at %lu",(ulong) info->cur_row.lastpos));
DBUG_RETURN(0);
@@ -190,7 +229,7 @@ err:
info->cur_row.lastpos= HA_OFFSET_ERROR;
info->page_changed=1;
DBUG_RETURN (-1);
-} /* _ma_search */
+}
/*
diff --git a/storage/maria/ma_write.c b/storage/maria/ma_write.c
index 20304618229..3b9ca46899f 100644
--- a/storage/maria/ma_write.c
+++ b/storage/maria/ma_write.c
@@ -587,6 +587,12 @@ my_bool _ma_enlarge_root(MARIA_HA *info, MARIA_KEY *key, my_off_t *root)
/*
Search after a position for a key and store it there
+ TODO:
+ Change this to use pagecache directly instead of creating a copy
+ of the page. To do this, we must however change write-key-on-page
+ algorithm to not overwrite the buffer but instead store any overflow
+ key in a separate buffer.
+
@return
@retval -1 error
@retval 0 ok
diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h
index 1d60beece6b..29eb32a4fb2 100644
--- a/storage/maria/maria_def.h
+++ b/storage/maria/maria_def.h
@@ -979,6 +979,11 @@ extern ulonglong transid_get_packed(MARIA_SHARE *share, const uchar *from);
#define page_store_info(share, page) \
_ma_store_keypage_flag((share), (page)->buff, (page)->flag); \
_ma_store_page_used((share), (page)->buff, (page)->size);
+#ifdef IDENTICAL_PAGES_AFTER_RECOVERY
+void page_cleanup(MARIA_SHARE *share, MARIA_PAGE *page)
+#else
+#define page_cleanup(A,B) while (0)
+#endif
extern MARIA_KEY *_ma_make_key(MARIA_HA *info, MARIA_KEY *int_key, uint keynr,
uchar *key, const uchar *record,
@@ -1197,7 +1202,7 @@ void _ma_tmp_disable_logging_for_table(MARIA_HA *info,
my_bool log_incomplete);
my_bool _ma_reenable_logging_for_table(MARIA_HA *info, my_bool flush_pages);
my_bool write_log_record_for_bulk_insert(MARIA_HA *info);
-
+void _ma_unpin_all_pages(MARIA_HA *info, LSN undo_lsn);
#define MARIA_NO_CRC_NORMAL_PAGE 0xffffffff
#define MARIA_NO_CRC_BITMAP_PAGE 0xfffffffe
diff --git a/storage/myisam/ft_stopwords.c b/storage/myisam/ft_stopwords.c
index 5e550b9dff5..aa209e082e0 100644
--- a/storage/myisam/ft_stopwords.c
+++ b/storage/myisam/ft_stopwords.c
@@ -45,7 +45,7 @@ static int ft_add_stopword(const char *w)
{
FT_STOPWORD sw;
return !w ||
- (((sw.len= (uint) strlen(sw.pos=w)) >= ft_min_word_len) &&
+ (((sw.len= (uint) strlen(sw.pos=(const uchar *)w)) >= ft_min_word_len) &&
(tree_insert(stopwords3, &sw, 0, stopwords3->custom_arg)==NULL));
}
diff --git a/storage/myisam/mi_create.c b/storage/myisam/mi_create.c
index 1b92d64d529..d5ce941bf75 100644
--- a/storage/myisam/mi_create.c
+++ b/storage/myisam/mi_create.c
@@ -192,6 +192,13 @@ int mi_create(const char *name,uint keys,MI_KEYDEF *keydefs,
options|= HA_OPTION_CHECKSUM;
min_pack_length++;
}
+ /*
+ Don't set HA_OPTION_NULL_FIELDS if no checksums, as this flag makes
+ that file incompatible with MySQL. This is ok, as this flag is only
+ used if one specifics table level checksums.
+ */
+ if (!(options & HA_OPTION_CHECKSUM))
+ options&= ~HA_OPTION_NULL_FIELDS;
if (flags & HA_CREATE_DELAY_KEY_WRITE)
options|= HA_OPTION_DELAY_KEY_WRITE;
if (flags & HA_CREATE_RELIES_ON_SQL_LAYER)
diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c
index 37523a9acca..a3c700794f9 100644
--- a/storage/myisam/mi_packrec.c
+++ b/storage/myisam/mi_packrec.c
@@ -1493,20 +1493,54 @@ static int _mi_read_rnd_mempack_record(MI_INFO*, uchar *,my_off_t, my_bool);
my_bool _mi_memmap_file(MI_INFO *info)
{
MYISAM_SHARE *share=info->s;
+ my_bool eom;
+
DBUG_ENTER("mi_memmap_file");
if (!info->s->file_map)
{
+ my_off_t data_file_length= share->state.state.data_file_length;
+
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ eom= data_file_length > myisam_mmap_size - myisam_mmap_used - MEMMAP_EXTRA_MARGIN;
+ if (!eom)
+ myisam_mmap_used+= data_file_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
+ else
+ eom= data_file_length > myisam_mmap_size - MEMMAP_EXTRA_MARGIN;
+
+ if (eom)
+ {
+ DBUG_PRINT("warning", ("File is too large for mmap"));
+ DBUG_RETURN(0);
+ }
if (my_seek(info->dfile,0L,MY_SEEK_END,MYF(0)) <
share->state.state.data_file_length+MEMMAP_EXTRA_MARGIN)
{
DBUG_PRINT("warning",("File isn't extended for memmap"));
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
DBUG_RETURN(0);
}
if (mi_dynmap_file(info,
share->state.state.data_file_length +
MEMMAP_EXTRA_MARGIN))
+ {
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ myisam_mmap_used-= data_file_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
DBUG_RETURN(0);
+ }
}
info->opt_flag|= MEMMAP_USED;
info->read_record= share->read_record= _mi_read_mempack_record;
@@ -1519,6 +1553,13 @@ void _mi_unmap_file(MI_INFO *info)
{
VOID(my_munmap((char*) info->s->file_map,
(size_t) info->s->mmaped_length + MEMMAP_EXTRA_MARGIN));
+
+ if (myisam_mmap_size != SIZE_T_MAX)
+ {
+ pthread_mutex_lock(&THR_LOCK_myisam_mmap);
+ myisam_mmap_used-= info->s->mmaped_length + MEMMAP_EXTRA_MARGIN;
+ pthread_mutex_unlock(&THR_LOCK_myisam_mmap);
+ }
}
diff --git a/storage/myisam/mi_static.c b/storage/myisam/mi_static.c
index a3ba785a94f..27485e101ff 100644
--- a/storage/myisam/mi_static.c
+++ b/storage/myisam/mi_static.c
@@ -40,7 +40,7 @@ ulong myisam_concurrent_insert= 0;
my_off_t myisam_max_temp_length= MAX_FILE_SIZE;
ulong myisam_bulk_insert_tree_size=8192*1024;
ulong myisam_data_pointer_size=4;
-
+ulonglong myisam_mmap_size= SIZE_T_MAX, myisam_mmap_used= 0;
static int always_valid(const char *filename __attribute__((unused)))
{
diff --git a/storage/myisam/mi_write.c b/storage/myisam/mi_write.c
index f2528f2ec60..6ad23154b45 100644
--- a/storage/myisam/mi_write.c
+++ b/storage/myisam/mi_write.c
@@ -735,10 +735,12 @@ static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
}
end=page+length-key_ref_length;
+ DBUG_ASSERT(page < end);
*key='\0';
length=0;
lastpos=page;
- while (page < end)
+
+ do
{
prevpos=lastpos; lastpos=page;
last_length=length;
@@ -749,7 +751,8 @@ static uchar *_mi_find_last_pos(MI_KEYDEF *keyinfo, uchar *page,
my_errno=HA_ERR_CRASHED;
DBUG_RETURN(0);
}
- }
+ } while (page < end);
+
*return_key_length=last_length;
*after_key=lastpos;
DBUG_PRINT("exit",("returns: 0x%lx page: 0x%lx end: 0x%lx",
diff --git a/storage/myisam/myisamdef.h b/storage/myisam/myisamdef.h
index 48e5d92a9a9..7eb7089f38c 100644
--- a/storage/myisam/myisamdef.h
+++ b/storage/myisam/myisamdef.h
@@ -392,7 +392,6 @@ struct st_myisam_info
#define MI_MAX_BLOCK_LENGTH ((((ulong) 1 << 24)-1) & (~ (ulong) (MI_DYN_ALIGN_SIZE-1)))
#define MI_REC_BUFF_OFFSET ALIGN_SIZE(MI_DYN_DELETE_BLOCK_HEADER+sizeof(uint32))
-#define MEMMAP_EXTRA_MARGIN 7 /* Write this as a suffix for file */
#define PACK_TYPE_SELECTED 1 /* Bits in field->pack_type */
#define PACK_TYPE_SPACE_FIELDS 2
diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc
index 9be80dab4eb..0d4ab20a834 100644
--- a/storage/myisammrg/ha_myisammrg.cc
+++ b/storage/myisammrg/ha_myisammrg.cc
@@ -382,7 +382,7 @@ static MI_INFO *myisammrg_attach_children_callback(void *callback_param)
my_errno= HA_ERR_WRONG_MRG_TABLE_DEF;
}
DBUG_PRINT("myrg", ("MyISAM handle: 0x%lx my_errno: %d",
- (long) myisam, my_errno));
+ my_errno ? NULL : (long) myisam, my_errno));
err:
DBUG_RETURN(my_errno ? NULL : myisam);
diff --git a/storage/xtradb/btr/btr0cur.c b/storage/xtradb/btr/btr0cur.c
index f010ce93fe3..ce07b99c611 100644
--- a/storage/xtradb/btr/btr0cur.c
+++ b/storage/xtradb/btr/btr0cur.c
@@ -3233,7 +3233,7 @@ btr_estimate_number_of_different_key_vals(
ulint matched_bytes;
ib_int64_t n_recs = 0;
ib_int64_t* n_diff;
- ib_int64_t* n_not_nulls;
+ ib_int64_t* n_not_nulls= 0;
ullint n_sample_pages; /* number of pages to sample */
ulint not_empty_flag = 0;
ulint total_external_size = 0;