【问题标题】:How do I solve this issue with gethostbyname_r and DBI or DBD::MySQL on FreeBSD?如何在 FreeBSD 上使用 gethostbyname_r 和 DBI 或 DBD::MySQL 解决这个问题?
【发布时间】:2010-09-28 13:35:58
【问题描述】:

我有一些旧的 perl 代码最近停止在 FreeBSD 机器上工作。失败的代码(最简单的形式)如下所示:

#!/usr/local/bin/perl -w

use strict;
use DBI;

my $datasource = "DBI:mysql:dbname:hostname.domain.com";
my $user = "username";
my $pass = "password";

DBI->connect($datasource, $user, $pass);

这会失败并出现以下错误:

/libexec/ld-elf.so.1: /usr/local/lib/mysql/libmysqlclient.so.15: Undefined symbol "gethostbyname_r"

如果我将数据源更改为引用“localhost”,则代码成功。

我已经从端口重新安装了 mysql-client、DBI 和 DBD-mysql;没有效果。

此服务器上的其他应用程序(PHP、命令行工具)能够通过主机名轻松访问 mysql 数据库。

关于如何解决这个问题的建议?

编辑添加:我注意到我的盒子有libmysqlclient.so.15libmysqlclient_r.so.15。问题可能是 DBD::mysql 在应该使用 libmysqlclient_r 时尝试使用 libmysqlclient 吗?如果是,如何解决?

【问题讨论】:

    标签: mysql perl dbi freebsd


    【解决方案1】:
    # ldd libmysqlclient.so.15
    libmysqlclient.so.15:
            libcrypt.so.3 => /lib/libcrypt.so.3 (0x281bf000)
            libm.so.4 => /lib/libm.so.4 (0x281d7000)
            libz.so.3 => /lib/libz.so.3 (0x281ed000)
    

    FreeBSD 6.4-p3,从端口安装 mysql-client,重新安装无济于事 ;(

    ldd 输出中没有 libc ;(

    但是mysql编译正确:

    # ldd mysql
    mysql:
            libreadline.so.6 => /lib/libreadline.so.6 (0x28089000)
            libncursesw.so.6 => /lib/libncursesw.so.6 (0x280b9000)
            libmysqlclient.so.15 => /usr/local/lib/mysql/libmysqlclient.so.15 (0x28102000)
            libcrypt.so.3 => /lib/libcrypt.so.3 (0x2815c000)
            libz.so.3 => /lib/libz.so.3 (0x28174000)
            libstdc++.so.5 => /usr/lib/libstdc++.so.5 (0x28185000)
            libm.so.4 => /lib/libm.so.4 (0x28250000)
            libc.so.6 => /lib/libc.so.6 (0x28266000)
            libncurses.so.6 => /lib/libncurses.so.6 (0x2834d000)
    

    【讨论】:

      【解决方案2】:

      在黑暗中拍摄:

      gethostbyname_r 表明 Perl 使用解析器代码的“可重入”(也称为线程/多线程)版本。好像有什么问题。

      从端口树编译依赖项时,您通常可以打开或关闭多线程。您可以在每个端口应用程序目录中使用 make config 更改您之前的选择。

      如果您安装了二进制包,则可能存在版本不匹配的地方。

      【讨论】:

      • 这听起来很合理,但我在任何相关端口上都没有看到这样的可调选项。
      • 哦,我不使用二进制包——所有东西都是从源代码编译的。
      • 查看我的问题底部的编辑,了解可能的线索。
      【解决方案3】:

      作为一种解决方法,尝试将 hostname.domain.com 添加到 /etc/hosts,或者在您的 Perl 代码中显式查找 IP 地址并改用它。

      【讨论】:

        【解决方案4】:

        暂时将/usr/local/lib/mysql/libmysqlclient.so.15/usr/local/lib/mysql/libmysqlclient.a 移开(重命名或其他)后,尝试从端口重新安装 DBD-mysql。这可能会强制 DBD-mysql 与 libmysqlclient_r 链接。

        【讨论】:

        • 不幸的是,当我这样做时,DBD::mysql 拒绝安装。
        • 再试一次,用 libmysqlclient.a 链接到 libmysqlclient_r.a。
        【解决方案5】:

        您的 libmysqlclient 版本对于您的操作系统版本已过期。由于它在 /usr/local 中,我假设它是从源代码编译的,而不是安装的。您可能可以通过重新编译来修复它,但您可能想查看是否有可以通过您的操作系统包管理器安装的受支持版本的 mysql。

        【讨论】:

        • 它已经重新编译没有效果,并且已经从FreeBSD端口安装,这应该表明它支持我的操作系统版本。另外,正如问题中提到的,PHP和命令行应用程序没有这个问题,只有perl。
        • php 和 perl 是否使用相同的 .so.15,或者 perl 是否与过时版本相关联?也许是 perl 需要升级?
        【解决方案6】:

        'gethostbyname_r' 是 GNU 扩展,不是 POSIX 标准的一部分。 不过,在我的 Freebsd 7 机器上,我的 libc 包含它:

        nm /usr/lib/libc.a | grep gethostbyname_r
        00000eb0 T gethostbyname_r
        

        你的 libc 是否包含这个符号?

        【讨论】:

        • 是:风险# nm /usr/lib/libc.a | grep gethostbyname_r 00000744 T gethostbyname_r
        • 那么你的 libmysqlclient 构建不正确。您应该尝试其他人的建议(重新编译端口等)。
        • 如前所述,我已经重新编译了几次端口,但没有任何效果。
        猜你喜欢
        • 1970-01-01
        • 2017-05-07
        • 2021-11-24
        • 1970-01-01
        • 2022-01-12
        • 1970-01-01
        • 2020-02-08
        • 2014-10-07
        • 1970-01-01
        相关资源
        最近更新 更多