lt_upgrade

lt_upgrade — 升级LightDB服务器实例

Synopsis

lt_upgrade -b oldbindir [-B newbindir] -d oldconfigdir -D newconfigdir [option...]

描述

lt_upgrade(之前被称为pg_migrator) 允许存储在LightDB数据文件中的数据被升级到一个较晚 的LightDB主版本而无需进行主版本升级(例如从9.5.8到9.6.4或者从10.7到11.2)通常所需的数据转储/重载。 对于次版本升级(例如从9.6.2到9.6.3或者从10.1到10.2)则不需要这个程序。

LightDB主发行版本通常会加入新的特性,这些新特性常常会更改系统表的 布局,但是内部数据存储格式很少会改变。lt_upgrade 使用这一事实来通过创建新系统表并且重用旧的用户数据文件来执行快速升级。 如果未来的主发行版本更改了数据存储格式,导致旧数据格式不可读,那么 lt_upgrade将无法用于此类升级。(社区将努力避免这种情况)。

lt_upgrade会尽力(例如通过检查兼容的编译时设 置)确保新旧实例在二进制上也是兼容的,包括 32/64 位二进制。保持 外部模块也是二进制兼容的也很重要,不过 lt_upgrade无法检查这一点。

lt_upgrade 支持从 8.4.X 及其后版本升级到当前的 LightDB主发布,包括快照和 beta 发布。

选项

lt_upgrade接受下列命令行参数:

-b bindir
--old-bindir=bindir

旧的 LightDB 可执行文件目录; 环境变量LTBINOLD

-B bindir
--new-bindir=bindir

新的 LightDB 可执行文件目录; 默认为lt_upgrade所在的目录; 环境变量LTBINNEW

-c
--check

只检查实例,不更改任何数据

-d configdir
--old-datadir=configdir

旧的实例数据目录;环境变量 LTDATAOLD

-D configdir
--new-datadir=configdir

新的实例数据目录;环境变量 LTDATANEW

-j
--jobs=njobs

要同时使用的进程或线程数

-k
--link

使用硬链接来代替将文件拷贝到新实例

-o options
--old-options options

直接传送给旧 lightdb命令的选项,多个选项可以追加在后面

-O options
--new-options options

直接传送给新 lightdb命令的选项,多个选项可以追加在后面

-p port
--old-port=port

旧的实例端口号;环境变量 LTPORTOLD

-P port
--new-port=port

新的实例端口号;环境变量 LTPORTNEW

-r
--retain

即使在成功完成后也保留 SQL 和日志文件

-s dir
--socketdir=dir

用于升级期间postmaster套接字的目录;默认是当前目录; 环境变量 LTSOCKETDIR

-U username
--username=username

实例的安装用户名;环境变量 LTUSER

-v
--verbose

启用详细的内部日志

-V
--version

显示版本信息,然后退出

--clone

使用有效的文件克隆(在一些系统上也被称为reflinks),而不是将文件拷贝到新群集。 这可以导致数据文件接近瞬时的复制,从而获得-k/--link的速度优势,同时保留旧群集不受影响。

文件克隆仅在某些操作系统和文件系统上得到支持。如果选中但不被支持,则 lt_upgrade运行将会出错。 目前,它支持在Linux(内核4.5或更高版本)上的Btrfs和XFS(在文件系统创建reflink支持),以及macOS上的APFS。

-?
--help

显示帮助,然后退出

使用

