尝试删除条目时收到System.IO.IOException

时间:2019-03-28 11:55:41

标签: c# postgresql foreign-keys sql-delete npgsql

我有一个包含60个表的数据库。一个是表person,该表还被大量其他表(大约40个)引用,大部分使用ON DELETE CASCADE ON UPDATE CASCADE

使用Npgsql,我尝试运行以下命令: DELETE FROM person WHERE id = @PersonId

结果是我收到System.IO.Exception:

  

Npgsql.NpgsqlException(0x80004005):从流中读取时发生异常---> System.IO.IOException:Von derÜbertragungsverbindungkönnenkeine Daten gelesen werden:Ein Verbindungsversuch ist fehlgeschlagen,Gegenstelle nach hatitspannermm ,或从hergestellte Verbindung战役中撤离,由und verbundene主持人提供。 ---> System.Net.Sockets.SocketException:Ein Verbindungsversuch ist fehlgeschlagen,Gegenstelle nach einer bestimmten Zeitspanne nicht richtig reagiert hat,oder die hergestellte Verbindung war fehlerhaft,da der verbundene Host nicht reagiert hatt      bei System.Net.Sockets.Socket.Receive(Byte []缓冲区,Int32偏移量,Int32大小,SocketFlags socketFlags)      bei System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)      --- Ende der internenAusnahmestapelüberwachung---      bei System.Net.Sockets.NetworkStream.Read(Byte []缓冲区,Int32偏移量,Int32大小)      bei Npgsql.NpgsqlReadBuffer。<> c__DisplayClass31_0。 d.MoveNext()      bei Npgsql.NpgsqlReadBuffer。<> c__DisplayClass31_0。 d.MoveNext()   --- Ende derStapelüberwachungvom vorhergehenden Ort,奥斯曼·奥斯格洛斯特·伍德      bei System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务)      bei System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务)      bei Npgsql.NpgsqlConnector。<> c__DisplayClass161_0。 d.MoveNext()

在英语中,内部例外是

  

Npgsql.NpgsqlException(0x80004005):从中读取时发生异常   流---> System.IO.IOException:无法从   传输连接:连接尝试失败,因为   一段时间后,远程站未正确响应   时间或建立的连接有问题,因为连接的主机   没有回应。 ---> System.Net.Sockets.SocketException:连接   尝试失败,因为远程站未正确响应   经过一定时间后,或者连接失败,原因是   连接的主机未响应System.Net.Sockets。   Socket.Receive(字节[]缓冲区,Int32偏移量,Int32大小,SocketFlags   System.Net.Sockets.NetworkStream.Read中的socketFlags)(字节[]缓冲区,   Int32偏移量,Int32大小)---内部异常堆栈跟踪结束

在Postgres日志中显示:

  

2019-03-28 12:42:15.077 CET [75060]日志:konnte Daten vom Client nicht empfangen:无法识别的winsock错误10053

我想这不是死锁,因为日志中没有死锁消息。

我认为这与表被众多外键引用这一事实有关。但是我不知道如何进一步调查。

2 个答案:

答案 0 :(得分:3)

作为例外,此问题与长时间运行的脚本超时有关。您没有包括代码示例,因此我无法专门提供语法来增加此示例,但是设置commandTimeout = 0将禁用超时并解决问题。

要在评论中解决您的问题,

  

有什么方法可以调查为什么需要这么长时间?

它可能只是删除大量记录。您应该在C#之外运行查询,以确保在将查询插入代码之前对查询进行了优化。

删除大量记录可能需要一段时间,您应该研究truncate或其他清除设计,例如转储到临时表等。

答案 1 :(得分:1)

我的钱花在引用person的外键上缺少索引上。

如果您有一个这样的表:

CREATE TABLE atable (
   id bigint PRIMARY KEY,
   parent_id bigint NOT NULL
      REFERENCING parent ON DELETE CASCADE
);

,并且该表包含很多行,那么在person中删除的每一行将导致对atable进行顺序表扫描以找到匹配的行。那可能就是您所有时间都用在的地方。

在所有引用person的表上创建索引:

CREATE INDEX ON atable (parent_id);

这将使删除速度更快。

This blog post详细说明了问题。