Minor DROP TABLESPACE issue

Started by Tom Laneover 21 years ago10 messages
#1Tom Lane
tgl@sss.pgh.pa.us

Although DROP TABLESPACE can detect tables existing in the target
tablespace, it doesn't have any way to detect schemas that reference
that tablespace as their default tablespace. Thus you can get
implementation-level failures like this one:

$ mkdir /tmp/junk

regression=# create tablespace junk location '/tmp/junk';
CREATE TABLESPACE
regression=# create schema junk tablespace junk;
CREATE SCHEMA
regression=# drop tablespace junk;
DROP TABLESPACE
regression=# create table junk.foo(f1 text);
ERROR: could not create directory "/u/pg_data/pg_tablespaces/292909/155056": No such file or directory
regression=#

The fact that it fails isn't a big problem, but the error message is
pretty unclear if you're unfamiliar with the implementation.

The same problem would exist with respect to a database's default
tablespace, except that a database will always have its system catalogs
stored there and so the file-level check prevents dropping the
tablespace.

I don't think we can directly prevent the DROP TABLESPACE, since we
can't see what's in pg_namespace of other databases. I thought about
creating a placeholder file associated with every schema that has a
nondefault tablespace, thereby allowing the file-level check to detect
the problem. But that looks very ugly, not least because namespaces
don't have relfilenode values. What might be the most appropriate
solution is just to issue a specialized error message in
TablespaceCreateDbspace(): if mkdir fails with ENOENT, we could say
something like
ERROR: tablespace 292909 has been deleted
after making an appropriate stat() test to verify that the symlink is
indeed gone. It's not great that we'd have to use the OID in this
message, but since the pg_tablespace row is (presumably) gone I don't
see any way to get the actual name of the tablespace.

Anyone see other alternatives?

regards, tom lane

#2Gavin Sherry
swm@linuxworld.com.au
In reply to: Tom Lane (#1)
Re: Minor DROP TABLESPACE issue

On Fri, 18 Jun 2004, Tom Lane wrote:

Although DROP TABLESPACE can detect tables existing in the target
tablespace, it doesn't have any way to detect schemas that reference
that tablespace as their default tablespace. Thus you can get
implementation-level failures like this one:

Of course. Never thought of that one.

The fact that it fails isn't a big problem, but the error message is
pretty unclear if you're unfamiliar with the implementation.

The same problem would exist with respect to a database's default
tablespace, except that a database will always have its system catalogs
stored there and so the file-level check prevents dropping the
tablespace.

Is it really that bad? NamespaceCreate() could just touch a file at
pg_tablespaces/<tablespaceoid>/<MyDatabaseId>/<namespace oid> and
RemoveSchema() could remove it.

Is there anything ugly that I've missed?

Gavin

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gavin Sherry (#2)
Re: Minor DROP TABLESPACE issue

Gavin Sherry <swm@linuxworld.com.au> writes:

Is it really that bad? NamespaceCreate() could just touch a file at
pg_tablespaces/<tablespaceoid>/<MyDatabaseId>/<namespace oid> and
RemoveSchema() could remove it.

No, because that wouldn't be rollback-safe. You'd have to make the
placeholder file act enough like a real relation that the smgr
delete-at-commit-or-abort mechanisms could handle it. So then you
have to buy into not having its name actually collide with any real
relations, which is where I started feeling like I didn't want to
pursue that solution.

This is certainly doable in theory, it just seems like much more
complexity than the problem is worth ...

regards, tom lane

#4Gavin Sherry
swm@linuxworld.com.au
In reply to: Tom Lane (#3)
Re: Minor DROP TABLESPACE issue

On Fri, 18 Jun 2004, Tom Lane wrote:

Gavin Sherry <swm@linuxworld.com.au> writes:

Is it really that bad? NamespaceCreate() could just touch a file at
pg_tablespaces/<tablespaceoid>/<MyDatabaseId>/<namespace oid> and
RemoveSchema() could remove it.

No, because that wouldn't be rollback-safe. You'd have to make the
placeholder file act enough like a real relation that the smgr
delete-at-commit-or-abort mechanisms could handle it. So then you
have to buy into not having its name actually collide with any real
relations, which is where I started feeling like I didn't want to
pursue that solution.

This is certainly doable in theory, it just seems like much more
complexity than the problem is worth ...

Oh yeah... I forgot about OID wrap around issues and integration into WAL,
etc, wouldn't be great fun.

If we just wanted to make the error message more user friendly, perhaps we
could *gulp* store the tablespace name in PG_VERSION. Then again, all of
this can probably be handled better in the manual.

Gavin

#5Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gavin Sherry (#4)
Re: Minor DROP TABLESPACE issue

Gavin Sherry <swm@linuxworld.com.au> writes:

If we just wanted to make the error message more user friendly, perhaps we
could *gulp* store the tablespace name in PG_VERSION.

That's actually not a bad idea from a debugging standpoint. But I don't
see that it helps any for this particular problem. The PG_VERSION file
will be gone when we need the info.

regards, tom lane

#6Gavin Sherry
swm@linuxworld.com.au
In reply to: Tom Lane (#5)
Re: Minor DROP TABLESPACE issue

On Fri, 18 Jun 2004, Tom Lane wrote:

Gavin Sherry <swm@linuxworld.com.au> writes:

If we just wanted to make the error message more user friendly, perhaps we
could *gulp* store the tablespace name in PG_VERSION.

That's actually not a bad idea from a debugging standpoint. But I don't
see that it helps any for this particular problem. The PG_VERSION file
will be gone when we need the info.

Duh. I best get some coffee into me.

Gavin

#7Christopher Kings-Lynne
chriskl@familyhealth.com.au
In reply to: Tom Lane (#1)
Re: Minor DROP TABLESPACE issue

ERROR: tablespace 292909 has been deleted

How about "schema default tablespace 292909 has been deleted"?

Chris

#8Tom Lane
tgl@sss.pgh.pa.us
In reply to: Christopher Kings-Lynne (#7)
Re: Minor DROP TABLESPACE issue

Christopher Kings-Lynne <chriskl@familyhealth.com.au> writes:

ERROR: tablespace 292909 has been deleted

How about "schema default tablespace 292909 has been deleted"?

Yeah, I was wondering if we could finger the specific schema that
was causing the problem, but the place that would detect the error
couldn't really know that. Perhaps we could add a HINT advising
to look in pg_namespace for the relevant entry.

regards, tom lane

#9Gaetano Mendola
mendola@bigfoot.com
In reply to: Tom Lane (#1)
Re: Minor DROP TABLESPACE issue

Tom Lane wrote:

Although DROP TABLESPACE can detect tables existing in the target
tablespace, it doesn't have any way to detect schemas that reference
that tablespace as their default tablespace. Thus you can get
implementation-level failures like this one:

$ mkdir /tmp/junk

regression=# create tablespace junk location '/tmp/junk';
CREATE TABLESPACE
regression=# create schema junk tablespace junk;
CREATE SCHEMA
regression=# drop tablespace junk;
DROP TABLESPACE

Why this doesn't fail? The junk schema depend on tablespace junk,
is there no dependencies between these two objects.

G.

#10Tom Lane
tgl@sss.pgh.pa.us
In reply to: Gaetano Mendola (#9)
Re: Minor DROP TABLESPACE issue

Gaetano Mendola <mendola@bigfoot.com> writes:

is there no dependencies between these two objects.

No, and there's little point in adding one, since it wouldn't prevent
the problem from happening if you issue the DROP TABLESPACE from a
different database.

regards, tom lane