PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 10/07/2017 11:32:04

mba
Membre

ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Bonjour,

Je viens de changer le tablespace d'une table avec la commande ALTER TABLE matable SET TABLESPACE NEW_TABLESPACE.
Je vois bien ma table sur le nouveau FS mais il ne m'a pas récupéré l'espace sur l'ancien FS ?

Quelqu'un aurait une idée SVP !

Cordialement.
Mahdi,

Hors ligne

#2 10/07/2017 12:42:03

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Il me semble que j'ai trouvé, apparemment il faut également faire la même action sur les indexes de la table.

Hors ligne

#3 10/07/2017 16:54:52

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Toujours dans le même contexte:
après avoir déplacé la table et ses indexes j'ai effectué un  vacuum full mais il ne m'a pas récupéré de l'espace :
nohup: ignoring input
INFO:  vacuuming "public.abonnement"
INFO:  "abonnement": found 0 removable, 153625015 nonremovable row versions in 1519342 pages
DETAIL:  68880619 dead row versions cannot be removed yet.
CPU 68.37s/147.85u sec elapsed 277.41 sec.
INFO:  analyzing "public.idg_etu_abonnement"
INFO:  "abonnement": scanned 30000 of 1511144 pages, containing 1679913 live rows and 1370361 dead rows; 30000 rows in sample, 152255079 estimated total rows
VACUUM

Pour information la table fait 12GB avec un seul index de 9GB.
La ligne DETAIL:  68880619 dead row versions cannot be removed yet. correspond à quoi exactement ?.
d'avance merci pour votre aide.
Cordialement.
Mahdi,

Hors ligne

#4 11/07/2017 08:49:59

ruizsebastien
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

bonjour,

Etes-vous sûr d'avoir fait un vacuum full ?
Pouvez-vous essayer avec le binaire vacuumdb :
Usage:
  vacuumdb [OPTION]... [DBNAME]

Options:
  -a, --all                       vacuum all databases
  -d, --dbname=DBNAME             database to vacuum
  -e, --echo                      show the commands being sent to the server
  -f, --full                      do full vacuuming
  -F, --freeze                    freeze row transaction information
  -q, --quiet                     don't write any messages
  -t, --table='TABLE[(COLUMNS)]'  vacuum specific table(s) only
  -v, --verbose                   write a lot of output
  -V, --version                   output version information, then exit
  -z, --analyze                   update optimizer statistics
  -Z, --analyze-only              only update optimizer statistics
      --analyze-in-stages         only update optimizer statistics, in multiple
                                  stages for faster results
  -?, --help                      show this help, then exit

Connection options:
  -h, --host=HOSTNAME       database server host or socket directory
  -p, --port=PORT           database server port
  -U, --username=USERNAME   user name to connect as
  -w, --no-password         never prompt for password
  -W, --password            force password prompt
  --maintenance-db=DBNAME   alternate maintenance database


Cordialement,

Sébastien.

Hors ligne

#5 11/07/2017 10:08:01

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Bonjour Sébastien,

Ci_dessous la commande que j'ai lancé:
nohup psql -p 5436 mbase -c "vacuum (full,analyze,verbose) public.abonnement" > abonnement_vacuumfull.log 2>&1 &

Cordialement.
Mahdi,

Hors ligne

#6 11/07/2017 10:43:59

ruizsebastien
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

essayez quand même avec vacuumdb pour voir.


Cordialement,

Sébastien.

Hors ligne

#7 11/07/2017 10:51:50

rjuju
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

La ligne DETAIL:  68880619 dead row versions cannot be removed yet. correspond à quoi exactement ?.

Cela veut dire que vous avez une transaction suffisamment vieille pour voir ces lignes, et qu'elles ne peuvent donc pas être supprimées.

Regardez dans pg_stat_activity si vous avez une transaction très vieille.  Sinon, c'est probablement une transaction préparée (pg_prepared_xacts) ou un slot de réplication oublié (pg_replication_slots)

Hors ligne

#8 20/07/2017 10:49:02

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Bonjour,

Effectivement, j'ai kill toutes les sessions en idle et ça fonctionné.
Par contre j'ai un un autre problème je n'arrive pas à supprimer un tablespace que j'ai utilisé pour les opérations de vacuum.
Pourtant il n'y a aucun objet dessus:
postgres=# SELECT
postgres-#   c.relname,
postgres-#   t.spcname
postgres-# FROM
postgres-#   pg_class c
postgres-#     JOIN pg_tablespace t ON c.reltablespace = t.oid
postgres-# WHERE
postgres-#   t.spcname = 'new_tbspace';
relname | spcname
---------+---------
(0 rows)

postgres=# DROP TABLESPACE new_tbspace;
ERROR:  tablespace "new_tbspace" is not empty
postgres=#

Quelqu'un aurait une idée SVP.

