Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7809cbf

Browse files
committed
Some badly needed documentation about EvalPlanQual.
1 parenta4155d3 commit7809cbf

File tree

1 file changed

+99
-0
lines changed

1 file changed

+99
-0
lines changed

‎src/backend/executor/README

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
$Header: /cvsroot/pgsql/src/backend/executor/README,v 1.1 2001/05/15 00:35:50 tgl Exp $
2+
3+
The Postgres Executor
4+
---------------------
5+
6+
The executor processes a tree of "plan nodes". The plan tree is essentially
7+
a demand-pull pipeline of tuple processing operations. Each node, when
8+
called, will produce the next tuple in its output sequence, or NULL if no
9+
more tuples are available. If the node is not a primitive relation-scanning
10+
node, it will have child node(s) that it calls in turn to obtain input
11+
tuples.
12+
13+
Refinements on this basic model include:
14+
15+
* Choice of scan direction (forwards or backwards). Caution: this is not
16+
currently well-supported. It works for primitive scan nodes, but not very
17+
well for joins, aggregates, etc.
18+
19+
* Rescan command to reset a node and make it generate its output sequence
20+
over again.
21+
22+
* Parameters that can alter a node's results. After adjusting a parameter,
23+
the rescan command must be applied to that node and all nodes above it.
24+
There is a moderately intelligent scheme to avoid rescanning nodes
25+
unnecessarily (for example, Sort does not rescan its input if no parameters
26+
of the input have changed, since it can just reread its stored sorted data).
27+
28+
The plan tree concept implements SELECT directly: it is only necessary to
29+
deliver the top-level result tuples to the client, or insert them into
30+
another table in the case of INSERT ... SELECT. (INSERT ... VALUES is
31+
handled similarly, but the plan tree is just a Result node with no source
32+
tables.) For UPDATE, the plan tree selects the tuples that need to be
33+
updated (WHERE condition) and delivers a new calculated tuple value for each
34+
such tuple, plus a "junk" (hidden) tuple CTID identifying the target tuple.
35+
The executor's top level then uses this information to update the correct
36+
tuple. DELETE is similar to UPDATE except that only a CTID need be
37+
delivered by the plan tree.
38+
39+
XXX a great deal more documentation needs to be written here...
40+
41+
42+
EvalPlanQual (READ COMMITTED update checking)
43+
---------------------------------------------
44+
45+
For simple SELECTs, the executor need only pay attention to tuples that are
46+
valid according to the snapshot seen by the current transaction (ie, they
47+
were inserted by a previously committed transaction, and not deleted by any
48+
previously committed transaction). However, for UPDATE and DELETE it is not
49+
cool to modify or delete a tuple that's been modified by an open or
50+
concurrently-committed transaction. If we are running in SERIALIZABLE
51+
isolation level then we just raise an error when this condition is seen to
52+
occur. In READ COMMITTED isolation level, we must work a lot harder.
53+
54+
The basic idea in READ COMMITTED mode is to take the modified tuple
55+
committed by the concurrent transaction (after waiting for it to commit,
56+
if need be) and re-evaluate the query qualifications to see if it would
57+
still meet the quals. If so, we regenerate the updated tuple (if we are
58+
doing an UPDATE) from the modified tuple, and finally update/delete the
59+
modified tuple. SELECT FOR UPDATE behaves similarly, except that its action
60+
is just to mark the modified tuple for update by the current transaction.
61+
62+
To implement this checking, we actually re-run the entire query from scratch
63+
for each modified tuple, but with the scan node that sourced the original
64+
tuple set to return only the modified tuple, not the original tuple or any
65+
of the rest of the relation. If this query returns a tuple, then the
66+
modified tuple passes the quals (and the query output is the suitably
67+
modified update tuple, if we're doing UPDATE). If no tuple is returned,
68+
then the modified tuple fails the quals, so we ignore it and continue the
69+
original query. (This is reasonably efficient for simple queries, but may
70+
be horribly slow for joins. A better design would be nice; one thought for
71+
future investigation is to treat the tuple substitution like a parameter,
72+
so that we can avoid rescanning unrelated nodes.)
73+
74+
Note a fundamental bogosity of this approach: if the relation containing
75+
the original tuple is being used in a self-join, the other instance(s) of
76+
the relation will be treated as still containing the original tuple, whereas
77+
logical consistency would demand that the modified tuple appear in them too.
78+
But we'd have to actually substitute the modified tuple for the original,
79+
while still returning all the rest of the relation, to ensure consistent
80+
answers. Implementing this correctly is a task for future work.
81+
82+
In UPDATE/DELETE, only the target relation needs to be handled this way,
83+
so only one special recheck query needs to execute at a time. In SELECT FOR
84+
UPDATE, there may be multiple relations flagged FOR UPDATE, so it's possible
85+
that while we are executing a recheck query for one modified tuple, we will
86+
hit another modified tuple in another relation. In this case we "stack up"
87+
recheck queries: a sub-recheck query is spawned in which both the first and
88+
second modified tuples will be returned as the only components of their
89+
relations. (In event of success, all these modified tuples will be marked
90+
for update.) Again, this isn't necessarily quite the right thing ... but in
91+
simple cases it works. Potentially, recheck queries could get nested to the
92+
depth of the number of FOR UPDATE relations in the query.
93+
94+
It should be noted also that UPDATE/DELETE expect at most one tuple to
95+
result from the modified query, whereas in the FOR UPDATE case it's possible
96+
for multiple tuples to result (since we could be dealing with a join in
97+
which multiple tuples join to the modified tuple). We want FOR UPDATE to
98+
mark all relevant tuples, so we pass all tuples output by all the stacked
99+
recheck queries back to the executor toplevel for marking.

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp