Open hariharasudhan-yb opened 4 days ago
Please make copy-pastable instructions next time. It takes a while to parse your text and reverse engineer what you are doing.
create table new_ioc_table (id text, uuid_col uuid, name text, primary key ((id, name), uuid_col), unique (uuid_col), unique (name));
create unique index on new_ioc_table (name, id);
create extension "uuid-ossp";
EXPLAIN (ANALYZE,DIST)INSERT INTO public.new_ioc_table (
id, uuid_col, name
)
VALUES
('user-id-1-1', uuid_generate_v4(), 'Test Name 1')
ON CONFLICT (id, name)
DO UPDATE SET
uuid_col = EXCLUDED.uuid_col;
EXPLAIN (ANALYZE,DIST)INSERT INTO public.new_ioc_table (
id, uuid_col, name
)
VALUES
('user-id-1-1', uuid_generate_v4(), 'Test Name 1')
ON CONFLICT (id, name)
DO UPDATE SET
uuid_col = EXCLUDED.uuid_col;
EXPLAIN (ANALYZE,DIST)INSERT INTO public.new_ioc_table (
id, uuid_col, name
)
VALUES
('user-id-1-1', uuid_generate_v4(), 'Test Name 1')
ON CONFLICT (id, name)
DO UPDATE SET
uuid_col = EXCLUDED.uuid_col;
Narrowed down to commit aad56955e18179d6c9fbaab4652777ba144d607d. cc: @karthik-ramanathan-3006
When statement
INSERT INTO public.new_ioc_table (
id, uuid_col, name
)
VALUES
('user-id-1-1', uuid_generate_v4(), 'Test Name 1')
ON CONFLICT (id, name)
DO UPDATE SET
uuid_col = EXCLUDED.uuid_col;
inserts a conflicting record it modifies the primary key, so all 3 secondary indexes are to be updated.
The keys of new_u_key_name
and new_unique_id_name_idx
are not modified, so their records can be updated, new_ioc_table_uuid_col_key
requires its record to be deleted and new one inserted.
If conflict happens when ysql_yb_skip_redundant_update_ops
flag is set to true, Postgres sends seemingly correct set of write operations, however the updated records of new_u_key_name
and new_unique_id_name_idx
disappear:
yugabyte=# explain select name from new_ioc_table where name = 'user-id-1-1';
QUERY PLAN
--------------------------------------------------------------------------------------------------
Index Only Scan using new_u_key_name on new_ioc_table (cost=0.00..4.11 rows=1 width=32)
Index Cond: (name = 'user-id-1-1'::text)
(2 rows)
yugabyte=# select name from new_ioc_table where name = 'user-id-1-1';
name
------
(0 rows)
yugabyte=# explain select name, id from new_ioc_table where name = 'user-id-1-1' and id > '';
QUERY PLAN
-----------------------------------------------------------------------------------------------------
Index Only Scan using new_unique_id_name_idx on new_ioc_table (cost=0.00..4.12 rows=1 width=64)
Index Cond: ((name = 'user-id-1-1'::text) AND (id > ''::text))
(2 rows)
yugabyte=# select name, id from new_ioc_table where name = 'user-id-1-1' and id > '';
name | id
------+----
(0 rows)
The new_unique_id_name_idx is the arbiter index, that explains why Postgres can't see the conflict, but it is not clear how the new_u_key_name constraint fails.
Jira Link: DB-14205
Description
Repro and schema details as following , This is in version 2.25.0.0-b350 . With and without batching same issue schema :
First insert - succeeded
second insert : AS i'm executing the same query again , there is a conflict on (id,name) and resolution is to update the uuid_col - succeded
Third time - Executing the same query again , it should perform the same ( it should update the uuid_col column again but it failed , throwing error - duplicate key value violates unique constraint "new_u_key_name")
Postgres behaviour (15.2): In postgres , It doesn't throw the error
Had the same schema
Anytime i repeat the query it succeeded updating the uuid_col
sample plan :
Issue Type
kind/bug
Warning: Please confirm that this issue does not contain any sensitive information