下面是用lt_upgrade执行一次升级的步骤:

  1. 移动旧实例(可选)

    需要移动当前的 LightDB 安装目录,以便不会干扰新的 LightDB 安装。 一旦当前的 LightDB 服务器关闭,就可以安全地重命名 LightDB 安装目录。 假设旧目录为 /usr/local/lightdbx,则可以执行以下操作:

    mv /usr/local/lightdbx /usr/local/lightdbx.old
    

    来重命名该目录。

  2. 对于源码安装,编译新版本

    用兼容旧实例的configure标记编译新的 LightDB 源码。在开始升级之前,lt_upgrade 将检查lt_controldata来确保所有设置都是兼容的。

  3. 安装新的 LightDB 二进制文件

    安装新服务器的二进制文件和支持文件。lt_upgrade 会被包含在默认的安装中。

  4. 初始化新的 LightDB 实例

    如果您的 LightDB 是独立的,请使用 lt_initdb 初始化新的集群。 同样,使用与旧集群匹配的兼容 lt_initdb 标志,然后添加另一个选项 --upgrade-mode。 无需启动新集群。

    lt_initdb -p 5432 -D /home/lightdb/lightdbx/data --upgrade-mode
    

    如果您的 LightDB 部署在高可用性或分布式环境中,请使用 lightdb-installer 初始化新的集群。 您必须修改 shell 脚本 script/8_lightdb_create_extension.sh, 在启动 install.sh 之前删除其中所有的 exeuteSQL 命令。

  5. 安装扩展共享对象文件

    许多扩展和自定义模块,无论是来自contrib或其他源,使用共享对象文件(或DLLs),例如, pgcrypto.so。 如果旧集群使用过这些,匹配新服务器二进制的共享对象文件,必须安装在新集群中。 通常是通过操作系统命令。 不要加载模式定义,例如CREATE EXTENSION pgcrypto,因为这些将从旧集群复制。 如果扩展更新是可用的,lt_upgrade将报告这一点,并创建一个脚本,可以稍后运行来更新它们。

    您不需要担心内置扩展,LightDB 会自动处理它们。

  6. 调整认证

    lt_upgrade将会多次连接到旧服务器和新服务器,因此 你可能想要在lt_hba.conf中把认证设置成 peer或者使用一个~/.pgpass文件(见 Section 32.15)。

  7. 停止两个服务器

    确认两个数据库服务器都被停止使用,例如在 Unix 上可以:

    lt_ctl -D /opt/LightDB/13 stop
    lt_ctl -D /opt/LightDB/13 stop
    

    直到后面的步骤之前,流复制和日志传送后备服务器可以保持运行。

  8. 为后备服务器升级做准备

    如果正在使用小节Step 10中给出的方法升级后备服务器,请对旧的主实例和后备实例运行lt_controldata以验证旧的后备服务器已经完全追上。验证Latest checkpoint location值在所有实例中都匹配(如果旧后备服务器在旧的主服务器之前被关闭或者如果旧的后备服务器仍在运行,则将会出现失配)。此外,请确保在新的主实例上的lightdb.conf文件中,wal_level未设置为minimal

  9. 运行 lt_upgrade

    总是应该运行新服务器而不是旧服务器的lt_upgrade二进制文件。 lt_upgrade要求制定新旧实例的数据和可执行文件(bin)目录。 你也可以指定用户和端口值,以及你是否想要用链接或克隆来取代默认的复制行为对数据文件进行处理。

    如果你使用链接模式,升级将会快很多(不需要文件拷贝)并且将使用 更少的磁盘空间,但是在升级后一旦启动新实例,旧实例就无法被访问。 链接模式也要求新旧实例数据目录位于同一个文件系统中(表空间和 lt_wal可以在不同的文件系统中)。 克隆模式提供了相同的速度以及磁盘空间优势,但不会导致新群集启动后旧群集不可用。 克隆模式还需要新旧数据目录位于同一文件系统中。 此模式仅在某些操作系统和文件系统上可用。

    --jobs选项允许多个 CPU 核心被用来复制/链接文件以及 并行地转储和重载数据库模式。这个选项一个比较好的值是 CPU 核心数 和表空间数的最大值。这个选项可以显著地减少升级运行在一台多处理 器机器上的多数据库服务器的时间。

    对于 Windows 用户,您必须以管理员账户登录,然后以 postgres 用户身份启动 shell 并设置正确的路径: 启动后,lt_upgrade 将验证两个集群是否兼容,然后进行升级。 即使旧服务器仍在运行,您也可以使用 lt_upgrade --check 仅执行检查。 lt_upgrade --check 还将概述升级后需要进行的任何手动调整。 如果您将使用链接或克隆模式,则应使用选项 --link--clone 以及 --check 以启用特定于模式的检查。 lt_upgrade 要求在当前目录中具有写权限。

    显然,没有人可以在升级期间访问这些实例。lt_upgrade 默认会在端口 50432 上运行服务器来避免意外的客户端连接。在做升级时, 可以对两个实例使用相同的端口号,因为新旧实例不会在同时被运行。不过, 在检查一个旧的运行中服务器时,新旧端口号必须不同。

    如果在恢复数据库模式时发生错误,lt_upgrade将会退出 并且你必须按照下文Step 16中所说的恢复 旧实例。要再次尝试lt_upgrade,你将需要修改 旧实例,这样 lt_upgrade 模式会成功恢复。如果问题是一个 contrib模块, 你可能需要从旧实例中卸载该模块并且在升级后重新把它安装在新实例中,不过 这样做的前提是该模块没有被用来存储用户数据。

  10. 升级流复制和日志传送后备服务器

    如果使用链接模式并且有流复制(见Section 25.2.5)或者日志 传送(见Section 25.2)后备服务器,你可以遵照下面的 步骤对它们进行快速的升级。你将不用在这些后备服务器上运行 lt_upgrade,而是在主服务器上运行rsync。 到这里还不要启动任何服务器。

    如果你没有使用链接模式、没有或不想使用rsync或者想用一种更容易的解决方案,请跳过这一节中的过程并且在lt_upgrade完成并且新的主实例开始运行后重建后备服务器。

    1. 在后备服务器上安装新的 LightDB 二进制文件

      确保新的二进制和支持文件被安装在所有后备服务器上。

    2. 确保存在新的后备机数据目录

      确保新的后备机数据目录存在或者为空。如果 运行过lt_initdb,请删除后备服务器的新数据目录。

    3. 安装扩展共享对象文件

      在新的后备机上安装和新的主实例中相同的扩展共享对象文件。

    4. 停止后备服务器

      如果后备服务器仍在运行,现在使用上述的指令停止它们。

    5. 保存配置文件

      从旧后备机的配置目录保存任何需要保留的配置文件,例如 lightdb.conf(以及它包含的任何文件)、 lightdb.auto.conflt_hba.conf, 因为这些文件在下一步中会被重写或者移除。

    6. 运行rsync

      在使用链接模式时,后备服务器可以使用rsync快速升级。为了实现这一点,在服务器上一个高于新旧数据库实例目录的目录中为每个后备服务器运行这个命令:

      rsync --archive --delete --hard-links --size-only --no-inc-recursive old_cluster new_cluster remote_dir
      

      其中old_clusternew_cluster是相对于主服务器上的当前目录的,而remote_dir是后备服务器上高于新旧实例目录的一个目录。在主服务器和后备服务器上指定目录之下的目录结构必须匹配。指定远程目录的详细情况请参考rsync的手册,例如:

      rsync --archive --delete --hard-links --size-only --no-inc-recursive /opt/LightDB/22.1 \
            /opt/LightDB/22.2 standby.example.com:/opt/LightDB
      

      可以使用rsync--dry-run选项验证该命令将做的事情。虽然在主服务器上必须为至少一台后备运行rsync,可以在一台已经升级过的后备服务器上运行rsync来升级其他的后备服务器,只要已升级的后备服务器还没有被启动。

      这个命令所做的事情是记录由lt_upgrade的链接模式创建的链接,它们连接主服务器上新旧实例中的文件。该命令接下来在后备服务器的旧实例中寻找匹配的文件并且为它们在该后备的新实例中创建链接。主服务器上没有被链接的文件会被从主服务器拷贝到后备服务器(通常都很小)。这提供了快速的后备服务器升级。不幸地是,rsync会不必要地拷贝与临时表和不做日志表相关的文件,因为通常在后备服务器上不存在这些文件。

      如果有表空间,你将需要为每个表空间目录运行一个类似的rsync命令,例如:

      rsync --archive --delete --hard-links --size-only --no-inc-recursive /home/lightdbx/LT_22.1_201510051 \
            /home/lightdbx/LT_22.2_201608131 standby.example.com:/home/lightdbx
      

      如果你已经把lt_wal放在数据目录外面,也必须在那些目录上运行rsync

    7. 配置流复制和日志传送后备服务器

      为日志传送配置服务器(不需要运行pg_start_backup() 以及pg_stop_backup()或者做文件系统备份,因为从属机 仍在与主机同步)。

  11. 恢复 lt_hba.conf

    如果你修改了lt_hba.conf,则要将其恢复到原始的设置。 也可能需要调整新实例中的其他配置文件来匹配旧实例,例如 lightdb.conf(以及它包含的任何文件)和 lightdb.auto.conf

  12. 启动新服务器

    现在可以安全地启动新的服务器,并且可以接着启动任何 rsync过的后备服务器。

  13. 升级后处理

    如果需要做任何升级后处理,lt_upgrade 将在完成后发出警告。它也将 生成必须由管理员运行的脚本文件。这些脚本文件将连接到每一个需要做 升级后处理的数据库。每一个脚本应该这样运行:

    ltsql --username=lightdb --file=script.sql postgres
    

    这些脚本可以以任何顺序运行并且在运行之后立即删除。

    Caution

    通常在重建脚本运行完成之前访问重建脚本中引用的表是不安全的,这样做 可能会得到不正确的结果或者很差的性能。没有在重建脚本中引用的表可以 随时被访问。

  14. 统计信息

    由于lt_upgrade并未传输优化器统计信息,在升级的尾声 你将被指示运行一个命令来生成这些信息。你可能需要设置连接参数来匹配你 的新实例。

  15. 删除旧实例

    一旦你对升级表示满意,你就可以通过运行 lt_upgrade完成时提到的脚本来删除旧实例的 数据目录(如果在旧数据目录中有用户定义的表空间就不可能实现自动删除)。 你也可以删除旧安装目录(例如binshare)。

  16. 恢复到旧实例

    在运行lt_upgrade之后,如果你希望恢复到 旧实例,有几个选项:

    • 如果使用了 --check 选项, 则旧集群没有被修改;它可以被重新启动。

    • 如果 --link 选项 没有被使用, 旧集群没有被修改;它可以被重新启动。

    • 如果使用了--link 选项, 数据文件可能在新旧群集之间共享:

      • 如果lt_upgrade在链接启动之前中止,旧群集没有被修改,它可以重新启动。

      • 如果你没有启动新集群,旧集群没有被修改,当链接启动时,一个.old后缀会附加到$LTDATA/global/lt_control。 如果要重用旧集群,从$LTDATA/global/lt_control移除.old后缀;你就可以重启旧集群。

      • 如果你已经启动新群集,它已经写入了共享文件,并且使用旧群集会不安全。这种情况下,需要从备份中还原旧群集。

