Also be more assertive that "ctid" should not be used for long-term
storage.
Reported-by: Bernice Southey
Discussion: https://postgr.es/m/CAEDh4nyn5swFYuSfcnGAbpQrKOc47Hh_ZyKVSPYJcu2P=51Luw@mail.gmail.com
Backpatch-through: 17
locate the row version very quickly, a row's
<structfield>ctid</structfield> will change if it is
updated or moved by <command>VACUUM FULL</command>. Therefore
- <structfield>ctid</structfield> is useless as a long-term row
+ <structfield>ctid</structfield> should not be used as a row
identifier. A primary key should be used to identify logical rows.
</para>
</listitem>
USING delete_batch AS del
WHERE dl.ctid = del.ctid;
</programlisting>
+ This use of <structfield>ctid</structfield> is only safe because
+ the query is repeatedly run, avoiding the problem of changed
+ <structfield>ctid</structfield>s.
</para>
</refsect1>
WHERE work_item.ctid = emr.ctid;
</programlisting>
This command will need to be repeated until no rows remain to be updated.
+ (This use of <structfield>ctid</structfield> is only safe because
+ the query is repeatedly run, avoiding the problem of changed
+ <structfield>ctid</structfield>s.)
Use of an <literal>ORDER BY</literal> clause allows the command to
prioritize which rows will be updated; it can also prevent deadlock
with other update operations if they use the same ordering.