mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 04:53:01 +01:00
row0mysql.h:
Improve the comment on stored_select_lock_type ha_innodb.cc: Let InnoDB remember select_lock_type inside LOCK TABLES, also over plain consistent read SELECTs; fix Bug #5538 : assertion failure when using mysqldump with the -l option; in MERGING this patch to 4.1, there may be PROBLEMS; that is because previous patch was never merged to 4.1; Heikki Tuuri has to polish the code in 4.1 after this patch has been merged.
This commit is contained in:
parent
4c7c2343c7
commit
d6b4c4f90e
2 changed files with 43 additions and 30 deletions
|
@ -508,9 +508,11 @@ struct row_prebuilt_struct {
|
||||||
dtuple_t* clust_ref; /* prebuilt dtuple used in
|
dtuple_t* clust_ref; /* prebuilt dtuple used in
|
||||||
sel/upd/del */
|
sel/upd/del */
|
||||||
ulint select_lock_type;/* LOCK_NONE, LOCK_S, or LOCK_X */
|
ulint select_lock_type;/* LOCK_NONE, LOCK_S, or LOCK_X */
|
||||||
ulint stored_select_lock_type;/* inside LOCK TABLES, either
|
ulint stored_select_lock_type;/* this field is used to
|
||||||
LOCK_S or LOCK_X depending on the lock
|
remember the original select_lock_type
|
||||||
type */
|
that was decided in ha_innodb.cc,
|
||||||
|
::store_lock(), ::external_lock(),
|
||||||
|
etc. */
|
||||||
ulint mysql_row_len; /* length in bytes of a row in the
|
ulint mysql_row_len; /* length in bytes of a row in the
|
||||||
MySQL format */
|
MySQL format */
|
||||||
ulint n_rows_fetched; /* number of rows fetched after
|
ulint n_rows_fetched; /* number of rows fetched after
|
||||||
|
|
|
@ -767,6 +767,7 @@ ha_innobase::init_table_handle_for_HANDLER(void)
|
||||||
if the trx isolation level would have been specified as SERIALIZABLE */
|
if the trx isolation level would have been specified as SERIALIZABLE */
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_NONE;
|
prebuilt->select_lock_type = LOCK_NONE;
|
||||||
|
prebuilt->stored_select_lock_type = LOCK_NONE;
|
||||||
|
|
||||||
/* Always fetch all columns in the index record */
|
/* Always fetch all columns in the index record */
|
||||||
|
|
||||||
|
@ -4562,40 +4563,40 @@ ha_innobase::start_stmt(
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_X;
|
prebuilt->select_lock_type = LOCK_X;
|
||||||
} else {
|
} else {
|
||||||
/* When we first come here after LOCK TABLES,
|
if (trx->isolation_level != TRX_ISO_SERIALIZABLE
|
||||||
select_lock_type is set to LOCK_S or LOCK_X. Store the value
|
&& thd->lex.sql_command == SQLCOM_SELECT
|
||||||
in case we run also consistent reads and need to restore the
|
&& thd->lex.lock_option == TL_READ) {
|
||||||
value later. */
|
|
||||||
|
/* For other than temporary tables, we obtain
|
||||||
|
no lock for consistent read (plain SELECT). */
|
||||||
|
|
||||||
if (prebuilt->select_lock_type != LOCK_NONE) {
|
prebuilt->select_lock_type = LOCK_NONE;
|
||||||
prebuilt->stored_select_lock_type =
|
} else {
|
||||||
prebuilt->select_lock_type;
|
/* Not a consistent read: restore the
|
||||||
|
select_lock_type value. The value of
|
||||||
|
stored_select_lock_type was decided in:
|
||||||
|
1) ::store_lock(),
|
||||||
|
2) ::external_lock(), and
|
||||||
|
3) ::init_table_handle_for_HANDLER(). */
|
||||||
|
|
||||||
|
prebuilt->select_lock_type =
|
||||||
|
prebuilt->stored_select_lock_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (prebuilt->stored_select_lock_type != LOCK_S
|
if (prebuilt->stored_select_lock_type != LOCK_S
|
||||||
&& prebuilt->stored_select_lock_type != LOCK_X) {
|
&& prebuilt->stored_select_lock_type != LOCK_X) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"InnoDB: Error: select_lock_type is %lu inside ::start_stmt()!\n",
|
"InnoDB: Error: stored_select_lock_type is %lu inside ::start_stmt()!\n",
|
||||||
prebuilt->stored_select_lock_type);
|
prebuilt->stored_select_lock_type);
|
||||||
|
|
||||||
ut_error;
|
/* Set the value to LOCK_X: this is just fault
|
||||||
}
|
tolerance, we do not know what the correct value
|
||||||
|
should be! */
|
||||||
|
|
||||||
if (thd->lex.sql_command == SQLCOM_SELECT
|
prebuilt->select_lock_type = LOCK_X;
|
||||||
&& thd->lex.lock_option == TL_READ) {
|
|
||||||
|
|
||||||
/* For other than temporary tables, we obtain
|
|
||||||
no lock for consistent read (plain SELECT) */
|
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_NONE;
|
|
||||||
} else {
|
|
||||||
/* Not a consistent read: restore the
|
|
||||||
select_lock_type value */
|
|
||||||
prebuilt->select_lock_type =
|
|
||||||
prebuilt->stored_select_lock_type;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the MySQL flag to mark that there is an active transaction */
|
/* Set the MySQL flag to mark that there is an active transaction */
|
||||||
thd->transaction.all.innodb_active_trans = 1;
|
thd->transaction.all.innodb_active_trans = 1;
|
||||||
|
|
||||||
|
@ -4656,6 +4657,7 @@ ha_innobase::external_lock(
|
||||||
/* If this is a SELECT, then it is in UPDATE TABLE ...
|
/* If this is a SELECT, then it is in UPDATE TABLE ...
|
||||||
or SELECT ... FOR UPDATE */
|
or SELECT ... FOR UPDATE */
|
||||||
prebuilt->select_lock_type = LOCK_X;
|
prebuilt->select_lock_type = LOCK_X;
|
||||||
|
prebuilt->stored_select_lock_type = LOCK_X;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_type != F_UNLCK) {
|
if (lock_type != F_UNLCK) {
|
||||||
|
@ -4910,14 +4912,22 @@ ha_innobase::store_lock(
|
||||||
{
|
{
|
||||||
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
|
||||||
|
|
||||||
if (lock_type == TL_READ_WITH_SHARED_LOCKS ||
|
if ((lock_type == TL_READ && thd->in_lock_tables) ||
|
||||||
|
(lock_type == TL_READ_HIGH_PRIORITY && thd->in_lock_tables) ||
|
||||||
|
lock_type == TL_READ_WITH_SHARED_LOCKS ||
|
||||||
lock_type == TL_READ_NO_INSERT) {
|
lock_type == TL_READ_NO_INSERT) {
|
||||||
/* This is a SELECT ... IN SHARE MODE, or
|
/* The OR cases above are in this order:
|
||||||
we are doing a complex SQL statement like
|
1) MySQL is doing LOCK TABLES ... READ LOCAL, or
|
||||||
|
2) (we do not know when TL_READ_HIGH_PRIORITY is used), or
|
||||||
|
3) this is a SELECT ... IN SHARE MODE, or
|
||||||
|
4) we are doing a complex SQL statement like
|
||||||
INSERT INTO ... SELECT ... and the logical logging (MySQL
|
INSERT INTO ... SELECT ... and the logical logging (MySQL
|
||||||
binlog) requires the use of a locking read */
|
binlog) requires the use of a locking read, or
|
||||||
|
MySQL is doing LOCK TABLES ... READ. */
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_S;
|
prebuilt->select_lock_type = LOCK_S;
|
||||||
|
prebuilt->stored_select_lock_type = LOCK_S;
|
||||||
|
|
||||||
} else if (lock_type != TL_IGNORE) {
|
} else if (lock_type != TL_IGNORE) {
|
||||||
|
|
||||||
/* In ha_berkeley.cc there is a comment that MySQL
|
/* In ha_berkeley.cc there is a comment that MySQL
|
||||||
|
@ -4928,6 +4938,7 @@ ha_innobase::store_lock(
|
||||||
here even if this would be SELECT ... FOR UPDATE */
|
here even if this would be SELECT ... FOR UPDATE */
|
||||||
|
|
||||||
prebuilt->select_lock_type = LOCK_NONE;
|
prebuilt->select_lock_type = LOCK_NONE;
|
||||||
|
prebuilt->stored_select_lock_type = LOCK_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
|
if (lock_type != TL_IGNORE && lock.type == TL_UNLOCK) {
|
||||||
|
|
Loading…
Reference in a new issue