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
87bedb59
Commit
87bedb59
authored
Apr 07, 2009
by
Satya B
Browse files
Options
Browse Files
Download
Plain Diff
merge to latest 5.0-bugteam
parents
b9bdc35d
c045d1dc
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
287 additions
and
34 deletions
+287
-34
myisam/mi_packrec.c
myisam/mi_packrec.c
+9
-27
mysql-test/r/lock_multi.result
mysql-test/r/lock_multi.result
+55
-0
mysql-test/r/myisampack.result
mysql-test/r/myisampack.result
+22
-0
mysql-test/t/lock_multi.test
mysql-test/t/lock_multi.test
+128
-0
mysql-test/t/myisampack.test
mysql-test/t/myisampack.test
+25
-0
scripts/mysqld_multi.sh
scripts/mysqld_multi.sh
+0
-5
sql/sql_lex.cc
sql/sql_lex.cc
+1
-0
sql/sql_lex.h
sql/sql_lex.h
+16
-0
sql/sql_parse.cc
sql/sql_parse.cc
+25
-1
sql/sql_yacc.yy
sql/sql_yacc.yy
+6
-1
No files found.
myisam/mi_packrec.c
View file @
87bedb59
...
...
@@ -208,10 +208,17 @@ my_bool _mi_read_pack_info(MI_INFO *info, pbool fix_keys)
This segment will be reallocated after construction of the tables.
*/
length
=
(
uint
)
(
elements
*
2
+
trees
*
(
1
<<
myisam_quick_table_bits
));
/*
To keep some algorithms simpler, we accept that they access
bytes beyond the end of the input data. This can affect up to
one byte less than the "word size" size used in this file,
which is BITS_SAVED / 8. To avoid accessing non-allocated
data, we add (BITS_SAVED / 8) - 1 bytes to the buffer size.
*/
if
(
!
(
share
->
decode_tables
=
(
uint16
*
)
my_malloc
((
length
+
OFFSET_TABLE_SIZE
)
*
sizeof
(
uint16
)
+
(
uint
)
(
share
->
pack
.
header_length
-
sizeof
(
header
)
),
MYF
(
MY_WME
|
MY_ZEROFILL
))))
(
uint
)
(
share
->
pack
.
header_length
-
sizeof
(
header
)
+
(
BITS_SAVED
/
8
)
-
1
),
MYF
(
MY_WME
|
MY_ZEROFILL
))))
goto
err1
;
tmp_buff
=
share
->
decode_tables
+
length
;
disk_cache
=
(
byte
*
)
(
tmp_buff
+
OFFSET_TABLE_SIZE
);
...
...
@@ -1430,31 +1437,6 @@ static void fill_buffer(MI_BIT_BUFF *bit_buff)
bit_buff
->
current_byte
=
0
;
return
;
}
else
{
uint
len
=
0
;
uint
i
=
0
;
/*
Check if the remaining buffer/record to read is less than the word size.
If so read byte by byte
Note: if this branch becomes a bottleneck it can be removed, assuming
that the second memory segment allocates 7 extra bytes (see
_mi_read_pack_info()).
*/
len
=
bit_buff
->
end
-
bit_buff
->
pos
;
if
(
len
<
(
BITS_SAVED
/
8
))
{
bit_buff
->
current_byte
=
0
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
bit_buff
->
current_byte
+=
(((
uint
)
((
uchar
)
bit_buff
->
pos
[
len
-
i
-
1
]))
<<
(
8
*
i
));
}
bit_buff
->
pos
=
bit_buff
->
end
;
return
;
}
}
#if BITS_SAVED == 64
bit_buff
->
current_byte
=
((((
uint
)
((
uchar
)
bit_buff
->
pos
[
7
])))
+
...
...
mysql-test/r/lock_multi.result
View file @
87bedb59
...
...
@@ -133,3 +133,58 @@ ALTER TABLE t1 ADD COLUMN a INT;
# 2.2.1. normal mode
# 2.2.2. PS mode
DROP TABLE t1;
create table t1 (a int);
create table t2 like t1;
# con1
lock tables t1 write;
# con2
flush tables with read lock;
# con5
# global read lock is taken
# con3
select * from t2 for update;
# waiting for release of read lock
# con4
# would hang and later cause a deadlock
flush tables t2;
# clean up
unlock tables;
unlock tables;
a
drop table t1,t2;
#
# Lightweight version:
# Ensure that the wait for a GRL is done before opening tables.
#
create table t1 (a int);
create table t2 like t1;
#
# UPDATE
#
# default
flush tables with read lock;
# con1
update t2 set a = 1;
# default
# statement is waiting for release of read lock
# con2
flush table t2;
# default
unlock tables;
# con1
#
# LOCK TABLES .. WRITE
#
# default
flush tables with read lock;
# con1
lock tables t2 write;
# default
# statement is waiting for release of read lock
# con2
flush table t2;
# default
unlock tables;
# con1
unlock tables;
drop table t1,t2;
mysql-test/r/myisampack.result
View file @
87bedb59
...
...
@@ -38,3 +38,25 @@ SELECT COUNT(*) FROM t1;
COUNT(*)
1024
DROP TABLE t1;
#
# Bug #43973 - backup_myisam.test fails on 6.0-bugteam
#
CREATE DATABASE mysql_db1;
CREATE TABLE mysql_db1.t1 (c1 VARCHAR(5), c2 int);
CREATE INDEX i1 ON mysql_db1.t1 (c1, c2);
INSERT INTO mysql_db1.t1 VALUES ('A',1);
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
INSERT INTO mysql_db1.t1 SELECT * FROM mysql_db1.t1;
FLUSH TABLE mysql_db1.t1;
# Compress the table using MYISAMPACK tool
# Run MYISAMCHK tool on the compressed table
SELECT COUNT(*) FROM mysql_db1.t1 WHERE c2 < 5;
COUNT(*)
128
DROP TABLE mysql_db1.t1;
DROP DATABASE mysql_db1;
mysql-test/t/lock_multi.test
View file @
87bedb59
...
...
@@ -683,6 +683,134 @@ DROP TABLE t1;
--
disconnect
locker
--
disconnect
writer
#
# Bug#43230: SELECT ... FOR UPDATE can hang with FLUSH TABLES WITH READ LOCK indefinitely
#
connect
(
con1
,
localhost
,
root
,,);
connect
(
con2
,
localhost
,
root
,,);
connect
(
con3
,
localhost
,
root
,,);
connect
(
con4
,
localhost
,
root
,,);
connect
(
con5
,
localhost
,
root
,,);
create
table
t1
(
a
int
);
create
table
t2
like
t1
;
connection
con1
;
--
echo
# con1
lock
tables
t1
write
;
connection
con2
;
--
echo
# con2
send
flush
tables
with
read
lock
;
connection
con5
;
--
echo
# con5
let
$show_statement
=
SHOW
PROCESSLIST
;
let
$field
=
State
;
let
$condition
=
=
'Flushing tables'
;
--
source
include
/
wait_show_condition
.
inc
--
echo
# global read lock is taken
connection
con3
;
--
echo
# con3
send
select
*
from
t2
for
update
;
connection
con5
;
let
$show_statement
=
SHOW
PROCESSLIST
;
let
$field
=
State
;
let
$condition
=
=
'Waiting for release of readlock'
;
--
source
include
/
wait_show_condition
.
inc
--
echo
# waiting for release of read lock
connection
con4
;
--
echo
# con4
--
echo
# would hang and later cause a deadlock
flush
tables
t2
;
connection
con1
;
--
echo
# clean up
unlock
tables
;
connection
con2
;
--
reap
unlock
tables
;
connection
con3
;
--
reap
connection
default
;
disconnect
con5
;
disconnect
con4
;
disconnect
con3
;
disconnect
con2
;
disconnect
con1
;
drop
table
t1
,
t2
;
--
echo
#
--
echo
# Lightweight version:
--
echo
# Ensure that the wait for a GRL is done before opening tables.
--
echo
#
connect
(
con1
,
localhost
,
root
,,);
connect
(
con2
,
localhost
,
root
,,);
create
table
t1
(
a
int
);
create
table
t2
like
t1
;
--
echo
#
--
echo
# UPDATE
--
echo
#
connection
default
;
--
echo
# default
flush
tables
with
read
lock
;
connection
con1
;
--
echo
# con1
send
update
t2
set
a
=
1
;
connection
default
;
--
echo
# default
let
$show_statement
=
SHOW
PROCESSLIST
;
let
$field
=
State
;
let
$condition
=
=
'Waiting for release of readlock'
;
--
source
include
/
wait_show_condition
.
inc
--
echo
# statement is waiting for release of read lock
connection
con2
;
--
echo
# con2
flush
table
t2
;
connection
default
;
--
echo
# default
unlock
tables
;
connection
con1
;
--
echo
# con1
--
reap
--
echo
#
--
echo
# LOCK TABLES .. WRITE
--
echo
#
connection
default
;
--
echo
# default
flush
tables
with
read
lock
;
connection
con1
;
--
echo
# con1
send
lock
tables
t2
write
;
connection
default
;
--
echo
# default
let
$show_statement
=
SHOW
PROCESSLIST
;
let
$field
=
State
;
let
$condition
=
=
'Waiting for release of readlock'
;
--
source
include
/
wait_show_condition
.
inc
--
echo
# statement is waiting for release of read lock
connection
con2
;
--
echo
# con2
flush
table
t2
;
connection
default
;
--
echo
# default
unlock
tables
;
connection
con1
;
--
echo
# con1
--
reap
unlock
tables
;
connection
default
;
disconnect
con2
;
disconnect
con1
;
drop
table
t1
,
t2
;
# End of 5.0 tests
# Wait till all disconnects are completed
...
...
mysql-test/t/myisampack.test
View file @
87bedb59
...
...
@@ -50,3 +50,28 @@ FLUSH TABLE t1;
--
exec
$MYISAMPACK
$MYSQLTEST_VARDIR
/
master
-
data
/
test
/
t1
SELECT
COUNT
(
*
)
FROM
t1
;
DROP
TABLE
t1
;
--
echo
#
--
echo
# Bug #43973 - backup_myisam.test fails on 6.0-bugteam
--
echo
#
CREATE
DATABASE
mysql_db1
;
CREATE
TABLE
mysql_db1
.
t1
(
c1
VARCHAR
(
5
),
c2
int
);
CREATE
INDEX
i1
ON
mysql_db1
.
t1
(
c1
,
c2
);
INSERT
INTO
mysql_db1
.
t1
VALUES
(
'A'
,
1
);
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
INSERT
INTO
mysql_db1
.
t1
SELECT
*
FROM
mysql_db1
.
t1
;
FLUSH
TABLE
mysql_db1
.
t1
;
#
--
echo
# Compress the table using MYISAMPACK tool
--
exec
$MYISAMPACK
-
s
$MYSQLTEST_VARDIR
/
master
-
data
/
mysql_db1
/
t1
--
echo
# Run MYISAMCHK tool on the compressed table
--
exec
$MYISAMCHK
-
srq
$MYSQLTEST_VARDIR
/
master
-
data
/
mysql_db1
/
t1
SELECT
COUNT
(
*
)
FROM
mysql_db1
.
t1
WHERE
c2
<
5
;
#
DROP
TABLE
mysql_db1
.
t1
;
DROP
DATABASE
mysql_db1
;
scripts/mysqld_multi.sh
View file @
87bedb59
...
...
@@ -293,12 +293,7 @@ sub start_mysqlds()
@groups
=
&find_groups
(
$groupids
)
;
for
(
$i
=
0
;
defined
(
$groups
[
$i
])
;
$i
++
)
{
# Defaults are made explicit parameters to server execution...
@options
=
defaults_for_group
(
$groups
[
$i
])
;
# ...so server MUST NOT try to read again from some config file, especially
# as the "right" file may be unknown to the server if we are using
# --defaults-file=... params in here.
unshift
(
@options,
"--no-defaults"
)
;
$mysqld_found
=
1
;
# The default
$mysqld_found
=
0
if
(!
length
(
$mysqld
))
;
...
...
sql/sql_lex.cc
View file @
87bedb59
...
...
@@ -204,6 +204,7 @@ void lex_start(THD *thd)
lex
->
nest_level
=
0
;
lex
->
allow_sum_func
=
0
;
lex
->
in_sum_func
=
NULL
;
lex
->
protect_against_global_read_lock
=
FALSE
;
DBUG_VOID_RETURN
;
}
...
...
sql/sql_lex.h
View file @
87bedb59
...
...
@@ -1176,6 +1176,22 @@ typedef struct st_lex : public Query_tables_list
bool
escape_used
;
/*
Special case for SELECT .. FOR UPDATE and LOCK TABLES .. WRITE.
Protect from a impending GRL as otherwise the thread might deadlock
if it starts waiting for the GRL in mysql_lock_tables.
The protection is needed because there is a race between setting
the global read lock and waiting for all open tables to be closed.
The problem is a circular wait where a thread holding "old" open
tables will wait for the global read lock to be released while the
thread holding the global read lock will wait for all "old" open
tables to be closed -- the flush part of flush tables with read
lock.
*/
bool
protect_against_global_read_lock
;
st_lex
();
virtual
~
st_lex
()
...
...
sql/sql_parse.cc
View file @
87bedb59
...
...
@@ -2800,6 +2800,10 @@ mysql_execute_command(THD *thd)
if
(
res
)
goto
error
;
if
(
!
thd
->
locked_tables
&&
lex
->
protect_against_global_read_lock
&&
!
(
need_start_waiting
=
!
wait_if_global_read_lock
(
thd
,
0
,
1
)))
goto
error
;
if
(
!
(
res
=
open_and_lock_tables
(
thd
,
all_tables
)))
{
if
(
lex
->
describe
)
...
...
@@ -3660,6 +3664,9 @@ end_with_restore_list:
DBUG_ASSERT
(
first_table
==
all_tables
&&
first_table
!=
0
);
if
(
update_precheck
(
thd
,
all_tables
))
break
;
if
(
!
thd
->
locked_tables
&&
!
(
need_start_waiting
=
!
wait_if_global_read_lock
(
thd
,
0
,
1
)))
goto
error
;
DBUG_ASSERT
(
select_lex
->
offset_limit
==
0
);
unit
->
set_limit
(
select_lex
);
res
=
(
up_result
=
mysql_update
(
thd
,
all_tables
,
...
...
@@ -3686,6 +3693,15 @@ end_with_restore_list:
else
res
=
0
;
/*
Protection might have already been risen if its a fall through
from the SQLCOM_UPDATE case above.
*/
if
(
!
thd
->
locked_tables
&&
lex
->
sql_command
==
SQLCOM_UPDATE_MULTI
&&
!
(
need_start_waiting
=
!
wait_if_global_read_lock
(
thd
,
0
,
1
)))
goto
error
;
res
=
mysql_multi_update_prepare
(
thd
);
#ifdef HAVE_REPLICATION
...
...
@@ -3853,7 +3869,8 @@ end_with_restore_list:
ER
(
ER_LOCK_OR_ACTIVE_TRANSACTION
),
MYF
(
0
));
goto
error
;
}
if
(
!
(
need_start_waiting
=
!
wait_if_global_read_lock
(
thd
,
0
,
1
)))
goto
error
;
res
=
mysql_truncate
(
thd
,
first_table
,
0
);
break
;
case
SQLCOM_DELETE
:
...
...
@@ -4027,6 +4044,10 @@ end_with_restore_list:
if
(
check_one_table_access
(
thd
,
privilege
,
all_tables
))
goto
error
;
if
(
!
thd
->
locked_tables
&&
!
(
need_start_waiting
=
!
wait_if_global_read_lock
(
thd
,
0
,
1
)))
goto
error
;
res
=
mysql_load
(
thd
,
lex
->
exchange
,
first_table
,
lex
->
field_list
,
lex
->
update_list
,
lex
->
value_list
,
lex
->
duplicates
,
lex
->
ignore
,
(
bool
)
lex
->
local_file
);
...
...
@@ -4082,6 +4103,9 @@ end_with_restore_list:
goto
error
;
if
(
check_table_access
(
thd
,
LOCK_TABLES_ACL
|
SELECT_ACL
,
all_tables
,
0
))
goto
error
;
if
(
lex
->
protect_against_global_read_lock
&&
!
(
need_start_waiting
=
!
wait_if_global_read_lock
(
thd
,
0
,
1
)))
goto
error
;
thd
->
in_lock_tables
=
1
;
thd
->
options
|=
OPTION_TABLE_LOCK
;
...
...
sql/sql_yacc.yy
View file @
87bedb59
...
...
@@ -4522,6 +4522,7 @@ select_lock_type:
LEX *lex=Lex;
lex->current_select->set_lock_for_tables(TL_WRITE);
lex->safe_to_cache_query=0;
lex->protect_against_global_read_lock= TRUE;
}
| LOCK_SYM IN_SYM SHARE_SYM MODE_SYM
{
...
...
@@ -10058,8 +10059,12 @@ table_lock_list:
table_lock:
table_ident opt_table_alias lock_option
{
if (!Select->add_table_to_list(YYTHD, $1, $2, 0, (thr_lock_type) $3))
thr_lock_type lock_type= (thr_lock_type) $3;
if (!Select->add_table_to_list(YYTHD, $1, $2, 0, lock_type))
MYSQL_YYABORT;
/* If table is to be write locked, protect from a impending GRL. */
if (lock_type >= TL_WRITE_ALLOW_WRITE)
Lex->protect_against_global_read_lock= TRUE;
}
;
...
...
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