dotnetcore / FreeSql

🦄 .NET aot orm, C# orm, VB.NET orm, Mysql orm, Postgresql orm, SqlServer orm, Oracle orm, Sqlite orm, Firebird orm, 达梦 orm, 人大金仓 orm, 神通 orm, 翰高 orm, 南大通用 orm, 虚谷 orm, 国产 orm, Clickhouse orm, DuckDB orm, TDengine orm, QuestDB orm, MsAccess orm.
https://dotnetcore.github.io/FreeSql/
MIT License
4.1k stars 857 forks source link

freesql 3.2.661 #1146

Closed Dvrsty closed 2 years ago

Dvrsty commented 2 years ago
  1. 首先感谢作者的辛勤付出
  2. 随着业务量的增加, 出现不稳定情况

运行环境 net6, k8s(pod数10~30, 4CPU, 8G内存), mysql 8.0(52核, 128G内存)

问题反馈

  1. 高并发时, 部分POD读取到旧数据, 这种情况一般发生在POD CPU突然增高的情况下发生, 持续时间为1-7分钟的数据延迟. 1) 已排除数据库多节点同步延迟的问题 2) 已排除因为程序代码事务未提交造成的问题 3) 已排除Nginx缓存问题 4) 已排除程序接口缓存问题 目前解决办法是, 将原有的 UseConnectionString(DataType.MySql, connStr) 更换为 UseConnectionFactory(DataType.MySql, () => new MySqlConnection(connectionStrings)), 目前已观察了两天, 未发生以上反馈的问题

  2. 在已存在的表中增加字段, 字段属性设置为: [Column(IsIdentity = true, IsPrimary = false)], 并且增加唯一索引. 此时表的主键会被移除, 并增加到新字段上. 经过测试, 如果表是全新创建, 不会有类似问题, 只有在已经存在数据的表上添加类似属性会发生这种情况. 目前解决办法是, 等字段类型更改完成后, 手动更改primary的指向.

2881099 commented 2 years ago
  1. 数据延迟是什么意思,具体环境是什么
  2. IsIdentity false 确实会有这个限制,一开始了解到的信息是 mysql isidentity 只能用在主键,创建新表也是后来 pr 进来的,等有时间再整理之下这块
2881099 commented 2 years ago

问题1,是不是云数据库集群,可能域名解析到了新的 node,但是 freesql 还在读取旧的 node 数据

Dvrsty commented 2 years ago

问题1,是不是云数据库集群,可能域名解析到了新的 node,但是 freesql 还在读取旧的 node 数据

这个问题已经排除了, 问题反馈已排除项的第一条. 具体是之前使用阿里云polardb, 1个主库, 8个从库, 开先也以为是这个问题, 所以现在迁移到mysql的单节点数据库上, 问题依旧存在. 很奇怪, 按照我上面的方法, 完美的解决了这个问题, 没有再出现这种情况. 至于具体环境, 上面的运行环境算是吧?

Dvrsty commented 2 years ago

问题1,是不是云数据库集群,可能域名解析到了新的 node,但是 freesql 还在读取旧的 node 数据

通过源码我并没能从本地测试环境中还原出这样的问题, 并且这个问题仅存在CPU较高的POD上, 通过线上的日志发现CPU高于80%的时候, 极其容易出现类似情况.

Dvrsty commented 2 years ago

具体环境 net 6.0.300 mysql RDS 8.0 小版本信息 rds_20220331 52核 128G内存 ask POD 10-30, 4核 8G

使用到的包 FreeSql 3.2.661 FreeSql.Extensions.JsonMap 3.2.661 FreeSql.Provider.MySql 3.2.661 FreeSql.Repository 3.2.661 FreeSql.DynamicProxy 1.5.0

2881099 commented 2 years ago

mysql rds 版本,可能就是我所描述的原因了。

它内部其实是集群,即每次通过 ado.net 连接域名,可能指向的 ip 都不一样。

如果使用=连接池,可能导致旧的连接对象仍然连接到了旧的 ip。

Dvrsty commented 2 years ago

mysql rds 版本,可能就是我所描述的原因了。

它内部其实是集群,即每次通过 ado.net 连接域名,可能指向的 ip 都不一样。

如果使用=连接池,可能导致旧的连接对象仍然连接到了旧的 ip。

那这个方法是否能确保每次连接都能连接到最新的ip上? UseConnectionFactory(DataType.MySql, () => new MySqlConnection(connectionStrings))

或者是说这个方法, 每次请求都会建立新的连接?

2881099 commented 2 years ago

取决于 connectionString 有没有开启连接池技术,如果没有开启每次会建立新的连接。