Closed GuptaManan100 closed 9 months ago
I looked at this failure, and I know what's happening. The plan that Vitess produces for this query is this -
{
"OperatorType": "FkCascade",
"Inputs": [
{
"InputName": "Selection",
"OperatorType": "Route",
"Variant": "Unsharded",
"Keyspace": {
"Name": "uks",
"Sharded": false
},
"FieldQuery": "select fk_t11.col from fk_t11, fk_t12 where 1 != 1",
"Query": "select fk_t11.col from fk_t11, fk_t12 where fk_t11.id = 4 and fk_t11.id = fk_t12.id for update",
"Table": "fk_t11, fk_t12"
},
{
"InputName": "CascadeChild-1",
"OperatorType": "Delete",
"Variant": "Unsharded",
"Keyspace": {
"Name": "uks",
"Sharded": false
},
"TargetTabletType": "PRIMARY",
"BvName": "fkc_vals",
"Cols": [
0
],
"Query": "delete from fk_t12 where (col) in ::fkc_vals",
"Table": "fk_t12"
},
{
"InputName": "Parent",
"OperatorType": "Delete",
"Variant": "Unsharded",
"Keyspace": {
"Name": "uks",
"Sharded": false
},
"TargetTabletType": "PRIMARY",
"Query": "delete fk_t11 from fk_t11, fk_t12 where fk_t11.id = 4 and fk_t11.id = fk_t12.id",
"Table": "fk_t11"
}
]
}
From the outset, the plan looks fine, but when we try to see the exact order of execution, the problem becomes apparent.
The order of queries Vitess runs is this -
select fk_t11.col from fk_t11, fk_t12 where fk_t11.id = 4 and fk_t11.id = fk_t12.id for update
delete from fk_t12 where (col) in ::fkc_vals
delete fk_t11 from fk_t11, fk_t12 where fk_t11.id = 4 and fk_t11.id = fk_t12.id
The problem is that once the 2nd query runs, (which is the cascade), the rows with id = 4
are gone from the fk_t12
table!! So now when we run the last query, there is no delete, since no row qualifies and therefore no failure!
This essentially shows up as though the delete query only ended up deleting 2 rows from fk_t12
and nothing else!
Overview of the Issue
This bug has been caught by the fuzzer introduced in https://github.com/vitessio/vitess/pull/13980.
Consider the following tables in an unsharded keyspace that is running Vitess in a foreign key managed mode -
If we insert the following data in the tables -
If we now try and run the multi delete query -
MySQL fails this query with the error
Cannot delete or update a parent row: a foreign key constraint fails (
ks.
fk_t13, CONSTRAINT
fk_t13_ibfk_1FOREIGN KEY (
col) REFERENCES
fk_t11(
col) ON DELETE RESTRICT ON UPDATE RESTRICT) (errno 1451) (sqlstate 23000)
But Vitess lets the query succeed and ends up only deleting 2 rows from
fk_t12
corresponding to the rows with id4
and10
.Reproduction Steps
Given in the description
Binary Version
Operating System and Environment details
Log Fragments
No response