Earlier quoted context omitted.
Well, you can't just delete it. It is an object that was created by some user and there's no good reason for the database to get rid of it automatically. The database keeps a record of the invalid thing, even though it is invalid.
The good reason to get rid of it automatically: It takes up space. Is there any good reason to keep it? (The fact that it was "created by some user" doesn't seem like much of a reason.) IMHO, creating an index should be atomic: Either you end up with a valid index, or you end up with nothing.
An unexpected find that freed 20GB of unused index space in PostgreSQL
71–80 of 81 posts
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#72Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#73Earlier quoted context omitted.
> The database is obviously not able to tell that there will never be any values above 7 You say "obviously", but with updated statistics this is the exactly the kind of thing you might expect the planner to know and aid index decisions. I'm a huge fan of Postgres, coming to it around 5 years ago from at least 10 previous years with SQL Server, but I have hit a few things like this in that time. IME the planner is mu…
No, I don't think statistics can let you get away with this. Databases are concurrent, you can't guarantee that a different session will not insert a record that invalidates your current statistics. You could argue that it should be able to use it if the table has a check constraint preventing severity_id above 7 being ever inserted. That is something that could be done, I don't know if PostgreSQL does it (I doubt it…
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#74That left me wondering how, if all indexes are by default partial in Oracle… how does one make an unpartial? nonpartial? index.
https://use-the-index-luke.com/sql/where-clause/null/index
Apparently, you add a computed column to the index that just computes a constant value. And single non-null column then causes the nulls in other columns to get indexed, it's only if the whole tuple is composed of nulls that it gets left out.
That also seems like a bug waiting to happen; someone inverts a query to find unset (NULL) entries, and now you're doing a table scan.
…but it seems also like a form of brain rot, induced by a particular implementation, e.g., similar to how I've had MySQL users ask how to make a key on a table. Where a "key" is an index, it's just that MySQL by default uses the word "key" to mean index, instead of … key¹. (The query language even supports "INDEX" in place of "KEY", but things like "SHOW TABLE" default to the "wrong" (linguistically, not programmatically) word.) And then you might have to de-tangle why these two are different concepts, how they're different. It's very Arrival, in the sense of language (mis-)shaping perception.
¹a key is a set of columns that are sufficient to identify a row. The primary such set of columns is … the primary key. An index can index a key (if more than one exists within a table), but it doesn't have to.
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#75> Clear bloat in tables Ohh, we've had issues with this. We have this table that's mostly ephemeral data, so rows are constantly inserted and then deleted after a certain amount of time. Due to a bug the deletion didn't work for a while and the db grew very large. Fixed the deletion, but no amount of vacuuming actually allows us to fully reclaim that space so we don't have to pay for it. At the same time the extra co…
> but no amount of vacuuming actually allows us to fully reclaim that space
a full vacuum would. but it would also lock the table for the duration (which is something pg_repack won't do)
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#76> Clear bloat in tables Ohh, we've had issues with this. We have this table that's mostly ephemeral data, so rows are constantly inserted and then deleted after a certain amount of time. Due to a bug the deletion didn't work for a while and the db grew very large. Fixed the deletion, but no amount of vacuuming actually allows us to fully reclaim that space so we don't have to pay for it. At the same time the extra co…
have a look at pg_repack. That'll solve it for you. > but no amount of vacuuming actually allows us to fully reclaim that space a full vacuum would. but it would also lock the table for the duration (which is something pg_repack won't do)
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#77Earlier quoted context omitted.
Since 9 there's pg_upgrade, personally I never had an issue and it was very fast, so the downtime is in the order of a few minutes, which is ok for my usecase. YMMV.
"pg_upgrade does its best to make sure the old and new clusters are binary-compatible, e.g., by checking for compatible compile-time settings, including 32/64-bit binaries. It is important that any external modules are also binary compatible, though this cannot be checked by pg_upgrade." This makes me very nervous tho, I've at least two exts (trigrams and gists) maybe they work, maybe not, I just prefer the ease of m…
It'd be something like nominatim.so, which is external to PGSQL and (AFAIK) has its own format for certain types of data and indexes.
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#78Partial indexes are amazing but you have to keep in mind some pecularities. If your query doesn't contain a proper match with the WHERE clause of the index - the index will not be used. It is easy to forget about it or to get it wrong in subtle ways. Here is an example from work. There was an event tracing structure which contained the event severity_id. Id values 0-6 inclusive are user facing events. Severity 7 and…
On the other hand, with sqlite, the WHERE clause of the query and the partial index must match *literally*. So let's say you have a partial index with WHERE severity_id != 0, and a query with WHERE severity_id = 1. All the rows with severity_id = 1 are already indexed, but the engine is still not able to make use of the partial index. This one bit us hard.
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#79Earlier quoted context omitted.
Well, you can't just delete it. It is an object that was created by some user and there's no good reason for the database to get rid of it automatically. The database keeps a record of the invalid thing, even though it is invalid.
The good reason to get rid of it automatically: It takes up space. Is there any good reason to keep it? (The fact that it was "created by some user" doesn't seem like much of a reason.) IMHO, creating an index should be atomic: Either you end up with a valid index, or you end up with nothing.
Want real atomicity? Don't use `CONCURRENTLY`.
Re: An unexpected find that freed 20GB of unused index space in PostgreSQL
#80Earlier quoted context omitted.
The good reason to get rid of it automatically: It takes up space. Is there any good reason to keep it? (The fact that it was "created by some user" doesn't seem like much of a reason.) IMHO, creating an index should be atomic: Either you end up with a valid index, or you end up with nothing.
I had the same thoughts. Is there any reason to keep it? Is there any scenario where that invalid index could be useful?