注解

lt_upgrade创建不同的工作文件,如模式转储,在当前工作目录中。为了安全,请确保该目录不可被任何其他用户读取或者写入。

lt_upgrade在新旧数据目录中启动短期的postmasters。临时 Unix 套接字文件用于与这些postmasters通信,默认情况下,在当前工作目录中进行。 在某些情况下,当前目录的路径名称可能太长,无法成为有效的套接字名称。这种情况下你可以使用-s选项将套接字文件放在某些具有较短路径名称的目录中。 为了安全原因,请确保该目录不可被任何其他用户读取或者写入。

如果失败、重建和重索引会影响你的安装,lt_upgrade 将会报告这些情况。用来重建表和索引的升级后脚本将会自动被建立。 如果你正在尝试自动升级很多实例,你应该发现具有相同数据库模式的实例 对所有实例升级都要求同样的升级后步骤,这是因为升级后步骤是基于数据 库模式而不是用户数据。

LightDB 内置了扩展和计划任务。 这些扩展和任务在 lt_extension.dat 和 lt_cron.dat 中有描述。 您无法修改这两个文件,因为它们由 LightDB 维护。 lt_upgrade 使用这两个文件来升级和更新内置扩展和计划任务。 从 LightDB 22.3 开始,lt_extension.dat 和 lt_cron.dat 合并为一个文件 lt_builtin.dat。 但是,lt_extension.dat 和 lt_cron.dat 仍然被保留。

