This article explains how to move a database to a new tablespace in postgres. This is same as changing the default tablespace for a postgres database.   For this activity we have make sure that no application sessions are connecting to that database. We can say this activity will need some downtime.

Objective – We will move the database prod_crm from pg_default tablespace to crm_tblspc;

 Check existing tablespace details:


prod_crm=# \l+ prod_crm
                                                        List of databases
   Name    |    Owner     | Encoding |   Collate   |    Ctype    | ICU | Access privileges |  Size   | Tablespace  | Description
-----------+--------------+----------+-------------+-------------+-----+-------------------+---------+-------------+-------------
 prod_crm | enterprisedb | UTF8     | en_US.UTF-8 | en_US.UTF-8 |     |                   | 6677 MB | pg_default |
(1 row)

Alter database command


prod_crm=# alter database prod_crm set tablespace crm_tblspc;
ERROR:  cannot change the tablespace of the currently open database
prod_crm=#

Above error is because, we are connecting to the same database for which we are altering. We should issue the command by connecting to a different database.

-- Connect a different database 
prod_crm=# \q
-bash-4.2$ psql -d postgres -p 5432
Password for user enterprisedb:
psql.bin (11.8.15)
Type "help" for help.

postgres=#  alter database prod_crm set tablespace crm_tblspc;
ERROR:  database "prod_crm" is being accessed by other users
DETAIL:  There are 11 other sessions using the database.

New error says, the few sessions are using the database. So we need kill them.

Find the sessions using db:


postgres=# select usename,pid,application_name from  pg_stat_activity where datname='prod_crm';
  usename   |  pid  |    application_name
------------+-------+------------------------
 PROD_CRM | 15225 | PostgreSQL JDBC Driver
 PROD_CRM | 15283 | PostgreSQL JDBC Driver
 PROD_CRM | 15285 | PostgreSQL JDBC Driver
 PROD_CRM | 15286 | PostgreSQL JDBC Driver
 PROD_CRM | 15287 | PostgreSQL JDBC Driver
 PROD_CRM | 15290 | PostgreSQL JDBC Driver
 PROD_CRM | 15291 | PostgreSQL JDBC Driver
 PROD_CRM | 15292 | PostgreSQL JDBC Driver
 PROD_CRM | 15298 | PostgreSQL JDBC Driver
 PROD_CRM | 15300 | PostgreSQL JDBC Driver
 PROD_CRM | 15303 | PostgreSQL JDBC Driver
(11 rows)

As all the sessions are from PROD_CRM, so we need to kill the all the sessions of that user.

Kill the sessions for user PROD_CRM

 
postgres=# select pg_terminate_backend(pid) from pg_stat_activity where usename='PROD_CRM';
 pg_terminate_backend
----------------------
 t
 t
 t
 t
 t
 t
 t
 t
 t
 t
 t
(11 rows)


alternatively you can kill the sessions individually using below command.

select pg_terminate_backend(pid) from pg_stat_activity where pid=’15225′


postgres=#  alter database prod_crm set tablespace crm_tblspc;
ALTER DATABASE
postgres=#

prod_crm=# \l+ prod_crm
                                                        List of databases
   Name    |    Owner     | Encoding |   Collate   |    Ctype    | ICU | Access privileges |  Size   | Tablespace  | Description
-----------+--------------+----------+-------------+-------------+-----+-------------------+---------+-------------+-------------
 prod_crm | enterprisedb | UTF8     | en_US.UTF-8 | en_US.UTF-8 |     |                   | 6677 MB | crm_tblspc |
(1 row)