List:General Discussion« Previous MessageNext Message »
From:Chris Tucker Date:October 22 2003 4:31pm
Subject:Replication of foreign key constraint names (InnoDB) inconsistent
View as plain text  
 >Description:
   It is possible to get into a situation where foreign key constraints 
on a replication slave have different labels to the same foreign key 
constraint on the master.  This normally causes replication to fail when 
a drop of a foreign key on the master is attempted (although presumably 
it could, in a particularly unfortunate circumstance, drop the wrong 
constraint for a given table).

 >How-To-Repeat:
   Run the following on the master:
CREATE TABLE t1 (
    a INT NOT NULL PRIMARY KEY
);

   Then, on the slave run:
CREATE TABLE t2 (
    b INT NOT NULL PRIMARY KEY,
    FOREIGN KEY (b) REFERENCES t1 (a)
);

   And finally, on the master, run:
CREATE TABLE t3 (
    c INT NOT NULL PRIMARY KEY,
    FOREIGN KEY (c) REFERENCES t1 (a)
);

If you now go into the master and look at the SHOW CREATE TABLE output 
for table t3 you should see something like:

*************************** 1. row ***************************
        Table: t3
Create Table: CREATE TABLE `t3` (
   `c` int(11) NOT NULL default '0',
   PRIMARY KEY  (`c`),
   CONSTRAINT `0_15` FOREIGN KEY (`c`) REFERENCES `t1` (`a`)
) TYPE=InnoDB


while in the slave you will see:

*************************** 1. row ***************************
        Table: t3
Create Table: CREATE TABLE `t3` (
   `c` int(11) NOT NULL default '0',
   PRIMARY KEY  (`c`),
   CONSTRAINT `0_17` FOREIGN KEY (`c`) REFERENCES `t1` (`a`)
) TYPE=InnoDB

Note the constraint name on the master is `0_15` while on the slave it 
is `0_17`.


 >Fix:

There are two workarounds at present:

1) Don't ever create a foreign key anywhere on the slave (unless it 
comes through the binlog from the master).  This works fine until 
someone makes a mistake...

2) Accept that replication will halt.  Drop the key from the master, 
then manually drop the key from the slave; set the slave skip counter to 
1 and restart the slave.  This is something of a problem if 100% uptime 
is expected/required.

I would imagine this problem would also manifest if restoring a slave 
from a mysqldump of a master, or using any other mechanism that is not 
guaranteed to create the foreign keys in exactly the order they were 
created on the master.

Making the parser and InnoDB foreign key management systems aware of 
constraint names being indicated in the foreign key definition would 
eliminate this problem: if I could reliably use a SHOW CREATE TABLE on 
the master and be guaranteed that either the table will create with the 
same foreign key labels, or will fail with an error if the labels are 
already in use elsewhere, then the problem will go away.  If the 
constraint names also held the name of the table to which they are tied, 
the problem of collisions would also disappear: for example, CONSTRAINT 
`test_t3_0_15` would be a suitable label for the key on table t3 in 
database test.

 >Submitter-Id:	<submitter ID>
 >Originator:	chris.tucker@stripped
 >Organization:
  <organization of PR author (multiple lines)>
 >MySQL support: none
 >Synopsis:	Foreign key label replication inconsistent
 >Severity:	serious
 >Priority:	<[ low | medium | high ] (one line)>
 >Category:	mysql
 >Class:		<[ sw-bug | doc-bug | change-request | support ] (one line)>
 >Release:	mysql-4.0.15-standard (Official MySQL-standard binary)
 >Server: /usr/local/bin/mysqladmin  Ver 8.40 Distrib 4.0.15, for 
pc-linux on i686
Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL license

Server version		4.0.15-standard-log
Protocol version	10
Connection		Localhost via UNIX socket
UNIX socket		/tmp/mysql.sock
Uptime:			10 min 59 sec

Threads: 3  Questions: 30  Slow queries: 0  Opens: 17  Flush tables: 1 
Open tables: 1  Queries per second avg: 0.046
 >C compiler:    2.95.3
 >C++ compiler:  2.95.3
 >Environment:
	<machine, os, target, libraries (multiple lines)>
System: Linux localhost.localdomain 2.4.18-3smp #1 SMP Thu Apr 18 
07:27:31 EDT 2002 i686 unknown
Architecture: i686

Some paths:  /usr/local/bin/perl /usr/bin/make /usr/bin/gmake 
/usr/bin/gcc /usr/bin/cc
GCC: Reading specs from /usr/lib/gcc-lib/i386-redhat-linux/2.96/specs
gcc version 2.96 20000731 (Red Hat Linux 7.3 2.96-113)
Compilation info: CC='gcc'  CFLAGS='-O2 -mcpu=pentiumpro'  CXX='gcc' 
CXXFLAGS='-O2 -mcpu=pentiumpro -felide-constructors'  LDFLAGS=''  ASFLAGS=''
LIBC:
lrwxrwxrwx    1 root     root           13 Oct 13 16:32 /lib/libc.so.6 
-> libc-2.2.5.so
-rwxr-xr-x    1 root     root      1260480 Mar  5  2003 /lib/libc-2.2.5.so
-rw-r--r--    1 root     root      2312442 Mar  5  2003 /usr/lib/libc.a
-rw-r--r--    1 root     root          178 Mar  5  2003 /usr/lib/libc.so
Configure command: ./configure '--prefix=/usr/local/mysql' 
'--localstatedir=/usr/local/mysql/data' 
'--libexecdir=/usr/local/mysql/bin' '--with-comment=Official 
MySQL-standard binary' '--with-extra-charsets=complex' 
'--with-server-suffix=-standard' '--enable-thread-safe-client' 
'--enable-local-infile' '--enable-assembler' '--disable-shared' 
'--with-client-ldflags=-all-static' '--with-mysqld-ldflags=-all-static' 
'--with-embedded-server' '--with-innodb' 'CFLAGS=-O2 -mcpu=pentiumpro' 
'CXXFLAGS=-O2 -mcpu=pentiumpro -felide-constructors' 'CXX=gcc'


Thread
Replication of foreign key constraint names (InnoDB) inconsistentChris Tucker22 Oct