Commit 95cb4cc8 authored by unknown's avatar unknown

ha_innobase.cc:

  Since MySQL commits the stmt always at the end of an INSERT, it is enough to release auto-inc lock at innobase_commit and innobase_rollback; add also more comments to code


sql/ha_innobase.cc:
  Since MySQL commits the stmt always at the end of an INSERT, it is enough to release auto-inc lock at innobase_commit and innobase_rollback; add also more comments to code
parent d47ee142
...@@ -130,8 +130,9 @@ static void innobase_print_error(const char* db_errpfx, char* buffer); ...@@ -130,8 +130,9 @@ static void innobase_print_error(const char* db_errpfx, char* buffer);
/* General functions */ /* General functions */
/********************************************************************** /**********************************************************************
Releases possible search latch, auto inc lock, and InnoDB thread FIFO ticket. Releases possible search latch and InnoDB thread FIFO ticket. These should
These should be released at each SQL statement end. */ be released at each SQL statement end. It does no harm to release these
also in the middle of an SQL statement. */
static static
void void
innobase_release_stat_resources( innobase_release_stat_resources(
...@@ -142,16 +143,6 @@ innobase_release_stat_resources( ...@@ -142,16 +143,6 @@ innobase_release_stat_resources(
trx_search_latch_release_if_reserved(trx); trx_search_latch_release_if_reserved(trx);
} }
if (trx->auto_inc_lock) {
/* If we had reserved the auto-inc lock for
some table in this SQL statement, we release it now */
srv_conc_enter_innodb(trx);
row_unlock_table_autoinc_for_mysql(trx);
srv_conc_exit_innodb(trx);
}
if (trx->declared_to_be_inside_innodb) { if (trx->declared_to_be_inside_innodb) {
/* Release our possible ticket in the FIFO */ /* Release our possible ticket in the FIFO */
...@@ -635,6 +626,16 @@ innobase_commit( ...@@ -635,6 +626,16 @@ innobase_commit(
trx = check_trx_exists(thd); trx = check_trx_exists(thd);
if (trx->auto_inc_lock) {
/* If we had reserved the auto-inc lock for
some table in this SQL statement, we release it now */
srv_conc_enter_innodb(trx);
row_unlock_table_autoinc_for_mysql(trx);
srv_conc_exit_innodb(trx);
}
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
innobase_commit_low(trx); innobase_commit_low(trx);
} }
...@@ -704,6 +705,16 @@ innobase_rollback( ...@@ -704,6 +705,16 @@ innobase_rollback(
trx = check_trx_exists(thd); trx = check_trx_exists(thd);
if (trx->auto_inc_lock) {
/* If we had reserved the auto-inc lock for
some table in this SQL statement, we release it now */
srv_conc_enter_innodb(trx);
row_unlock_table_autoinc_for_mysql(trx);
srv_conc_exit_innodb(trx);
}
srv_conc_enter_innodb(trx); srv_conc_enter_innodb(trx);
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) { if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
...@@ -1900,6 +1911,55 @@ convert_search_mode_to_innobase( ...@@ -1900,6 +1911,55 @@ convert_search_mode_to_innobase(
return(0); return(0);
} }
/*
BACKGROUND INFO: HOW A SELECT SQL QUERY IS EXECUTED
---------------------------------------------------
The following does not cover all the details, but explains how we determine
the start of a new SQL statement, and what is associated with it.
For each table in the database the MySQL interpreter may have several
table handle instances in use, also in a single SQL query. For each table
handle instance there is an InnoDB 'prebuilt' struct which contains most
of the InnoDB data associated with this table handle instance.
A) if the user has not explicitly set any MySQL table level locks:
1) MySQL calls ::external_lock to set an 'intention' table level lock on
the table of the handle instance. There we set
prebuilt->sql_stat_start = TRUE. The flag sql_stat_start should be set
true if we are taking this table handle instance to use in a new SQL
statement issued by the user. We also increment trx->n_mysql_tables_in_use.
2) If prebuilt->sql_stat_start == TRUE we 'pre-compile' the MySQL search
instructions to prebuilt->template of the table handle instance in
::index_read. The template is used to save CPU time in large joins.
3) In row_search_for_mysql, if prebuilt->sql_stat_start is true, we
allocate a new consistent read view for the trx if it does not yet have one,
or in the case of a locking read, set an InnoDB 'intention' table level
lock on the table.
4) We do the SELECT. MySQL may repeatedly call ::index_read for the
same table handle instance, if it is a join.
5) When the SELECT ends, MySQL removes its intention table level locks
in ::external_lock. When trx->n_mysql_tables_in_use drops to zero,
(a) we execute a COMMIT there if the autocommit is on,
(b) we also release possible 'SQL statement level resources' InnoDB may
have for this SQL statement. The MySQL interpreter does NOT execute
autocommit for pure read transactions, though it should. That is why the
table handler in that case has to execute the COMMIT in ::external_lock.
B) If the user has explicitly set MySQL table level locks, then MySQL
does NOT call ::external_lock at the start of the statement. To determine
when we are at the start of a new SQL statement we at the start of
::index_read also compare the query id to the latest query id where the
table handle instance was used. If it has changed, we know we are at the
start of a new SQL statement. Since the query id can theoretically
overwrap, we use this test only as a secondary way of determining the
start of a new SQL statement. */
/************************************************************************** /**************************************************************************
Positions an index cursor to the index specified in the handle. Fetches the Positions an index cursor to the index specified in the handle. Fetches the
row if any. */ row if any. */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment