summaryrefslogtreecommitdiff
path: root/sql/ha_innodb.cc
diff options
context:
space:
mode:
authorunknown <monty@hundin.mysql.fi>2002-01-30 16:37:47 +0200
committerunknown <monty@hundin.mysql.fi>2002-01-30 16:37:47 +0200
commit85278245af45fc301dc7940bec9a3434003285a6 (patch)
tree3ca7f6fddbb9bdc0b635f243af69c6606924c3c2 /sql/ha_innodb.cc
parent9369764f2226e0e8cb9724bcdac256f45330ba67 (diff)
parent8a56717c4ce14aa7e36e04a8dc880dcc1311ea28 (diff)
downloadmariadb-git-85278245af45fc301dc7940bec9a3434003285a6.tar.gz
Merge from 3.23.48 tree
BitKeeper/etc/logging_ok: auto-union Docs/manual.texi: Auto merged innobase/dict/dict0dict.c: Auto merged innobase/include/srv0srv.h: Auto merged innobase/mem/mem0dbg.c: Auto merged innobase/os/os0file.c: Auto merged innobase/que/que0que.c: Auto merged innobase/rem/rem0rec.c: Auto merged innobase/row/row0sel.c: Auto merged innobase/srv/srv0srv.c: Auto merged innobase/srv/srv0start.c: Auto merged innobase/sync/sync0arr.c: Auto merged innobase/trx/trx0trx.c: Auto merged innobase/trx/trx0undo.c: Auto merged myisam/mi_check.c: Auto merged mysql-test/t/join.test: Auto merged mysys/hash.c: Auto merged scripts/mysql_config.sh: Auto merged sql/ha_innodb.h: Auto merged sql/handler.cc: Auto merged sql/handler.h: Auto merged sql/sql_acl.cc: Auto merged
Diffstat (limited to 'sql/ha_innodb.cc')
-rw-r--r--sql/ha_innodb.cc269
1 files changed, 170 insertions, 99 deletions
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index 8941481a95f..a86bd21934b 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -14,8 +14,8 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-/* This file defines the InnoDB handler: the interface between MySQL and
-InnoDB */
+/*
+ This file defines the InnoDB handler: the interface between MySQL and InnoDB */
/* TODO list for the InnoDB handler:
- Ask Monty if strings of different languages can exist in the same
@@ -118,6 +118,36 @@ static void innobase_print_error(const char* db_errpfx, char* buffer);
/* General functions */
+/**********************************************************************
+Releases possible search latch, auto inc lock, and InnoDB thread FIFO ticket.
+These should be released at each SQL statement end. */
+static
+void
+innobase_release_stat_resources(
+/*============================*/
+ trx_t* trx) /* in: transaction object */
+{
+ if (trx->has_search_latch) {
+ 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) {
+ /* Release our possible ticket in the FIFO */
+
+ srv_conc_force_exit_innodb(trx);
+ }
+}
+
/************************************************************************
Increments innobase_active_counter and every INNOBASE_WAKE_INTERVALth
time calls srv_active_wake_master_thread. This function should be used
@@ -715,13 +745,12 @@ innobase_commit(
trx = check_trx_exists(thd);
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
- srv_conc_enter_innodb(trx);
trx_commit_for_mysql(trx);
-
- srv_conc_exit_innodb();
}
+ /* Release possible statement level resources */
+ innobase_release_stat_resources(trx);
trx_mark_sql_stat_end(trx);
#ifndef DBUG_OFF
@@ -738,6 +767,32 @@ innobase_commit(
}
/*********************************************************************
+This is called when MySQL writes the binlog entry for the current
+transaction. Writes to the InnoDB tablespace info which tells where the
+MySQL binlog entry for the current transaction ended. Also commits the
+transaction inside InnoDB. */
+
+int
+innobase_report_binlog_offset_and_commit(
+/*=====================================*/
+ /* out: 0 or error code */
+ THD* thd, /* in: user thread */
+ void* trx_handle, /* in: InnoDB trx handle */
+ char* log_file_name, /* in: latest binlog file name */
+ my_off_t end_offset) /* in: the offset in the binlog file
+ up to which we wrote */
+{
+ trx_t* trx;
+
+ trx = (trx_t*)trx_handle;
+
+ trx->mysql_log_file_name = log_file_name;
+ trx->mysql_log_offset = (ib_longlong)end_offset;
+
+ return(innobase_commit(thd, trx_handle));
+}
+
+/*********************************************************************
Rolls back a transaction in an InnoDB database. */
int
@@ -764,7 +819,10 @@ innobase_rollback(
error = trx_rollback_last_sql_stat_for_mysql(trx);
}
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(trx);
+
+ /* Release possible statement level resources */
+ innobase_release_stat_resources(trx);
trx_mark_sql_stat_end(trx);
@@ -1437,6 +1495,8 @@ ha_innobase::write_row(
if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
}
if (table->next_number_field && record == table->record[0]) {
@@ -1487,7 +1547,7 @@ ha_innobase::write_row(
srv_conc_enter_innodb(prebuilt->trx);
error = row_lock_table_autoinc_for_mysql(prebuilt);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
if (error != DB_SUCCESS) {
@@ -1504,7 +1564,7 @@ ha_innobase::write_row(
error = row_lock_table_autoinc_for_mysql(
prebuilt);
if (error != DB_SUCCESS) {
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
error = convert_error_code_to_mysql(
error);
@@ -1513,7 +1573,7 @@ ha_innobase::write_row(
}
auto_inc = dict_table_autoinc_get(prebuilt->table);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
/* If auto_inc is now != 0 the autoinc counter
was already initialized for the table: we can give
@@ -1540,7 +1600,7 @@ ha_innobase::write_row(
srv_conc_enter_innodb(prebuilt->trx);
error = row_lock_table_autoinc_for_mysql(prebuilt);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
if (error != DB_SUCCESS) {
@@ -1580,7 +1640,7 @@ ha_innobase::write_row(
error = row_insert_for_mysql((byte*) record, prebuilt);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
@@ -1775,6 +1835,8 @@ ha_innobase::update_row(
if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
}
if (prebuilt->upd_node) {
@@ -1799,7 +1861,7 @@ ha_innobase::update_row(
error = row_update_for_mysql((byte*) old_row, prebuilt);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
error = convert_error_code_to_mysql(error);
@@ -1828,6 +1890,8 @@ ha_innobase::delete_row(
if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
}
if (!prebuilt->upd_node) {
@@ -1843,7 +1907,7 @@ ha_innobase::delete_row(
error = row_update_for_mysql((byte*) record, prebuilt);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
error = convert_error_code_to_mysql(error);
@@ -1942,6 +2006,8 @@ ha_innobase::index_read(
if (last_query_id != user_thd->query_id) {
prebuilt->sql_stat_start = TRUE;
last_query_id = user_thd->query_id;
+
+ innobase_release_stat_resources(prebuilt->trx);
}
index = prebuilt->index;
@@ -1987,7 +2053,7 @@ ha_innobase::index_read(
ret = row_search_for_mysql((byte*) buf, mode, prebuilt, match_mode, 0);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
if (ret == DB_SUCCESS) {
error = 0;
@@ -2126,7 +2192,7 @@ ha_innobase::general_fetch(
ret = row_search_for_mysql((byte*)buf, 0, prebuilt, match_mode,
direction);
- srv_conc_exit_innodb();
+ srv_conc_exit_innodb(prebuilt->trx);
if (ret == DB_SUCCESS) {
error = 0;
@@ -2426,88 +2492,6 @@ int ha_innobase::reset(void)
return(0);
}
-/**********************************************************************
-As MySQL will execute an external lock for every new table it uses when it
-starts to process an SQL statement, we can use this function to store the
-pointer to the THD in the handle. We will also use this function to communicate
-to InnoDB that a new SQL statement has started and that we must store a
-savepoint to our transaction handle, so that we are able to roll back
-the SQL statement in case of an error. */
-
-int
-ha_innobase::external_lock(
-/*=======================*/
- THD* thd, /* in: handle to the user thread */
- int lock_type) /* in: lock type */
-{
- row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
- int error = 0;
- trx_t* trx;
-
- DBUG_ENTER("ha_innobase::external_lock");
-
- update_thd(thd);
-
- trx = prebuilt->trx;
-
- prebuilt->sql_stat_start = TRUE;
- prebuilt->in_update_remember_pos = TRUE;
-
- prebuilt->read_just_key = 0;
-
- if (lock_type == F_WRLCK) {
-
- /* If this is a SELECT, then it is in UPDATE TABLE ...
- or SELECT ... FOR UPDATE */
- prebuilt->select_lock_type = LOCK_X;
- }
-
- if (lock_type != F_UNLCK) {
- if (trx->n_mysql_tables_in_use == 0) {
- trx_mark_sql_stat_end(trx);
- }
-
- thd->transaction.all.innodb_active_trans = 1;
- trx->n_mysql_tables_in_use++;
-
- if (prebuilt->select_lock_type != LOCK_NONE) {
-
- trx->mysql_n_tables_locked++;
- }
- } else {
- trx->n_mysql_tables_in_use--;
- auto_inc_counter_for_this_stat = 0;
-
- if (trx->n_mysql_tables_in_use == 0) {
-
- trx->mysql_n_tables_locked = 0;
-
- if (trx->has_search_latch) {
-
- 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();
- }
-
- if (!(thd->options
- & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
-
- innobase_commit(thd, trx);
- }
- }
- }
-
- DBUG_RETURN(error);
-}
/*********************************************************************
Creates a table definition to an InnoDB database. */
@@ -2684,7 +2668,7 @@ ha_innobase::create(
/* Create the table definition in InnoDB */
- if ((error = create_table_def(trx, form, norm_name))) {
+ if (error = create_table_def(trx, form, norm_name)) {
trx_commit_for_mysql(trx);
@@ -3166,7 +3150,22 @@ ha_innobase::info(
rec_per_key = 1;
}
- table->key_info[i].rec_per_key[j]
+ /* Since the MySQL optimizer is often too
+ pessimistic in the assumption that a table
+ does not fit in the buffer pool, we
+ increase the attractiveness of indexes
+ by assuming the selectivity of any prefix
+ of an index is 1 / 100 or better.
+ (Actually, we should look at the table
+ size, and if the table is smaller than
+ the buffer pool, we should uniformly
+ increase the attractiveness of indexes,
+ regardless of the estimated selectivity.) */
+
+ if (rec_per_key > records / 100) {
+ rec_per_key = records / 100;
+ }
+ table->key_info[i].rec_per_key[j]
= rec_per_key;
}
@@ -3264,6 +3263,78 @@ ha_innobase::update_table_comment(
return(str);
}
+/**********************************************************************
+As MySQL will execute an external lock for every new table it uses when it
+starts to process an SQL statement, we can use this function to store the
+pointer to the THD in the handle. We will also use this function to communicate
+to InnoDB that a new SQL statement has started and that we must store a
+savepoint to our transaction handle, so that we are able to roll back
+the SQL statement in case of an error. */
+
+int
+ha_innobase::external_lock(
+/*=======================*/
+ THD* thd, /* in: handle to the user thread */
+ int lock_type) /* in: lock type */
+{
+ row_prebuilt_t* prebuilt = (row_prebuilt_t*) innobase_prebuilt;
+ int error = 0;
+ trx_t* trx;
+
+ DBUG_ENTER("ha_innobase::external_lock");
+
+ update_thd(thd);
+
+ trx = prebuilt->trx;
+
+ prebuilt->sql_stat_start = TRUE;
+ prebuilt->in_update_remember_pos = TRUE;
+
+ prebuilt->read_just_key = 0;
+
+ if (lock_type == F_WRLCK) {
+
+ /* If this is a SELECT, then it is in UPDATE TABLE ...
+ or SELECT ... FOR UPDATE */
+ prebuilt->select_lock_type = LOCK_X;
+ }
+
+ if (lock_type != F_UNLCK) {
+ if (trx->n_mysql_tables_in_use == 0) {
+ trx_mark_sql_stat_end(trx);
+ }
+
+ thd->transaction.all.innodb_active_trans = 1;
+ trx->n_mysql_tables_in_use++;
+
+ if (prebuilt->select_lock_type != LOCK_NONE) {
+
+ trx->mysql_n_tables_locked++;
+ }
+ } else {
+ trx->n_mysql_tables_in_use--;
+ auto_inc_counter_for_this_stat = 0;
+
+ if (trx->n_mysql_tables_in_use == 0) {
+
+ trx->mysql_n_tables_locked = 0;
+
+ /* Here we release the search latch, auto_inc_lock,
+ and InnoDB thread FIFO ticket if they were reserved. */
+
+ innobase_release_stat_resources(trx);
+
+ if (!(thd->options
+ & (OPTION_NOT_AUTO_COMMIT | OPTION_BEGIN))) {
+
+ innobase_commit(thd, trx);
+ }
+ }
+ }
+
+ DBUG_RETURN(error);
+}
+
/****************************************************************************
Handling the shared INNOBASE_SHARE structure that is needed to provide table
locking.