如何绕过c"语言c" Heroku错误?

时间:2016-04-05 18:45:10

标签: c postgresql heroku

我有一个project,它调用Postgres函数gen_random_bytesdeclared就像这样:

CREATE OR REPLACE FUNCTION core.gen_random_bytes(integer) RETURNS bytea AS '$libdir/pgcrypto', 'pg_random_bytes' LANGUAGE c STRICT;

只要我在本地机器上使用它,它工作正常。但是我无法在Heroku上创建该功能 - 我收到以下错误:

[WARNING  ] CREATE OR REPLACE FUNCTION core.gen_random_bytes(integer) RETURNS bytea AS '$libdir/pgcrypto', 'pg_random_bytes' LANGUAGE c STRICT
ERROR:  permission denied for language c

似乎只有超级用户才能在C中声明函数。我找到了另一个answer,建议使用命令

UPDATE pg_language SET lanpltrusted = true WHERE lanname LIKE 'c';

我没有获得该命令的许可:

ERROR: permission denied for relation pg_language
SQL state: 42501

如何让我的代码在Heroku上运行?

我至少有以下选项:

  1. 使用Postgres语言重写core.gen_random_bytes
  2. 使用core.gen_random_bytes的一些现有替代方案,但这并不需要超级用户。
  3. 从Heroku切换到另一个托管服务提供商,这将给予我超级用​​户权限(例如Digital Ocean,Amazon EC2等)。
  4. 现在,我只是为这个项目做原型设计。哪个选项最简单(包括我没有提到的内容)?

1 个答案:

答案 0 :(得分:5)

答案是:你不能除非你自己在一个裸实例上运行Postgres(我不确定它是Heroku上的一个选项)。

所有Postgres托管服务(如Heroku和Amazon RDS)的缺点是内部需要能够在单个虚拟服务器中运行多个Postgres数据库。这意味着他们不能允许Postgres做任何可能影响操作系统级别事情的事情。不受信任的过程语言(例如C,plpythonu和plperlu,但不是plperl)能够在运行Postgres的OS用户可以在操作系统级别执行任何操作。这是一个在共享环境中无法接受的安全漏洞。 (举个例子,在服务器上为每个其他客户阅读原始的Postgres数据很容易。)

这里唯一的选择是自己安装和管理Postgres。在亚马逊上这很容易;只需使用您选择的操作系统获取原始EC2实例并在其上拍击Postgres。你失去了RDS为你提供的一些易维护性,但是如果你知道Postgres它真的没什么大不了的。我倾向于推动我的客户做到这一点,这样我就能够使用RDS团队没有祝福的扩展(在共享环境中不安全的其他东西)。

我对Heroku的产品并不熟悉,但只要它们具有与裸EC2实例相当的东西,你就可以做同样的事情。