DEBUG.WIKI
晚安云;香港 CN2 ¥15/月
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
搬瓦工;先看线路,再选 VPS;CN2 GIA · 对应线路套餐;查看线路 →

Microsoft.Data.Sqlite 在 RHEL 8 报 GLIBC_2.33 not found,检查原生包版本

RHEL 8 上 e_sqlite3 文件存在却加载失败时,核对 SQLitePCLRaw 原生库的 glibc 需求;2.1.14 已为旧 Linux 兼容发布修正,重新发布并在目标环境验证。

更新 Microsoft.Data.Sqlite 后,应用还没打开数据库,就在 SqliteConnection 的类型初始化中失败:

DllNotFoundException: Unable to load shared library 'e_sqlite3'
/lib64/libc.so.6: version `GLIBC_2.33' not found
(required by /app/libe_sqlite3.so)

这里已经出现了实际的 libe_sqlite3.so 路径。它可能并不缺文件,而是该文件要求的 glibc 符号比运行系统新。继续把同一份 .so 复制到更多目录,并不能让旧 libc 提供这些符号。

明确的故障涉及 .NET 10、Microsoft.Data.Sqlite 10.0.11 及其带入的 SQLitePCLRaw 2.1.12,运行在 glibc 2.28 的 RHEL 8 或兼容环境中。SQLitePCLRaw 2.1.13 也有相同平台兼容反馈;不要把 .NET 支持某个系统,推导为每一个第三方原生产物都使用相同 ABI 基线。

查看部署中的原生依赖,不只看托管包

先在目标运行环境记录 glibc 版本,并检查发布目录实际使用的包来源。例如:

getconf GNU_LIBC_VERSION
dotnet list path/to/App.csproj package --include-transitive

第二条针对源工程,路径替换成真实项目;它不能单独证明服务器正在运行哪份旧发布目录。还要核对恢复锁文件、RID、发布日志及实际的 runtimes/linux-x64/native 资产。

对于可信的自有发布库,可用 objdump -T 查看它引用的 GLIBC_ 符号版本。不同原生资产可能报 2.33 或其他更高要求,不应把报错里的一个版本数字当成所有包和架构的统一最低值。也要区分 glibc 与 musl,不能给 Alpine 随意复制一个 glibc 资产。

采用针对旧 Linux 兼容性的 2.1.14 修正

SQLitePCLRaw 2.1.14 已作为正式 NuGet 包发布,目的是恢复 .NET 10 所需的旧 Linux 兼容。对于仍使用 2.1 系列 bundle 的项目,可显式选择该版本,再核对最终解析结果:

<PackageReference Include="SQLitePCLRaw.bundle_e_sqlite3"
                  Version="2.1.14" />

这段放入项目已有的 ItemGroup。使用 Central Package Management 时,版本应放在 Directory.Packages.props,项目保留不带版本的引用,不能把两套管理方式混用。

恢复后检查 provider 与 native lib 没有继续被其他直接依赖固定到旧版,重新生成原 RID 的发布产物,再在目标 RHEL 8 环境验证。只在新系统上成功运行,不足以覆盖旧 glibc 的兼容边界。

若工程已经选择 SQLitePCLRaw 3.x 或自定义 SQLite 提供程序,不要强行加入另一套 2.1 bundle。应按现有 provider 的包布局选择包含兼容修正的原生资产,并保留扩展、加密和线程配置需求。

不要为一个库替换系统 libc

手工覆盖 RHEL 的 glibc 会影响整机程序;把新 libc 塞进全局动态库路径,也可能改变其他依赖。应优先修正应用的原生产物,或在有明确迁移计划时更新运行基础镜像。

回退到 2.1.11 虽可能避开加载错误,却会撤回后续 SQLite 安全修正,不能作为默认长期方案,也不应全局压掉 NuGet 降级警告。

验收使用隔离数据库,确认原生库可加载、连接能打开、必要 SQL 与扩展可执行;然后核对原应用发布方式。此类类型初始化失败通常早于业务 SQL,看到它消失不等于现有数据库已经完成迁移,也不需要因此删除数据库文件。