我不小心从pg_class
删除了一个表,并且我在模式中的不同服务器中存在相同的表。我该如何恢复它?
我试过这个
psql -U {user-name} -d {desintation_db} -f {dumpfilename.sql}`
这就是我得到的 -
ERROR: type "food_ingredients" already exists`
HINT: A relation has an associated type of the same name, so you must use a name that doesn't conflict with any existing type.`
ERROR: relation "food_ingredients" does not exist`
ERROR: syntax error at or near "19411"`
LINE 1: 19411 10405 2074 45.3333333333 0.17550085492131515 NULL NULL...`
ERROR: relation "food_ingredients" does not exist`
food_ingredients
是我从pg_class中删除的表。
答案 0 :(得分:0)
这就是你弄乱系统目录所得到的。
简单而正确的答案是“从备份中恢复”,但有些事情告诉我,这不是您正在寻找的答案。
您可以删除属于该表的类型,表上的所有索引,所有约束,Toast表等等,但您可能忘记删除某些内容或删除不应该删除的内容,最后使用比以前更糟糕了。
此外,表文件将被遗忘,并且很难识别和删除它。
尝试重新创建您删除的pg_class
行会很有吸引力,但是您无法使用正确的oid
创建它,因为您无法直接插入某个oid
或者更新该列。
您可以使用pg_dumpall
转储整个数据库群集,使用initdb
创建新群集并在那里恢复备份,但由于数据不一致,这可能会失败。
真的,最好的办法是恢复备份。
答案 1 :(得分:0)
我能够使用pg_dirtyread扩展名执行部分还原。
最初的情况是:
undefind
以下查询向我提供了我删除的值:
relation "messed_table" does not exist`
我将结果用于执行INSERT:
SELECT * FROM pg_dirtyread('pg_class'::regclass)
as t(relname name, relnamespace oid, reltype oid, reloftype oid, relowner oid, relam oid, relfilenode oid, reltablespace oid, relpages integer, reltuples real, relallvisible integer, reltoastrelid oid, relhasindex boolean, relisshared boolean, relpersistence "char", relkind "char", relnatts smallint, relchecks smallint, relhasoids boolean, relhaspkey boolean, relhasrules boolean, relhastriggers boolean, relhassubclass boolean, relrowsecurity boolean, relforcerowsecurity boolean, relispopulated boolean, relreplident "char", relispartition boolean, relfrozenxid xid, relminmxid xid, relacl aclitem[], reloptions text[], relpartbound pg_node_tree)
WHERE relname = 'messed_table';
在此阶段,执行INSERT INTO pg_class
(relname,relnamespace,reltype,reloftype,relowner,relam,relfilenode,reltablespace,relpages,reltuples,relallvisible,reltoastrelid,relhasindex,relisshared,relpersistence,relkind,relnatts,relchecks,relhasoids,relhaspkey,relhasrules,relhastriggers,relhassubclass,relrowsecurity,relforcerowsecurity,relispopulated,relreplident,relispartition,relfrozenxid,relminmxid,relacl,reloptions,relpartbound)
VALUES('messed_table',16447,17863,0,10,0,17861,0,0,0,0,0,false,false,'p','r',78,0,false,false,false,false,false,false,false,true,'d',false,1129231::text::xid,1::text::xid,null,null,null);
返回
SELECT * from messed_table
因此,我创建了一个新表catalog is missing 78 attribute(s) for relid 26130
,其结构与混乱表相同。
我使用以下查询将messed_table_copy
表的pg_attribute
内容导出到文件中:
messed_table_copy
我将Copy (SELECT * FROM pg_attribute WHERE attrelid = (SELECT oid from pg_class WHERE relname LIKE 'messed_table_copy') and attnum > 0) To '/tmp/recover.csv' With CSV DELIMITER ',' HEADER;
的值更改为错误消息中指出的attrelid
的值,然后再次从文件中导入了数据:
relid
在此阶段,COPY pg_attribute(attrelid,attname,atttypid,attstattarget,attlen,attnum,attndims,attcacheoff,atttypmod,attbyval,attstorage,attalign,attnotnull,atthasdef,attidentity,attisdropped,attislocal,attinhcount,attcollation,attacl,attoptions,attfdwoptions) FROM '/tmp/recover.csv' DELIMITER ',' CSV HEADER;
工作正常,但是SELECT count(*) FROM messed_table
使数据库崩溃,并出现以下错误:
SELECT * FROM messed_table
执行一些仅指定所有可用列子集的查询,我注意到仅选择某些列会发生崩溃。我已经能够恢复大约90%的数据,丢失了某些列的内容。祝您好运,切记不要再玩server closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
The connection to the server was lost. Attempting reset: Failed.
表了。