错误:无法在只读事务中执行CREATE TABLE操作。

57

我正在尝试在我的本地机器上设置 pgexercises 数据。当我运行以下命令时:psql -U <username> -f clubdata.sql -d postgres -x 我收到错误信息:psql:clubdata.sql:6: ERROR: cannot execute CREATE SCHEMA in a read-only transaction

为什么它在我的本地机器上创建了只读数据库?我能改变这个吗?


你使用的是哪个用户名?这个用户有哪些访问权限?能创建数据库吗? - Renzo
在我的情况下,我有另一个在screen中运行的psql -f进程。启动另一个psql -f(即使使用不同的-h)也会给我带来你描述的错误。在这种情况下,您必须等待第一个psql进程完成,或者使用不同的主机来运行第二个psql命令。 - OrangePot
我知道这不是一个通用的解决方案,但当我遇到这个问题时,我无意中连接到了我的主数据库的只读副本。当我尝试使用 set transaction read write; 时,我收到了错误消息 cannot set transaction read-write mode during recovery - Andrew Rueckert
16个回答

51

通常,这种错误的最合理原因是:

  • 在只读副本上尝试创建语句(整个实例都是只读的)。

  • <username>default_transaction_read_only 设置为 ON。

  • 数据库的 default_transaction_read_only 设置为 ON。

所提到的脚本在其前几行中有:

CREATE DATABASE exercises;
\c exercises
CREATE SCHEMA cd;

并且您报告说错误发生在第6行的CREATE SCHEMA之后,而不是之前。

这意味着当使用<username>运行时,CREATE DATABASE确实有效。 如果上述任何原因直接适用,则无法正常工作。

一个可能的技术解释是,在postgresql.conf文件中default_transaction_read_only设置为ON,并且对于数据库postgres将其设置为OFF,即psql调用连接到的数据库,通过ALTER DATABASE语句覆盖了配置文件。

这就是为什么CREATE DATABASE有效,但是一旦连接到具有\c的不同数据库,会话的default_transaction_read_only设置将翻转为ON

但是这当然是相当奇怪和不寻常的配置。


查看了我的postgresql.conf文件,发现default_transaction_read_only设置为off。 - ltrainpr

32

我遇到了“无法在只读事务中执行CREATE TABLE”、“无法在只读事务中执行DELETE TABLE”和其他类似的问题。

这些问题都是由于“无法在只读事务中执行INSERT”引起的。就好像连接在批处理过程中自动切换为只读一样。

后来发现,这是由于存储空间不足导致的

当数据库不能再写入任何内容时,写入访问权限将被禁用。我在Azure上使用Postgres。如果我使用专用服务器,我不知道是否会出现相同的效果。


6
这也是我的问题,但解决方案不在这里。例如,对于任何使用DigitalOcean的人,请使用SET default_transaction_read_only = OFF; - Mdev
还有在Azure上的Postgres,灵活服务器。在我进行任何清理以腾出存储空间之前,我不得不重新启动服务器以清除整个数据库的只读属性。 - undefined

31

我联系了pgexercises.com,他们帮我解决了问题。

我分别运行了以下命令:

psql -U <username> -d postgres
begin;
set transaction read write;
alter database exercises set default_transaction_read_only = off;
commit;
\q

然后我从终端中删除了数据库dropdb exercises,并再次运行脚本psql -U <username> -f clubdata.sql -d postgres -x -q


实际上这个解决方案可行!我在Heruko应用程序中完成了这个操作,但是不需要凭据。只需从“开始”即可。 - muhammad tayyab

11

我在更新Postgre语句时遇到了同样的问题。

SQL Error: 0, SQLState: 25006 ERROR: cannot execute UPDATE in a read-only transaction

通过运行以下查询验证 数据库 访问,它将返回 truefalse

SELECT pg_is_in_recovery()

true -> 数据库仅具有读取权限

false -> 数据库具有完全访问权限

如果返回true,则需与数据库管理员团队核实完全访问权限,并尝试在命令提示符中进行ping,确保连接正常。

ping <database hostname or dns>

请确认您的数据库是否有主节点和备用节点。


5

Dbeaver:在我的情况下

输入图像描述

这是开启的。


4

我的情况是有一个主节点和一个复制节点,主节点成为了复制节点,这将它切换到hot_standby模式。因此,我在尝试向一个只能用于读取的节点写入数据,所以出现了“只读”问题。

您可以使用SELECT pg_is_in_recovery()查询相关节点,如果它返回True,则该节点为“只读”,我想您应该切换到目前使用的主节点。

我得到这些信息来源于:https://serverfault.com/questions/630753/how-to-change-postgresql-database-from-read-only-to-writable。所以我要感谢 Craig Ringer 并给予完整的认可!


2

1
这并没有完全回答原问题,但我遇到了同样的错误并找到了这个页面,最终解决了问题。
我的问题是尝试运行一个创建和删除临时表的函数。该函数使用SECURITY DEFINER特权创建,并且用户在本地具有访问权限。
在另一个环境中,我收到了cannot execute DROP TABLE in a read-only transaction错误消息。这个环境是AWS Aurora,默认情况下,非管理员开发人员只有只读权限。因此,他们的服务器连接被设置为使用Aurora的只读节点(连接URL中带有-ro-),这必须将连接置于只读状态。对写节点使用相同的用户运行相同的函数可以正常工作。
看起来这是SQL Server的表变量的一个很好的用例!或者至少,AWS应该修改他们的流程,允许在只读节点上创建和删除临时表。

0
如果你和我一样正在尝试在Heroku上创建数据库,但是在数据剪辑选项卡中出现了这个消息而卡住了,那么请看我是如何解决的。
Choose Resources from(Overview Resources Deploy Metrics Activity Access Settings)

Choose Settings out of (Overview, Durability, Settings, Dataclip)

Then in Administration->Database Credentials choose View Credentials...

然后打开终端,在此处填写信息并输入

psql --host=***************.amazonaws.com --port=5432 --username=*********pubxl --password --dbname=*******lol

然后它会要求输入密码,复制粘贴即可运行Postgres命令。


0

我刚刚遇到了这个错误。我的原因是没有授予 SEQUENCE 权限。

GRANT ALL ON SEQUENCE word_mash_word_cube_template_description_reference_seq TO ronshome_user;

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接