【问题标题】:Setting PostgreSQL application_name on Heroku在 Heroku 上设置 PostgreSQL application_name
【发布时间】:2013-03-21 11:54:35
【问题描述】:

application_name 是 PostgreSQL 特定的连接参数,每个客户端可以(并且应该)在连接时设置。它稍后会帮助 DBA 和操作人员将行为不端的查询与特定的应用程序代码相关联。

这个 SO 问题解释了how to set application_name using SQLAlchemy,但不幸的是,它在 Heroku 上不起作用,因为在 PostgreSQL 8.5 分支(仅作为 9.0 发布)上添加了设置 application_name,而Heroku dynos 上安装的 PostgreSQL 客户端库 (libpq) 是从 PostgreSQL 8.4.9 构建的。

如何在 Heroku 上设置 application_name?

【问题讨论】:

    标签: heroku postgresql-9.1 buildpack


    【解决方案1】:

    据我所知,only 解决方案是将vendor 更新版本的libpq 放入您的 slug。

    我的目标包是libpq5 和libpq-dev,它们是从源包postgresql-9.1 构建的。 为了节省大量工作,如果您信任我的二进制文件,您可以直接跳到第 8 步并使用我制作的预构建二进制文件 libpq。不不,不要感谢我。

    1. 使用 vanilla 12.04 启动新 VM
    2. sudo apt-get update
    3. apt-get source postgresql-9.1(您可能需要先sudo apt-get install dpkg-src)
    4. 在提取的源代码中,查看rules 文件(postgresql-9.1-9.1.8/debian/rules,如果precise-updates 仍在 PostgreSQL 9.1.8 中)。
    5. 从规则文件中,我认为我们应该用于构建 libpq 的配置选项是:

      LDFLAGS="-Wl,--as-needed -Wl,-z,now" \
      CFLAGS="-fPIC -DLINUX_OOM_ADJ=0" \
      ./configure --prefix=/app/vendor \
        --enable-integer-datetimes \
        --enable-thread-safety \
        --enable-debug \
        --disable-rpath \
        --with-gnu-ld \
        --with-pgport=5432 \
        --with-system-tzdata=/usr/share/zoneinfo \
        --without-tcl \
        --without-perl \
        --without-python \
        --with-krb5 \
        --with-gssapi \
        --with-openssl \
        --with-libxml \
        --with-libxslt \
        --with-ldap
      

      请注意,我删除/否定了--enable-nls --with-ossp-uuid --with-tcl --with-perl --without-python --with-pam,因为在 Heroku dyno 上它们会导致配置/构建失败。我不需要它们中的任何一个,我不确定它们是否会影响libpq5,我怀疑它们在测功机上非常需要,如果您觉得不一样,请享受修复它的乐趣,我向您致敬好先生。

    6. make && make install

    7. 现在所有的 postgresql 都安装到了/vendor。我们需要获取的文件在postgresql-9.1-9.1.8/debian/libpq5.install 和postgresql-9.1-9.1.8/debian/libpq-dev.install 中指定。唉,因为我们没有遵循 debian 的安装布局,所以我们需要调整这些列表以找到我们真正需要的文件。我想出了这个列表:

      tar c \
          include/postgresql/internal/* \
          include/libpq-fe.h \
          include/libpq-events.h \
          include/libpq/libpq-fs.h \
          include/pg_config*.h \
          include/postgres_ext.h \
          include/postgresql/9.1/server/catalog/pg_type.h \
          include/postgresql/9.1/server/catalog/genbki.h \
          include/postgresql/9.1/server/nodes/nodes.h \
          include/postgresql/9.1/server/utils/elog.h \
          include/postgresql/9.1/server/utils/errcodes.h \
          include/postgresql/9.1/server/utils/palloc.h \
          include/postgresql/9.1/server/c.h \
          include/postgresql/9.1/server/pg_config.h \
          include/postgresql/9.1/server/pg_config_manual.h \
          include/postgresql/9.1/server/pg_config_os.h \
          include/postgresql/9.1/server/port.h \
          include/postgresql/9.1/server/pg_trace.h \
          include/postgresql/9.1/server/postgres.h \
          include/postgresql/9.1/server/postgres_fe.h \
          include/postgresql/9.1/server/postgres_ext.h \
          include/postgresql/9.1/server/mb/pg_wchar.h \
          lib/libpq.so \
          bin/pg_config \
          lib/libpq.so.5* \
          | gzip --best > /tmp/libpq-5.4_9.1.8.tar.gz
      

      请注意,我必须删除联机帮助页 (pg_config.1.gz) 和本地化消息(share/locale 下的LC_MESSAGES/pg_config-9.1.mo LC_MESSAGES/libpq*.mo),由于某种原因,它们不是基于我的测功机构建的。我设法将 Python 的 psycopg2 链接到这个文件列表并成功使用它,但如果你觉得它很重要,你也可以弄清楚并修复它。

    8. 我们的麻烦现在几乎结束了。您应该获取生成的libpq-5.4_9.1.8.tar.gz 文件并将其放在您的测功机构建包(如 S3)可以访问的位置,然后将其出售到 slug 中。如果您不确定如何执行此操作,我的建议(对于当前的Python buildpack)是您在 slug 中创建文件“bin/pre_compile”,并将其放入其中:

      #!/bin/sh
      
      vendor() {
          printf "       "
          echo -n "$1 "
          curl --location --fail --silent $1 | tar -zx -C vendor && echo OK
      }
      
      echo "       (lines by the app will be prefixed with ---->>)"
      
      echo "---->> Fetching vendored binaries"
      mkdir -p vendor
      vendor "http://fusic.s3.amazonaws.com/executables/heroku/libpq-5.4_9.1.8.tar.gz"
      
      echo "---->> Injecting shell environment"
      # Even though Heroku's Python buildback has a hook mechanism, hooks can't
      #  change the buildpack's process environment (they are spawned, not
      #  sourced). This makes it possible to write hooks in any language, but
      #  makes vendoring stuff that should be linked against libraries installed
      #  during the rest of the build process harder. The kludge below hijacks
      #  $BIN_DIR/steps/pylibmc, which is sourced after this code and before pip
      #  is ran. Puked a little in my mouth.
      # See also: https://twitter.com/aknin/status/290832546260979712
      cat > $BIN_DIR/steps/pylibmc << EOF
      echo "---->> Injected environment hook executing"
      source .profile.d/activate_vendor_tree.sh
      EOF
      

      并创建.profile.d/activate_vendor_tree.sh 并将其放入其中:

      #!sh
      
      export PATH="/app/vendor/bin:$PATH"
      export CFLAGS="-I/app/vendor/include"
      export LDFLAGS="-L/app/vendor/lib -R/app/vendor/lib"
      export LD_LIBRARY_PATH="/app/vendor/lib:$LD_LIBRARY_PATH"
      

      编译您的 slug 时,我们安装的 pre-hook 会启动,下载我们向后移植的 libpq 并将其供应到 slug 中。如果您使用的是 Python buildpack 或类似受限的 buildpack(请参阅上面的详细评论),那么丑陋但必要的环境注入钩子就会启动,并且您的需求将针对新的 libpq 进行编译。当您运行您的应用程序时,Heroku 在执行您的代码之前方便地在 .profile.d 中获取所有内容,再次激活新的 libpq。哦对了。

    9. 终于,你完成了。将您的应用程序部署到 Heroku,并且您的依赖项应该链接到新的 libpq。如果您的应用程序已经部署,您可能需要在 Heroku 的 slug 编译器尝试重新安装这些要求之前清除您的 slug's cache dir(以便它们可以链接到您的新 libpq;这是一个棘手的话题,超出了范围本教程的;我知道的唯一方法是在pre_compile 中粘贴一些东西,这将删除缓存)。呃。

    【讨论】:

    • 我已经联系了 Martin Pitt(libpq5 和 libpq-dev 的包维护者),他很友好地对这些说明进行了简要回顾;我已经按照他的 cmets 稍微更改了说明。
    猜你喜欢
    • 2013-03-19
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 2018-12-21
    • 1970-01-01
    • 2013-10-04
    • 1970-01-01
    • 2023-04-01
    相关资源
    最近更新 更多