On read committed isolation level, x1 should see the new index when it execute the next sql after x2 is committed.
Best Regards, Heisenberg > 2025年8月1日 14:47,Chao Li <[email protected]> 写道: > > > If the index points to the newest version of the tuple, how do old > > transactions read the old version of the tuple using an index scan for old > > transactions? > > Say there is a long transaction x1, it is on-going. > > And transaction x2 started later than x1 started, and x2 created an index. > Should x1 be visible to the new index? > > My understanding is, the old transaction x1 cannot use the new index to scan > for the old version of the tuple. If you read my example, in the index, the > key is the new age value (99), while the old age value is 4, thus using the > old value will not hit the index entry. > > Chao Li (Evan) > ------------------------------ > HighGo Software Inc. > https://www.highgo.com/ > > > Tender Wang <[email protected] <mailto:[email protected]>> 于2025年8月1日周五 > 14:37写道: >> >> >> Chao Li <[email protected] <mailto:[email protected]>> >> 于2025年8月1日周五 14:16写道: >>> Hi Community, >>> >>> Let me use a small example to demonstrate my observation. >>> >>> Step 1: create a simple table, insert a tuple and update it. >>> >>> create table ta (id int, name varchar(32), age int); >>> insert into ta values(1, 'aa', 4); >>> update ta set age=99 where id=1; >>> >>> Step 2: with pageinspect, we can the 2 version of the tuple: >>> >>> SELECT * FROM heap_page_items(get_raw_page('ta', 0)); >>> lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_field3 | t_ctid | >>> t_infomask2 | t_infomask | t_hoff | t_bits | t_oid | t_data >>> ----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------+---------------------------- >>> 1 | 8152 | 1 | 36 | 765 | 765 | 0 | (0,2) | >>> 16387 | 34 | 24 | | | \x010000000761610004000000 >>> 2 | 8112 | 1 | 36 | 765 | 0 | 2 | (0,2) | >>> 32771 | 10242 | 24 | | | \x010000000761610063000000 >>> (2 rows) >>> >>> The old version's ctid now points to (0,2) which is expected. >>> >>> Step 3: create a index on the table >>> >>> create index idx_ta_age on ta(age); >>> >>> Step 4: view the index page >>> >>> evantest=# SELECT * FROM bt_page_items('idx_ta_age', 1); >>> itemoffset | ctid | itemlen | nulls | vars | data | >>> dead | htid | tids >>> ------------+-------+---------+-------+------+-------------------------+------+-------+------ >>> 1 | (0,1) | 16 | f | f | 63 00 00 00 00 00 00 00 | f >>> | (0,1) | >>> (1 row) >>> >>> Here comes my question, why the index entry's ctid points to the old >>> version tuple? >>> >>> I understand that, for updated tuples, old version's ctid points to new >>> version, that builds a chain of all versions. But my confusion is that, >>> when an index is created, older transactions and in-progress transactions >>> won't see the newly created index. So, it should be ok for the index to >>> point to the newest version of tuple version that is visible to the index. >>> >>> Can anyone please explain me about that? >>> >> >> If the index points to the newest version of the tuple, how do old >> transactions read the old version of the tuple using an index scan for old >> transactions? >> Pointing to the old version is friendly if the table is often updated. This >> way, we don't need to update the index tuple. >> >> >> -- >> Thanks, >> Tender Wang
