From ce073c5046c659476a250d2879dee5df0f7f78f6 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Wed, 4 Apr 2018 21:53:48 +0000 Subject: [PATCH v7 12/12] Open up VACOPT_SKIP_LOCKED to users. --- doc/src/sgml/ref/analyze.sgml | 12 ++ doc/src/sgml/ref/vacuum.sgml | 12 ++ src/backend/parser/gram.y | 2 + src/include/nodes/parsenodes.h | 2 +- src/test/isolation/expected/vacuum-skip-locked.out | 171 +++++++++++++++++++++ src/test/isolation/isolation_schedule | 1 + src/test/isolation/specs/vacuum-skip-locked.spec | 59 +++++++ src/test/regress/expected/vacuum.out | 10 ++ src/test/regress/sql/vacuum.sql | 10 ++ 9 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/vacuum-skip-locked.out create mode 100644 src/test/isolation/specs/vacuum-skip-locked.spec diff --git a/doc/src/sgml/ref/analyze.sgml b/doc/src/sgml/ref/analyze.sgml index 10b3a9a673..4e6ae38a52 100644 --- a/doc/src/sgml/ref/analyze.sgml +++ b/doc/src/sgml/ref/analyze.sgml @@ -27,6 +27,7 @@ ANALYZE [ VERBOSE ] [ table_and_columnswhere option can be one of: VERBOSE + SKIP LOCKED and table_and_columns is: @@ -76,6 +77,17 @@ ANALYZE [ VERBOSE ] [ table_and_columns + + SKIP LOCKED + + + Specifies that ANALYZE should not wait for any + conflicting locks to be released: if a relation cannot be locked + immediately without waiting, the relation is skipped. + + + + table_name diff --git a/doc/src/sgml/ref/vacuum.sgml b/doc/src/sgml/ref/vacuum.sgml index b760e8ede1..1ef5bc9d4a 100644 --- a/doc/src/sgml/ref/vacuum.sgml +++ b/doc/src/sgml/ref/vacuum.sgml @@ -31,6 +31,7 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_and_columns is: @@ -160,6 +161,17 @@ VACUUM [ FULL ] [ FREEZE ] [ VERBOSE ] [ ANALYZE ] [ table_name diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 1592b58bb4..e170e8762a 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -10543,6 +10543,7 @@ vacuum_option_elem: errmsg("unrecognized VACUUM option \"%s\"", $1), parser_errposition(@1))); } + | SKIP LOCKED { $$ = VACOPT_SKIP_LOCKED; } ; AnalyzeStmt: analyze_keyword opt_verbose opt_vacuum_relation_list @@ -10570,6 +10571,7 @@ analyze_option_list: analyze_option_elem: VERBOSE { $$ = VACOPT_VERBOSE; } + | SKIP LOCKED { $$ = VACOPT_SKIP_LOCKED; } ; analyze_keyword: diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h index 5340d29f0b..8d9a57215a 100644 --- a/src/include/nodes/parsenodes.h +++ b/src/include/nodes/parsenodes.h @@ -3158,7 +3158,7 @@ typedef enum VacuumOption VACOPT_VERBOSE = 1 << 2, /* print progress info */ VACOPT_FREEZE = 1 << 3, /* FREEZE option */ VACOPT_FULL = 1 << 4, /* FULL (non-concurrent) vacuum */ - VACOPT_SKIP_LOCKED = 1 << 5, /* don't wait to get lock (autovacuum only) */ + VACOPT_SKIP_LOCKED = 1 << 5, /* don't wait to get lock */ VACOPT_SKIPTOAST = 1 << 6, /* don't process the TOAST table, if any */ VACOPT_DISABLE_PAGE_SKIPPING = 1 << 7 /* don't skip any pages */ } VacuumOption; diff --git a/src/test/isolation/expected/vacuum-skip-locked.out b/src/test/isolation/expected/vacuum-skip-locked.out new file mode 100644 index 0000000000..a6fe617db1 --- /dev/null +++ b/src/test/isolation/expected/vacuum-skip-locked.out @@ -0,0 +1,171 @@ +Parsed test spec with 2 sessions + +starting permutation: lock_share vac_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +WARNING: skipping vacuum of "part1" --- lock not available +step vac_specified: VACUUM (SKIP LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share vac_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step vac_all_parts: VACUUM (SKIP LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_share analyze_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +WARNING: skipping analyze of "part1" --- lock not available +step analyze_specified: ANALYZE (SKIP LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share analyze_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step analyze_all_parts: ANALYZE (SKIP LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_share vac_analyze_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +WARNING: skipping vacuum of "part1" --- lock not available +step vac_analyze_specified: VACUUM (ANALYZE, SKIP LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share vac_analyze_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step vac_analyze_all_parts: VACUUM (ANALYZE, SKIP LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_share vac_full_specified commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +WARNING: skipping vacuum of "part1" --- lock not available +step vac_full_specified: VACUUM (SKIP LOCKED, FULL) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_share vac_full_all_parts commit +step lock_share: + BEGIN; + LOCK part1 IN SHARE MODE; + +step vac_full_all_parts: VACUUM (SKIP LOCKED, FULL) parted; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +WARNING: skipping vacuum of "part1" --- lock not available +step vac_specified: VACUUM (SKIP LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +step vac_all_parts: VACUUM (SKIP LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive analyze_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +WARNING: skipping analyze of "part1" --- lock not available +step analyze_specified: ANALYZE (SKIP LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive analyze_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +WARNING: skipping analyze of "parted" --- lock not available +step analyze_all_parts: ANALYZE (SKIP LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_analyze_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +WARNING: skipping vacuum of "part1" --- lock not available +step vac_analyze_specified: VACUUM (ANALYZE, SKIP LOCKED) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_analyze_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +WARNING: skipping analyze of "parted" --- lock not available +step vac_analyze_all_parts: VACUUM (ANALYZE, SKIP LOCKED) parted; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_full_specified commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +WARNING: skipping vacuum of "part1" --- lock not available +step vac_full_specified: VACUUM (SKIP LOCKED, FULL) part1, part2; +step commit: + COMMIT; + + +starting permutation: lock_access_exclusive vac_full_all_parts commit +step lock_access_exclusive: + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; + +step vac_full_all_parts: VACUUM (SKIP LOCKED, FULL) parted; +step commit: + COMMIT; + diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 99dd7c6bdb..bbb4bd4186 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -72,3 +72,4 @@ test: timeouts test: vacuum-concurrent-drop test: predicate-gist test: predicate-gin +test: vacuum-skip-locked diff --git a/src/test/isolation/specs/vacuum-skip-locked.spec b/src/test/isolation/specs/vacuum-skip-locked.spec new file mode 100644 index 0000000000..3e9e968798 --- /dev/null +++ b/src/test/isolation/specs/vacuum-skip-locked.spec @@ -0,0 +1,59 @@ +# Test for the SKIP LOCKED option for VACUUM and ANALYZE commands. +# +# This also verifies that log messages are not emitted for skipped relations +# that were not specified in the VACUUM or ANALYZE command. + +setup +{ + CREATE TABLE parted (a INT) PARTITION BY LIST (a); + CREATE TABLE part1 PARTITION OF parted FOR VALUES IN (1); + CREATE TABLE part2 PARTITION OF parted FOR VALUES IN (2); +} + +teardown +{ + DROP TABLE IF EXISTS parted; +} + +session "s1" +step "lock_share" +{ + BEGIN; + LOCK part1 IN SHARE MODE; +} +step "lock_access_exclusive" +{ + BEGIN; + LOCK part1 IN ACCESS EXCLUSIVE MODE; +} +step "commit" +{ + COMMIT; +} + +session "s2" +step "vac_specified" { VACUUM (SKIP LOCKED) part1, part2; } +step "vac_all_parts" { VACUUM (SKIP LOCKED) parted; } +step "analyze_specified" { ANALYZE (SKIP LOCKED) part1, part2; } +step "analyze_all_parts" { ANALYZE (SKIP LOCKED) parted; } +step "vac_analyze_specified" { VACUUM (ANALYZE, SKIP LOCKED) part1, part2; } +step "vac_analyze_all_parts" { VACUUM (ANALYZE, SKIP LOCKED) parted; } +step "vac_full_specified" { VACUUM (SKIP LOCKED, FULL) part1, part2; } +step "vac_full_all_parts" { VACUUM (SKIP LOCKED, FULL) parted; } + +permutation "lock_share" "vac_specified" "commit" +permutation "lock_share" "vac_all_parts" "commit" +permutation "lock_share" "analyze_specified" "commit" +permutation "lock_share" "analyze_all_parts" "commit" +permutation "lock_share" "vac_analyze_specified" "commit" +permutation "lock_share" "vac_analyze_all_parts" "commit" +permutation "lock_share" "vac_full_specified" "commit" +permutation "lock_share" "vac_full_all_parts" "commit" +permutation "lock_access_exclusive" "vac_specified" "commit" +permutation "lock_access_exclusive" "vac_all_parts" "commit" +permutation "lock_access_exclusive" "analyze_specified" "commit" +permutation "lock_access_exclusive" "analyze_all_parts" "commit" +permutation "lock_access_exclusive" "vac_analyze_specified" "commit" +permutation "lock_access_exclusive" "vac_analyze_all_parts" "commit" +permutation "lock_access_exclusive" "vac_full_specified" "commit" +permutation "lock_access_exclusive" "vac_full_all_parts" "commit" diff --git a/src/test/regress/expected/vacuum.out b/src/test/regress/expected/vacuum.out index d66e2aa3b7..5d4a1e51c0 100644 --- a/src/test/regress/expected/vacuum.out +++ b/src/test/regress/expected/vacuum.out @@ -119,6 +119,16 @@ ANALYZE (nonexistant-arg) does_not_exist; ERROR: syntax error at or near "nonexistant" LINE 1: ANALYZE (nonexistant-arg) does_not_exist; ^ +-- ensure argument order independence, and that SKIP LOCKED on non-existing +-- relation still errors out. +ANALYZE (SKIP LOCKED, VERBOSE) does_not_exist; +ERROR: relation "does_not_exist" does not exist +ANALYZE (VERBOSE, SKIP LOCKED) does_not_exist; +ERROR: relation "does_not_exist" does not exist +-- SKIP LOCKED option +VACUUM (SKIP LOCKED) vactst; +VACUUM (SKIP LOCKED, FULL) vactst; +ANALYZE (SKIP LOCKED) vactst; DROP TABLE vaccluster; DROP TABLE vactst; DROP TABLE vacparted; diff --git a/src/test/regress/sql/vacuum.sql b/src/test/regress/sql/vacuum.sql index 275ce2e270..15749ffd94 100644 --- a/src/test/regress/sql/vacuum.sql +++ b/src/test/regress/sql/vacuum.sql @@ -93,6 +93,16 @@ ANALYZE vactst (i), vacparted (does_not_exist); ANALYZE (VERBOSE) does_not_exist; ANALYZE (nonexistant-arg) does_not_exist; +-- ensure argument order independence, and that SKIP LOCKED on non-existing +-- relation still errors out. +ANALYZE (SKIP LOCKED, VERBOSE) does_not_exist; +ANALYZE (VERBOSE, SKIP LOCKED) does_not_exist; + +-- SKIP LOCKED option +VACUUM (SKIP LOCKED) vactst; +VACUUM (SKIP LOCKED, FULL) vactst; +ANALYZE (SKIP LOCKED) vactst; + DROP TABLE vaccluster; DROP TABLE vactst; DROP TABLE vacparted; -- 2.16.2