diff options
author | unknown <heikki@work.mysql.com> | 2002-09-04 18:53:48 +0200 |
---|---|---|
committer | unknown <heikki@work.mysql.com> | 2002-09-04 18:53:48 +0200 |
commit | 385319b2cfad4edcd926f5bd5163c7921ca832e3 (patch) | |
tree | ef3cb267c01475b0d1b8c2385ecee59dcd84b7f4 | |
parent | bc995f9a19f4aeef276ecc883e180dcaca8996b7 (diff) | |
download | mariadb-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.c | 19 | ||||
-rw-r--r-- | innobase/dict/dict0dict.c | 21 | ||||
-rw-r--r-- | innobase/include/dict0dict.h | 10 | ||||
-rw-r--r-- | sql/ha_innodb.cc | 68 |
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; } } } |