从 LightDB 22.3 开始,lt_upgrade 将检查 lightdb_syntax_compatible_type 的一致性。 旧集群的值必须与新集群的值相同。

从 LightDB 22.3 开始,lt_upgrade 将在升级后为新集群创建名为 lt_test 的数据库。

从 LightDB 22.3 开始,当 lightdb_syntax_compatible_type 的值为 'oracle' 时,空字符串将作为 null 值存储。 因此,如果您正在从 22.2 升级到 22.3,且兼容性都为 'oracle',不建议使用 lt_upgrade。

对于部署测试,创建一个只有模式的旧实例副本,在其中插入假数据并且升级。

lt_upgrade不支持包含使用这些reg* OID-引用 系统数据类型的表列的数据库的升级:

regcollation
regconfig
regdictionary
regnamespace
regoper
regoperator
regproc
regprocedure

(regclass, regrole, and regtype can be upgraded.)

如果你想要使用链接模式并且你不想让你的旧实例在新实例启动时被修改,考虑使用克隆模式。 如果(克隆模式)不可用,可以复制一份旧实例并且在副本上以链接模式进行升级。要创建旧实例的一 份合法拷贝,可以在服务器运行时使用rsync创建旧实例的 一份脏拷贝,然后关闭旧服务器并且再次运行rsync --checksum 把更改更新到该拷贝以让其一致(--checksum是必要的,因为 rsync在判断文件修改时间的更改时的精度只能到秒级)。如 Section 24.3.3中所述,你可能想要排除 一些文件,例如postmaster.pid。如果你的文件系统支持文 件系统快照或者 copy-on-write 文件副本,你可以使用它们来创建旧实例和 表空间的一个备份,不过快照和副本必须被同时创建或者在数据库服务器关闭 期间被创建。

另见

lt_initdb, lt_ctl, lt_dump, lightdb