From 9da56d39290b56f8d1b92ddac411dc26c70787e7 Mon Sep 17 00:00:00 2001 From: Maxim Orlov Date: Mon, 14 Nov 2022 18:24:58 +0300 Subject: [PATCH v1] Add "out of disk space" elog level. --- doc/src/sgml/config.sgml | 19 +++++++ doc/src/sgml/ref/alter_tablespace.sgml | 23 +++++--- doc/src/sgml/ref/create_tablespace.sgml | 23 +++++--- src/backend/access/common/reloptions.c | 23 +++++++- src/backend/access/heap/hio.c | 6 +++ src/backend/storage/file/buffile.c | 54 ++++++++++++++----- src/backend/storage/file/fd.c | 2 +- src/backend/storage/file/fileset.c | 4 +- src/backend/storage/smgr/md.c | 7 ++- src/backend/utils/cache/spccache.c | 36 +++++++++++++ src/backend/utils/misc/guc_tables.c | 15 ++++++ src/backend/utils/misc/postgresql.conf.sample | 1 + src/bin/psql/tab-complete.c | 3 +- src/include/commands/tablespace.h | 1 + src/include/storage/fd.h | 2 +- src/include/storage/fileset.h | 4 +- src/include/utils/spccache.h | 3 ++ src/test/regress/expected/tablespace.out | 23 +++++++- src/test/regress/sql/tablespace.sql | 19 ++++++- 19 files changed, 230 insertions(+), 38 deletions(-) diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml index 559eb898a9..85e5906faa 100644 --- a/doc/src/sgml/config.sgml +++ b/doc/src/sgml/config.sgml @@ -2526,6 +2526,25 @@ include_dir 'conf.d' + + on_no_space (integer) + + on_no_space configuration parameter + + + + + Specifies the log level used for reporting of an insufficient disk + resources from the tablespace. + + + The default is ERROR. This value can be overridden for tables in a + particular tablespace by setting the tablespace parameter of the same + name (see ). + + + + max_worker_processes (integer) diff --git a/doc/src/sgml/ref/alter_tablespace.sgml b/doc/src/sgml/ref/alter_tablespace.sgml index 6de80746d5..a37e417f7c 100644 --- a/doc/src/sgml/ref/alter_tablespace.sgml +++ b/doc/src/sgml/ref/alter_tablespace.sgml @@ -84,12 +84,18 @@ ALTER TABLESPACE name RESET ( , , , @@ -97,6 +103,11 @@ ALTER TABLESPACE name RESET ( value. + diff --git a/doc/src/sgml/ref/create_tablespace.sgml b/doc/src/sgml/ref/create_tablespace.sgml index 9d5ab02526..bb075aa332 100644 --- a/doc/src/sgml/ref/create_tablespace.sgml +++ b/doc/src/sgml/ref/create_tablespace.sgml @@ -106,12 +106,18 @@ CREATE TABLESPACE tablespace_name A tablespace parameter to be set or reset. Currently, the only available parameters are seq_page_cost, - random_page_cost, effective_io_concurrency - and maintenance_io_concurrency. - Setting these values for a particular tablespace will override the - planner's usual estimate of the cost of reading pages from tables in - that tablespace, and the executor's prefetching behavior, as established - by the configuration parameters of the + random_page_cost, effective_io_concurrency, + maintenance_io_concurrency and on_no_space. + + + + Setting seq_page_cost, + random_page_cost, + effective_io_concurrency and + maintenance_io_concurrency + values for a particular tablespace will override the planner's usual estimate + of the cost of reading pages from tables in that tablespace, and the executor's + prefetching behavior, as established by the configuration parameters of the same name (see , , , @@ -119,6 +125,11 @@ CREATE TABLESPACE tablespace_name one tablespace is located on a disk which is faster or slower than the remainder of the I/O subsystem. + + + Setting on_no_space value for a particular tablespace + will override the value. + diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c index 75b7344891..105eaad862 100644 --- a/src/backend/access/common/reloptions.c +++ b/src/backend/access/common/reloptions.c @@ -507,6 +507,15 @@ static relopt_enum_elt_def viewCheckOptValues[] = {(const char *) NULL} /* list terminator */ }; +/* some values from elog level */ +static relopt_enum_elt_def onNoSpaceOptValues[] = +{ + {"error", ERROR}, + {"fatal", FATAL}, + {"panic", PANIC}, + {(const char *) NULL} /* list terminator */ +}; + static relopt_enum enumRelOpts[] = { { @@ -542,6 +551,17 @@ static relopt_enum enumRelOpts[] = VIEW_OPTION_CHECK_OPTION_NOT_SET, gettext_noop("Valid values are \"local\" and \"cascaded\".") }, + { + { + "on_no_space", + "Specifies the log level used for reporting of an insufficient disk.", + RELOPT_KIND_TABLESPACE, + ShareUpdateExclusiveLock + }, + onNoSpaceOptValues, + ERROR, + gettext_noop("Valid values are \"error\", \"fatal\" and \"panic\".") + }, /* list terminator */ {{NULL}} }; @@ -2090,7 +2110,8 @@ tablespace_reloptions(Datum reloptions, bool validate) {"random_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, random_page_cost)}, {"seq_page_cost", RELOPT_TYPE_REAL, offsetof(TableSpaceOpts, seq_page_cost)}, {"effective_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, effective_io_concurrency)}, - {"maintenance_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, maintenance_io_concurrency)} + {"maintenance_io_concurrency", RELOPT_TYPE_INT, offsetof(TableSpaceOpts, maintenance_io_concurrency)}, + {"on_no_space", RELOPT_TYPE_ENUM, offsetof(TableSpaceOpts, on_no_space)} }; return (bytea *) build_reloptions(reloptions, validate, diff --git a/src/backend/access/heap/hio.c b/src/backend/access/heap/hio.c index b0ece66629..dbe75f3ef0 100644 --- a/src/backend/access/heap/hio.c +++ b/src/backend/access/heap/hio.c @@ -23,6 +23,7 @@ #include "storage/freespace.h" #include "storage/lmgr.h" #include "storage/smgr.h" +#include "utils/spccache.h" /* @@ -422,6 +423,11 @@ RelationGetBufferForTuple(Relation relation, Size len, targetBlock = nblocks - 1; } + /* + * Put tablespace into cache. + */ + get_tablespace_elevel(relation->rd_locator.spcOid); + loop: while (targetBlock != InvalidBlockNumber) { diff --git a/src/backend/storage/file/buffile.c b/src/backend/storage/file/buffile.c index b0b4eeb3bd..57f146ecea 100644 --- a/src/backend/storage/file/buffile.c +++ b/src/backend/storage/file/buffile.c @@ -53,6 +53,7 @@ #include "storage/buffile.h" #include "storage/fd.h" #include "utils/resowner.h" +#include "utils/spccache.h" /* * We break BufFiles into gigabyte-sized segments, regardless of RELSEG_SIZE. @@ -72,6 +73,7 @@ struct BufFile int numFiles; /* number of physical files in set */ /* all files except the last have length exactly MAX_PHYSICAL_FILESIZE */ File *files; /* palloc'd array with numFiles entries */ + Oid *tablespaces; /* palloc'd array with numFiles entries */ bool isInterXact; /* keep open over transactions? */ bool dirty; /* does buffer need to be written? */ @@ -99,12 +101,12 @@ struct BufFile }; static BufFile *makeBufFileCommon(int nfiles); -static BufFile *makeBufFile(File firstfile); +static BufFile *makeBufFile(File firstfile, Oid tablespace); static void extendBufFile(BufFile *file); static void BufFileLoadBuffer(BufFile *file); static void BufFileDumpBuffer(BufFile *file); static void BufFileFlush(BufFile *file); -static File MakeNewFileSetSegment(BufFile *buffile, int segment); +static File MakeNewFileSetSegment(BufFile *file, int segment, Oid *tablespace); /* * Create BufFile and perform the common initialization. @@ -131,12 +133,14 @@ makeBufFileCommon(int nfiles) * NOTE: caller must set isInterXact if appropriate. */ static BufFile * -makeBufFile(File firstfile) +makeBufFile(File firstfile, Oid tablespace) { BufFile *file = makeBufFileCommon(1); file->files = (File *) palloc(sizeof(File)); file->files[0] = firstfile; + file->tablespaces = (Oid *) palloc0(sizeof(Oid)); + file->tablespaces[0] = tablespace; file->readOnly = false; file->fileset = NULL; file->name = NULL; @@ -151,6 +155,7 @@ static void extendBufFile(BufFile *file) { File pfile; + Oid tablespace; ResourceOwner oldowner; /* Be sure to associate the file with the BufFile's resource owner */ @@ -158,9 +163,9 @@ extendBufFile(BufFile *file) CurrentResourceOwner = file->resowner; if (file->fileset == NULL) - pfile = OpenTemporaryFile(file->isInterXact); + pfile = OpenTemporaryFile(file->isInterXact, &tablespace); else - pfile = MakeNewFileSetSegment(file, file->numFiles); + pfile = MakeNewFileSetSegment(file, file->numFiles, &tablespace); Assert(pfile >= 0); @@ -168,7 +173,10 @@ extendBufFile(BufFile *file) file->files = (File *) repalloc(file->files, (file->numFiles + 1) * sizeof(File)); + file->tablespaces = (Oid *) repalloc(file->tablespaces, + (file->numFiles + 1) * sizeof(Oid)); file->files[file->numFiles] = pfile; + file->tablespaces[file->numFiles] = tablespace; file->numFiles++; } @@ -189,6 +197,7 @@ BufFileCreateTemp(bool interXact) { BufFile *file; File pfile; + Oid tablespace; /* * Ensure that temp tablespaces are set up for OpenTemporaryFile to use. @@ -201,10 +210,10 @@ BufFileCreateTemp(bool interXact) */ PrepareTempTablespaces(); - pfile = OpenTemporaryFile(interXact); + pfile = OpenTemporaryFile(interXact, &tablespace); Assert(pfile >= 0); - file = makeBufFile(pfile); + file = makeBufFile(pfile, tablespace); file->isInterXact = interXact; return file; @@ -223,7 +232,7 @@ FileSetSegmentName(char *name, const char *buffile_name, int segment) * Create a new segment file backing a fileset based BufFile. */ static File -MakeNewFileSetSegment(BufFile *buffile, int segment) +MakeNewFileSetSegment(BufFile *buffile, int segment, Oid *tablespace) { char name[MAXPGPATH]; File file; @@ -239,7 +248,7 @@ MakeNewFileSetSegment(BufFile *buffile, int segment) /* Create the new segment. */ FileSetSegmentName(name, buffile->name, segment); - file = FileSetCreate(buffile->fileset, name); + file = FileSetCreate(buffile->fileset, name, tablespace); /* FileSetCreate would've errored out */ Assert(file > 0); @@ -262,12 +271,15 @@ BufFile * BufFileCreateFileSet(FileSet *fileset, const char *name) { BufFile *file; + Oid tablespace; file = makeBufFileCommon(1); file->fileset = fileset; file->name = pstrdup(name); file->files = (File *) palloc(sizeof(File)); - file->files[0] = MakeNewFileSetSegment(file, 0); + file->files[0] = MakeNewFileSetSegment(file, 0, &tablespace); + file->tablespaces = (Oid *) palloc(sizeof(Oid)); + file->tablespaces[0] = tablespace; file->readOnly = false; return file; @@ -290,9 +302,12 @@ BufFileOpenFileSet(FileSet *fileset, const char *name, int mode, char segment_name[MAXPGPATH]; Size capacity = 16; File *files; + Oid *tablespaces, + tablespace; int nfiles = 0; files = palloc(sizeof(File) * capacity); + tablespaces = palloc(sizeof(Oid) * capacity); /* * We don't know how many segments there are, so we'll probe the @@ -305,10 +320,12 @@ BufFileOpenFileSet(FileSet *fileset, const char *name, int mode, { capacity *= 2; files = repalloc(files, sizeof(File) * capacity); + tablespaces = repalloc(tablespaces, sizeof(Oid) * capacity); } /* Try to load a segment. */ FileSetSegmentName(segment_name, name, nfiles); - files[nfiles] = FileSetOpen(fileset, segment_name, mode); + files[nfiles] = FileSetOpen(fileset, segment_name, mode, &tablespace); + tablespaces[nfiles] = tablespace; if (files[nfiles] <= 0) break; ++nfiles; @@ -324,6 +341,7 @@ BufFileOpenFileSet(FileSet *fileset, const char *name, int mode, { /* free the memory */ pfree(files); + pfree(tablespaces); if (missing_ok) return NULL; @@ -336,6 +354,7 @@ BufFileOpenFileSet(FileSet *fileset, const char *name, int mode, file = makeBufFileCommon(nfiles); file->files = files; + file->tablespaces = tablespaces; file->readOnly = (mode == O_RDONLY); file->fileset = fileset; file->name = pstrdup(name); @@ -415,6 +434,7 @@ BufFileClose(BufFile *file) FileClose(file->files[i]); /* release the buffer space */ pfree(file->files); + pfree(file->tablespaces); pfree(file); } @@ -532,10 +552,14 @@ BufFileDumpBuffer(BufFile *file) file->curOffset, WAIT_EVENT_BUFFILE_WRITE); if (bytestowrite <= 0) - ereport(ERROR, + { + Oid tablespace = file->tablespaces[file->curFile]; + + ereport(get_tablespace_elevel(tablespace), (errcode_for_file_access(), errmsg("could not write to file \"%s\": %m", FilePathName(thisfile)))); + } if (track_io_timing) { @@ -885,8 +909,14 @@ BufFileAppend(BufFile *target, BufFile *source) target->files = (File *) repalloc(target->files, sizeof(File) * newNumFiles); + target->tablespaces = (Oid *) + repalloc(target->tablespaces, sizeof(Oid) * newNumFiles); + for (i = target->numFiles; i < newNumFiles; i++) + { target->files[i] = source->files[i - target->numFiles]; + target->tablespaces[i] = source->tablespaces[i - target->numFiles]; + } target->numFiles = newNumFiles; return startBlock; diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c index 4151cafec5..61ae827cdf 100644 --- a/src/backend/storage/file/fd.c +++ b/src/backend/storage/file/fd.c @@ -1626,7 +1626,7 @@ PathNameDeleteTemporaryDir(const char *dirname) * case, the file is removed when the File is explicitly closed. */ File -OpenTemporaryFile(bool interXact) +OpenTemporaryFile(bool interXact, Oid *tablespace) { File file = 0; diff --git a/src/backend/storage/file/fileset.c b/src/backend/storage/file/fileset.c index 9c63f2b267..10f57b95ac 100644 --- a/src/backend/storage/file/fileset.c +++ b/src/backend/storage/file/fileset.c @@ -91,7 +91,7 @@ FileSetInit(FileSet *fileset) * Create a new file in the given set. */ File -FileSetCreate(FileSet *fileset, const char *name) +FileSetCreate(FileSet *fileset, const char *name, Oid *tablespace) { char path[MAXPGPATH]; File file; @@ -118,7 +118,7 @@ FileSetCreate(FileSet *fileset, const char *name) /* * Open a file that was created with FileSetCreate() */ File -FileSetOpen(FileSet *fileset, const char *name, int mode) +FileSetOpen(FileSet *fileset, const char *name, int mode, Oid *tablespace) { char path[MAXPGPATH]; File file; diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 14b6fa0fd9..36b8b39f82 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -40,6 +40,7 @@ #include "storage/sync.h" #include "utils/hsearch.h" #include "utils/memutils.h" +#include "utils/spccache.h" /* * The magnetic disk storage manager keeps track of open file @@ -479,14 +480,16 @@ mdextend(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum, if ((nbytes = FileWrite(v->mdfd_vfd, buffer, BLCKSZ, seekpos, WAIT_EVENT_DATA_FILE_EXTEND)) != BLCKSZ) { + int elevel = get_tablespace_elevel(reln->smgr_rlocator.locator.spcOid); + if (nbytes < 0) - ereport(ERROR, + ereport(elevel, (errcode_for_file_access(), errmsg("could not extend file \"%s\": %m", FilePathName(v->mdfd_vfd)), errhint("Check free disk space."))); /* short write: complain appropriately */ - ereport(ERROR, + ereport(elevel, (errcode(ERRCODE_DISK_FULL), errmsg("could not extend file \"%s\": wrote only %d of %d bytes at block %u", FilePathName(v->mdfd_vfd), diff --git a/src/backend/utils/cache/spccache.c b/src/backend/utils/cache/spccache.c index 5609246c2f..d0f929c865 100644 --- a/src/backend/utils/cache/spccache.c +++ b/src/backend/utils/cache/spccache.c @@ -25,11 +25,24 @@ #include "optimizer/optimizer.h" #include "storage/bufmgr.h" #include "utils/catcache.h" +#include "utils/guc.h" #include "utils/hsearch.h" #include "utils/inval.h" #include "utils/spccache.h" #include "utils/syscache.h" +/* + * GUC support + */ +const struct config_enum_entry on_no_space_options[] = { + {"error", ERROR, false}, + {"fatal", FATAL, false}, + {"panic", PANIC, false}, + {NULL, 0, false} +}; + +/* GUC variable */ +int on_no_space = ERROR; /* Hash table for information about each tablespace */ static HTAB *TableSpaceCacheHash = NULL; @@ -234,3 +247,26 @@ get_tablespace_maintenance_io_concurrency(Oid spcid) else return spc->opts->maintenance_io_concurrency; } + +/* + * get_tablespace_elevel + * + * Return the error level for the namespace. + */ +int +get_tablespace_elevel(Oid spcid) +{ + TableSpaceCacheEntry *spc; + + /* + * Use GUC level only in normal mode. + */ + if (!IsNormalProcessingMode()) + return ERROR; + + spc = get_tablespace(spcid); + if (!spc->opts) + return on_no_space; + else + return spc->opts->on_no_space; +} diff --git a/src/backend/utils/misc/guc_tables.c b/src/backend/utils/misc/guc_tables.c index 836b49484a..a2f3461499 100644 --- a/src/backend/utils/misc/guc_tables.c +++ b/src/backend/utils/misc/guc_tables.c @@ -77,6 +77,7 @@ #include "utils/pg_locale.h" #include "utils/portal.h" #include "utils/ps_status.h" +#include "utils/spccache.h" #include "utils/queryjumble.h" #include "utils/inval.h" #include "utils/xml.h" @@ -454,6 +455,7 @@ extern const struct config_enum_entry archive_mode_options[]; extern const struct config_enum_entry recovery_target_action_options[]; extern const struct config_enum_entry sync_method_options[]; extern const struct config_enum_entry dynamic_shared_memory_options[]; +extern const struct config_enum_entry on_no_space_options[]; /* * GUC option variables that are exported from this module @@ -2914,6 +2916,19 @@ struct config_int ConfigureNamesInt[] = NULL }, + { + {"on_no_space", + PGC_POSTMASTER, + RESOURCES_DISK, + gettext_noop("Error level on an out of disk memory."), + NULL, + GUC_EXPLAIN + }, + &on_no_space, + ERROR, ERROR, PANIC, + NULL, NULL, NULL + }, + { {"backend_flush_after", PGC_USERSET, RESOURCES_ASYNCHRONOUS, gettext_noop("Number of pages after which previously performed writes are flushed to disk."), diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample index 868d21c351..b947ed928d 100644 --- a/src/backend/utils/misc/postgresql.conf.sample +++ b/src/backend/utils/misc/postgresql.conf.sample @@ -160,6 +160,7 @@ #temp_file_limit = -1 # limits per-process temp file space # in kilobytes, or -1 for no limit +#on_no_space = ERROR # - Kernel Resources - diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c index 7b73886ce1..94a78c5b6e 100644 --- a/src/bin/psql/tab-complete.c +++ b/src/bin/psql/tab-complete.c @@ -2514,7 +2514,8 @@ psql_completion(const char *text, int start, int end) /* ALTER TABLESPACE SET|RESET ( */ else if (Matches("ALTER", "TABLESPACE", MatchAny, "SET|RESET", "(")) COMPLETE_WITH("seq_page_cost", "random_page_cost", - "effective_io_concurrency", "maintenance_io_concurrency"); + "effective_io_concurrency", "maintenance_io_concurrency", + "on_no_space"); /* ALTER TEXT SEARCH */ else if (Matches("ALTER", "TEXT", "SEARCH")) diff --git a/src/include/commands/tablespace.h b/src/include/commands/tablespace.h index a11c9e9473..75d3a3b061 100644 --- a/src/include/commands/tablespace.h +++ b/src/include/commands/tablespace.h @@ -43,6 +43,7 @@ typedef struct TableSpaceOpts float8 seq_page_cost; int effective_io_concurrency; int maintenance_io_concurrency; + int on_no_space; } TableSpaceOpts; extern Oid CreateTableSpace(CreateTableSpaceStmt *stmt); diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h index c0a212487d..5c0073f28c 100644 --- a/src/include/storage/fd.h +++ b/src/include/storage/fd.h @@ -100,7 +100,7 @@ extern PGDLLIMPORT int max_safe_fds; /* Operations on virtual Files --- equivalent to Unix kernel file ops */ extern File PathNameOpenFile(const char *fileName, int fileFlags); extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode); -extern File OpenTemporaryFile(bool interXact); +extern File OpenTemporaryFile(bool interXact, Oid *tablespace); extern void FileClose(File file); extern int FilePrefetch(File file, off_t offset, int amount, uint32 wait_event_info); extern int FileRead(File file, char *buffer, int amount, off_t offset, uint32 wait_event_info); diff --git a/src/include/storage/fileset.h b/src/include/storage/fileset.h index ad37884717..e50da55d95 100644 --- a/src/include/storage/fileset.h +++ b/src/include/storage/fileset.h @@ -30,9 +30,9 @@ typedef struct FileSet } FileSet; extern void FileSetInit(FileSet *fileset); -extern File FileSetCreate(FileSet *fileset, const char *name); +extern File FileSetCreate(FileSet *fileset, const char *name, Oid *tablespace); extern File FileSetOpen(FileSet *fileset, const char *name, - int mode); + int mode, Oid *tablespace); extern bool FileSetDelete(FileSet *fileset, const char *name, bool error_on_failure); extern void FileSetDeleteAll(FileSet *fileset); diff --git a/src/include/utils/spccache.h b/src/include/utils/spccache.h index 5163eeedbd..a31304c0fb 100644 --- a/src/include/utils/spccache.h +++ b/src/include/utils/spccache.h @@ -13,9 +13,12 @@ #ifndef SPCCACHE_H #define SPCCACHE_H +extern PGDLLIMPORT int on_no_space; + extern void get_tablespace_page_costs(Oid spcid, float8 *spc_random_page_cost, float8 *spc_seq_page_cost); extern int get_tablespace_io_concurrency(Oid spcid); extern int get_tablespace_maintenance_io_concurrency(Oid spcid); +extern int get_tablespace_elevel(Oid spcid); #endif /* SPCCACHE_H */ diff --git a/src/test/regress/expected/tablespace.out b/src/test/regress/expected/tablespace.out index c52cf1cfcf..5b92008e1e 100644 --- a/src/test/regress/expected/tablespace.out +++ b/src/test/regress/expected/tablespace.out @@ -22,6 +22,22 @@ SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; -- drop the tablespace so we can re-use the location DROP TABLESPACE regress_tblspacewith; +-- check "on_no_space" tablespace opt +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = 1); -- fail +ERROR: invalid value for enum option "on_no_space": 1 +DETAIL: Valid values are "error", "fatal" and "panic". +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = true); -- fail +ERROR: invalid value for enum option "on_no_space": true +DETAIL: Valid values are "error", "fatal" and "panic". +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = WARNING); -- fail +ERROR: invalid value for enum option "on_no_space": warning +DETAIL: Valid values are "error", "fatal" and "panic". +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = ERROR); -- ok +DROP TABLESPACE regress_tblspacewith; +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = FATAL); -- ok +DROP TABLESPACE regress_tblspacewith; +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = PANIC); -- ok +DROP TABLESPACE regress_tblspacewith; -- create a tablespace we can use CREATE TABLESPACE regress_tblspace LOCATION ''; -- This returns a relative path as of an effect of allow_in_place_tablespaces, @@ -34,12 +50,15 @@ SELECT regexp_replace(pg_tablespace_location(oid), '(pg_tblspc)/(\d+)', '\1/NNN' (1 row) -- try setting and resetting some properties for the new tablespace -ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); +ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1, on_no_space = PANIC); ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true); -- fail ERROR: unrecognized parameter "some_nonexistent_parameter" +ALTER TABLESPACE regress_tblspace SET (on_no_space = WARNING); -- fail +ERROR: invalid value for enum option "on_no_space": warning +DETAIL: Valid values are "error", "fatal" and "panic". ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0); -- fail ERROR: RESET must not include values for parameters -ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency); -- ok +ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency, on_no_space); -- ok -- REINDEX (TABLESPACE) -- catalogs and system tablespaces -- system catalog, fail diff --git a/src/test/regress/sql/tablespace.sql b/src/test/regress/sql/tablespace.sql index 21db433f2a..aa1100b641 100644 --- a/src/test/regress/sql/tablespace.sql +++ b/src/test/regress/sql/tablespace.sql @@ -20,6 +20,20 @@ SELECT spcoptions FROM pg_tablespace WHERE spcname = 'regress_tblspacewith'; -- drop the tablespace so we can re-use the location DROP TABLESPACE regress_tblspacewith; +-- check "on_no_space" tablespace opt +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = 1); -- fail +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = true); -- fail +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = WARNING); -- fail + +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = ERROR); -- ok +DROP TABLESPACE regress_tblspacewith; + +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = FATAL); -- ok +DROP TABLESPACE regress_tblspacewith; + +CREATE TABLESPACE regress_tblspacewith LOCATION '' WITH (on_no_space = PANIC); -- ok +DROP TABLESPACE regress_tblspacewith; + -- create a tablespace we can use CREATE TABLESPACE regress_tblspace LOCATION ''; -- This returns a relative path as of an effect of allow_in_place_tablespaces, @@ -28,10 +42,11 @@ SELECT regexp_replace(pg_tablespace_location(oid), '(pg_tblspc)/(\d+)', '\1/NNN' FROM pg_tablespace WHERE spcname = 'regress_tblspace'; -- try setting and resetting some properties for the new tablespace -ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1); +ALTER TABLESPACE regress_tblspace SET (random_page_cost = 1.0, seq_page_cost = 1.1, on_no_space = PANIC); ALTER TABLESPACE regress_tblspace SET (some_nonexistent_parameter = true); -- fail +ALTER TABLESPACE regress_tblspace SET (on_no_space = WARNING); -- fail ALTER TABLESPACE regress_tblspace RESET (random_page_cost = 2.0); -- fail -ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency); -- ok +ALTER TABLESPACE regress_tblspace RESET (random_page_cost, effective_io_concurrency, on_no_space); -- ok -- REINDEX (TABLESPACE) -- catalogs and system tablespaces -- 2.38.1