Postgres迁移陷阱:排序规则

使用PostgresSQL进行数据迁移是很便利的,但是如果你没考虑到处理排序规则审查和更新,则可能导致数据被破坏。以下简述几个需要考虑的点:

注意glibc版本是否匹配

使用不匹配的glibc版本可能存在以下风险:

  • 查询时缺少数据
  • 版本之间的排序不一致
  • 未检测到唯一约束冲突

这些都可能导致数据损坏问题。例如,如果对电子邮件地址有唯一的限制,并且不同版本的排序结果不同,那么在有两个用户帐户同时查询时。查询时可能会得到空结果。如果数据损坏是单个记录,那么解决数据损坏可能很简单,但数据规模越大,清理工作就难度越大。

在以下情况下,glibc版本之间的差异会导致问题:

  • 使用物理复制将数据库(即,wal-e、wal-g、pgbackrest)从一个主机迁移到新主机。
  • 在具有不同操作系统配置的系统上恢复二进制备份(使用pg_basebackup)。
  • 操作系统Linux升级到新的版本,同时保留PostgreSQL数据目录。在这种情况下,glibc版本可能已经更改,但基础数据没有更改。

并非所有类型的迁移或复制都受此不一致性的影响。数据以逻辑(非二进制)方式传输的情况非常安全,包括:

  • 使用pg_dump进行备份和恢复过程,因为该过程仅使用逻辑数据
  • 逻辑复制,仅使用数据拷贝而不使用物理拷贝

排序工作原理

这里举个例子,2.28以上的glibc版本上,运行此查询并查看数据如何排序。

test=# SELECT * FROM (values ('a'), ('$a'), ('a$'), ('b'), ('$b'), ('b$'), ('A'), ('B')) AS l(x) ORDER BY x ;
 x  
----
 a
 $a
 a$
 A
 b
 $b
 b$
 B
(8 rows)

glibc

Libc是Linux系统使用的主要C库。包括Postgres在内的许多Linux程序都使用glibc实现。它用于提供许多基本的软件操作,并在Postgres中用于在创建索引时对文本进行排序或比较数据。

2018年发布的glibc 2.28更新使本地化和校对信息使其符合2016年第4版ISO 14651标准。由于存在更新,使用先前版本的排序规则创建的索引在系统使用更新的排序规则读取时可能会出现损坏。如果存在不匹配,则必须重建索引以避免出现问题。

排序规则查询方法

可以通过pg_database的datcollate字段找到数据库正在使用的数据排序规则。

test=# SELECT datname, datcollate FROM pg_database;
  datname  | datcollate  
-----------+-------------
 test      | en_US.UTF-8
 security  | en_US.UTF-8
 template1 | en_US.UTF-8
 template0 | en_US.UTF-8

检查glibc的版本

ldd --version //ldd命令查询版本

ldd (GNU libc) 2.17
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

修复方法

  • 迁移期间修复

由于此问题出现在跨操作系统的glibc版本移动的二进制数据中,因此通常会在迁移过程中出现。通过逻辑复制或逻辑备份(即pg_dump)进行迁移可以消除此问题,因为此时将重新创建任何受影响的索引。所以改变恢复方法为数据库的逻辑恢复是一种有效方式。

对于超过100GB的大型数据库,逻辑备份迁移可能需要过长的时间。在这些情况下,WAL迁移后重建受影响的索引通常是首选的方法,这样可以尽量减少停机时间和工作量。

  • 在实时数据库上

如果认为迁移后的排序规则可能有问题,插件amcheck可以帮助识别数据不一致。

附带说明:从I/O和时间方面来看,插件amcheck是一个需要密集型资源运行的进程。如果数据库规模较大,或者不希望影响数据库运行,可以考虑在物理副本上运行该数据库,这样就不会中断生产工作流,因为可以数据库的副本上检测。

  • 重建索引

如果上述步骤中发现存在问题,则需执行REINDEX或REINDEX CONCURRENTLY。(注意:如果使用的是Postgres 14,建议使用14.4或更高版本,以便正确地在线重建索引,以避免进一步的损坏风险)。

猜你喜欢

转载自blog.csdn.net/hezhou876887962/article/details/129431205
今日推荐