1

I would like to know how it reduces spaces. Certain forums mentions it does this by:

  • Moving dead tuples to the front of the table. Essentially reusing dead tuples.
  • Rebuilds the table and indices. Dead tuples are moved to the end of the table. A second step vaccum is required to reclaim the space. (using normal vaccum would just allow reclaimed spaces to be reusable within the table itself, not other tables).

The above two points may work together or contradict each other. This seems to be a popular solution but not well documented. Prefer not to read the perl code directly.

References:

1 Answer 1

1

When updating a row, postgresql creates a new version of that row (mvcc). This new version of the row is written to the beginning of the table if there is free space somewhere.

If there are empty pages at the end of the table that do not contain live rows, the vacuum process can truncate those empty pages and return used space to the file system.

Knowing about these two features of postgresql, we wrote pgcompacttable. (I am a contributor):

  • pgcompacttable runs normal update commands that don't change anything on the real data. But due to the implementation of mvcc, a new version of the row is created somewhere at the beginning of the table
  • then we run vacuum, which cleans up the old versions of the rows, notices that there are empty pages at the end of the table, and returns them to the file system
7
  • Awesome internet. Thanks for commenting. To clarify: 1. It creates new versions at the beginning of the table for existing data. The old versions are disconnected/marked as not used. 2. For completely new data without existing data, it just overwrites dead tuples. 3. Indices points to the new versions in the beginning of the table for newly updated/inserted data. 4. The old versions since there are no indices pointing to it becomes obsolete pages, and gets vaccumed. The overall solution seems to be removing old versions. Commented Dec 29, 2022 at 11:58
  • May I ask how long in production one can expect pgcompacttable to run? How does it know it has finished its job? @Melkij Commented Dec 29, 2022 at 12:00
  • depends on the size of the table. Reasonably sized tables (hundred gigabytes) are processed in a few hours usually. Compared to pg_repack, pgcompacttable is generally slower, but it doesn't cause stress peaks in load.
    – Melkij
    Commented Dec 29, 2022 at 12:24
  • How does it know it has finished its job? - we know how many pages the table has and we visit each page of the table.
    – Melkij
    Commented Dec 29, 2022 at 12:24
  • To clarify: - update command will write new version of the tuple in empty space and add this row to all related indexes. Old row is marked as deleted during update. Everything else is work for a vacuum (or autovacuum). Vacuum scan table, find dead rows, remove them from indexes, remove these rows from the table, truncate empty pages from table tail if any.
    – Melkij
    Commented Dec 29, 2022 at 12:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.