Cordialement.
Mahdi,

Hors ligne

#9 20/07/2017 12:30:11

rjuju
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Vérifiez s'il n'y a pas des objets sur les autres bases.

Hors ligne

#10 20/07/2017 12:40:51

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

J'ai qu'une seule base.
You are now connected to database "mkgetuprd" as user "postgres".
mkgetuprd=# SELECT
mkgetuprd-#   c.relname,
mkgetuprd-#   t.spcname
mkgetuprd-# FROM
mkgetuprd-#   pg_class c
mkgetuprd-#     JOIN pg_tablespace t ON c.reltablespace = t.oid
mkgetuprd-# WHERE
mkgetuprd-#   t.spcname = 'new_tbspace';
relname | spcname
---------+---------
(0 rows)
mkgetuprd=#
mkgetuprd=# DROP TABLESPACE new_tbspace;
ERROR:  tablespace "new_tbspace" is not empty
mkgetuprd=#

Même problème.

Mahdi,

Hors ligne

#11 20/07/2017 12:46:18

gleu
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

S'il vous dit simplement qu'il n'est pas vide, sans indiquer d'objets, c'est que d'autres bases contiennent des objets dans ce tablespace. Vous avez forcément d'autres bases, notamment postgres, template1 et template0.


Guillaume.

Hors ligne

#12 20/07/2017 12:47:11

rjuju
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Que contient le répertoire pointé par votre tablespace, sur 2 niveaux d'aborescence ?  Quelle version de postgres et quel système d'exploitation utilisez-vous ?

Hors ligne

#13 20/07/2017 13:10:56

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

postgres=# \! ls -ltr /u02/vacuum/psql5436/PG_9.4_201409291/16386
total 26478116
-rw------- 1 postgres postgres 1073741824 Jul 13 10:09 467033
-rw------- 1 postgres postgres 1073741824 Jul 13 10:09 467033.1
-rw------- 1 postgres postgres 1073741824 Jul 13 10:09 467033.2
-rw------- 1 postgres postgres 1073741824 Jul 13 10:10 467033.3
-rw------- 1 postgres postgres 1073741824 Jul 13 10:10 467033.4
-rw------- 1 postgres postgres 1073741824 Jul 13 10:10 467033.5
-rw------- 1 postgres postgres 1073741824 Jul 13 10:10 467033.6
-rw------- 1 postgres postgres 1073741824 Jul 13 10:11 467033.7
-rw------- 1 postgres postgres 1073741824 Jul 13 10:11 467033.8
-rw------- 1 postgres postgres 1073741824 Jul 13 10:11 467033.9
-rw------- 1 postgres postgres 1073741824 Jul 13 10:11 467033.10
-rw------- 1 postgres postgres 1073741824 Jul 13 10:12 467033.11
-rw------- 1 postgres postgres 1073741824 Jul 13 10:12 467033.12
-rw------- 1 postgres postgres 1073741824 Jul 13 10:12 467033.13
-rw------- 1 postgres postgres 1073741824 Jul 13 10:12 467033.14
-rw------- 1 postgres postgres 1073741824 Jul 13 10:13 467033.15
-rw------- 1 postgres postgres 1073741824 Jul 13 10:13 467033.16
-rw------- 1 postgres postgres 1073741824 Jul 13 10:13 467033.17
-rw------- 1 postgres postgres 1073741824 Jul 13 10:13 467033.18
-rw------- 1 postgres postgres 1073741824 Jul 13 10:13 467033.19
-rw------- 1 postgres postgres 1073741824 Jul 13 10:14 467033.20
-rw------- 1 postgres postgres 1073741824 Jul 13 10:14 467033.21
-rw------- 1 postgres postgres 1073741824 Jul 13 10:14 467033.22
-rw------- 1 postgres postgres 1073741824 Jul 13 10:14 467033.23
-rw------- 1 postgres postgres 1073741824 Jul 13 10:15 467033.24
-rw------- 1 postgres postgres  269942784 Jul 13 10:15 467033.25
postgres=# postgres=# \db+ new_tbspace
                                    List of tablespaces
    Name     |  Owner   |       Location       | Access privileges | Options | Description
-------------+----------+----------------------+-------------------+---------+-------------
new_tbspace | postgres | /u02/vacuum/psql5436 |                   |         |
(1 row)

postgres-# select version();
ERROR:  syntax error at or near "postgres"
LINE 1: postgres=#
        ^
postgres=# select version();
                                                    version
----------------------------------------------------------------------------------------------------------------
PostgreSQL 9.4.11 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.7 20120313 (Red Hat 4.4.7-17), 64-bit
(1 row)
postgres=#

Hors ligne

#14 20/07/2017 13:17:33

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

@Guillaume:

Aucun objet d'autres bases.
De toutes façons je l'ai utilisé que pour une seule base, j'ai déplacé une table, j'ai fait un vacuum et en suite j'ai remis la table à son tablespace initial (pg_default).
postgres=# \c template1
You are now connected to database "template1" as user "postgres".
template1=# SELECT
template1-#   c.relname,
template1-#   t.spcname
template1-# FROM
template1-#   pg_class c
template1-#     JOIN pg_tablespace t ON c.reltablespace = t.oid
template1-# WHERE
template1-#   t.spcname = 'new_tbspace';
relname | spcname
---------+---------
(0 rows)

template1=# \c template0
FATAL:  database "template0" is not currently accepting connections
Previous connection kept
template1=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=# SELECT
postgres-#   c.relname,
postgres-#   t.spcname
postgres-# FROM
postgres-#   pg_class c
postgres-#     JOIN pg_tablespace t ON c.reltablespace = t.oid
postgres-# WHERE
postgres-#   t.spcname = 'new_tbspace';
relname | spcname
---------+---------
(0 rows)

postgres=#

Hors ligne

#15 20/07/2017 13:29:17

gleu
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Donc il existe bien un objet. Il faudrait se connecter sur la base d'OID 16386 et chercher à quelle table correspond le relfilenode 467033.

Je ne serais pas étonné que ça corresponde à votre base. La requête que vous utilisez pour récupérer tous les objets compris dans un tablespace fonctionne uniquement pour les objets qui ne sont pas dans une base de données dont le tablespace par défaut est ce tablespace.


Guillaume.

Hors ligne

#16 20/07/2017 13:43:19

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

L'OID correspond bien à ma base mais je n'ai aucune ligne dans pg_class pour ce refilenode

mkgetuprd=# select count(*) from pg_class where relfilenode=467033;
count
-------
     0
(1 row)

mkgetuprd=# \c postgres
You are now connected to database "postgres" as user "postgres".
postgres=# select count(*) from pg_class where relfilenode=467033;
count
-------
     0
(1 row)

postgres=# \c nobody
You are now connected to database "nobody" as user "postgres".
nobody=# select count(*) from pg_class where relfilenode=467033;
count
-------
     0
(1 row)

nobody=# \c template1
You are now connected to database "template1" as user "postgres".
template1=# select count(*) from pg_class where relfilenode=467033;
count
-------
     0
(1 row)

template1=#

Ma table pointe bien vers le tablespace par défaut:
                          ^
template1=# \c mkgetuprd
You are now connected to database "mkgetuprd" as user "postgres".
mkgetuprd=# select pg_relation_filepath('public.idg_etu_vente_lig');
pg_relation_filepath
----------------------
base/16386/475347
(1 row)

mkgetuprd=# select count(*) from pg_class where relfilenode=475347;
count
-------
     1
(1 row)
mkgetuprd=#

Hors ligne

#17 20/07/2017 17:31:16

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Pour information, j'ai rebooté l'instance pareil.

Hors ligne

#18 20/07/2017 22:38:20

gleu
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Avez-vous essayé l'outil oid2name pour voir s'il arrive à donner un nom à l'objet représenté par ces ficheirs ?


Guillaume.

Hors ligne

#19 20/07/2017 22:56:55

rjuju
Administrateur

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

La seule explication que j'ai serais due à un scénario tel que :


- vous avez une table relativement volumineuse (au moins 25 Go dans votre cas)
- vous déplacez cette table sur le tablespace en question, ce qui prend un certain temps
- durant le déplacement, un arrêt brutal survient (crash de l'instance, kill -SIGKILL du processus...)

Dans ce cas, effectivement la partie de la tale déjà copiée sur le nouveau tablespace restera en l'état et ne sera pas nettoyée.


Est-ce qu'un scénario de ce genre est survenu sur votre instance ?  Si oui, le seul moyen dans ce cas est de nettoyer manuellement les fichiers, en ayant vérifié, revérifié et contrevérifié qu'il s'agit bien de données mortes.

Hors ligne

#20 21/07/2017 10:40:26

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Bonjour,

@Julien

C'est exactement ce que s'est passé, le premier ALTER a échoué à cause de la génération des wal le FS était plein.

-bash-4.1$ oid2name -p 5436 -d mkgetuprd -f 467033
From database "mkgetuprd":
  Filenode  Table Name
----------------------
-bash-4.1$

Je suis partant pour un nettoyage manuel mais je voudrais savoir la méthode (la bonne pratique).

D'avance merci !

Cordialement.
Mahdi BAICHE

Hors ligne

#21 21/07/2017 14:15:58

mba
Membre

Re : ALTER TABLE SET NEW_TABLESPACE sur un autre FS

Bonjour,

J'ai supprimé les fichiers manuellement puis drop de tablespace tout est OK.
Merci beaucoup pour votre aide !

Cordialement.
Mahdi,

Hors ligne

Pied de page des forums