Commit 54d10622 authored by monty@hundin.mysql.fi's avatar monty@hundin.mysql.fi

Merge work:/home/bk/mysql into hundin.mysql.fi:/my/bk/mysql

parents f0495434 a6fedfc3
...@@ -455,7 +455,7 @@ dict_table_get( ...@@ -455,7 +455,7 @@ dict_table_get(
mutex_exit(&(dict_sys->mutex)); mutex_exit(&(dict_sys->mutex));
if (table != NULL) { if (table != NULL) {
if (table->stat_last_estimate_counter == (ulint)(-1)) { if (!table->stat_initialized) {
dict_update_statistics(table); dict_update_statistics(table);
} }
} }
...@@ -2614,7 +2614,9 @@ dict_update_statistics_low( ...@@ -2614,7 +2614,9 @@ dict_update_statistics_low(
table->stat_sum_of_other_index_sizes = sum_of_index_sizes table->stat_sum_of_other_index_sizes = sum_of_index_sizes
- index->stat_index_size; - index->stat_index_size;
table->stat_last_estimate_counter = table->stat_modif_counter; table->stat_initialized = TRUE;
table->stat_modified_counter = 0;
} }
/************************************************************************* /*************************************************************************
......
...@@ -73,9 +73,9 @@ dict_mem_table_create( ...@@ -73,9 +73,9 @@ dict_mem_table_create(
table->does_not_fit_in_memory = FALSE; table->does_not_fit_in_memory = FALSE;
table->stat_last_estimate_counter = (ulint)(-1); table->stat_initialized = FALSE;
table->stat_modif_counter = 0; table->stat_modified_counter = 0;
mutex_create(&(table->autoinc_mutex)); mutex_create(&(table->autoinc_mutex));
mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX); mutex_set_level(&(table->autoinc_mutex), SYNC_DICT_AUTOINC_MUTEX);
......
...@@ -348,20 +348,20 @@ struct dict_table_struct{ ...@@ -348,20 +348,20 @@ struct dict_table_struct{
database pages */ database pages */
ulint stat_sum_of_other_index_sizes; ulint stat_sum_of_other_index_sizes;
/* other indexes in database pages */ /* other indexes in database pages */
ulint stat_last_estimate_counter; ibool stat_initialized; /* TRUE if statistics have
/* when the estimates were last time been calculated the first time
calculated; a value (ulint)-1 denotes that after database startup or table creation */
they have not yet been calculated for this ulint stat_modified_counter;
table (or the counter has wrapped over) */
ulint stat_modif_counter;
/* when a row is inserted, updated, or deleted, /* when a row is inserted, updated, or deleted,
we add the row length to this number; we we add the row length to this number; we
calculate new estimates for the stat_... calculate new estimates for the stat_...
values for the table and the indexes at an values for the table and the indexes at an
interval of DICT_STAT_CALCULATE_INTERVAL, interval of 2 GB or when about 1 / 16 of table
but for small tables more often, also has been modified; also
when the estimate operation is called when the estimate operation is called
for MySQL SHOW TABLE STATUS; this counter for MySQL SHOW TABLE STATUS; the counter is
reset to zero at statistics calculation;
this counter
is not protected by any latch, because this is not protected by any latch, because this
is only used for heuristics */ is only used for heuristics */
/*----------------------*/ /*----------------------*/
...@@ -378,10 +378,6 @@ struct dict_table_struct{ ...@@ -378,10 +378,6 @@ struct dict_table_struct{
}; };
#define DICT_TABLE_MAGIC_N 76333786 #define DICT_TABLE_MAGIC_N 76333786
/* Statistics are calculated at least with this interval; see the struct
above */
#define DICT_STAT_CALCULATE_INTERVAL (UNIV_PAGE_SIZE * 8)
/* Data structure for a stored procedure */ /* Data structure for a stored procedure */
struct dict_proc_struct{ struct dict_proc_struct{
mem_heap_t* heap; /* memory heap */ mem_heap_t* heap; /* memory heap */
......
...@@ -432,19 +432,24 @@ row_update_statistics_if_needed( ...@@ -432,19 +432,24 @@ row_update_statistics_if_needed(
row_prebuilt_t* prebuilt) /* in: prebuilt struct */ row_prebuilt_t* prebuilt) /* in: prebuilt struct */
{ {
ulint counter; ulint counter;
ulint old_counter;
counter = prebuilt->table->stat_modif_counter; counter = prebuilt->table->stat_modified_counter;
counter += prebuilt->mysql_row_len; /* Since the physical size of an InnoDB row is bigger than the
prebuilt->table->stat_modif_counter = counter; MySQL row len, we put a safety factor 2 below */
old_counter = prebuilt->table->stat_last_estimate_counter; counter += 2 * prebuilt->mysql_row_len;
if (counter - old_counter >= DICT_STAT_CALCULATE_INTERVAL prebuilt->table->stat_modified_counter = counter;
|| counter - old_counter >=
(UNIV_PAGE_SIZE /* Calculate new statistics if 1 / 16 of table has been modified
* prebuilt->table->stat_clustered_index_size / 2)) { since the last time a statistics batch was run, or if
stat_modified_counter > 2 000 000 000 (to avoid wrap-around) */
if (counter > 2000000000
|| ((ib_longlong)counter >
(UNIV_PAGE_SIZE * prebuilt->table->stat_clustered_index_size)
/ 16)) {
dict_update_statistics(prebuilt->table); dict_update_statistics(prebuilt->table);
} }
...@@ -1019,6 +1024,26 @@ row_create_table_for_mysql( ...@@ -1019,6 +1024,26 @@ row_create_table_for_mysql(
os_event_set(srv_lock_timeout_thread_event); os_event_set(srv_lock_timeout_thread_event);
} }
keywordlen = ut_strlen("innodb_mem_validate");
if (namelen >= keywordlen
&& 0 == ut_memcmp(table->name + namelen - keywordlen,
"innodb_mem_validate", keywordlen)) {
/* We define here a debugging feature intended for
developers */
printf("Validating InnoDB memory:\n"
"to use this feature you must compile InnoDB with\n"
"UNIV_MEM_DEBUG defined in univ.i and the server must be\n"
"quiet because allocation from a mem heap is not protected\n"
"by any semaphore.\n");
ut_a(mem_validate());
printf("Memory validated\n");
}
/* Serialize data dictionary operations with dictionary mutex: /* Serialize data dictionary operations with dictionary mutex:
no deadlocks can occur then in these operations */ no deadlocks can occur then in these operations */
......
...@@ -3035,15 +3035,18 @@ ha_innobase::estimate_number_of_rows(void) ...@@ -3035,15 +3035,18 @@ ha_innobase::estimate_number_of_rows(void)
DBUG_ENTER("info"); DBUG_ENTER("info");
dict_update_statistics(prebuilt->table);
index = dict_table_get_first_index_noninline(prebuilt->table); index = dict_table_get_first_index_noninline(prebuilt->table);
data_file_length = ((ulonglong) index->stat_n_leaf_pages) data_file_length = ((ulonglong) index->stat_n_leaf_pages)
* UNIV_PAGE_SIZE; * UNIV_PAGE_SIZE;
/* Calculate a minimum length for a clustered index record */
estimate = data_file_length / dict_index_calc_min_rec_len(index); /* Calculate a minimum length for a clustered index record and from
that an upper bound for the number of rows. Since we only calculate
new statistics in row0mysql.c when a tablehas grown
by a threshold factor, we must add a safety factor 2 in front
of the formula below. */
estimate = 2 * data_file_length / dict_index_calc_min_rec_len(index);
if (prebuilt->trx) { if (prebuilt->trx) {
prebuilt->trx->op_info = ""; prebuilt->trx->op_info = "";
......
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