我使用的是 UB 16.04 LTS 服务器,昨天发布并安装了新版本的locales -package:
Start-Date: 2019-02-21 09:44:05
Commandline: /usr/bin/apt-get -y -o Dpkg::Options::=--force-confdef -o Dpkg::Options::=--force-confold dist-upgrade
Upgrade: [...], locales:amd64 (2.23-0ubuntu10, 2.23-0ubuntu11), [...]
End-Date: 2019-02-21 09:44:45
windows-1252
由于历史原因,我还使用 PostgreSQL 11 和依赖字符集的数据库:
Name | Owner | Encoding | Collate | Ctype | Access[...]
------+----------+----------+--------------+--------------+--------------
[...] | postgres | WIN1252 | de_DE.CP1252 | de_DE.CP1252 |
为了使其可用,使用以下命令:
localedef -f CP1252 -i /usr/share/i18n/locales/de_DE /usr/lib/locale/de_DE.CP1252
使用locale-gen
before/afterlocaledef
会出现以下错误:
locale-gen de_DE.CP1252
Error: 'de_DE.CP1252' is not a supported language or locale
该错误消息是正确的,该文件/usr/share/i18n/SUPPORTED
不包含我的语言环境。据我了解,这就是为什么我需要使用localedef
.
现在的问题是,很可能在安装新的locales
-package 之后,我手动添加的一个被自动删除,并且访问依赖于该语言环境的数据库失败:
2019-02-21 09:42:45.109 CET [27039] FATAL: Datenbank-Locale ist inkompatibel mit Betriebssystem
2019-02-21 09:42:45.109 CET [27039] DETAIL: Die Datenbank wurde mit LC_COLLATE »de_DE.CP1252« initialisiert, was von setlocale() nicht erkannt wird.
据我了解,所有被识别和启用的语言环境dpkg-reconfigure locales
都已保留,我的自定义语言环境未在此处列出。因此,我按照说明/etc/locale.gen
并使用以下行创建了以下文件:
/usr/local/share/i18n/SUPPORTED
de_DE.CP1252 CP1252
这最终使我的语言环境可用:
问题是这似乎不足以解决我的目标:每当我运行dpkg-reconfigure locales
时,创建的语言环境 usinglocaledef
会从文件夹中删除,/usr/lib/locale/de_DE.CP1252
并且 Postgres 再次失败。即使locale -a
打印我的语言环境等。因此,这很可能是安装新locales
软件包时/之后发生的情况。如果我localedef
再次像上面记录的那样手动运行,Postgres 立即允许再次访问旧数据库。
我认识到的一件有趣的事情C.UTF-8
是可用的语言环境,/usr/lib/locale
就像我的自定义语言环境一样,但由于某种原因永远不会被自动删除。在 Web 中搜索该语言环境,它似乎是作为某个包的一部分由发行版提供,而不是根据需要在本地配置和生成:
我们现在有一个“不可安装的”C.UTF-8 语言环境,即使您删除了 locale-archive,或者更改了为 locale-archive 设置的已安装语言,它仍然可用。
https://bugzilla.redhat.com/show_bug.cgi?id=902094#c20
/usr/lib/locale/C.UTF-8/LC_ADDRESS
/usr/lib/locale/C.UTF-8/LC_COLLATE
https://packages.debian.org/de/sid/sh4/libc-bin/filelist
那么,我需要做些什么才能让我的localedef
-results 存活下来dpkg-reconfigure locales
,或者在安装新的locales
-packages期间做了什么?
谢谢!
这里有不同的事情需要注意:
localedef 的删除结果
手动创建的结果
localedef
实际上总是被删除,仅仅是因为locale-gen
一个脚本这样做:为了避免这种情况,确实需要使语言环境以不同的方式可用,以便始终在生成语言环境时生成它。
/usr/local/share/i18n/支持
该文件实际上是使我的语言环境可用的正确方法以及我添加它的方式是正确的。该行
de_DE.CP1252 CP1252
导致使用dpkg-reconfigure locales
like usinglocaledef
手动创建相同的语言环境。唯一的区别是,在第一种情况下,语言环境被添加到文件/usr/lib/locale/locale-archive
中,而后者创建单独的目录。这种差异导致了以下问题......Postgres 无法识别更改
我只是在执行后的测试期间从未重新启动过 Postgres
dpkg-reconfigure locales
,这是必要的!当使用
localedef
where 删除或添加创建单个目录时,Postgres 会立即识别出使用该语言环境的数据库会话。这就是为什么我认为总是根据需要读取语言环境,但似乎并非如此。相反,我猜存档文件每个进程只打开一次,并且只有在其中找不到某些语言环境时,才会识别其他目录并按需识别。因此,当存档文件被删除并新创建时,Postgres 根本无法识别并且仍然使用旧内容,这些内容不包含我的语言环境。在重新启动使用嵌入了我的语言环境的新存档文件的 Postgres 之后,一切又恢复了。这可以通过再次运行以删除我的语言环境来轻松复制,
dpkg-reconfigure locales
并且无需重新启动 Postgres,它只会继续工作。重新启动后,它再次失败,直到语言环境再次添加到存档文件中。不使用localedef?
localedef
因此,最终获得生存结果的正确方法似乎dpkg-reconfigure locales
是不要localedef
手动使用,而是在文件中定义所需的语言环境,/usr/local/share/i18n/SUPPORTED
并在最坏的情况下重新启动系统。