PostgreSQL 的 `initdb` 失败,并显示“区域设置无效;检查 LANG 和 LC_* 环境变量”

tor*_*tte 9 postgresql locale

已经找到了解决方案(请参阅下面的答案),但我不确定它是否合适;另外,这也可能对其他人有帮助。


尝试按照文档( 18.2创建数据库集群)设置PostgreSQL ,但在Ubuntu 18.04(内核:4.15.0-22-generic)上出现以下错误:

$ initdb -D /usr/local/pgsql/data
  (...)
initdb: invalid locale settings; check LANG and LC_* environment variables 
Run Code Online (Sandbox Code Playgroud)

在 Stackoverflow ( 1 , 2 )上找到了几个相关的答案,但这些答案并没有解决问题,而Serverfault 上的答案建议重新启动服务,但 PostgreSQL 甚至没有运行。

尝试在系统上发现的每个变体中显式传递区域设置,但这些也失败了,

 3617  2018/06/07-08:36 initdb -D ~/Downloads/ --locale=en_US.utf8
 3618  2018/06/07-08:36 initdb -D ~/Downloads/ --locale=en_US.UTF8
 3621  2018/06/07-08:37 initdb -D ~/Downloads/ --locale=en_US.UTF-8
 3622  2018/06/07-08:37 initdb -D ~/Downloads/ --locale="en_US.UTF-8"
 3623  2018/06/07-08:37 initdb -D ~/Downloads/ --locale="en_US.utf8"
 3645  2018/06/07-09:24 initdb -D ~/Downloads/ --locale="en_US.utf8"
Run Code Online (Sandbox Code Playgroud)

initdb: invalid locale name <the_option_value_above>
Run Code Online (Sandbox Code Playgroud)

Arch Linux 论坛对此有过讨论,但没有解决方案。


2018/06/07 1214 更新

我在上面链接了答案,但也许不够明确:我确实查看了locale -alocale(没有列出前者的输出,因为我在下面的尝试中安装了所有这些):

$ locale
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_PAPER="en_US.UTF-8"
LC_NAME="en_US.UTF-8"
LC_ADDRESS="en_US.UTF-8"
LC_TELEPHONE="en_US.UTF-8"
LC_MEASUREMENT="en_US.UTF-8"
LC_IDENTIFICATION="en_US.UTF-8"
LC_ALL=en_US.UTF-8
Run Code Online (Sandbox Code Playgroud)

已尝试过但不起作用(并且每次迭代都重新启动终端):

TODO: https://unix.stackexchange.com/questions/294845/bash-warning-setlocale-lc-all-cannot-change-locale-en-us-utf-8

tor*_*tte 7

这个线程

initdb -D <your_data_location> --no-locale --encoding=UTF8
Run Code Online (Sandbox Code Playgroud)

在哪里

  --locale=LOCALE       set default locale for new databases
  --no-locale           equivalent to --locale=C
Run Code Online (Sandbox Code Playgroud)

有一些警告(请参阅下面的警告),但可以使用template0(请参阅21.3. 模板数据库)创建全 utf8 数据库。

来自客户端(psql):

postgres=# create database test LC_COLLATE "en_US.UTF-8" LC_CTYPE "en_US.UTF-8" template template0;
Run Code Online (Sandbox Code Playgroud)

或通过createdb

createdb --lc-collate="en_US.UTF-8" --lc-ctype="en_US.UTF-8" --template="template0" test2
Run Code Online (Sandbox Code Playgroud)

查看:

$ psql
psql (10.3)
Type "help" for help.

postgres=# \l
                                  List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    |   Access privileges   
-----------+----------+----------+-------------+-------------+-----------------------
 postgres  | postgres | UTF8     | C           | C           | 
 template0 | postgres | UTF8     | C           | C           | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 template1 | postgres | UTF8     | C           | C           | =c/postgres          +
           |          |          |             |             | postgres=CTc/postgres
 test      | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
 test2     | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 | 
Run Code Online (Sandbox Code Playgroud)

警告:这可能不是正确的解决方案,上面的解决方法只是一种解决方法。

请注意使用上述解决方案创建的数据库中下面的“Collat​​e”和“Ctype”字段,这可能会导致问题,因为“字符串之间的比较结果取决于LC_CTYPE。实际上,最明显的影响是排序顺序。” (请参阅 DBA StackExchange 线程)。这也在 PostgreSQL 邮件列表上得到了证实(请参阅有关生产数据库上的此问题的线程)。解决此问题的最简单方法可能是重新初始化/重新创建数据库

postgres=# \l
                             List of databases
   Name    |  Owner   | Encoding | Collate | Ctype |   Access privileges   
-----------+----------+----------+---------+-------+-----------------------
 postgres  | postgres | UTF8     | C       | C     | 
 template0 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
 template1 | postgres | UTF8     | C       | C     | =c/postgres          +
           |          |          |         |       | postgres=CTc/postgres
(3 rows)
Run Code Online (Sandbox Code Playgroud)


Ric*_*rdW 6

虽然这个问题没有提到 Nix,但原始发帖者从Nix 讨论网站链接到这个问题,所以我相信这是一个与 Nix 相关的问题。

我在 Nix shell 下运行时遇到了这个问题,经过大量搜索后找到了解决方案。我只需要添加glibcLocales到我的环境中。即运行nix-shell -p glibcLocales或添加glibcLocalesbuildInputs.