#At file:///home/oysteing/mysql/mysql-6.0-backup-38810/
2707 oystein.grovlen@stripped 2008-10-13
BUG#38810 Backup: crash if trigger and event with same name
Issue: Server crashes when restoring a backup image of a database
with trigger and event with the same names.
Cause: Dependency table is indexed by name. Hence, trigger is not added when
event with same name has already been inserted.
Fix: Add type id to the key for the dependency table.
modified:
mysql-test/suite/backup/r/backup_triggers_and_events.result
mysql-test/suite/backup/t/backup_triggers_and_events.test
sql/backup/backup_info.cc
sql/backup/backup_info.h
per-file messages:
mysql-test/suite/backup/r/backup_triggers_and_events.result
Rename one trigger to test name collisions with events.
mysql-test/suite/backup/t/backup_triggers_and_events.test
Rename one trigger to test name collisions with events.
sql/backup/backup_info.cc
Add type info to keys for the dependency table.
sql/backup/backup_info.h
Add type parameter to get_dep_node so it so that type info can be added to the
Dep_node keys.
=== modified file 'mysql-test/suite/backup/r/backup_triggers_and_events.result'
--- a/mysql-test/suite/backup/r/backup_triggers_and_events.result 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/r/backup_triggers_and_events.result 2008-10-13 12:27:36 +0000
@@ -34,7 +34,7 @@ CALL trg_msg(NEW.a);
CREATE TRIGGER before_upd BEFORE UPDATE ON t1 FOR EACH ROW
CALL trg_msg(NEW.a);
||
-CREATE TRIGGER before_del BEFORE DELETE ON t1 FOR EACH ROW
+CREATE TRIGGER ev BEFORE DELETE ON t1 FOR EACH ROW
CALL trg_msg(OLD.a);
||
USE test||
@@ -134,7 +134,7 @@ Definer root@localhost
character_set_client #
collation_connection latin1_swedish_ci
Database Collation latin1_swedish_ci
-Trigger before_del
+Trigger ev
Event DELETE
Table t1
Statement CALL trg_msg(OLD.a)
=== modified file 'mysql-test/suite/backup/t/backup_triggers_and_events.test'
--- a/mysql-test/suite/backup/t/backup_triggers_and_events.test 2008-10-07 17:15:44 +0000
+++ b/mysql-test/suite/backup/t/backup_triggers_and_events.test 2008-10-13 12:27:36 +0000
@@ -79,7 +79,9 @@ CREATE TRIGGER before_upd BEFORE UPDATE
CALL trg_msg(NEW.a);
||
-CREATE TRIGGER before_del BEFORE DELETE ON t1 FOR EACH ROW
+# Create a trigger with the same name as an event to test that backup is
+# able to handle that. (Bug#38810)
+CREATE TRIGGER ev BEFORE DELETE ON t1 FOR EACH ROW
CALL trg_msg(OLD.a);
||
=== modified file 'sql/backup/backup_info.cc'
--- a/sql/backup/backup_info.cc 2008-09-16 16:09:18 +0000
+++ b/sql/backup/backup_info.cc 2008-10-13 12:27:36 +0000
@@ -250,7 +250,7 @@ struct Backup_info::Dep_node: public Sql
Dbobj *obj;
String key;
- Dep_node(const ::String &db_name, const ::String &name);
+ Dep_node(const ::String &db_name, const ::String &name, const obj_type type);
Dep_node(const Dep_node&);
static uchar* get_key(const uchar *record, size_t *key_length, my_bool);
@@ -264,13 +264,20 @@ struct Backup_info::Dep_node: public Sql
it belongs.
*/
inline
-Backup_info::Dep_node::Dep_node(const ::String &db_name, const ::String &name)
+Backup_info::Dep_node::Dep_node(const ::String &db_name, const ::String &name,
+ const obj_type type)
:next(NULL), obj(NULL)
{
key.length(0);
key.append(db_name);
key.append(".");
key.append(name);
+
+ // Add type to make sure keys are unique even between different namespaces
+ key.append("|");
+ String typestr;
+ typestr.set_int(type, TRUE, &my_charset_bin);
+ key.append(typestr);
}
inline
@@ -939,13 +946,13 @@ int Backup_info::add_view_deps(obs::Obj
Dep_node *n= NULL;
const ::String *name= bv->get_name();
const ::String *db_name= bv->get_db_name();
-
+
DBUG_ASSERT(name);
DBUG_ASSERT(db_name);
// Locate or create a dependency list node for the base view.
- int res= get_dep_node(*db_name, *name, n);
+ int res= get_dep_node(*db_name, *name, BSTREAM_IT_VIEW, n);
if (res == get_dep_node_res::ERROR)
goto error;
@@ -1061,7 +1068,7 @@ Backup_info::add_db_object(Db &db, const
// Get a dep. list node for the object.
- int res= get_dep_node(db.name(), *name, n);
+ int res= get_dep_node(db.name(), *name, type, n);
if (res == get_dep_node_res::ERROR)
{
@@ -1146,9 +1153,10 @@ Backup_info::add_db_object(Db &db, const
*/
int Backup_info::get_dep_node(const ::String &db_name,
const ::String &name,
+ const obj_type type,
Dep_node* &node)
{
- Dep_node n(db_name, name);
+ Dep_node n(db_name, name, type);
size_t klen;
uchar *key= Dep_node::get_key((const uchar*)&n, &klen, TRUE);
=== modified file 'sql/backup/backup_info.h'
--- a/sql/backup/backup_info.h 2008-08-20 13:23:10 +0000
+++ b/sql/backup/backup_info.h 2008-10-13 12:27:36 +0000
@@ -69,7 +69,8 @@ class Backup_info: public backup::Image_
struct Dep_node;
- int get_dep_node(const ::String&, const ::String&, Dep_node*&);
+ int get_dep_node(const ::String&, const ::String&, const obj_type,
+ Dep_node*&);
int add_to_dep_list(const obj_type, Dep_node*);
struct get_dep_node_res