Commit 3b090265 authored by jimw@mysql.com's avatar jimw@mysql.com

Merge bk-internal:/home/bk/mysql-5.0

into mysql.com:/home/jimw/my/mysql-5.0-clean
parents 9307f61c 7b0e8726
......@@ -6,7 +6,7 @@ AC_PREREQ(2.50)dnl Minimum Autoconf version required.
AC_INIT(sql/mysqld.cc)
AC_CANONICAL_SYSTEM
# Don't forget to also update the NDB lines below.
AM_INIT_AUTOMAKE(mysql, 5.0.3-beta)
AM_INIT_AUTOMAKE(mysql, 5.0.4-beta)
AM_CONFIG_HEADER(config.h)
PROTOCOL_VERSION=10
......@@ -17,7 +17,7 @@ SHARED_LIB_VERSION=14:0:0
# ndb version
NDB_VERSION_MAJOR=5
NDB_VERSION_MINOR=0
NDB_VERSION_BUILD=3
NDB_VERSION_BUILD=4
NDB_VERSION_STATUS="beta"
# Set all version vars based on $VERSION. How do we do this more elegant ?
......
......@@ -96,7 +96,8 @@ clean-local:
`echo $(sql_cmn_objects) | sed "s;\.lo;.c;g"` \
$(CHARSET_SRCS) $(CHARSET_OBJS) \
$(mystringsextra) $(mysysheaders) $(vioheaders)\
../linked_client_sources net.c
../linked_libmysql_sources ../linked_libmysql_r_sources \
net.c
conf_to_src_SOURCES = conf_to_src.c
conf_to_src_LDADD=
......
......@@ -2862,6 +2862,17 @@ int STDCALL mysql_stmt_execute(MYSQL_STMT *stmt)
mysql->status= MYSQL_STATUS_READY;
stmt->read_row_func= stmt_read_row_from_cursor;
}
else if (stmt->flags & CURSOR_TYPE_READ_ONLY)
{
/*
This is a single-row result set, a result set with no rows, EXPLAIN,
SHOW VARIABLES, or some other command which either a) bypasses the
cursors framework in the server and writes rows directly to the
network or b) is more efficient if all (few) result set rows are
precached on client and server's resources are freed.
*/
DBUG_RETURN(mysql_stmt_store_result(stmt));
}
else
{
stmt->mysql->unbuffered_fetch_owner= &stmt->unbuffered_fetch_cancelled;
......
......@@ -8,6 +8,9 @@ create table t1 (a int not null, key(a)) engine=innodb;
create table t2 (a int not null, key(a)) engine=innodb;
create table t3 (a int) engine=innodb;
create table t4 (a int) engine=innodb;
show variables like 'slave_transaction_retries';
Variable_name Value
slave_transaction_retries 10
show create table t1;
Table Create Table
t1 CREATE TABLE `t1` (
......@@ -20,6 +23,9 @@ t2 CREATE TABLE `t2` (
`a` int(11) NOT NULL,
KEY `a` (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
show variables like 'slave_transaction_retries';
Variable_name Value
slave_transaction_retries 2
stop slave;
begin;
insert into t3 select * from t2 for update;
......
......@@ -65,6 +65,22 @@ SET @@session.time_zone='Europe/Moscow';
insert into t1 values ('20040101000000'), ('20040611093902');
ROLLBACK;
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
delete from t1;
set time_zone='UTC';
load data infile '../../std_data/rpl_timezone.dat' into table t1;
select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
set time_zone='UTC';
select * from t1;
t
2004-01-01 00:00:00
2004-06-11 09:39:02
set time_zone='Europe/Moscow';
set time_zone='Europe/Moscow';
delete from t1;
insert into t1 values ('20040101000000'), ('20040611093902');
set time_zone='MET';
insert into t2 (select t from t1);
select * from t1;
......
......@@ -142,6 +142,25 @@ Warning 1265 Data truncated for column 'b' at row 10
select @@warning_count;
@@warning_count
50
set max_error_count=0;
show variables like 'max_error_count';
Variable_name Value
max_error_count 0
update t1 set b='hi';
Warnings:
select @@warning_count;
@@warning_count
50
show warnings;
Level Code Message
set max_error_count=65535;
show variables like 'max_error_count';
Variable_name Value
max_error_count 65535
set max_error_count=10;
show variables like 'max_error_count';
Variable_name Value
max_error_count 10
drop table t1;
create table t1 (id int) engine=isam;
Warnings:
......
20040101000000
20040611093902
......@@ -7,6 +7,8 @@
# (Guilhem) have seen the test manage to provoke lock wait timeout
# error but not deadlock error; that is ok as code deals with the two
# errors in exactly the same way.
# We don't 'show status like 'slave_retried_transactions'' because this
# is not repeatable (depends on sleeps).
source include/have_innodb.inc;
source include/master-slave.inc;
......@@ -16,10 +18,12 @@ create table t1 (a int not null, key(a)) engine=innodb;
create table t2 (a int not null, key(a)) engine=innodb;
create table t3 (a int) engine=innodb;
create table t4 (a int) engine=innodb;
show variables like 'slave_transaction_retries';
sync_slave_with_master;
show create table t1;
show create table t2;
show variables like 'slave_transaction_retries';
stop slave;
# 1) Test deadlock
......
......@@ -49,6 +49,24 @@ connection master;
--replace_result $MYSQL_TEST_DIR MYSQL_TEST_DIR
--exec $MYSQL_BINLOG --short-form $MYSQL_TEST_DIR/var/log/master-bin.000001
# Let us check with LOAD DATA INFILE
# (we do it after mysqlbinlog because the temp files names are not constant)
connection master;
delete from t1;
set time_zone='UTC';
load data infile '../../std_data/rpl_timezone.dat' into table t1;
select * from t1;
sync_slave_with_master;
set time_zone='UTC';
select * from t1;
set time_zone='Europe/Moscow';
# Put back values of before the LOAD
connection master;
set time_zone='Europe/Moscow';
delete from t1;
insert into t1 values ('20040101000000'), ('20040611093902');
#
# Now let us check how well we replicate statments reading TIMESTAMP fields
# (We should see the same data on master and on slave but it should differ
......
......@@ -96,6 +96,19 @@ update t1 set b=a;
select @@warning_count;
--enable_ps_protocol
# Bug#9072
set max_error_count=0;
show variables like 'max_error_count';
update t1 set b='hi';
--disable_ps_protocol
select @@warning_count;
--enable_ps_protocol
show warnings;
set max_error_count=65535;
show variables like 'max_error_count';
set max_error_count=10;
show variables like 'max_error_count';
#
# Test for handler type
#
......
......@@ -3134,8 +3134,17 @@ we force server id to 2, but this MySQL server will not act as a slave.");
#endif
if (opt_bootstrap) /* If running with bootstrap, do not start replication. */
opt_skip_slave_start= 1;
/* init_slave() must be called after the thread keys are created */
init_slave();
/*
init_slave() must be called after the thread keys are created.
Some parts of the code (e.g. SHOW STATUS LIKE 'slave_running' and other
places) assume that active_mi != 0, so let's fail if it's 0 (out of
memory); a message has already been printed.
*/
if (init_slave() && !active_mi)
{
end_thr_alarm(1); // Don't allow alarms
unireg_abort(1);
}
if (opt_bootstrap)
{
......@@ -5225,7 +5234,7 @@ The minimum value for this variable is 4096.",
"Max number of errors/warnings to store for a statement.",
(gptr*) &global_system_variables.max_error_count,
(gptr*) &max_system_variables.max_error_count,
0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 1, 65535, 0, 1, 0},
0, GET_ULONG, REQUIRED_ARG, DEFAULT_ERROR_COUNT, 0, 65535, 0, 1, 0},
{"max_heap_table_size", OPT_MAX_HEP_TABLE_SIZE,
"Don't allow creation of heap tables bigger than this.",
(gptr*) &global_system_variables.max_heap_table_size,
......@@ -5689,7 +5698,8 @@ struct show_var_st status_vars[]= {
{"Select_range_check", (char*) offsetof(STATUS_VAR, select_range_check_count), SHOW_LONG_STATUS},
{"Select_scan", (char*) offsetof(STATUS_VAR, select_scan_count), SHOW_LONG_STATUS},
{"Slave_open_temp_tables", (char*) &slave_open_temp_tables, SHOW_LONG},
{"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
{"Slave_running", (char*) 0, SHOW_SLAVE_RUNNING},
{"Slave_retried_transactions",(char*) 0, SHOW_SLAVE_RETRIED_TRANS},
{"Slow_launch_threads", (char*) &slow_launch_threads, SHOW_LONG},
{"Slow_queries", (char*) offsetof(STATUS_VAR, long_query_count), SHOW_LONG_STATUS},
{"Sort_merge_passes", (char*) offsetof(STATUS_VAR, filesort_merge_passes), SHOW_LONG_STATUS},
......
......@@ -27,6 +27,7 @@
#include <my_dir.h>
#include <sql_common.h>
#define MAX_SLAVE_RETRY_PAUSE 5
bool use_slave_mask = 0;
MY_BITMAP slave_error_mask;
......@@ -2528,7 +2529,7 @@ st_relay_log_info::st_relay_log_info()
ignore_log_space_limit(0), last_master_timestamp(0), slave_skip_counter(0),
abort_pos_wait(0), slave_run_id(0), sql_thd(0), last_slave_errno(0),
inited(0), abort_slave(0), slave_running(0), until_condition(UNTIL_NONE),
until_log_pos(0)
until_log_pos(0), retried_trans(0)
{
group_relay_log_name[0]= event_relay_log_name[0]=
group_master_log_name[0]= 0;
......@@ -3261,9 +3262,8 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
init_master_info()).
b) init_relay_log_pos(), because the BEGIN may be an older relay log.
*/
if (rli->trans_retries--)
if (rli->trans_retries < slave_trans_retries)
{
sql_print_information("Slave SQL thread retries transaction");
if (init_master_info(rli->mi, 0, 0, 0, SLAVE_SQL))
sql_print_error("Failed to initialize the master info structure");
else if (init_relay_log_pos(rli,
......@@ -3275,8 +3275,16 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
else
{
exec_res= 0;
sleep(2); // chance for concurrent connection to get more locks
}
/* chance for concurrent connection to get more locks */
safe_sleep(thd, min(rli->trans_retries, MAX_SLAVE_RETRY_PAUSE),
(CHECK_KILLED_FUNC)sql_slave_killed, (void*)rli);
pthread_mutex_lock(&rli->data_lock); // because of SHOW STATUS
rli->trans_retries++;
rli->retried_trans++;
pthread_mutex_unlock(&rli->data_lock);
DBUG_PRINT("info", ("Slave retries transaction "
"rli->trans_retries: %lu", rli->trans_retries));
}
}
else
sql_print_error("Slave SQL thread retried transaction %lu time(s) "
......@@ -3285,8 +3293,8 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
slave_trans_retries);
}
if (!((thd->options & OPTION_BEGIN) && opt_using_transactions))
rli->trans_retries= slave_trans_retries; // restart from fresh
}
rli->trans_retries= 0; // restart from fresh
}
return exec_res;
}
else
......@@ -3701,7 +3709,7 @@ extern "C" pthread_handler_decl(handle_slave_sql,arg)
pthread_mutex_lock(&rli->log_space_lock);
rli->ignore_log_space_limit= 0;
pthread_mutex_unlock(&rli->log_space_lock);
rli->trans_retries= slave_trans_retries; // start from "no error"
rli->trans_retries= 0; // start from "no error"
if (init_relay_log_pos(rli,
rli->group_relay_log_name,
......
......@@ -293,7 +293,14 @@ typedef struct st_relay_log_info
} until_log_names_cmp_result;
char cached_charset[6];
ulong trans_retries;
/*
trans_retries varies between 0 to slave_transaction_retries and counts how
many times the slave has retried the present transaction; gets reset to 0
when the transaction finally succeeds. retried_trans is a cumulative
counter: how many times the slave has retried a transaction (any) since
slave started.
*/
ulong trans_retries, retried_trans;
st_relay_log_info();
~st_relay_log_info();
......
......@@ -1970,6 +1970,7 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
{
ulong stmt_id= uint4korr(packet);
ulong flags= (ulong) ((uchar) packet[4]);
Cursor *cursor= 0;
/*
Query text for binary log, or empty string if the query is not put into
binary log.
......@@ -2007,15 +2008,17 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
statement: we can't open a cursor for it.
*/
flags= 0;
my_error(ER_SP_BAD_CURSOR_QUERY, MYF(0));
goto err;
}
else
{
DBUG_PRINT("info",("Using READ_ONLY cursor"));
if (!stmt->cursor &&
!(stmt->cursor= new (&stmt->main_mem_root) Cursor()))
!(cursor= stmt->cursor= new (&stmt->main_mem_root) Cursor()))
DBUG_VOID_RETURN;
/* If lex->result is set, mysql_execute_command will use it */
stmt->lex->result= &stmt->cursor->result;
stmt->lex->result= &cursor->result;
}
}
#ifndef EMBEDDED_LIBRARY
......@@ -2061,11 +2064,10 @@ void mysql_stmt_execute(THD *thd, char *packet, uint packet_length)
my_pthread_setprio(pthread_self(), WAIT_PRIOR);
thd->protocol= &thd->protocol_simple; // Use normal protocol
if (flags & (ulong) CURSOR_TYPE_READ_ONLY)
if (cursor && cursor->is_open())
{
if (stmt->cursor->is_open())
stmt->cursor->init_from_thd(thd);
stmt->cursor->state= stmt->state;
cursor->init_from_thd(thd);
cursor->state= stmt->state;
}
else
{
......
......@@ -370,7 +370,7 @@ class Cursor: public Sql_alloc, public Item_arena
void close();
void set_unit(SELECT_LEX_UNIT *unit_arg) { unit= unit_arg; }
Cursor() :join(0), unit(0) {}
Cursor() :Item_arena(TRUE), join(0), unit(0) {}
~Cursor();
};
......
......@@ -1331,6 +1331,19 @@ static bool show_status_array(THD *thd, const char *wild,
pthread_mutex_unlock(&LOCK_active_mi);
break;
}
case SHOW_SLAVE_RETRIED_TRANS:
{
/*
TODO: in 5.1 with multimaster, have one such counter per line in SHOW
SLAVE STATUS, and have the sum over all lines here.
*/
pthread_mutex_lock(&LOCK_active_mi);
pthread_mutex_lock(&active_mi->rli.data_lock);
end= int10_to_str(active_mi->rli.retried_trans, buff, 10);
pthread_mutex_unlock(&active_mi->rli.data_lock);
pthread_mutex_unlock(&LOCK_active_mi);
break;
}
#endif /* HAVE_REPLICATION */
case SHOW_OPENTABLES:
end= int10_to_str((long) cached_tables(), buff, 10);
......
......@@ -182,7 +182,7 @@ enum SHOW_TYPE
SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL,
SHOW_SSL_GET_CIPHER_LIST,
#endif /* HAVE_OPENSSL */
SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING,
SHOW_RPL_STATUS, SHOW_SLAVE_RUNNING, SHOW_SLAVE_RETRIED_TRANS,
SHOW_KEY_CACHE_LONG, SHOW_KEY_CACHE_CONST_LONG,
SHOW_LONG_STATUS, SHOW_LONG_CONST_STATUS
};
......
......@@ -12782,6 +12782,72 @@ static void test_bug8722()
}
MYSQL_STMT *open_cursor(char *query)
{
int rc;
const ulong type= (ulong)CURSOR_TYPE_READ_ONLY;
MYSQL_STMT *stmt= mysql_stmt_init(mysql);
rc= mysql_stmt_prepare(stmt, query, strlen(query));
check_execute(stmt, rc);
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (void*) &type);
return stmt;
}
static void test_bug8880()
{
MYSQL_STMT *stmt_list[2], **stmt;
MYSQL_STMT **stmt_list_end= (MYSQL_STMT**) stmt_list + 2;
int rc;
myheader("test_bug8880");
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
rc= mysql_query(mysql, "insert into t1 values (1,1)");
myquery(rc); /* one check is enough */
/*
when inserting 2 rows everything works well
mysql_query(mysql, "INSERT INTO t1 VALUES (1,1),(2,2)");
*/
for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
*stmt= open_cursor("select a from t1");
for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
{
rc= mysql_stmt_execute(*stmt);
check_execute(*stmt, rc);
}
for (stmt= stmt_list; stmt < stmt_list_end; stmt++)
mysql_stmt_close(*stmt);
}
static void test_bug9159()
{
MYSQL_STMT *stmt;
int rc;
const char *stmt_text= "select a, b from t1";
const unsigned long type= CURSOR_TYPE_READ_ONLY;
myheader("test_bug9159");
mysql_query(mysql, "drop table if exists t1");
mysql_query(mysql, "create table t1 (a int not null primary key, b int)");
rc= mysql_query(mysql, "insert into t1 values (1,1)");
myquery(rc);
stmt= mysql_stmt_init(mysql);
mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text));
mysql_stmt_attr_set(stmt, STMT_ATTR_CURSOR_TYPE, (const void *)&type);
mysql_stmt_execute(stmt);
mysql_stmt_close(stmt);
rc= mysql_query(mysql, "drop table if exists t1");
myquery(rc);
}
/*
Read and parse arguments and MySQL options from my.cnf
*/
......@@ -13005,6 +13071,8 @@ static struct my_tests_st my_tests[]= {
{ "test_bug7990", test_bug7990 },
{ "test_bug8378", test_bug8378 },
{ "test_bug8722", test_bug8722 },
{ "test_bug8880", test_bug8880 },
{ "test_bug9159", test_bug9159 },
{ 0, 0 }
};
......
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