mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge tulin@bk-internal.mysql.com:/home/bk/mysql-5.0
into poseidon.ndb.mysql.com:/home/tomas/mysql-5.0
This commit is contained in:
0
BUILD/compile-pentium64-valgrind-max
Normal file → Executable file
0
BUILD/compile-pentium64-valgrind-max
Normal file → Executable file
@@ -73,5 +73,6 @@ hours:
|
||||
[nick:]checkout:get
|
||||
[jonas:]checkout:get
|
||||
[tomas:]checkout:get
|
||||
[guilhem:]checkout:get
|
||||
checkout:edit
|
||||
eoln:unix
|
||||
|
@@ -51,5 +51,5 @@ enum options_client
|
||||
#endif
|
||||
OPT_TRIGGERS,
|
||||
OPT_IGNORE_TABLE,OPT_INSERT_IGNORE,OPT_SHOW_WARNINGS,OPT_DROP_DATABASE,
|
||||
OPT_AUTO_CLOSE
|
||||
OPT_TZ_UTC, OPT_AUTO_CLOSE
|
||||
};
|
||||
|
@@ -1003,7 +1003,8 @@ static int dump_remote_log_entries(const char* logname)
|
||||
{
|
||||
char buf[128];
|
||||
LAST_EVENT_INFO last_event_info;
|
||||
uint len, logname_len;
|
||||
ulong len;
|
||||
uint logname_len;
|
||||
NET* net;
|
||||
int error= 0;
|
||||
my_off_t old_off= start_position_mot;
|
||||
|
@@ -92,7 +92,7 @@ static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1,
|
||||
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
|
||||
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
|
||||
opt_complete_insert= 0, opt_drop_database= 0,
|
||||
opt_dump_triggers= 0, opt_routines=0;
|
||||
opt_dump_triggers= 0, opt_routines=0, opt_tz_utc=1;
|
||||
static ulong opt_max_allowed_packet, opt_net_buffer_length;
|
||||
static MYSQL mysql_connection,*sock=0;
|
||||
static my_bool insert_pat_inited=0;
|
||||
@@ -385,6 +385,9 @@ static struct my_option my_long_options[] =
|
||||
{"triggers", OPT_TRIGGERS, "Dump triggers for each dumped table",
|
||||
(gptr*) &opt_dump_triggers, (gptr*) &opt_dump_triggers, 0, GET_BOOL,
|
||||
NO_ARG, 1, 0, 0, 0, 0, 0},
|
||||
{"tz-utc", OPT_TZ_UTC,
|
||||
"SET TIME_ZONE='UTC' at top of dump to allow dumping of date types between servers with different time zones.",
|
||||
(gptr*) &opt_tz_utc, (gptr*) &opt_tz_utc, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
|
||||
#ifndef DONT_ALLOW_USER_CHANGE
|
||||
{"user", 'u', "User for login if not current user.",
|
||||
(gptr*) ¤t_user, (gptr*) ¤t_user, 0, GET_STR, REQUIRED_ARG,
|
||||
@@ -509,6 +512,13 @@ static void write_header(FILE *sql_file, char *db_name)
|
||||
"\n/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;"
|
||||
"\n/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;"
|
||||
"\n/*!40101 SET NAMES %s */;\n",default_charset);
|
||||
|
||||
if (opt_tz_utc)
|
||||
{
|
||||
fprintf(sql_file, "/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;\n");
|
||||
fprintf(sql_file, "/*!40103 SET TIME_ZONE='+00:00' */;\n");
|
||||
}
|
||||
|
||||
if (!path)
|
||||
{
|
||||
fprintf(md_result_file,"\
|
||||
@@ -535,6 +545,9 @@ static void write_footer(FILE *sql_file)
|
||||
}
|
||||
else if (!opt_compact)
|
||||
{
|
||||
if (opt_tz_utc)
|
||||
fprintf(sql_file,"/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;\n");
|
||||
|
||||
fprintf(sql_file,"\n/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;\n");
|
||||
if (!path)
|
||||
{
|
||||
@@ -902,6 +915,20 @@ static int dbConnect(char *host, char *user,char *passwd)
|
||||
safe_exit(EX_MYSQLERR);
|
||||
return 1;
|
||||
}
|
||||
/*
|
||||
set time_zone to UTC to allow dumping date types between servers with
|
||||
different time zone settings
|
||||
*/
|
||||
if (opt_tz_utc)
|
||||
{
|
||||
my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */");
|
||||
if (mysql_query_with_error_report(sock, 0, buff))
|
||||
{
|
||||
mysql_close(sock);
|
||||
safe_exit(EX_MYSQLERR);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} /* dbConnect */
|
||||
|
||||
|
@@ -158,7 +158,8 @@ extern gptr my_memdup(const byte *from,uint length,myf MyFlags);
|
||||
extern char *my_strdup(const char *from,myf MyFlags);
|
||||
extern char *my_strdup_with_length(const byte *from, uint length,
|
||||
myf MyFlags);
|
||||
#define my_free(PTR,FG) my_no_flags_free(PTR)
|
||||
/* we do use FG (as a no-op) in below so that a typo on FG is caught */
|
||||
#define my_free(PTR,FG) ((void)FG,my_no_flags_free(PTR))
|
||||
#define CALLER_INFO_PROTO /* nothing */
|
||||
#define CALLER_INFO /* nothing */
|
||||
#define ORIG_CALLER_INFO /* nothing */
|
||||
|
@@ -61,6 +61,7 @@ dist-hook:
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/des_key_file $(distdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(distdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(distdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(distdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(distdir)/lib
|
||||
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(distdir)/lib
|
||||
|
||||
@@ -89,6 +90,7 @@ install-data-local:
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/Moscow_leap $(DESTDIR)$(testdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/*.pem $(DESTDIR)$(testdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/*.frm $(DESTDIR)$(testdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/std_data/*.cnf $(DESTDIR)$(testdir)/std_data
|
||||
$(INSTALL_DATA) $(srcdir)/lib/init_db.sql $(DESTDIR)$(testdir)/lib
|
||||
$(INSTALL_DATA) $(srcdir)/lib/*.pl $(DESTDIR)$(testdir)/lib
|
||||
|
||||
|
@@ -79,7 +79,7 @@ Table Create Table
|
||||
t2 CREATE TABLE `t2` (
|
||||
`id` int(20) NOT NULL,
|
||||
`name` varchar(32) NOT NULL default ''
|
||||
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:9308/federated/t1'
|
||||
) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'
|
||||
INSERT INTO federated.t2 (id, name) VALUES (1, 'foo');
|
||||
INSERT INTO federated.t2 (id, name) VALUES (2, 'fee');
|
||||
SELECT * FROM federated.t2;
|
||||
|
File diff suppressed because one or more lines are too long
22
mysql-test/r/rpl_dual_pos_advance.result
Normal file
22
mysql-test/r/rpl_dual_pos_advance.result
Normal file
@@ -0,0 +1,22 @@
|
||||
stop slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
reset master;
|
||||
reset slave;
|
||||
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9;
|
||||
start slave;
|
||||
reset master;
|
||||
change master to master_host="127.0.0.1",master_port=SLAVE_PORT,master_user="root";
|
||||
start slave;
|
||||
create table t1 (n int);
|
||||
create table t4 (n int);
|
||||
create table t5 (n int);
|
||||
create table t6 (n int);
|
||||
show tables;
|
||||
Tables_in_test
|
||||
t1
|
||||
t4
|
||||
t5
|
||||
t6
|
||||
stop slave;
|
||||
reset slave;
|
||||
drop table t1,t4,t5,t6;
|
@@ -264,6 +264,14 @@ master-bin.000002 # Query 1 # use `mysqltest1`; insert into t1 values (1)
|
||||
select * from t1;
|
||||
a
|
||||
1
|
||||
create procedure foo()
|
||||
not deterministic
|
||||
reads sql data
|
||||
select * from t1;
|
||||
call foo();
|
||||
a
|
||||
1
|
||||
drop procedure foo;
|
||||
drop function fn1;
|
||||
drop database mysqltest1;
|
||||
drop user "zedjzlcsjhd"@127.0.0.1;
|
||||
|
@@ -834,3 +834,41 @@ ERROR HY000: Not allowed to set autocommit from a stored function or trigger
|
||||
create trigger bug12712
|
||||
before insert on t1 for each row set session autocommit = 0;
|
||||
ERROR HY000: Not allowed to set autocommit from a stored function or trigger
|
||||
drop procedure if exists bug13510_1|
|
||||
drop procedure if exists bug13510_2|
|
||||
drop procedure if exists bug13510_3|
|
||||
drop procedure if exists bug13510_4|
|
||||
create procedure bug13510_1()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
set password = 'foo1';
|
||||
select password;
|
||||
end|
|
||||
ERROR 42000: Variable 'password' must be quoted with `...`, or renamed
|
||||
create procedure bug13510_2()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
set names = 'foo2';
|
||||
select names;
|
||||
end|
|
||||
ERROR 42000: Variable 'names' must be quoted with `...`, or renamed
|
||||
create procedure bug13510_3()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
set `password` = 'foo3';
|
||||
select password;
|
||||
end|
|
||||
create procedure bug13510_4()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
set `names` = 'foo4';
|
||||
select names;
|
||||
end|
|
||||
call bug13510_3()|
|
||||
password
|
||||
foo3
|
||||
call bug13510_4()|
|
||||
names
|
||||
foo4
|
||||
drop procedure bug13510_3|
|
||||
drop procedure bug13510_4|
|
||||
|
@@ -2987,3 +2987,4 @@ select * from (select max(fld) from t1) as foo;
|
||||
max(fld)
|
||||
1
|
||||
drop table t1;
|
||||
purge master logs before (select adddate(current_timestamp(), interval -4 day));
|
||||
|
@@ -75,7 +75,8 @@ eval CREATE TABLE federated.t2 (
|
||||
ENGINE="FEDERATED" DEFAULT CHARSET=latin1
|
||||
CONNECTION='mysql://root@127.0.0.1:$SLAVE_MYPORT/federated/t1';
|
||||
|
||||
SHOW CREATE TABLE federated.t2;
|
||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||
eval SHOW CREATE TABLE federated.t2;
|
||||
|
||||
INSERT INTO federated.t2 (id, name) VALUES (1, 'foo');
|
||||
INSERT INTO federated.t2 (id, name) VALUES (2, 'fee');
|
||||
|
@@ -907,3 +907,24 @@ DROP PROCEDURE bug9056_proc1;
|
||||
DROP PROCEDURE bug9056_proc2;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG# 13052 - mysqldump timestamp reloads broken
|
||||
#
|
||||
--disable_warnings
|
||||
drop table if exists t1;
|
||||
--enable_warnings
|
||||
|
||||
create table t1 (`d` timestamp, unique (`d`));
|
||||
set time_zone='+00:00';
|
||||
insert into t1 values ('2003-10-25 22:00:00'),('2003-10-25 23:00:00');
|
||||
# results should show two different time values
|
||||
select * from t1;
|
||||
set time_zone='Europe/Moscow';
|
||||
# results should show two same time values, despite unique
|
||||
select * from t1;
|
||||
set global time_zone='Europe/Moscow';
|
||||
--exec $MYSQL_DUMP --skip-comments --databases test
|
||||
--exec $MYSQL_DUMP --skip-tz-utc --skip-comments --databases test
|
||||
drop table t1;
|
||||
set global time_zone=default;
|
||||
set time_zone=default;
|
||||
|
1
mysql-test/t/rpl_dual_pos_advance-master.opt
Normal file
1
mysql-test/t/rpl_dual_pos_advance-master.opt
Normal file
@@ -0,0 +1 @@
|
||||
--loose-to-force-a-restart
|
108
mysql-test/t/rpl_dual_pos_advance.test
Normal file
108
mysql-test/t/rpl_dual_pos_advance.test
Normal file
@@ -0,0 +1,108 @@
|
||||
# This test checks that in a dual-head setup
|
||||
# A->B->A, where A has --log-slave-updates (why would it?
|
||||
# assume that there is a C as slave of A),
|
||||
# then the Exec_master_log_pos of SHOW SLAVE STATUS does
|
||||
# not stay too low on B(BUG#13023 due to events ignored because
|
||||
# of their server id).
|
||||
# It also will test BUG#13861.
|
||||
|
||||
source include/master-slave.inc;
|
||||
|
||||
|
||||
# set up "dual head"
|
||||
|
||||
connection slave;
|
||||
reset master;
|
||||
|
||||
connection master;
|
||||
--replace_result $SLAVE_MYPORT SLAVE_PORT
|
||||
eval change master to master_host="127.0.0.1",master_port=$SLAVE_MYPORT,master_user="root";
|
||||
|
||||
start slave;
|
||||
|
||||
# now we test it
|
||||
|
||||
connection slave;
|
||||
|
||||
create table t1 (n int);
|
||||
|
||||
save_master_pos;
|
||||
connection master;
|
||||
sync_with_master;
|
||||
|
||||
# Now test BUG#13861. This will be enabled when Guilhem fixes this
|
||||
# bug.
|
||||
|
||||
# stop slave
|
||||
|
||||
# create table t2 (n int); # create one ignored event
|
||||
|
||||
# save_master_pos;
|
||||
# connection slave;
|
||||
# sync_with_master;
|
||||
|
||||
# connection slave;
|
||||
|
||||
# show tables;
|
||||
|
||||
# save_master_pos;
|
||||
|
||||
# create table t3 (n int);
|
||||
|
||||
# connection master;
|
||||
|
||||
# bug is that START SLAVE UNTIL may stop too late, we test that by
|
||||
# asking it to stop before creation of t3.
|
||||
|
||||
# start slave until master_log_file="slave-bin.000001",master_log_pos=195;
|
||||
|
||||
# wait until it's started (the position below is the start of "CREATE
|
||||
# TABLE t2") (otherwise wait_for_slave_to_stop may return at once)
|
||||
|
||||
# select master_pos_wait("slave-bin.000001",137);
|
||||
|
||||
# wait_for_slave_to_stop;
|
||||
|
||||
# then BUG#13861 causes t3 to show up below (because stopped too
|
||||
# late).
|
||||
|
||||
# show tables;
|
||||
|
||||
# start slave;
|
||||
|
||||
# BUG#13023 is that Exec_master_log_pos may stay too low "forever":
|
||||
|
||||
connection master;
|
||||
|
||||
create table t4 (n int); # create 3 ignored events
|
||||
create table t5 (n int);
|
||||
create table t6 (n int);
|
||||
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
connection slave;
|
||||
|
||||
save_master_pos;
|
||||
|
||||
connection master;
|
||||
|
||||
# then BUG#13023 caused hang below ("master" looks behind, while it's
|
||||
# not in terms of updates done).
|
||||
|
||||
sync_with_master;
|
||||
|
||||
show tables;
|
||||
|
||||
# cleanup
|
||||
|
||||
stop slave;
|
||||
reset slave;
|
||||
drop table t1,t4,t5,t6; # add t2 and t3 later
|
||||
|
||||
save_master_pos;
|
||||
connection slave;
|
||||
sync_with_master;
|
||||
|
||||
# End of 4.1 tests
|
@@ -258,6 +258,23 @@ sync_slave_with_master;
|
||||
select * from t1;
|
||||
|
||||
|
||||
#
|
||||
# Test for bug #13969 "Routines which are replicated from master can't be
|
||||
# executed on slave".
|
||||
#
|
||||
connection master;
|
||||
create procedure foo()
|
||||
not deterministic
|
||||
reads sql data
|
||||
select * from t1;
|
||||
sync_slave_with_master;
|
||||
# This should not fail
|
||||
call foo();
|
||||
connection master;
|
||||
drop procedure foo;
|
||||
sync_slave_with_master;
|
||||
|
||||
|
||||
# Clean up
|
||||
connection master;
|
||||
drop function fn1;
|
||||
|
@@ -1212,6 +1212,59 @@ call bug9367();
|
||||
drop procedure bug9367;
|
||||
drop table t1;
|
||||
--enable_parsing
|
||||
|
||||
#
|
||||
# BUG#13510: Setting password local variable changes current password
|
||||
#
|
||||
delimiter |;
|
||||
--disable_warnings
|
||||
drop procedure if exists bug13510_1|
|
||||
drop procedure if exists bug13510_2|
|
||||
drop procedure if exists bug13510_3|
|
||||
drop procedure if exists bug13510_4|
|
||||
--enable_warnings
|
||||
|
||||
--error ER_SP_BAD_VAR_SHADOW
|
||||
create procedure bug13510_1()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
|
||||
set password = 'foo1';
|
||||
select password;
|
||||
end|
|
||||
|
||||
--error ER_SP_BAD_VAR_SHADOW
|
||||
create procedure bug13510_2()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
|
||||
set names = 'foo2';
|
||||
select names;
|
||||
end|
|
||||
|
||||
create procedure bug13510_3()
|
||||
begin
|
||||
declare password varchar(10);
|
||||
|
||||
set `password` = 'foo3';
|
||||
select password;
|
||||
end|
|
||||
|
||||
create procedure bug13510_4()
|
||||
begin
|
||||
declare names varchar(10);
|
||||
|
||||
set `names` = 'foo4';
|
||||
select names;
|
||||
end|
|
||||
|
||||
call bug13510_3()|
|
||||
call bug13510_4()|
|
||||
|
||||
drop procedure bug13510_3|
|
||||
drop procedure bug13510_4|
|
||||
delimiter ;|
|
||||
|
||||
#
|
||||
# BUG#NNNN: New bug synopsis
|
||||
#
|
||||
|
@@ -1962,4 +1962,9 @@ insert into t1 values ('1');
|
||||
select * from (select max(fld) from t1) as foo;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
# BUG #10308: purge log with subselect
|
||||
#
|
||||
|
||||
purge master logs before (select adddate(current_timestamp(), interval -4 day));
|
||||
|
||||
|
@@ -52,7 +52,7 @@ gptr my_realloc(gptr oldpoint, uint size, myf my_flags)
|
||||
if ((point = (char*)realloc(oldpoint,size)) == NULL)
|
||||
{
|
||||
if (my_flags & MY_FREE_ON_ERROR)
|
||||
my_free(oldpoint,MyFLAGS);
|
||||
my_free(oldpoint, my_flags);
|
||||
if (my_flags & MY_HOLD_ON_ERROR)
|
||||
DBUG_RETURN(oldpoint);
|
||||
my_errno=errno;
|
||||
|
@@ -232,6 +232,7 @@ $CP mysql-test/t/*.def $BASE/mysql-test/t
|
||||
$CP mysql-test/std_data/*.dat mysql-test/std_data/*.frm \
|
||||
mysql-test/std_data/*.pem mysql-test/std_data/Moscow_leap \
|
||||
mysql-test/std_data/des_key_file mysql-test/std_data/*.*001 \
|
||||
mysql-test/std_data/*.cnf \
|
||||
$BASE/mysql-test/std_data
|
||||
$CP mysql-test/t/*.test mysql-test/t/*.disabled mysql-test/t/*.opt \
|
||||
mysql-test/t/*.slave-mi mysql-test/t/*.sh mysql-test/t/*.sql $BASE/mysql-test/t
|
||||
|
@@ -7042,8 +7042,7 @@ ha_innobase::cmp_ref(
|
||||
(const char*)ref1, len1,
|
||||
(const char*)ref2, len2);
|
||||
} else {
|
||||
result = field->key_cmp((const char*)ref1,
|
||||
(const char*)ref2);
|
||||
result = field->key_cmp(ref1, ref2);
|
||||
}
|
||||
|
||||
if (result) {
|
||||
|
@@ -1353,7 +1353,8 @@ void MYSQL_LOG::new_file(bool need_lock)
|
||||
to change base names at some point.
|
||||
*/
|
||||
THD *thd = current_thd; /* may be 0 if we are reacting to SIGHUP */
|
||||
Rotate_log_event r(thd,new_name+dirname_length(new_name));
|
||||
Rotate_log_event r(thd,new_name+dirname_length(new_name),
|
||||
0, LOG_EVENT_OFFSET, 0);
|
||||
r.write(&log_file);
|
||||
bytes_written += r.data_written;
|
||||
}
|
||||
@@ -1432,7 +1433,7 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...)
|
||||
|
||||
DBUG_ASSERT(log_file.type == SEQ_READ_APPEND);
|
||||
|
||||
pthread_mutex_lock(&LOCK_log);
|
||||
safe_mutex_assert_owner(&LOCK_log);
|
||||
do
|
||||
{
|
||||
if (my_b_append(&log_file,(byte*) buf,len))
|
||||
@@ -1447,7 +1448,6 @@ bool MYSQL_LOG::appendv(const char* buf, uint len,...)
|
||||
new_file(0);
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&LOCK_log);
|
||||
if (!error)
|
||||
signal_update();
|
||||
DBUG_RETURN(error);
|
||||
|
@@ -2962,13 +2962,39 @@ void Rotate_log_event::print(FILE* file, bool short_form, LAST_EVENT_INFO* last_
|
||||
#endif /* MYSQL_CLIENT */
|
||||
|
||||
|
||||
|
||||
/*
|
||||
Rotate_log_event::Rotate_log_event()
|
||||
Rotate_log_event::Rotate_log_event() (2 constructors)
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MYSQL_CLIENT
|
||||
Rotate_log_event::Rotate_log_event(THD* thd_arg,
|
||||
const char* new_log_ident_arg,
|
||||
uint ident_len_arg, ulonglong pos_arg,
|
||||
uint flags_arg)
|
||||
:Log_event(), new_log_ident(new_log_ident_arg),
|
||||
pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
|
||||
(uint) strlen(new_log_ident_arg)), flags(flags_arg)
|
||||
{
|
||||
#ifndef DBUG_OFF
|
||||
char buff[22];
|
||||
DBUG_ENTER("Rotate_log_event::Rotate_log_event(THD*,...)");
|
||||
DBUG_PRINT("enter",("new_log_ident %s pos %s flags %lu", new_log_ident_arg,
|
||||
llstr(pos_arg, buff), flags));
|
||||
#endif
|
||||
if (flags & DUP_NAME)
|
||||
new_log_ident= my_strdup_with_length(new_log_ident_arg,
|
||||
ident_len,
|
||||
MYF(MY_WME));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
|
||||
const Format_description_log_event* description_event)
|
||||
:Log_event(buf, description_event) ,new_log_ident(NULL),alloced(0)
|
||||
:Log_event(buf, description_event) ,new_log_ident(0), flags(DUP_NAME)
|
||||
{
|
||||
DBUG_ENTER("Rotate_log_event::Rotate_log_event(char*,...)");
|
||||
// The caller will ensure that event_len is what we have at EVENT_LEN_OFFSET
|
||||
@@ -2983,12 +3009,9 @@ Rotate_log_event::Rotate_log_event(const char* buf, uint event_len,
|
||||
(header_size+post_header_len));
|
||||
ident_offset = post_header_len;
|
||||
set_if_smaller(ident_len,FN_REFLEN-1);
|
||||
if (!(new_log_ident= my_strdup_with_length((byte*) buf +
|
||||
ident_offset,
|
||||
new_log_ident= my_strdup_with_length((byte*) buf + ident_offset,
|
||||
(uint) ident_len,
|
||||
MYF(MY_WME))))
|
||||
DBUG_VOID_RETURN;
|
||||
alloced = 1;
|
||||
MYF(MY_WME));
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
|
||||
|
@@ -1247,18 +1247,17 @@ public:
|
||||
class Rotate_log_event: public Log_event
|
||||
{
|
||||
public:
|
||||
enum {
|
||||
DUP_NAME= 2 // if constructor should dup the string argument
|
||||
};
|
||||
const char* new_log_ident;
|
||||
ulonglong pos;
|
||||
uint ident_len;
|
||||
bool alloced;
|
||||
uint flags;
|
||||
#ifndef MYSQL_CLIENT
|
||||
Rotate_log_event(THD* thd_arg, const char* new_log_ident_arg,
|
||||
uint ident_len_arg = 0,
|
||||
ulonglong pos_arg = LOG_EVENT_OFFSET)
|
||||
:Log_event(), new_log_ident(new_log_ident_arg),
|
||||
pos(pos_arg),ident_len(ident_len_arg ? ident_len_arg :
|
||||
(uint) strlen(new_log_ident_arg)), alloced(0)
|
||||
{}
|
||||
uint ident_len_arg,
|
||||
ulonglong pos_arg, uint flags);
|
||||
#ifdef HAVE_REPLICATION
|
||||
void pack_info(Protocol* protocol);
|
||||
int exec_event(struct st_relay_log_info* rli);
|
||||
@@ -1271,8 +1270,8 @@ public:
|
||||
const Format_description_log_event* description_event);
|
||||
~Rotate_log_event()
|
||||
{
|
||||
if (alloced)
|
||||
my_free((gptr) new_log_ident, MYF(0));
|
||||
if (flags & DUP_NAME)
|
||||
my_free((gptr) new_log_ident, MYF(MY_ALLOW_ZERO_PTR));
|
||||
}
|
||||
Log_event_type get_type_code() { return ROTATE_EVENT;}
|
||||
int get_data_size() { return ident_len + ROTATE_HEADER_LEN;}
|
||||
|
@@ -5420,3 +5420,5 @@ ER_ROW_IS_REFERENCED_2 23000
|
||||
eng "Cannot delete or update a parent row: a foreign key constraint fails (%.192s)"
|
||||
ER_NO_REFERENCED_ROW_2 23000
|
||||
eng "Cannot add or update a child row: a foreign key constraint fails (%.192s)"
|
||||
ER_SP_BAD_VAR_SHADOW 42000
|
||||
eng "Variable '%-.64s' must be quoted with `...`, or renamed"
|
||||
|
147
sql/slave.cc
147
sql/slave.cc
@@ -1722,9 +1722,26 @@ static int init_relay_log_info(RELAY_LOG_INFO* rli,
|
||||
{
|
||||
char buf[FN_REFLEN];
|
||||
const char *ln;
|
||||
static bool name_warning_sent= 0;
|
||||
ln= rli->relay_log.generate_name(opt_relay_logname, "-relay-bin",
|
||||
1, buf);
|
||||
|
||||
/* We send the warning only at startup, not after every RESET SLAVE */
|
||||
if (!opt_relay_logname && !opt_relaylog_index_name && !name_warning_sent)
|
||||
{
|
||||
/*
|
||||
User didn't give us info to name the relay log index file.
|
||||
Picking `hostname`-relay-bin.index like we do, causes replication to
|
||||
fail if this slave's hostname is changed later. So, we would like to
|
||||
instead require a name. But as we don't want to break many existing
|
||||
setups, we only give warning, not error.
|
||||
*/
|
||||
sql_print_warning("Neither --relay-log nor --relay-log-index were used;"
|
||||
" so replication "
|
||||
"may break when this MySQL server acts as a "
|
||||
"slave and has his hostname changed!! Please "
|
||||
"use '--relay-log=%s' to avoid this problem.", ln);
|
||||
name_warning_sent= 1;
|
||||
}
|
||||
/*
|
||||
note, that if open() fails, we'll still have index file open
|
||||
but a destructor will take care of that
|
||||
@@ -1948,6 +1965,55 @@ static int count_relay_log_space(RELAY_LOG_INFO* rli)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Builds a Rotate from the ignored events' info and writes it to relay log.
|
||||
|
||||
SYNOPSIS
|
||||
write_ignored_events_info_to_relay_log()
|
||||
thd pointer to I/O thread's thd
|
||||
mi
|
||||
|
||||
DESCRIPTION
|
||||
Slave I/O thread, going to die, must leave a durable trace of the
|
||||
ignored events' end position for the use of the slave SQL thread, by
|
||||
calling this function. Only that thread can call it (see assertion).
|
||||
*/
|
||||
static void write_ignored_events_info_to_relay_log(THD *thd, MASTER_INFO *mi)
|
||||
{
|
||||
RELAY_LOG_INFO *rli= &mi->rli;
|
||||
pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
|
||||
DBUG_ASSERT(thd == mi->io_thd);
|
||||
pthread_mutex_lock(log_lock);
|
||||
if (rli->ign_master_log_name_end[0])
|
||||
{
|
||||
DBUG_PRINT("info",("writing a Rotate event to track down ignored events"));
|
||||
Rotate_log_event *ev= new Rotate_log_event(thd, rli->ign_master_log_name_end,
|
||||
0, rli->ign_master_log_pos_end,
|
||||
Rotate_log_event::DUP_NAME);
|
||||
rli->ign_master_log_name_end[0]= 0;
|
||||
/* can unlock before writing as slave SQL thd will soon see our Rotate */
|
||||
pthread_mutex_unlock(log_lock);
|
||||
if (likely((bool)ev))
|
||||
{
|
||||
ev->server_id= 0; // don't be ignored by slave SQL thread
|
||||
if (unlikely(rli->relay_log.append(ev)))
|
||||
sql_print_error("Slave I/O thread failed to write a Rotate event"
|
||||
" to the relay log, "
|
||||
"SHOW SLAVE STATUS may be inaccurate");
|
||||
rli->relay_log.harvest_bytes_written(&rli->log_space_total);
|
||||
flush_master_info(mi, 1);
|
||||
delete ev;
|
||||
}
|
||||
else
|
||||
sql_print_error("Slave I/O thread failed to create a Rotate event"
|
||||
" (out of memory?), "
|
||||
"SHOW SLAVE STATUS may be inaccurate");
|
||||
}
|
||||
else
|
||||
pthread_mutex_unlock(log_lock);
|
||||
}
|
||||
|
||||
|
||||
void init_master_info_with_options(MASTER_INFO* mi)
|
||||
{
|
||||
mi->master_log_name[0] = 0;
|
||||
@@ -2544,7 +2610,7 @@ st_relay_log_info::st_relay_log_info()
|
||||
{
|
||||
group_relay_log_name[0]= event_relay_log_name[0]=
|
||||
group_master_log_name[0]= 0;
|
||||
last_slave_error[0]=0; until_log_name[0]= 0;
|
||||
last_slave_error[0]= until_log_name[0]= ign_master_log_name_end[0]= 0;
|
||||
|
||||
bzero((char*) &info_file, sizeof(info_file));
|
||||
bzero((char*) &cache_buf, sizeof(cache_buf));
|
||||
@@ -3137,12 +3203,20 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli)
|
||||
wait for something for example inside of next_event().
|
||||
*/
|
||||
pthread_mutex_lock(&rli->data_lock);
|
||||
|
||||
/*
|
||||
This tests if the position of the end of the last previous executed event
|
||||
hits the UNTIL barrier.
|
||||
We would prefer to test if the position of the start (or possibly) end of
|
||||
the to-be-read event hits the UNTIL barrier, this is different if there
|
||||
was an event ignored by the I/O thread just before (BUG#13861 to be
|
||||
fixed).
|
||||
*/
|
||||
if (rli->until_condition!=RELAY_LOG_INFO::UNTIL_NONE &&
|
||||
rli->is_until_satisfied())
|
||||
{
|
||||
char buf[22];
|
||||
sql_print_error("Slave SQL thread stopped because it reached its"
|
||||
" UNTIL position %ld", (long) rli->until_pos());
|
||||
" UNTIL position %s", llstr(rli->until_pos(), buf));
|
||||
/*
|
||||
Setting abort_slave flag because we do not want additional message about
|
||||
error in query execution to be printed.
|
||||
@@ -3330,6 +3404,7 @@ pthread_handler_t handle_slave_io(void *arg)
|
||||
THD *thd; // needs to be first for thread_stack
|
||||
MYSQL *mysql;
|
||||
MASTER_INFO *mi = (MASTER_INFO*)arg;
|
||||
RELAY_LOG_INFO *rli= &mi->rli;
|
||||
char llbuff[22];
|
||||
uint retry_count;
|
||||
|
||||
@@ -3572,16 +3647,16 @@ reconnect done to recover from failed read");
|
||||
char llbuf1[22], llbuf2[22];
|
||||
DBUG_PRINT("info", ("log_space_limit=%s log_space_total=%s \
|
||||
ignore_log_space_limit=%d",
|
||||
llstr(mi->rli.log_space_limit,llbuf1),
|
||||
llstr(mi->rli.log_space_total,llbuf2),
|
||||
(int) mi->rli.ignore_log_space_limit));
|
||||
llstr(rli->log_space_limit,llbuf1),
|
||||
llstr(rli->log_space_total,llbuf2),
|
||||
(int) rli->ignore_log_space_limit));
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mi->rli.log_space_limit && mi->rli.log_space_limit <
|
||||
mi->rli.log_space_total &&
|
||||
!mi->rli.ignore_log_space_limit)
|
||||
if (wait_for_relay_log_space(&mi->rli))
|
||||
if (rli->log_space_limit && rli->log_space_limit <
|
||||
rli->log_space_total &&
|
||||
!rli->ignore_log_space_limit)
|
||||
if (wait_for_relay_log_space(rli))
|
||||
{
|
||||
sql_print_error("Slave I/O thread aborted while waiting for relay \
|
||||
log space");
|
||||
@@ -3612,6 +3687,7 @@ err:
|
||||
mysql_close(mysql);
|
||||
mi->mysql=0;
|
||||
}
|
||||
write_ignored_events_info_to_relay_log(thd, mi);
|
||||
thd->proc_info = "Waiting for slave mutex on exit";
|
||||
pthread_mutex_lock(&mi->run_lock);
|
||||
mi->slave_running = 0;
|
||||
@@ -3996,6 +4072,7 @@ static int process_io_rotate(MASTER_INFO *mi, Rotate_log_event *rev)
|
||||
if (unlikely(!rev->is_valid()))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
/* Safe copy as 'rev' has been "sanitized" in Rotate_log_event's ctor */
|
||||
memcpy(mi->master_log_name, rev->new_log_ident, rev->ident_len+1);
|
||||
mi->master_log_pos= rev->pos;
|
||||
DBUG_PRINT("info", ("master_log_pos: '%s' %d",
|
||||
@@ -4246,6 +4323,7 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
|
||||
int error= 0;
|
||||
ulong inc_pos;
|
||||
RELAY_LOG_INFO *rli= &mi->rli;
|
||||
pthread_mutex_t *log_lock= rli->relay_log.get_log_lock();
|
||||
DBUG_ENTER("queue_event");
|
||||
|
||||
if (mi->rli.relay_log.description_event_for_queue->binlog_version<4 &&
|
||||
@@ -4254,11 +4332,6 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
|
||||
|
||||
pthread_mutex_lock(&mi->data_lock);
|
||||
|
||||
/*
|
||||
TODO: figure out if other events in addition to Rotate
|
||||
require special processing.
|
||||
Guilhem 2003-06 : I don't think so.
|
||||
*/
|
||||
switch (buf[EVENT_TYPE_OFFSET]) {
|
||||
case STOP_EVENT:
|
||||
/*
|
||||
@@ -4343,14 +4416,21 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
|
||||
direct master (an unsupported, useless setup!).
|
||||
*/
|
||||
|
||||
pthread_mutex_lock(log_lock);
|
||||
|
||||
if ((uint4korr(buf + SERVER_ID_OFFSET) == ::server_id) &&
|
||||
!replicate_same_server_id)
|
||||
{
|
||||
/*
|
||||
Do not write it to the relay log.
|
||||
We still want to increment, so that we won't re-read this event from the
|
||||
master if the slave IO thread is now stopped/restarted (more efficient if
|
||||
the events we are ignoring are big LOAD DATA INFILE).
|
||||
a) We still want to increment mi->master_log_pos, so that we won't
|
||||
re-read this event from the master if the slave IO thread is now
|
||||
stopped/restarted (more efficient if the events we are ignoring are big
|
||||
LOAD DATA INFILE).
|
||||
b) We want to record that we are skipping events, for the information of
|
||||
the slave SQL thread, otherwise that thread may let
|
||||
rli->group_relay_log_pos stay too small if the last binlog's event is
|
||||
ignored.
|
||||
But events which were generated by this slave and which do not exist in
|
||||
the master's binlog (i.e. Format_desc, Rotate & Stop) should not increment
|
||||
mi->master_log_pos.
|
||||
@@ -4358,7 +4438,13 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
|
||||
if (buf[EVENT_TYPE_OFFSET]!=FORMAT_DESCRIPTION_EVENT &&
|
||||
buf[EVENT_TYPE_OFFSET]!=ROTATE_EVENT &&
|
||||
buf[EVENT_TYPE_OFFSET]!=STOP_EVENT)
|
||||
{
|
||||
mi->master_log_pos+= inc_pos;
|
||||
memcpy(rli->ign_master_log_name_end, mi->master_log_name, FN_REFLEN);
|
||||
DBUG_ASSERT(rli->ign_master_log_name_end[0]);
|
||||
rli->ign_master_log_pos_end= mi->master_log_pos;
|
||||
}
|
||||
rli->relay_log.signal_update(); // the slave SQL thread needs to re-check
|
||||
DBUG_PRINT("info", ("master_log_pos: %d, event originating from the same server, ignored", (ulong) mi->master_log_pos));
|
||||
}
|
||||
else
|
||||
@@ -4372,7 +4458,10 @@ int queue_event(MASTER_INFO* mi,const char* buf, ulong event_len)
|
||||
}
|
||||
else
|
||||
error= 3;
|
||||
rli->ign_master_log_name_end[0]= 0; // last event is not ignored
|
||||
}
|
||||
pthread_mutex_unlock(log_lock);
|
||||
|
||||
|
||||
err:
|
||||
pthread_mutex_unlock(&mi->data_lock);
|
||||
@@ -4756,6 +4845,26 @@ Log_event* next_event(RELAY_LOG_INFO* rli)
|
||||
rli->last_master_timestamp= 0;
|
||||
|
||||
DBUG_ASSERT(rli->relay_log.get_open_count() == rli->cur_log_old_open_count);
|
||||
|
||||
if (rli->ign_master_log_name_end[0])
|
||||
{
|
||||
/* We generate and return a Rotate, to make our positions advance */
|
||||
DBUG_PRINT("info",("seeing an ignored end segment"));
|
||||
ev= new Rotate_log_event(thd, rli->ign_master_log_name_end,
|
||||
0, rli->ign_master_log_pos_end,
|
||||
Rotate_log_event::DUP_NAME);
|
||||
rli->ign_master_log_name_end[0]= 0;
|
||||
if (unlikely(!ev))
|
||||
{
|
||||
errmsg= "Slave SQL thread failed to create a Rotate event "
|
||||
"(out of memory?), SHOW SLAVE STATUS may be inaccurate";
|
||||
goto err;
|
||||
}
|
||||
pthread_mutex_unlock(log_lock);
|
||||
ev->server_id= 0; // don't be ignored by slave SQL thread
|
||||
DBUG_RETURN(ev);
|
||||
}
|
||||
|
||||
/*
|
||||
We can, and should release data_lock while we are waiting for
|
||||
update. If we do not, show slave status will block
|
||||
|
11
sql/slave.h
11
sql/slave.h
@@ -302,6 +302,17 @@ typedef struct st_relay_log_info
|
||||
*/
|
||||
ulong trans_retries, retried_trans;
|
||||
|
||||
/*
|
||||
If the end of the hot relay log is made of master's events ignored by the
|
||||
slave I/O thread, these two keep track of the coords (in the master's
|
||||
binlog) of the last of these events seen by the slave I/O thread. If not,
|
||||
ign_master_log_name_end[0] == 0.
|
||||
As they are like a Rotate event read/written from/to the relay log, they
|
||||
are both protected by rli->relay_log.LOCK_log.
|
||||
*/
|
||||
char ign_master_log_name_end[FN_REFLEN];
|
||||
ulonglong ign_master_log_pos_end;
|
||||
|
||||
st_relay_log_info();
|
||||
~st_relay_log_info();
|
||||
|
||||
|
@@ -1052,8 +1052,10 @@ int sp_head::execute(THD *thd)
|
||||
original thd->db will then have been freed */
|
||||
if (dbchanged)
|
||||
{
|
||||
/* No access check when changing back to where we came from.
|
||||
(It would generate an error from mysql_change_db() when olddb=="") */
|
||||
if (! thd->killed)
|
||||
ret= mysql_change_db(thd, olddb, 0);
|
||||
ret= mysql_change_db(thd, olddb, 1);
|
||||
}
|
||||
m_flags&= ~IS_INVOKED;
|
||||
DBUG_RETURN(ret);
|
||||
@@ -2651,9 +2653,24 @@ sp_change_security_context(THD *thd, sp_head *sp, Security_context **backup)
|
||||
sp->m_definer_host.str,
|
||||
sp->m_db.str))
|
||||
{
|
||||
#ifdef NOT_YET_REPLICATION_SAFE
|
||||
/*
|
||||
Until we don't properly replicate information about stored routine
|
||||
definer with stored routine creation statement all stored routines
|
||||
on slave are created under ''@'' definer. Therefore we won't be able
|
||||
to run any routine which was replicated from master on slave server
|
||||
if we emit error here. This will cause big problems for users
|
||||
who use slave for fail-over. So until we fully implement WL#2897
|
||||
"Complete definer support in the stored routines" we run suid
|
||||
stored routines for which we were unable to find definer under
|
||||
invoker security context.
|
||||
*/
|
||||
my_error(ER_NO_SUCH_USER, MYF(0), sp->m_definer_user.str,
|
||||
sp->m_definer_host.str);
|
||||
return TRUE;
|
||||
#else
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
*backup= thd->security_ctx;
|
||||
thd->security_ctx= &sp->m_security_ctx;
|
||||
|
@@ -7992,6 +7992,18 @@ option_value:
|
||||
$2= $2 ? $2: global_system_variables.character_set_client;
|
||||
lex->var_list.push_back(new set_var_collation_client($2,thd->variables.collation_database,$2));
|
||||
}
|
||||
| NAMES_SYM equal expr
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
LEX_STRING names;
|
||||
|
||||
names.str= (char *)"names";
|
||||
names.length= 5;
|
||||
if (spc && spc->find_pvar(&names))
|
||||
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), names.str);
|
||||
YYABORT;
|
||||
}
|
||||
| NAMES_SYM charset_name_or_default opt_collate
|
||||
{
|
||||
LEX *lex= Lex;
|
||||
@@ -8009,6 +8021,17 @@ option_value:
|
||||
{
|
||||
THD *thd=YYTHD;
|
||||
LEX_USER *user;
|
||||
LEX *lex= Lex;
|
||||
sp_pcontext *spc= lex->spcont;
|
||||
LEX_STRING pw;
|
||||
|
||||
pw.str= (char *)"password";
|
||||
pw.length= 8;
|
||||
if (spc && spc->find_pvar(&pw))
|
||||
{
|
||||
my_error(ER_SP_BAD_VAR_SHADOW, MYF(0), pw.str);
|
||||
YYABORT;
|
||||
}
|
||||
if (!(user=(LEX_USER*) thd->alloc(sizeof(LEX_USER))))
|
||||
YYABORT;
|
||||
user->host=null_lex_str;
|
||||
|
Reference in New Issue
Block a user