reorg / pg_repack

Reorganize tables in PostgreSQL databases with minimal locks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

version 1.5.0 pg_repack the pg_repack command returns an ERROR: the request was not executed: ERROR: the tablespace ""XXXX"" does not exist

976Evill opened this issue · comments

version 1.5.0 pg_repack the pg_repack command returns an ERROR: the request was not executed: ERROR: the tablespace ""XXXX"" does not exist

Steps for playback:
The name of the tablespace must start with a number. The error example is below:

CREATE A TABLESPACE "2c_cfs" AT THE LOCATION "/2c_cfs" WITH (compression=true);
CREATE THE appdb TABLESPACE OF THE "2c_cfs" DATABASE;

\c appdb
create the pg_repack extension;

CREATE A workbook TABLE (
PRIMARY KEY book_id INTEGER,
title text,
integer prices
);

INSERT INTO books(book_id, name, price)
values
('101', 'Jobs', '2000'),
('102', ' Gita', '250'),
('103', ' Ramayana', '354'),
('104', ' Vedas', '268');

delete from books;

pg_repack -U postgres -d appdb -t books --tablespace "2c_cfs" -e --elevation=debug

LOG: (query) SELECT THE pid FROM pg_locks, WHERE locktype = 'relation' And granted = false And relation = 16788 And mode = 'AccessExclusiveLock' AND pid <> pg_backend_pid()
DEBUGGING: There is no competing DDL to cancel.
LOG: (request) SET LOCAL lock_timeout = 100
LOG: (request) LOCK THE public.books TABLE IN SHARED ACCESS MODE
LOG: (request) RESET lock_timeout
LOG: (query) SELECT repack.create_table($1, $2)
LOG: (parameter:0) = 16788
journal: (parameter:1) = "2c_cfs"
ERROR: query failed: ERROR: tablespace ""2c_cfs"" does not exist
CONTEXT: SQL statement "CREATE A TABLE repack.table_16788 WITH A TABLESPACE (oids = false) " ""2c_cfs""" HOW TO SELECT book_id, name,price ONLY FROM public.books WITHOUT DATA"
Function PL/pgSQL repack.create_table(oid,name) line 3 when EXECUTING
DETAILS: the request was: SELECT repack.create_table($1, $2)
DEBUGGING: There are no work items to disable.
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (request) START ISOLATION LEVEL READING IS FIXED
LOG: (request) SAVE POINT repack_sp1
LOG: (request) SET LOCAL lock_timeout = 100
LOG: (request) LOCK THE public.books TABLE IN EXCLUSIVE ACCESS MODE
LOG: (request) RESET lock_timeout
LOG: (request) SELECT repack.repack_drop($1, $2)
LOG: (parameter:0) = 16788
LOG: (parameter:1) = 3
LOG: (request) COMMIT

Can you quote the original commands and result? Without strange rephrasing of commands syntax.

Well, --tablespace "2c_cfs" should be --tablespace 2c_cfs anyway

Yes, I'm sorry, extra characters were added during auto-translation

The problem seems to be in the new repack.create_table() function. There is an extra quote_ident().

postgres=#
postgres=# CREATE TABLESPACE 2c_cfs LOCATION '/2c_cfs';
ERROR: syntax error at or near "2"
LINE 1: CREATE TABLESPACE 2c_cfs LOCATION '/2c_cfs';
^
postgres=# CREATE TABLESPACE "2c_cfs" LOCATION '/2c_cfs';
CREATE TABLESPACE
postgres=# CREATE DATABASE appdb TABLESPACE "2c_cfs";
CREATE DATABASE
postgres=# \c appdb
You are now connected to database "appdb" as user "postgres".
appdb=# create extension pg_repack;
CREATE EXTENSION
appdb=# CREATE TABLE books (
appdb(# book_id INTEGER PRIMARY KEY,
appdb(# title TEXT,
appdb(# price INTEGER
appdb(# );
CREATE TABLE
appdb=# INSERT INTO books(book_id, title, price)
appdb-# VALUES
appdb-# ('101', 'Jobs', '2000'),
appdb-# ('102', 'Geeta', '250'),
appdb-# ('103', 'Ramayana', '354'),
appdb-# ('104', 'Vedas', '268');
INSERT 0 4
appdb=#
appdb=# delete from books;
DELETE 4
appdb=# \q
bash-4.2$ cd /opt/pgpro/ent-14/bin/
bash-4.2$ ./pg_repack -U postgres -d appdb -t books --tablespace "2c_cfs" -e --e level=debug
DEBUG: No workers to disconnect.
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) select spcname from pg_tablespace where spcname = $1
LOG: (param:0) = 2c_cfs
DEBUG: No workers to disconnect.
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) select repack.version(), repack.version_sql()
LOG: (query) SET statement_timeout = 0
LOG: (query) SET search_path = pg_catalog, pg_temp, public
LOG: (query) SET client_min_messages = warning
LOG: (query) SELECT r FROM (VALUES ($1, 'r')) AS given_t(r,kind) WHERE NOT EXIST S( SELECT FROM repack.tables WHERE relid=to_regclass(given_t.r)) AND NOT EXISTS ( SELECT FROM pg_catalog.pg_class c WHERE c.oid=to_regclass(given_t.r) AND c.re lkind = given_t.kind AND given_t.kind = 'p')
LOG: (param:0) = books
LOG: (query) SELECT t., coalesce(v.tablespace, t.tablespace_orig) as tablespace _dest FROM repack.tables t, (VALUES (quote_ident($1::text))) as v (tablespace) WHERE (relid = $2::regclass) ORDER BY t.relname, t.schemaname
LOG: (param:0) = 2c_cfs
LOG: (param:1) = books
INFO: repacking table "public.books"
DEBUG: ---- repack_one_table ----
DEBUG: target_name : public.books
DEBUG: target_oid : 16963
DEBUG: target_toast : 16966
DEBUG: target_tidx : 16967
DEBUG: pkid : 16968
DEBUG: ckid : 0
DEBUG: create_pktype : SELECT repack.create_index_type(16968,16963)
DEBUG: create_log : SELECT repack.create_log_table(16963)
DEBUG: create_trigger : CREATE TRIGGER repack_trigger AFTER INSERT OR DELETE OR UPDATE ON public.books FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger(' book_id')
DEBUG: enable_trigger : ALTER TABLE public.books ENABLE ALWAYS TRIGGER repack _trigger
DEBUG: create_table : SELECT repack.create_table($1, $2)
DEBUG: dest_tablespace : "2c_cfs"
DEBUG: copy_data : INSERT INTO repack.table_16963 SELECT book_id,title,p rice FROM ONLY public.books
DEBUG: alter_col_storage : (skipped)
DEBUG: drop_columns : (skipped)
DEBUG: delete_log : DELETE FROM repack.log_16963
DEBUG: lock_table : LOCK TABLE public.books IN ACCESS EXCLUSIVE MODE
DEBUG: sql_peek : SELECT * FROM repack.log_16963 ORDER BY id LIMIT $1
DEBUG: sql_insert : INSERT INTO repack.table_16963 VALUES ($1.
)
DEBUG: sql_delete : DELETE FROM repack.table_16963 WHERE (book_id) = ($1. book_id)
DEBUG: sql_update : UPDATE repack.table_16963 SET (book_id, title, price) = ($2.book_id, $2.title, $2.price) WHERE (book_id) = ($1.book_id)
DEBUG: sql_pop : DELETE FROM repack.log_16963 WHERE id IN (
DEBUG: ---- setup ----
LOG: (query) SELECT pg_try_advisory_lock($1, CAST(-2147483648 + $2::bigint AS in teger))
LOG: (param:0) = 16185446
LOG: (param:1) = 16963
LOG: (query) BEGIN ISOLATION LEVEL READ COMMITTED
LOG: (query) SET LOCAL lock_timeout = 100
LOG: (query) LOCK TABLE public.books IN ACCESS EXCLUSIVE MODE
LOG: (query) RESET lock_timeout
LOG: (query) SELECT pg_get_indexdef(indexrelid) FROM pg_index WHERE indrelid = $ 1 AND NOT indisvalid
LOG: (param:0) = 16963
LOG: (query) SELECT indexrelid, repack.repack_indexdef(indexrelid, indrelid, $2, FALSE) FROM pg_index WHERE indrelid = $1 AND indisvalid
LOG: (param:0) = 16963
LOG: (param:1) = (null)
DEBUG: index[0].target_oid : 16968
DEBUG: index[0].create_index : CREATE UNIQUE INDEX index_16968 ON repack.tabl e_16963 USING btree (book_id)
LOG: (query) SELECT repack.conflicted_triggers($1)
LOG: (param:0) = 16963
LOG: (query) SELECT repack.create_index_type(16968,16963)
LOG: (query) SELECT repack.create_log_table(16963)
LOG: (query) CREATE TRIGGER repack_trigger AFTER INSERT OR DELETE OR UPDATE ON p ublic.books FOR EACH ROW EXECUTE PROCEDURE repack.repack_trigger('book_id')
LOG: (query) ALTER TABLE public.books ENABLE ALWAYS TRIGGER repack_trigger
LOG: (query) SELECT repack.disable_autovacuum('repack.log_16963')
LOG: (query) BEGIN ISOLATION LEVEL READ COMMITTED
LOG: (query) SELECT pg_backend_pid()
DEBUG: LOCK TABLE public.books IN ACCESS SHARE MODE
LOG: (query) SELECT pid FROM pg_locks WHERE locktype = 'relation' AND granted = false AND relation = 16963 AND mode = 'AccessExclusiveLock' AND pid <> pg_backen d_pid()
DEBUG: No competing DDL to cancel.
LOG: (query) COMMIT
DEBUG: Waiting on ACCESS SHARE lock...
DEBUG: ---- copy tuples ----
LOG: (query) BEGIN ISOLATION LEVEL SERIALIZABLE
LOG: (query) SELECT set_config('work_mem', current_setting('maintenance_work_mem '), true)
LOG: (query) SELECT coalesce(array_agg(l.virtualtransaction), '{}') FROM pg_lo cks AS l LEFT JOIN pg_stat_activity AS a ON l.pid = a.pid LEFT JOIN pg_d atabase AS d ON a.datid = d.oid WHERE l.locktype = 'virtualxid' AND l.pi d NOT IN (pg_backend_pid(), $1) AND (l.virtualxid, l.virtualtransaction) <> (' 1/1', '-1/0') AND (a.application_name IS NULL OR a.application_name <> $2) AN D a.query !* E'^\s*vacuum\s+' AND a.query ! E'^autovacuum: ' AND ((d.dat name IS NULL OR d.datname = current_database()) OR l.database = 0)
LOG: (param:0) = 8942
LOG: (param:1) = pg_repack
LOG: (query) DELETE FROM repack.log_16963
LOG: (query) SELECT pid FROM pg_locks WHERE locktype = 'relation' AND granted = false AND relation = 16963 AND mode = 'AccessExclusiveLock' AND pid <> pg_backen d_pid()
DEBUG: No competing DDL to cancel.
LOG: (query) SET LOCAL lock_timeout = 100
LOG: (query) LOCK TABLE public.books IN ACCESS SHARE MODE
LOG: (query) RESET lock_timeout
LOG: (query) SELECT repack.create_table($1, $2)
LOG: (param:0) = 16963
LOG: (param:1) = "2c_cfs"
ERROR: query failed: ERROR: tablespace ""2c_cfs"" does not exist
CONTEXT: SQL statement "CREATE TABLE repack.table_16963 WITH (oids = false) TA BLESPACE """2c_cfs""" AS SELECT book_id,title,price FROM ONLY public.books WITH NO DATA"
PL/pgSQL function repack.create_table(oid,name) line 3 at EXECUTE
DETAIL: query was: SELECT repack.create_table($1, $2)
DEBUG: No workers to disconnect.
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) SET search_path TO pg_catalog, pg_temp, public
LOG: (query) BEGIN ISOLATION LEVEL READ COMMITTED
LOG: (query) SAVEPOINT repack_sp1
LOG: (query) SET LOCAL lock_timeout = 100
LOG: (query) LOCK TABLE public.books IN ACCESS EXCLUSIVE MODE
LOG: (query) RESET lock_timeout
LOG: (query) SELECT repack.repack_drop($1, $2)
LOG: (param:0) = 16963
LOG: (param:1) = 3
LOG: (query) COMMIT

Indeed, there is call of quote_ident() within repack_one_database() already:

" (VALUES (quote_ident($1::text))) as v (tablespace)"

I'd remove that call of quote_ident() from the C code and keep it in the SQL function for the sake of consistency, because that query of repack_one_database() doesn't call quote_ident() for any other identifiers.

As a temporary workaround you'd have to fix the repack.create_table() function and remove call of quote_ident().

I created a PR to fix the issue: #387.

Thanks @976Evill for the report. The PR #387 was merged. I'm closing this ticket, but feel free to re-open it if the issue is still persist.