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
dc2a2e15
Commit
dc2a2e15
authored
Mar 12, 2010
by
Alexander Nozdrin
Browse files
Options
Browse Files
Download
Plain Diff
Auto-merge from mysql-trunk-bugfixing.
parents
9ad6cb15
30cb1779
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
363 additions
and
59 deletions
+363
-59
mysql-test/r/read_only_innodb.result
mysql-test/r/read_only_innodb.result
+171
-0
mysql-test/t/read_only_innodb.test
mysql-test/t/read_only_innodb.test
+146
-0
sql/lock.cc
sql/lock.cc
+46
-59
No files found.
mysql-test/r/read_only_innodb.result
View file @
dc2a2e15
...
@@ -46,3 +46,174 @@ UNLOCK TABLES;
...
@@ -46,3 +46,174 @@ UNLOCK TABLES;
DROP TABLE t1;
DROP TABLE t1;
DROP USER test@localhost;
DROP USER test@localhost;
echo End of 5.1 tests
echo End of 5.1 tests
#
# Bug#33669: Transactional temporary tables do not work under --read-only
#
DROP DATABASE IF EXISTS db1;
# Setup user and tables
CREATE USER bug33669@localhost;
CREATE DATABASE db1;
CREATE TABLE db1.t1 (a INT) ENGINE=INNODB;
CREATE TABLE db1.t2 (a INT) ENGINE=INNODB;
INSERT INTO db1.t1 VALUES (1);
INSERT INTO db1.t2 VALUES (2);
GRANT CREATE TEMPORARY TABLES, DROP, INSERT, DELETE, UPDATE,
SELECT, LOCK TABLES ON db1.* TO bug33669@localhost;
SET GLOBAL READ_ONLY = ON;
# Connection con1 (user bug33669):
# Create, insert and drop temporary table:
CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB;
INSERT INTO temp VALUES (1);
DROP TABLE temp;
# Lock base tables and use temporary table:
CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB;
LOCK TABLES t1 READ, t2 READ;
SELECT * FROM t1;
a
1
INSERT INTO temp values (1);
SELECT * FROM t2;
a
2
UNLOCK TABLES;
DROP TABLE temp;
# Transaction
BEGIN;
SELECT * FROM t1;
a
1
CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB;
INSERT INTO t1 VALUES (1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
INSERT INTO temp VALUES (1);
SELECT * FROM t2;
a
2
ROLLBACK;
SELECT * FROM temp;
a
DROP TABLE temp;
# Lock base table as READ and temporary table as WRITE:
CREATE TEMPORARY TABLE temp (a INT) ENGINE=INNODB;
LOCK TABLES t1 READ, temp WRITE;
SELECT * FROM t1;
a
1
SELECT * FROM temp;
a
INSERT INTO t1 VALUES (1);
ERROR HY000: The MySQL server is running with the --read-only option so it cannot execute this statement
INSERT INTO temp VALUES (1);
DROP TABLE temp;
UNLOCK TABLES;
# Lock temporary table that shadows a base table:
CREATE TEMPORARY TABLE t1 (a INT) ENGINE=INNODB;
LOCK TABLES t1 WRITE;
DROP TABLE t1;
SELECT * FROM t1;
ERROR HY000: Table 't1' was not locked with LOCK TABLES
# INSERT SELECT from base table into temporary table:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
BEGIN;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
a
1
10
SELECT * FROM temp2 ORDER BY a;
a
2
10
ROLLBACK;
SELECT * FROM temp1,temp2;
a a
LOCK TABLES t1 READ, t2 READ;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
a
1
10
SELECT * FROM temp2 ORDER BY a;
a
2
10
UNLOCK TABLES;
DELETE temp1, temp2 FROM temp1, temp2;
INSERT INTO temp1 VALUES (10);
INSERT INTO temp2 VALUES (10);
INSERT INTO temp1 SELECT * FROM t1;
INSERT INTO temp2 SELECT * FROM t2;
SELECT * FROM temp1 ORDER BY a;
a
1
10
SELECT * FROM temp2 ORDER BY a;
a
2
10
DROP TABLE temp1, temp2;
# INSERT and INSERT SELECT that uses subqueries:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
INSERT INTO temp1 (a) VALUES ((SELECT MAX(a) FROM t1));
LOCK TABLES t2 READ;
INSERT INTO temp2 (a) VALUES ((SELECT MAX(a) FROM t2));
UNLOCK TABLES;
LOCK TABLES t1 READ, t2 READ;
INSERT INTO temp1 SELECT * FROM t1 WHERE a < (SELECT MAX(a) FROM t2);
INSERT INTO temp2 SELECT * FROM t2 WHERE a > (SELECT MAX(a) FROM t1);
UNLOCK TABLES;
INSERT INTO temp1 SELECT * FROM t1 WHERE a < (SELECT MAX(a) FROM t2);
INSERT INTO temp2 SELECT * FROM t2 WHERE a > (SELECT MAX(a) FROM t1);
SELECT * FROM temp1 ORDER BY a;
a
1
1
1
SELECT * FROM temp2 ORDER BY a;
a
2
2
2
DROP TABLE temp1, temp2;
# Multiple table update:
CREATE TEMPORARY TABLE temp1 (a INT) ENGINE=INNODB;
CREATE TEMPORARY TABLE temp2 LIKE temp1;
INSERT INTO temp1 VALUES (1),(2);
INSERT INTO temp2 VALUES (3),(4);
UPDATE temp1,temp2 SET temp1.a = 5, temp2.a = 10;
SELECT * FROM temp1, temp2;
a a
5 10
5 10
5 10
5 10
DROP TABLE temp1, temp2;
# Disconnect and cleanup
SET GLOBAL READ_ONLY = OFF;
DROP USER bug33669@localhost;
DROP DATABASE db1;
mysql-test/t/read_only_innodb.test
View file @
dc2a2e15
...
@@ -83,3 +83,149 @@ DROP USER test@localhost;
...
@@ -83,3 +83,149 @@ DROP USER test@localhost;
disconnect
con1
;
disconnect
con1
;
--
echo
echo
End
of
5.1
tests
--
echo
echo
End
of
5.1
tests
--
echo
#
--
echo
# Bug#33669: Transactional temporary tables do not work under --read-only
--
echo
#
--
disable_warnings
DROP
DATABASE
IF
EXISTS
db1
;
--
enable_warnings
--
echo
# Setup user and tables
CREATE
USER
bug33669
@
localhost
;
CREATE
DATABASE
db1
;
CREATE
TABLE
db1
.
t1
(
a
INT
)
ENGINE
=
INNODB
;
CREATE
TABLE
db1
.
t2
(
a
INT
)
ENGINE
=
INNODB
;
INSERT
INTO
db1
.
t1
VALUES
(
1
);
INSERT
INTO
db1
.
t2
VALUES
(
2
);
GRANT
CREATE
TEMPORARY
TABLES
,
DROP
,
INSERT
,
DELETE
,
UPDATE
,
SELECT
,
LOCK
TABLES
ON
db1
.*
TO
bug33669
@
localhost
;
SET
GLOBAL
READ_ONLY
=
ON
;
connect
(
con1
,
localhost
,
bug33669
,,
db1
);
--
echo
# Connection con1 (user bug33669):
--
echo
--
echo
# Create, insert and drop temporary table:
--
echo
CREATE
TEMPORARY
TABLE
temp
(
a
INT
)
ENGINE
=
INNODB
;
INSERT
INTO
temp
VALUES
(
1
);
DROP
TABLE
temp
;
--
echo
--
echo
# Lock base tables and use temporary table:
--
echo
CREATE
TEMPORARY
TABLE
temp
(
a
INT
)
ENGINE
=
INNODB
;
LOCK
TABLES
t1
READ
,
t2
READ
;
SELECT
*
FROM
t1
;
INSERT
INTO
temp
values
(
1
);
SELECT
*
FROM
t2
;
UNLOCK
TABLES
;
DROP
TABLE
temp
;
--
echo
--
echo
# Transaction
--
echo
BEGIN
;
SELECT
*
FROM
t1
;
CREATE
TEMPORARY
TABLE
temp
(
a
INT
)
ENGINE
=
INNODB
;
--
error
ER_OPTION_PREVENTS_STATEMENT
INSERT
INTO
t1
VALUES
(
1
);
INSERT
INTO
temp
VALUES
(
1
);
SELECT
*
FROM
t2
;
ROLLBACK
;
SELECT
*
FROM
temp
;
DROP
TABLE
temp
;
--
echo
--
echo
# Lock base table as READ and temporary table as WRITE:
--
echo
CREATE
TEMPORARY
TABLE
temp
(
a
INT
)
ENGINE
=
INNODB
;
LOCK
TABLES
t1
READ
,
temp
WRITE
;
SELECT
*
FROM
t1
;
SELECT
*
FROM
temp
;
--
error
ER_OPTION_PREVENTS_STATEMENT
INSERT
INTO
t1
VALUES
(
1
);
INSERT
INTO
temp
VALUES
(
1
);
DROP
TABLE
temp
;
UNLOCK
TABLES
;
--
echo
--
echo
# Lock temporary table that shadows a base table:
--
echo
CREATE
TEMPORARY
TABLE
t1
(
a
INT
)
ENGINE
=
INNODB
;
LOCK
TABLES
t1
WRITE
;
DROP
TABLE
t1
;
--
error
ER_TABLE_NOT_LOCKED
SELECT
*
FROM
t1
;
--
echo
--
echo
# INSERT SELECT from base table into temporary table:
--
echo
CREATE
TEMPORARY
TABLE
temp1
(
a
INT
)
ENGINE
=
INNODB
;
CREATE
TEMPORARY
TABLE
temp2
LIKE
temp1
;
BEGIN
;
INSERT
INTO
temp1
VALUES
(
10
);
INSERT
INTO
temp2
VALUES
(
10
);
INSERT
INTO
temp1
SELECT
*
FROM
t1
;
INSERT
INTO
temp2
SELECT
*
FROM
t2
;
SELECT
*
FROM
temp1
ORDER
BY
a
;
SELECT
*
FROM
temp2
ORDER
BY
a
;
ROLLBACK
;
SELECT
*
FROM
temp1
,
temp2
;
LOCK
TABLES
t1
READ
,
t2
READ
;
INSERT
INTO
temp1
VALUES
(
10
);
INSERT
INTO
temp2
VALUES
(
10
);
INSERT
INTO
temp1
SELECT
*
FROM
t1
;
INSERT
INTO
temp2
SELECT
*
FROM
t2
;
SELECT
*
FROM
temp1
ORDER
BY
a
;
SELECT
*
FROM
temp2
ORDER
BY
a
;
UNLOCK
TABLES
;
DELETE
temp1
,
temp2
FROM
temp1
,
temp2
;
INSERT
INTO
temp1
VALUES
(
10
);
INSERT
INTO
temp2
VALUES
(
10
);
INSERT
INTO
temp1
SELECT
*
FROM
t1
;
INSERT
INTO
temp2
SELECT
*
FROM
t2
;
SELECT
*
FROM
temp1
ORDER
BY
a
;
SELECT
*
FROM
temp2
ORDER
BY
a
;
DROP
TABLE
temp1
,
temp2
;
--
echo
--
echo
# INSERT and INSERT SELECT that uses subqueries:
CREATE
TEMPORARY
TABLE
temp1
(
a
INT
)
ENGINE
=
INNODB
;
CREATE
TEMPORARY
TABLE
temp2
LIKE
temp1
;
INSERT
INTO
temp1
(
a
)
VALUES
((
SELECT
MAX
(
a
)
FROM
t1
));
LOCK
TABLES
t2
READ
;
INSERT
INTO
temp2
(
a
)
VALUES
((
SELECT
MAX
(
a
)
FROM
t2
));
UNLOCK
TABLES
;
LOCK
TABLES
t1
READ
,
t2
READ
;
INSERT
INTO
temp1
SELECT
*
FROM
t1
WHERE
a
<
(
SELECT
MAX
(
a
)
FROM
t2
);
INSERT
INTO
temp2
SELECT
*
FROM
t2
WHERE
a
>
(
SELECT
MAX
(
a
)
FROM
t1
);
UNLOCK
TABLES
;
INSERT
INTO
temp1
SELECT
*
FROM
t1
WHERE
a
<
(
SELECT
MAX
(
a
)
FROM
t2
);
INSERT
INTO
temp2
SELECT
*
FROM
t2
WHERE
a
>
(
SELECT
MAX
(
a
)
FROM
t1
);
SELECT
*
FROM
temp1
ORDER
BY
a
;
SELECT
*
FROM
temp2
ORDER
BY
a
;
DROP
TABLE
temp1
,
temp2
;
--
echo
--
echo
# Multiple table update:
--
echo
CREATE
TEMPORARY
TABLE
temp1
(
a
INT
)
ENGINE
=
INNODB
;
CREATE
TEMPORARY
TABLE
temp2
LIKE
temp1
;
INSERT
INTO
temp1
VALUES
(
1
),(
2
);
INSERT
INTO
temp2
VALUES
(
3
),(
4
);
UPDATE
temp1
,
temp2
SET
temp1
.
a
=
5
,
temp2
.
a
=
10
;
SELECT
*
FROM
temp1
,
temp2
;
DROP
TABLE
temp1
,
temp2
;
--
echo
--
echo
# Disconnect and cleanup
--
echo
disconnect
con1
;
connection
default
;
SET
GLOBAL
READ_ONLY
=
OFF
;
DROP
USER
bug33669
@
localhost
;
DROP
DATABASE
db1
;
sql/lock.cc
View file @
dc2a2e15
...
@@ -89,8 +89,8 @@ extern HASH open_cache;
...
@@ -89,8 +89,8 @@ extern HASH open_cache;
#define GET_LOCK_UNLOCK 1
#define GET_LOCK_UNLOCK 1
#define GET_LOCK_STORE_LOCKS 2
#define GET_LOCK_STORE_LOCKS 2
static
MYSQL_LOCK
*
get_lock_data
(
THD
*
thd
,
TABLE
**
table
,
uint
count
,
static
MYSQL_LOCK
*
get_lock_data
(
THD
*
thd
,
TABLE
**
table
_ptr
,
uint
count
,
uint
flags
,
TABLE
**
write_locked
);
uint
flags
);
static
int
lock_external
(
THD
*
thd
,
TABLE
**
table
,
uint
count
);
static
int
lock_external
(
THD
*
thd
,
TABLE
**
table
,
uint
count
);
static
int
unlock_external
(
THD
*
thd
,
TABLE
**
table
,
uint
count
);
static
int
unlock_external
(
THD
*
thd
,
TABLE
**
table
,
uint
count
);
static
void
print_lock_error
(
int
error
,
const
char
*
);
static
void
print_lock_error
(
int
error
,
const
char
*
);
...
@@ -107,15 +107,18 @@ static int thr_lock_errno_to_mysql[]=
...
@@ -107,15 +107,18 @@ static int thr_lock_errno_to_mysql[]=
@param flags Lock flags
@param flags Lock flags
@return 0 if all the check passed, non zero if a check failed.
@return 0 if all the check passed, non zero if a check failed.
*/
*/
int
mysql_lock_tables_check
(
THD
*
thd
,
TABLE
**
tables
,
uint
count
,
uint
flags
)
static
int
lock_tables_check
(
THD
*
thd
,
TABLE
**
tables
,
uint
count
,
bool
*
write_lock_used
,
uint
flags
)
{
{
bool
log_table_write_query
;
uint
system_count
,
i
;
uint
system_count
;
bool
is_superuser
,
log_table_write_query
;
uint
i
;
DBUG_ENTER
(
"
mysql_
lock_tables_check"
);
DBUG_ENTER
(
"lock_tables_check"
);
system_count
=
0
;
system_count
=
0
;
*
write_lock_used
=
FALSE
;
is_superuser
=
thd
->
security_ctx
->
master_access
&
SUPER_ACL
;
log_table_write_query
=
(
is_log_table_write_query
(
thd
->
lex
->
sql_command
)
log_table_write_query
=
(
is_log_table_write_query
(
thd
->
lex
->
sql_command
)
||
((
flags
&
MYSQL_LOCK_PERF_SCHEMA
)
!=
0
));
||
((
flags
&
MYSQL_LOCK_PERF_SCHEMA
)
!=
0
));
...
@@ -148,10 +151,18 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
...
@@ -148,10 +151,18 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
}
}
}
}
if
((
t
->
s
->
table_category
==
TABLE_CATEGORY_SYSTEM
)
&&
if
(
t
->
reginfo
.
lock_type
>=
TL_WRITE_ALLOW_WRITE
)
(
t
->
reginfo
.
lock_type
>=
TL_WRITE_ALLOW_WRITE
))
{
{
system_count
++
;
*
write_lock_used
=
TRUE
;
if
(
t
->
s
->
table_category
==
TABLE_CATEGORY_SYSTEM
)
system_count
++
;
if
(
t
->
db_stat
&
HA_READ_ONLY
)
{
my_error
(
ER_OPEN_AS_READONLY
,
MYF
(
0
),
t
->
alias
);
DBUG_RETURN
(
1
);
}
}
}
/*
/*
...
@@ -172,6 +183,20 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
...
@@ -172,6 +183,20 @@ int mysql_lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
thd
->
mdl_context
.
is_lock_owner
(
MDL_key
::
TABLE
,
thd
->
mdl_context
.
is_lock_owner
(
MDL_key
::
TABLE
,
t
->
s
->
db
.
str
,
t
->
s
->
table_name
.
str
,
t
->
s
->
db
.
str
,
t
->
s
->
table_name
.
str
,
MDL_SHARED
)));
MDL_SHARED
)));
/*
Prevent modifications to base tables if READ_ONLY is activated.
In any case, read only does not apply to temporary tables.
*/
if
(
!
(
flags
&
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY
)
&&
!
t
->
s
->
tmp_table
)
{
if
(
t
->
reginfo
.
lock_type
>=
TL_WRITE_ALLOW_WRITE
&&
!
is_superuser
&&
opt_readonly
&&
!
thd
->
slave_thread
)
{
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--read-only"
);
DBUG_RETURN
(
1
);
}
}
}
}
/*
/*
...
@@ -267,15 +292,15 @@ static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
...
@@ -267,15 +292,15 @@ static void reset_lock_data_and_free(MYSQL_LOCK **mysql_lock)
MYSQL_LOCK
*
mysql_lock_tables
(
THD
*
thd
,
TABLE
**
tables
,
uint
count
,
MYSQL_LOCK
*
mysql_lock_tables
(
THD
*
thd
,
TABLE
**
tables
,
uint
count
,
uint
flags
,
bool
*
need_reopen
)
uint
flags
,
bool
*
need_reopen
)
{
{
MYSQL_LOCK
*
sql_lock
;
TABLE
*
write_lock_used
;
int
rc
;
int
rc
;
MYSQL_LOCK
*
sql_lock
;
bool
write_lock_used
;
DBUG_ENTER
(
"mysql_lock_tables"
);
DBUG_ENTER
(
"mysql_lock_tables"
);
*
need_reopen
=
FALSE
;
*
need_reopen
=
FALSE
;
if
(
mysql_lock_tables_check
(
thd
,
tables
,
count
,
flags
))
if
(
lock_tables_check
(
thd
,
tables
,
count
,
&
write_lock_used
,
flags
))
DBUG_RETURN
(
NULL
);
DBUG_RETURN
(
NULL
);
ulong
timeout
=
(
flags
&
MYSQL_LOCK_IGNORE_TIMEOUT
)
?
ulong
timeout
=
(
flags
&
MYSQL_LOCK_IGNORE_TIMEOUT
)
?
...
@@ -283,8 +308,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
...
@@ -283,8 +308,7 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
for
(;;)
for
(;;)
{
{
if
(
!
(
sql_lock
=
get_lock_data
(
thd
,
tables
,
count
,
GET_LOCK_STORE_LOCKS
,
if
(
!
(
sql_lock
=
get_lock_data
(
thd
,
tables
,
count
,
GET_LOCK_STORE_LOCKS
)))
&
write_lock_used
)))
break
;
break
;
if
(
global_read_lock
&&
write_lock_used
&&
if
(
global_read_lock
&&
write_lock_used
&&
...
@@ -308,21 +332,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
...
@@ -308,21 +332,6 @@ MYSQL_LOCK *mysql_lock_tables(THD *thd, TABLE **tables, uint count,
}
}
}
}
if
(
!
(
flags
&
MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY
)
&&
write_lock_used
&&
opt_readonly
&&
!
(
thd
->
security_ctx
->
master_access
&
SUPER_ACL
)
&&
!
thd
->
slave_thread
)
{
/*
Someone has issued SET GLOBAL READ_ONLY=1 and we want a write lock.
We do not wait for READ_ONLY=0, and fail.
*/
reset_lock_data_and_free
(
&
sql_lock
);
my_error
(
ER_OPTION_PREVENTS_STATEMENT
,
MYF
(
0
),
"--read-only"
);
break
;
}
thd_proc_info
(
thd
,
"System lock"
);
thd_proc_info
(
thd
,
"System lock"
);
DBUG_PRINT
(
"info"
,
(
"thd->proc_info %s"
,
thd
->
proc_info
));
DBUG_PRINT
(
"info"
,
(
"thd->proc_info %s"
,
thd
->
proc_info
));
if
(
sql_lock
->
table_count
&&
lock_external
(
thd
,
sql_lock
->
table
,
if
(
sql_lock
->
table_count
&&
lock_external
(
thd
,
sql_lock
->
table
,
...
@@ -459,9 +468,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
...
@@ -459,9 +468,7 @@ void mysql_unlock_tables(THD *thd, MYSQL_LOCK *sql_lock)
void
mysql_unlock_some_tables
(
THD
*
thd
,
TABLE
**
table
,
uint
count
)
void
mysql_unlock_some_tables
(
THD
*
thd
,
TABLE
**
table
,
uint
count
)
{
{
MYSQL_LOCK
*
sql_lock
;
MYSQL_LOCK
*
sql_lock
;
TABLE
*
write_lock_used
;
if
((
sql_lock
=
get_lock_data
(
thd
,
table
,
count
,
GET_LOCK_UNLOCK
)))
if
((
sql_lock
=
get_lock_data
(
thd
,
table
,
count
,
GET_LOCK_UNLOCK
,
&
write_lock_used
)))
mysql_unlock_tables
(
thd
,
sql_lock
);
mysql_unlock_tables
(
thd
,
sql_lock
);
}
}
...
@@ -603,9 +610,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
...
@@ -603,9 +610,7 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
thr_lock_type
new_lock_type
)
thr_lock_type
new_lock_type
)
{
{
MYSQL_LOCK
*
locked
;
MYSQL_LOCK
*
locked
;
TABLE
*
write_lock_used
;
if
((
locked
=
get_lock_data
(
thd
,
&
table
,
1
,
GET_LOCK_UNLOCK
)))
if
((
locked
=
get_lock_data
(
thd
,
&
table
,
1
,
GET_LOCK_UNLOCK
,
&
write_lock_used
)))
{
{
for
(
uint
i
=
0
;
i
<
locked
->
lock_count
;
i
++
)
for
(
uint
i
=
0
;
i
<
locked
->
lock_count
;
i
++
)
thr_downgrade_write_lock
(
locked
->
locks
[
i
],
new_lock_type
);
thr_downgrade_write_lock
(
locked
->
locks
[
i
],
new_lock_type
);
...
@@ -619,11 +624,9 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
...
@@ -619,11 +624,9 @@ void mysql_lock_downgrade_write(THD *thd, TABLE *table,
void
mysql_lock_abort
(
THD
*
thd
,
TABLE
*
table
,
bool
upgrade_lock
)
void
mysql_lock_abort
(
THD
*
thd
,
TABLE
*
table
,
bool
upgrade_lock
)
{
{
MYSQL_LOCK
*
locked
;
MYSQL_LOCK
*
locked
;
TABLE
*
write_lock_used
;
DBUG_ENTER
(
"mysql_lock_abort"
);
DBUG_ENTER
(
"mysql_lock_abort"
);
if
((
locked
=
get_lock_data
(
thd
,
&
table
,
1
,
GET_LOCK_UNLOCK
,
if
((
locked
=
get_lock_data
(
thd
,
&
table
,
1
,
GET_LOCK_UNLOCK
)))
&
write_lock_used
)))
{
{
for
(
uint
i
=
0
;
i
<
locked
->
lock_count
;
i
++
)
for
(
uint
i
=
0
;
i
<
locked
->
lock_count
;
i
++
)
thr_abort_locks
(
locked
->
locks
[
i
]
->
lock
,
upgrade_lock
);
thr_abort_locks
(
locked
->
locks
[
i
]
->
lock
,
upgrade_lock
);
...
@@ -648,12 +651,10 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
...
@@ -648,12 +651,10 @@ void mysql_lock_abort(THD *thd, TABLE *table, bool upgrade_lock)
bool
mysql_lock_abort_for_thread
(
THD
*
thd
,
TABLE
*
table
)
bool
mysql_lock_abort_for_thread
(
THD
*
thd
,
TABLE
*
table
)
{
{
MYSQL_LOCK
*
locked
;
MYSQL_LOCK
*
locked
;
TABLE
*
write_lock_used
;
bool
result
=
FALSE
;
bool
result
=
FALSE
;
DBUG_ENTER
(
"mysql_lock_abort_for_thread"
);
DBUG_ENTER
(
"mysql_lock_abort_for_thread"
);
if
((
locked
=
get_lock_data
(
thd
,
&
table
,
1
,
GET_LOCK_UNLOCK
,
if
((
locked
=
get_lock_data
(
thd
,
&
table
,
1
,
GET_LOCK_UNLOCK
)))
&
write_lock_used
)))
{
{
for
(
uint
i
=
0
;
i
<
locked
->
lock_count
;
i
++
)
for
(
uint
i
=
0
;
i
<
locked
->
lock_count
;
i
++
)
{
{
...
@@ -848,11 +849,10 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
...
@@ -848,11 +849,10 @@ static int unlock_external(THD *thd, TABLE **table,uint count)
@param flags One of:
@param flags One of:
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
- GET_LOCK_UNLOCK : If we should send TL_IGNORE to store lock
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
- GET_LOCK_STORE_LOCKS : Store lock info in TABLE
@param write_lock_used Store pointer to last table with WRITE_ALLOW_WRITE
*/
*/
static
MYSQL_LOCK
*
get_lock_data
(
THD
*
thd
,
TABLE
**
table_ptr
,
uint
count
,
static
MYSQL_LOCK
*
get_lock_data
(
THD
*
thd
,
TABLE
**
table_ptr
,
uint
count
,
uint
flags
,
TABLE
**
write_lock_used
)
uint
flags
)
{
{
uint
i
,
tables
,
lock_count
;
uint
i
,
tables
,
lock_count
;
MYSQL_LOCK
*
sql_lock
;
MYSQL_LOCK
*
sql_lock
;
...
@@ -861,9 +861,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
...
@@ -861,9 +861,8 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
DBUG_ENTER
(
"get_lock_data"
);
DBUG_ENTER
(
"get_lock_data"
);
DBUG_ASSERT
((
flags
==
GET_LOCK_UNLOCK
)
||
(
flags
==
GET_LOCK_STORE_LOCKS
));
DBUG_ASSERT
((
flags
==
GET_LOCK_UNLOCK
)
||
(
flags
==
GET_LOCK_STORE_LOCKS
));
DBUG_PRINT
(
"info"
,
(
"count %d"
,
count
));
DBUG_PRINT
(
"info"
,
(
"count %d"
,
count
));
*
write_lock_used
=
0
;
for
(
i
=
tables
=
lock_count
=
0
;
i
<
count
;
i
++
)
for
(
i
=
tables
=
lock_count
=
0
;
i
<
count
;
i
++
)
{
{
TABLE
*
t
=
table_ptr
[
i
];
TABLE
*
t
=
table_ptr
[
i
];
...
@@ -895,24 +894,12 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
...
@@ -895,24 +894,12 @@ static MYSQL_LOCK *get_lock_data(THD *thd, TABLE **table_ptr, uint count,
{
{
TABLE
*
table
;
TABLE
*
table
;
enum
thr_lock_type
lock_type
;
enum
thr_lock_type
lock_type
;
THR_LOCK_DATA
**
org_locks
=
locks
;
if
((
table
=
table_ptr
[
i
])
->
s
->
tmp_table
==
NON_TRANSACTIONAL_TMP_TABLE
)
if
((
table
=
table_ptr
[
i
])
->
s
->
tmp_table
==
NON_TRANSACTIONAL_TMP_TABLE
)
continue
;
continue
;
lock_type
=
table
->
reginfo
.
lock_type
;
lock_type
=
table
->
reginfo
.
lock_type
;
DBUG_ASSERT
(
lock_type
!=
TL_WRITE_DEFAULT
&&
lock_type
!=
TL_READ_DEFAULT
);
DBUG_ASSERT
(
lock_type
!=
TL_WRITE_DEFAULT
&&
lock_type
!=
TL_READ_DEFAULT
);
if
(
lock_type
>=
TL_WRITE_ALLOW_WRITE
)
{
*
write_lock_used
=
table
;
if
(
table
->
db_stat
&
HA_READ_ONLY
)
{
my_error
(
ER_OPEN_AS_READONLY
,
MYF
(
0
),
table
->
alias
);
/* Clear the lock type of the lock data that are stored already. */
sql_lock
->
lock_count
=
(
uint
)
(
locks
-
sql_lock
->
locks
);
reset_lock_data_and_free
(
&
sql_lock
);
DBUG_RETURN
(
0
);
}
}
THR_LOCK_DATA
**
org_locks
=
locks
;
locks_start
=
locks
;
locks_start
=
locks
;
locks
=
table
->
file
->
store_lock
(
thd
,
locks
,
locks
=
table
->
file
->
store_lock
(
thd
,
locks
,
(
flags
&
GET_LOCK_UNLOCK
)
?
TL_IGNORE
:
(
flags
&
GET_LOCK_UNLOCK
)
?
TL_IGNORE
:
...
...
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