Search code examples
postgresqltablespacepg-upgrade

What to do if there are two tablespace directories after pg_upgrade using hard-links option


A while back, I ran a PostgreSQL pg_upgrade on a PG11 database, to PG12, which has a tablespace located at /ssd in it.

I used the --link option in my command to create hard links, as to not double up the space as it is a huge database.

Unfortunately, I did not remove the old cluster after the upgrade.

A few months have passed since then, and we wanted to upgrade to PG15 now, but I noticed that inside /ssd, both PG_11_201809051 and PG_12_201909212 were still being used, with very recent modification dates on certain files in both directories.

When checking presence of files, I noticed there are some files in PG_11_201809051 that aren't in PG_12_201909212 and vice versa.

So, my question is: If I upgrade now to PG15, will it safely take all that's required from both of those directories, and move it all into a new PG_15 directory in /ssd?

If not, what options do I have to ensure a successful upgrade, and removal of old clusters?

Tried: Ran a PostgreSQL upgrade from PG11 to PG12.

Expected result: Nothing from PG11 would be used anymore.

Actual Result: PG_11_201809051 is still being used alongside PG_12_201909212 within the /ssd directory

Postgres config for tablespace:

temp_tablespaces = 'ssd'

Tablespace was initially created like so:

CREATE TABLESPACE ssd OWNER postgres LOCATION '/ssd';
$ ls -lh /data/pg12/pg_tblspc/
total 0
lrwxrwxrwx. 1 postgres postgres 4 Jun 16  2023 16412 -> /ssd


$ ls -lh /ssd/
total 0
drwx------. 2 postgres postgres  6 Mar  6  2021 lost+found
drwx------. 4 postgres postgres 36 May 26  2023 PG_11_201809051
drwx------. 4 postgres postgres 36 Jun 17  2023 PG_12_201909212
 $ tree -d /ssd  
/ssd
 ├── lost+found
 ├── PG_11_201809051
 │   ├── 16420
 │   └── pgsql_tmp
 └── PG_12_201909212
     ├── 16414
     └── pgsql_tmp

Solution

  • You are probably better off exploring this on the mailing list or in a chatroom - a lot depends on the details.

    It looks to me like you might just have not unlinked the old installation after the changeover. This is the final step in the pg_upgrade instructions and can be easily missed. ("16. Delete old cluster").

    Let me show you a little example with hardlinks:

    $ date > foo
    $ date > bar
    $ ln bar baz
    $ ls -l
    total 12
    -rw-rw-r-- 2 richard richard 29 Mar  8 08:28 bar
    -rw-rw-r-- 2 richard richard 29 Mar  8 08:28 baz
    -rw-rw-r-- 1 richard richard 29 Mar  8 08:28 foo
    # wait for a couple of minutes...
    $ date > bar
    $ ls -l
    total 12
    -rw-rw-r-- 2 richard richard 29 Mar  8 08:29 bar
    -rw-rw-r-- 2 richard richard 29 Mar  8 08:29 baz
    -rw-rw-r-- 1 richard richard 29 Mar  8 08:28 foo
    

    You can see the "2" for the linked files and "1" for a file that has no links to it. Also the timestamps are linked because they are actually the same file.

    So - check the link number on those maybe-duplicated tablespace files and also check what stat has to say about them. If they are indeed copies you should be safe to unlink them.

    You may also have old linked files in somewhere like /var/lib/postgresql/12/... (location will depend on your setup).

    NOTE: Personally I would stop postgresql and take a full filesystem backup of all of its files before doing that. It depends how much data you have, how important it is, recent backup availability etc.