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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
500fbf5c
Commit
500fbf5c
authored
Jan 30, 2005
by
acurtis@pcgem.rdg.cyberkinetica.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Bug#7011
Fix replication for multi-update new test - rpl_multi_update2
parent
f003fb1f
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
192 additions
and
19 deletions
+192
-19
mysql-test/r/rpl_multi_update2.result
mysql-test/r/rpl_multi_update2.result
+42
-0
mysql-test/t/rpl_multi_update2-slave.opt
mysql-test/t/rpl_multi_update2-slave.opt
+1
-0
mysql-test/t/rpl_multi_update2.test
mysql-test/t/rpl_multi_update2.test
+33
-0
sql/mysql_priv.h
sql/mysql_priv.h
+3
-0
sql/sql_parse.cc
sql/sql_parse.cc
+80
-1
sql/sql_update.cc
sql/sql_update.cc
+33
-18
No files found.
mysql-test/r/rpl_multi_update2.result
0 → 100644
View file @
500fbf5c
slave stop;
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;
slave start;
CREATE TABLE t1 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
CREATE TABLE t2 (
a int unsigned not null auto_increment primary key,
b int unsigned
) TYPE=MyISAM;
INSERT INTO t1 VALUES (NULL, 0);
INSERT INTO t1 SELECT NULL, 0 FROM t1;
INSERT INTO t2 VALUES (NULL, 0), (NULL,1);
SELECT * FROM t1 ORDER BY a;
a b
1 0
2 0
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
UPDATE t1, t2 SET t1.b = (t2.b+4) WHERE t1.a = t2.a;
SELECT * FROM t1 ORDER BY a;
a b
1 4
2 5
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
SELECT * FROM t1 ORDER BY a;
a b
1 4
2 5
SELECT * FROM t2 ORDER BY a;
a b
1 0
2 1
mysql-test/t/rpl_multi_update2-slave.opt
0 → 100644
View file @
500fbf5c
--replicate-ignore-table=nothing.sensible
mysql-test/t/rpl_multi_update2.test
0 → 100644
View file @
500fbf5c
# Let's verify that multi-update is not always skipped by slave if
# some replicate-* rules exist.
# (BUG#7011)
source
include
/
master
-
slave
.
inc
;
CREATE
TABLE
t1
(
a
int
unsigned
not
null
auto_increment
primary
key
,
b
int
unsigned
)
TYPE
=
MyISAM
;
CREATE
TABLE
t2
(
a
int
unsigned
not
null
auto_increment
primary
key
,
b
int
unsigned
)
TYPE
=
MyISAM
;
INSERT
INTO
t1
VALUES
(
NULL
,
0
);
INSERT
INTO
t1
SELECT
NULL
,
0
FROM
t1
;
INSERT
INTO
t2
VALUES
(
NULL
,
0
),
(
NULL
,
1
);
SELECT
*
FROM
t1
ORDER
BY
a
;
SELECT
*
FROM
t2
ORDER
BY
a
;
UPDATE
t1
,
t2
SET
t1
.
b
=
(
t2
.
b
+
4
)
WHERE
t1
.
a
=
t2
.
a
;
SELECT
*
FROM
t1
ORDER
BY
a
;
SELECT
*
FROM
t2
ORDER
BY
a
;
save_master_pos
;
connection
slave
;
sync_with_master
;
SELECT
*
FROM
t1
ORDER
BY
a
;
SELECT
*
FROM
t2
ORDER
BY
a
;
sql/mysql_priv.h
View file @
500fbf5c
...
@@ -469,6 +469,9 @@ int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
...
@@ -469,6 +469,9 @@ int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
List
<
Item
>
&
values
,
COND
*
conds
,
List
<
Item
>
&
values
,
COND
*
conds
,
ORDER
*
order
,
ha_rows
limit
,
ORDER
*
order
,
ha_rows
limit
,
enum
enum_duplicates
handle_duplicates
);
enum
enum_duplicates
handle_duplicates
);
int
mysql_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
);
int
mysql_multi_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
int
mysql_multi_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
COND
*
conds
,
ulong
options
,
COND
*
conds
,
ulong
options
,
...
...
sql/sql_parse.cc
View file @
500fbf5c
...
@@ -56,6 +56,8 @@ static int check_for_max_user_connections(USER_CONN *uc);
...
@@ -56,6 +56,8 @@ static int check_for_max_user_connections(USER_CONN *uc);
static
void
decrease_user_connections
(
USER_CONN
*
uc
);
static
void
decrease_user_connections
(
USER_CONN
*
uc
);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_db_used
(
THD
*
thd
,
TABLE_LIST
*
tables
);
static
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
tables
);
static
bool
check_merge_table_access
(
THD
*
thd
,
char
*
db
,
TABLE_LIST
*
tables
);
static
bool
check_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
*
fields
);
static
void
mysql_init_query
(
THD
*
thd
);
static
void
mysql_init_query
(
THD
*
thd
);
static
void
remove_escape
(
char
*
name
);
static
void
remove_escape
(
char
*
name
);
static
void
refresh_status
(
void
);
static
void
refresh_status
(
void
);
...
@@ -1338,10 +1340,28 @@ mysql_execute_command(void)
...
@@ -1338,10 +1340,28 @@ mysql_execute_command(void)
LEX
*
lex
=
&
thd
->
lex
;
LEX
*
lex
=
&
thd
->
lex
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
lex
->
select_lex
.
table_list
.
first
;
SELECT_LEX
*
select_lex
=
lex
->
select
;
SELECT_LEX
*
select_lex
=
lex
->
select
;
bool
slave_fake_lock
=
0
;
MYSQL_LOCK
*
fake_prev_lock
=
0
;
DBUG_ENTER
(
"mysql_execute_command"
);
DBUG_ENTER
(
"mysql_execute_command"
);
if
(
thd
->
slave_thread
)
if
(
thd
->
slave_thread
)
{
{
if
(
lex
->
sql_command
==
SQLCOM_MULTI_UPDATE
)
{
DBUG_PRINT
(
"info"
,(
"need faked locked tables"
));
if
(
check_multi_update_lock
(
thd
,
tables
,
&
select_lex
->
item_list
))
goto
error
;
/* Fix for replication, the tables are opened and locked,
now we pretend that we have performed a LOCK TABLES action */
fake_prev_lock
=
thd
->
locked_tables
;
if
(
thd
->
lock
)
thd
->
locked_tables
=
thd
->
lock
;
thd
->
lock
=
0
;
slave_fake_lock
=
1
;
}
/*
/*
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
...
@@ -1949,7 +1969,7 @@ mysql_execute_command(void)
...
@@ -1949,7 +1969,7 @@ mysql_execute_command(void)
if
(
select_lex
->
item_list
.
elements
!=
lex
->
value_list
.
elements
)
if
(
select_lex
->
item_list
.
elements
!=
lex
->
value_list
.
elements
)
{
{
send_error
(
&
thd
->
net
,
ER_WRONG_VALUE_COUNT
);
send_error
(
&
thd
->
net
,
ER_WRONG_VALUE_COUNT
);
DBUG_VOID_RETURN
;
goto
error
;
}
}
{
{
const
char
*
msg
=
0
;
const
char
*
msg
=
0
;
...
@@ -2641,6 +2661,14 @@ mysql_execute_command(void)
...
@@ -2641,6 +2661,14 @@ mysql_execute_command(void)
send_error
(
&
thd
->
net
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
send_error
(
&
thd
->
net
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
error:
error:
if
(
unlikely
(
slave_fake_lock
))
{
DBUG_PRINT
(
"info"
,(
"undoing faked lock"
));
thd
->
lock
=
thd
->
locked_tables
;
thd
->
locked_tables
=
fake_prev_lock
;
if
(
thd
->
lock
==
thd
->
locked_tables
)
thd
->
lock
=
0
;
}
DBUG_VOID_RETURN
;
DBUG_VOID_RETURN
;
}
}
...
@@ -3907,3 +3935,54 @@ bool check_simple_select()
...
@@ -3907,3 +3935,54 @@ bool check_simple_select()
}
}
return
0
;
return
0
;
}
}
/*
Setup locking for multi-table updates. Used by the replication slave.
Replication slave SQL thread examines (all_tables_not_ok()) the
locking state of referenced tables to determine if the query has to
be executed or ignored. Since in multi-table update, the
'default' lock is read-only, this lock is corrected early enough by
calling this function, before the slave decides to execute/ignore.
SYNOPSIS
check_multi_update_lock()
thd Current thread
tables List of user-supplied tables
fields List of fields requiring update
RETURN VALUES
0 ok
1 error
*/
static
bool
check_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
*
fields
)
{
bool
res
=
1
;
TABLE_LIST
*
table
;
DBUG_ENTER
(
"check_multi_update_lock"
);
if
(
check_db_used
(
thd
,
tables
))
goto
error
;
/*
Ensure that we have UPDATE or SELECT privilege for each table
The exact privilege is checked in mysql_multi_update()
*/
for
(
table
=
tables
;
table
;
table
=
table
->
next
)
{
TABLE_LIST
*
save
=
table
->
next
;
table
->
next
=
0
;
if
(
check_one_table_access
(
thd
,
UPDATE_ACL
,
table
,
1
)
&&
check_one_table_access
(
thd
,
SELECT_ACL
,
table
,
0
))
goto
error
;
table
->
next
=
save
;
}
if
(
mysql_multi_update_lock
(
thd
,
tables
,
fields
))
goto
error
;
res
=
0
;
error:
DBUG_RETURN
(
res
);
}
sql/sql_update.cc
View file @
500fbf5c
...
@@ -403,26 +403,20 @@ static table_map get_table_map(List<Item> *items)
...
@@ -403,26 +403,20 @@ static table_map get_table_map(List<Item> *items)
}
}
/*
/*
Setup multi-update handling and call SELECT to do the join
Prepare tables for multi-update
Analyse which tables need specific privileges and perform locking
as required
*/
*/
int
mysql_multi_update
(
THD
*
thd
,
int
mysql_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
fields
)
List
<
Item
>
*
values
,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
)
{
{
int
res
;
int
res
;
multi_update
*
result
;
TABLE_LIST
*
tl
;
TABLE_LIST
*
tl
;
const
bool
using_lock_tables
=
thd
->
locked_tables
!=
0
;
const
bool
using_lock_tables
=
thd
->
locked_tables
!=
0
;
DBUG_ENTER
(
"mysql_multi_update"
);
DBUG_ENTER
(
"mysql_multi_update_lock"
);
thd
->
select_limit
=
HA_POS_ERROR
;
for
(;;)
for
(;;)
{
{
...
@@ -490,7 +484,7 @@ int mysql_multi_update(THD *thd,
...
@@ -490,7 +484,7 @@ int mysql_multi_update(THD *thd,
(
grant_option
&&
check_grant
(
thd
,
wants
,
tl
,
0
,
0
)))
(
grant_option
&&
check_grant
(
thd
,
wants
,
tl
,
0
,
0
)))
{
{
tl
->
next
=
save
;
tl
->
next
=
save
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
1
);
}
}
tl
->
next
=
save
;
tl
->
next
=
save
;
}
}
...
@@ -498,11 +492,7 @@ int mysql_multi_update(THD *thd,
...
@@ -498,11 +492,7 @@ int mysql_multi_update(THD *thd,
/* Relock the tables with the correct modes */
/* Relock the tables with the correct modes */
res
=
lock_tables
(
thd
,
table_list
);
res
=
lock_tables
(
thd
,
table_list
);
if
(
using_lock_tables
)
if
(
using_lock_tables
)
{
if
(
res
)
DBUG_RETURN
(
res
);
break
;
// Don't have to do setup_field()
break
;
// Don't have to do setup_field()
}
/*
/*
We must setup fields again as the file may have been reopened
We must setup fields again as the file may have been reopened
...
@@ -535,6 +525,31 @@ int mysql_multi_update(THD *thd,
...
@@ -535,6 +525,31 @@ int mysql_multi_update(THD *thd,
*/
*/
close_thread_tables
(
thd
);
close_thread_tables
(
thd
);
}
}
DBUG_RETURN
(
res
);
}
/*
Setup multi-update handling and call SELECT to do the join
*/
int
mysql_multi_update
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
List
<
Item
>
*
values
,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
)
{
int
res
;
TABLE_LIST
*
tl
;
multi_update
*
result
;
DBUG_ENTER
(
"mysql_multi_update"
);
thd
->
select_limit
=
HA_POS_ERROR
;
if
((
res
=
mysql_multi_update_lock
(
thd
,
table_list
,
fields
)))
DBUG_RETURN
(
res
);
/*
/*
Count tables and setup timestamp handling
Count tables and setup timestamp handling
...
...
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