diff options
author | Andrei Elkin <aelkin@mysql.com> | 2009-11-30 20:20:26 +0200 |
---|---|---|
committer | Andrei Elkin <aelkin@mysql.com> | 2009-11-30 20:20:26 +0200 |
commit | 184d7b0250da10e685d2c3f12a69f8a58d1f39cf (patch) | |
tree | 2d1788c10fb236cceb33b0b073390568b163d0fb /storage | |
parent | 558feaa2087397d43a48116743dcdaee9558485e (diff) | |
parent | 3962da934f6e2a92ba04505bd6a33dd7d8322005 (diff) | |
download | mariadb-git-184d7b0250da10e685d2c3f12a69f8a58d1f39cf.tar.gz |
mergin 5.1 -> rep+2 -> rep+3. create_table_from_dump issue will be merged on the next step
Diffstat (limited to 'storage')
28 files changed, 374 insertions, 347 deletions
diff --git a/storage/blackhole/ha_blackhole.cc b/storage/blackhole/ha_blackhole.cc index 357496fe095..e3ba111043b 100644 --- a/storage/blackhole/ha_blackhole.cc +++ b/storage/blackhole/ha_blackhole.cc @@ -105,7 +105,7 @@ int ha_blackhole::update_row(const uchar *old_data, uchar *new_data) { DBUG_ENTER("ha_blackhole::update_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -114,7 +114,7 @@ int ha_blackhole::delete_row(const uchar *buf) { DBUG_ENTER("ha_blackhole::delete_row"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_WRONG_COMMAND); } @@ -130,7 +130,7 @@ int ha_blackhole::rnd_next(uchar *buf) { DBUG_ENTER("ha_blackhole::rnd_next"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_END_OF_FILE); } @@ -212,7 +212,7 @@ int ha_blackhole::index_read_map(uchar * buf, const uchar * key, { DBUG_ENTER("ha_blackhole::index_read"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_END_OF_FILE); } @@ -224,7 +224,7 @@ int ha_blackhole::index_read_idx_map(uchar * buf, uint idx, const uchar * key, { DBUG_ENTER("ha_blackhole::index_read_idx"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_END_OF_FILE); } @@ -235,7 +235,7 @@ int ha_blackhole::index_read_last_map(uchar * buf, const uchar * key, { DBUG_ENTER("ha_blackhole::index_read_last"); THD *thd= ha_thd(); - if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query == NULL) + if (thd->system_thread == SYSTEM_THREAD_SLAVE_SQL && thd->query() == NULL) DBUG_RETURN(0); DBUG_RETURN(HA_ERR_END_OF_FILE); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 028643c6d98..6a7bb1268c2 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -41,7 +41,7 @@ have disabled the InnoDB inlining in this file. */ #include <mysql/plugin.h> #ifndef MYSQL_SERVER -/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t +/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t is defined the same in both builds: the MySQL server and the InnoDB plugin. */ extern pthread_mutex_t LOCK_thread_count; #endif /* MYSQL_SERVER */ @@ -54,6 +54,7 @@ static ulong commit_threads = 0; static pthread_mutex_t commit_threads_m; static pthread_cond_t commit_cond; static pthread_mutex_t commit_cond_m; +static pthread_mutex_t analyze_mutex; static bool innodb_inited = 0; /* @@ -1932,6 +1933,7 @@ innobase_init( pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST); pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST); pthread_cond_init(&commit_cond, NULL); innodb_inited= 1; @@ -1971,6 +1973,7 @@ innobase_end(handlerton *hton, ha_panic_function type) pthread_mutex_destroy(&prepare_commit_mutex); pthread_mutex_destroy(&commit_threads_m); pthread_mutex_destroy(&commit_cond_m); + pthread_mutex_destroy(&analyze_mutex); pthread_cond_destroy(&commit_cond); } @@ -2215,6 +2218,8 @@ innobase_rollback( innobase_release_stat_resources(trx); + trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */ + /* If we had reserved the auto-inc lock for some table (if we come here to roll back the latest SQL statement) we release it now before a possibly lengthy rollback */ @@ -3240,7 +3245,10 @@ ha_innobase::store_key_val_for_row( } else if (mysql_type == MYSQL_TYPE_TINY_BLOB || mysql_type == MYSQL_TYPE_MEDIUM_BLOB || mysql_type == MYSQL_TYPE_BLOB - || mysql_type == MYSQL_TYPE_LONG_BLOB) { + || mysql_type == MYSQL_TYPE_LONG_BLOB + /* MYSQL_TYPE_GEOMETRY data is treated + as BLOB data in innodb. */ + || mysql_type == MYSQL_TYPE_GEOMETRY) { CHARSET_INFO* cs; ulint key_len; @@ -5186,7 +5194,7 @@ create_table_def( if (dict_col_name_is_reserved(field->field_name)){ push_warning_printf( (THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_CANT_CREATE_TABLE, "Error creating table '%s' with " "column name '%s'. '%s' is a " @@ -5433,13 +5441,15 @@ ha_innobase::create( 1. <database_name>/<table_name>: for normal table creation 2. full path: for temp table creation, or sym link - When srv_file_per_table is on, check for full path pattern, i.e. + When srv_file_per_table is on and mysqld_embedded is off, + check for full path pattern, i.e. X:\dir\..., X is a driver letter, or \\dir1\dir2\..., UNC path returns error if it is in full path format, but not creating a temp. table. Currently InnoDB does not support symbolic link on Windows. */ if (srv_file_per_table + && !mysqld_embedded && (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) { if ((name[1] == ':') @@ -5595,18 +5605,22 @@ ha_innobase::create( setup at this stage and so we use thd. */ /* We need to copy the AUTOINC value from the old table if - this is an ALTER TABLE. */ + this is an ALTER TABLE or CREATE INDEX because CREATE INDEX + does a table copy too. */ if (((create_info->used_fields & HA_CREATE_USED_AUTO) - || thd_sql_command(thd) == SQLCOM_ALTER_TABLE) - && create_info->auto_increment_value != 0) { - - /* Query was ALTER TABLE...AUTO_INCREMENT = x; or - CREATE TABLE ...AUTO_INCREMENT = x; Find out a table - definition from the dictionary and get the current value - of the auto increment field. Set a new value to the - auto increment field if the value is greater than the - maximum value in the column. */ + || thd_sql_command(thd) == SQLCOM_ALTER_TABLE + || thd_sql_command(thd) == SQLCOM_CREATE_INDEX) + && create_info->auto_increment_value > 0) { + + /* Query was one of : + CREATE TABLE ...AUTO_INCREMENT = x; or + ALTER TABLE...AUTO_INCREMENT = x; or + CREATE INDEX x on t(...); + Find out a table definition from the dictionary and get + the current value of the auto increment field. Set a new + value to the auto increment field if the value is greater + than the maximum value in the column. */ auto_inc_value = create_info->auto_increment_value; @@ -6428,9 +6442,15 @@ ha_innobase::analyze( THD* thd, /* in: connection thread handle */ HA_CHECK_OPT* check_opt) /* in: currently ignored */ { + /* Serialize ANALYZE TABLE inside InnoDB, see + Bug#38996 Race condition in ANALYZE TABLE */ + pthread_mutex_lock(&analyze_mutex); + /* Simply call ::info() with all the flags */ info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + pthread_mutex_unlock(&analyze_mutex); + return(0); } @@ -7028,7 +7048,9 @@ ha_innobase::external_lock( */ if (lock_type == F_WRLCK && !(table_flags() & HA_BINLOG_STMT_CAPABLE) && - thd_binlog_format(thd) == BINLOG_FORMAT_STMT) { + thd_binlog_format(thd) == BINLOG_FORMAT_STMT && + thd_binlog_filter_ok(thd)) + { /* The error may be suppressed by test cases, by setting the no_innodb_binlog_errors debug symbol. */ if (DBUG_EVALUATE_IF("no_innodb_binlog_errors", 0, 1)) { @@ -7864,6 +7886,7 @@ ha_innobase::get_auto_increment( AUTOINC counter after attempting to insert the row. */ if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) { ulonglong need; + ulonglong current; ulonglong next_value; ulonglong col_max_value; @@ -7872,11 +7895,12 @@ ha_innobase::get_auto_increment( col_max_value = innobase_get_int_col_max_value( table->next_number_field); + current = *first_value > col_max_value ? autoinc : *first_value; need = *nb_reserved_values * increment; /* Compute the last value in the interval */ next_value = innobase_next_autoinc( - *first_value, need, offset, col_max_value); + current, need, offset, col_max_value); prebuilt->autoinc_last_value = next_value; @@ -8501,7 +8525,7 @@ innobase_index_name_is_reserved( innobase_index_reserve_name) == 0) { /* Push warning to mysql */ push_warning_printf((THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_CANT_CREATE_TABLE, "Cannot Create Index with name " "'%s'. The name is reserved " diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index 8ca72ee1a60..9ddb516c3dc 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -252,4 +252,11 @@ int thd_binlog_format(const MYSQL_THD thd); @param all TRUE <=> rollback main transaction. */ void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all); + +/** + Check if binary logging is filtered for thread's current db. + @param thd Thread handle + @retval 1 the query is not filtered, 0 otherwise. +*/ +bool thd_binlog_filter_ok(const MYSQL_THD thd); } diff --git a/storage/innobase/os/os0proc.c b/storage/innobase/os/os0proc.c index a99fe8b6a0e..f00475fc528 100644 --- a/storage/innobase/os/os0proc.c +++ b/storage/innobase/os/os0proc.c @@ -591,6 +591,7 @@ os_mem_alloc_large( fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to" " attach shared memory segment, errno %d\n", errno); + ptr = NULL; } /* Remove the shared memory segment so that it will be diff --git a/storage/innobase/row/row0mysql.c b/storage/innobase/row/row0mysql.c index d0364c9c568..4fcb1fbf9f2 100644 --- a/storage/innobase/row/row0mysql.c +++ b/storage/innobase/row/row0mysql.c @@ -2089,7 +2089,7 @@ Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function should be called after the indexes for a table have been created. Each foreign key constraint must be accompanied with indexes in -bot participating tables. The indexes are allowed to contain more +both participating tables. The indexes are allowed to contain more fields than mentioned in the constraint. Check also that foreign key constraints which reference this table are ok. */ diff --git a/storage/innodb_plugin/ChangeLog b/storage/innodb_plugin/ChangeLog index 0f8f4c4d071..70225ffd9d9 100644 --- a/storage/innodb_plugin/ChangeLog +++ b/storage/innodb_plugin/ChangeLog @@ -1,9 +1,89 @@ +2009-10-29 The InnoDB Team + + * handler/ha_innodb.cc, mysql-test/innodb-autoinc.result, + mysql-test/innodb-autoinc.test: + Fix Bug#47125 auto_increment start value is ignored if an index is + created and engine=innodb + +2009-10-29 The InnoDB Team + + * handler/ha_innodb.cc, mysql-test/innodb_bug47777.result, + mysql-test/innodb_bug47777.test: + Fix Bug#47777 innodb dies with spatial pk: Failing assertion: buf <= + original_buf + buf_len + +2009-10-29 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#38996 Race condition in ANALYZE TABLE + +2009-10-29 The InnoDB Team + + * handler/ha_innodb.cc: + Fix bug#42383: Can't create table 'test.bug39438' + +2009-10-29 The InnoDB Team + + * os/os0proc.c: + Fix Bug#48237 Error handling in os_mem_alloc_large appears to + be incorrect + +2009-10-29 The InnoDB Team + + * buf/buf0buf.c, buf/buf0lru.c, include/buf0buf.h, include/buf0buf.ic: + Fix corruption of the buf_pool->LRU_old list and improve debug + assertions. + +2009-10-28 The InnoDB Team + + * srv/srv0start.c: + Fix Bug#41490 After enlargement of InnoDB page size, the error message + become inaccurate + +2009-10-26 The InnoDB Team + + * row/row0ins.c: + When allocating a data tuple, zero out the system fields in order + to avoid Valgrind warnings about uninitialized fields in + dtuple_validate(). + +2009-10-22 The InnoDB Team + + * handler/ha_innodb.cc, mysql-test/innodb-zip.result, + mysql-test/innodb-zip.test, mysql-test/innodb_bug44369.result, + mysql-test/innodb_bug44369.test: + Fix Bug#47233 Innodb calls push_warning(MYSQL_ERROR::WARN_LEVEL_ERROR) + +2009-10-19 The InnoDB Team + + * mysql-test/innodb_information_schema.test: + Fix Bug#47808 innodb_information_schema.test fails when run under + valgrind + +2009-10-15 The InnoDB Team + + * include/page0page.ic: + Fix Bug#47058 Failure to compile innodb_plugin on solaris 10u7 + spro + cc/CC 5.10 + +2009-10-05 The InnoDB Team + + * buf/buf0buf.c: + Do not invalidate buffer pool while an LRU batch is active. Added code + to buf_pool_invalidate() to wait for the running batches to finish. + +2009-10-01 The InnoDB Team + + * handler/ha_innodb.cc: + Fix Bug#47763 typo in error message: Failed to open table %s after %lu + attemtps. + 2009-10-01 The InnoDB Team * fsp/fsp0fsp.c, row/row0merge.c: - Clean up after a crash during DROP INDEX. When InnoDB crashes + Clean up after a crash during DROP INDEX. When InnoDB crashes while dropping an index, ensure that the index will be completely - dropped during crash recovery. The MySQL .frm file may still + dropped during crash recovery. The MySQL .frm file may still contain the dropped index, but there is little that we can do about it. @@ -20,15 +100,15 @@ include/page0zip.h, page/page0cur.c, page/page0page.c, page/page0zip.c: Do not write to PAGE_INDEX_ID when restoring an uncompressed page - after a compression failure. The field should only be written - when creating a B-tree page. This fix addresses a race condition + after a compression failure. The field should only be written + when creating a B-tree page. This fix addresses a race condition in a debug assertion. 2009-09-28 The InnoDB Team * fil/fil0fil.c: Try to prevent the reuse of tablespace identifiers after InnoDB - has crashed during table creation. Also, refuse to start if files + has crashed during table creation. Also, refuse to start if files with duplicate tablespace identifiers are encountered. 2009-09-25 The InnoDB Team diff --git a/storage/innodb_plugin/buf/buf0buf.c b/storage/innodb_plugin/buf/buf0buf.c index d87abbd0ed9..ff31457d200 100644 --- a/storage/innodb_plugin/buf/buf0buf.c +++ b/storage/innodb_plugin/buf/buf0buf.c @@ -1163,10 +1163,15 @@ buf_relocate( #ifdef UNIV_LRU_DEBUG /* buf_pool->LRU_old must be the first item in the LRU list whose "old" flag is set. */ + ut_a(buf_pool->LRU_old->old); ut_a(!UT_LIST_GET_PREV(LRU, buf_pool->LRU_old) || !UT_LIST_GET_PREV(LRU, buf_pool->LRU_old)->old); ut_a(!UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old) || UT_LIST_GET_NEXT(LRU, buf_pool->LRU_old)->old); + } else { + /* Check that the "old" flag is consistent in + the block and its neighbours. */ + buf_page_set_old(dpage, buf_page_is_old(dpage)); #endif /* UNIV_LRU_DEBUG */ } diff --git a/storage/innodb_plugin/buf/buf0flu.c b/storage/innodb_plugin/buf/buf0flu.c index 74dd0c07ca6..8b614ce90e5 100644 --- a/storage/innodb_plugin/buf/buf0flu.c +++ b/storage/innodb_plugin/buf/buf0flu.c @@ -304,6 +304,28 @@ buf_flush_write_complete( } /********************************************************************//** +Flush a batch of writes to the datafiles that have already been +written by the OS. */ +static +void +buf_flush_sync_datafiles(void) +/*==========================*/ +{ + /* Wake possible simulated aio thread to actually post the + writes to the operating system */ + os_aio_simulated_wake_handler_threads(); + + /* Wait that all async writes to tablespaces have been posted to + the OS */ + os_aio_wait_until_no_pending_writes(); + + /* Now we flush the data to disk (for example, with fsync) */ + fil_flush_file_spaces(FIL_TABLESPACE); + + return; +} + +/********************************************************************//** Flushes possible buffered writes from the doublewrite memory buffer to disk, and also wakes up the aio thread if simulated aio is used. It is very important to call this function after a batch of writes has been posted, @@ -320,8 +342,8 @@ buf_flush_buffered_writes(void) ulint i; if (!srv_use_doublewrite_buf || trx_doublewrite == NULL) { - os_aio_simulated_wake_handler_threads(); - + /* Sync the writes to the disk. */ + buf_flush_sync_datafiles(); return; } @@ -529,22 +551,10 @@ flush: buf_LRU_stat_inc_io(); } - /* Wake possible simulated aio thread to actually post the - writes to the operating system */ - - os_aio_simulated_wake_handler_threads(); - - /* Wait that all async writes to tablespaces have been posted to - the OS */ - - os_aio_wait_until_no_pending_writes(); - - /* Now we flush the data to disk (for example, with fsync) */ - - fil_flush_file_spaces(FIL_TABLESPACE); + /* Sync the writes to the disk. */ + buf_flush_sync_datafiles(); /* We can now reuse the doublewrite memory buffer: */ - trx_doublewrite->first_free = 0; mutex_exit(&(trx_doublewrite->mutex)); diff --git a/storage/innodb_plugin/buf/buf0lru.c b/storage/innodb_plugin/buf/buf0lru.c index d3a79d62d3f..4f19fd13fa5 100644 --- a/storage/innodb_plugin/buf/buf0lru.c +++ b/storage/innodb_plugin/buf/buf0lru.c @@ -978,14 +978,14 @@ buf_LRU_old_adjust_len(void) #ifdef UNIV_LRU_DEBUG ut_a(!LRU_old->old); #endif /* UNIV_LRU_DEBUG */ - buf_page_set_old(LRU_old, TRUE); old_len = ++buf_pool->LRU_old_len; + buf_page_set_old(LRU_old, TRUE); } else if (old_len > new_len + BUF_LRU_OLD_TOLERANCE) { - buf_page_set_old(LRU_old, FALSE); buf_pool->LRU_old = UT_LIST_GET_NEXT(LRU, LRU_old); old_len = --buf_pool->LRU_old_len; + buf_page_set_old(LRU_old, FALSE); } else { return; } @@ -1009,13 +1009,13 @@ buf_LRU_old_init(void) the adjust function to move the LRU_old pointer to the right position */ - bpage = UT_LIST_GET_FIRST(buf_pool->LRU); - - while (bpage != NULL) { + for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); bpage != NULL; + bpage = UT_LIST_GET_PREV(LRU, bpage)) { ut_ad(bpage->in_LRU_list); ut_ad(buf_page_in_file(bpage)); - buf_page_set_old(bpage, TRUE); - bpage = UT_LIST_GET_NEXT(LRU, bpage); + /* This loop temporarily violates the + assertions of buf_page_set_old(). */ + bpage->old = TRUE; } buf_pool->LRU_old = UT_LIST_GET_FIRST(buf_pool->LRU); @@ -1091,10 +1091,19 @@ buf_LRU_remove_block( buf_unzip_LRU_remove_block_if_needed(bpage); - /* If the LRU list is so short that LRU_old not defined, return */ + /* If the LRU list is so short that LRU_old is not defined, + clear the "old" flags and return */ if (UT_LIST_GET_LEN(buf_pool->LRU) < BUF_LRU_OLD_MIN_LEN) { + for (bpage = UT_LIST_GET_FIRST(buf_pool->LRU); bpage != NULL; + bpage = UT_LIST_GET_NEXT(LRU, bpage)) { + /* This loop temporarily violates the + assertions of buf_page_set_old(). */ + bpage->old = FALSE; + } + buf_pool->LRU_old = NULL; + buf_pool->LRU_old_len = 0; return; } @@ -1155,14 +1164,13 @@ buf_LRU_add_block_to_end_low( UT_LIST_ADD_LAST(LRU, buf_pool->LRU, bpage); ut_d(bpage->in_LRU_list = TRUE); - buf_page_set_old(bpage, TRUE); - if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) { ut_ad(buf_pool->LRU_old); /* Adjust the length of the old block list if necessary */ + buf_page_set_old(bpage, TRUE); buf_pool->LRU_old_len++; buf_LRU_old_adjust_len(); @@ -1171,8 +1179,9 @@ buf_LRU_add_block_to_end_low( /* The LRU list is now long enough for LRU_old to become defined: init it */ - buf_pool->LRU_old_len++; buf_LRU_old_init(); + } else { + buf_page_set_old(bpage, buf_pool->LRU_old != NULL); } /* If this is a zipped block with decompressed frame as well @@ -1223,14 +1232,13 @@ buf_LRU_add_block_low( ut_d(bpage->in_LRU_list = TRUE); - buf_page_set_old(bpage, old); - if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) { ut_ad(buf_pool->LRU_old); /* Adjust the length of the old block list if necessary */ + buf_page_set_old(bpage, old); buf_LRU_old_adjust_len(); } else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) { @@ -1239,6 +1247,8 @@ buf_LRU_add_block_low( defined: init it */ buf_LRU_old_init(); + } else { + buf_page_set_old(bpage, buf_pool->LRU_old != NULL); } /* If this is a zipped block with decompressed frame as well @@ -1436,15 +1446,6 @@ alloc: buf_pool->LRU_old = b; } -#ifdef UNIV_LRU_DEBUG - ut_a(prev_b->old - || !UT_LIST_GET_NEXT(LRU, b) - || UT_LIST_GET_NEXT(LRU, b)->old); - } else { - ut_a(!prev_b->old - || !UT_LIST_GET_NEXT(LRU, b) - || !UT_LIST_GET_NEXT(LRU, b)->old); -#endif /* UNIV_LRU_DEBUG */ } lru_len = UT_LIST_GET_LEN(buf_pool->LRU); @@ -1460,6 +1461,11 @@ alloc: defined: init it */ buf_LRU_old_init(); } +#ifdef UNIV_LRU_DEBUG + /* Check that the "old" flag is consistent + in the block and its neighbours. */ + buf_page_set_old(b, buf_page_is_old(b)); +#endif /* UNIV_LRU_DEBUG */ } else { ut_d(b->in_LRU_list = FALSE); buf_LRU_add_block_low(b, buf_page_is_old(b)); @@ -1966,19 +1972,24 @@ buf_LRU_validate(void) } if (buf_page_is_old(bpage)) { - old_len++; - } + const buf_page_t* prev + = UT_LIST_GET_PREV(LRU, bpage); + const buf_page_t* next + = UT_LIST_GET_NEXT(LRU, bpage); + + if (!old_len++) { + ut_a(buf_pool->LRU_old == bpage); + } else { + ut_a(!prev || buf_page_is_old(prev)); + } - if (buf_pool->LRU_old && (old_len == 1)) { - ut_a(buf_pool->LRU_old == bpage); + ut_a(!next || buf_page_is_old(next)); } bpage = UT_LIST_GET_NEXT(LRU, bpage); } - if (buf_pool->LRU_old) { - ut_a(buf_pool->LRU_old_len == old_len); - } + ut_a(buf_pool->LRU_old_len == old_len); UT_LIST_VALIDATE(list, buf_page_t, buf_pool->free, ut_ad(ut_list_node_313->in_free_list)); diff --git a/storage/innodb_plugin/fil/fil0fil.c b/storage/innodb_plugin/fil/fil0fil.c index df6dad86990..ba6f2f8666f 100644 --- a/storage/innodb_plugin/fil/fil0fil.c +++ b/storage/innodb_plugin/fil/fil0fil.c @@ -659,6 +659,7 @@ fil_node_open_file( #ifdef UNIV_HOTBACKUP if (space->id == 0) { node->size = (ulint) (size_bytes / UNIV_PAGE_SIZE); + os_file_close(node->handle); goto add_size; } #endif /* UNIV_HOTBACKUP */ @@ -3244,7 +3245,7 @@ fil_load_single_table_tablespace( fprintf(stderr, "InnoDB: Renaming tablespace %s of id %lu,\n" "InnoDB: to %s_ibbackup_old_vers_<timestamp>\n" - "InnoDB: because its size %lld is too small" + "InnoDB: because its size %" PRId64 " is too small" " (< 4 pages 16 kB each),\n" "InnoDB: or the space id in the file header" " is not sensible.\n" diff --git a/storage/innodb_plugin/handler/ha_innodb.cc b/storage/innodb_plugin/handler/ha_innodb.cc index 1e3f92a994c..9954d893bbb 100644 --- a/storage/innodb_plugin/handler/ha_innodb.cc +++ b/storage/innodb_plugin/handler/ha_innodb.cc @@ -110,7 +110,7 @@ extern "C" { # ifndef MYSQL_PLUGIN_IMPORT # define MYSQL_PLUGIN_IMPORT /* nothing */ # endif /* MYSQL_PLUGIN_IMPORT */ -/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t +/* This is needed because of Bug #3596. Let us hope that pthread_mutex_t is defined the same in both builds: the MySQL server and the InnoDB plugin. */ extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count; @@ -129,6 +129,7 @@ static ulong commit_threads = 0; static pthread_mutex_t commit_threads_m; static pthread_cond_t commit_cond; static pthread_mutex_t commit_cond_m; +static pthread_mutex_t analyze_mutex; static bool innodb_inited = 0; #define INSIDE_HA_INNOBASE_CC @@ -229,21 +230,6 @@ static handler *innobase_create_handler(handlerton *hton, TABLE_SHARE *table, MEM_ROOT *mem_root); -/*********************************************************************** -This function checks each index name for a table against reserved -system default primary index name 'GEN_CLUST_INDEX'. If a name matches, -this function pushes an error message to the client, and returns true. */ -static -bool -innobase_index_name_is_reserved( -/*============================*/ - /* out: true if index name matches a - reserved name */ - const trx_t* trx, /* in: InnoDB transaction handle */ - const TABLE* form, /* in: information on table - columns and indexes */ - const char* norm_name); /* in: table name */ - /* "GEN_CLUST_INDEX" is the name reserved for Innodb default system primary index. */ static const char innobase_index_reserve_name[]= "GEN_CLUST_INDEX"; @@ -2266,6 +2252,7 @@ innobase_change_buffering_inited_ok: pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST); pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST); pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST); + pthread_mutex_init(&analyze_mutex, MY_MUTEX_INIT_FAST); pthread_cond_init(&commit_cond, NULL); innodb_inited= 1; #ifdef MYSQL_DYNAMIC_PLUGIN @@ -2320,6 +2307,7 @@ innobase_end( pthread_mutex_destroy(&prepare_commit_mutex); pthread_mutex_destroy(&commit_threads_m); pthread_mutex_destroy(&commit_cond_m); + pthread_mutex_destroy(&analyze_mutex); pthread_cond_destroy(&commit_cond); } @@ -2598,6 +2586,8 @@ innobase_rollback( innobase_release_stat_resources(trx); + trx->n_autoinc_rows = 0; /* Reset the number AUTO-INC rows required */ + /* If we had reserved the auto-inc lock for some table (if we come here to roll back the latest SQL statement) we release it now before a possibly lengthy rollback */ @@ -3758,7 +3748,10 @@ ha_innobase::store_key_val_for_row( } else if (mysql_type == MYSQL_TYPE_TINY_BLOB || mysql_type == MYSQL_TYPE_MEDIUM_BLOB || mysql_type == MYSQL_TYPE_BLOB - || mysql_type == MYSQL_TYPE_LONG_BLOB) { + || mysql_type == MYSQL_TYPE_LONG_BLOB + /* MYSQL_TYPE_GEOMETRY data is treated + as BLOB data in innodb. */ + || mysql_type == MYSQL_TYPE_GEOMETRY) { CHARSET_INFO* cs; ulint key_len; @@ -5688,7 +5681,7 @@ create_table_def( number fits in one byte in prtype */ push_warning_printf( (THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_CANT_CREATE_TABLE, "In InnoDB, charset-collation codes" " must be below 256." @@ -5722,7 +5715,7 @@ create_table_def( if (dict_col_name_is_reserved(field->field_name)){ push_warning_printf( (THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_CANT_CREATE_TABLE, "Error creating table '%s' with " "column name '%s'. '%s' is a " @@ -5956,7 +5949,7 @@ create_options_are_valid( /* Valid value. */ break; default: - push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: invalid" " KEY_BLOCK_SIZE = %lu." @@ -5970,7 +5963,7 @@ create_options_are_valid( /* If KEY_BLOCK_SIZE was specified, check for its dependencies. */ if (kbs_specified && !srv_file_per_table) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: KEY_BLOCK_SIZE" " requires innodb_file_per_table."); @@ -5978,7 +5971,7 @@ create_options_are_valid( } if (kbs_specified && srv_file_format < DICT_TF_FORMAT_ZIP) { - push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: KEY_BLOCK_SIZE" " requires innodb_file_format >" @@ -6002,7 +5995,7 @@ create_options_are_valid( if (!srv_file_per_table) { push_warning_printf( thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ROW_FORMAT=%s" " requires innodb_file_per_table.", @@ -6014,7 +6007,7 @@ create_options_are_valid( if (srv_file_format < DICT_TF_FORMAT_ZIP) { push_warning_printf( thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: ROW_FORMAT=%s" " requires innodb_file_format >" @@ -6031,7 +6024,7 @@ create_options_are_valid( && form->s->row_type == ROW_TYPE_DYNAMIC) { push_warning_printf( thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: cannot specify" " ROW_FORMAT = DYNAMIC with" @@ -6055,7 +6048,7 @@ create_options_are_valid( if (kbs_specified) { push_warning_printf( thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: cannot specify" " ROW_FORMAT = %s with" @@ -6068,7 +6061,7 @@ create_options_are_valid( default: push_warning(thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, + MYSQL_ERROR::WARN_LEVEL_WARN, ER_ILLEGAL_HA_CREATE_OPTION, "InnoDB: invalid ROW_FORMAT specifier."); ret = FALSE; @@ -6132,13 +6125,15 @@ ha_innobase::create( 1. <database_name>/<table_name>: for normal table creation 2. full path: for temp table creation, or sym link - When srv_file_per_table is on, check for full path pattern, i.e. + When srv_file_per_table is on and mysqld_embedded is off, + check for full path pattern, i.e. X:\dir\..., X is a driver letter, or \\dir1\dir2\..., UNC path returns error if it is in full path format, but not creating a temp. table. Currently InnoDB does not support symbolic link on Windows. */ if (srv_file_per_table + && !mysqld_embedded && (!create_info->options & HA_LEX_CREATE_TMP_TABLE)) { if ((name[1] == ':') @@ -6342,7 +6337,8 @@ ha_innobase::create( /* Check for name conflicts (with reserved name) for any user indices to be created. */ - if (innobase_index_name_is_reserved(trx, form, norm_name)) { + if (innobase_index_name_is_reserved(trx, form->key_info, + form->s->keys)) { error = -1; goto cleanup; } @@ -6429,18 +6425,22 @@ ha_innobase::create( setup at this stage and so we use thd. */ /* We need to copy the AUTOINC value from the old table if - this is an ALTER TABLE. */ + this is an ALTER TABLE or CREATE INDEX because CREATE INDEX + does a table copy too. */ if (((create_info->used_fields & HA_CREATE_USED_AUTO) - || thd_sql_command(thd) == SQLCOM_ALTER_TABLE) - && create_info->auto_increment_value != 0) { - - /* Query was ALTER TABLE...AUTO_INCREMENT = x; or - CREATE TABLE ...AUTO_INCREMENT = x; Find out a table - definition from the dictionary and get the current value - of the auto increment field. Set a new value to the - auto increment field if the value is greater than the - maximum value in the column. */ + || thd_sql_command(thd) == SQLCOM_ALTER_TABLE + || thd_sql_command(thd) == SQLCOM_CREATE_INDEX) + && create_info->auto_increment_value > 0) { + + /* Query was one of : + CREATE TABLE ...AUTO_INCREMENT = x; or + ALTER TABLE...AUTO_INCREMENT = x; or + CREATE INDEX x on t(...); + Find out a table definition from the dictionary and get + the current value of the auto increment field. Set a new + value to the auto increment field if the value is greater + than the maximum value in the column. */ auto_inc_value = create_info->auto_increment_value; @@ -7294,9 +7294,15 @@ ha_innobase::analyze( THD* thd, /*!< in: connection thread handle */ HA_CHECK_OPT* check_opt) /*!< in: currently ignored */ { + /* Serialize ANALYZE TABLE inside InnoDB, see + Bug#38996 Race condition in ANALYZE TABLE */ + pthread_mutex_lock(&analyze_mutex); + /* Simply call ::info() with all the flags */ info(HA_STATUS_TIME | HA_STATUS_CONST | HA_STATUS_VARIABLE); + pthread_mutex_unlock(&analyze_mutex); + return(0); } @@ -7889,7 +7895,8 @@ ha_innobase::external_lock( informative error message and return with an error. */ if (lock_type == F_WRLCK && !(table_flags() & HA_BINLOG_STMT_CAPABLE) && - thd_binlog_format(thd) == BINLOG_FORMAT_STMT) { + thd_binlog_format(thd) == BINLOG_FORMAT_STMT && + thd_binlog_filter_ok(thd)) { /* The error may be suppressed by test cases, by setting the no_innodb_binlog_errors debug symbol. */ if (DBUG_EVALUATE_IF("no_innodb_binlog_errors", 0, 1)) { @@ -8768,6 +8775,7 @@ ha_innobase::get_auto_increment( AUTOINC counter after attempting to insert the row. */ if (innobase_autoinc_lock_mode != AUTOINC_OLD_STYLE_LOCKING) { ulonglong need; + ulonglong current; ulonglong next_value; ulonglong col_max_value; @@ -8776,11 +8784,12 @@ ha_innobase::get_auto_increment( col_max_value = innobase_get_int_col_max_value( table->next_number_field); + current = *first_value > col_max_value ? autoinc : *first_value; need = *nb_reserved_values * increment; /* Compute the last value in the interval */ next_value = innobase_next_autoinc( - *first_value, need, offset, col_max_value); + current, need, offset, col_max_value); prebuilt->autoinc_last_value = next_value; @@ -9799,36 +9808,39 @@ static int show_innodb_vars(THD *thd, SHOW_VAR *var, char *buff) /*********************************************************************** This function checks each index name for a table against reserved system default primary index name 'GEN_CLUST_INDEX'. If a name matches, -this function pushes an error message to the client, and returns true. */ -static +this function pushes an warning message to the client, and returns true. */ +extern "C" UNIV_INTERN bool innobase_index_name_is_reserved( /*============================*/ /* out: true if an index name matches the reserved name */ const trx_t* trx, /* in: InnoDB transaction handle */ - const TABLE* form, /* in: information on table - columns and indexes */ - const char* norm_name) /* in: table name */ + const KEY* key_info, /* in: Indexes to be created */ + ulint num_of_keys) /* in: Number of indexes to + be created. */ { - KEY* key; + const KEY* key; uint key_num; /* index number */ - for (key_num = 0; key_num < form->s->keys; key_num++) { - key = form->key_info + key_num; + for (key_num = 0; key_num < num_of_keys; key_num++) { + key = &key_info[key_num]; if (innobase_strcasecmp(key->name, innobase_index_reserve_name) == 0) { /* Push warning to mysql */ push_warning_printf((THD*) trx->mysql_thd, - MYSQL_ERROR::WARN_LEVEL_ERROR, - ER_CANT_CREATE_TABLE, + MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_NAME_FOR_INDEX, "Cannot Create Index with name " "'%s'. The name is reserved " "for the system default primary " "index.", innobase_index_reserve_name); + my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), + innobase_index_reserve_name); + return(true); } } diff --git a/storage/innodb_plugin/handler/ha_innodb.h b/storage/innodb_plugin/handler/ha_innodb.h index cc98003f8ff..4779651ee27 100644 --- a/storage/innodb_plugin/handler/ha_innodb.h +++ b/storage/innodb_plugin/handler/ha_innodb.h @@ -257,6 +257,13 @@ int thd_binlog_format(const MYSQL_THD thd); @param all TRUE <=> rollback main transaction. */ void thd_mark_transaction_to_rollback(MYSQL_THD thd, bool all); + +/** + Check if binary logging is filtered for thread's current db. + @param thd Thread handle + @retval 1 the query is not filtered, 0 otherwise. +*/ +bool thd_binlog_filter_ok(const MYSQL_THD thd); } typedef struct trx_struct trx_t; @@ -282,3 +289,21 @@ trx_t* innobase_trx_allocate( /*==================*/ MYSQL_THD thd); /*!< in: user thread handle */ + + +/*********************************************************************//** +This function checks each index name for a table against reserved +system default primary index name 'GEN_CLUST_INDEX'. If a name +matches, this function pushes an warning message to the client, +and returns true. */ +extern "C" +bool +innobase_index_name_is_reserved( +/*============================*/ + /* out: true if the index name + matches the reserved name */ + const trx_t* trx, /* in: InnoDB transaction handle */ + const KEY* key_info, /* in: Indexes to be created */ + ulint num_of_keys); /* in: Number of indexes to + be created. */ + diff --git a/storage/innodb_plugin/handler/handler0alter.cc b/storage/innodb_plugin/handler/handler0alter.cc index 1aa0e6b126c..37aed06b28a 100644 --- a/storage/innodb_plugin/handler/handler0alter.cc +++ b/storage/innodb_plugin/handler/handler0alter.cc @@ -628,7 +628,7 @@ ha_innobase::add_index( ulint num_created = 0; ibool dict_locked = FALSE; ulint new_primary; - ulint error; + int error; DBUG_ENTER("ha_innobase::add_index"); ut_a(table); @@ -656,9 +656,13 @@ ha_innobase::add_index( innodb_table = indexed_table = dict_table_get(prebuilt->table->name, FALSE); - /* Check that index keys are sensible */ - - error = innobase_check_index_keys(key_info, num_of_keys); + /* Check if the index name is reserved. */ + if (innobase_index_name_is_reserved(trx, key_info, num_of_keys)) { + error = -1; + } else { + /* Check that index keys are sensible */ + error = innobase_check_index_keys(key_info, num_of_keys); + } if (UNIV_UNLIKELY(error)) { err_exit: diff --git a/storage/innodb_plugin/include/buf0buf.h b/storage/innodb_plugin/include/buf0buf.h index e9d95a14f1b..927ff893e39 100644 --- a/storage/innodb_plugin/include/buf0buf.h +++ b/storage/innodb_plugin/include/buf0buf.h @@ -1129,7 +1129,7 @@ struct buf_page_struct{ debugging */ #endif /* UNIV_DEBUG */ unsigned old:1; /*!< TRUE if the block is in the old - blocks in the LRU list */ + blocks in buf_pool->LRU_old */ unsigned freed_page_clock:31;/*!< the value of buf_pool->freed_page_clock when this block was the last @@ -1393,8 +1393,7 @@ struct buf_pool_struct{ the block to which LRU_old points onward, including that block; see buf0lru.c for the restrictions - on this value; not defined if - LRU_old == NULL; + on this value; 0 if LRU_old == NULL; NOTE: LRU_old_len must be adjusted whenever LRU_old shrinks or grows! */ diff --git a/storage/innodb_plugin/include/buf0buf.ic b/storage/innodb_plugin/include/buf0buf.ic index 8b1f904a090..0f92a59a1c7 100644 --- a/storage/innodb_plugin/include/buf0buf.ic +++ b/storage/innodb_plugin/include/buf0buf.ic @@ -466,10 +466,19 @@ buf_page_set_old( ut_ad(bpage->in_LRU_list); #ifdef UNIV_LRU_DEBUG - if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage) - && UT_LIST_GET_PREV(LRU, bpage)->old - == UT_LIST_GET_NEXT(LRU, bpage)->old) { - ut_a(UT_LIST_GET_PREV(LRU, bpage)->old == old); + ut_a((buf_pool->LRU_old_len == 0) == (buf_pool->LRU_old == NULL)); + /* If a block is flagged "old", the LRU_old list must exist. */ + ut_a(!old || buf_pool->LRU_old); + + if (UT_LIST_GET_PREV(LRU, bpage) && UT_LIST_GET_NEXT(LRU, bpage)) { + const buf_page_t* prev = UT_LIST_GET_PREV(LRU, bpage); + const buf_page_t* next = UT_LIST_GET_NEXT(LRU, bpage); + if (prev->old == next->old) { + ut_a(prev->old == old); + } else { + ut_a(!prev->old); + ut_a(buf_pool->LRU_old == (old ? bpage : next)); + } } #endif /* UNIV_LRU_DEBUG */ diff --git a/storage/innodb_plugin/include/page0page.ic b/storage/innodb_plugin/include/page0page.ic index 318ec1cc1f2..8f794410f20 100644 --- a/storage/innodb_plugin/include/page0page.ic +++ b/storage/innodb_plugin/include/page0page.ic @@ -907,7 +907,7 @@ page_get_data_size( /************************************************************//** Allocates a block of memory from the free list of an index page. */ -UNIV_INTERN +UNIV_INLINE void page_mem_alloc_free( /*================*/ diff --git a/storage/innodb_plugin/include/row0mysql.h b/storage/innodb_plugin/include/row0mysql.h index 6d5d195172e..b05241f00f8 100644 --- a/storage/innodb_plugin/include/row0mysql.h +++ b/storage/innodb_plugin/include/row0mysql.h @@ -756,8 +756,6 @@ struct row_prebuilt_struct { store it here so that we can return it to MySQL */ /*----------------------*/ - UT_LIST_NODE_T(row_prebuilt_t) prebuilts; - /*!< list node of table->prebuilts */ ulint magic_n2; /*!< this should be the same as magic_n */ }; diff --git a/storage/innodb_plugin/include/univ.i b/storage/innodb_plugin/include/univ.i index 0e14f7b1cba..5d0361658af 100644 --- a/storage/innodb_plugin/include/univ.i +++ b/storage/innodb_plugin/include/univ.i @@ -237,7 +237,7 @@ by one. */ /* Linkage specifier for non-static InnoDB symbols (variables and functions) that are only referenced from within InnoDB, not from MySQL */ -#if defined(__GNUC__) && (__GNUC__ >= 4) && !defined(UNIV_HOTBACKUP) +#if defined(__GNUC__) && (__GNUC__ >= 4) || defined(__INTEL_COMPILER) # define UNIV_INTERN __attribute__((visibility ("hidden"))) #else # define UNIV_INTERN diff --git a/storage/innodb_plugin/os/os0file.c b/storage/innodb_plugin/os/os0file.c index a1d3bad2add..0cb76d1796f 100644 --- a/storage/innodb_plugin/os/os0file.c +++ b/storage/innodb_plugin/os/os0file.c @@ -832,6 +832,23 @@ next_file: ret = stat(full_path, &statinfo); if (ret) { + + if (errno == ENOENT) { + /* readdir() returned a file that does not exist, + it must have been deleted in the meantime. Do what + would have happened if the file was deleted before + readdir() - ignore and go to the next entry. + If this is the last entry then info->name will still + contain the name of the deleted file when this + function returns, but this is not an issue since the + caller shouldn't be looking at info when end of + directory is returned. */ + + ut_free(full_path); + + goto next_file; + } + os_file_handle_error_no_exit(full_path, "stat"); ut_free(full_path); diff --git a/storage/innodb_plugin/os/os0proc.c b/storage/innodb_plugin/os/os0proc.c index a0ea9a1b258..48922886f23 100644 --- a/storage/innodb_plugin/os/os0proc.c +++ b/storage/innodb_plugin/os/os0proc.c @@ -97,6 +97,7 @@ os_mem_alloc_large( fprintf(stderr, "InnoDB: HugeTLB: Warning: Failed to" " attach shared memory segment, errno %d\n", errno); + ptr = NULL; } /* Remove the shared memory segment so that it will be diff --git a/storage/innodb_plugin/row/row0ins.c b/storage/innodb_plugin/row/row0ins.c index ab3ae70e3e2..fe51fce82c4 100644 --- a/storage/innodb_plugin/row/row0ins.c +++ b/storage/innodb_plugin/row/row0ins.c @@ -141,7 +141,7 @@ row_ins_alloc_sys_fields( dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - ptr = mem_heap_alloc(heap, DATA_ROW_ID_LEN); + ptr = mem_heap_zalloc(heap, DATA_ROW_ID_LEN); dfield_set_data(dfield, ptr, DATA_ROW_ID_LEN); @@ -152,7 +152,7 @@ row_ins_alloc_sys_fields( col = dict_table_get_sys_col(table, DATA_TRX_ID); dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - ptr = mem_heap_alloc(heap, DATA_TRX_ID_LEN); + ptr = mem_heap_zalloc(heap, DATA_TRX_ID_LEN); dfield_set_data(dfield, ptr, DATA_TRX_ID_LEN); @@ -163,7 +163,7 @@ row_ins_alloc_sys_fields( col = dict_table_get_sys_col(table, DATA_ROLL_PTR); dfield = dtuple_get_nth_field(row, dict_col_get_no(col)); - ptr = mem_heap_alloc(heap, DATA_ROLL_PTR_LEN); + ptr = mem_heap_zalloc(heap, DATA_ROLL_PTR_LEN); dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN); } diff --git a/storage/innodb_plugin/row/row0mysql.c b/storage/innodb_plugin/row/row0mysql.c index 819381fc280..540a4450045 100644 --- a/storage/innodb_plugin/row/row0mysql.c +++ b/storage/innodb_plugin/row/row0mysql.c @@ -2068,7 +2068,7 @@ Scans a table create SQL string and adds to the data dictionary the foreign key constraints declared in the string. This function should be called after the indexes for a table have been created. Each foreign key constraint must be accompanied with indexes in -bot participating tables. The indexes are allowed to contain more +both participating tables. The indexes are allowed to contain more fields than mentioned in the constraint. Check also that foreign key constraints which reference this table are ok. @return error code or DB_SUCCESS */ diff --git a/storage/innodb_plugin/srv/srv0start.c b/storage/innodb_plugin/srv/srv0start.c index 37263317126..796541a9f1a 100644 --- a/storage/innodb_plugin/srv/srv0start.c +++ b/storage/innodb_plugin/srv/srv0start.c @@ -1376,7 +1376,7 @@ innobase_start_or_create_for_mysql(void) sum_of_new_sizes += srv_data_file_sizes[i]; } - if (sum_of_new_sizes < 640) { + if (sum_of_new_sizes < 10485760 / UNIV_PAGE_SIZE) { fprintf(stderr, "InnoDB: Error: tablespace size must be" " at least 10 MB\n"); diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index aa9a2eeb77a..cdfbf16db99 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -115,6 +115,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, Also we likely need to lock mutex here (in both cases with protocol and push_warning). */ +#ifdef THREAD + if (param->need_print_msg_lock) + pthread_mutex_lock(¶m->print_msg_mutex); +#endif protocol->prepare_for_resend(); protocol->store(name, length, system_charset_info); protocol->store(param->op_name, system_charset_info); @@ -123,6 +127,10 @@ static void mi_check_print_msg(MI_CHECK *param, const char* msg_type, if (protocol->write()) sql_print_error("Failed on my_net_write, writing to stderr instead: %s\n", msgbuf); +#ifdef THREAD + if (param->need_print_msg_lock) + pthread_mutex_unlock(¶m->print_msg_mutex); +#endif return; } @@ -576,90 +584,6 @@ const char *ha_myisam::index_type(uint key_number) "BTREE"); } -#ifdef HAVE_REPLICATION -int ha_myisam::net_read_dump(NET* net) -{ - int data_fd = file->dfile; - int error = 0; - - my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)); - for (;;) - { - ulong packet_len = my_net_read(net); - if (!packet_len) - break ; // end of file - if (packet_len == packet_error) - { - sql_print_error("ha_myisam::net_read_dump - read error "); - error= -1; - goto err; - } - if (my_write(data_fd, (uchar*)net->read_pos, (uint) packet_len, - MYF(MY_WME|MY_FNABP))) - { - error = errno; - goto err; - } - } -err: - return error; -} - - -int ha_myisam::dump(THD* thd, int fd) -{ - MYISAM_SHARE* share = file->s; - NET* net = &thd->net; - uint blocksize = share->blocksize; - my_off_t bytes_to_read = share->state.state.data_file_length; - int data_fd = file->dfile; - uchar *buf = (uchar*) my_malloc(blocksize, MYF(MY_WME)); - if (!buf) - return ENOMEM; - - int error = 0; - my_seek(data_fd, 0L, MY_SEEK_SET, MYF(MY_WME)); - for (; bytes_to_read > 0;) - { - size_t bytes = my_read(data_fd, buf, blocksize, MYF(MY_WME)); - if (bytes == MY_FILE_ERROR) - { - error = errno; - goto err; - } - - if (fd >= 0) - { - if (my_write(fd, buf, bytes, MYF(MY_WME | MY_FNABP))) - { - error = errno ? errno : EPIPE; - goto err; - } - } - else - { - if (my_net_write(net, buf, bytes)) - { - error = errno ? errno : EPIPE; - goto err; - } - } - bytes_to_read -= bytes; - } - - if (fd < 0) - { - if (my_net_write(net, (uchar*) "", 0)) - error = errno ? errno : EPIPE; - net_flush(net); - } - -err: - my_free((uchar*) buf, MYF(0)); - return error; -} -#endif /* HAVE_REPLICATION */ - /* Name is here without an extension */ int ha_myisam::open(const char *name, int mode, uint test_if_locked) @@ -897,113 +821,6 @@ int ha_myisam::analyze(THD *thd, HA_CHECK_OPT* check_opt) } -int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) -{ - HA_CHECK_OPT tmp_check_opt; - char *backup_dir= thd->lex->backup_dir; - char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char table_name[FN_REFLEN]; - int error; - const char* errmsg; - DBUG_ENTER("restore"); - - VOID(tablename_to_filename(table->s->table_name.str, table_name, - sizeof(table_name))); - - if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, - MI_NAME_DEXT)) - DBUG_RETURN(HA_ADMIN_INVALID); - - strxmov(dst_path, table->s->normalized_path.str, MI_NAME_DEXT, NullS); - if (my_copy(src_path, dst_path, MYF(MY_WME))) - { - error= HA_ADMIN_FAILED; - errmsg= "Failed in my_copy (Error %d)"; - goto err; - } - - tmp_check_opt.init(); - tmp_check_opt.flags |= T_VERY_SILENT | T_CALC_CHECKSUM | T_QUICK; - DBUG_RETURN(repair(thd, &tmp_check_opt)); - - err: - { - MI_CHECK param; - myisamchk_init(¶m); - param.thd= thd; - param.op_name= "restore"; - param.db_name= table->s->db.str; - param.table_name= table->s->table_name.str; - param.testflag= 0; - mi_check_print_error(¶m, errmsg, my_errno); - DBUG_RETURN(error); - } -} - - -int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) -{ - char *backup_dir= thd->lex->backup_dir; - char src_path[FN_REFLEN], dst_path[FN_REFLEN]; - char table_name[FN_REFLEN]; - int error; - const char *errmsg; - DBUG_ENTER("ha_myisam::backup"); - - VOID(tablename_to_filename(table->s->table_name.str, table_name, - sizeof(table_name))); - - if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir, - reg_ext)) - { - errmsg= "Failed in fn_format() for .frm file (errno: %d)"; - error= HA_ADMIN_INVALID; - goto err; - } - - strxmov(src_path, table->s->normalized_path.str, reg_ext, NullS); - if (my_copy(src_path, dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE))) - { - error = HA_ADMIN_FAILED; - errmsg = "Failed copying .frm file (errno: %d)"; - goto err; - } - - /* Change extension */ - if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir, - MI_NAME_DEXT)) - { - errmsg = "Failed in fn_format() for .MYD file (errno: %d)"; - error = HA_ADMIN_INVALID; - goto err; - } - - strxmov(src_path, table->s->normalized_path.str, MI_NAME_DEXT, NullS); - if (my_copy(src_path, dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES | MY_DONT_OVERWRITE_FILE))) - { - errmsg = "Failed copying .MYD file (errno: %d)"; - error= HA_ADMIN_FAILED; - goto err; - } - DBUG_RETURN(HA_ADMIN_OK); - - err: - { - MI_CHECK param; - myisamchk_init(¶m); - param.thd= thd; - param.op_name= "backup"; - param.db_name= table->s->db.str; - param.table_name= table->s->table_name.str; - param.testflag = 0; - mi_check_print_error(¶m,errmsg, my_errno); - DBUG_RETURN(error); - } -} - - int ha_myisam::repair(THD* thd, HA_CHECK_OPT *check_opt) { int error; @@ -1594,8 +1411,8 @@ bool ha_myisam::check_and_repair(THD *thd) check_opt.flags|=T_QUICK; sql_print_warning("Checking table: '%s'",table->s->path.str); - old_query= thd->query; - old_query_length= thd->query_length; + old_query= thd->query(); + old_query_length= thd->query_length(); thd->set_query(table->s->table_name.str, (uint) table->s->table_name.length); diff --git a/storage/myisam/ha_myisam.h b/storage/myisam/ha_myisam.h index 55a5eac92de..5bb46b03650 100644 --- a/storage/myisam/ha_myisam.h +++ b/storage/myisam/ha_myisam.h @@ -125,15 +125,9 @@ class ha_myisam: public handler bool is_crashed() const; bool auto_repair() const { return myisam_recover_options != 0; } int optimize(THD* thd, HA_CHECK_OPT* check_opt); - int restore(THD* thd, HA_CHECK_OPT* check_opt); - int backup(THD* thd, HA_CHECK_OPT* check_opt); int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt); int preload_keys(THD* thd, HA_CHECK_OPT* check_opt); bool check_if_incompatible_data(HA_CREATE_INFO *info, uint table_changes); -#ifdef HAVE_REPLICATION - int dump(THD* thd, int fd); - int net_read_dump(NET* net); -#endif #ifdef HAVE_QUERY_CACHE my_bool register_query_cache_table(THD *thd, char *table_key, uint key_length, diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 8f7b1399aa2..c10cfdd0c9b 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -104,6 +104,9 @@ void myisamchk_init(MI_CHECK *param) param->max_record_length= LONGLONG_MAX; param->key_cache_block_size= KEY_CACHE_BLOCK_SIZE; param->stats_method= MI_STATS_METHOD_NULLS_NOT_EQUAL; +#ifdef THREAD + param->need_print_msg_lock= 0; +#endif } /* Check the status flags for the table */ @@ -2703,6 +2706,8 @@ int mi_repair_parallel(MI_CHECK *param, register MI_INFO *info, /* Initialize pthread structures before goto err. */ pthread_mutex_init(&sort_info.mutex, MY_MUTEX_INIT_FAST); pthread_cond_init(&sort_info.cond, 0); + pthread_mutex_init(¶m->print_msg_mutex, MY_MUTEX_INIT_FAST); + param->need_print_msg_lock= 1; if (!(sort_info.key_block= alloc_key_blocks(param, (uint) param->sort_key_blocks, @@ -3108,6 +3113,8 @@ err: pthread_cond_destroy (&sort_info.cond); pthread_mutex_destroy(&sort_info.mutex); + pthread_mutex_destroy(¶m->print_msg_mutex); + param->need_print_msg_lock= 0; my_free((uchar*) sort_info.ft_buf, MYF(MY_ALLOW_ZERO_PTR)); my_free((uchar*) sort_info.key_block,MYF(MY_ALLOW_ZERO_PTR)); diff --git a/storage/myisam/sort.c b/storage/myisam/sort.c index fb16af9cddf..b450d27de66 100644 --- a/storage/myisam/sort.c +++ b/storage/myisam/sort.c @@ -466,8 +466,12 @@ ok: Detach from the share if the writer is involved. Avoid others to be blocked. This includes a flush of the write buffer. This will also indicate EOF to the readers. + That means that a writer always gets here first and readers - + only when they see EOF. But if a reader finishes prematurely + because of an error it may reach this earlier - don't allow it + to detach the writer thread. */ - if (sort_param->sort_info->info->rec_cache.share) + if (sort_param->master && sort_param->sort_info->info->rec_cache.share) remove_io_thread(&sort_param->sort_info->info->rec_cache); /* Readers detach from the share if any. Avoid others to be blocked. */ @@ -789,6 +793,7 @@ cleanup: close_cached_file(to_file); /* This holds old result */ if (to_file == t_file) { + DBUG_ASSERT(t_file2.type == WRITE_CACHE); *t_file=t_file2; /* Copy result file */ t_file->current_pos= &t_file->write_pos; t_file->current_end= &t_file->write_end; diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index bc8adf6fd32..11e8c1cc191 100644 --- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -14831,7 +14831,7 @@ void Dblqh::srLogLimits(Signal* signal) while(true) { ndbrequire(tmbyte < clogFileSize); if (logPartPtr.p->logExecState == LogPartRecord::LES_SEARCH_STOP) { - if (logFilePtr.p->logMaxGciCompleted[tmbyte] < logPartPtr.p->logLastGci) { + if (logFilePtr.p->logMaxGciCompleted[tmbyte] <= logPartPtr.p->logLastGci) { jam(); /* -------------------------------------------------------------------- * WE ARE STEPPING BACKWARDS FROM MBYTE TO MBYTE. THIS IS THE FIRST |