Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
eac4388c
Commit
eac4388c
authored
Sep 09, 2005
by
sergefp@mysql.com
Browse files
Options
Browse Files
Download
Plain Diff
Merge spetrunia@bk-internal.mysql.com:/home/bk/mysql-5.0
into mysql.com:/home/psergey/mysql-5.0-bug12943
parents
871ac087
e5b42524
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
204 additions
and
38 deletions
+204
-38
mysql-test/r/rpl_sp_effects.result
mysql-test/r/rpl_sp_effects.result
+57
-0
mysql-test/r/sp.result
mysql-test/r/sp.result
+13
-0
mysql-test/t/rpl_sp_effects.test
mysql-test/t/rpl_sp_effects.test
+48
-0
mysql-test/t/sp.test
mysql-test/t/sp.test
+13
-19
sql/item_func.cc
sql/item_func.cc
+11
-4
sql/log.cc
sql/log.cc
+7
-0
sql/sp_head.cc
sql/sp_head.cc
+39
-11
sql/sp_head.h
sql/sp_head.h
+3
-2
sql/sql_class.h
sql/sql_class.h
+10
-2
sql/sql_parse.cc
sql/sql_parse.cc
+3
-0
No files found.
mysql-test/r/rpl_sp_effects.result
View file @
eac4388c
...
@@ -156,3 +156,60 @@ slave: 6
...
@@ -156,3 +156,60 @@ slave: 6
drop procedure p1;
drop procedure p1;
drop function f1;
drop function f1;
drop table t1,t2;
drop table t1,t2;
create table t1 (a int);
create procedure p1()
begin
insert into t1 values(@x);
set @x=@x+1;
insert into t1 values(@x);
if (f2()) then
insert into t1 values(1243);
end if;
end//
create function f2() returns int
begin
insert into t1 values(@z);
set @z=@z+1;
insert into t1 values(@z);
return 0;
end//
create function f1() returns int
begin
insert into t1 values(@y);
call p1();
return 0;
end//
set @x=10;
set @y=20;
set @z=100;
select f1();
f1()
0
set @x=30;
call p1();
select 'master', a from t1;
master a
master 20
master 10
master 11
master 100
master 101
master 30
master 31
master 101
master 102
select 'slave', a from t1;
slave a
slave 20
slave 10
slave 11
slave 100
slave 101
slave 30
slave 31
slave 101
slave 102
drop table t1;
drop function f1;
drop function f2;
drop procedure p1;
mysql-test/r/sp.result
View file @
eac4388c
...
@@ -3085,6 +3085,19 @@ column_name bug10055(t.column_name)
...
@@ -3085,6 +3085,19 @@ column_name bug10055(t.column_name)
id id
id id
data data
data data
drop function bug10055|
drop function bug10055|
drop procedure if exists bug12297|
create procedure bug12297(lim int)
begin
set @x = 0;
repeat
insert into t1(id,data)
values('aa', @x);
set @x = @x + 1;
until @x >= lim
end repeat;
end|
call bug12297(10)|
drop procedure bug12297|
drop function if exists f_bug11247|
drop function if exists f_bug11247|
drop procedure if exists p_bug11247|
drop procedure if exists p_bug11247|
create function f_bug11247(param int)
create function f_bug11247(param int)
...
...
mysql-test/t/rpl_sp_effects.test
View file @
eac4388c
...
@@ -152,4 +152,52 @@ drop procedure p1;
...
@@ -152,4 +152,52 @@ drop procedure p1;
drop
function
f1
;
drop
function
f1
;
drop
table
t1
,
t2
;
drop
table
t1
,
t2
;
# BUG#12637: User variables + SPs replication
create
table
t1
(
a
int
);
delimiter
//;
create
procedure
p1
()
begin
insert
into
t1
values
(
@
x
);
set
@
x
=@
x
+
1
;
insert
into
t1
values
(
@
x
);
if
(
f2
())
then
insert
into
t1
values
(
1243
);
end
if
;
end
//
create
function
f2
()
returns
int
begin
insert
into
t1
values
(
@
z
);
set
@
z
=@
z
+
1
;
insert
into
t1
values
(
@
z
);
return
0
;
end
//
create
function
f1
()
returns
int
begin
insert
into
t1
values
(
@
y
);
call
p1
();
return
0
;
end
//
delimiter
;
//
set
@
x
=
10
;
set
@
y
=
20
;
set
@
z
=
100
;
select
f1
();
set
@
x
=
30
;
call
p1
();
select
'master'
,
a
from
t1
;
sync_slave_with_master
;
connection
slave
;
select
'slave'
,
a
from
t1
;
connection
master
;
drop
table
t1
;
drop
function
f1
;
drop
function
f2
;
drop
procedure
p1
;
sync_slave_with_master
;
sync_slave_with_master
;
mysql-test/t/sp.test
View file @
eac4388c
...
@@ -3877,29 +3877,23 @@ drop function bug10055|
...
@@ -3877,29 +3877,23 @@ drop function bug10055|
# consumption by passing large input parameter.
# consumption by passing large input parameter.
#
#
#
# Note: the test is currenly disabled because of the
# Bug #12637: SP crashes the server if it has update query with user var
# & binlog is enabled.
#
--
disable_warnings
--
disable_warnings
#
drop procedure if exists bug12297|
drop
procedure
if
exists
bug12297
|
--
enable_warnings
--
enable_warnings
#
create procedure bug12297(lim int)
create
procedure
bug12297
(
lim
int
)
#
begin
begin
#
set @x = 0;
set
@
x
=
0
;
#
repeat
repeat
#
insert into t1(id,data)
insert
into
t1
(
id
,
data
)
#
values('aa', @x);
values
(
'aa'
,
@
x
);
#
set @x = @x + 1;
set
@
x
=
@
x
+
1
;
#
until @x >= lim
until
@
x
>=
lim
#
end repeat;
end
repeat
;
#
end|
end
|
#
call bug12297(10)|
call
bug12297
(
10
)
|
#
drop procedure bug12297|
drop
procedure
bug12297
|
#
#
# Bug #11247 "Stored procedures: Function calls in long loops leak memory"
# Bug #11247 "Stored procedures: Function calls in long loops leak memory"
...
...
sql/item_func.cc
View file @
eac4388c
...
@@ -3884,7 +3884,8 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
...
@@ -3884,7 +3884,8 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
if
(
!
(
var_entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
0
)))
if
(
!
(
var_entry
=
get_variable
(
&
thd
->
user_vars
,
name
,
0
)))
goto
err
;
goto
err
;
}
}
else
if
(
var_entry
->
used_query_id
==
thd
->
query_id
)
else
if
(
var_entry
->
used_query_id
==
thd
->
query_id
||
mysql_bin_log
.
is_query_in_union
(
thd
,
var_entry
->
used_query_id
))
{
{
/*
/*
If this variable was already stored in user_var_events by this query
If this variable was already stored in user_var_events by this query
...
@@ -3901,10 +3902,16 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
...
@@ -3901,10 +3902,16 @@ int get_var_with_binlog(THD *thd, enum_sql_command sql_command,
appears:
appears:
> set @a:=1;
> set @a:=1;
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
> insert into t1 values (@a), (@a:=@a+1), (@a:=@a+1);
We have to write to binlog value @a= 1;
We have to write to binlog value @a= 1.
We allocate the user_var_event on user_var_events_alloc pool, not on
the this-statement-execution pool because in SPs user_var_event objects
may need to be valid after current [SP] statement execution pool is
destroyed.
*/
*/
size
=
ALIGN_SIZE
(
sizeof
(
BINLOG_USER_VAR_EVENT
))
+
var_entry
->
length
;
size
=
ALIGN_SIZE
(
sizeof
(
BINLOG_USER_VAR_EVENT
))
+
var_entry
->
length
;
if
(
!
(
user_var_event
=
(
BINLOG_USER_VAR_EVENT
*
)
thd
->
alloc
(
size
)))
if
(
!
(
user_var_event
=
(
BINLOG_USER_VAR_EVENT
*
)
alloc_root
(
thd
->
user_var_events_alloc
,
size
)))
goto
err
;
goto
err
;
user_var_event
->
value
=
(
char
*
)
user_var_event
+
user_var_event
->
value
=
(
char
*
)
user_var_event
+
...
...
sql/log.cc
View file @
eac4388c
...
@@ -1559,6 +1559,7 @@ void MYSQL_LOG::start_union_events(THD *thd)
...
@@ -1559,6 +1559,7 @@ void MYSQL_LOG::start_union_events(THD *thd)
thd
->
binlog_evt_union
.
do_union
=
TRUE
;
thd
->
binlog_evt_union
.
do_union
=
TRUE
;
thd
->
binlog_evt_union
.
unioned_events
=
FALSE
;
thd
->
binlog_evt_union
.
unioned_events
=
FALSE
;
thd
->
binlog_evt_union
.
unioned_events_trans
=
FALSE
;
thd
->
binlog_evt_union
.
unioned_events_trans
=
FALSE
;
thd
->
binlog_evt_union
.
first_query_id
=
thd
->
query_id
;
}
}
void
MYSQL_LOG
::
stop_union_events
(
THD
*
thd
)
void
MYSQL_LOG
::
stop_union_events
(
THD
*
thd
)
...
@@ -1567,6 +1568,12 @@ void MYSQL_LOG::stop_union_events(THD *thd)
...
@@ -1567,6 +1568,12 @@ void MYSQL_LOG::stop_union_events(THD *thd)
thd
->
binlog_evt_union
.
do_union
=
FALSE
;
thd
->
binlog_evt_union
.
do_union
=
FALSE
;
}
}
bool
MYSQL_LOG
::
is_query_in_union
(
THD
*
thd
,
query_id_t
query_id_param
)
{
return
(
thd
->
binlog_evt_union
.
do_union
&&
query_id_param
>=
thd
->
binlog_evt_union
.
first_query_id
);
}
/*
/*
Write an event to the binary log
Write an event to the binary log
*/
*/
...
...
sql/sp_head.cc
View file @
eac4388c
...
@@ -689,10 +689,35 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
...
@@ -689,10 +689,35 @@ int cmp_splocal_locations(Item_splocal * const *a, Item_splocal * const *b)
* If this function invocation is done from a statement that is written
* If this function invocation is done from a statement that is written
into the binary log.
into the binary log.
* If there were any attempts to write events to the binary log during
* If there were any attempts to write events to the binary log during
function execution.
function execution (grep for start_union_events and stop_union_events)
If the answers are No and Yes, we write the function call into the binary
If the answers are No and Yes, we write the function call into the binary
log as "DO spfunc(<param1value>, <param2value>, ...)"
log as "DO spfunc(<param1value>, <param2value>, ...)"
4. Miscellaneous issues.
4.1 User variables.
When we call mysql_bin_log.write() for an SP statement, thd->user_var_events
must hold set<{var_name, value}> pairs for all user variables used during
the statement execution.
This set is produced by tracking user variable reads during statement
execution.
Fo SPs, this has the following implications:
1) thd->user_var_events may contain events from several SP statements and
needs to be valid after exection of these statements was finished. In
order to achieve that, we
* Allocate user_var_events array elements on appropriate mem_root (grep
for user_var_events_alloc).
* Use is_query_in_union() to determine if user_var_event is created.
2) We need to empty thd->user_var_events after we have wrote a function
call. This is currently done by making
reset_dynamic(&thd->user_var_events);
calls in several different places. (TODO cosider moving this into
mysql_bin_log.write() function)
*/
*/
...
@@ -908,6 +933,7 @@ int sp_head::execute(THD *thd)
...
@@ -908,6 +933,7 @@ int sp_head::execute(THD *thd)
/* Don't change NOW() in FUNCTION or TRIGGER */
/* Don't change NOW() in FUNCTION or TRIGGER */
if
(
!
thd
->
in_sub_stmt
)
if
(
!
thd
->
in_sub_stmt
)
thd
->
set_time
();
// Make current_time() et al work
thd
->
set_time
();
// Make current_time() et al work
/*
/*
We have to set thd->stmt_arena before executing the instruction
We have to set thd->stmt_arena before executing the instruction
to store in the instruction free_list all new items, created
to store in the instruction free_list all new items, created
...
@@ -915,6 +941,13 @@ int sp_head::execute(THD *thd)
...
@@ -915,6 +941,13 @@ int sp_head::execute(THD *thd)
items made during other permanent subquery transformations).
items made during other permanent subquery transformations).
*/
*/
thd
->
stmt_arena
=
i
;
thd
->
stmt_arena
=
i
;
/* will binlog this separately */
if
(
thd
->
prelocked_mode
==
NON_PRELOCKED
)
//TODO: change to event union?
{
thd
->
user_var_events_alloc
=
thd
->
mem_root
;
}
ret
=
i
->
execute
(
thd
,
&
ip
);
ret
=
i
->
execute
(
thd
,
&
ip
);
/*
/*
...
@@ -929,15 +962,6 @@ int sp_head::execute(THD *thd)
...
@@ -929,15 +962,6 @@ int sp_head::execute(THD *thd)
/* we should cleanup free_list and memroot, used by instruction */
/* we should cleanup free_list and memroot, used by instruction */
thd
->
free_items
();
thd
->
free_items
();
/*
FIXME: we must free user var events only if the routine is executed
in non-prelocked mode and statement-by-statement replication is used.
But if we don't free them now, the server crashes because user var
events are allocated in execute_mem_root. This is Bug#12637, and when
it's fixed, please add if (thd->options & OPTION_BIN_LOG) here.
*/
if
(
opt_bin_log
)
reset_dynamic
(
&
thd
->
user_var_events
);
free_root
(
&
execute_mem_root
,
MYF
(
0
));
free_root
(
&
execute_mem_root
,
MYF
(
0
));
/*
/*
...
@@ -1095,7 +1119,10 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
...
@@ -1095,7 +1119,10 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
binlog_save_options
=
thd
->
options
;
binlog_save_options
=
thd
->
options
;
need_binlog_call
=
mysql_bin_log
.
is_open
()
&&
(
thd
->
options
&
OPTION_BIN_LOG
);
need_binlog_call
=
mysql_bin_log
.
is_open
()
&&
(
thd
->
options
&
OPTION_BIN_LOG
);
if
(
need_binlog_call
)
if
(
need_binlog_call
)
{
reset_dynamic
(
&
thd
->
user_var_events
);
mysql_bin_log
.
start_union_events
(
thd
);
mysql_bin_log
.
start_union_events
(
thd
);
}
thd
->
options
&=
~
OPTION_BIN_LOG
;
thd
->
options
&=
~
OPTION_BIN_LOG
;
ret
=
execute
(
thd
);
ret
=
execute
(
thd
);
...
@@ -1129,6 +1156,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
...
@@ -1129,6 +1156,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, Item **resp)
"Invoked ROUTINE modified a transactional table but MySQL "
"Invoked ROUTINE modified a transactional table but MySQL "
"failed to reflect this change in the binary log"
);
"failed to reflect this change in the binary log"
);
}
}
reset_dynamic
(
&
thd
->
user_var_events
);
}
}
if
(
m_type
==
TYPE_ENUM_FUNCTION
&&
ret
==
0
)
if
(
m_type
==
TYPE_ENUM_FUNCTION
&&
ret
==
0
)
...
...
sql/sp_head.h
View file @
eac4388c
...
@@ -108,13 +108,14 @@ class sp_head :private Query_arena
...
@@ -108,13 +108,14 @@ class sp_head :private Query_arena
MEM_ROOT
main_mem_root
;
MEM_ROOT
main_mem_root
;
public:
public:
/* Possible values of m_flags */
/* Possible values of m_flags */
const
static
int
enum
{
HAS_RETURN
=
1
,
// For FUNCTIONs only: is set if has RETURN
HAS_RETURN
=
1
,
// For FUNCTIONs only: is set if has RETURN
IN_SIMPLE_CASE
=
2
,
// Is set if parsing a simple CASE
IN_SIMPLE_CASE
=
2
,
// Is set if parsing a simple CASE
IN_HANDLER
=
4
,
// Is set if the parser is in a handler body
IN_HANDLER
=
4
,
// Is set if the parser is in a handler body
MULTI_RESULTS
=
8
,
// Is set if a procedure with SELECT(s)
MULTI_RESULTS
=
8
,
// Is set if a procedure with SELECT(s)
CONTAINS_DYNAMIC_SQL
=
16
,
// Is set if a procedure with PREPARE/EXECUTE
CONTAINS_DYNAMIC_SQL
=
16
,
// Is set if a procedure with PREPARE/EXECUTE
IS_INVOKED
=
32
;
// Is set if this sp_head is being used.
IS_INVOKED
=
32
// Is set if this sp_head is being used.
};
int
m_type
;
// TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
int
m_type
;
// TYPE_ENUM_FUNCTION or TYPE_ENUM_PROCEDURE
uint
m_flags
;
// Boolean attributes of a stored routine
uint
m_flags
;
// Boolean attributes of a stored routine
...
...
sql/sql_class.h
View file @
eac4388c
...
@@ -313,6 +313,7 @@ class MYSQL_LOG: public TC_LOG
...
@@ -313,6 +313,7 @@ class MYSQL_LOG: public TC_LOG
void
start_union_events
(
THD
*
thd
);
void
start_union_events
(
THD
*
thd
);
void
stop_union_events
(
THD
*
thd
);
void
stop_union_events
(
THD
*
thd
);
bool
is_query_in_union
(
THD
*
thd
,
query_id_t
query_id_param
);
/*
/*
v stands for vector
v stands for vector
...
@@ -1303,8 +1304,9 @@ class THD :public Statement,
...
@@ -1303,8 +1304,9 @@ class THD :public Statement,
/* variables.transaction_isolation is reset to this after each commit */
/* variables.transaction_isolation is reset to this after each commit */
enum_tx_isolation
session_tx_isolation
;
enum_tx_isolation
session_tx_isolation
;
enum_check_fields
count_cuted_fields
;
enum_check_fields
count_cuted_fields
;
/* for user variables replication*/
DYNAMIC_ARRAY
user_var_events
;
DYNAMIC_ARRAY
user_var_events
;
/* For user variables replication */
MEM_ROOT
*
user_var_events_alloc
;
/* Allocate above array elements here */
enum
killed_state
{
NOT_KILLED
=
0
,
KILL_BAD_DATA
=
1
,
KILL_CONNECTION
=
ER_SERVER_SHUTDOWN
,
KILL_QUERY
=
ER_QUERY_INTERRUPTED
};
enum
killed_state
{
NOT_KILLED
=
0
,
KILL_BAD_DATA
=
1
,
KILL_CONNECTION
=
ER_SERVER_SHUTDOWN
,
KILL_QUERY
=
ER_QUERY_INTERRUPTED
};
killed_state
volatile
killed
;
killed_state
volatile
killed
;
...
@@ -1366,6 +1368,12 @@ class THD :public Statement,
...
@@ -1366,6 +1368,12 @@ class THD :public Statement,
mysql_bin_log.start_union_events() call.
mysql_bin_log.start_union_events() call.
*/
*/
bool
unioned_events_trans
;
bool
unioned_events_trans
;
/*
'queries' (actually SP statements) that run under inside this binlog
union have thd->query_id >= first_query_id.
*/
query_id_t
first_query_id
;
}
binlog_evt_union
;
}
binlog_evt_union
;
THD
();
THD
();
...
...
sql/sql_parse.cc
View file @
eac4388c
...
@@ -5162,7 +5162,10 @@ void mysql_reset_thd_for_next_command(THD *thd)
...
@@ -5162,7 +5162,10 @@ void mysql_reset_thd_for_next_command(THD *thd)
if
(
!
thd
->
in_sub_stmt
)
if
(
!
thd
->
in_sub_stmt
)
{
{
if
(
opt_bin_log
)
if
(
opt_bin_log
)
{
reset_dynamic
(
&
thd
->
user_var_events
);
reset_dynamic
(
&
thd
->
user_var_events
);
thd
->
user_var_events_alloc
=
thd
->
mem_root
;
}
thd
->
clear_error
();
thd
->
clear_error
();
thd
->
total_warn_count
=
0
;
// Warnings for this query
thd
->
total_warn_count
=
0
;
// Warnings for this query
thd
->
rand_used
=
0
;
thd
->
rand_used
=
0
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment