当前位置:网站首页>PostgreSQL source code (57) why is the performance gap so large in hot update?
PostgreSQL source code (57) why is the performance gap so large in hot update?
2022-07-01 23:28:00 【mingjie73】
relevant
《Postgresql Source code (52)bitmapset analysis RelationGetIndexAttrBitmap》
《Postgresql Source code (57)HOT Why is the performance gap between updates so large ?》
background
PostgreSQL Multi version implementation , Heap pages are multiple versions , The index page is a single version . If you update a heap page , The new element group is actually direct append To the table , Old tuple tags are not visible .
At the same time, the index also needs to add a , But the index can be optimized , The method is to form a linked list of old and new table tuples , Use the old index to point to the old tuple , Then point from the old tuple to the new group .
This is it. PG Of HOT Renewal mechanism , stay 8.3 This optimization is introduced after version , The write amplification problem under multiple versions has been optimized to a great extent .
1 HOT And non HOT Update performance gap
result
- The test environment is kvm virtual machine 16C, Disk performance is poor .( Loose testing )
- The reason for the large difference in results is mainly due to the two test scenarios IO Is played ,IO The increase in the proportion of impacts has caused a large gap
- IO When all are full ,HOT Are updating the table page ,NOHOT Also update many index pages .
- Let's analyze later when we will leave HOT?(2.2 Step six of )
- Meet three conditions :
- BUFFER unchanged
- hot_attrs_checked:PAGE Not full
- modified_attrs: Some index columns have been modified
- Meet three conditions :
| TPS | |
|---|---|
| HOT | 6035.041159 |
| NOHOT | 2447.563057 |
IO Status interception 
nohot
transaction type: ./test_nohot.sql
scaling factor: 1
query mode: prepared
number of clients: 32
number of threads: 32
duration: 120 s
number of transactions actually processed: 293701
latency average = 13.073 ms
latency stddev = 31.841 ms
initial connection time = 5.961 ms
tps = 2447.563057 (without initial connection time)
statement latencies in milliseconds:
0.001 \set id random(1,10000000)
13.064 update t0 set n1 = random()*100 where id = :id;
hot
transaction type: ./test_hot.sql
scaling factor: 1
query mode: prepared
number of clients: 32
number of threads: 32
duration: 120 s
number of transactions actually processed: 724192
latency average = 5.302 ms
latency stddev = 14.019 ms
initial connection time = 6.242 ms
tps = 6035.041159 (without initial connection time)
statement latencies in milliseconds:
0.001 \set id random(1,10000000)
5.321 update t0 set n2 = random()*100 where id = :id;
test CASE
drop table t0;
create table t0(id int primary key, n1 int, n2 int);
create index idx_t0_id_n1 on t0(id, n1);
insert into t0 select generate_series(1,10000000);
vi test_nohot.sql
\set id random(1,10000000)
update t0 set n1 = random()*100 where id = :id;
pgbench -M prepared -n -r -P 1 -f ./test_nohot.sql -c 32 -j 32 -T 120
vi test_hot.sql
\set id random(1,10000000)
update t0 set n2 = random()*100 where id = :id;
pgbench -M prepared -n -r -P 1 -f ./test_hot.sql -c 32 -j 32 -T 120
2 update technological process
from ExecUpdate Function into
- Before updating : trigger 、 Foreign key trigger 、FDW etc.
- Check the new element group constraint ExecConstraints
- Perform the update table_tuple_update
- Insert a new index tuple ExecInsertIndexTuples(HOT Update does not need to update the index )
ExecUpdate
/* Trigger before update 、 Foreign key trigger 、FDW etc. */
/* BEFORE ROW UPDATE Triggers */
/* INSTEAD OF ROW UPDATE Triggers */
/* update in foreign table: let the FDW do it */
...
ExecConstraints
table_tuple_update
/* May go HOT No new index items are required */
ExecInsertIndexTuples
/* AFTER ROW UPDATE Triggers */
/* Process RETURNING if present */
...
return
2.1 update Process details (HOT)
Then expand the above process
- Before updating : stay ExecutorState Reassemble tuples in memory ExecMaterializeSlot
- Before updating : Get all relevant indexes ExecOpenIndices
- Before updating : perform : trigger 、 Foreign key trigger 、FDW etc.
- Check : New element group constraint ExecConstraints
- Perform the update :table_tuple_update
- Returns whether the index needs to be updated , If it is HOT There is no need to update the index
- heap_update Execute specific update process ( Let's continue the analysis )
- Insert a new index tuple ExecInsertIndexTuples(HOT There is no need to update the index )
ExecUpdate
ExecMaterializeSlot
tts_buffer_heap_materialize
// Switch to ExecutorState Memory context
// Spell out tuples in the new memory pool
heap_form_tuple
/* Trigger before update 、 Foreign key trigger 、FDW etc. */
...
/* Get the relevant index oid list */
ExecOpenIndices
/* BEFORE ROW UPDATE Triggers */
/* INSTEAD OF ROW UPDATE Triggers */
/* update in foreign table: let the FDW do it */
...
ExecConstraints
table_tuple_update
heapam_tuple_update
// Perform the update
heap_update
// Whether the index needs to be updated ?HOT?
*update_indexes = result == TM_Ok && !HeapTupleIsHeapOnly(tuple)
/* May go HOT No new index items are required */
if (... && update_indexes)
ExecInsertIndexTuples
// For each relevant index, we need to construct a new index tuple
for (i = 0; i < numIndices; i++)
FormIndexDatum
index_insert
// checkUnique
/* AFTER ROW UPDATE Triggers */
/* Process RETURNING if present */
...
return
2.2 heap_update Function to perform analysis (HOT)
Expand... In the above process heap_update function :
perform :
drop table t0;
create table t0(id int primary key, n1 int, n2 int);
create index idx_t0_id_n1 on t0(id, n1);
insert into t0 select generate_series(1,2), generate_series(1,2)+100, 888;
update t0 set n2 = 0 where id = 2;
First step :bitmap To configure , Find the position of all index columns
What is the bitmap here? Refer to this article :《Postgresql Source code (52)bitmapset analysis RelationGetIndexAttrBitmap》
Generate three bitmaps to record the index position :hot_attrs、key_attrs、id_attrs
n1 id
\/
||
hot_attrs = 1100000000 : Which columns have indexes ?
key_attrs = 100000000 : Which columns have unique indexes ?
id_attrs = 100000000 : Copy identity
The second step : If PAGE Not full , May go HOT, structure bitmap interesting_attrs
To configure :hot_attrs_checked=true
n1 id
\/
||
interesting_attrs = 1100000000
The third step : Lock page
Step four : Which index columns have been modified ?
HeapDetermineColumnsInfo The function structure modified_attrs Bitmap , No index columns have been modified here
modified_attrs = 0000000000
This bitmap records which index columns have been modified , Notice the index column
Step five : Whether the old tuple is visible ?
HeapTupleSatisfiesUpdate(MVCC)
Step six : Decide whether to go HOT
Meet three conditions :
- BUFFER unchanged
- hot_attrs_checked: The second step above :PAGE Not full
- modified_attrs: Step 4 above : Some index columns have been modified
if (newbuf == buffer)
if (hot_attrs_checked && !bms_overlap(modified_attrs, hot_attrs))
use_hot_update = true;
Step seven : Start HOT to update
- One 、 Add a flag bit :
- Old tuple :HEAP_HOT_UPDATED、HEAP_ONLY_TUPLE
- Xinyuan formation :HEAP_ONLY_TUPLE
- Two 、 Configure the header of the old tuple
- 3、 ... and 、 Insert new element group
if (use_hot_update)
HeapTupleSetHotUpdated(&oldtup)
(tup)->t_infomask2 |= HEAP_HOT_UPDATED
HeapTupleSetHeapOnly(heaptup)
(tup)->t_infomask2 |= HEAP_ONLY_TUPLE
HeapTupleSetHeapOnly(newtup)
(tup)->t_infomask2 |= HEAP_ONLY_TUPLE
Step eight : Record XLOG
log_heap_update
边栏推荐
猜你喜欢

CADD课程学习(3)-- 靶点药物相互作用

from pip._internal.cli.main import main ModuleNotFoundError: No module named ‘pip‘

Redis data types and application scenarios

from pip._ internal. cli. main import main ModuleNotFoundError: No module named ‘pip‘

会声会影2022智能、快速、简单的视频剪辑软件

Future trend and development of neural network Internet of things

The digital summit is popular, and city chain technology has triggered a new round of business transformation

from pip._internal.cli.main import main ModuleNotFoundError: No module named ‘pip‘

notBlank 和 notEmpty

Practical application and extension of plain framework
随机推荐
[micro service sentinel] sentinel integrates openfeign
13 MySQL-约束
Win 10 mstsc connect RemoteApp
证券开户选哪个证券公司比较好,哪个更安全
Three development trends of enterprise application from the perspective of the third technological revolution
Redis数据类型和应用场景
马赛克后挡板是什么?
What is the relationship between modeling and later film and television?
De PIP. Interne. CLI. Main Import main modulenotfounderror: No module named 'PIP'
Switch to software testing, knowing these four points is enough!
[must] bm41 output the right view of the binary tree [medium +]
物联网技术应用属于什么专业分类
Leetcode (34) -- find the first and last positions of elements in a sorted array
共享电商的背后: 共创、共生、共享、共富,共赢的共富精神
"35 years old, the boss of the company, with a monthly salary of 20000, give away takeout": the times abandoned you, not even saying goodbye
Linux foundation - centos7 offline installation of MySQL
Distance measurement - Hamming distance
问题随记 —— file /usr/share/mysql/charsets/README from install of MySQL-server-5.1.73-1.glibc23.x86_64 c
Wechat personal small store one click opening assistant applet development
云信小课堂 | IM及音视频中常见的认知误区