On Mon, 6 Jul 2026 at 22:54, Zsolt Parragi <[email protected]> wrote:
>
> This is a great feature, I did some testing of it.

Thanks for testing!

> 1. If a table has an ON COMMIT clause:
>
> CREATE GLOBAL TEMPORARY TABLE gtt_del (id int) ON COMMIT DELETE ROWS
>
> Then pg_dump forgets that.

Fixed in v9.

> 2. Even an aborted transaction pins frozenxid:
>
> CREATE GLOBAL TEMPORARY TABLE gtt (id int);
>
> In one session
>
> BEGIN; SELECT count(*) FROM gtt; ABORT;
> -- and keep session alive
>
> Then in another session,
> SELECT datfrozenxid FROM pg_database WHERE datname=current_database();
> -- do some work
> VACUUM (FREEZE);
> SELECT datfrozenxid FROM pg_database WHERE datname=current_database();
> -- ...
>
> And repeat the above a few times for the second session, datfrozenxid
> will remain the same until the first session is closed.

Fixed in v9.

> 3. in AtEOSubXact_UsageCleanup and also in AtEOSubXact_StorageCleanup
>
> +               else
> +                       gtr_remove_usage(entry->relid);
> +       }
> +
> +       /* Update the usage stopped subid */
> +       if (entry->stopped_subid == mySubid)
> +       {
> +               if (isCommit)
> +                       entry->stopped_subid = parentSubid;
> +               else
> +                       entry->stopped_subid = InvalidSubTransactionId;
> +       }
>
> if we follow the else branch with gtr_remove_usage, shouldn't the
> function immediately return?

OK, fixed in v9. It wasn't actually broken, in that "entry" is still
valid memory after removing it from the hash table (it's on a
freelist), but I agree that it's neater to return immediately.

> 4. in AtEOSubXact_PendingInsertCleanup
>
> +               else
> +                       hash_search(pending_inserts, &entry->relid, 
> HASH_REMOVE, NULL);
> +       }
> +
> +       /* Update the inserted subid (may rollback flush) */
> +       if (entry->inserted_subid == mySubid)
> +       {
> +               if (isCommit)
> +                       entry->inserted_subid = parentSubid;
> +               else
> +               {
> +                       entry->inserted_subid = InvalidSubTransactionId;
> +                       have_inserts_to_flush = true;
> +               }
> +       }
>
> same question, isn't the else branch missing a return?

As above, fixed in v9.

> 5. in gtr_remove_usage / gtr_remove_all_usage_on_exit
>
> +       shared_entry = dshash_find(gtr_shared_usage, &key, true);
> +
> +       if (shared_entry->usage_count > 1)
>
> and in gtr_record_usage
>
> +       /* Flag the usage entry for eoxact cleanup */
> +       EOXactUsageListAdd(relid);
> +
> +       /* Add/update shared usage entry */
> +       key.dbid = MyDatabaseId;
> +       key.relid = relid;
> +       shared_entry = dshash_find_or_insert(gtr_shared_usage, &key, &found);
>
> Can't this crash with a null pointer access in the above if
> dshash_find_or_insert fails with OOM?

No, because it would throw an error, so it will never try to access
"shared_entry" if it couldn't insert it. I checked against other code
using dshash_find_or_insert(), and it's the same.

Regards,
Dean


Reply via email to