在Heroku上设置PostgreSQL application_name

时间:2013-03-31 03:18:07

标签: heroku postgresql-9.1 buildpack

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

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

如果有什么可以在Heroku上设置libpq

1 个答案:

答案 0 :(得分:2)

据我所知,only解决方案是将vendor更新版本的libpq添加到您的子弹中。

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

  1. 使用vanilla 12.04
  2. 启动新VM
  3. sudo apt-get update
  4. apt-get source postgresql-9.1(您可能需要先sudo apt-get install dpkg-src
  5. 在提取的来源中,查看rules文件(postgresql-9.1-9.1.8/debian/rules,如果precise-updates仍在PostgreSQL 9.1.8中。)
  6. 从规则文件中,我认为我们应该用于构建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,我怀疑它们是非常需要的,如果你感觉不是这样,那就玩得开心,修好我的帽子吧对你好先生。

  7. make && make install

  8. 现在所有postgresql都安装到/vendor。我们需要采取的文件在postgresql-9.1-9.1.8/debian/libpq5.installpostgresql-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)和本地化消息(LC_MESSAGES/pg_config-9.1.mo LC_MESSAGES/libpq*.mo下的share/locale),由于某种原因,这些消息并非构建在我的dyno上。我设法将Python的psycopg2链接到这个文件列表并成功使用它,但如果您觉得它很重要,您可以解决这个问题并进行修复。

  9. 我们的麻烦实际上已经过去了。您应该将生成的libpq-5.4_9.1.8.tar.gz文件放在可以访问dyno的buildpack(如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启动,下载我们的backported libpq并将它们提供给slug。如果您正在使用Python buildpack或类似的有限buildpack(请参阅上面的详细注释),那么丑陋但必要的环境注入钩子会启动,您的需求将针对新的libpq进行编译。当您运行应用程序时,Heroku可以在执行代码之前方便地在.profile.d中获取所有内容,再次激活新的libpq。哦是的。

  10. 最后,你已经完成了。将您的应用程序部署到Heroku,您的依赖项应链接到新的libpq。如果您的应用程序已经部署,您可能需要在Heroku的slug编译器尝试重新安装这些要求之前清除slug's cache dir(因此它们可以链接到您的新libpq;这是一个棘手的话题,在外面本教程的范围;我知道的唯一方法是在pre_compile中粘贴将删除缓存的内容。啊。