Database PostgreSQL 8.3.11已锁定;孤立pg_toast数据库对象恢复

Database PostgreSQL 8.3.11已锁定;孤立pg_toast数据库对象恢复,database,postgresql,psql,vacuum,Database,Postgresql,Psql,Vacuum,你好,懒散的人 所以我遇到了一个运行8.3.11的PostgreSQL服务器(是的,我知道),它处于锁定状态,具有: ERROR: database is not accepting commands to avoid wraparound data loss in database "postgres" HINT: Stop the postmaster and use a standalone backend to vacuum that database. 通常情况下,自动真空守护程

你好,懒散的人

所以我遇到了一个运行8.3.11的PostgreSQL服务器(是的,我知道),它处于锁定状态,具有:

ERROR:  database is not accepting commands to avoid wraparound data loss in database "postgres"
HINT:  Stop the postmaster and use a standalone backend to vacuum that database.
通常情况下,自动真空守护程序(
autovacum=on
)会处理此问题,但由于以下四个TOAST(允许存储大字段值8KB的切片,如bread)是数据库对象。但由于这些损坏的数据库对象,该数据库的XID从未重置

以下是以单用户模式与管理员用户一起运行服务器时的输出片段:

SELECT oid, relname, age(relfrozenxid) FROM pg_class WHERE relkind = 't' ORDER BY age(relfrozenxid) DESC LIMIT 4;


    ----
     1: oid = "2421459"     (typeid = 26, len = 4, typmod = -1, byval = t)
     2: relname = "pg_toast_2421456"        (typeid = 19, len = 64, typmod = -1, byval = f)
     3: age = "2146484084"  (typeid = 23, len = 4, typmod = -1, byval = t)
    ----
     1: oid = "2421450"     (typeid = 26, len = 4, typmod = -1, byval = t)
     2: relname = "pg_toast_2421447"        (typeid = 19, len = 64, typmod = -1, byval = f)
     3: age = "2146484084"  (typeid = 23, len = 4, typmod = -1, byval = t)
    ----
     1: oid = "2421435"     (typeid = 26, len = 4, typmod = -1, byval = t)
     2: relname = "pg_toast_2421432"        (typeid = 19, len = 64, typmod = -1, byval = f)
     3: age = "2146484084"  (typeid = 23, len = 4, typmod = -1, byval = t)
    ----
     1: oid = "2421426"     (typeid = 26, len = 4, typmod = -1, byval = t)
     2: relname = "pg_toast_2421423"        (typeid = 19, len = 64, typmod = -1, byval = f)
     3: age = "2146484084"  (typeid = 23, len = 4, typmod = -1, byval = t)
请注意,此服务器上的年龄远高于
真空\u冻结\u分钟\u年龄
(在成功真空后设置的值),因此它会发出上述原始错误。上述操作是在运行
真空满压后进行的
;其他桌子都好

SELECT relfilenode FROM pg_class WHERE oid=2421459;
因此,当我们查看磁盘时(对上面的每个表使用pg_class.relfilenode值),toast表的文件丢失了:

$ find /var/lib/pgsql/data/ -type f -name '2421426' | wc -l  # Bad toast
0
当我们在磁盘上查看toast的索引时

 SELECT relfilenode FROM pg_class WHERE (select reltoastidxid FROM pg_class WHERE oid=2421459)

$ find /var/lib/pgsql/data/ -type f -name '2421459' | wc -l  # Bad toast's index
0
然后,我们试图找到与坏吐司记录相关的表:

SELECT * FROM pg_class WHERE reltoastrelid=2421459;
上面每个表都有0个结果!没有表可供
真空
命令重置这些关系的XID

当我们检查pg_depend表时,发现这些TOAST表没有引用:

SELECT * FROM pg_depend WHERE refobjid IN(2421459,2421450,2421435,2421426)
问题:
  • 可以从中删除坏的TOAST表和TOAST表索引吗 pg_类表(例如,
    从pg_类中删除,其中oid=2421459
  • 是否还有其他表需要删除该关系 从哪里来的
  • 我们可以创建一个临时表并将其链接到TOAST的 索引的oid
  • 上述第3项的示例:

    编辑:


    select txid\u current()
    是3094769499,所以这些表很久以前就损坏了。我们不需要恢复数据。我们正在Linux 2.6.18-238.el5上运行ext4文件系统。我们检查了相关的
    lost+found/
    目录,但文件不在那里。

    仅针对家庭观众,在这种特殊情况下,解决方案是直接编辑pg_类。当然,还要将服务器更新到受支持的Postgres版本

    具体答复:

  • 可以,不过在大多数情况下,最好创建一个空表,将toast关系附加到该表,添加pg_depend条目,然后删除该表。在本例中,这是没有意义的,因为实际上没有其他对象依赖于那些toast表

  • 通常,toast表在pg_索引中也有一个索引,pg_中的条目取决于。但事实并非如此

  • 见上文


  • 仅针对家庭观众,在这种特殊情况下,解决方案是直接编辑pg_类。当然,还要将服务器更新到受支持的Postgres版本

    具体答复:

  • 可以,不过在大多数情况下,最好创建一个空表,将toast关系附加到该表,添加pg_depend条目,然后删除该表。在本例中,这是没有意义的,因为实际上没有其他对象依赖于那些toast表

  • 通常,toast表在pg_索引中也有一个索引,pg_中的条目取决于。但事实并非如此

  • 见上文


  • 想知道在另一个Slack exchange社区中这样问是否更有意义,因为它是以
    数据库
    为中心的?想知道在另一个Slack exchange社区中这样问是否更有意义,因为它是以
    数据库
    为中心的?
    CREATE TABLE adoptedparent (colnameblah char(1));
    UPDATE pg_class SET reltoastrelid=2421459 WHERE relname='adoptedparent';  
    VACUUM FULL VERBOSE adoptedparent