#At file:///usr/local/devel/bzrroot/server/mysql-trunk-innodb/ based on revid:vasil.dimov@stripped
3233 Vasil Dimov 2010-08-24 [merge]
Merge mysql-5.5-innodb -> mysql-trunk-innodb
modified:
storage/innobase/dict/dict0dict.c
storage/innobase/handler/ha_innodb.cc
storage/innobase/include/buf0flu.h
storage/innobase/row/row0sel.c
storage/innobase/srv/srv0srv.c
storage/innobase/srv/srv0start.c
=== modified file 'storage/innobase/dict/dict0dict.c'
--- a/storage/innobase/dict/dict0dict.c revid:vasil.dimov@stripped
+++ b/storage/innobase/dict/dict0dict.c revid:vasil.dimov@stripped
@@ -4209,7 +4209,6 @@ dict_update_statistics_low(
dictionary mutex */
{
dict_index_t* index;
- ulint size;
ulint sum_of_index_sizes = 0;
if (table->ibd_file_missing) {
@@ -4224,14 +4223,6 @@ dict_update_statistics_low(
return;
}
- /* If we have set a high innodb_force_recovery level, do not calculate
- statistics, as a badly corrupted index can cause a crash in it. */
-
- if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
-
- return;
- }
-
/* Find out the sizes of the indexes and how many different values
for the key they approximately have */
@@ -4243,26 +4234,48 @@ dict_update_statistics_low(
return;
}
- while (index) {
- size = btr_get_size(index, BTR_TOTAL_SIZE);
-
- index->stat_index_size = size;
- sum_of_index_sizes += size;
+ do {
+ if (UNIV_LIKELY
+ (srv_force_recovery < SRV_FORCE_NO_IBUF_MERGE
+ || (srv_force_recovery < SRV_FORCE_NO_LOG_REDO
+ && dict_index_is_clust(index)))) {
+ ulint size;
+ size = btr_get_size(index, BTR_TOTAL_SIZE);
+
+ index->stat_index_size = size;
+
+ sum_of_index_sizes += size;
+
+ size = btr_get_size(index, BTR_N_LEAF_PAGES);
+
+ if (size == 0) {
+ /* The root node of the tree is a leaf */
+ size = 1;
+ }
- size = btr_get_size(index, BTR_N_LEAF_PAGES);
+ index->stat_n_leaf_pages = size;
- if (size == 0) {
- /* The root node of the tree is a leaf */
- size = 1;
- }
+ btr_estimate_number_of_different_key_vals(index);
+ } else {
+ /* If we have set a high innodb_force_recovery
+ level, do not calculate statistics, as a badly
+ corrupted index can cause a crash in it.
+ Initialize some bogus index cardinality
+ statistics, so that the data can be queried in
+ various means, also via secondary indexes. */
+ ulint i;
- index->stat_n_leaf_pages = size;
+ sum_of_index_sizes++;
+ index->stat_index_size = index->stat_n_leaf_pages = 1;
- btr_estimate_number_of_different_key_vals(index);
+ for (i = dict_index_get_n_unique(index); i; ) {
+ index->stat_n_diff_key_vals[i--] = 1;
+ }
+ }
index = dict_table_get_next_index(index);
- }
+ } while (index);
index = dict_table_get_first_index(table);
=== modified file 'storage/innobase/handler/ha_innodb.cc'
--- a/storage/innobase/handler/ha_innodb.cc revid:vasil.dimov@stripped
+++ b/storage/innobase/handler/ha_innodb.cc revid:vasil.dimov@stripped
@@ -7714,28 +7714,15 @@ ha_innobase::info(
dict_index_t* index;
ha_rows rec_per_key;
ib_int64_t n_rows;
- ulong j;
- ulong i;
char path[FN_REFLEN];
os_file_stat_t stat_info;
-
DBUG_ENTER("info");
/* If we are forcing recovery at a high level, we will suppress
statistics calculation on tables, because that may crash the
server if an index is badly corrupted. */
- if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
-
- /* We return success (0) instead of HA_ERR_CRASHED,
- because we want MySQL to process this query and not
- stop, like it would do if it received the error code
- HA_ERR_CRASHED. */
-
- DBUG_RETURN(0);
- }
-
/* We do not know if MySQL can call this function before calling
external_lock(). To be safe, update the thd of the current table
handle. */
@@ -7830,12 +7817,18 @@ ha_innobase::info(
acquiring latches inside InnoDB, we do not call it if we
are asked by MySQL to avoid locking. Another reason to
avoid the call is that it uses quite a lot of CPU.
- See Bug#38185.
- We do not update delete_length if no locking is requested
- so the "old" value can remain. delete_length is initialized
- to 0 in the ha_statistics' constructor. */
- if (!(flag & HA_STATUS_NO_LOCK)) {
-
+ See Bug#38185. */
+ if (flag & HA_STATUS_NO_LOCK) {
+ /* We do not update delete_length if no
+ locking is requested so the "old" value can
+ remain. delete_length is initialized to 0 in
+ the ha_statistics' constructor. */
+ } else if (UNIV_UNLIKELY
+ (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE)) {
+ /* Avoid accessing the tablespace if
+ innodb_crash_recovery is set to a high value. */
+ stats.delete_length = 0;
+ } else {
/* lock the data dictionary to avoid races with
ibd_file_missing and tablespace_discarded */
row_mysql_lock_data_dictionary(prebuilt->trx);
@@ -7880,6 +7873,7 @@ ha_innobase::info(
}
if (flag & HA_STATUS_CONST) {
+ ulong i;
/* Verify the number of index in InnoDB and MySQL
matches up. If prebuilt->clust_index_was_generated
holds, InnoDB defines GEN_CLUST_INDEX internally */
@@ -7896,6 +7890,7 @@ ha_innobase::info(
}
for (i = 0; i < table->s->keys; i++) {
+ ulong j;
/* We could get index quickly through internal
index mapping with the index translation table.
The identity of index (match up index name with
@@ -7961,6 +7956,11 @@ ha_innobase::info(
}
}
+ if (srv_force_recovery >= SRV_FORCE_NO_IBUF_MERGE) {
+
+ goto func_exit;
+ }
+
if (flag & HA_STATUS_ERRKEY) {
const dict_index_t* err_index;
@@ -7981,6 +7981,7 @@ ha_innobase::info(
stats.auto_increment_value = innobase_peek_autoinc();
}
+func_exit:
prebuilt->trx->op_info = (char*)"";
DBUG_RETURN(0);
=== modified file 'storage/innobase/include/buf0flu.h'
--- a/storage/innobase/include/buf0flu.h revid:vasil.dimov@stripped
+++ b/storage/innobase/include/buf0flu.h revid:vasil.dimov@stripped
@@ -228,8 +228,8 @@ make sure that a read-ahead batch can be
sweep). */
#define BUF_FLUSH_FREE_BLOCK_MARGIN(b) (5 + BUF_READ_AHEAD_AREA(b))
/** Extra margin to apply above BUF_FLUSH_FREE_BLOCK_MARGIN */
-#define BUF_FLUSH_EXTRA_MARGIN(b) (BUF_FLUSH_FREE_BLOCK_MARGIN(b) / 4 \
- + 100)
+#define BUF_FLUSH_EXTRA_MARGIN(b) ((BUF_FLUSH_FREE_BLOCK_MARGIN(b) / 4 \
+ + 100) / srv_buf_pool_instances)
#endif /* !UNIV_HOTBACKUP */
#ifndef UNIV_NONINL
=== modified file 'storage/innobase/row/row0sel.c'
--- a/storage/innobase/row/row0sel.c revid:vasil.dimov@stripped
+++ b/storage/innobase/row/row0sel.c revid:vasil.dimov@stripped
@@ -2682,7 +2682,6 @@ row_sel_store_mysql_rec(
ut_ad(prebuilt->mysql_template);
ut_ad(prebuilt->default_rec);
ut_ad(rec_offs_validate(rec, NULL, offsets));
- ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
mem_heap_free(prebuilt->blob_heap);
@@ -3603,6 +3602,7 @@ row_search_for_mysql(
row_sel_try_search_shortcut_for_mysql().
The latch will not be released until
mtr_commit(&mtr). */
+ ut_ad(!rec_get_deleted_flag(rec, comp));
if (!row_sel_store_mysql_rec(buf, prebuilt,
rec, offsets)) {
@@ -4230,7 +4230,7 @@ no_gap_lock:
rec = old_vers;
}
- } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
+ } else {
/* We are looking into a non-clustered index,
and to get the right version of the record we
have to look also into the clustered index: this
@@ -4238,8 +4238,12 @@ no_gap_lock:
information via the clustered index record. */
ut_ad(index != clust_index);
+ ut_ad(!dict_index_is_clust(index));
- goto requires_clust_rec;
+ if (!lock_sec_rec_cons_read_sees(
+ rec, trx->read_view)) {
+ goto requires_clust_rec;
+ }
}
}
@@ -4362,8 +4366,13 @@ requires_clust_rec:
ULINT_UNDEFINED, &heap);
result_rec = rec;
}
+
+ /* result_rec can legitimately be delete-marked
+ now that it has been established that it points to a
+ clustered index record that exists in the read view. */
} else {
result_rec = rec;
+ ut_ad(!rec_get_deleted_flag(rec, comp));
}
/* We found a qualifying record 'result_rec'. At this point,
=== modified file 'storage/innobase/srv/srv0srv.c'
--- a/storage/innobase/srv/srv0srv.c revid:vasil.dimov@stripped
+++ b/storage/innobase/srv/srv0srv.c revid:vasil.dimov@stripped
@@ -1592,6 +1592,18 @@ srv_suspend_mysql_thread(
row_mysql_unfreeze_data_dictionary(trx);
break;
case RW_X_LATCH:
+ /* There should never be a lock wait when the
+ dictionary latch is reserved in X mode. Dictionary
+ transactions should only acquire locks on dictionary
+ tables, not other tables. All access to dictionary
+ tables should be covered by dictionary
+ transactions. */
+ ut_print_timestamp(stderr);
+ fputs(" InnoDB: Error: dict X latch held in "
+ "srv_suspend_mysql_thread\n", stderr);
+ /* This should never occur. This incorrect handling
+ was added in the early development of
+ ha_innobase::add_index() in InnoDB Plugin 1.0. */
/* Release fast index creation latch */
row_mysql_unlock_data_dictionary(trx);
break;
@@ -1611,6 +1623,9 @@ srv_suspend_mysql_thread(
row_mysql_freeze_data_dictionary(trx);
break;
case RW_X_LATCH:
+ /* This should never occur. This incorrect handling
+ was added in the early development of
+ ha_innobase::add_index() in InnoDB Plugin 1.0. */
row_mysql_lock_data_dictionary(trx);
break;
}
=== modified file 'storage/innobase/srv/srv0start.c'
--- a/storage/innobase/srv/srv0start.c revid:vasil.dimov@stripped
+++ b/storage/innobase/srv/srv0start.c revid:vasil.dimov@stripped
@@ -1334,8 +1334,27 @@ innobase_start_or_create_for_mysql(void)
fil_init(srv_file_per_table ? 50000 : 5000,
srv_max_n_open_files);
+ /* Print time to initialize the buffer pool */
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Initializing buffer pool, size =");
+
+ if (srv_buf_pool_size >= 1024 * 1024 * 1024) {
+ fprintf(stderr,
+ " %.1fG\n",
+ ((double) srv_buf_pool_size) / (1024 * 1024 * 1024));
+ } else {
+ fprintf(stderr,
+ " %.1fM\n",
+ ((double) srv_buf_pool_size) / (1024 * 1024));
+ }
+
err = buf_pool_init(srv_buf_pool_size, srv_buf_pool_instances);
+ ut_print_timestamp(stderr);
+ fprintf(stderr,
+ " InnoDB: Completed initialization of buffer pool\n");
+
if (err != DB_SUCCESS) {
fprintf(stderr,
"InnoDB: Fatal error: cannot allocate the memory"
Attachment: [text/bzr-bundle] bzr/vasil.dimov@oracle.com-20100824144033-2ckxm3tknz1fq2if.bundle
| Thread |
|---|
| • bzr commit into mysql-trunk-bugfixing branch (vasil.dimov:3233) | vasil.dimov | 24 Aug |