在 Firebird 脚本中创建表会导致“元数据更新失败”并出现死锁

Posted

技术标签:

【中文标题】在 Firebird 脚本中创建表会导致“元数据更新失败”并出现死锁【英文标题】:Creating table in Firebird script causes "unsuccessful metadata update" with deadlock 【发布时间】:2015-02-11 02:39:27 【问题描述】:

我有以下使用“isql -i scriptfile.sql”运行的脚本:

CONNECT C:\Databasefile.fdb USER user PASSWORD password;

SET TERM !! ;
EXECUTE BLOCK AS BEGIN
IF (EXISTS(SELECT 1 FROM rdb$relations WHERE rdb$relation_name = 'MYTABLE')) THEN
EXECUTE STATEMENT 'DROP TABLE MYTABLE;';
END!!
SET TERM ; !!

CREATE TABLE MYTABLE 
(
  MYCOLUMN      VARCHAR(14) NOT NULL
);

我第一次运行此程序时(当表不存在时),表按预期创建。 如果我再次运行脚本,我会收到以下错误:

Statement failed, SQLCODE = -607
unsuccessful metadata update
-STORE RDB$RELATIONS failed
-deadlock
After line 8 in file d:\myscript.sql

当脚本退出时,MYTABLE 已被删除,无法再在数据库中找到。 如果我第三次运行该脚本,则会再次创建表并且不会引发任何错误。

为什么脚本不能同时删除然后重新创建表?

【问题讨论】:

【参考方案1】:

不允许来自 PSQL 的 DDL,使用 EXECUTE STATEMENT 不是直接禁止的,通常是可能的,但由于这类问题,仍然不明智。我不太确定原因,但部分原因与 DDL 更改在 Firebird 中的应用方式有关;使用 execute 语句会增加额外的锁 iirc,这会与相同表名的后续 DDL 冲突。

您应该使用 DDL 语句 RECREATE TABLE 而不是以这种方式删除和创建。

请注意,这个错误中的deadlock这个词实际上有点用词不当(没有真正的死锁)。

【讨论】:

RECREATE 似乎成功了。 ALTER TABLE 我刚刚在 RECREATE 之后添加一些外键约束似乎也有效。谢谢:) @GTHvidsten 不客气。请注意,您实际上不需要 alter table 来添加约束:您可以在(重新)创建表中执行此操作。 是的,我知道,但是从 Database Workbench 复制 DDL 很容易;)

以上是关于在 Firebird 脚本中创建表会导致“元数据更新失败”并出现死锁的主要内容,如果未能解决你的问题,请参考以下文章

AWS EMR - Hive在S3中创建新表会导致AmazonS3Exception:Bad Request

隐藏的工作表会导致Google表格的导出工作表作为PDF网址的输出损坏

我可以以编程方式退出 Firebird 脚本吗

无法使用 Psycopg2 在 Amazon Redshift 中创建表

从 Firebird 数据库中删除垃圾

在 Firebird 中创建一个整数时间戳