Skip to content

Commit

Permalink
Add pg_advance_vacuum_cleanup_age().
Browse files Browse the repository at this point in the history
This function specifies the number of transactions by
which VACUUM and HOT updates will advance cleanup
of dead row versions.
  • Loading branch information
MasaoFujii committed Jul 14, 2016
1 parent bad13e2 commit 640baf6
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,29 @@ This function returns a record, shown in the table below.
This function is restricted to superusers by default,
but other users can be granted EXECUTE to run the function.

### integer pg_advance_vacuum_cleanup_age(integer)
Specify the number of transactions by which VACUUM and HOT updates
will advance cleanup of dead row versions.
[vacuum_defer_cleanup_age](https://www.postgresql.org/docs/devel/static/runtime-config-replication.html#GUC-VACUUM-DEFER-CLEANUP-AGE)
in the session calling this function is set to
the negative value of that specified number. If the argument is omitted
or NULL is specified, vacuum_defer_cleanup_age is reset to
its original setting value specified in the configuration file.
This function returns the vacuum cleanup age.

By advancing the cleanup age, VACUUM and HOT updates can clean up
even dead tuples that were produced since oldest transaction had started.
So this function is helpful to prevent the database from bloating due to
unremovable dead tuples while long transaction is running.

Note that this is extremely dangerous function and can easily corrupt
the database. Any important data may disappear and data consistency
may be lost completely.
This function must not be used for a purpose other than debug.

This function is restricted to superusers by default,
but other users can be granted EXECUTE to run the function.

### void pg_checkpoint(fast bool, wait bool, force bool)
Perform a checkpoint.
If fast is true (default), a checkpoint will finish as soon as possible.
Expand Down
6 changes: 6 additions & 0 deletions pg_cheat_funcs--1.0.sql
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,12 @@ AS 'MODULE_PATHNAME'
LANGUAGE C STRICT VOLATILE;
REVOKE ALL ON FUNCTION pg_oid_assignment() FROM PUBLIC;

CREATE FUNCTION pg_advance_vacuum_cleanup_age(integer DEFAULT NULL)
RETURNS integer
AS 'MODULE_PATHNAME'
LANGUAGE C CALLED ON NULL INPUT VOLATILE;
REVOKE ALL ON FUNCTION pg_advance_vacuum_cleanup_age(integer) FROM PUBLIC;

CREATE FUNCTION pg_checkpoint(bool DEFAULT true, bool DEFAULT true,
bool DEFAULT true)
RETURNS void
Expand Down
31 changes: 31 additions & 0 deletions pg_cheat_funcs.c
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ PG_FUNCTION_INFO_V1(pg_set_next_xid);
PG_FUNCTION_INFO_V1(pg_xid_assignment);
PG_FUNCTION_INFO_V1(pg_set_next_oid);
PG_FUNCTION_INFO_V1(pg_oid_assignment);
PG_FUNCTION_INFO_V1(pg_advance_vacuum_cleanup_age);
PG_FUNCTION_INFO_V1(pg_checkpoint);
PG_FUNCTION_INFO_V1(pg_promote);
PG_FUNCTION_INFO_V1(pg_recovery_settings);
Expand Down Expand Up @@ -124,6 +125,7 @@ Datum pg_set_next_xid(PG_FUNCTION_ARGS);
Datum pg_xid_assignment(PG_FUNCTION_ARGS);
Datum pg_set_next_oid(PG_FUNCTION_ARGS);
Datum pg_oid_assignment(PG_FUNCTION_ARGS);
Datum pg_advance_vacuum_cleanup_age(PG_FUNCTION_ARGS);
Datum pg_checkpoint(PG_FUNCTION_ARGS);
Datum pg_promote(PG_FUNCTION_ARGS);
Datum pg_recovery_settings(PG_FUNCTION_ARGS);
Expand Down Expand Up @@ -843,6 +845,35 @@ pg_oid_assignment(PG_FUNCTION_ARGS)
heap_form_tuple(tupdesc, values, nulls)));
}

/*
* Specify the number of transactions by which VACUUM and HOT updates
* will advance cleanup of dead row versions.
*/
Datum
pg_advance_vacuum_cleanup_age(PG_FUNCTION_ARGS)
{
static bool advanced = false;
static int save_cleanup_age = 0;
static int orig_cleanup_age = 0;

if (!advanced || vacuum_defer_cleanup_age != save_cleanup_age)
orig_cleanup_age = vacuum_defer_cleanup_age;

if (PG_ARGISNULL(0))
{
vacuum_defer_cleanup_age = orig_cleanup_age;
advanced = false;
}
else
{
vacuum_defer_cleanup_age = - PG_GETARG_INT32(0);
advanced = true;
}
save_cleanup_age = vacuum_defer_cleanup_age;

PG_RETURN_INT32(- vacuum_defer_cleanup_age);
}

/*
* Perform a checkpoint.
*/
Expand Down
15 changes: 15 additions & 0 deletions sql/pg_cheat_funcs.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,21 @@ SELECT pg_eucjp('xa4', 'xa2');

SELECT pg_set_next_xid(next_xid) = next_xid FROM pg_xid_assignment();

DO $$
DECLARE
orig_cleanup_age text := current_setting('vacuum_defer_cleanup_age');
BEGIN
PERFORM pg_advance_vacuum_cleanup_age(99);
IF current_setting('vacuum_defer_cleanup_age') <> '-99' THEN
RAISE WARNING 'could not advance vacuum cleanup age properly.';
END IF;
PERFORM pg_advance_vacuum_cleanup_age();
IF current_setting('vacuum_defer_cleanup_age') <> orig_cleanup_age THEN
RAISE NOTICE 'could not reset vacuum cleanup age properly.';
END IF;
END;
$$ LANGUAGE plpgsql;

SELECT to_octal(num) FROM generate_series(1, 10) num;
SELECT to_octal(2147483647::integer);
SELECT to_octal(9223372036854775807::bigint);
Expand Down

0 comments on commit 640baf6

Please sign in to comment.