1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

5.5-merge

This commit is contained in:
Sergei Golubchik
2011-07-02 22:08:51 +02:00
3220 changed files with 94894 additions and 422456 deletions

View File

@@ -1,4 +1,5 @@
/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
Copyright (c) 2011 Monty Program Ab
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -29,8 +30,6 @@
#include "sql_cache.h" // query_cache, query_cache_*
#include "key.h" // key_copy, key_unpack, key_cmp_if_same, key_cmp
#include "sql_table.h" // build_table_filename
#include "lock.h" // wait_if_global_read_lock,
// start_waiting_global_read_lock
#include "sql_parse.h" // check_stack_overrun
#include "sql_acl.h" // SUPER_ACL
#include "sql_base.h" // free_io_cache
@@ -42,7 +41,7 @@
#include "transaction.h"
#include "myisam.h"
#include "probes_mysql.h"
#include "sql_connect.h"
#include "debug_sync.h" // DEBUG_SYNC
#ifdef WITH_PARTITION_STORAGE_ENGINE
#include "ha_partition.h"
@@ -279,7 +278,7 @@ handler *get_ha_partition(partition_info *part_info)
}
else
{
my_error(ER_OUTOFMEMORY, MYF(0), sizeof(ha_partition));
my_error(ER_OUTOFMEMORY, MYF(0), static_cast<int>(sizeof(ha_partition)));
}
DBUG_RETURN(((handler*) partition));
}
@@ -358,6 +357,7 @@ int ha_init_errors(void)
SETMSG(HA_ERR_AUTOINC_READ_FAILED, ER_DEFAULT(ER_AUTOINC_READ_FAILED));
SETMSG(HA_ERR_AUTOINC_ERANGE, ER_DEFAULT(ER_WARN_DATA_OUT_OF_RANGE));
SETMSG(HA_ERR_TOO_MANY_CONCURRENT_TRXS, ER_DEFAULT(ER_TOO_MANY_CONCURRENT_TRXS));
SETMSG(HA_ERR_INDEX_COL_TOO_LONG, ER_DEFAULT(ER_INDEX_COLUMN_TOO_LONG));
/* Register the error messages for use with my_error(). */
return my_error_register(get_handler_errmsgs, HA_ERR_FIRST, HA_ERR_LAST);
@@ -1168,8 +1168,9 @@ int ha_commit_trans(THD *thd, bool all)
{
uint rw_ha_count;
bool rw_trans;
MDL_request mdl_request;
DBUG_EXECUTE_IF("crash_commit_before", DBUG_ABORT(););
DBUG_EXECUTE_IF("crash_commit_before", DBUG_SUICIDE(););
/* Close all cursors that can not survive COMMIT */
if (is_real_trans) /* not a statement commit */
@@ -1179,11 +1180,27 @@ int ha_commit_trans(THD *thd, bool all)
/* rw_trans is TRUE when we in a transaction changing data */
rw_trans= is_real_trans && (rw_ha_count > 0);
if (rw_trans &&
thd->global_read_lock.wait_if_global_read_lock(thd, FALSE, FALSE))
if (rw_trans)
{
ha_rollback_trans(thd, all);
DBUG_RETURN(1);
/*
Acquire a metadata lock which will ensure that COMMIT is blocked
by an active FLUSH TABLES WITH READ LOCK (and vice versa:
COMMIT in progress blocks FTWRL).
We allow the owner of FTWRL to COMMIT; we assume that it knows
what it does.
*/
mdl_request.init(MDL_key::COMMIT, "", "", MDL_INTENTION_EXCLUSIVE,
MDL_EXPLICIT);
if (thd->mdl_context.acquire_lock(&mdl_request,
thd->variables.lock_wait_timeout))
{
ha_rollback_trans(thd, all);
DBUG_RETURN(1);
}
DEBUG_SYNC(thd, "ha_commit_trans_after_acquire_commit_lock");
}
if (rw_trans &&
@@ -1221,7 +1238,7 @@ int ha_commit_trans(THD *thd, bool all)
}
status_var_increment(thd->status_var.ha_prepare_count);
}
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_ABORT(););
DBUG_EXECUTE_IF("crash_commit_after_prepare", DBUG_SUICIDE(););
if (error || (is_real_trans && xid &&
(error= !(cookie= tc_log->log_xid(thd, xid)))))
{
@@ -1229,17 +1246,29 @@ int ha_commit_trans(THD *thd, bool all)
error= 1;
goto end;
}
DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_ABORT(););
DBUG_EXECUTE_IF("crash_commit_after_log", DBUG_SUICIDE(););
}
error=ha_commit_one_phase(thd, all) ? (cookie ? 2 : 1) : 0;
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_ABORT(););
DBUG_EXECUTE_IF("crash_commit_before_unlog", DBUG_SUICIDE(););
if (cookie)
tc_log->unlog(cookie, xid);
DBUG_EXECUTE_IF("crash_commit_after", DBUG_ABORT(););
if(tc_log->unlog(cookie, xid))
{
error= 2;
goto end;
}
DBUG_EXECUTE_IF("crash_commit_after", DBUG_SUICIDE(););
RUN_HOOK(transaction, after_commit, (thd, FALSE));
end:
if (rw_trans)
thd->global_read_lock.start_waiting_global_read_lock(thd);
if (rw_trans && mdl_request.ticket)
{
/*
We do not always immediately release transactional locks
after ha_commit_trans() (see uses of ha_enable_transaction()),
thus we release the commit blocker lock as soon as it's
not needed.
*/
thd->mdl_context.release_lock(mdl_request.ticket);
}
}
/* Free resources and perform other cleanup even for 'empty' transactions. */
else if (is_real_trans)
@@ -1614,7 +1643,8 @@ int ha_recover(HASH *commit_list)
}
if (!info.list)
{
sql_print_error(ER(ER_OUTOFMEMORY), info.len*sizeof(XID));
sql_print_error(ER(ER_OUTOFMEMORY),
static_cast<int>(info.len*sizeof(XID)));
DBUG_RETURN(1);
}
@@ -2052,26 +2082,28 @@ int ha_delete_table(THD *thd, handlerton *table_type, const char *path,
/****************************************************************************
** General handler functions
****************************************************************************/
handler *handler::clone(MEM_ROOT *mem_root)
handler *handler::clone(const char *name, MEM_ROOT *mem_root)
{
handler *new_handler= get_new_handler(table->s, mem_root, table->s->db_type());
if (!new_handler)
return NULL;
handler *new_handler= get_new_handler(table->s, mem_root, ht);
/*
Allocate handler->ref here because otherwise ha_open will allocate it
on this->table->mem_root and we will not be able to reclaim that memory
when the clone handler object is destroyed.
*/
if (!(new_handler->ref= (uchar*) alloc_root(mem_root, ALIGN_SIZE(ref_length)*2)))
return NULL;
if (new_handler->ha_open(table,
table->s->normalized_path.str,
table->db_stat,
HA_OPEN_IGNORE_IF_LOCKED))
return NULL;
new_handler->cloned= 1; // Marker for debugging
if (new_handler &&
!(new_handler->ref= (uchar*) alloc_root(mem_root,
ALIGN_SIZE(ref_length)*2)))
new_handler= NULL;
/*
TODO: Implement a more efficient way to have more than one index open for
the same table instance. The ha_open call is not cachable for clone.
*/
if (new_handler && new_handler->ha_open(table,
name,
table->db_stat,
HA_OPEN_IGNORE_IF_LOCKED))
new_handler= NULL;
return new_handler;
}
@@ -2217,7 +2249,8 @@ int handler::read_first_row(uchar * buf, uint primary_key)
computes the lowest number
- strictly greater than "nr"
- of the form: auto_increment_offset + N * auto_increment_increment
If overflow happened then return MAX_ULONGLONG value as an
indication of overflow.
In most cases increment= offset= 1, in which case we get:
@verbatim 1,2,3,4,5,... @endverbatim
If increment=10 and offset=5 and previous number is 1, we get:
@@ -2226,13 +2259,23 @@ int handler::read_first_row(uchar * buf, uint primary_key)
inline ulonglong
compute_next_insert_id(ulonglong nr,struct system_variables *variables)
{
const ulonglong save_nr= nr;
if (variables->auto_increment_increment == 1)
return (nr+1); // optimization of the formula below
nr= (((nr+ variables->auto_increment_increment -
variables->auto_increment_offset)) /
(ulonglong) variables->auto_increment_increment);
return (nr* (ulonglong) variables->auto_increment_increment +
variables->auto_increment_offset);
nr= nr + 1; // optimization of the formula below
else
{
nr= (((nr+ variables->auto_increment_increment -
variables->auto_increment_offset)) /
(ulonglong) variables->auto_increment_increment);
nr= (nr* (ulonglong) variables->auto_increment_increment +
variables->auto_increment_offset);
}
if (unlikely(nr <= save_nr))
return ULONGLONG_MAX;
return nr;
}
@@ -2443,7 +2486,7 @@ int handler::update_auto_increment()
variables->auto_increment_increment,
nb_desired_values, &nr,
&nb_reserved_values);
if (nr == ~(ulonglong) 0)
if (nr == ULONGLONG_MAX)
DBUG_RETURN(HA_ERR_AUTOINC_READ_FAILED); // Mark failure
/*
@@ -2474,6 +2517,9 @@ int handler::update_auto_increment()
}
}
if (unlikely(nr == ULONGLONG_MAX))
DBUG_RETURN(HA_ERR_AUTOINC_ERANGE);
DBUG_PRINT("info",("auto_increment: %lu", (ulong) nr));
if (unlikely(table->next_number_field->store((longlong) nr, TRUE)))
@@ -2701,6 +2747,7 @@ void handler::print_error(int error, myf errflag)
break;
case HA_ERR_KEY_NOT_FOUND:
case HA_ERR_NO_ACTIVE_RECORD:
case HA_ERR_RECORD_DELETED:
case HA_ERR_END_OF_FILE:
/*
This errors is not not normally fatal (for example for reads). However
@@ -2868,6 +2915,9 @@ void handler::print_error(int error, myf errflag)
case HA_ERR_TOO_MANY_CONCURRENT_TRXS:
textno= ER_TOO_MANY_CONCURRENT_TRXS;
break;
case HA_ERR_INDEX_COL_TOO_LONG:
textno= ER_INDEX_COLUMN_TOO_LONG;
break;
default:
{
/* The error was "unknown" to this function.
@@ -3235,9 +3285,13 @@ int handler::ha_repair(THD* thd, HA_CHECK_OPT* check_opt)
mark_trx_read_write();
if ((result= repair(thd, check_opt)))
return result;
return update_frm_version(table);
result= repair(thd, check_opt);
DBUG_ASSERT(result == HA_ADMIN_NOT_IMPLEMENTED ||
ha_table_flags() & HA_CAN_REPAIR);
if (result == HA_ADMIN_OK)
result= update_frm_version(table);
return result;
}
@@ -3272,6 +3326,21 @@ handler::ha_delete_all_rows()
}
/**
Truncate table: public interface.
@sa handler::truncate()
*/
int
handler::ha_truncate()
{
mark_trx_read_write();
return truncate();
}
/**
Reset auto increment: public interface.
@@ -4807,6 +4876,7 @@ int handler::ha_reset()
free_io_cache(table);
/* reset the bitmaps to point to defaults */
table->default_column_bitmaps();
pushed_cond= NULL;
DBUG_RETURN(reset());
}