Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
#
|
|
|
|
# SUMMARY
|
|
|
|
# Check that statement reading table '$table' doesn't allow concurrent
|
|
|
|
# inserts in it.
|
|
|
|
#
|
|
|
|
# PARAMETERS
|
|
|
|
# $table Table in which concurrent inserts should be disallowed.
|
|
|
|
# $con_aux1 Name of the first auxiliary connection to be used by this
|
|
|
|
# script.
|
|
|
|
# $con_aux2 Name of the second auxiliary connection to be used by this
|
|
|
|
# script.
|
|
|
|
# $statement Statement to be checked.
|
2010-05-30 11:27:44 +02:00
|
|
|
# $restore_table Table which might be modified by statement to be checked
|
|
|
|
# and thus needs backing up before its execution and
|
|
|
|
# restoring after it (can be empty).
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
#
|
|
|
|
# EXAMPLE
|
|
|
|
# lock_sync.test
|
|
|
|
#
|
|
|
|
--disable_result_log
|
|
|
|
--disable_query_log
|
|
|
|
|
2010-05-21 14:41:24 +02:00
|
|
|
# Reset DEBUG_SYNC facility for safety.
|
|
|
|
set debug_sync= "RESET";
|
|
|
|
|
2010-10-20 16:15:32 +02:00
|
|
|
if ($restore_table)
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
{
|
2010-05-30 11:27:44 +02:00
|
|
|
--eval create temporary table t_backup select * from $restore_table;
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
connection $con_aux1;
|
|
|
|
set debug_sync='after_lock_tables_takes_lock SIGNAL parked WAIT_FOR go';
|
|
|
|
--send_eval $statement;
|
|
|
|
|
|
|
|
connection $con_aux2;
|
|
|
|
set debug_sync='now WAIT_FOR parked';
|
2010-05-30 11:27:44 +02:00
|
|
|
--send_eval insert into $table (i) values (0);
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
|
|
|
|
--enable_result_log
|
|
|
|
--enable_query_log
|
|
|
|
connection default;
|
|
|
|
# Wait until concurrent insert is successfully blocked because
|
|
|
|
# of our statement.
|
|
|
|
let $wait_condition=
|
|
|
|
select count(*) = 1 from information_schema.processlist
|
Part of fix for bug#52044 "FLUSH TABLES WITH READ LOCK and
FLUSH TABLES <list> WITH READ LOCK are incompatible" to
be pushed as separate patch.
Replaced thread state name "Waiting for table", which was
used by threads waiting for a metadata lock or table flush,
with a set of names which better reflect types of resources
being waited for.
Also replaced "Table lock" thread state name, which was used
by threads waiting on thr_lock.c table level lock, with more
elaborate "Waiting for table level lock", to make it
more consistent with other thread state names.
Updated test cases and their results according to these
changes.
Fixed sys_vars.query_cache_wlock_invalidate_func test to not
to wait for timeout of wait_condition.inc script.
mysql-test/r/query_cache.result:
Added test coverage for query_cache_wlock_invalidate
behavior for implicitly locked tables.
mysql-test/suite/sys_vars/r/query_cache_wlock_invalidate_func.result:
Fixed sys_vars.query_cache_wlock_invalidate_func test to not
to wait for timeout of wait_condition.inc script. Reverted
changes to test which introduced timeout and replaced waiting
condition with a more appropriate one.
Test coverage for query_cache_wlock_invalidate behavior for
implicitly locked tables was added to query_cache.test.
mysql-test/suite/sys_vars/t/query_cache_wlock_invalidate_func.test:
Fixed sys_vars.query_cache_wlock_invalidate_func test to not
to wait for timeout of wait_condition.inc script. Reverted
changes to test which introduced timeout and replaced waiting
condition with a more appropriate one.
Test coverage for query_cache_wlock_invalidate behavior for
implicitly locked tables was added to query_cache.test.
mysql-test/t/query_cache.test:
Added test coverage for query_cache_wlock_invalidate
behavior for implicitly locked tables.
mysys/thr_lock.c:
Replaced "Table lock" thread state name, which was used by
threads waiting on thr_lock.c table level lock, with more
elaborate "Waiting for table level lock", to make it
consistent with thread state names which are used while
waiting for metadata locks and table flush.
sql/mdl.cc:
Replaced thread state name "Waiting for table", which was
used by threads waiting for a metadata lock or table flush,
with a set of names which better reflect types of resources
being waited for.
To implement this:
- Adjusted MDL_wait::timed_wait() to take thread state name
as parameter.
- Introduced method of MDL_key class which allows to get
thread state name to be used while waiting for resource
corresponding to the key and changed code to use it.
Added array translating namespaces to thread state names
as part of this change.
sql/mdl.h:
To implement this:
- Adjusted MDL_wait::timed_wait() to take thread state name
as parameter.
- Introduced method of MDL_key class which allows to get
thread state name to be used while waiting for resource
corresponding to the key and changed code to use it.
Added array translating namespaces to thread state names
as part of this change.
sql/sql_base.cc:
Replaced thread state name "Waiting for table", which was
used by threads waiting for table flush, with a more elaborate
"Waiting for table flush".
2010-08-06 13:29:37 +02:00
|
|
|
where state = "Waiting for table level lock" and
|
|
|
|
info = "insert into $table (i) values (0)";
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
--source include/wait_condition.inc
|
|
|
|
|
|
|
|
--disable_result_log
|
|
|
|
--disable_query_log
|
|
|
|
|
|
|
|
set debug_sync= 'now SIGNAL go';
|
|
|
|
connection $con_aux1;
|
|
|
|
--reap
|
|
|
|
connection $con_aux2;
|
|
|
|
--reap
|
|
|
|
connection default;
|
|
|
|
|
|
|
|
if ($success)
|
|
|
|
{
|
|
|
|
--echo Success: '$statement' doesn't allow concurrent inserts into '$table'.
|
|
|
|
}
|
|
|
|
if (!$success)
|
|
|
|
{
|
|
|
|
--echo Error: '$statement' allows concurrent inserts into '$table'!
|
|
|
|
}
|
|
|
|
|
|
|
|
--eval delete from $table where i = 0;
|
|
|
|
|
2010-10-20 16:15:32 +02:00
|
|
|
if ($restore_table)
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
{
|
|
|
|
--eval truncate table $restore_table;
|
|
|
|
--eval insert into $restore_table select * from t_backup;
|
2010-05-30 11:27:44 +02:00
|
|
|
drop temporary table t_backup;
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
}
|
|
|
|
|
2010-05-21 14:41:24 +02:00
|
|
|
# Clean-up. Reset DEBUG_SYNC facility after use.
|
|
|
|
set debug_sync= "RESET";
|
|
|
|
|
Committing on behalf or Dmitry Lenev:
Fix for bug #46947 "Embedded SELECT without FOR UPDATE is
causing a lock", with after-review fixes.
SELECT statements with subqueries referencing InnoDB tables
were acquiring shared locks on rows in these tables when they
were executed in REPEATABLE-READ mode and with statement or
mixed mode binary logging turned on.
This was a regression which were introduced when fixing
bug 39843.
The problem was that for tables belonging to subqueries
parser set TL_READ_DEFAULT as a lock type. In cases when
statement/mixed binary logging at open_tables() time this
type of lock was converted to TL_READ_NO_INSERT lock at
open_tables() time and caused InnoDB engine to acquire
shared locks on reads from these tables. Although in some
cases such behavior was correct (e.g. for subqueries in
DELETE) in case of SELECT it has caused unnecessary locking.
This patch tries to solve this problem by rethinking our
approach to how we handle locking for SELECT and subqueries.
Now we always set TL_READ_DEFAULT lock type for all cases
when we read data. When at open_tables() time this lock
is interpreted as TL_READ_NO_INSERT or TL_READ depending
on whether this statement as a whole or call to function
which uses particular table should be written to the
binary log or not (if yes then statement should be properly
serialized with concurrent statements and stronger lock
should be acquired).
Test coverage is added for both InnoDB and MyISAM.
This patch introduces an "incompatible" change in locking
scheme for subqueries used in SELECT ... FOR UPDATE and
SELECT .. IN SHARE MODE.
In 4.1 the server would use a snapshot InnoDB read for
subqueries in SELECT FOR UPDATE and SELECT .. IN SHARE MODE
statements, regardless of whether the binary log is on or off.
If the user required a different type of read (i.e. locking read),
he/she could request so explicitly by providing FOR UPDATE/IN SHARE MODE
clause for each individual subquery.
On of the patches for 5.0 broke this behaviour (which was not documented
or tested), and started to use locking reads fora all subqueries in SELECT ...
FOR UPDATE/IN SHARE MODE. This patch restored 4.1 behaviour.
mysql-test/include/check_concurrent_insert.inc:
Added auxiliary script which allows to check if statement
reading table allows concurrent inserts in it.
mysql-test/include/check_no_concurrent_insert.inc:
Added auxiliary script which allows to check that statement
reading table doesn't allow concurrent inserts in it.
mysql-test/include/check_no_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table doesn't take locks on its rows.
mysql-test/include/check_shared_row_lock.inc:
Added auxiliary script which allows to check if statement
reading table takes shared locks on some of its rows.
mysql-test/r/bug39022.result:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/r/innodb_mysql_lock2.result:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/r/lock_sync.result:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
mysql-test/t/bug39022.test:
After bug #46947 'Embedded SELECT without FOR UPDATE is
causing a lock' was fixed test case for bug 39022 has to
be adjusted in order to trigger execution path on which
original problem was encountered.
mysql-test/t/innodb_mysql_lock2.test:
Added coverage for handling of locking in various cases when
we read data from InnoDB tables (includes test case for
bug #46947 'Embedded SELECT without FOR UPDATE is causing a
lock').
mysql-test/t/lock_sync.test:
Added coverage for handling of locking in various cases when
we read data from MyISAM tables.
sql/log_event.cc:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/log_event.h:
Since LEX::lock_option member was removed we no longer can
rely on its value in Load_log_event::print_query() to
determine that log event correponds to LOAD DATA CONCURRENT
statement (this was not correct in all situations anyway).
A new Load_log_event's member was introduced as a replacement.
It is initialized at event object construction time and
explicitly indicates whether LOAD DATA was concurrent.
sql/sp_head.cc:
sp_head::reset_lex():
Before parsing substatement reset part of parser state
which needs this (e.g. set Yacc_state::m_lock_type to
default value).
sql/sql_acl.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_base.cc:
Changed read_lock_type_for_table() to return a weak TL_READ
type of lock in cases when we are executing statement which
won't update tables directly and table doesn't belong to
statement's prelocking list and thus can't be used by a
stored function. It is OK to do so since in this case table
won't be used by statement or function call which will be
written to the binary log, so serializability requirements
for it can be relaxed.
One of results from this change is that SELECTs on InnoDB
tables no longer takes shared row locks for tables which
are used in subqueries (i.e. bug #46947 is fixed).
Another result is that for similar SELECTs on MyISAM tables
concurrent inserts are allowed.
In order to implement this change signature of
read_lock_type_for_table() function was changed to take
pointers to Query_tables_list and TABLE_LIST objects.
sql/sql_base.h:
- Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_lex.cc:
- Removed LEX::lock_option and st_select_lex::lock_option
members. Places in parser that were using them now use
Yacc_state::m_lock_type instead.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class. It is now reset by
Query_tables_list::reset_query_tables_list() method.
sql/sql_lex.h:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- To emphasize that LEX::sql_command member is used during
process of opening and locking of tables it was moved to
Query_tables_list class.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
sql/sql_load.cc:
Load_log_event constructor now requires a parameter that
indicates whether LOAD DATA is concurrent.
sql/sql_parse.cc:
LEX::lock_option was replaced with Yacc_state::m_lock_type.
And instead of resetting the latter implicitly in
mysql_init_multi_delete() we do it explicitly in the
places in parser which call this function.
sql/sql_priv.h:
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method added flag for
HIGH_PRIORITY option.
sql/sql_select.cc:
Changed code not to rely on LEX::lock_option to determine
that it is high-priority SELECT. It was replaced with
Yacc_state::m_lock_type which is accessible only at
parse time. So instead of LEX::lock_option we now rely
on a newly introduced flag for st_select_lex::options -
SELECT_HIGH_PRIORITY.
sql/sql_show.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed.
sql/sql_table.cc:
Since LEX::reset_query_tables_list() now also resets
LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore value of this
member when this method is called by mysql_admin_table(),
to make this code safe for re-execution.
sql/sql_trigger.cc:
Since LEX::reset_n_backup_query_tables_list() now also
resets LEX::sql_command member (as it became part of
Query_tables_list class) we have to restore it in cases
when while working with proxy Query_table_list we assume
that LEX::sql_command still corresponds to original SQL
command being executed (for example, when we are logging
statement to the binary log while having Query_tables_list
reset and backed up).
sql/sql_update.cc:
Function read_lock_type_for_table() now takes pointers
to Query_tables_list and TABLE_LIST elements as its
arguments since to correctly determine lock type it needs
to know what statement is being performed and whether table
element for which lock type to be determined belongs to
prelocking list.
sql/sql_yacc.yy:
- Removed st_select_lex::lock_option member as there is no
real need for per-SELECT lock type (HIGH_PRIORITY option
should apply to the whole statement. FOR UPDATE/LOCK IN
SHARE MODE clauses can be handled without this member).
The main effect which was achieved by introduction of this
member, i.e. using TL_READ_DEFAULT lock type for
subqueries, is now achieved by setting LEX::lock_option
(or rather its replacement - Yacc_state::m_lock_type) to
TL_READ_DEFAULT in almost all cases.
- Replaced LEX::lock_option with Yacc_state::m_lock_type
in order to emphasize that this value is relevant only
during parsing. Unlike for LEX::lock_option the default
value for Yacc_state::m_lock_type is TL_READ_DEFAULT.
Note that for cases when it is OK to take a "weak" read
lock (e.g. simple SELECT) this lock type will be converted
to TL_READ at open_tables() time. So this change won't
cause negative change in behavior for such statements.
OTOH this change ensures that, for example, for SELECTs
which are used in stored functions TL_READ_NO_INSERT lock
is taken when necessary and as result calls to such stored
functions can be written to the binary log with correct
serialization.
- To be able more easily distinguish high-priority SELECTs
in st_select_lex::print() method we now use new flag
in st_select_lex::options bit-field.
2010-04-28 12:04:11 +02:00
|
|
|
--enable_result_log
|
|
|
|
--enable_query_log
|