On Tue, Dec 21, 2021 at 11:10 AM Ashutosh Sharma <ashu.coe...@gmail.com> wrote:
>
> I am getting the below error when running the same test-case that Neha shared 
> in her previous email.
>
> ERROR:  55000: some relations of database "test1" are already in tablespace 
> "tab1"
> HINT:  You must move them back to the database's default tablespace before 
> using this command.
> LOCATION:  movedb, dbcommands.c:1555
>
> test-case:
> ========
> create tablespace tab1 location '/home/ashu/test1';
> create tablespace tab location '/home/ashu/test';
>
> create database test tablespace tab;
> \c test
>
> create table t(a int primary key, b text);
>
> create or replace function large_val() returns text language sql as 'select 
> array_agg(md5(g::text))::text from generate_series(1, 256) g';
>
> insert into t values (generate_series(1,100000), large_val());
>
> alter table t set tablespace tab1 ;
>
> \c postgres
> create database test1 template test;
>
> \c test1
> alter table t set tablespace tab;
>
> \c postgres
> alter database test1 set tablespace tab1; -- this fails with  the given error.
>
> Observations:
> ===========
> Please note that before running above alter database statement, the table 't' 
>  is moved to tablespace 'tab' from 'tab1' so not sure why ReadDir() is 
> returning true when searching for table 't' in tablespace 'tab1'. It should 
> have returned NULL here:
>
>  while ((xlde = ReadDir(dstdir, dst_dbpath)) != NULL)
>         {
>             if (strcmp(xlde->d_name, ".") == 0 ||
>                 strcmp(xlde->d_name, "..") == 0)
>                 continue;
>
>             ereport(ERROR,
>                     (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
>                      errmsg("some relations of database \"%s\" are already in 
> tablespace \"%s\"",
>                             dbname, tblspcname),
>                      errhint("You must move them back to the database's 
> default tablespace before using this command.")));
>         }
>
> Also, if I run the checkpoint explicitly before executing the above alter 
> database statement, this error doesn't appear which means it only happens 
> with the new changes because earlier we were doing the force checkpoint at 
> the end of createdb statement.
>

Basically, ALTER TABLE SET TABLESPACE, will register the
SYNC_UNLINK_REQUEST for the table files w.r.t the old tablespace, but
those will get unlinked during the next checkpoint.  Although the
files must be truncated during commit itself but unlink might not have
been processed until the next checkpoint.  This is the explanation for
the behavior you found during your investigation, but I haven't looked
into the issue so I will do it latest by tomorrow and send my
analysis.

Thanks for working on this.


-- 
Regards,
Dilip Kumar
EnterpriseDB: http://www.enterprisedb.com


Reply via email to