#At file:///home/mtaylor/src/mysql/mysql-5.1-telco-6.2/
2612 Monty Taylor 2008-06-02 [merge]
Merged.
added:
mysql-test/include/show_qc_status.inc
mysql-test/suite/ndb/r/ndb_cache_trans.result
mysql-test/suite/ndb/t/ndb_cache_trans.test
modified:
client/mysqltest.c
sql/ha_ndbcluster.cc
storage/ndb/src/kernel/blocks/ERROR_codes.txt
storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
storage/ndb/test/ndbapi/testDict.cpp
=== modified file 'client/mysqltest.c'
--- a/client/mysqltest.c 2008-03-30 11:12:27 +0000
+++ b/client/mysqltest.c 2008-05-30 15:39:09 +0000
@@ -67,7 +67,8 @@
enum {
OPT_SKIP_SAFEMALLOC=OPT_MAX_CLIENT_OPTION,
OPT_PS_PROTOCOL, OPT_SP_PROTOCOL, OPT_CURSOR_PROTOCOL, OPT_VIEW_PROTOCOL,
- OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES
+ OPT_MAX_CONNECT_RETRIES, OPT_MARK_PROGRESS, OPT_LOG_DIR, OPT_TAIL_LINES,
+ OPT_RESULT_FORMAT_VERSION
};
static int record= 0, opt_sleep= -1;
@@ -77,6 +78,7 @@ const char *opt_logdir= "";
const char *opt_include= 0, *opt_charsets_dir;
static int opt_port= 0;
static int opt_max_connect_retries;
+static int opt_result_format_version;
static my_bool opt_compress= 0, silent= 0, verbose= 0;
static my_bool debug_info_flag= 0, debug_check_flag= 0;
static my_bool tty_password= 0;
@@ -268,10 +270,12 @@ enum enum_commands {
Q_WRITE_FILE, Q_COPY_FILE, Q_PERL, Q_DIE, Q_EXIT, Q_SKIP,
Q_CHMOD_FILE, Q_APPEND_FILE, Q_CAT_FILE, Q_DIFF_FILES,
Q_SEND_QUIT, Q_CHANGE_USER, Q_MKDIR, Q_RMDIR,
+ Q_RESULT_FORMAT_VERSION,
Q_UNKNOWN, /* Unknown command. */
Q_COMMENT, /* Comments, ignored. */
- Q_COMMENT_WITH_COMMAND
+ Q_COMMENT_WITH_COMMAND,
+ Q_EMPTY_LINE
};
@@ -359,6 +363,7 @@ const char *command_names[]=
"change_user",
"mkdir",
"rmdir",
+ "result_format",
0
};
@@ -1994,6 +1999,59 @@ void var_query_set(VAR *var, const char
}
+static void
+set_result_format_version(ulong new_version)
+{
+ switch (new_version){
+ case 1:
+ /* The first format */
+ break;
+ case 2:
+ /* New format that also writes comments and empty lines
+ from test file to result */
+ break;
+ default:
+ die("Version format %lu has not yet been implemented", new_version);
+ break;
+ }
+ opt_result_format_version= new_version;
+}
+
+
+/*
+ Set the result format version to use when generating
+ the .result file
+*/
+
+static void
+do_result_format_version(struct st_command *command)
+{
+ long version;
+ static DYNAMIC_STRING ds_version;
+ const struct command_arg result_format_args[] = {
+ "version", ARG_STRING, TRUE, &ds_version, "Version to use",
+ };
+
+ DBUG_ENTER("do_result_format_version");
+
+ check_command_args(command, command->first_argument,
+ result_format_args,
+ sizeof(result_format_args)/sizeof(struct command_arg),
+ ',');
+
+ /* Convert version number to int */
+ if (!str2int(ds_version.str, 10, (long) 0, (long) INT_MAX, &version))
+ die("Invalid version number: '%s'", ds_version.str);
+
+ set_result_format_version(version);
+
+ dynstr_append(&ds_res, "result_format: ");
+ dynstr_append_mem(&ds_res, ds_version.str, ds_version.length);
+ dynstr_append(&ds_res, "\n");
+ dynstr_free(&ds_version);
+}
+
+
/*
Set variable from the result of a field in a query
@@ -4654,7 +4712,7 @@ my_bool end_of_query(int c)
int read_line(char *buf, int size)
{
- char c, last_quote;
+ char c, last_quote, last_char= 0;
char *p= buf, *buf_end= buf + size - 1;
int skip_char= 0;
enum {R_NORMAL, R_Q, R_SLASH_IN_Q,
@@ -4753,14 +4811,24 @@ int read_line(char *buf, int size)
}
else if (my_isspace(charset_info, c))
{
- /* Skip all space at begining of line */
if (c == '\n')
{
+ if (last_char == '\n')
+ {
+ /* Two new lines in a row, return empty line */
+ DBUG_PRINT("info", ("Found two new lines in a row"));
+ *p++= c;
+ *p= 0;
+ DBUG_RETURN(0);
+ }
+
/* Query hasn't started yet */
start_lineno= cur_file->lineno;
DBUG_PRINT("info", ("Query hasn't started yet, start_lineno: %d",
start_lineno));
}
+
+ /* Skip all space at begining of line */
skip_char= 1;
}
else if (end_of_query(c))
@@ -4801,6 +4869,8 @@ int read_line(char *buf, int size)
}
+ last_char= c;
+
if (!skip_char)
{
/* Could be a multibyte character */
@@ -5046,9 +5116,10 @@ int read_command(struct st_command** com
DBUG_RETURN(1);
}
- convert_to_format_v1(read_command_buf);
+ if (opt_result_format_version == 1)
+ convert_to_format_v1(read_command_buf);
- DBUG_PRINT("info", ("query: %s", read_command_buf));
+ DBUG_PRINT("info", ("query: '%s'", read_command_buf));
if (*p == '#')
{
command->type= Q_COMMENT;
@@ -5058,6 +5129,10 @@ int read_command(struct st_command** com
command->type= Q_COMMENT_WITH_COMMAND;
p+= 2; /* Skip past -- */
}
+ else if (*p == '\n')
+ {
+ command->type= Q_EMPTY_LINE;
+ }
/* Skip leading spaces */
while (*p && my_isspace(charset_info, *p))
@@ -5150,6 +5225,11 @@ static struct my_option my_long_options[
{"result-file", 'R', "Read/Store result from/in this file.",
(uchar**) &result_file_name, (uchar**) &result_file_name, 0,
GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"result-format-version", OPT_RESULT_FORMAT_VERSION,
+ "Version of the result file format to use",
+ (uchar**) &opt_result_format_version,
+ (uchar**) &opt_result_format_version, 0,
+ GET_INT, REQUIRED_ARG, 1, 1, 2, 0, 0, 0},
{"server-arg", 'A', "Send option value to embedded server as a parameter.",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
{"server-file", 'F', "Read embedded server arguments from file.",
@@ -5341,6 +5421,9 @@ get_one_option(int optid, const struct m
sf_malloc_quick=1;
#endif
break;
+ case OPT_RESULT_FORMAT_VERSION:
+ set_result_format_version(opt_result_format_version);
+ break;
case 'V':
print_version();
exit(0);
@@ -7035,6 +7118,7 @@ int main(int argc, char **argv)
case Q_COPY_FILE: do_copy_file(command); break;
case Q_CHMOD_FILE: do_chmod_file(command); break;
case Q_PERL: do_perl(command); break;
+ case Q_RESULT_FORMAT_VERSION: do_result_format_version(command); break;
case Q_DELIMITER:
do_delimiter(command);
break;
@@ -7151,9 +7235,38 @@ int main(int argc, char **argv)
do_sync_with_master2(0);
break;
}
- case Q_COMMENT: /* Ignore row */
+ case Q_COMMENT:
+ {
+ const char* p= command->query;
command->last_argument= command->end;
+
+ /* Don't output comments in v1 */
+ if (opt_result_format_version == 1)
+ break;
+
+ /* Don't output comments if query logging is off */
+ if (disable_query_log)
+ break;
+
+ /* Write comment's with two starting #'s to result file */
+ if (p && *p == '#' && *(p+1) == '#')
+ {
+ dynstr_append_mem(&ds_res, command->query, command->query_len);
+ dynstr_append(&ds_res, "\n");
+ }
break;
+ }
+ case Q_EMPTY_LINE:
+ /* Don't output newline in v1 */
+ if (opt_result_format_version == 1)
+ break;
+
+ /* Don't output newline if query logging is off */
+ if (disable_query_log)
+ break;
+
+ dynstr_append(&ds_res, "\n");
+ break;
case Q_PING:
(void) mysql_ping(&cur_con->mysql);
break;
=== added file 'mysql-test/include/show_qc_status.inc'
--- a/mysql-test/include/show_qc_status.inc 1970-01-01 00:00:00 +0000
+++ b/mysql-test/include/show_qc_status.inc 2008-05-28 14:26:26 +0000
@@ -0,0 +1,10 @@
+#
+# Retrieve the value of 'show status like "Qcache_[inserts, hits, queries]"'
+# and display it in a minimal fashion on one line
+#
+let $_qcache_inserts= query_get_value(SHOW STATUS LIKE "Qcache_inserts", Value, 1);
+let $_qcache_hits= query_get_value(SHOW STATUS LIKE "Qcache_hits", Value, 1);
+let $_qcache_queries= query_get_value(SHOW STATUS LIKE "Qcache_queries_in_cache", Value, 1);
+echo Qcache_queries $_qcache_queries;
+echo Qcache_inserts $_qcache_inserts;
+echo Qcache_hits $_qcache_hits;
=== added file 'mysql-test/suite/ndb/r/ndb_cache_trans.result'
--- a/mysql-test/suite/ndb/r/ndb_cache_trans.result 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/r/ndb_cache_trans.result 2008-05-30 15:46:02 +0000
@@ -0,0 +1,317 @@
+result_format: 2
+drop table if exists t1;
+set GLOBAL query_cache_type=on;
+set GLOBAL query_cache_size=1355776;
+reset query cache;
+flush status;
+
+## Turn off autocommit, instead use COMMIT after each statement
+set AUTOCOMMIT=off;
+
+## Create test table in NDB
+CREATE TABLE t1 (
+ pk int not null primary key,
+ a int,
+ b int not null,
+ c varchar(20)
+) ENGINE=ndbcluster;
+
+## Add first row
+insert into t1 value (1, 2, 3, 'First row');
+COMMIT;
+
+## Query should be inserted in qcache
+Qcache_queries 0
+Qcache_inserts 0
+Qcache_hits 0
+select * from t1;
+pk a b c
+1 2 3 First row
+Qcache_queries 1
+Qcache_inserts 1
+Qcache_hits 0
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 1
+Qcache_hits 0
+
+## Perform the same query and make sure the query cache is hit
+Qcache_queries 1
+Qcache_inserts 1
+Qcache_hits 0
+select * from t1;
+pk a b c
+1 2 3 First row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 1
+Qcache_hits 1
+
+## Update the table, should be no queries in cache afterwards
+update t1 set a=3 where pk=1;
+COMMIT;
+Qcache_queries 0
+Qcache_inserts 1
+Qcache_hits 1
+
+## Read row after update, should not hit the cache, but get inserted
+select * from t1;
+pk a b c
+1 3 3 First row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 2
+Qcache_hits 1
+
+## Read row from cache
+select * from t1;
+pk a b c
+1 3 3 First row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 2
+Qcache_hits 2
+
+## Insert two new rows, queries in cache should be zero
+insert into t1 value (2, 7, 8, 'Second row');
+insert into t1 value (4, 5, 6, 'Fourth row');
+COMMIT;
+Qcache_queries 0
+Qcache_inserts 2
+Qcache_hits 2
+
+## Read the three rows, should not hit the cache
+select * from t1 order by pk;
+pk a b c
+1 3 3 First row
+2 7 8 Second row
+4 5 6 Fourth row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 3
+Qcache_hits 2
+
+## Read the three rows, should now hit the cache!
+select * from t1 order by pk;
+pk a b c
+1 3 3 First row
+2 7 8 Second row
+4 5 6 Fourth row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 3
+Qcache_hits 3
+
+## Two selects in the same transaction should hit cache
+select * from t1 order by pk;
+pk a b c
+1 3 3 First row
+2 7 8 Second row
+4 5 6 Fourth row
+select * from t1 order by pk;
+pk a b c
+1 3 3 First row
+2 7 8 Second row
+4 5 6 Fourth row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 3
+Qcache_hits 5
+
+## Perform a "new" query and make sure the query cache is not hit
+select * from t1 where b=3;
+pk a b c
+1 3 3 First row
+COMMIT;
+Qcache_queries 2
+Qcache_inserts 4
+Qcache_hits 5
+
+## Same query again...
+select * from t1 where b=3;
+pk a b c
+1 3 3 First row
+COMMIT;
+Qcache_queries 2
+Qcache_inserts 4
+Qcache_hits 6
+
+## Delete from the table, should clear the cache
+delete from t1 where c='Fourth row';
+COMMIT;
+Qcache_queries 0
+Qcache_inserts 4
+Qcache_hits 6
+select * from t1 where b=3;
+pk a b c
+1 3 3 First row
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 5
+Qcache_hits 6
+
+## Start another connection and check that the query cache is hit
+set AUTOCOMMIT=off;
+use test;
+select * from t1 order by pk;
+pk a b c
+1 3 3 First row
+2 7 8 Second row
+select * from t1 where b=3;
+pk a b c
+1 3 3 First row
+Qcache_queries 2
+Qcache_inserts 6
+Qcache_hits 7
+
+## Update the table and switch to other connection
+update t1 set a=4 where b=3;
+COMMIT;
+
+## Connection 2
+set AUTOCOMMIT=off;
+use test;
+
+## Should not hit cache, table updated
+Qcache_queries 0
+Qcache_inserts 6
+Qcache_hits 7
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 4 3 First row
+Qcache_queries 1
+Qcache_inserts 7
+Qcache_hits 7
+## Should hit cache
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 4 3 First row
+Qcache_queries 1
+Qcache_inserts 7
+Qcache_hits 8
+
+## Connection 1, should hit the cache
+Qcache_queries 1
+Qcache_inserts 7
+Qcache_hits 8
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 4 3 First row
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 4 3 First row
+Qcache_queries 1
+Qcache_inserts 7
+Qcache_hits 10
+
+## Starting transaction and update t1
+begin;
+update t1 set a=5 where pk=1;
+Qcache_queries 0
+Qcache_inserts 7
+Qcache_hits 10
+
+## Connection 2
+## Update has flushed the qc for t1, should not hit qc
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 4 3 First row
+Qcache_queries 1
+Qcache_inserts 8
+Qcache_hits 10
+
+## Connection 1
+commit;
+Qcache_queries 1
+Qcache_inserts 8
+Qcache_hits 10
+
+## Connection 2
+## Update is now committed, should not hit the cache
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 5 3 First row
+Qcache_queries 1
+Qcache_inserts 9
+Qcache_hits 10
+COMMIT;
+Qcache_queries 1
+Qcache_inserts 9
+Qcache_hits 10
+
+## Connection 1
+## Should hit the cache
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 5 3 First row
+Qcache_queries 1
+Qcache_inserts 9
+Qcache_hits 11
+
+update t1 set a=6 where pk=1;
+
+## Following query should not be taken from cache, trans is ongoing
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 6 3 First row
+Qcache_queries 0
+Qcache_inserts 9
+Qcache_hits 11
+
+## Connection 2 should still see old data and not hit cache
+Qcache_queries 0
+Qcache_inserts 9
+Qcache_hits 11
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 5 3 First row
+Qcache_queries 1
+Qcache_inserts 10
+Qcache_hits 11
+
+## Connection 1
+COMMIT;
+
+## Update has just been committed, should not hit cache
+Qcache_queries 1
+Qcache_inserts 10
+Qcache_hits 11
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 6 3 First row
+Qcache_queries 1
+Qcache_inserts 11
+Qcache_hits 11
+
+## Connection 2
+
+## Should hit cache
+Qcache_queries 1
+Qcache_inserts 11
+Qcache_hits 11
+select * from t1 order by pk desc;
+pk a b c
+2 7 8 Second row
+1 6 3 First row
+Qcache_queries 1
+Qcache_inserts 11
+Qcache_hits 12
+
+drop table t1;
+
+## Finally, there should be no queries in cache
+Qcache_queries 0
+Qcache_inserts 11
+Qcache_hits 12
+
+SET GLOBAL query_cache_size=0;
=== added file 'mysql-test/suite/ndb/t/ndb_cache_trans.test'
--- a/mysql-test/suite/ndb/t/ndb_cache_trans.test 1970-01-01 00:00:00 +0000
+++ b/mysql-test/suite/ndb/t/ndb_cache_trans.test 2008-05-28 14:26:26 +0000
@@ -0,0 +1,200 @@
+-- source include/have_query_cache.inc
+-- source include/have_ndb.inc
+-- source include/not_embedded.inc
+
+--result_format 2
+
+--disable_warnings
+drop table if exists t1;
+--enable_warnings
+
+# Turn on and reset query cache
+set GLOBAL query_cache_type=on;
+set GLOBAL query_cache_size=1355776;
+reset query cache;
+flush status;
+
+## Turn off autocommit, instead use COMMIT after each statement
+set AUTOCOMMIT=off;
+
+## Create test table in NDB
+CREATE TABLE t1 (
+ pk int not null primary key,
+ a int,
+ b int not null,
+ c varchar(20)
+) ENGINE=ndbcluster;
+
+## Add first row
+insert into t1 value (1, 2, 3, 'First row');
+COMMIT;
+
+## Query should be inserted in qcache
+--source include/show_qc_status.inc
+select * from t1;
+--source include/show_qc_status.inc
+COMMIT;
+--source include/show_qc_status.inc
+
+## Perform the same query and make sure the query cache is hit
+--source include/show_qc_status.inc
+select * from t1;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Update the table, should be no queries in cache afterwards
+update t1 set a=3 where pk=1;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Read row after update, should not hit the cache, but get inserted
+select * from t1;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Read row from cache
+select * from t1;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Insert two new rows, queries in cache should be zero
+insert into t1 value (2, 7, 8, 'Second row');
+insert into t1 value (4, 5, 6, 'Fourth row');
+COMMIT;
+--source include/show_qc_status.inc
+
+## Read the three rows, should not hit the cache
+select * from t1 order by pk;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Read the three rows, should now hit the cache!
+select * from t1 order by pk;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Two selects in the same transaction should hit cache
+select * from t1 order by pk;
+select * from t1 order by pk;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Perform a "new" query and make sure the query cache is not hit
+select * from t1 where b=3;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Same query again...
+select * from t1 where b=3;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Delete from the table, should clear the cache
+delete from t1 where c='Fourth row';
+COMMIT;
+--source include/show_qc_status.inc
+select * from t1 where b=3;
+COMMIT;
+--source include/show_qc_status.inc
+
+## Start another connection and check that the query cache is hit
+connect (con1,localhost,root,,);
+connection con1;
+set AUTOCOMMIT=off;
+use test;
+select * from t1 order by pk;
+select * from t1 where b=3;
+--source include/show_qc_status.inc
+
+## Update the table and switch to other connection
+update t1 set a=4 where b=3;
+COMMIT;
+
+## Connection 2
+connect (con2,localhost,root,,);
+connection con2;
+set AUTOCOMMIT=off;
+use test;
+
+## Should not hit cache, table updated
+--source include/show_qc_status.inc
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+## Should hit cache
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+## Connection 1, should hit the cache
+connection con1;
+--source include/show_qc_status.inc
+select * from t1 order by pk desc;
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+
+## Starting transaction and update t1
+begin;
+update t1 set a=5 where pk=1;
+--source include/show_qc_status.inc
+
+## Connection 2
+connection con2;
+## Update has flushed the qc for t1, should not hit qc
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+## Connection 1
+connection con1;
+commit;
+--source include/show_qc_status.inc
+
+## Connection 2
+connection con2;
+## Update is now committed, should not hit the cache
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+COMMIT;
+--source include/show_qc_status.inc
+
+## Connection 1
+connection con1;
+## Should hit the cache
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+update t1 set a=6 where pk=1;
+
+## Following query should not be taken from cache, trans is ongoing
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+
+## Connection 2 should still see old data and not hit cache
+connection con2;
+--source include/show_qc_status.inc
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+## Connection 1
+connection con1;
+COMMIT;
+
+## Update has just been committed, should not hit cache
+--source include/show_qc_status.inc
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+## Connection 2
+connection con2;
+
+## Should hit cache
+--source include/show_qc_status.inc
+select * from t1 order by pk desc;
+--source include/show_qc_status.inc
+
+drop table t1;
+
+## Finally, there should be no queries in cache
+--source include/show_qc_status.inc
+
+SET GLOBAL query_cache_size=0;
=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc 2008-05-27 14:12:38 +0000
+++ b/sql/ha_ndbcluster.cc 2008-05-30 11:12:38 +0000
@@ -4614,21 +4614,26 @@ int ha_ndbcluster::external_lock(THD *th
{
DBUG_PRINT("info", ("lock_type == F_UNLCK"));
- if (ndb_cache_check_time && m_rows_changed)
+ if (m_rows_changed)
{
- DBUG_PRINT("info", ("Rows has changed and util thread is running"));
+ DBUG_PRINT("info", ("Rows has changed"));
+
if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
- DBUG_PRINT("info", ("Add share to list of tables to be invalidated"));
+ DBUG_PRINT("info", ("Add share to list of changed tables"));
/* NOTE push_back allocates memory using transactions mem_root! */
- thd_ndb->changed_tables.push_back(m_share, &thd->transaction.mem_root);
+ thd_ndb->changed_tables.push_back(m_share,
+ &thd->transaction.mem_root);
}
- pthread_mutex_lock(&m_share->mutex);
- DBUG_PRINT("info", ("Invalidating commit_count"));
- m_share->commit_count= 0;
- m_share->commit_count_lock++;
- pthread_mutex_unlock(&m_share->mutex);
+ if (ndb_cache_check_time)
+ {
+ pthread_mutex_lock(&m_share->mutex);
+ DBUG_PRINT("info", ("Invalidating commit_count"));
+ m_share->commit_count= 0;
+ m_share->commit_count_lock++;
+ pthread_mutex_unlock(&m_share->mutex);
+ }
}
if (!--thd_ndb->lock_count)
@@ -8080,20 +8085,34 @@ ndbcluster_cache_retrieval_allowed(THD *
ulonglong *engine_data)
{
Uint64 commit_count;
- bool is_autocommit= !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
char *dbname= full_name;
char *tabname= dbname+strlen(dbname)+1;
#ifndef DBUG_OFF
char buff[22], buff2[22];
#endif
DBUG_ENTER("ndbcluster_cache_retrieval_allowed");
- DBUG_PRINT("enter", ("dbname: %s, tabname: %s, is_autocommit: %d",
- dbname, tabname, is_autocommit));
+ DBUG_PRINT("enter", ("dbname: %s, tabname: %s",
+ dbname, tabname));
- if (!is_autocommit)
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
- DBUG_PRINT("exit", ("No, don't use cache in transaction"));
- DBUG_RETURN(FALSE);
+ /* Don't allow qc to be used if table has been previously
+ modified in transaction */
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
+ if (!thd_ndb->changed_tables.is_empty())
+ {
+ NDB_SHARE* share;
+ List_iterator_fast<NDB_SHARE> it(thd_ndb->changed_tables);
+ while ((share= it++))
+ {
+ if (strcmp(share->table_name, tabname) == 0 &&
+ strcmp(share->db, dbname) == 0)
+ {
+ DBUG_PRINT("exit", ("No, transaction has changed table"));
+ DBUG_RETURN(FALSE);
+ }
+ }
+ }
}
if (ndb_get_commitcount(thd, dbname, tabname, &commit_count))
@@ -8155,15 +8174,29 @@ ha_ndbcluster::register_query_cache_tabl
#ifndef DBUG_OFF
char buff[22];
#endif
- bool is_autocommit= !(thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN));
DBUG_ENTER("ha_ndbcluster::register_query_cache_table");
- DBUG_PRINT("enter",("dbname: %s, tabname: %s, is_autocommit: %d",
- m_dbname, m_tabname, is_autocommit));
+ DBUG_PRINT("enter",("dbname: %s, tabname: %s",
+ m_dbname, m_tabname));
- if (!is_autocommit)
+ if (thd->options & (OPTION_NOT_AUTOCOMMIT | OPTION_BEGIN))
{
- DBUG_PRINT("exit", ("Can't register table during transaction"));
- DBUG_RETURN(FALSE);
+ /* Don't allow qc to be used if table has been previously
+ modified in transaction */
+ Thd_ndb *thd_ndb= get_thd_ndb(thd);
+ if (!thd_ndb->changed_tables.is_empty())
+ {
+ DBUG_ASSERT(m_share);
+ NDB_SHARE* share;
+ List_iterator_fast<NDB_SHARE> it(thd_ndb->changed_tables);
+ while ((share= it++))
+ {
+ if (m_share == share)
+ {
+ DBUG_PRINT("exit", ("No, transaction has changed table"));
+ DBUG_RETURN(FALSE);
+ }
+ }
+ }
}
if (ndb_get_commitcount(thd, m_dbname, m_tabname, &commit_count))
=== modified file 'storage/ndb/src/kernel/blocks/ERROR_codes.txt'
--- a/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2008-04-25 07:14:29 +0000
+++ b/storage/ndb/src/kernel/blocks/ERROR_codes.txt 2008-05-30 08:03:55 +0000
@@ -551,6 +551,11 @@ Dbdict:
6005 Crash in participant @ CreateTabReq::CreateDrop
6007 Fail on readTableFile for READ_TAB_FILE1 (28770)
+6200 Set error code after handleTabInfoInit in master
+6201 Set error code after handleTabInfoInit in master (index)
+6202 Set error code before CREATE_FRAGMENTATION in master
+6203 Set error code before CREATE_FRAGMENTATION in master (index)
+
Dbtup:
4014 - handleInsert - Out of undo buffer
4015 - handleInsert - Out of log space
=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2008-05-29 15:58:58 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp 2008-05-30 08:03:55 +0000
@@ -2061,7 +2061,6 @@ Uint32 Dbdict::getFreeTableRecord(Uint32
c_tableRecordPool.getPtr(tablePtr, i);
ndbrequire(tablePtr.p->tabState == TableRecord::NOT_DEFINED);
initialiseTableRecord(tablePtr);
- tablePtr.p->tabState = TableRecord::DEFINING;
return i;
}
@@ -3959,10 +3958,26 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
handleTabInfoInit(r, &parseRecord);
releaseSections(signal);
+
+ if (parseRecord.errorCode == 0)
+ {
+ if (ERROR_INSERTED(6200) ||
+ (ERROR_INSERTED(6201) &&
+ DictTabInfo::isIndex(parseRecord.tablePtr.p->tableType)))
+ {
+ CLEAR_ERROR_INSERT_VALUE;
+ parseRecord.errorCode = 1;
+ }
+ }
if(parseRecord.errorCode != 0){
jam();
c_opCreateTable.release(createTabPtr);
+ if (!parseRecord.tablePtr.isNull())
+ {
+ jam();
+ releaseTableObject(parseRecord.tablePtr.i, true);
+ }
break;
}
@@ -4012,9 +4027,20 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
*/
parseRecord.tablePtr.p->primaryTableId = RNIL;
}
- EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
- CreateFragmentationReq::SignalLength);
- jamEntry();
+ if (ERROR_INSERTED(6202) ||
+ (ERROR_INSERTED(6203) &&
+ DictTabInfo::isIndex(parseRecord.tablePtr.p->tableType)))
+ {
+ CLEAR_ERROR_INSERT_VALUE;
+ signal->theData[0] = 1;
+ }
+ else
+ {
+ EXECUTE_DIRECT(DBDIH, GSN_CREATE_FRAGMENTATION_REQ, signal,
+ CreateFragmentationReq::SignalLength);
+ jamEntry();
+ }
+
if (signal->theData[0] != 0)
{
jam();
@@ -6285,7 +6311,7 @@ Dbdict::execTC_SCHVERCONF(Signal* signal
jam(); \
parseP->errorCode = error; parseP->errorLine = __LINE__; \
parseP->errorKey = it.getKey(); \
- return; \
+ return; \
}//if
// handleAddTableFailure(signal, __LINE__, allocatedTable);
@@ -6371,10 +6397,11 @@ void Dbdict::handleTabInfoInit(SimplePro
if(checkExist){
jam();
- tabRequire(get_object(c_tableDesc.TableName, tableNameLength) == 0,
- CreateTableRef::TableAlreadyExist);
+
+ tabRequire(get_object(c_tableDesc.TableName, tableNameLength) == 0,
+ CreateTableRef::TableAlreadyExist;);
}
-
+
TableRecordPtr tablePtr;
switch (parseP->requestType) {
case DictTabInfo::CreateTableFromAPI: {
@@ -6387,7 +6414,6 @@ void Dbdict::handleTabInfoInit(SimplePro
// Check if no free tables existed.
/* ---------------------------------------------------------------- */
tabRequire(tablePtr.i != RNIL, CreateTableRef::NoMoreTableRecords);
-
c_tableRecordPool.getPtr(tablePtr);
break;
}
@@ -6422,21 +6448,20 @@ void Dbdict::handleTabInfoInit(SimplePro
/* ---------------------------------------------------------------- */
Uint32 tableVersion = c_tableDesc.TableVersion;
tablePtr.p->tableVersion = tableVersion;
-
+
break;
}
default:
ndbrequire(false);
break;
}//switch
- parseP->tablePtr = tablePtr;
{
Rope name(c_rope_pool, tablePtr.p->tableName);
tabRequire(name.assign(c_tableDesc.TableName, tableNameLength, name_hash),
- CreateTableRef::OutOfStringBuffer);
+ CreateTableRef::OutOfStringBuffer);
}
-
+
Ptr<DictObject> obj_ptr;
if (parseP->requestType != DictTabInfo::AlterTableFromAPI) {
jam();
@@ -6453,7 +6478,9 @@ void Dbdict::handleTabInfoInit(SimplePro
c_tableDesc.TableName, tablePtr.i, tablePtr.p->m_obj_ptr_i);
#endif
}
-
+ parseP->tablePtr = tablePtr;
+ tablePtr.p->tabState = TableRecord::DEFINING;
+
// Disallow logging of a temporary table.
tabRequire(!(c_tableDesc.TableTemporaryFlag && c_tableDesc.TableLoggedFlag),
CreateTableRef::NoLoggingTemporaryTable);
@@ -6533,6 +6560,7 @@ void Dbdict::handleTabInfoInit(SimplePro
* Release table
*/
releaseTableObject(tablePtr.i, checkExist);
+ parseP->tablePtr.setNull();
return;
}
=== modified file 'storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp'
--- a/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp 2008-05-29 15:58:58 +0000
+++ b/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp 2008-05-30 08:03:55 +0000
@@ -1125,6 +1125,7 @@ private:
* Temporary structure used when parsing table info
*/
struct ParseDictTabInfoRecord {
+ ParseDictTabInfoRecord() { tablePtr.setNull();}
DictTabInfo::RequestType requestType;
Uint32 errorCode;
Uint32 errorLine;
=== modified file 'storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2007-11-19 10:04:24 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2008-05-30 06:33:46 +0000
@@ -2647,6 +2647,7 @@ private:
// Configurable
FragrecordPtr fragptr;
ArrayPool<Fragrecord> c_fragment_pool;
+ RSS_AP_SNAPSHOT(c_fragment_pool);
#define ZGCPREC_FILE_SIZE 1
GcpRecord *gcpRecord;
=== modified file 'storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp'
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2008-04-23 14:29:01 +0000
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2008-05-30 06:33:46 +0000
@@ -19725,6 +19725,18 @@ Dblqh::execDUMP_STATE_ORD(Signal* signal
infoEvent(buf);
}
}
+
+ if (arg == DumpStateOrd::SchemaResourceSnapshot)
+ {
+ RSS_AP_SNAPSHOT_SAVE(c_fragment_pool);
+ return;
+ }
+
+ if (arg == DumpStateOrd::SchemaResourceCheckLeak)
+ {
+ RSS_AP_SNAPSHOT_CHECK(c_fragment_pool);
+ return;
+ }
}//Dblqh::execDUMP_STATE_ORD()
/* **************************************************************** */
=== modified file 'storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp 2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/Dbtux.hpp 2008-05-30 06:33:46 +0000
@@ -451,6 +451,7 @@ private:
};
typedef Ptr<Index> IndexPtr;
ArrayPool<Index> c_indexPool;
+ RSS_AP_SNAPSHOT(c_indexPool);
/*
* Fragment of an index, as known to DIH/TC. Represents the two
@@ -481,6 +482,7 @@ private:
};
typedef Ptr<Frag> FragPtr;
ArrayPool<Frag> c_fragPool;
+ RSS_AP_SNAPSHOT(c_fragPool);
/*
* Fragment metadata operation.
@@ -500,6 +502,7 @@ private:
};
typedef Ptr<FragOp> FragOpPtr;
ArrayPool<FragOp> c_fragOpPool;
+ RSS_AP_SNAPSHOT(c_fragOpPool);
// node handles
=== modified file 'storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp'
--- a/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2006-12-23 19:20:40 +0000
+++ b/storage/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp 2008-05-30 06:33:46 +0000
@@ -55,6 +55,20 @@ Dbtux::execDUMP_STATE_ORD(Signal* signal
abort();
}
#endif
+
+ if (signal->theData[0] == DumpStateOrd::SchemaResourceSnapshot)
+ {
+ RSS_AP_SNAPSHOT_SAVE(c_indexPool);
+ RSS_AP_SNAPSHOT_SAVE(c_fragPool);
+ RSS_AP_SNAPSHOT_SAVE(c_fragOpPool);
+ }
+
+ if (signal->theData[0] == DumpStateOrd::SchemaResourceCheckLeak)
+ {
+ RSS_AP_SNAPSHOT_CHECK(c_indexPool);
+ RSS_AP_SNAPSHOT_CHECK(c_fragPool);
+ RSS_AP_SNAPSHOT_CHECK(c_fragOpPool);
+ }
}
#ifdef VM_TRACE
=== modified file 'storage/ndb/test/ndbapi/testDict.cpp'
--- a/storage/ndb/test/ndbapi/testDict.cpp 2008-05-29 15:58:58 +0000
+++ b/storage/ndb/test/ndbapi/testDict.cpp 2008-05-30 08:03:55 +0000
@@ -1972,9 +1972,10 @@ runCreateDiskTable(NDBT_Context* ctx, ND
#include <NDBT_Tables.hpp>
int runFailAddFragment(NDBT_Context* ctx, NDBT_Step* step){
- static int acclst[] = { 3001 };
+ static int acclst[] = { 3001, 6200, 6202 };
static int tuplst[] = { 4007, 4008, 4009, 4010, 4011, 4012 };
- static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006 };
+ static int tuxlst[] = { 12001, 12002, 12003, 12004, 12005, 12006,
+ 6201, 6203 };
static unsigned acccnt = sizeof(acclst)/sizeof(acclst[0]);
static unsigned tupcnt = sizeof(tuplst)/sizeof(tuplst[0]);
static unsigned tuxcnt = sizeof(tuxlst)/sizeof(tuxlst[0]);
| Thread |
|---|
| • bzr commit into mysql-5.1-telco-6.2 branch (monty:2612) | Monty Taylor | 2 Jun |