diff options
author | Sergei Golubchik <sergii@pisem.net> | 2010-06-16 12:58:56 +0200 |
---|---|---|
committer | Sergei Golubchik <sergii@pisem.net> | 2010-06-16 12:58:56 +0200 |
commit | 9b48499dc44ef8a7b1722a273f12a3198ec7784b (patch) | |
tree | 4876aa326b76a82a1fb88ab7ca04965ddd550544 | |
parent | fdd62e53c21f01381e2b366b757d2c3d0e1a207c (diff) | |
parent | cfbee9359c4282cbff7426d6e71994205964f2df (diff) | |
download | mariadb-git-9b48499dc44ef8a7b1722a273f12a3198ec7784b.tar.gz |
merged
-rwxr-xr-x | CMakeLists.txt | 1 | ||||
-rw-r--r-- | client/mysqldump.c | 2 | ||||
-rw-r--r-- | client/mysqltest.cc | 43 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 6 | ||||
-rw-r--r-- | mysql-test/r/openssl_1.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/maria/r/maria-recover.result | 2 | ||||
-rw-r--r-- | mysql-test/suite/maria/r/maria3.result | 26 | ||||
-rw-r--r-- | mysql-test/suite/maria/t/maria3.test | 18 | ||||
-rw-r--r-- | sql/log_event.cc | 11 | ||||
-rw-r--r-- | storage/maria/ha_maria.cc | 85 | ||||
-rw-r--r-- | storage/maria/ha_maria.h | 2 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.h | 3 | ||||
-rw-r--r-- | storage/maria/ma_init.c | 6 | ||||
-rw-r--r-- | storage/maria/ma_open.c | 5 | ||||
-rw-r--r-- | storage/maria/ma_pagecache.c | 20 | ||||
-rw-r--r-- | storage/maria/ma_recovery.c | 11 | ||||
-rw-r--r-- | storage/maria/ma_state.c | 49 | ||||
-rw-r--r-- | storage/maria/ma_static.c | 2 | ||||
-rw-r--r-- | storage/maria/maria_chk.c | 2 | ||||
-rw-r--r-- | storage/maria/maria_def.h | 7 | ||||
-rw-r--r-- | storage/maria/unittest/ma_pagecache_single.c | 102 | ||||
-rw-r--r-- | storage/myisam/mi_dynrec.c | 2 | ||||
-rw-r--r-- | support-files/compiler_warnings.supp | 2 |
23 files changed, 328 insertions, 81 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 442e782a720..db7415ed0e5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -329,7 +329,6 @@ ADD_SUBDIRECTORY(libmysql) ADD_SUBDIRECTORY(libservices) ADD_SUBDIRECTORY(tests) ADD_SUBDIRECTORY(unittest/mytap) -ADD_SUBDIRECTORY(unittest/examples) ADD_SUBDIRECTORY(unittest/mysys) IF(WITH_EMBEDDED_SERVER) ADD_SUBDIRECTORY(libmysqld) diff --git a/client/mysqldump.c b/client/mysqldump.c index dca8ecb7dfb..212baca6be8 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -964,7 +964,7 @@ static int get_options(int *argc, char ***argv) static void DB_error(MYSQL *mysql_arg, const char *when) { DBUG_ENTER("DB_error"); - maybe_die(EX_MYSQLERR, "Got error: %d: %s %s", + maybe_die(EX_MYSQLERR, "Got error: %d: \"%s\" %s", mysql_errno(mysql_arg), mysql_error(mysql_arg), when); DBUG_VOID_RETURN; } diff --git a/client/mysqltest.cc b/client/mysqltest.cc index e128fa427a0..e0c5cbddbad 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -74,6 +74,10 @@ #define QUERY_SEND_FLAG 1 #define QUERY_REAP_FLAG 2 +#ifndef HAVE_SETENV +static int setenv(const char *name, const char *value, int overwrite); +#endif + enum { OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION, OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL, @@ -227,7 +231,6 @@ typedef struct int alloced_len; int int_dirty; /* do not update string if int is updated until first read */ int alloced; - char *env_s; } VAR; /*Perl/shell-like variable registers */ @@ -1982,13 +1985,20 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, + name_len+1, MYF(MY_WME)))) die("Out of memory"); - tmp_var->name = (name) ? (char*) tmp_var + sizeof(*tmp_var) : 0; + if (name != NULL) + { + tmp_var->name= reinterpret_cast<char*>(tmp_var) + sizeof(*tmp_var); + memcpy(tmp_var->name, name, name_len); + tmp_var->name[name_len]= 0; + } + else + tmp_var->name= NULL; + tmp_var->alloced = (v == 0); if (!(tmp_var->str_val = (char*)my_malloc(val_alloc_len+1, MYF(MY_WME)))) die("Out of memory"); - memcpy(tmp_var->name, name, name_len); if (val) { memcpy(tmp_var->str_val, val, val_len); @@ -1999,7 +2009,6 @@ VAR *var_init(VAR *v, const char *name, int name_len, const char *val, tmp_var->alloced_len = val_alloc_len; tmp_var->int_val = (val) ? atoi(val) : 0; tmp_var->int_dirty = 0; - tmp_var->env_s = 0; return tmp_var; } @@ -2127,20 +2136,15 @@ void var_set(const char *var_name, const char *var_name_end, if (env_var) { - char buf[1024], *old_env_s= v->env_s; if (v->int_dirty) { sprintf(v->str_val, "%d", v->int_val); v->int_dirty= 0; v->str_val_len= strlen(v->str_val); } - my_snprintf(buf, sizeof(buf), "%.*s=%.*s", - v->name_len, v->name, - v->str_val_len, v->str_val); - if (!(v->env_s= my_strdup(buf, MYF(MY_WME)))) - die("Out of memory"); - putenv(v->env_s); - my_free(old_env_s, MYF(MY_ALLOW_ZERO_PTR)); + /* setenv() expects \0-terminated strings */ + DBUG_ASSERT(v->name[v->name_len] == 0); + setenv(v->name, v->str_val, 1); } DBUG_VOID_RETURN; } @@ -9831,3 +9835,18 @@ void dynstr_append_sorted(DYNAMIC_STRING* ds, DYNAMIC_STRING *ds_input) delete_dynamic(&lines); DBUG_VOID_RETURN; } + +#ifndef HAVE_SETENV +static int setenv(const char *name, const char *value, int overwrite) +{ + size_t buflen= strlen(name) + strlen(value) + 2; + char *envvar= (char *)malloc(buflen); + if(!envvar) + return ENOMEM; + strcpy(envvar, name); + strcat(envvar, "="); + strcat(envvar, value); + putenv(envvar); + return 0; +} +#endif diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 328f7e2a675..ad77d04d583 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1658,8 +1658,8 @@ mysqldump: Couldn't find table: "T_1" mysqldump: Couldn't find table: "T_" test_sequence ------ Testing with illegal database names ------ -mysqldump: Got error: 1049: Unknown database 'mysqldump_test_d' when selecting the database -mysqldump: Got error: 1049: Unknown database 'mysqld\ump_test_db' when selecting the database +mysqldump: Got error: 1049: "Unknown database 'mysqldump_test_d'" when selecting the database +mysqldump: Got error: 1049: "Unknown database 'mysqld\ump_test_db'" when selecting the database drop table t1, t2, t3; drop database mysqldump_test_db; use test; @@ -1833,7 +1833,7 @@ drop table t1, t2, t3; # create table t1 (a int); mysqldump: Couldn't execute 'SELECT /*!40001 SQL_NO_CACHE */ * FROM `t1` WHERE xx xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx': You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 (1064) -mysqldump: Got error: 1064: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1 when retrieving data from server +mysqldump: Got error: 1064: "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' at line 1" when retrieving data from server /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index d68b436d089..d87aeefbc34 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -189,7 +189,7 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; SSL error: Unable to get private key from 'MYSQL_TEST_DIR/std_data/client-cert.pem' -mysqldump: Got error: 2026: SSL connection error when trying to connect +mysqldump: Got error: 2026: "SSL connection error" when trying to connect DROP TABLE t1; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA diff --git a/mysql-test/suite/maria/r/maria-recover.result b/mysql-test/suite/maria/r/maria-recover.result index aee4119304f..e9bfc019c81 100644 --- a/mysql-test/suite/maria/r/maria-recover.result +++ b/mysql-test/suite/maria/r/maria-recover.result @@ -8,7 +8,7 @@ OFF set global maria_recover=default; select @@global.maria_recover; @@global.maria_recover -OFF +NORMAL set global maria_recover=normal; select @@global.maria_recover; @@global.maria_recover diff --git a/mysql-test/suite/maria/r/maria3.result b/mysql-test/suite/maria/r/maria3.result index ff609eb21da..4fb08ed192e 100644 --- a/mysql-test/suite/maria/r/maria3.result +++ b/mysql-test/suite/maria/r/maria3.result @@ -315,7 +315,7 @@ maria_pagecache_age_threshold 300 maria_pagecache_buffer_size 8384512 maria_pagecache_division_limit 100 maria_page_checksum OFF -maria_recover OFF +maria_recover NORMAL maria_repair_threads 1 maria_sort_buffer_size 8388608 maria_stats_method nulls_unequal @@ -552,6 +552,30 @@ select count(*) from t1 where a >= 4; count(*) 1 drop table t1, t2; +create temporary table t1 (a int, key(a)) transactional=0 row_format=page; +create temporary table t2 (a int, key(a)) transactional=0 row_format=page; +insert into t1 values (0),(1),(2),(3),(4); +insert into t2 select * from t1; +insert into t1 select NULL from t2; +select count(*) from t1; +count(*) +10 +select count(*) from t1 where a >= 4; +count(*) +1 +drop table t1, t2; +create temporary table t1 (a int, key(a)) transactional=0 row_format=fixed; +create temporary table t2 (a int, key(a)) transactional=0 row_format=dynamic; +insert into t1 values (0),(1),(2),(3),(4); +insert into t2 select * from t1; +insert into t1 select NULL from t2; +select count(*) from t1; +count(*) +10 +select count(*) from t1 where a >= 4; +count(*) +1 +drop table t1, t2; create table t1 (i int auto_increment not null primary key) transactional=0; check table t1 extended; Table Op Msg_type Msg_text diff --git a/mysql-test/suite/maria/t/maria3.test b/mysql-test/suite/maria/t/maria3.test index 45765b3b868..f2ae5d73fb2 100644 --- a/mysql-test/suite/maria/t/maria3.test +++ b/mysql-test/suite/maria/t/maria3.test @@ -433,6 +433,24 @@ select count(*) from t1; select count(*) from t1 where a >= 4; drop table t1, t2; +create temporary table t1 (a int, key(a)) transactional=0 row_format=page; +create temporary table t2 (a int, key(a)) transactional=0 row_format=page; +insert into t1 values (0),(1),(2),(3),(4); +insert into t2 select * from t1; +insert into t1 select NULL from t2; +select count(*) from t1; +select count(*) from t1 where a >= 4; +drop table t1, t2; + +create temporary table t1 (a int, key(a)) transactional=0 row_format=fixed; +create temporary table t2 (a int, key(a)) transactional=0 row_format=dynamic; +insert into t1 values (0),(1),(2),(3),(4); +insert into t2 select * from t1; +insert into t1 select NULL from t2; +select count(*) from t1; +select count(*) from t1 where a >= 4; +drop table t1, t2; + # # Test problems with small rows and row_type=page # Bug 35048 "maria table corruption reported when transactional=0" diff --git a/sql/log_event.cc b/sql/log_event.cc index 0a658719eca..06fcdf5003c 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1716,14 +1716,13 @@ beg: case MYSQL_TYPE_DATETIME: { - /* these must be size_t, because it's what my_b_printf expects for %d */ - size_t d, t; + ulong d, t; uint64 i64= uint8korr(ptr); /* YYYYMMDDhhmmss */ - d= (size_t)(i64 / 1000000); - t= (size_t)(i64 % 1000000); + d= (ulong) (i64 / 1000000); + t= (ulong) (i64 % 1000000); my_b_printf(file, "%04d-%02d-%02d %02d:%02d:%02d", - d / 10000, (d % 10000) / 100, d % 100, - t / 10000, (t % 10000) / 100, t % 100); + (int) (d / 10000), (int) (d % 10000) / 100, (int) (d % 100), + (int) (t / 10000), (int) (t % 10000) / 100, (int) t % 100); my_snprintf(typestr, typestr_length, "DATETIME"); return 8; } diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index b1db4dad197..9f32adbc4cb 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -238,7 +238,7 @@ static MYSQL_SYSVAR_ENUM(recover, maria_recover_options, PLUGIN_VAR_OPCMDARG, "Specifies how corrupted tables should be automatically repaired." " Possible values are \"NORMAL\" (the default), \"BACKUP\", \"FORCE\"," " \"QUICK\", or \"OFF\" which is like not using the option.", - NULL, NULL, HA_RECOVER_NONE, &maria_recover_typelib); + NULL, NULL, HA_RECOVER_DEFAULT, &maria_recover_typelib); static MYSQL_THDVAR_ULONG(repair_threads, PLUGIN_VAR_RQCMDARG, "Number of threads to use when repairing maria tables. The value of 1 " @@ -743,8 +743,54 @@ void _ma_check_print_warning(HA_CHECK *param, const char *fmt, ...) DBUG_VOID_RETURN; } +/* + Create a transaction object + + SYNOPSIS + info Maria handler + + RETURN + 0 ok + # Error number (HA_ERR_OUT_OF_MEM) +*/ + +static int maria_create_trn_for_mysql(MARIA_HA *info) +{ + THD *thd= (THD*) info->external_ptr; + TRN *trn= THD_TRN; + DBUG_ENTER("maria_create_trn_for_mysql"); + + if (!trn) /* no transaction yet - open it now */ + { + trn= trnman_new_trn(& thd->transaction.wt); + if (unlikely(!trn)) + DBUG_RETURN(HA_ERR_OUT_OF_MEM); + THD_TRN= trn; + if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) + trans_register_ha(thd, TRUE, maria_hton); + } + _ma_set_trn_for_table(info, trn); + if (!trnman_increment_locked_tables(trn)) + { + trans_register_ha(thd, FALSE, maria_hton); + trnman_new_statement(trn); + } +#ifdef EXTRA_DEBUG + if (info->lock_type == F_WRLCK && + ! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED)) + { + trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED | + TRN_STATE_TABLES_CAN_CHANGE); + (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY, + (uchar*) thd->query(), + thd->query_length()); + } +#endif + DBUG_RETURN(0); } +} /* extern "C" */ + /** Transactional table doing bulk insert with one single UNDO (UNDO_BULK_INSERT) and with repair. @@ -2349,9 +2395,9 @@ int ha_maria::delete_table(const char *name) return maria_delete_table(name); } + int ha_maria::external_lock(THD *thd, int lock_type) { - TRN *trn= THD_TRN; DBUG_ENTER("ha_maria::external_lock"); /* We don't test now_transactional because it may vary between lock/unlock @@ -2371,22 +2417,7 @@ int ha_maria::external_lock(THD *thd, int lock_type) /* Transactional table */ if (lock_type != F_UNLCK) { - /* Start of new statement */ - if (!trn) /* no transaction yet - open it now */ - { - trn= trnman_new_trn(& thd->transaction.wt); - if (unlikely(!trn)) - DBUG_RETURN(HA_ERR_OUT_OF_MEM); - THD_TRN= trn; - if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN)) - trans_register_ha(thd, TRUE, maria_hton); - } - _ma_set_trn_for_table(file, trn); - if (!trnman_increment_locked_tables(trn)) - { - trans_register_ha(thd, FALSE, maria_hton); - trnman_new_statement(trn); - } + file->external_ptr= thd; // For maria_register_trn() if (!file->s->lock_key_trees) // If we don't use versioning { @@ -2419,20 +2450,10 @@ int ha_maria::external_lock(THD *thd, int lock_type) DBUG_PRINT("info", ("Disabling logging for table")); _ma_tmp_disable_logging_for_table(file, TRUE); } -#ifdef EXTRA_DEBUG - if (lock_type == F_WRLCK && - ! (trnman_get_flags(trn) & TRN_STATE_INFO_LOGGED)) - { - trnman_set_flags(trn, trnman_get_flags(trn) | TRN_STATE_INFO_LOGGED | - TRN_STATE_TABLES_CAN_CHANGE); - (void) translog_log_debug_info(trn, LOGREC_DEBUG_INFO_QUERY, - (uchar*) thd->query(), - thd->query_length()); - } -#endif } else { + TRN *trn= THD_TRN; /* End of transaction */ /* @@ -2457,6 +2478,8 @@ int ha_maria::external_lock(THD *thd, int lock_type) file->state= &file->s->state.state; if (trn) { + DBUG_PRINT("info", + ("locked_tables: %u", trnman_has_locked_tables(trn))); if (trnman_has_locked_tables(trn) && !trnman_decrement_locked_tables(trn)) { @@ -3223,9 +3246,11 @@ static int ha_maria_init(void *p) MYSQL_VERSION_ID, server_id, maria_log_pagecache, TRANSLOG_DEFAULT_FLAGS, 0) || maria_recovery_from_log() || - ((force_start_after_recovery_failures != 0) && mark_recovery_success()) || + ((force_start_after_recovery_failures != 0 || + maria_recovery_changed_data) && mark_recovery_success()) || ma_checkpoint_init(checkpoint_interval); maria_multi_threaded= maria_in_ha_maria= TRUE; + maria_create_trn_hook= maria_create_trn_for_mysql; #if defined(HAVE_REALPATH) && !defined(HAVE_valgrind) && !defined(HAVE_BROKEN_REALPATH) /* We can only test for sub paths if my_symlink.c is using realpath */ diff --git a/storage/maria/ha_maria.h b/storage/maria/ha_maria.h index 23fb74f1c27..ab4012ca38c 100644 --- a/storage/maria/ha_maria.h +++ b/storage/maria/ha_maria.h @@ -141,7 +141,7 @@ public: bool check_and_repair(THD * thd); bool is_crashed() const; bool is_changed() const; - bool auto_repair() const { return 1; } + bool auto_repair() const { return maria_recover_options != HA_RECOVER_NONE; } 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); diff --git a/storage/maria/ma_blockrec.h b/storage/maria/ma_blockrec.h index cb682eef701..16dedc93b28 100644 --- a/storage/maria/ma_blockrec.h +++ b/storage/maria/ma_blockrec.h @@ -279,7 +279,8 @@ my_bool write_hook_for_file_id(enum translog_record_type type, my_bool write_hook_for_commit(enum translog_record_type type, TRN *trn, MARIA_HA *tbl_info, LSN *lsn, void *hook_arg); -void _ma_block_get_status(void* param, my_bool concurrent_insert); +void _ma_block_get_status(void *param, my_bool concurrent_insert); +void _ma_block_get_status_no_versioning(void *param, my_bool concurrent_ins); void _ma_block_update_status(void *param); void _ma_block_restore_status(void *param); my_bool _ma_block_check_status(void *param); diff --git a/storage/maria/ma_init.c b/storage/maria/ma_init.c index 552b0767bec..838e9814c89 100644 --- a/storage/maria/ma_init.c +++ b/storage/maria/ma_init.c @@ -40,6 +40,11 @@ void history_state_free(MARIA_STATE_HISTORY_CLOSED *closed_history) } +static int dummy_maria_create_trn_hook(MARIA_HA *info __attribute__((unused))) +{ + return 0; +} + /* Initialize maria @@ -64,6 +69,7 @@ int maria_init(void) pthread_mutex_init(&THR_LOCK_maria,MY_MUTEX_INIT_SLOW); _ma_init_block_record_data(); trnman_end_trans_hook= _ma_trnman_end_trans_hook; + maria_create_trn_hook= dummy_maria_create_trn_hook; my_handler_error_register(); } hash_init(&maria_stored_state, &my_charset_bin, 32, diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c index c86c439a702..98ccb3e23cd 100644 --- a/storage/maria/ma_open.c +++ b/storage/maria/ma_open.c @@ -892,6 +892,11 @@ MARIA_HA *maria_open(const char *name, int mode, uint open_flags) share->lock_restore_status= _ma_restore_status; } } + else if (share->now_transactional) + { + DBUG_ASSERT(share->data_file_type == BLOCK_RECORD); + share->lock.get_status= _ma_block_get_status_no_versioning; + } } #endif /* diff --git a/storage/maria/ma_pagecache.c b/storage/maria/ma_pagecache.c index dd676028f05..441310a60ea 100644 --- a/storage/maria/ma_pagecache.c +++ b/storage/maria/ma_pagecache.c @@ -4187,7 +4187,16 @@ static int flush_cached_blocks(PAGECACHE *pagecache, { PAGECACHE_BLOCK_LINK *block= *cache; - if (block->pins) + /* + In the case of non_transactional tables we want to flush also + block pinned with reads. This is becasue we may have other + threads reading the block during flush, as non transactional + tables can have many readers while the one writer is doing the + flush. + We don't want to do flush pinned blocks during checkpoint. + We detect the checkpoint case by checking if type is LAZY. + */ + if ((type == FLUSH_KEEP_LAZY && block->pins) || block->wlocks) { KEYCACHE_DBUG_PRINT("flush_cached_blocks", ("block: %u (0x%lx) pinned", @@ -4204,13 +4213,9 @@ static int flush_cached_blocks(PAGECACHE *pagecache, *first_errno= HA_ERR_INTERNAL_ERROR; continue; } - /* if the block is not pinned then it is not write locked */ - DBUG_ASSERT(block->wlocks == 0); - DBUG_ASSERT(block->pins == 0); if (make_lock_and_pin(pagecache, block, - PAGECACHE_LOCK_WRITE, PAGECACHE_PIN, FALSE)) + PAGECACHE_LOCK_READ, PAGECACHE_PIN, FALSE)) DBUG_ASSERT(0); - DBUG_ASSERT(block->pins == 1); KEYCACHE_DBUG_PRINT("flush_cached_blocks", ("block: %u (0x%lx) to be flushed", @@ -4222,7 +4227,6 @@ static int flush_cached_blocks(PAGECACHE *pagecache, DBUG_PRINT("info", ("block: %u (0x%lx) pins: %u", PCBLOCK_NUMBER(pagecache, block), (ulong)block, block->pins)); - DBUG_ASSERT(block->pins == 1); /** @todo IO If page is contiguous with next page to flush, group flushes in one single my_pwrite(). @@ -4241,7 +4245,7 @@ static int flush_cached_blocks(PAGECACHE *pagecache, pagecache_pthread_mutex_lock(&pagecache->cache_lock); if (make_lock_and_pin(pagecache, block, - PAGECACHE_LOCK_WRITE_UNLOCK, + PAGECACHE_LOCK_READ_UNLOCK, PAGECACHE_UNPIN, FALSE)) DBUG_ASSERT(0); diff --git a/storage/maria/ma_recovery.c b/storage/maria/ma_recovery.c index 7b3065b0208..e74f52b2ef6 100644 --- a/storage/maria/ma_recovery.c +++ b/storage/maria/ma_recovery.c @@ -266,6 +266,7 @@ int maria_apply_log(LSN from_lsn, enum maria_apply_log_way apply, DBUG_ASSERT(apply == MARIA_LOG_APPLY || !should_run_undo_phase); DBUG_ASSERT(!maria_multi_threaded); recovery_warnings= 0; + maria_recovery_changed_data= 0; /* checkpoints can happen only if TRNs have been built */ DBUG_ASSERT(should_run_undo_phase || !take_checkpoints); all_active_trans= (struct st_trn_for_recovery *) @@ -465,8 +466,18 @@ end: fflush(stderr); } if (!error) + { ma_message_no_user(ME_JUST_INFO, "recovery done"); + maria_recovery_changed_data= 1; + } } + else if (!error && max_trid_in_control_file != max_long_trid) + { + /* Set max trid in log file so that one can run maria_chk on the tables */ + max_trid_in_control_file= trnman_get_max_trid(); + maria_recovery_changed_data= 1; + } + if (error) my_message(HA_ERR_INITIALIZATION, "Maria recovery failed. Please run maria_chk -r on all maria " diff --git a/storage/maria/ma_state.c b/storage/maria/ma_state.c index d7ddc73e2b4..cc5eea578a5 100644 --- a/storage/maria/ma_state.c +++ b/storage/maria/ma_state.c @@ -53,12 +53,16 @@ my_bool _ma_setup_live_state(MARIA_HA *info) { - TRN *trn= info->trn; + TRN *trn; MARIA_SHARE *share= info->s; MARIA_USED_TABLES *tables; MARIA_STATE_HISTORY *history; DBUG_ENTER("_ma_setup_live_state"); + if (maria_create_trn_hook(info)) + DBUG_RETURN(1); + + trn= info->trn; for (tables= (MARIA_USED_TABLES*) info->trn->used_tables; tables; tables= tables->next) @@ -69,6 +73,7 @@ my_bool _ma_setup_live_state(MARIA_HA *info) goto end; } } + /* Table was not used before, create new table state entry */ if (!(tables= (MARIA_USED_TABLES*) my_malloc(sizeof(*tables), MYF(MY_WME | MY_ZEROFILL)))) @@ -566,7 +571,8 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert) { MARIA_HA *info=(MARIA_HA*) param; DBUG_ENTER("_ma_block_get_status"); - DBUG_PRINT("info", ("concurrent_insert %d", concurrent_insert)); + DBUG_PRINT("enter", ("concurrent_insert %d", concurrent_insert)); + info->row_base_length= info->s->base_length; info->row_flag= info->s->base.default_row_flag; if (concurrent_insert) @@ -589,6 +595,21 @@ void _ma_block_get_status(void* param, my_bool concurrent_insert) */ (void) _ma_setup_live_state(info); } + else + { + /* + Info->trn is set if this table is already handled and we are + called from maria_versioning() + */ + if (info->s->base.born_transactional && !info->trn) + { + /* + Assume for now that this doesn't fail (It can only fail in + out of memory conditions) + */ + (void) maria_create_trn_hook(info); + } + } DBUG_VOID_RETURN; } @@ -616,6 +637,30 @@ my_bool _ma_block_check_status(void *param __attribute__((unused))) } +/* Get status when transactional but not versioned */ + +void _ma_block_get_status_no_versioning(void* param, + my_bool concurrent_insert + __attribute__((unused))) +{ + MARIA_HA *info=(MARIA_HA*) param; + DBUG_ENTER("_ma_block_get_status_no_version"); + DBUG_PRINT("enter", ("concurrent_insert %d", concurrent_insert)); + DBUG_ASSERT(info->s->base.born_transactional); + + info->state->changed= 0; /* from _ma_reset_update_flag() */ + if (!info->trn) + { + /* + Assume for now that this doesn't fail (It can only fail in + out of memory conditions) + */ + (void) maria_create_trn_hook(info); + } + DBUG_VOID_RETURN; +} + + /** Enable/disable versioning */ diff --git a/storage/maria/ma_static.c b/storage/maria/ma_static.c index b4589469caf..d870b034eb8 100644 --- a/storage/maria/ma_static.c +++ b/storage/maria/ma_static.c @@ -37,6 +37,7 @@ my_bool maria_flush= 0, maria_single_user= 0; my_bool maria_delay_key_write= 0, maria_page_checksums= 1; my_bool maria_inited= FALSE; my_bool maria_in_ha_maria= FALSE; /* If used from ha_maria or not */ +my_bool maria_recovery_changed_data= 0; pthread_mutex_t THR_LOCK_maria; #if defined(THREAD) && !defined(DONT_USE_RW_LOCKS) ulong maria_concurrent_insert= 2; @@ -55,6 +56,7 @@ PAGECACHE *maria_log_pagecache= &maria_log_pagecache_var; MY_TMPDIR *maria_tmpdir; /* Tempdir for redo */ char *maria_data_root; HASH maria_stored_state; +int (*maria_create_trn_hook)(MARIA_HA *); /** @brief when transactionality does not matter we can use this transaction diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index ab3c641b55f..0bf38ac5dc8 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -1094,7 +1094,7 @@ static int maria_chk(HA_CHECK *param, char *filename) */ maria_lock_database(info, F_EXTRA_LCK); datafile= info->dfile.file; - if (init_pagecache(maria_pagecache, param->use_buffers, 0, 0, + if (init_pagecache(maria_pagecache, (size_t) param->use_buffers, 0, 0, maria_block_size, MY_WME) == 0) { _ma_check_print_error(param, "Can't initialize page cache with %lu memory", diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index db6845cb345..868885c961b 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -482,7 +482,8 @@ typedef struct st_maria_block_scan struct st_maria_handler { MARIA_SHARE *s; /* Shared between open:s */ - struct st_ma_transaction *trn; /* Pointer to active transaction */ + struct st_ma_transaction *trn; /* Pointer to active transaction */ + void *external_ptr; /* Pointer to THD in mysql */ MARIA_STATUS_INFO *state, state_save; MARIA_STATUS_INFO *state_start; /* State at start of transaction */ MARIA_ROW cur_row; /* The active row that we just read */ @@ -788,8 +789,9 @@ extern uint32 maria_read_vec[], maria_readnext_vec[]; extern uint maria_quick_table_bits; extern char *maria_data_root; extern uchar maria_zero_string[]; -extern my_bool maria_inited, maria_in_ha_maria; +extern my_bool maria_inited, maria_in_ha_maria, maria_recovery_changed_data; extern HASH maria_stored_state; +extern int (*maria_create_trn_hook)(MARIA_HA *); /* This is used by _ma_calc_xxx_key_length och _ma_store_key */ typedef struct st_maria_s_param @@ -1242,5 +1244,4 @@ extern my_bool maria_flush_log_for_page(uchar *page, extern my_bool maria_flush_log_for_page_none(uchar *page, pgcache_page_no_t page_no, uchar *data_ptr); -void maria_concurrent_inserts(MARIA_HA *info, my_bool concurrent_insert); extern PAGECACHE *maria_log_pagecache; diff --git a/storage/maria/unittest/ma_pagecache_single.c b/storage/maria/unittest/ma_pagecache_single.c index 53c820dcd2e..32e588e165a 100644 --- a/storage/maria/unittest/ma_pagecache_single.c +++ b/storage/maria/unittest/ma_pagecache_single.c @@ -246,7 +246,7 @@ int simple_read_change_write_read_test() /* Prepare page, read page 0 (and pin) then write page 1 and page 0. - Flush the file (shold flush only page 1 and return 1 (page 0 is + Flush the file (should flush only page 1 and return 1 (page 0 is still pinned). Check file on the disk. Unpin and flush. @@ -284,7 +284,7 @@ int simple_pin_test() bfill(buffw + TEST_PAGE_SIZE/2, TEST_PAGE_SIZE/2, ((unsigned char) 129)); pagecache_write(&pagecache, &file1, 0, 3, buffw, PAGECACHE_PLAIN_PAGE, - PAGECACHE_LOCK_WRITE_TO_READ, + PAGECACHE_LOCK_LEFT_WRITELOCKED, PAGECACHE_PIN_LEFT_PINNED, PAGECACHE_WRITE_DELAY, 0, LSN_IMPOSSIBLE); @@ -304,7 +304,7 @@ int simple_pin_test() pagecache_unlock(&pagecache, &file1, 0, - PAGECACHE_LOCK_READ_UNLOCK, + PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_UNPIN, 0, 0, 0); if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE)) @@ -324,6 +324,93 @@ err: } /* + Prepare page, read page 0 (and pin) then write page 1 and page 0. + Flush the file (should flush only page 1 and return 1 (page 0 is + still pinned). + Check file on the disk. + Unpin and flush. + Check file on the disk. +*/ +int simple_pin_test2() +{ + unsigned char *buffw= malloc(TEST_PAGE_SIZE); + int res; + DBUG_ENTER("simple_pin_test2"); + /* prepare the file */ + bfill(buffw, TEST_PAGE_SIZE, '\1'); + pagecache_write(&pagecache, &file1, 0, 3, buffw, + PAGECACHE_PLAIN_PAGE, + PAGECACHE_LOCK_LEFT_UNLOCKED, + PAGECACHE_PIN_LEFT_UNPINNED, + PAGECACHE_WRITE_DELAY, + 0, LSN_IMPOSSIBLE); + /* test */ + if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE)) + { + diag("Got error during flushing pagecache\n"); + exit(1); + } + pagecache_read(&pagecache, &file1, 0, 3, buffw, + PAGECACHE_PLAIN_PAGE, + PAGECACHE_LOCK_WRITE, + 0); + pagecache_write(&pagecache, &file1, 1, 3, buffw, + PAGECACHE_PLAIN_PAGE, + PAGECACHE_LOCK_LEFT_UNLOCKED, + PAGECACHE_PIN_LEFT_UNPINNED, + PAGECACHE_WRITE_DELAY, + 0, LSN_IMPOSSIBLE); + bfill(buffw + TEST_PAGE_SIZE/2, TEST_PAGE_SIZE/2, ((unsigned char) 129)); + pagecache_write(&pagecache, &file1, 0, 3, buffw, + PAGECACHE_PLAIN_PAGE, + PAGECACHE_LOCK_WRITE_TO_READ, + PAGECACHE_PIN_LEFT_PINNED, + PAGECACHE_WRITE_DELAY, + 0, LSN_IMPOSSIBLE); + /* + We have to get error because one page of the file is pinned, + other page should be flushed + */ + if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_KEEP_LAZY)) + { + diag("Did not get error in flush_pagecache_blocks 2\n"); + res= 0; + goto err; + } + ok((res= test(test_file(file1, file1_name, TEST_PAGE_SIZE*2, TEST_PAGE_SIZE*2, + simple_pin_test_file1))), + "Simple pin page file with pin 2"); + + /* Test that a normal flush goes through */ + if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE)) + { + diag("Got error in flush_pagecache_blocks 3\n"); + res= 0; + goto err; + } + pagecache_unlock(&pagecache, + &file1, + 0, + PAGECACHE_LOCK_READ_UNLOCK, + PAGECACHE_UNPIN, + 0, 0, 0); + if (flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE)) + { + diag("Got error in flush_pagecache_blocks 4\n"); + res= 0; + goto err; + } + ok((res&= test(test_file(file1, file1_name, TEST_PAGE_SIZE*2, TEST_PAGE_SIZE, + simple_pin_test_file2))), + "Simple pin page result file 2"); + if (res) + reset_file(&file1, file1_name); +err: + free(buffw); + DBUG_RETURN(res); +} + +/* Checks pins without lock. */ int simple_pin_no_lock_test() @@ -357,7 +444,7 @@ int simple_pin_no_lock_test() We have to get error because one page of the file is pinned, other page should be flushed */ - if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE)) + if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_KEEP_LAZY)) { diag("Did not get error in flush_pagecache_blocks 2\n"); res= 0; @@ -392,7 +479,7 @@ int simple_pin_no_lock_test() pagecache_unlock_by_link(&pagecache, link, PAGECACHE_LOCK_WRITE_UNLOCK, PAGECACHE_PIN_LEFT_PINNED, 0, 0, 1, FALSE); - if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_FORCE_WRITE)) + if (!flush_pagecache_blocks(&pagecache, &file1, FLUSH_KEEP_LAZY)) { diag("Did not get error in flush_pagecache_blocks 3\n"); res= 0; @@ -609,6 +696,7 @@ static void *test_thread(void *arg) if (!simple_read_write_test() || !simple_read_change_write_read_test() || !simple_pin_test() || + !simple_pin_test2() || !simple_pin_no_lock_test() || !simple_delete_forget_test() || !simple_delete_flush_test()) @@ -657,8 +745,8 @@ int main(int argc __attribute__((unused)), DBUG_ENTER("main"); DBUG_PRINT("info", ("Main thread: %s\n", my_thread_name())); - plan(16); - SKIP_BIG_TESTS(16) + plan(18); + SKIP_BIG_TESTS(18) { if ((tmp_file= my_open(file2_name, O_CREAT | O_TRUNC | O_RDWR, diff --git a/storage/myisam/mi_dynrec.c b/storage/myisam/mi_dynrec.c index adae7076858..dae8fbe50a8 100644 --- a/storage/myisam/mi_dynrec.c +++ b/storage/myisam/mi_dynrec.c @@ -116,7 +116,7 @@ int mi_munmap_file(MI_INFO *info) { int ret; DBUG_ENTER("mi_unmap_file"); - if ((ret= my_munmap(info->s->file_map, info->s->mmaped_length))) + if ((ret= my_munmap(info->s->file_map, (size_t) info->s->mmaped_length))) DBUG_RETURN(ret); info->s->file_read= mi_nommap_pread; info->s->file_write= mi_nommap_pwrite; diff --git a/support-files/compiler_warnings.supp b/support-files/compiler_warnings.supp index 8e2b63e7a46..c8d2926145d 100644 --- a/support-files/compiler_warnings.supp +++ b/support-files/compiler_warnings.supp @@ -130,7 +130,7 @@ xaction_xt\.cc: may be used uninitialized in this function # storage/pbxt/ : typedef.*was ignored in this declaration ha_pbxt\.cc : variable.*might be clobbered by.*longjmp -table_xt\.cc : variable.*might be clobbered by ~longjm~p or ~vfork~ +table_xt\.cc : variable.*might be clobbered by.*longjmp # # Yassl |