diff options
-rw-r--r-- | client/mysqldump.c | 229 | ||||
-rw-r--r-- | mysql-test/r/mysqldump.result | 163 | ||||
-rw-r--r-- | mysql-test/t/mysqldump.test | 82 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 4 | ||||
-rw-r--r-- | sql/sp_head.cc | 21 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp | 22 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp | 140 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.cpp | 11 | ||||
-rw-r--r-- | storage/ndb/src/kernel/blocks/dblqh/redoLogReader/records.hpp | 11 |
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 */ }; //---------------------------------------------------------------- |