mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
Merge kboortz@bk-internal.mysql.com:/home/bk/mysql-4.1
into mysql.com:/Users/kent/mysql/bk/mysql-4.1-perl
This commit is contained in:
@@ -17,8 +17,6 @@ master-bin.000001 # Query 1 # create database `drop-temp+table-test`
|
|||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int)
|
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn1 (a int)
|
||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int)
|
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table `table:name` (a int)
|
||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int)
|
master-bin.000001 # Query 1 # use `drop-temp+table-test`; create temporary table shortn2 (a int)
|
||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`
|
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn2`,`drop-temp+table-test`.`table:name`,`drop-temp+table-test`.`shortn1`
|
||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`table:name`
|
|
||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `drop-temp+table-test`.`shortn1`
|
|
||||||
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DO RELEASE_LOCK("a")
|
master-bin.000001 # Query 1 # use `drop-temp+table-test`; DO RELEASE_LOCK("a")
|
||||||
drop database `drop-temp+table-test`;
|
drop database `drop-temp+table-test`;
|
||||||
|
12
mysql-test/r/rpl_drop_temp.result
Normal file
12
mysql-test/r/rpl_drop_temp.result
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
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;
|
||||||
|
create database if not exists mysqltest;
|
||||||
|
create temporary table mysqltest.t1 (n int);
|
||||||
|
create temporary table mysqltest.t2 (n int);
|
||||||
|
show status like 'Slave_open_temp_tables';
|
||||||
|
Variable_name Value
|
||||||
|
Slave_open_temp_tables 0
|
32
mysql-test/r/rpl_multi_query.result
Normal file
32
mysql-test/r/rpl_multi_query.result
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
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;
|
||||||
|
drop database if exists mysqltest;
|
||||||
|
create database mysqltest;
|
||||||
|
create table mysqltest.t1 ( n int);
|
||||||
|
insert into mysqltest.t1 values(1)/
|
||||||
|
insert into mysqltest.t1 values(2);
|
||||||
|
insert into mysqltest.t1 values(3);
|
||||||
|
insert into mysqltest.t1 values(4);
|
||||||
|
insert into mysqltest.t1 values(5)/
|
||||||
|
select * from mysqltest.t1;
|
||||||
|
n
|
||||||
|
1
|
||||||
|
2
|
||||||
|
3
|
||||||
|
4
|
||||||
|
5
|
||||||
|
show binlog events from 79;
|
||||||
|
Log_name Pos Event_type Server_id Orig_log_pos Info
|
||||||
|
master-bin.000001 # Query 1 # drop database if exists mysqltest
|
||||||
|
master-bin.000001 # Query 1 # create database mysqltest
|
||||||
|
master-bin.000001 # Query 1 # use `test`; create table mysqltest.t1 ( n int)
|
||||||
|
master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(1)
|
||||||
|
master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(2)
|
||||||
|
master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(3)
|
||||||
|
master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(4)
|
||||||
|
master-bin.000001 # Query 1 # use `test`; insert into mysqltest.t1 values(5)
|
||||||
|
drop database mysqltest;
|
2
mysql-test/t/rpl_drop_temp-slave.opt
Normal file
2
mysql-test/t/rpl_drop_temp-slave.opt
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
--replicate-ignore-table=mysqltest.t2
|
||||||
|
|
13
mysql-test/t/rpl_drop_temp.test
Normal file
13
mysql-test/t/rpl_drop_temp.test
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
source include/master-slave.inc;
|
||||||
|
--disable_warnings
|
||||||
|
create database if not exists mysqltest;
|
||||||
|
--enable_warnings
|
||||||
|
|
||||||
|
create temporary table mysqltest.t1 (n int);
|
||||||
|
create temporary table mysqltest.t2 (n int);
|
||||||
|
sync_slave_with_master;
|
||||||
|
connection master;
|
||||||
|
disconnect master;
|
||||||
|
connection slave;
|
||||||
|
--real_sleep 3; # time for DROP to be written
|
||||||
|
show status like 'Slave_open_temp_tables';
|
26
mysql-test/t/rpl_multi_query.test
Normal file
26
mysql-test/t/rpl_multi_query.test
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
# Test for BUG#8436: verify that a multi-query (i.e. one query
|
||||||
|
# containing several queries (assuming client has
|
||||||
|
# CLIENT_MULTI_STATEMENTS) will be binlogged ONE-query-per-event (not
|
||||||
|
# one binlog event containing all queries)
|
||||||
|
|
||||||
|
source include/master-slave.inc;
|
||||||
|
--disable_warnings
|
||||||
|
drop database if exists mysqltest;
|
||||||
|
--enable_warnings
|
||||||
|
create database mysqltest;
|
||||||
|
|
||||||
|
delimiter /;
|
||||||
|
create table mysqltest.t1 ( n int);
|
||||||
|
insert into mysqltest.t1 values(1)/
|
||||||
|
insert into mysqltest.t1 values(2);
|
||||||
|
insert into mysqltest.t1 values(3);
|
||||||
|
insert into mysqltest.t1 values(4);
|
||||||
|
insert into mysqltest.t1 values(5)/
|
||||||
|
delimiter ;/
|
||||||
|
sync_slave_with_master;
|
||||||
|
select * from mysqltest.t1;
|
||||||
|
connection master;
|
||||||
|
--replace_column 2 # 5 #
|
||||||
|
show binlog events from 79;
|
||||||
|
drop database mysqltest;
|
||||||
|
sync_slave_with_master;
|
@@ -472,7 +472,7 @@ innobase_mysql_tmpfile(void)
|
|||||||
{
|
{
|
||||||
char filename[FN_REFLEN];
|
char filename[FN_REFLEN];
|
||||||
int fd2 = -1;
|
int fd2 = -1;
|
||||||
File fd = create_temp_file(filename, NullS, "ib",
|
File fd = create_temp_file(filename, mysql_tmpdir, "ib",
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
O_BINARY | O_TRUNC | O_SEQUENTIAL |
|
O_BINARY | O_TRUNC | O_SEQUENTIAL |
|
||||||
O_TEMPORARY | O_SHORT_LIVED |
|
O_TEMPORARY | O_SHORT_LIVED |
|
||||||
|
@@ -1645,7 +1645,8 @@ String *Item_func_format::val_str(String *str)
|
|||||||
{
|
{
|
||||||
DBUG_ASSERT(fixed == 1);
|
DBUG_ASSERT(fixed == 1);
|
||||||
double nr =args[0]->val();
|
double nr =args[0]->val();
|
||||||
uint32 diff,length,str_length;
|
int diff;
|
||||||
|
uint32 length, str_length;
|
||||||
uint dec;
|
uint dec;
|
||||||
if ((null_value=args[0]->null_value))
|
if ((null_value=args[0]->null_value))
|
||||||
return 0; /* purecov: inspected */
|
return 0; /* purecov: inspected */
|
||||||
@@ -1670,9 +1671,12 @@ String *Item_func_format::val_str(String *str)
|
|||||||
pos[0]= pos[-(int) diff];
|
pos[0]= pos[-(int) diff];
|
||||||
while (diff)
|
while (diff)
|
||||||
{
|
{
|
||||||
pos[0]=pos[-(int) diff]; pos--;
|
*pos= *(pos - diff);
|
||||||
pos[0]=pos[-(int) diff]; pos--;
|
pos--;
|
||||||
pos[0]=pos[-(int) diff]; pos--;
|
*pos= *(pos - diff);
|
||||||
|
pos--;
|
||||||
|
*pos= *(pos - diff);
|
||||||
|
pos--;
|
||||||
pos[0]=',';
|
pos[0]=',';
|
||||||
pos--;
|
pos--;
|
||||||
diff--;
|
diff--;
|
||||||
|
@@ -485,58 +485,62 @@ void close_temporary(TABLE *table,bool delete_table)
|
|||||||
void close_temporary_tables(THD *thd)
|
void close_temporary_tables(THD *thd)
|
||||||
{
|
{
|
||||||
TABLE *table,*next;
|
TABLE *table,*next;
|
||||||
char *query, *name_in_query, *end;
|
char *query, *end;
|
||||||
uint greatest_key_length= 0;
|
uint query_buf_size;
|
||||||
|
bool found_user_tables = 0;
|
||||||
|
|
||||||
if (!thd->temporary_tables)
|
if (!thd->temporary_tables)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
|
||||||
We write a DROP TEMPORARY TABLE for each temp table left, so that our
|
|
||||||
replication slave can clean them up. Not one multi-table DROP TABLE binlog
|
|
||||||
event: this would cause problems if slave uses --replicate-*-table.
|
|
||||||
*/
|
|
||||||
LINT_INIT(end);
|
LINT_INIT(end);
|
||||||
|
query_buf_size= 50; // Enough for DROP ... TABLE IF EXISTS
|
||||||
|
|
||||||
/* We'll re-use always same buffer so make it big enough for longest name */
|
|
||||||
for (table=thd->temporary_tables ; table ; table=table->next)
|
for (table=thd->temporary_tables ; table ; table=table->next)
|
||||||
greatest_key_length= max(greatest_key_length, table->key_length);
|
/*
|
||||||
|
We are going to add 4 ` around the db/table names, so 1 does not look
|
||||||
|
enough; indeed it is enough, because table->key_length is greater (by 8,
|
||||||
|
because of server_id and thread_id) than db||table.
|
||||||
|
*/
|
||||||
|
query_buf_size+= table->key_length+1;
|
||||||
|
|
||||||
if ((query = alloc_root(thd->mem_root, greatest_key_length+50)))
|
if ((query = alloc_root(thd->mem_root, query_buf_size)))
|
||||||
// Better add "if exists", in case a RESET MASTER has been done
|
// Better add "if exists", in case a RESET MASTER has been done
|
||||||
name_in_query= strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS `");
|
end=strmov(query, "DROP /*!40005 TEMPORARY */ TABLE IF EXISTS ");
|
||||||
|
|
||||||
for (table=thd->temporary_tables ; table ; table=next)
|
for (table=thd->temporary_tables ; table ; table=next)
|
||||||
{
|
{
|
||||||
/*
|
if (query) // we might be out of memory, but this is not fatal
|
||||||
In we are OOM for 'query' this is not fatal. We skip temporary tables
|
|
||||||
not created directly by the user.
|
|
||||||
*/
|
|
||||||
if (query && mysql_bin_log.is_open() && (table->real_name[0] != '#'))
|
|
||||||
{
|
{
|
||||||
|
// skip temporary tables not created directly by the user
|
||||||
|
if (table->real_name[0] != '#')
|
||||||
|
found_user_tables = 1;
|
||||||
/*
|
/*
|
||||||
Here we assume table_cache_key always starts
|
Here we assume table_cache_key always starts
|
||||||
with \0 terminated db name
|
with \0 terminated db name
|
||||||
*/
|
*/
|
||||||
end = strxmov(name_in_query, table->table_cache_key, "`.`",
|
end = strxmov(end,"`",table->table_cache_key,"`.`",
|
||||||
table->real_name, "`", NullS);
|
table->real_name,"`,", NullS);
|
||||||
Query_log_event qinfo(thd, query, (ulong)(end-query), 0, FALSE);
|
|
||||||
/*
|
|
||||||
Imagine the thread had created a temp table, then was doing a SELECT, and
|
|
||||||
the SELECT was killed. Then it's not clever to mark the statement above as
|
|
||||||
"killed", because it's not really a statement updating data, and there
|
|
||||||
are 99.99% chances it will succeed on slave. And, if thread is
|
|
||||||
killed now, it's not clever either.
|
|
||||||
If a real update (one updating a persistent table) was killed on the
|
|
||||||
master, then this real update will be logged with error_code=killed,
|
|
||||||
rightfully causing the slave to stop.
|
|
||||||
*/
|
|
||||||
qinfo.error_code= 0;
|
|
||||||
mysql_bin_log.write(&qinfo);
|
|
||||||
}
|
}
|
||||||
next=table->next;
|
next=table->next;
|
||||||
close_temporary(table);
|
close_temporary(table);
|
||||||
}
|
}
|
||||||
|
if (query && found_user_tables && mysql_bin_log.is_open())
|
||||||
|
{
|
||||||
|
/* The -1 is to remove last ',' */
|
||||||
|
thd->clear_error();
|
||||||
|
Query_log_event qinfo(thd, query, (ulong)(end-query)-1, 0, FALSE);
|
||||||
|
/*
|
||||||
|
Imagine the thread had created a temp table, then was doing a SELECT, and
|
||||||
|
the SELECT was killed. Then it's not clever to mark the statement above as
|
||||||
|
"killed", because it's not really a statement updating data, and there
|
||||||
|
are 99.99% chances it will succeed on slave.
|
||||||
|
If a real update (one updating a persistent table) was killed on the
|
||||||
|
master, then this real update will be logged with error_code=killed,
|
||||||
|
rightfully causing the slave to stop.
|
||||||
|
*/
|
||||||
|
qinfo.error_code= 0;
|
||||||
|
mysql_bin_log.write(&qinfo);
|
||||||
|
}
|
||||||
thd->temporary_tables=0;
|
thd->temporary_tables=0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -656,12 +656,12 @@ static int check_connection(THD *thd)
|
|||||||
{
|
{
|
||||||
uint connect_errors= 0;
|
uint connect_errors= 0;
|
||||||
NET *net= &thd->net;
|
NET *net= &thd->net;
|
||||||
|
ulong pkt_len= 0;
|
||||||
|
char *end;
|
||||||
|
|
||||||
DBUG_PRINT("info",
|
DBUG_PRINT("info",
|
||||||
("New connection received on %s", vio_description(net->vio)));
|
("New connection received on %s", vio_description(net->vio)));
|
||||||
|
|
||||||
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
|
||||||
|
|
||||||
if (!thd->host) // If TCP/IP connection
|
if (!thd->host) // If TCP/IP connection
|
||||||
{
|
{
|
||||||
char ip[30];
|
char ip[30];
|
||||||
@@ -671,6 +671,7 @@ static int check_connection(THD *thd)
|
|||||||
if (!(thd->ip= my_strdup(ip,MYF(0))))
|
if (!(thd->ip= my_strdup(ip,MYF(0))))
|
||||||
return (ER_OUT_OF_RESOURCES);
|
return (ER_OUT_OF_RESOURCES);
|
||||||
thd->host_or_ip= thd->ip;
|
thd->host_or_ip= thd->ip;
|
||||||
|
vio_in_addr(net->vio,&thd->remote.sin_addr);
|
||||||
#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
|
#if !defined(HAVE_SYS_UN_H) || defined(HAVE_mit_thread)
|
||||||
/* Fast local hostname resolve for Win32 */
|
/* Fast local hostname resolve for Win32 */
|
||||||
if (!strcmp(thd->ip,"127.0.0.1"))
|
if (!strcmp(thd->ip,"127.0.0.1"))
|
||||||
@@ -706,10 +707,10 @@ static int check_connection(THD *thd)
|
|||||||
DBUG_PRINT("info",("Host: %s",thd->host));
|
DBUG_PRINT("info",("Host: %s",thd->host));
|
||||||
thd->host_or_ip= thd->host;
|
thd->host_or_ip= thd->host;
|
||||||
thd->ip= 0;
|
thd->ip= 0;
|
||||||
|
/* Reset sin_addr */
|
||||||
|
bzero((char*) &thd->remote, sizeof(thd->remote));
|
||||||
}
|
}
|
||||||
vio_keepalive(net->vio, TRUE);
|
vio_keepalive(net->vio, TRUE);
|
||||||
ulong pkt_len= 0;
|
|
||||||
char *end;
|
|
||||||
{
|
{
|
||||||
/* buff[] needs to big enough to hold the server_version variable */
|
/* buff[] needs to big enough to hold the server_version variable */
|
||||||
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
|
char buff[SERVER_VERSION_LENGTH + SCRAMBLE_LENGTH + 64];
|
||||||
@@ -1472,6 +1473,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
{
|
{
|
||||||
if (alloc_query(thd, packet, packet_length))
|
if (alloc_query(thd, packet, packet_length))
|
||||||
break; // fatal error is set
|
break; // fatal error is set
|
||||||
|
char *packet_end= thd->query + thd->query_length;
|
||||||
mysql_log.write(thd,command,"%s",thd->query);
|
mysql_log.write(thd,command,"%s",thd->query);
|
||||||
DBUG_PRINT("query",("%-.4096s",thd->query));
|
DBUG_PRINT("query",("%-.4096s",thd->query));
|
||||||
mysql_parse(thd,thd->query, thd->query_length);
|
mysql_parse(thd,thd->query, thd->query_length);
|
||||||
@@ -1487,7 +1489,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd,
|
|||||||
if (thd->lock || thd->open_tables || thd->derived_tables)
|
if (thd->lock || thd->open_tables || thd->derived_tables)
|
||||||
close_thread_tables(thd);
|
close_thread_tables(thd);
|
||||||
#endif
|
#endif
|
||||||
ulong length= thd->query_length-(ulong)(packet-thd->query);
|
ulong length= (ulong)(packet_end-packet);
|
||||||
|
|
||||||
/* Remove garbage at start of query */
|
/* Remove garbage at start of query */
|
||||||
while (my_isspace(thd->charset(), *packet) && length > 0)
|
while (my_isspace(thd->charset(), *packet) && length > 0)
|
||||||
@@ -1924,9 +1926,14 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
Skip if we are in the slave thread, some table rules have been
|
Skip if we are in the slave thread, some table rules have been
|
||||||
given and the table list says the query should not be replicated
|
given and the table list says the query should not be replicated.
|
||||||
|
Exception is DROP TEMPORARY TABLE IF EXISTS: we always execute it
|
||||||
|
(otherwise we have stale files on slave caused by exclusion of one tmp
|
||||||
|
table).
|
||||||
*/
|
*/
|
||||||
if (all_tables_not_ok(thd,tables))
|
if (!(lex->sql_command == SQLCOM_DROP_TABLE &&
|
||||||
|
lex->drop_temporary && lex->drop_if_exists) &&
|
||||||
|
all_tables_not_ok(thd,tables))
|
||||||
{
|
{
|
||||||
/* we warn the slave SQL thread */
|
/* we warn the slave SQL thread */
|
||||||
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
my_error(ER_SLAVE_IGNORED_TABLE, MYF(0));
|
||||||
@@ -4118,6 +4125,20 @@ void mysql_parse(THD *thd, char *inBuf, uint length)
|
|||||||
send_error(thd, 0, NullS);
|
send_error(thd, 0, NullS);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
Binlog logs a string starting from thd->query and having length
|
||||||
|
thd->query_length; so we set thd->query_length correctly (to not
|
||||||
|
log several statements in one event, when we executed only first).
|
||||||
|
We set it to not see the ';' (otherwise it would get into binlog
|
||||||
|
and Query_log_event::print() would give ';;' output).
|
||||||
|
This also helps display only the current query in SHOW
|
||||||
|
PROCESSLIST.
|
||||||
|
Note that we don't need LOCK_thread_count to modify query_length.
|
||||||
|
*/
|
||||||
|
if (lex->found_colon &&
|
||||||
|
(thd->query_length= (ulong)(lex->found_colon - thd->query)))
|
||||||
|
thd->query_length--;
|
||||||
|
/* Actually execute the query */
|
||||||
mysql_execute_command(thd);
|
mysql_execute_command(thd);
|
||||||
query_cache_end_of_result(thd);
|
query_cache_end_of_result(thd);
|
||||||
}
|
}
|
||||||
|
@@ -272,6 +272,18 @@ my_bool vio_peer_addr(Vio * vio, char *buf, uint16 *port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get in_addr for a TCP/IP connection
|
||||||
|
|
||||||
|
SYNOPSIS
|
||||||
|
vio_in_addr()
|
||||||
|
vio vio handle
|
||||||
|
in put in_addr here
|
||||||
|
|
||||||
|
NOTES
|
||||||
|
one must call vio_peer_addr() before calling this one
|
||||||
|
*/
|
||||||
|
|
||||||
void vio_in_addr(Vio *vio, struct in_addr *in)
|
void vio_in_addr(Vio *vio, struct in_addr *in)
|
||||||
{
|
{
|
||||||
DBUG_ENTER("vio_in_addr");
|
DBUG_ENTER("vio_in_addr");
|
||||||
|
Reference in New Issue
Block a user