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
6a354b1b
Commit
6a354b1b
authored
Jan 31, 2005
by
acurtis@pcgem.rdg.cyberkinetica.com
Browse files
Options
Browse Files
Download
Plain Diff
Bug#7011
Merge from 4.0
parents
d8f467cf
500fbf5c
Changes
6
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
196 additions
and
20 deletions
+196
-20
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
+4
-0
sql/sql_parse.cc
sql/sql_parse.cc
+81
-0
sql/sql_update.cc
sql/sql_update.cc
+35
-20
No files found.
mysql-test/r/rpl_multi_update2.result
0 → 100644
View file @
6a354b1b
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 @
6a354b1b
--replicate-ignore-table=nothing.sensible
mysql-test/t/rpl_multi_update2.test
0 → 100644
View file @
6a354b1b
# 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 @
6a354b1b
...
@@ -564,6 +564,10 @@ int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
...
@@ -564,6 +564,10 @@ int mysql_multi_update(THD *thd, TABLE_LIST *table_list,
COND
*
conds
,
ulong
options
,
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
,
bool
ignore
,
enum
enum_duplicates
handle_duplicates
,
bool
ignore
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
);
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
);
int
mysql_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
List
<
Item
>
*
fields
,
SELECT_LEX
*
select_lex
);
int
mysql_prepare_insert
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
int
mysql_prepare_insert
(
THD
*
thd
,
TABLE_LIST
*
table_list
,
TABLE_LIST
*
insert_table_list
,
TABLE
*
table
,
TABLE_LIST
*
insert_table_list
,
TABLE
*
table
,
List
<
Item
>
&
fields
,
List_item
*
values
,
List
<
Item
>
&
fields
,
List_item
*
values
,
...
...
sql/sql_parse.cc
View file @
6a354b1b
...
@@ -52,6 +52,8 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
...
@@ -52,6 +52,8 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
#endif
#endif
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_multi_update_lock
(
THD
*
thd
,
TABLE_LIST
*
tables
,
List
<
Item
>
*
fields
,
SELECT_LEX
*
select_lex
);
static
void
remove_escape
(
char
*
name
);
static
void
remove_escape
(
char
*
name
);
static
void
refresh_status
(
void
);
static
void
refresh_status
(
void
);
static
bool
append_file_to_dir
(
THD
*
thd
,
const
char
**
filename_ptr
,
static
bool
append_file_to_dir
(
THD
*
thd
,
const
char
**
filename_ptr
,
...
@@ -1883,6 +1885,8 @@ mysql_execute_command(THD *thd)
...
@@ -1883,6 +1885,8 @@ mysql_execute_command(THD *thd)
{
{
int
res
=
0
;
int
res
=
0
;
LEX
*
lex
=
thd
->
lex
;
LEX
*
lex
=
thd
->
lex
;
bool
slave_fake_lock
=
0
;
MYSQL_LOCK
*
fake_prev_lock
=
0
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
SELECT_LEX
*
select_lex
=
&
lex
->
select_lex
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
TABLE_LIST
*
tables
=
(
TABLE_LIST
*
)
select_lex
->
table_list
.
first
;
SELECT_LEX_UNIT
*
unit
=
&
lex
->
unit
;
SELECT_LEX_UNIT
*
unit
=
&
lex
->
unit
;
...
@@ -1900,6 +1904,23 @@ mysql_execute_command(THD *thd)
...
@@ -1900,6 +1904,23 @@ mysql_execute_command(THD *thd)
#ifdef HAVE_REPLICATION
#ifdef HAVE_REPLICATION
if
(
thd
->
slave_thread
)
if
(
thd
->
slave_thread
)
{
{
if
(
lex
->
sql_command
==
SQLCOM_UPDATE_MULTI
)
{
DBUG_PRINT
(
"info"
,(
"need faked locked tables"
));
if
(
check_multi_update_lock
(
thd
,
tables
,
&
select_lex
->
item_list
,
select_lex
))
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
...
@@ -3582,6 +3603,14 @@ purposes internal to the MySQL server", MYF(0));
...
@@ -3582,6 +3603,14 @@ purposes internal to the MySQL server", MYF(0));
send_error
(
thd
,
thd
->
killed
?
ER_SERVER_SHUTDOWN
:
0
);
send_error
(
thd
,
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
;
}
}
...
@@ -5012,6 +5041,58 @@ bool check_simple_select()
...
@@ -5012,6 +5041,58 @@ 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
,
SELECT_LEX
*
select_lex
)
{
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_access
(
thd
,
UPDATE_ACL
,
table
->
db
,
&
table
->
grant
.
privilege
,
0
,
1
)
||
(
grant_option
&&
check_grant
(
thd
,
UPDATE_ACL
,
table
,
0
,
1
,
1
)))
&&
check_one_table_access
(
thd
,
SELECT_ACL
,
table
))
goto
error
;
table
->
next
=
save
;
}
if
(
mysql_multi_update_lock
(
thd
,
tables
,
fields
,
select_lex
))
goto
error
;
res
=
0
;
error:
DBUG_RETURN
(
res
);
}
Comp_creator
*
comp_eq_creator
(
bool
invert
)
Comp_creator
*
comp_eq_creator
(
bool
invert
)
{
{
...
...
sql/sql_update.cc
View file @
6a354b1b
...
@@ -464,30 +464,23 @@ static table_map get_table_map(List<Item> *items)
...
@@ -464,30 +464,23 @@ 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
,
SELECT_LEX
*
select_lex
)
COND
*
conds
,
ulong
options
,
enum
enum_duplicates
handle_duplicates
,
bool
ignore
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
)
{
{
int
res
;
int
res
;
multi_update
*
result
;
TABLE_LIST
*
tl
;
TABLE_LIST
*
tl
;
TABLE_LIST
*
update_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
TABLE_LIST
*
update_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
List
<
Item
>
total_list
;
const
bool
using_lock_tables
=
thd
->
locked_tables
!=
0
;
const
bool
using_lock_tables
=
thd
->
locked_tables
!=
0
;
bool
initialized_dervied
=
0
;
bool
initialized_dervied
=
0
;
DBUG_ENTER
(
"mysql_multi_update"
);
DBUG_ENTER
(
"mysql_multi_update_lock"
);
select_lex
->
select_limit
=
HA_POS_ERROR
;
/*
/*
The following loop is here to to ensure that we only lock tables
The following loop is here to to ensure that we only lock tables
...
@@ -593,7 +586,7 @@ int mysql_multi_update(THD *thd,
...
@@ -593,7 +586,7 @@ int mysql_multi_update(THD *thd,
(
grant_option
&&
check_grant
(
thd
,
wants
,
tl
,
0
,
0
,
0
)))
(
grant_option
&&
check_grant
(
thd
,
wants
,
tl
,
0
,
0
,
0
)))
{
{
tl
->
next
=
save
;
tl
->
next
=
save
;
DBUG_RETURN
(
0
);
DBUG_RETURN
(
1
);
}
}
tl
->
next
=
save
;
tl
->
next
=
save
;
}
}
...
@@ -616,11 +609,7 @@ int mysql_multi_update(THD *thd,
...
@@ -616,11 +609,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
,
table_count
);
res
=
lock_tables
(
thd
,
table_list
,
table_count
);
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
...
@@ -652,6 +641,32 @@ int mysql_multi_update(THD *thd,
...
@@ -652,6 +641,32 @@ 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
,
bool
ignore
,
SELECT_LEX_UNIT
*
unit
,
SELECT_LEX
*
select_lex
)
{
int
res
;
TABLE_LIST
*
tl
;
TABLE_LIST
*
update_list
=
(
TABLE_LIST
*
)
thd
->
lex
->
select_lex
.
table_list
.
first
;
List
<
Item
>
total_list
;
multi_update
*
result
;
DBUG_ENTER
(
"mysql_multi_update"
);
if
((
res
=
mysql_multi_update_lock
(
thd
,
table_list
,
fields
,
select_lex
)))
DBUG_RETURN
(
res
);
/* Setup timestamp handling */
/* Setup timestamp handling */
for
(
tl
=
update_list
;
tl
;
tl
=
tl
->
next
)
for
(
tl
=
update_list
;
tl
;
tl
=
tl
->
next
)
{
{
...
...
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