summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <heikki@work.mysql.com>2002-09-04 18:53:48 +0200
committerunknown <heikki@work.mysql.com>2002-09-04 18:53:48 +0200
commit385319b2cfad4edcd926f5bd5163c7921ca832e3 (patch)
treeef3cb267c01475b0d1b8c2385ecee59dcd84b7f4
parentbc995f9a19f4aeef276ecc883e180dcaca8996b7 (diff)
downloadmariadb-git-385319b2cfad4edcd926f5bd5163c7921ca832e3.tar.gz
btr0btr.c Add more documentation about B-tree latching
ha_innodb.cc Remove gaps in auto-inc in multi-row inserts, more space for foreign key listings in SHOW TABLE STATUS, move resetting of active_trx to amore logical place dict0dict.h Remove gaps from auto-inc sequence if errors in multi-row insert dict0dict.c Remove gaps from auto-inc sequence if errors in multi-row insert innobase/dict/dict0dict.c: Remove gaps from auto-inc sequence if errors in multi-row insert innobase/include/dict0dict.h: Remove gaps from auto-inc sequence if errors in multi-row insert sql/ha_innodb.cc: Remove gaps in auto-inc in multi-row inserts, more space for foreign key listings in SHOW TABLE STATUS, move resetting of active_trx to amore logical place innobase/btr/btr0btr.c: Add more documentation about B-tree latching
-rw-r--r--innobase/btr/btr0btr.c19
-rw-r--r--innobase/dict/dict0dict.c21
-rw-r--r--innobase/include/dict0dict.h10
-rw-r--r--sql/ha_innodb.cc68
4 files changed, 75 insertions, 43 deletions
diff --git a/innobase/btr/btr0btr.c b/innobase/btr/btr0btr.c
index 38d97785832..7a7678b2dcf 100644
--- a/innobase/btr/btr0btr.c
+++ b/innobase/btr/btr0btr.c
@@ -22,6 +22,25 @@ Created 6/2/1994 Heikki Tuuri
#include "ibuf0ibuf.h"
/*
+Latching strategy of the InnoDB B-tree
+--------------------------------------
+A tree latch protects all non-leaf nodes of the tree. Each node of a tree
+also has a latch of its own.
+
+A B-tree operation normally first acquires an S-latch on the tree. It
+searches down the tree and releases the tree latch when it has the
+leaf node latch. To save CPU time we do not acquire any latch on
+non-leaf nodes of the tree during a search, those pages are only bufferfixed.
+
+If an operation needs to restructure the tree, it acquires an X-latch on
+the tree before searching to a leaf node. If it needs, for example, to
+split a leaf,
+(1) InnoDB decides the split point in the leaf,
+(2) allocates a new page,
+(3) inserts the appropriate node pointer to the first non-leaf level,
+(4) releases the tree X-latch,
+(5) and then moves records from the leaf to the new allocated page.
+
Node pointers
-------------
Leaf pages of a B-tree contain the index records stored in the
diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c
index 85199b90a5a..7bf85557cde 100644
--- a/innobase/dict/dict0dict.c
+++ b/innobase/dict/dict0dict.c
@@ -308,29 +308,18 @@ dict_table_autoinc_get(
}
/************************************************************************
-Reads the autoinc counter value, 0 if not yet initialized. Does not
-increment the counter. */
+Decrements the autoinc counter value by 1. */
-ib_longlong
-dict_table_autoinc_read(
-/*====================*/
- /* out: value of the counter */
+void
+dict_table_autoinc_decrement(
+/*=========================*/
dict_table_t* table) /* in: table */
{
- ib_longlong value;
-
mutex_enter(&(table->autoinc_mutex));
- if (!table->autoinc_inited) {
-
- value = 0;
- } else {
- value = table->autoinc;
- }
+ table->autoinc = table->autoinc - 1;
mutex_exit(&(table->autoinc_mutex));
-
- return(value);
}
/************************************************************************
diff --git a/innobase/include/dict0dict.h b/innobase/include/dict0dict.h
index 832654d2666..bf393210763 100644
--- a/innobase/include/dict0dict.h
+++ b/innobase/include/dict0dict.h
@@ -114,13 +114,11 @@ dict_table_autoinc_get(
/* out: value for a new row, or 0 */
dict_table_t* table); /* in: table */
/************************************************************************
-Reads the autoinc counter value, 0 if not yet initialized. Does not
-increment the counter. */
+Decrements the autoinc counter value by 1. */
-ib_longlong
-dict_table_autoinc_read(
-/*====================*/
- /* out: value of the counter */
+void
+dict_table_autoinc_decrement(
+/*=========================*/
dict_table_t* table); /* in: table */
/************************************************************************
Peeks the autoinc counter value, 0 if not yet initialized. Does not
diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc
index ec32b0aa78a..13c83d48471 100644
--- a/sql/ha_innodb.cc
+++ b/sql/ha_innodb.cc
@@ -405,8 +405,6 @@ ha_innobase::update_thd(
return(0);
}
-/* The code here appears for documentational purposes only. Not used
-or tested yet. Will be used in 4.1. */
/*********************************************************************
Call this when you have opened a new table handle in HANDLER, before you
call index_read_idx() etc. Actually, we can let the cursor stay open even
@@ -667,20 +665,20 @@ innobase_commit_low(
/*================*/
trx_t* trx) /* in: transaction handle */
{
- if (current_thd->slave_thread)
- {
- /* Update the replication position info inside InnoDB */
+ if (current_thd->slave_thread) {
+ /* Update the replication position info inside InnoDB */
#ifdef NEED_TO_BE_FIXED
- trx->mysql_relay_log_file_name= active_mi->rli.log_file_name;
- trx->mysql_relay_log_pos= active_mi->rli.relay_log_pos;
+ trx->mysql_relay_log_file_name = active_mi->rli.log_file_name;
+ trx->mysql_relay_log_pos = active_mi->rli.relay_log_pos;
#endif
- trx->mysql_master_log_file_name= active_mi->rli.master_log_name;
- trx->mysql_master_log_pos= ((ib_longlong)
+ trx->mysql_master_log_file_name
+ = active_mi->rli.master_log_name;
+ trx->mysql_master_log_pos = ((ib_longlong)
(active_mi->rli.master_log_pos +
active_mi->rli.event_len +
active_mi->rli.pending));
- }
- trx_commit_for_mysql(trx);
+ }
+ trx_commit_for_mysql(trx);
}
/*********************************************************************
@@ -692,7 +690,8 @@ innobase_commit(
/* out: 0 or error number */
THD* thd, /* in: MySQL thread handle of the user for whom
the transaction should be committed */
- void* trx_handle)/* in: InnoDB trx handle or NULL: NULL means
+ void* trx_handle)/* in: InnoDB trx handle or
+ &innodb_dummy_stmt_trx_handle: the latter means
that the current SQL statement ended, and we should
mark the start of a new statement with a savepoint */
{
@@ -716,6 +715,7 @@ innobase_commit(
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
innobase_commit_low(trx);
+ thd->transaction.all.innodb_active_trans=0;
}
/* Release possible statement level resources */
@@ -772,7 +772,9 @@ innobase_rollback(
/* out: 0 or error number */
THD* thd, /* in: handle to the MySQL thread of the user
whose transaction should be rolled back */
- void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle */
+ void* trx_handle)/* in: InnoDB trx handle or a dummy stmt handle;
+ the latter means we roll back the latest SQL
+ statement */
{
int error = 0;
trx_t* trx;
@@ -796,6 +798,7 @@ innobase_rollback(
if (trx_handle != (void*)&innodb_dummy_stmt_trx_handle) {
error = trx_rollback_for_mysql(trx);
+ thd->transaction.all.innodb_active_trans=0;
} else {
error = trx_rollback_last_sql_stat_for_mysql(trx);
}
@@ -1190,11 +1193,11 @@ innobase_mysql_cmp(
ret = my_sortncmp((const char*) a, a_length,
(const char*) b, b_length);
if (ret < 0) {
- return(-1);
+ return(-1);
} else if (ret > 0) {
- return(1);
+ return(1);
} else {
- return(0);
+ return(0);
}
default:
assert(0);
@@ -1497,6 +1500,8 @@ ha_innobase::write_row(
int error;
longlong auto_inc;
longlong dummy;
+ ibool incremented_auto_inc_for_stat = FALSE;
+ ibool incremented_auto_inc_counter = FALSE;
DBUG_ENTER("ha_innobase::write_row");
@@ -1567,6 +1572,7 @@ ha_innobase::write_row(
assign sequential values from the counter. */
auto_inc_counter_for_this_stat++;
+ incremented_auto_inc_for_stat = TRUE;
auto_inc = auto_inc_counter_for_this_stat;
@@ -1615,7 +1621,12 @@ ha_innobase::write_row(
}
}
+ /* The following call gets the value of the auto-inc
+ counter of the table and increments it by 1 */
+
auto_inc = dict_table_autoinc_get(prebuilt->table);
+ incremented_auto_inc_counter = TRUE;
+
srv_conc_exit_innodb(prebuilt->trx);
/* We can give the new value for MySQL to place in
@@ -1652,6 +1663,20 @@ ha_innobase::write_row(
srv_conc_exit_innodb(prebuilt->trx);
+ if (error != DB_SUCCESS) {
+ /* If the insert did not succeed we restore the value of
+ the auto-inc counter we used; note that this behavior was
+ introduced only in version 4.0.4 */
+
+ if (incremented_auto_inc_counter) {
+ dict_autoinc_decrement(prebuilt->table);
+ }
+
+ if (incremented_auto_inc_for_stat) {
+ auto_inc_counter_for_this_stat--;
+ }
+ }
+
prebuilt->trx->ignore_duplicates_in_insert = FALSE;
error = convert_error_code_to_mysql(error, user_thd);
@@ -3311,7 +3336,7 @@ ha_innobase::update_table_comment(
{
row_prebuilt_t* prebuilt = (row_prebuilt_t*)innobase_prebuilt;
uint length = strlen(comment);
- char* str = my_malloc(length + 550, MYF(0));
+ char* str = my_malloc(length + 16500, MYF(0));
char* pos;
/* Warning: since it is not sure that MySQL calls external_lock
@@ -3333,10 +3358,12 @@ ha_innobase::update_table_comment(
(pos,"InnoDB free: %lu kB",
(ulong) innobase_get_free_space()));
- /* We assume 450 - length bytes of space to print info */
+ /* We assume 16000 - length bytes of space to print info; the limit
+ 16000 bytes is arbitrary, and MySQL could handle at least 64000
+ bytes */
- if (length < 450) {
- dict_print_info_on_foreign_keys(FALSE, pos, 450 - length,
+ if (length < 16000) {
+ dict_print_info_on_foreign_keys(FALSE, pos, 16000 - length,
prebuilt->table);
}
@@ -3508,7 +3535,6 @@ ha_innobase::external_lock(
& (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))) {
innobase_commit(thd, trx);
- thd->transaction.all.innodb_active_trans=0;
}
}
}