summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysqldump.c229
-rw-r--r--mysql-test/r/mysqldump.result163
-rw-r--r--mysql-test/t/mysqldump.test82
-rw-r--r--sql/item_cmpfunc.cc4
-rw-r--r--sql/sp_head.cc21
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp22
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp140
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp11
-rw-r--r--storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp11
9 files changed, 544 insertions, 139 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c
index 7c81f6909c1..e1218d1bc69 100644
--- a/client/mysqldump.c
+++ b/client/mysqldump.c
@@ -87,7 +87,7 @@ static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1,
opt_single_transaction=0, opt_comments= 0, opt_compact= 0,
opt_hex_blob=0, opt_order_by_primary=0, opt_ignore=0,
opt_complete_insert= 0, opt_drop_database= 0,
- opt_dump_triggers= 0;
+ opt_dump_triggers= 0, opt_routines=0;
static ulong opt_max_allowed_packet, opt_net_buffer_length;
static MYSQL mysql_connection,*sock=0;
static my_bool insert_pat_inited=0;
@@ -339,6 +339,9 @@ static struct my_option my_long_options[] =
{"result-file", 'r',
"Direct output to a given file. This option should be used in MSDOS, because it prevents new line '\\n' from being converted to '\\r\\n' (carriage return + line feed).",
0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0},
+ {"routines", 'R', "Dump routines FUNCTIONS and PROCEDURES.",
+ (gptr*) &opt_routines, (gptr*) &opt_routines, 0, GET_BOOL,
+ NO_ARG, 0, 0, 0, 0, 0, 0},
{"set-charset", OPT_SET_CHARSET,
"Add 'SET NAMES default_character_set' to the output. Enabled by default; suppress with --skip-set-charset.",
(gptr*) &opt_set_charset, (gptr*) &opt_set_charset, 0, GET_BOOL, NO_ARG, 1,
@@ -1157,7 +1160,7 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
uint i;
MYSQL_FIELD *field;
ulong *lengths= mysql_fetch_lengths(tableRes);
-
+
fprintf(xml_file, "\t\t<%s", row_name);
check_io(xml_file);
mysql_field_seek(tableRes, 0);
@@ -1177,6 +1180,112 @@ static void print_xml_row(FILE *xml_file, const char *row_name,
check_io(xml_file);
}
+/*
+ dump_routines_for_db
+ -- retrievs list of routines for a given db, and prints out
+ the CREATE PROCEDURE definition into the output (the dump).
+
+ This function has logic to print the appropriate syntax depending on whether
+ this is a procedure or functions
+
+ RETURN 0 succes, 1 if error
+*/
+
+static uint dump_routines_for_db (char *db)
+{
+ char query_buff[512], routine_type[10];
+ char db_name_buff[NAME_LEN+3], name_buff[NAME_LEN+3];
+ int i;
+ FILE *sql_file = md_result_file;
+ MYSQL_RES *routine_res= NULL;
+ MYSQL_RES *routine_list_res= NULL;
+ MYSQL_ROW row, routine_list_row;
+
+ DBUG_ENTER("dump_routines_for_db");
+
+ mysql_real_escape_string(sock, db_name_buff, db, strlen(db));
+ DBUG_PRINT("enter", ("db: '%s'", db_name_buff));
+
+ /* nice comments */
+ if (opt_comments)
+ fprintf(sql_file, "\n--\n-- Dumping routines for database '%s'\n--\n", db);
+
+ /*
+ not using "mysql_query_with_error_report" because of privileges
+ */
+ if (opt_lock)
+ mysql_query(sock, "LOCK TABLES mysql.proc READ");
+
+ fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n");
+ fprintf(sql_file, "DELIMITER //\n");
+
+ /* 0, retrieve and dump functions, 1, procedures */
+ for (i=0; i <= 1; i++)
+ {
+ my_snprintf(routine_type, sizeof(routine_type),
+ "%s", i == 0 ? "FUNCTION" : "PROCEDURE");
+
+ my_snprintf(query_buff, sizeof(query_buff),
+ "SHOW %s STATUS WHERE Db = '%s'",
+ routine_type, db_name_buff);
+
+ if (mysql_query_with_error_report(sock, &routine_list_res, query_buff))
+ DBUG_RETURN(1);
+
+ if (mysql_num_rows(routine_list_res))
+ {
+
+ while((routine_list_row= mysql_fetch_row(routine_list_res)))
+ {
+ DBUG_PRINT("info", ("retrieving CREATE %s for %s", routine_type, name_buff));
+ mysql_real_escape_string(sock, name_buff,
+ routine_list_row[1], strlen(routine_list_row[1]));
+ my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s",
+ routine_type, name_buff);
+
+ if (mysql_query_with_error_report(sock, &routine_res, query_buff))
+ DBUG_RETURN(1);
+
+ while ((row=mysql_fetch_row(routine_res)))
+ {
+ /*
+ the user can see routine names, but NOT the routine body of other
+ routines that are not the creator of!
+ */
+ DBUG_PRINT("info",("length of body for %s row[2] '%s' is %d",
+ name_buff, row[2], strlen(row[2])));
+ if (strlen(row[2]))
+ {
+ fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/ //\n",
+ row[1] /* sql_mode */);
+
+ if (opt_drop)
+ fprintf(sql_file, "/*!50003 DROP %s IF EXISTS %s */ //\n",
+ routine_type, name_buff);
+ /*
+ the i==0 is temporary until we can figure out why functions
+ can't be in comments
+ */
+ /* create proc/func body */;
+ fprintf(sql_file, "/*!50003 %s */ //\n", row[2]);
+ }
+ } /* end of routine printing */
+ } /* end of list of routines */
+ mysql_free_result(routine_res);
+ routine_res=NULL;
+ }
+ mysql_free_result(routine_list_res);
+ routine_list_res=NULL;
+ } /* end of for i (0 .. 1) */
+ /* set the delimiter back to ';' */
+ fprintf(sql_file, "DELIMITER ;\n");
+ fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;\n");
+
+ /* again, no error report due to permissions */
+ if (opt_lock)
+ mysql_query(sock, "UNLOCK TABLES");
+ DBUG_RETURN(0);
+}
/*
getTableStructure -- retrievs database structure, prints out corresponding
@@ -1330,41 +1439,6 @@ static uint get_table_structure(char *table, char *db)
fprintf(sql_file, "%s;\n", row[1]);
check_io(sql_file);
mysql_free_result(tableRes);
- if (opt_dump_triggers &&
- mysql_get_server_version(sock) >= 50009)
- {
- my_snprintf(query_buff, sizeof(query_buff),
- "SHOW TRIGGERS LIKE %s",
- quote_for_like(table, name_buff));
-
-
- if (mysql_query_with_error_report(sock, &tableRes, query_buff))
- {
- if (path)
- my_fclose(sql_file, MYF(MY_WME));
- safe_exit(EX_MYSQLERR);
- DBUG_RETURN(0);
- }
- if (mysql_num_rows(tableRes))
- fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n\
-DELIMITER //;\n");
- while ((row=mysql_fetch_row(tableRes)))
- {
- fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\"*/ //\n\
-/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s*/ //\n\n",
- row[6], /* sql_mode */
- quote_name(row[0], name_buff, 0), /* Trigger */
- row[4], /* Timing */
- row[1], /* Event */
- result_table,
- row[3] /* Statement */);
- }
- if (mysql_num_rows(tableRes))
- fprintf(sql_file,
- "DELIMITER ;//\n\
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;");
- mysql_free_result(tableRes);
- }
}
my_snprintf(query_buff, sizeof(query_buff), "show fields from %s",
result_table);
@@ -1657,6 +1731,68 @@ continue_xml:
} /* get_table_structure */
+/*
+
+ dump_triggers_for_table
+
+ Dumps the triggers given a table/db name. This should be called after
+ the tables have been dumped in case a trigger depends on the existence
+ of a table
+
+ INPUT
+ char * tablename and db name
+ RETURNS
+ 0 Failure
+ 1 Succes
+
+*/
+
+static void dump_triggers_for_table (char *table, char *db)
+{
+ MYSQL_RES *result;
+ MYSQL_ROW row;
+ char *result_table;
+ char name_buff[NAME_LEN+3], table_buff[NAME_LEN*2+3];
+ char query_buff[512];
+ FILE *sql_file = md_result_file;
+
+ DBUG_ENTER("dump_triggers_for_table");
+ DBUG_PRINT("enter", ("db: %s, table: %s", db, table));
+ result_table= quote_name(table, table_buff, 1);
+
+ my_snprintf(query_buff, sizeof(query_buff),
+ "SHOW TRIGGERS LIKE %s",
+ quote_for_like(table, name_buff));
+
+ if (mysql_query_with_error_report(sock, &result, query_buff))
+ {
+ if (path)
+ my_fclose(sql_file, MYF(MY_WME));
+ safe_exit(EX_MYSQLERR);
+ DBUG_VOID_RETURN;
+ }
+ if (mysql_num_rows(result))
+ fprintf(sql_file, "\n/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;\n\
+DELIMITER //;\n");
+ while ((row=mysql_fetch_row(result)))
+ {
+ fprintf(sql_file, "/*!50003 SET SESSION SQL_MODE=\"%s\" */ //\n\
+/*!50003 CREATE TRIGGER %s %s %s ON %s FOR EACH ROW%s */ //\n\n",
+ row[6], /* sql_mode */
+ quote_name(row[0], name_buff, 0), /* Trigger */
+ row[4], /* Timing */
+ row[1], /* Event */
+ result_table,
+ row[3] /* Statement */);
+ }
+ if (mysql_num_rows(result))
+ fprintf(sql_file,
+ "DELIMITER ;//\n\
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;");
+ mysql_free_result(result);
+ DBUG_VOID_RETURN;
+}
+
static char *add_load_option(char *ptr,const char *object,
const char *statement)
{
@@ -2376,8 +2512,17 @@ static int dump_all_tables_in_db(char *database)
dump_table(numrows,table);
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
order_by= 0;
+ if (opt_dump_triggers && ! opt_xml &&
+ mysql_get_server_version(sock) >= 50009)
+ dump_triggers_for_table(table, database);
}
}
+ if (opt_routines && !opt_xml &&
+ mysql_get_server_version(sock) >= 50009)
+ {
+ DBUG_PRINT("info", ("Dumping routines for database %s", database));
+ dump_routines_for_db(database);
+ }
if (opt_xml)
{
fputs("</database>\n", md_result_file);
@@ -2569,6 +2714,9 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
DBUG_PRINT("info",("Dumping table %s", table_name));
numrows= get_table_structure(table_name, db);
dump_table(numrows, table_name);
+ if (opt_dump_triggers &&
+ mysql_get_server_version(sock) >= 50009)
+ dump_triggers_for_table(table_name, db);
}
/* Dump each selected view */
@@ -2580,6 +2728,13 @@ static int dump_selected_tables(char *db, char **table_names, int tables)
get_view_structure(table_name, db);
}
}
+ /* obtain dump of routines (procs/functions) */
+ if (opt_routines && !opt_xml &&
+ mysql_get_server_version(sock) >= 50009)
+ {
+ DBUG_PRINT("info", ("Dumping routines for database %s", db));
+ dump_routines_for_db(db);
+ }
hash_free(&dump_tables);
my_free(order_by, MYF(MY_ALLOW_ZERO_PTR));
order_by= 0;
diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result
index 917724580cf..97d5aad2566 100644
--- a/mysql-test/r/mysqldump.result
+++ b/mysql-test/r/mysqldump.result
@@ -1738,61 +1738,61 @@ CREATE TABLE `t1` (
`b` bigint(20) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+LOCK TABLES `t1` WRITE;
+INSERT INTO `t1` VALUES (1,NULL),(2,NULL),(4,NULL),(11,NULL);
+UNLOCK TABLES;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+
/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER //;
-/*!50003 SET SESSION SQL_MODE=""*/ //
+/*!50003 SET SESSION SQL_MODE="" */ //
/*!50003 CREATE TRIGGER `trg1` BEFORE INSERT ON `t1` FOR EACH ROW
begin
if new.a > 10 then
set new.a := 10;
set new.a := 11;
end if;
-end*/ //
+end */ //
-/*!50003 SET SESSION SQL_MODE=""*/ //
+/*!50003 SET SESSION SQL_MODE="" */ //
/*!50003 CREATE TRIGGER `trg2` BEFORE UPDATE ON `t1` FOR EACH ROW begin
if old.a % 2 = 0 then set new.b := 12; end if;
-end*/ //
+end */ //
-/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER"*/ //
+/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */ //
/*!50003 CREATE TRIGGER `trg3` AFTER UPDATE ON `t1` FOR EACH ROW
begin
if new.a = -1 then
set @fired:= "Yes";
end if;
-end*/ //
+end */ //
DELIMITER ;//
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;
-
-/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
-LOCK TABLES `t1` WRITE;
-INSERT INTO `t1` VALUES (1,NULL),(2,NULL),(4,NULL),(11,NULL);
-UNLOCK TABLES;
-/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
-DROP TABLE IF EXISTS `t2`;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;DROP TABLE IF EXISTS `t2`;
CREATE TABLE `t2` (
`a` int(11) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
+LOCK TABLES `t2` WRITE;
+UNLOCK TABLES;
+/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
+
/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
DELIMITER //;
-/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER"*/ //
+/*!50003 SET SESSION SQL_MODE="STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER" */ //
/*!50003 CREATE TRIGGER `trg4` BEFORE INSERT ON `t2` FOR EACH ROW
begin
if new.a > 10 then
set @fired:= "No";
end if;
-end*/ //
+end */ //
DELIMITER ;//
-/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;
-
-/*!40000 ALTER TABLE `t2` DISABLE KEYS */;
-LOCK TABLES `t2` WRITE;
-UNLOCK TABLES;
-/*!40000 ALTER TABLE `t2` ENABLE KEYS */;
-
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
@@ -1875,3 +1875,120 @@ set @fired:= "No";
end if;
end BEFORE # STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER
DROP TABLE t1, t2;
+DROP TABLE IF EXISTS `test1`;
+Warnings:
+Note 1051 Unknown table 'test1'
+CREATE TABLE `test1` (
+`a1` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+DROP TABLE IF EXISTS `test2`;
+Warnings:
+Note 1051 Unknown table 'test2'
+CREATE TABLE `test2` (
+`a2` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+CREATE TRIGGER `testref` BEFORE INSERT ON `test1` FOR EACH ROW BEGIN
+INSERT INTO test2 SET a2 = NEW.a1; END //
+INSERT INTO `test1` VALUES (1);
+SELECT * FROM `test2`;
+a2
+1
+SHOW TRIGGERS;
+Trigger Event Table Statement Timing Created sql_mode
+testref INSERT test1 BEGIN
+INSERT INTO test2 SET a2 = NEW.a1; END BEFORE NULL
+SELECT * FROM `test1`;
+a1
+1
+SELECT * FROM `test2`;
+a2
+1
+DROP TRIGGER testref;
+DROP TABLE test1;
+DROP TABLE test2;
+CREATE TABLE t1 (id int);
+INSERT INTO t1 VALUES(1);
+INSERT INTO t1 VALUES(2);
+INSERT INTO t1 VALUES(3);
+INSERT INTO t1 VALUES(4);
+INSERT INTO t1 VALUES(5);
+DROP FUNCTION IF EXISTS bug9056_func1;
+CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
+RETURN a+b //
+CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
+BEGIN SELECT a+b INTO c; end //
+DROP FUNCTION IF EXISTS bug9056_func2 //
+create function bug9056_func2(f1 char binary) returns char binary
+begin
+set f1= concat( 'hello', f1 );
+return f1;
+end //
+DROP PROCEDURE IF EXISTS bug9056_proc2 //
+CREATE PROCEDURE bug9056_proc2(OUT a INT)
+BEGIN
+select sum(id) from t1 into a;
+END //
+
+/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
+/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
+/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
+/*!40101 SET NAMES utf8 */;
+/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
+/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
+/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
+/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
+
+CREATE DATABASE /*!32312 IF NOT EXISTS*/ `test` /*!40100 DEFAULT CHARACTER SET latin1 */;
+
+USE `test`;
+DROP TABLE IF EXISTS `t1`;
+CREATE TABLE `t1` (
+ `id` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+
+/*!40000 ALTER TABLE `t1` DISABLE KEYS */;
+LOCK TABLES `t1` WRITE;
+INSERT INTO `t1` VALUES (1),(2),(3),(4),(5);
+UNLOCK TABLES;
+/*!40000 ALTER TABLE `t1` ENABLE KEYS */;
+
+/*!50003 SET @OLD_SQL_MODE=@@SQL_MODE*/;
+DELIMITER //
+/*!50003 SET SESSION SQL_MODE=""*/ //
+/*!50003 DROP FUNCTION IF EXISTS bug9056_func1 */ //
+/*!50003 CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
+RETURN a+b */ //
+/*!50003 SET SESSION SQL_MODE=""*/ //
+/*!50003 DROP FUNCTION IF EXISTS bug9056_func2 */ //
+/*!50003 CREATE FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1)
+begin
+set f1= concat( 'hello', f1 );
+return f1;
+end */ //
+/*!50003 SET SESSION SQL_MODE=""*/ //
+/*!50003 DROP PROCEDURE IF EXISTS bug9056_proc1 */ //
+/*!50003 CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
+BEGIN SELECT a+b INTO c; end */ //
+/*!50003 SET SESSION SQL_MODE=""*/ //
+/*!50003 DROP PROCEDURE IF EXISTS bug9056_proc2 */ //
+/*!50003 CREATE PROCEDURE `bug9056_proc2`(OUT a INT)
+BEGIN
+select sum(id) from t1 into a;
+END */ //
+DELIMITER ;
+/*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;
+
+/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
+/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
+/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
+/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
+/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
+/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
+/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
+
+DROP PROCEDURE IF EXISTS bug9056_func1;
+DROP PROCEDURE IF EXISTS bug9056_func2;
+DROP PROCEDURE IF EXISTS bug9056_proc1;
+DROP PROCEDURE IF EXISTS bug9056_proc2;
+drop table t1;
diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test
index 27bea937dcf..6ff5ea8451f 100644
--- a/mysql-test/t/mysqldump.test
+++ b/mysql-test/t/mysqldump.test
@@ -761,3 +761,85 @@ show tables;
--replace_column 6 #
show triggers;
DROP TABLE t1, t2;
+
+# Test of fix to BUG 12597
+DROP TABLE IF EXISTS `test1`;
+CREATE TABLE `test1` (
+ `a1` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+DROP TABLE IF EXISTS `test2`;
+CREATE TABLE `test2` (
+ `a2` int(11) default NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1;
+
+DELIMITER //;
+CREATE TRIGGER `testref` BEFORE INSERT ON `test1` FOR EACH ROW BEGIN
+INSERT INTO test2 SET a2 = NEW.a1; END //
+DELIMITER ;//
+
+INSERT INTO `test1` VALUES (1);
+SELECT * FROM `test2`;
+
+# dump
+--exec $MYSQL_DUMP --skip-comments --databases test > var/tmp/mysqldump.sql
+
+#DROP TRIGGER testref;
+#DROP TABLE test1;
+#DROP TABLE test2;
+# restore
+--exec $MYSQL test < var/tmp/mysqldump.sql
+SHOW TRIGGERS;
+SELECT * FROM `test1`;
+SELECT * FROM `test2`;
+
+DROP TRIGGER testref;
+DROP TABLE test1;
+DROP TABLE test2;
+
+CREATE TABLE t1 (id int);
+INSERT INTO t1 VALUES(1);
+INSERT INTO t1 VALUES(2);
+INSERT INTO t1 VALUES(3);
+INSERT INTO t1 VALUES(4);
+INSERT INTO t1 VALUES(5);
+--disable_warnings
+DROP FUNCTION IF EXISTS bug9056_func1;
+DELIMITER //;
+--enable_warnings
+CREATE FUNCTION `bug9056_func1`(a INT, b INT) RETURNS int(11)
+RETURN a+b //
+CREATE PROCEDURE `bug9056_proc1`(IN a INT, IN b INT, OUT c INT)
+BEGIN SELECT a+b INTO c; end //
+
+--disable_warnings
+DROP FUNCTION IF EXISTS bug9056_func2 //
+--enable_warnings
+
+create function bug9056_func2(f1 char binary) returns char binary
+begin
+ set f1= concat( 'hello', f1 );
+ return f1;
+end //
+
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug9056_proc2 //
+--enable_warnings
+CREATE PROCEDURE bug9056_proc2(OUT a INT)
+BEGIN
+ select sum(id) from t1 into a;
+END //
+
+DELIMITER ;//
+
+# Dump the DB and ROUTINES
+--exec $MYSQL_DUMP --skip-comments --routines --databases test
+
+# ok, now blow it all away
+--disable_warnings
+DROP PROCEDURE IF EXISTS bug9056_func1;
+DROP PROCEDURE IF EXISTS bug9056_func2;
+DROP PROCEDURE IF EXISTS bug9056_proc1;
+DROP PROCEDURE IF EXISTS bug9056_proc2;
+drop table t1;
+--enable-warnings
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 5079c462ac0..78a512d0ddb 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1169,6 +1169,8 @@ void Item_func_between::print(String *str)
{
str->append('(');
args[0]->print(str);
+ if (negated)
+ str->append(" not", 4);
str->append(" between ", 9);
args[1]->print(str);
str->append(" and ", 5);
@@ -2411,6 +2413,8 @@ void Item_func_in::print(String *str)
{
str->append('(');
args[0]->print(str);
+ if (negated)
+ str->append(" not", 4);
str->append(" in (", 5);
print_args(str, 1);
str->append("))", 2);
diff --git a/sql/sp_head.cc b/sql/sp_head.cc
index 1ab8e0c205c..0444499de48 100644
--- a/sql/sp_head.cc
+++ b/sql/sp_head.cc
@@ -942,11 +942,12 @@ int sp_head::execute(THD *thd)
*/
thd->stmt_arena= i;
- /* will binlog this separately */
- if (thd->prelocked_mode == NON_PRELOCKED) //TODO: change to event union?
- {
+ /*
+ Will write this SP statement into binlog separately
+ (TODO: consider changing the condition to "not inside event union")
+ */
+ if (thd->prelocked_mode == NON_PRELOCKED)
thd->user_var_events_alloc= thd->mem_root;
- }
ret= i->execute(thd, &ip);
@@ -959,10 +960,20 @@ int sp_head::execute(THD *thd)
if (i->free_list)
cleanup_items(i->free_list);
i->state= Query_arena::EXECUTED;
+
+ /*
+ If we've set thd->user_var_events_alloc to mem_root of this SP
+ statement, clean all the events allocated in it.
+ */
+ if (thd->prelocked_mode == NON_PRELOCKED)
+ {
+ reset_dynamic(&thd->user_var_events);
+ thd->user_var_events_alloc= NULL;//DEBUG
+ }
/* we should cleanup free_list and memroot, used by instruction */
thd->free_items();
- free_root(&execute_mem_root, MYF(0));
+ free_root(&execute_mem_root, MYF(0));
/*
Check if an exception has occurred and a handler has been found
diff --git a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index 040f839711b..df1e269978f 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -89,6 +89,17 @@
#define ZCURR_PAGE_INDEX 8
#define ZLAST_LOG_PREP_REF 10
#define ZPOS_DIRTY 11
+/* A number of debug items written in the page header of all log files */
+#define ZPOS_LOG_TIMER 12
+#define ZPOS_PAGE_I 13
+#define ZPOS_PLACE_WRITTEN_FROM 14
+#define ZPOS_PAGE_NO 15
+#define ZPOS_PAGE_FILE_NO 16
+#define ZPOS_WORD_WRITTEN 17
+#define ZPOS_IN_WRITING 18
+#define ZPOS_PREV_PAGE_NO 19
+#define ZPOS_IN_FREE_LIST 20
+
/* ------------------------------------------------------------------------- */
/* CONSTANTS FOR THE VARIOUS REPLICA AND NODE TYPES. */
/* ------------------------------------------------------------------------- */
@@ -2281,7 +2292,7 @@ private:
const LogPartRecordPtr &sltLogPartPtr);
void checkGcpCompleted(Signal* signal, Uint32 pageWritten, Uint32 wordWritten);
void initFsopenconf(Signal* signal);
- void initFsrwconf(Signal* signal);
+ void initFsrwconf(Signal* signal, bool write);
void initLfo(Signal* signal);
void initLogfile(Signal* signal, Uint32 fileNo);
void initLogpage(Signal* signal);
@@ -2297,7 +2308,8 @@ private:
void writeFileDescriptor(Signal* signal);
void writeFileHeaderOpen(Signal* signal, Uint32 type);
void writeInitMbyte(Signal* signal);
- void writeSinglePage(Signal* signal, Uint32 pageNo, Uint32 wordWritten);
+ void writeSinglePage(Signal* signal, Uint32 pageNo,
+ Uint32 wordWritten, Uint32 place);
void buildLinkedLogPageList(Signal* signal);
void changeMbyte(Signal* signal);
Uint32 checkIfExecLog(Signal* signal);
@@ -2306,7 +2318,7 @@ private:
void checkScanTcCompleted(Signal* signal);
void checkSrCompleted(Signal* signal);
void closeFile(Signal* signal, LogFileRecordPtr logFilePtr);
- void completedLogPage(Signal* signal, Uint32 clpType);
+ void completedLogPage(Signal* signal, Uint32 clpType, Uint32 place);
void deleteFragrec(Uint32 fragId);
void deleteTransidHash(Signal* signal);
void findLogfile(Signal* signal,
@@ -2404,7 +2416,9 @@ private:
void writeAbortLog(Signal* signal);
void writeCommitLog(Signal* signal, LogPartRecordPtr regLogPartPtr);
void writeCompletedGciLog(Signal* signal);
- void writeDirty(Signal* signal);
+ void writeDbgInfoPageHeader(LogPageRecordPtr logPagePtr, Uint32 place,
+ Uint32 pageNo, Uint32 wordWritten);
+ void writeDirty(Signal* signal, Uint32 place);
void writeKey(Signal* signal);
void writeLogHeader(Signal* signal);
void writeLogWord(Signal* signal, Uint32 data);
diff --git a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 4353d481d1a..538850c4fb1 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -11796,42 +11796,34 @@ void Dblqh::execFSCLOSECONF(Signal* signal)
ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
exitFromInvalidate(signal);
return;
- break;
case LogFileRecord::CLOSING_INIT:
jam();
closingInitLab(signal);
return;
- break;
case LogFileRecord::CLOSING_SR:
jam();
closingSrLab(signal);
return;
- break;
case LogFileRecord::CLOSING_EXEC_SR:
jam();
closeExecSrLab(signal);
return;
- break;
case LogFileRecord::CLOSING_EXEC_SR_COMPLETED:
jam();
closeExecSrCompletedLab(signal);
return;
- break;
case LogFileRecord::CLOSING_WRITE_LOG:
jam();
closeWriteLogLab(signal);
return;
- break;
case LogFileRecord::CLOSING_EXEC_LOG:
jam();
closeExecLogLab(signal);
return;
- break;
default:
jam();
systemErrorLab(signal);
return;
- break;
}//switch
}//Dblqh::execFSCLOSECONF()
@@ -11849,77 +11841,64 @@ void Dblqh::execFSOPENCONF(Signal* signal)
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
readFileInInvalidate(signal);
return;
- break;
case LogFileRecord::OPENING_INIT:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openFileInitLab(signal);
return;
- break;
case LogFileRecord::OPEN_SR_FRONTPAGE:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openSrFrontpageLab(signal);
return;
- break;
case LogFileRecord::OPEN_SR_LAST_FILE:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openSrLastFileLab(signal);
return;
- break;
case LogFileRecord::OPEN_SR_NEXT_FILE:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openSrNextFileLab(signal);
return;
- break;
case LogFileRecord::OPEN_EXEC_SR_START:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openExecSrStartLab(signal);
return;
- break;
case LogFileRecord::OPEN_EXEC_SR_NEW_MBYTE:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openExecSrNewMbyteLab(signal);
return;
- break;
case LogFileRecord::OPEN_SR_FOURTH_PHASE:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openSrFourthPhaseLab(signal);
return;
- break;
case LogFileRecord::OPEN_SR_FOURTH_NEXT:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openSrFourthNextLab(signal);
return;
- break;
case LogFileRecord::OPEN_SR_FOURTH_ZERO:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openSrFourthZeroLab(signal);
return;
- break;
case LogFileRecord::OPENING_WRITE_LOG:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
return;
- break;
case LogFileRecord::OPEN_EXEC_LOG:
jam();
logFilePtr.p->logFileStatus = LogFileRecord::OPEN;
openExecLogLab(signal);
return;
- break;
default:
jam();
systemErrorLab(signal);
return;
- break;
}//switch
}//Dblqh::execFSOPENCONF()
@@ -11930,7 +11909,7 @@ void Dblqh::execFSOPENCONF(Signal* signal)
void Dblqh::execFSREADCONF(Signal* signal)
{
jamEntry();
- initFsrwconf(signal);
+ initFsrwconf(signal, false);
switch (lfoPtr.p->lfoState) {
case LogFileOperationRecord::READ_SR_LAST_MBYTE:
@@ -11938,57 +11917,47 @@ void Dblqh::execFSREADCONF(Signal* signal)
releaseLfo(signal);
readSrLastMbyteLab(signal);
return;
- break;
case LogFileOperationRecord::READ_SR_FRONTPAGE:
jam();
releaseLfo(signal);
readSrFrontpageLab(signal);
return;
- break;
case LogFileOperationRecord::READ_SR_LAST_FILE:
jam();
releaseLfo(signal);
readSrLastFileLab(signal);
return;
- break;
case LogFileOperationRecord::READ_SR_NEXT_FILE:
jam();
releaseLfo(signal);
readSrNextFileLab(signal);
return;
- break;
case LogFileOperationRecord::READ_EXEC_SR:
jam();
readExecSrLab(signal);
return;
- break;
case LogFileOperationRecord::READ_EXEC_LOG:
jam();
readExecLogLab(signal);
return;
- break;
case LogFileOperationRecord::READ_SR_INVALIDATE_PAGES:
jam();
invalidateLogAfterLastGCI(signal);
return;
- break;
case LogFileOperationRecord::READ_SR_FOURTH_PHASE:
jam();
releaseLfo(signal);
readSrFourthPhaseLab(signal);
return;
- break;
case LogFileOperationRecord::READ_SR_FOURTH_ZERO:
jam();
releaseLfo(signal);
readSrFourthZeroLab(signal);
return;
- break;
default:
jam();
systemErrorLab(signal);
return;
- break;
}//switch
}//Dblqh::execFSREADCONF()
@@ -12045,63 +12014,52 @@ void Dblqh::execFSREADREF(Signal* signal)
void Dblqh::execFSWRITECONF(Signal* signal)
{
jamEntry();
- initFsrwconf(signal);
+ initFsrwconf(signal, true);
switch (lfoPtr.p->lfoState) {
case LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES:
jam();
invalidateLogAfterLastGCI(signal);
return;
- break;
case LogFileOperationRecord::WRITE_PAGE_ZERO:
jam();
writePageZeroLab(signal);
return;
- break;
case LogFileOperationRecord::LAST_WRITE_IN_FILE:
jam();
lastWriteInFileLab(signal);
return;
- break;
case LogFileOperationRecord::INIT_WRITE_AT_END:
jam();
initWriteEndLab(signal);
return;
- break;
case LogFileOperationRecord::INIT_FIRST_PAGE:
jam();
initFirstPageLab(signal);
return;
- break;
case LogFileOperationRecord::WRITE_GCI_ZERO:
jam();
writeGciZeroLab(signal);
return;
- break;
case LogFileOperationRecord::WRITE_DIRTY:
jam();
writeDirtyLab(signal);
return;
- break;
case LogFileOperationRecord::WRITE_INIT_MBYTE:
jam();
writeInitMbyteLab(signal);
return;
- break;
case LogFileOperationRecord::ACTIVE_WRITE_LOG:
jam();
writeLogfileLab(signal);
return;
- break;
case LogFileOperationRecord::FIRST_PAGE_WRITE_IN_LOGFILE:
jam();
firstPageWriteLab(signal);
return;
- break;
default:
jam();
systemErrorLab(signal);
return;
- break;
}//switch
}//Dblqh::execFSWRITECONF()
@@ -12177,16 +12135,35 @@ void Dblqh::initFsopenconf(Signal* signal)
/* ======= INITIATE WHEN RECEIVING FSREADCONF AND FSWRITECONF ======= */
/* */
/* ========================================================================= */
-void Dblqh::initFsrwconf(Signal* signal)
+void Dblqh::initFsrwconf(Signal* signal, bool write)
{
+ LogPageRecordPtr logP;
+ Uint32 noPages, totPages;
lfoPtr.i = signal->theData[0];
ptrCheckGuard(lfoPtr, clfoFileSize, logFileOperationRecord);
+ totPages= lfoPtr.p->noPagesRw;
logFilePtr.i = lfoPtr.p->logFileRec;
ptrCheckGuard(logFilePtr, clogFileFileSize, logFileRecord);
logPartPtr.i = logFilePtr.p->logPartRec;
ptrCheckGuard(logPartPtr, clogPartFileSize, logPartRecord);
logPagePtr.i = lfoPtr.p->firstLfoPage;
ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
+ logP= logPagePtr;
+ noPages= 1;
+ ndbassert(totPages > 0);
+ for (;;)
+ {
+ logP.p->logPageWord[ZPOS_IN_WRITING]= 0;
+ logP.p->logPageWord[ZPOS_IN_FREE_LIST]= 0;
+ if (noPages == totPages)
+ return;
+ if (write)
+ logP.i= logP.p->logPageWord[ZNEXT_PAGE];
+ else
+ logP.i= lfoPtr.p->logPageArray[noPages];
+ ptrCheckGuard(logP, clogPageFileSize, logPageRecord);
+ noPages++;
+ }
}//Dblqh::initFsrwconf()
/* ######################################################################### */
@@ -12274,7 +12251,7 @@ void Dblqh::timeSup(Signal* signal)
ndbrequire(wordWritten < ZPAGE_SIZE);
if (logFilePtr.p->noLogpagesInBuffer > 0) {
jam();
- completedLogPage(signal, ZENFORCE_WRITE);
+ completedLogPage(signal, ZENFORCE_WRITE, __LINE__);
/*---------------------------------------------------------------------------*/
/*SINCE WE ARE ONLY WRITING PART OF THE LAST PAGE WE HAVE TO UPDATE THE WORD */
/*WRITTEN TO REFLECT THE REAL LAST WORD WRITTEN. WE ALSO HAVE TO MOVE THE */
@@ -12296,7 +12273,8 @@ void Dblqh::timeSup(Signal* signal)
releaseLogpage(signal);
} else {
jam();
- writeSinglePage(signal, logFilePtr.p->currentFilepage, wordWritten);
+ writeSinglePage(signal, logFilePtr.p->currentFilepage,
+ wordWritten, __LINE__);
lfoPtr.p->lfoState = LogFileOperationRecord::ACTIVE_WRITE_LOG;
}//if
}//if
@@ -12432,7 +12410,7 @@ void Dblqh::firstPageWriteLab(Signal* signal)
logPagePtr.i = logFilePtr.p->logPageZero;
ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
lfoPtr.p->logFileRec = currLogFile;
lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
return;
@@ -12521,7 +12499,7 @@ void Dblqh::lastWriteInFileLab(Signal* signal)
logPagePtr.i = logFilePtr.p->logPageZero;
ptrCheckGuard(logPagePtr, clogPageFileSize, logPageRecord);
logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + ZPOS_FILE_NO] = fileNo;
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
lfoPtr.p->logFileRec = currLogFile;
lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_PAGE_ZERO;
return;
@@ -12572,7 +12550,8 @@ void Dblqh::openFileInitLab(Signal* signal)
{
logFilePtr.p->logFileStatus = LogFileRecord::OPEN_INIT;
seizeLogpage(signal);
- writeSinglePage(signal, (ZNO_MBYTES_IN_FILE * ZPAGES_IN_MBYTE) - 1, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, (ZNO_MBYTES_IN_FILE * ZPAGES_IN_MBYTE) - 1,
+ ZPAGE_SIZE - 1, __LINE__);
lfoPtr.p->lfoState = LogFileOperationRecord::INIT_WRITE_AT_END;
return;
}//Dblqh::openFileInitLab()
@@ -12613,7 +12592,7 @@ void Dblqh::initFirstPageLab(Signal* signal)
logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 1;
logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE] = ZCOMPLETED_GCI_TYPE;
logPagePtr.p->logPageWord[ZPAGE_HEADER_SIZE + 1] = 1;
- writeSinglePage(signal, 1, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, 1, ZPAGE_SIZE - 1, __LINE__);
lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_GCI_ZERO;
return;
}//if
@@ -12915,17 +12894,13 @@ void Dblqh::releaseLogpage(Signal* signal)
{
#ifdef VM_TRACE
// Check that log page isn't already in free list
- LogPageRecordPtr TlogPagePtr;
- TlogPagePtr.i = cfirstfreeLogPage;
- while (TlogPagePtr.i != RNIL){
- ptrCheckGuard(TlogPagePtr, clogPageFileSize, logPageRecord);
- ndbrequire(TlogPagePtr.i != logPagePtr.i);
- TlogPagePtr.i = TlogPagePtr.p->logPageWord[ZNEXT_PAGE];
- }
+ ndbrequire(logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] == 0);
#endif
cnoOfLogPages++;
logPagePtr.p->logPageWord[ZNEXT_PAGE] = cfirstfreeLogPage;
+ logPagePtr.p->logPageWord[ZPOS_IN_WRITING]= 0;
+ logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST]= 1;
cfirstfreeLogPage = logPagePtr.i;
}//Dblqh::releaseLogpage()
@@ -12971,6 +12946,7 @@ void Dblqh::seizeLogpage(Signal* signal)
/* ------------------------------------------------------------------------- */
cfirstfreeLogPage = logPagePtr.p->logPageWord[ZNEXT_PAGE];
logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
+ logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST] = 0;
}//Dblqh::seizeLogpage()
/* ------------------------------------------------------------------------- */
@@ -13078,7 +13054,7 @@ WMO_LOOP:
/* LOG FILE. THIS HAS SPECIAL SIGNIFANCE TO FIND */
/* THE END OF THE LOG AT SYSTEM RESTART. */
/* ------------------------------------------------------- */
- writeSinglePage(signal, 0, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, 0, ZPAGE_SIZE - 1, __LINE__);
if (wmoType == ZINIT) {
jam();
lfoPtr.p->lfoState = LogFileOperationRecord::INIT_FIRST_PAGE;
@@ -13112,7 +13088,8 @@ WMO_LOOP:
void Dblqh::writeInitMbyte(Signal* signal)
{
initLogpage(signal);
- writeSinglePage(signal, logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, logFilePtr.p->currentMbyte * ZPAGES_IN_MBYTE,
+ ZPAGE_SIZE - 1, __LINE__);
lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_INIT_MBYTE;
}//Dblqh::writeInitMbyte()
@@ -13122,13 +13099,15 @@ void Dblqh::writeInitMbyte(Signal* signal)
/* INPUT: TWSP_PAGE_NO THE PAGE NUMBER WRITTEN */
/* SUBROUTINE SHORT NAME: WSP */
/* ------------------------------------------------------------------------- */
-void Dblqh::writeSinglePage(Signal* signal, Uint32 pageNo, Uint32 wordWritten)
+void Dblqh::writeSinglePage(Signal* signal, Uint32 pageNo,
+ Uint32 wordWritten, Uint32 place)
{
seizeLfo(signal);
initLfo(signal);
lfoPtr.p->firstLfoPage = logPagePtr.i;
logPagePtr.p->logPageWord[ZNEXT_PAGE] = RNIL;
+ writeDbgInfoPageHeader(logPagePtr, place, pageNo, wordWritten);
// Calculate checksum for page
logPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(logPagePtr);
@@ -14596,7 +14575,7 @@ void Dblqh::execSr(Signal* signal)
* IN THIS WE HAVE COMPLETED EXECUTION OF THE CURRENT LOG PAGE
* AND CAN WRITE IT TO DISK SINCE IT IS DIRTY.
* ----------------------------------------------------------------- */
- writeDirty(signal);
+ writeDirty(signal, __LINE__);
return;
break;
case LogPartRecord::LES_EXEC_LOG:
@@ -14607,7 +14586,7 @@ void Dblqh::execSr(Signal* signal)
* ------------------------------------------------------------------- */
if (logFilePtr.p->currentLogpage != logPartPtr.p->prevLogpage) {
jam();
- writeDirty(signal);
+ writeDirty(signal, __LINE__);
return;
}//if
break;
@@ -15051,7 +15030,8 @@ void Dblqh::invalidateLogAfterLastGCI(Signal* signal) {
// This page must be invalidated.
logPagePtr.p->logPageWord[ZPOS_LOG_LAP] = 0;
// Contact NDBFS. Real time break.
- writeSinglePage(signal, logPartPtr.p->invalidatePageNo, ZPAGE_SIZE - 1);
+ writeSinglePage(signal, logPartPtr.p->invalidatePageNo,
+ ZPAGE_SIZE - 1, __LINE__);
lfoPtr.p->lfoState = LogFileOperationRecord::WRITE_SR_INVALIDATE_PAGES;
} else {
// We are done with invalidating. Finish start phase 3.4.
@@ -16000,7 +15980,7 @@ void Dblqh::closeFile(Signal* signal, LogFileRecordPtr clfLogFilePtr)
// logPartPtr
// Defines lfoPtr
/* ---------------------------------------------------------------- */
-void Dblqh::completedLogPage(Signal* signal, Uint32 clpType)
+void Dblqh::completedLogPage(Signal* signal, Uint32 clpType, Uint32 place)
{
LogPageRecordPtr clpLogPagePtr;
LogPageRecordPtr wlpLogPagePtr;
@@ -16043,6 +16023,9 @@ void Dblqh::completedLogPage(Signal* signal, Uint32 clpType)
twlpNoPages++;
ptrCheckGuard(wlpLogPagePtr, clogPageFileSize, logPageRecord);
+ writeDbgInfoPageHeader(wlpLogPagePtr, place,
+ logFilePtr.p->filePosition + twlpNoPages - 1,
+ ZPAGE_SIZE);
// Calculate checksum for page
wlpLogPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(wlpLogPagePtr);
wlpLogPagePtr.i = wlpLogPagePtr.p->logPageWord[ZNEXT_PAGE];
@@ -16445,6 +16428,8 @@ void Dblqh::initialiseLogPage(Signal* signal)
refresh_watch_dog();
ptrAss(logPagePtr, logPageRecord);
logPagePtr.p->logPageWord[ZNEXT_PAGE] = logPagePtr.i + 1;
+ logPagePtr.p->logPageWord[ZPOS_IN_FREE_LIST]= 1;
+ logPagePtr.p->logPageWord[ZPOS_IN_WRITING]= 0;
}//for
logPagePtr.i = clogPageFileSize - 1;
ptrAss(logPagePtr, logPageRecord);
@@ -18101,10 +18086,14 @@ void Dblqh::writeCompletedGciLog(Signal* signal)
*
* SUBROUTINE SHORT NAME: WD
* ------------------------------------------------------------------------- */
-void Dblqh::writeDirty(Signal* signal)
+void Dblqh::writeDirty(Signal* signal, Uint32 place)
{
logPagePtr.p->logPageWord[ZPOS_DIRTY] = ZNOT_DIRTY;
+ ndbassert(logPartPtr.p->prevFilepage ==
+ logPagePtr.p->logPageWord[ZPOS_PAGE_NO]);
+ writeDbgInfoPageHeader(logPagePtr, place, logPartPtr.p->prevFilepage,
+ ZPAGE_SIZE);
// Calculate checksum for page
logPagePtr.p->logPageWord[ZPOS_CHECKSUM] = calcPageCheckSum(logPagePtr);
@@ -18138,7 +18127,7 @@ void Dblqh::writeLogWord(Signal* signal, Uint32 data)
logPagePtr.p->logPageWord[ZCURR_PAGE_INDEX] = logPos + 1;
if ((logPos + 1) == ZPAGE_SIZE) {
jam();
- completedLogPage(signal, ZNORMAL);
+ completedLogPage(signal, ZNORMAL, __LINE__);
seizeLogpage(signal);
initLogpage(signal);
logFilePtr.p->currentLogpage = logPagePtr.i;
@@ -18196,7 +18185,7 @@ void Dblqh::writeNextLog(Signal* signal)
/* -------------------------------------------------- */
/* WE HAVE TO CHANGE LOG FILE */
/* -------------------------------------------------- */
- completedLogPage(signal, ZLAST_WRITE_IN_FILE);
+ completedLogPage(signal, ZLAST_WRITE_IN_FILE, __LINE__);
if (wnlNextLogFilePtr.p->fileNo == 0) {
jam();
/* -------------------------------------------------- */
@@ -18215,7 +18204,7 @@ void Dblqh::writeNextLog(Signal* signal)
/* INCREMENT THE CURRENT MBYTE */
/* SET PAGE INDEX TO PAGE HEADER SIZE */
/* -------------------------------------------------- */
- completedLogPage(signal, ZENFORCE_WRITE);
+ completedLogPage(signal, ZENFORCE_WRITE, __LINE__);
twnlNewMbyte = logFilePtr.p->currentMbyte + 1;
}//if
/* -------------------------------------------------- */
@@ -18640,3 +18629,16 @@ Uint32 Dblqh::calcPageCheckSum(LogPageRecordPtr logP){
return checkSum;
}
+void Dblqh::writeDbgInfoPageHeader(LogPageRecordPtr logP, Uint32 place,
+ Uint32 pageNo, Uint32 wordWritten)
+{
+ logP.p->logPageWord[ZPOS_LOG_TIMER]= logPartPtr.p->logTimer;
+ logP.p->logPageWord[ZPOS_PREV_PAGE_NO]= logP.p->logPageWord[ZPOS_PAGE_NO];
+ logP.p->logPageWord[ZPOS_PAGE_I]= logP.i;
+ logP.p->logPageWord[ZPOS_PLACE_WRITTEN_FROM]= place;
+ logP.p->logPageWord[ZPOS_PAGE_NO]= pageNo;
+ logP.p->logPageWord[ZPOS_PAGE_FILE_NO]= logFilePtr.p->fileNo;
+ logP.p->logPageWord[ZPOS_WORD_WRITTEN]= wordWritten;
+ logP.p->logPageWord[ZPOS_IN_WRITING]= 1;
+}
+
diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp
index b7e2ab072b5..6eadefe5df5 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp
@@ -266,7 +266,16 @@ NdbOut& operator<<(NdbOut& no, const PageHeader& ph) {
printOut("Current page index:", ph.m_current_page_index);
printOut("Oldest prepare op. file No.:", ph.m_old_prepare_file_number);
printOut("Oldest prepare op. page ref.:", ph.m_old_prepare_page_reference);
- printOut("Dirty flag:", ph.m_dirty_flag);
+ printOut("Dirty flag:", ph.m_dirty_flag);
+ printOut("Write Timer:", ph.m_log_timer);
+ printOut("Page i-val:", ph.m_page_i_value);
+ printOut("Place written:", ph.m_place_written_from);
+ printOut("Page No in File:", ph.m_page_no);
+ printOut("File No:", ph.m_file_no);
+ printOut("Word Written:", ph.m_word_written);
+ printOut("In Writing (should be 1)", ph.m_in_writing_flag);
+ printOut("Prev Page No (can be garbage)", ph.m_prev_page_no);
+ printOut("In Free List (should be 0):", ph.m_in_free_list);
no << endl;
return no;
}
diff --git a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp
index b2da7427f4e..06bf7a85d53 100644
--- a/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp
+++ b/storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp
@@ -147,6 +147,17 @@ protected:
Uint32 m_old_prepare_file_number;
Uint32 m_old_prepare_page_reference;
Uint32 m_dirty_flag;
+/* Debug info Start */
+ Uint32 m_log_timer;
+ Uint32 m_page_i_value;
+ Uint32 m_place_written_from;
+ Uint32 m_page_no;
+ Uint32 m_file_no;
+ Uint32 m_word_written;
+ Uint32 m_in_writing_flag;
+ Uint32 m_prev_page_no;
+ Uint32 m_in_free_list;
+/* Debug info End */
};
//----------------------------------------------------------------