Closed jensens closed 1 year ago
Plone 5.2.6 RelStorage = 3.4.5 psycopg2 = 2.9.3 with Docker image postgres:12
The first step would be to find out what temp_store
is, if it exists. It shouldn't exist outside the scope of a single postgresql connection used as a RelStorage store connection (it's a temporary table, deleted when the connection closes), so if you open a new database connection (eg using psql
) and can find the relation (not necessarily a table) temp_store
in the catalogs, that's Bad. The solution would probably be to remove that object.
If there is no object of that name in an unrelated connection, then the connection involved in the stack trace is being misused somehow. It's possible an earlier error occurred that wasn't handled correctly and the connection is being re-used in an invalid state (when it should have been closed, it was instead returned to a pool). We'd need to find that error.
I am connected with psql
and tried this:
temp_store
does not appear in SELECT typname FROM pg_catalog.pg_type;
nor in SELECT * FROM pg_catalog.pg_tables;
.
SELECT n.nspname AS schemaname, c.relname, c.relkind FROM pg_class c JOIN pg_namespace n ON n.oid = c.relnamespace WHERE relname = 'temp_store';
shows an empty result.
Next step: breakpoint before https://github.com/zodb/relstorage/blob/f3825ba8071d19719447f52062930ae2e7199d6a/src/relstorage/adapters/postgresql/mover.py#L95
Debugger:
(Pdb) l
90 FOR EACH ROW
91 EXECUTE PROCEDURE temp_blob_chunk_delete_trigger();
92 """,
93 ]
94 breakpoint()
95 -> for stmt in ddl_stmts:
96 cursor.execute(stmt)
97 cursor.connection.commit()
98
99 AbstractObjectMover.on_store_opened(self, cursor, restart)
100
(Pdb) for stmt in ddl_stmts: print(stmt)
CREATE TEMPORARY TABLE IF NOT EXISTS temp_store (
zoid BIGINT NOT NULL PRIMARY KEY,
prev_tid BIGINT NOT NULL,
md5 CHAR(32),
state BYTEA
) ON COMMIT DELETE ROWS;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_store_replacements (
zoid BIGINT NOT NULL PRIMARY KEY,
prev_tid BIGINT NOT NULL,
md5 CHAR(32),
state BYTEA
) ON COMMIT DELETE ROWS;
CREATE TEMPORARY TABLE IF NOT EXISTS temp_blob_chunk (
zoid BIGINT NOT NULL,
chunk_num BIGINT NOT NULL,
chunk OID,
PRIMARY KEY (zoid, chunk_num)
) ON COMMIT DELETE ROWS;
-- This trigger removes blobs that get replaced before being
-- moved to blob_chunk. Note that it is never called when
-- the temp_blob_chunk table is being dropped or truncated.
CREATE TRIGGER temp_blob_chunk_delete
BEFORE DELETE ON temp_blob_chunk
FOR EACH ROW
EXECUTE PROCEDURE temp_blob_chunk_delete_trigger();
And there seems to be no such table:
(Pdb) cursor.execute("DROP TABLE temp_store;")
*** psycopg2.errors.UndefinedTable: table "temp_store" does not exist
Workaround: A dump of the whole database and restore in an empty database "fixes" the problem.
pg_dump -h localhost -p 5432 -U plone -W plone > /var/lib/postgresql/data/dump.sql
Then keep dump.sql
, empty the whole storage folder, start with fresh dbinit from container, copy back dump.sql
and then
psql -h localhost -p 5432 -U plone -W plone < /var/lib/postgresql/data/dump.sql
Anyway, I am curious what's the real problem. At least I will keep a copy of the defect database for now and move on.
I missed in the original report where it said specifically that a type with the same name existed. That's very interesting, and I haven't seen that before.
(I'd also forgotten that we have the IF NOT EXISTS
clause in there, which would prevent table-to-table conflicts.) Thanks for pulling this all up.
I was never able to reproduce anything like this, so it seems like it was something "broken" in that environment's database, which makes it next to impossible to try to handle generically; closing.
I have no idea how to start debuggng this one, what can cause it? Looks like its Postgres related, so I start here. It appears while creating a new folder in Plone (like this traceback) but also if I want to create a new user.