diff --git a/src/backend/cdb/cdbbufferedappend.c b/src/backend/cdb/cdbbufferedappend.c index 62a31f9d9bcf..3b0461c5ca71 100644 --- a/src/backend/cdb/cdbbufferedappend.c +++ b/src/backend/cdb/cdbbufferedappend.c @@ -180,11 +180,18 @@ BufferedAppendWrite(BufferedAppend *bufferedAppend, bool needsWAL) (char *) largeWriteMemory + bytestotal, bytesleft); if (byteswritten < 0) + { + /* + * Close the file before throwing the ereport + * to avoid orphaned file descriptors if we run out of space + */ + FileClose(bufferedAppend->file); ereport(ERROR, (errcode_for_file_access(), errmsg("could not write in table \"%s\" to segment file \"%s\": %m", bufferedAppend->relationName, bufferedAppend->filePathName))); + } bytesleft -= byteswritten; bytestotal += byteswritten; diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c index 3ac05982e46f..be1fb2b2dc5e 100644 --- a/src/backend/storage/smgr/md.c +++ b/src/backend/storage/smgr/md.c @@ -382,6 +382,14 @@ mdcreate_ao(RelFileNodeBackend rnode, int32 segmentFileNum, bool isRedo) } } + /* + * This function is intended only to a create file. + * So, once the file is created successfully, close it. + * If someone wants to access this file afterward, + * he will need to open it again. + */ + FileClose(fd); + if (path != buf) pfree(path); } diff --git a/src/test/regress/input/tablespace.source b/src/test/regress/input/tablespace.source index ece027cb0e24..f65f1a3b6259 100755 --- a/src/test/regress/input/tablespace.source +++ b/src/test/regress/input/tablespace.source @@ -112,6 +112,16 @@ CREATE TABLE tablespace_table (i int) TABLESPACE testspace; -- fail ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint; RESET ROLE; +CREATE TEMP TABLE test_table(a int) WITH (APPENDONLY = TRUE) TABLESPACE testspace DISTRIBUTED BY (a); +INSERT INTO test_table SELECT generate_series(1,100); +DROP TABLE test_table; + +CREATE TABLE test_table(a int) WITH (APPENDONLY = TRUE) TABLESPACE testspace DISTRIBUTED BY (a); +INSERT INTO test_table SELECT generate_series(1,100); +DROP TABLE test_table; +-- Check there is zero opened file descriptors after query +\! lsof +L1 | grep postgres | grep testtablespace + ALTER TABLESPACE testspace RENAME TO testspace_renamed; -- Test that default_tablespace GUC is honored even after gang reset. diff --git a/src/test/regress/output/tablespace.source b/src/test/regress/output/tablespace.source index 723b7d5f0081..3e02aa491f66 100755 --- a/src/test/regress/output/tablespace.source +++ b/src/test/regress/output/tablespace.source @@ -213,6 +213,14 @@ ALTER TABLE testschema.tablespace_acl ALTER c TYPE bigint; ERROR: cannot alter indexed column HINT: DROP the index first, and recreate it after the ALTER RESET ROLE; +CREATE TEMP TABLE test_table(a int) WITH (APPENDONLY = TRUE) TABLESPACE testspace DISTRIBUTED BY (a); +INSERT INTO test_table SELECT generate_series(1,100); +DROP TABLE test_table; +CREATE TABLE test_table(a int) WITH (APPENDONLY = TRUE) TABLESPACE testspace DISTRIBUTED BY (a); +INSERT INTO test_table SELECT generate_series(1,100); +DROP TABLE test_table; +-- Check there is zero opened file descriptors after query +\! lsof +L1 | grep postgres | grep testtablespace ALTER TABLESPACE testspace RENAME TO testspace_renamed; -- Test that default_tablespace GUC is honored even after gang reset. CREATE OR REPLACE FUNCTION cleanupAllGangs() RETURNS BOOL