校对
来自 PostgreSQL Wiki
跳转到导航跳转到搜索如果由于校对定义更改而导致字符串顺序发生变化,则 btree 索引(或更罕见地,检查约束或分区)可能会损坏。例如,GNU libc 2.28 将更改所有区域设置中许多字符串的顺序,并且最近的德语和匈牙利语对 Glibc 进行了细微的更改,导致人们的索引损坏。一些报告
- Locale_data_changes
- 注意您下次升级 glibc.
- 跨不同 glibc 版本进行流式传输的危险:一个警示故事
- FreeBSD 10 => 11:转储并重新加载您的 PostgreSQL 数据库,除非您喜欢它已损坏
- ...多年来有很多报告...
引用自 Unicode 技术标准
“随着时间的推移,校对顺序会发生变化:随着有关语言的信息变得越来越多,可能需要进行修复;可能会有需要更改的语言的新政府或行业标准;最后,添加到 Unicode 标准的新字符将与先前定义的字符交织在一起。这意味着对校对必须进行精心版本控制。”
我们正在采取哪些措施?
Peter Eisentraut 为 PostgreSQL 10 添加了 ICU 支持。ICU 是校对(以及许多其他内容)的备用提供程序,它比 libc 强大得多,而且至关重要的是,它可以报告一个版本字符串,您可以使用该字符串来检测其底层排序规则何时发生变化。在版本 10、11 和 12 中我们建模版本的方式存在问题
- 您还不能对“默认”校对使用 ICU,而这恰好是几乎所有用户几乎所有时候都在使用的东西
- 版本以一种不会强制您重建索引甚至不会帮助您找出哪些索引需要重建的方式进行跟踪,它只是相信在您输入 DDL 命令 ALTER COLLATION ... REFRESH VERSION 以清除版本不匹配警告后您已完成此操作,每当打开索引时,它都会发出版本不匹配警告
- 即使生成了警告,它仍然会使用可能已损坏的索引,而且用户可能看不到警告
在最近的版本中,我们做了一些小的改进
- 在可能的范围内,为 libc 校对添加版本控制
15+ 的未来计划
- 让它可以对默认校对使用 ICU,顺便一提,即使在默认校对也是 libc 时也要跟踪其版本(在我们可以从 libc 获取版本的系统上)
- 添加一个 REINDEX 命令,该命令可以自动找到因字符集版本更改而需要重新索引的索引
- 追踪每次重新建立索引时使用的每个字符集的版本,仅可在完全重新索引时更新,而不是相信用户能准确执行该操作(该操作已提交,但随后从 14 版本中恢复)
未来其他想法
- 至少 DB2 和 SQL Server 具有字符集版本的概念,而且一些版本允许同时使用多个版本。我们最终可能需要支持该功能(ICU64 和 ICU65 将是不同的提供程序,还是具有不同版本的同一提供程序,或者...?)
- 我们可能还需要拒绝使用我们认为可能已损坏的索引。
- 我们可能需要将基于每个数据库的对象版本追踪扩展到其他数据库对象,如受排序更改影响的 CHECK 约束和分区。
需要注意的一个有趣问题是,各种操作系统(Windows、FreeBSD、GNU 等)最近发生改变的原因在于,它们都放弃了维护自己的字符集系统并切换到 CLDR,所以最终在这一点上它们可能会同意 ICU。那么,唯一剩下的更改将来自 Unicode CLDR 项目进行的逐渐调整和改进,尽管这些调整和改进会以不同的速度流入不同的操作系统和库...所以,你使用的是 ICU 还是 libc 并不重要,但它们有时会不同步,而且无论一般是否趋同,我们始终必须处理版本和更改。