【问题标题】:PG::ConnectionBad: PQsocket() can't get socket descriptor: ROLLBACK on deleting recordPG::ConnectionBad:PQsocket() 无法获取套接字描述符:删除记录时 ROLLBACK
【发布时间】:2020-03-22 15:36:53
【问题描述】:

跑步:

Price.find(208999).delete

rails 控制台中,导致错误消息:

SQL (0.0ms)  DELETE FROM "prices" WHERE "prices"."id" = $1  [["id", 208999]]
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQsocket() can't get 
socket descriptor: DELETE FROM "prices" WHERE "prices"."id" = $1'

同一命令的后续重试会导致:

SQL (4.0ms)  DELETE FROM "prices" WHERE "prices"."id" = $1  [["id", 208999]]
ActiveRecord::StatementInvalid: PG::ConnectionBad: PQconsumeInput() server 
closed the connection unexpectedly
This probably means the server terminated abnormally
before or while processing the request.
: DELETE FROM "prices" WHERE "prices"."id" = $1

此时我无法运行任何查询命令而不会遇到此问题。在我运行删除之前,我可以删除另一个表上的另一个 SQL。

我已经尝试了与此错误相关的堆栈溢出的所有其他链接:

我没有设置任何 spec/rspec rake 任务,但是我尝试了 rails tmp:clear,其中指出,"# Clear cache and socket files from..."

我已经检查了这条记录是否与另一个表有任何关联,但是我的搜索没有返回任何内容。

【问题讨论】:

    标签: sql ruby-on-rails postgresql ruby-on-rails-5


    【解决方案1】:

    经过数小时的搜索...

    问题是在我的 price.rb 模型文件中,我声明了以下关系:

    class Price < ApplicationRecord
        belongs_to :card
    
        has_and_belongs_to_many :collections
    
        has_many :types
    
        class << self # Class methods
        end
    end
    

    我删除了 price.types 关联记录,但我没有反其道而行之,删除 card.prices 关联记录。

    所以我在哪里运行的命令:

    price = Price.find(208999)
    
    card = price.card
    
    #delete price_card association record
    card.prices.delete(price)
    
    #now i'll be able to delete the price record
    price.delete
    

    确实需要为此提供更好的错误消息,因为我一直在修改我的 database.yml 文件并重置我的套接字,因为这是错误消息让你相信的。

    希望这将在其他人开始搞乱数据库配置之前对其有所帮助。


    编辑 2

    刚刚又遇到了这个问题,我更新到最新版本的 PostgreSQL,即 12.4,因为我阅读了dba stackexchange answer,这是在我运行的 PostgreSQL 11 中发出 DELETE sql 命令时的常见问题。

    它并没有解决问题。

    下载并仔细查看 pgAdmin4 生成的日志文件后,我发现了对关系键的引用,因此我创建了一个小脚本来循环所有记录,并将任何外键值设置为 nil删除,它没有抛出任何令人讨厌的错误。

    Product.all.each do |product|
      product.update(cardset_id:nil,language_id:nil)
      product.delete
    end
    

    编辑 3

    所以我终于弄清楚了我的 PostgreSQL 数据库发疯的真正原因..

    我有一个名为 Cards 的表,其中有一个设置了 unique: true 选项的 slug 字段。

    在我的卡片模型中,我有一个函数

    extend FriendlyId
    friendly_id (:slug_id), use: :slugged
    
    def slug_id
        [
            [:name, :cardset_id],
        ]
    end
    

    通过名称和 cardset_id 的混合创建一个 slug,但是如果我想要同一记录的不同副本,出于某种原因创建相同的 slug id。

    当 PostgreSQL 去获取这条记录时,它会中断,因为数据没有意义,而且它本来就不应该存在。

    所以我的 slug 函数没有按预期运行有问题。

    在删除每条记录之前,我只是将 slug 设置为一个随机值,然后将其删除。

    【讨论】:

    • 当连接意外消失时,更好的错误信息从何而来?您不能通过不再存在的连接发送错误消息。无论发生什么,它都不像您的回答所暗示的那么简单。外键约束违规是例行公事,不应导致服务器崩溃。查看 PostgreSQL 服务器的日志文件以找到它报告的消息。
    • 您说得有道理,我会查看服务器日志以找出根本问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多