You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Concurrent DMLs were executing during the repack process and they failed with error that the table repack.log_26813 didn't exist.
2024-04-1101:27:50.933 UTC 33214 ddl_full0 42P01 2356 ERROR: relation "repack.log_26813" does not exist at character 132024-04-1101:27:50.933 UTC 33214 ddl_full0 42P01 2356 QUERY: INSERT INTOrepack.log_26813(pk, row) VALUES(CASE WHEN $1 IS NULL THEN NULL ELSE (ROW($1.id, $1.e)::repack.pk_26813) END, $2)
2024-04-1101:27:50.933 UTC 33214 ddl_full0 42P01 2356 STATEMENT: DELETEFROM t1 WHERE id BETWEEN ($1)::INTEGERAND ($2)::INTEGER;
I found log records of creating the log table but, the table's name was repack.log_26797 instead of repack.log_26813, referencing t2 instead of t1:
2024-04-1101:27:50.070 UTC 35477 ddl_full0 000002328 CONTEXT: SQL statement "CREATE TABLE repack.log_26797 (id bigserial PRIMARY KEY, pk repack.pk_26797, row normal.t2)"
Its the name for repack.table_26797 and it also referenced t2, not t1:
2024-04-1101:27:50.698 UTC 35477 ddl_full0 000002346 CONTEXT: SQL statement "CREATE TABLE repack.table_26797 WITH (toast_tuple_target=128, oids = false) TABLESPACE pg_default AS SELECT id,unique1,hundred,tenthous,a,b,c,d,f_char,g_vchar,h_bool,i_enum,j_array_bigint,extra,e FROM ONLY normal.t2 WITH NO DATA"
In the repack_one_table function, while reading configs from the repack.tables view, it used the t1 table to filter. However, when it came time to actually create the log table, it had changed to t2.
2024-04-1101:26:26.524 UTC 35477 ddl_full0 000000 LOG: execute <unnamed>: /*pg_catalog, pg_temp, public*/SELECT t.*, coalesce(v.tablespace, t.tablespace_orig) as tablespace_dest FROMrepack.tables t, (VALUES (quote_ident(NULL::text))) as v (tablespace) WHERE (relid = $$normal.t1$$::regclass) ORDER BYt.relname, t.schemaname
The reason for t1 becoming t2 was due to concurrent DDLs I ran on my testing system, and one of the table renaming tests had swapped t1 and t2:
2024-04-1101:27:49.690 UTC 33232 ddl_full0 000002198 LOG: execute <unnamed>: /*normal, public*/ DO $$
BEGINDROPTABLE IF EXISTS t2_tmp;
ALTERTABLE t2 RENAME TO t2_tmp;
DROPTABLE IF EXISTS t2;
ALTERTABLE t1 RENAME TO t2;
DROPTABLE IF EXISTS t1;
ALTERTABLE t2_tmp RENAME TO t1;
END $$;
Maybe the root cause is that the functions repack.create_log_table and repack.create_table accept an OID parameter, and the OID is only converted to a table name by the repack.oid2text function when the CREATE TABLE statement is actually executed. The OID is still that of the old t1 table, but by the time repack.oid2text is executed, this OID belongs to the new t2.
CREATEFUNCTIONrepack.create_log_table(oid) RETURNS void AS
$$
BEGIN
EXECUTE 'CREATE TABLE repack.log_'|| $1||' (id bigserial PRIMARY KEY,'||' pk repack.pk_'|| $1||','||' row '||repack.oid2text($1) ||')';
END
$$
LANGUAGE plpgsql;
CREATEFUNCTIONrepack.create_table(oid, name) RETURNS void AS
$$
BEGIN
EXECUTE 'CREATE TABLE repack.table_'|| $1||' WITH ('||repack.get_storage_param($1) ||') '||' TABLESPACE '|| quote_ident($2) ||' AS SELECT '||repack.get_columns_for_create_as($1) ||' FROM ONLY '||repack.oid2text($1) ||' WITH NO DATA';
END
$$
LANGUAGE plpgsql;
Such a case is unlikely in the actual use of pg_repack because it's too extreme. However, since I've encountered this issue, I decided to report it for a better pg_repack. Thanks.
The text was updated successfully, but these errors were encountered:
I executed the following command with pg_repack v1.5.0 on PG14:
Concurrent DMLs were executing during the repack process and they failed with error that the table repack.log_26813 didn't exist.
I found log records of creating the log table but, the table's name was repack.log_26797 instead of repack.log_26813, referencing t2 instead of t1:
Its the name for repack.table_26797 and it also referenced t2, not t1:
In the
repack_one_table
function, while reading configs from the repack.tables view, it used the t1 table to filter. However, when it came time to actually create the log table, it had changed to t2.The reason for t1 becoming t2 was due to concurrent DDLs I ran on my testing system, and one of the table renaming tests had swapped t1 and t2:
Maybe the root cause is that the functions
repack.create_log_table
andrepack.create_table
accept an OID parameter, and the OID is only converted to a table name by therepack.oid2text
function when theCREATE TABLE
statement is actually executed. The OID is still that of the old t1 table, but by the timerepack.oid2text
is executed, this OID belongs to the new t2.Such a case is unlikely in the actual use of pg_repack because it's too extreme. However, since I've encountered this issue, I decided to report it for a better pg_repack. Thanks.
The text was updated successfully, but these errors were encountered: