MVCC and VACUUM of PostgresSQL


  First of all, we know that the MVCC (multi-version concurrency control) of Oracle and MySQL is completed through undo logs; but there is no UNDO in PostgreSQL. The data tuples of the old version are directly stored in the data page, which causes the old problem. Tuples need to be constantly cleaned up to free up space, which is also the root cause of database expansion .

One, PostgreSQL data structure

1.1 Data page structure

  • header data: The data header is generated when the page is generated. The structure is defined by pageHeaderData. It is 24 bytes long and contains information about the page. The following is the data structure:
    • pd_lsn: Store the xlog location of the page that has recently changed.
    • pd_checksum: Store page checksum.
    • pdlower, pdupper: pdlower points to the end of the line pointer, and pdupper points to the last tuple.
    • pd_special: Used in the index page, it points to the beginning of the special space.
  • line pointer: line pointer, four bytes, each tuple will have a line pointer pointing to the real tuple position.
  • Heap tuple: Store the real tuple data. Note that the tuple is piled forward from the end of the page. The free space between the tuple and the row pointer is the data page.

1.2 Tuple structure

  A tuple, also called a tuple, is actually a record in the database.

  • tableoid, the OID of the table to which this row belongs.
  • xmin, insert the transaction identity (transaction ID) of the row version.
  • cmin, the command identifier inserted in the transaction (starting from 0).
  • xmax, the transaction ID of the update and delete transaction
  • cmax, delete the command identifier in the transaction, or 0.
  • ctid, the physical location of the row version in its table.

2. MVCC of PostgreSQL

  In PostgreSQL, when a row of records is updated, a new version of the row of data will be created and inserted into the table. The previous version provides a pointer to the new version. The previous version is marked as "expired", but it remains in the database until The garbage collector collects it. The
  transaction status is stored in $PGDATA/pg_xact. This table contains two bytes of status information for each transaction. The possible statuses are in-progress, committed, or aborted. When a transaction ends, PostgreSQL does not undo the undo rollback of the database record changes, it just marks the transaction as aborted. A PostgreSQL table may contain many such aborted transaction data.

Three, PostgreSQL cleanup mechanism

  PostgreSQL uses Vacuum to do garbage collection. The Vacuum Cleaner will delete the expired/aborted log version and the related index entries of the garbage collected tuple.
  VACUUM is similar to MySQL's purge thread, and in PG, the corresponding is vacuum.

#基本语法
VACUUM [ ( option [, ...] ) ] [ table_and_columns [, ...] ]
VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns [, ...] ]

其中option可以是下列之一:

FULL
选择“完全”清理,它可以收回更多空间,并且需要更长时间和表上的排他锁。这种方法还需要额外的磁盘空间,因为它会创建该表的一个新拷贝,并且在操作完成之前都不会释放旧的拷贝。通常这种方法只用于需要从表中收回数量庞大的空间时。

FREEZE
选择激进的元组“冻结”。指定FREEZE 等价于参数vacuum_freeze_min_age和 vacuum_freeze_table_age设置为0的 VACUUM。当表被重写时总是会执行激进的冻结, 因此指定FULL时这个选项是多余的。

VERBOSE
为每个表打印一份详细的清理活动报告。

ANALYZE
更新优化器用以决定最有效执行一个查询的方法的统计信息。

DISABLE_PAGE_SKIPPING
通常,VACUUM将基于可见性映射跳过页面。已知所有元组都被冻结的页面总是会被跳过,而那些所有元组对所有事务都可见的页面则可能会被跳过(除非执行的是激进的清理)。此外,除非在执行激进的清理时,一些页面也可能会被跳过,这样可避免等待其他页面完成对其使用。这个选项禁用所有的跳过页面的行为,其意图是只在可见性映射内容被怀疑时使用,这种情况只有在硬件或者软件问题导致数据库损坏时才会发生。

table_name
要清理的表或物化视图的名称(可以有模式修饰)。如果指定的表示一个分区表,则它所有的叶子分区也会被清理。

column_name
要分析的指定列的名称。缺省是所有列。如果指定了一个列的列表,则ANALYZE也必须被指定。

而table_and_columns是:

    table_name [ ( column_name [, ...] ) ]

  Simple VACUUM (without FULL) simply reclaims the space and makes it reusable. This form of command can be parallel to ordinary read and write operations of the table, because it will not acquire an exclusive lock. However, the extra space in this form is not returned to the operating system (in most cases), it is just kept in the same table for reuse. VACUUM FULL rewrites the entire contents of the table to a new disk file, and does not contain additional space, which makes the unused space returned to the operating system. This form of command is slower and requires an exclusive lock to be maintained on each table as it is processed.
Output
If VERBOSE is declared, VACUUM will issue a progress message to indicate which table is currently being processed. Various statistical information about these tables will also be printed.

note

  • To clean up a table, you usually must be the owner or super user of the table. However, database owners are allowed to clean up all tables in their database except for shared directories (restrictions on shared directories mean that a true database-wide VACUUM can only be executed by super users). VACUUM will skip tables for which the executor does not have permission to clean up.
  • VACUUM cannot be executed within a transaction block.
  • It is recommended to clean up the active production database frequently (at least once every night) to ensure that invalid rows are removed. After adding or deleting a large number of rows, it is a good practice to execute the VACUUM ANALYZE command on the affected table. Doing so will update the system catalog with recent changes and allow the PostgreSQL query planner to make better choices when planning user queries.
  • For daily use, the FULL option is not recommended, but it will be useful in special circumstances. An example is when you delete or update most of the rows in a table, if you want to physically shrink the table to reduce disk space and allow faster table scans, this option is more appropriate. VACUUM FULL usually shrinks the table more than simple VACUUM.
  • VACUUM will cause a substantial increase in I/O traffic, which may result in poor performance of other active sessions. Therefore, it is sometimes recommended to use the cost-based cleanup delay feature.

Guess you like

Origin blog.csdn.net/qq_42979842/article/details/108504680