关于升级数据库服务器软件的重要说明

[注意]

注意

本节讨论的是在已有数据库正在使用的情况下重新安装数据库软件。这不适用于初次安装,也不适用于被更新的软件包没有现存数据库的情况,但用户应当通读本节,以了解未来可能出现的各种问题。

让我们用一个真实发生过的错误截屏来开始本章的内容。如果你是第一次安装数据库软件,这个错误不会出现:

$ sudo systemctl status postgresql
-- postgresql.service - PostgreSQL database server
     Loaded: loaded (/usr/lib/systemd/system/postgresql.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Tue 2021-10-26 17:11:53 CDT; 2min 49s ago
    Process: 17336 ExecStart=/usr/bin/pg_ctl -s -D ${PGROOT}/data start -w -t 120 (code=exited, status=1/FAILURE)
        CPU: 7ms

Oct 26 17:11:53 SVRNAME systemd[1]: Starting PostgreSQL database server...
Oct 26 17:11:53 SRVNAME postgres[17338]: 2021-10-26 17:11:53.420 CDT [17338] FATAL:
                database files are incompatible with server
Oct 26 17:11:53 SRVNAME postgres[17338]: 2021-10-26 17:11:53.420 CDT [17338] DETAIL:
                The data directory was initialized by PostgreSQL version 13,
                which is not compatible with this version 14.0.
Oct 26 17:11:53 SRVNAME postgres[17336]: pg_ctl: could not start server
Oct 26 17:11:53 SRVNAME postgres[17336]: Examine the log output.
Oct 26 17:11:53 SRVNAME systemd[1]: postgresql.service: Control process exited, code=exited, status=1/FAILURE
Oct 26 17:11:53 SRVNAME systemd[1]: postgresql.service: Failed with result 'exit-code'.
Oct 26 17:11:53 SRVNAME systemd[1]: Failed to start PostgreSQL database server.

为避免出现此类情况(即数据库服务器软件拒绝启动),请阅读以下关于升级 DBMS(数据库管理系统)最佳方式的讨论。

上述错误的根本原因是服务器软件升级到了更新的主版本,而数据文件原封未动。在该案例中,管理员得以在没有任何数据丢失的情况下恢复 DBMS。

即便你是在初次安装 DBMS,也请通读本节。本节提供了有关实现备份和恢复流程(或至少是创建这些流程的策略)的信息,以满足你的需求并保证数据安全。

升级数据库服务器软件包

数据库系统所操作的文件,保存着数据库的元数据以及数据本身。这些文件的内部结构是针对服务器软件的使用而优化的。当此类服务器软件升级时,新软件所使用的文件格式可能与先前不同。有时新软件既能使用旧格式,也能使用新格式——但无法获得新格式带来的性能提升。还有些时候,新的服务器软件会在升级之后自动重新格式化数据文件。

然而不幸的是,最可能的情况是新的服务器软件抱怨文件格式过时并退出。一旦发生这种情况,而你已经覆盖了旧的服务器软件,最终可能得到一个损坏的系统以及丢失的数据。

数据文件格式的变更通常发生在主版本更替之时,但也可能在其他时候出现。在升级任何 DBMS 软件之前,请查阅文档,确认此次升级是否引入了需要重新格式化数据库的变更。

当然,如果你的数据库中存放着不易重建的内容,定期为数据库创建备份始终是个好主意。在升级服务器软件之前,你还应当再执行一次备份。

通过备份和恢复进行升级

[注意]

注意

如果没有经过验证的、从该备份恢复数据的流程,备份就毫无意义。在运行数据库服务器时,你不仅要创建备份,还要验证恢复流程确实可行。测试恢复流程的时机应当是在你急需恢复丢失数据之前。

大多数数据库服务器软件都提供了一些基本工具来为数据创建备份。通常,用这些工具创建的备份可以由更新版本的软件读取(通过恢复工具)。用旧的恢复工具去读取新备份的数据是个糟糕的主意;你应当绝不盲目假定它会奏效。也许可行,但通常都不行。

升级数据库文件最简单的方式如下:

  • 使用旧工具创建完整的数据库备份。

    这一步会创建数据库文件的离线副本——用于长期归档、灾难恢复,或作为升级前的准备。这种离线备份要么是(1)当前数据库文件的完整一对一副本,要么是(2)某一时间点的数据库文件完整备份,再加上该时间点之后描述所有变更的日志数据(这是 Oracle® 的术语,在 PostgreSQL 中称为“Continuous Archiving”或“write ahead log(WAL)”)。第二种形式创建起来更快(前提是 DB 软件提供此类日志功能),因为你只需保存自上次完整备份以来发生变化的数据。

    在升级数据库服务器软件时,应当创建一次完整备份(可用于后续的增量备份);但如果数据量很大,增量备份也足够了。最合适的策略取决于你数据库中存储的数据量(是几百行表记录,还是几百 TB?)。后一种情况下,完整备份无法迅速完成。为了全面保护你的数据,请创建旧程序(和/或其源代码)的备份并将其与数据文件一同保存,以确保在新软件无法读取旧数据时存在回退方案。

  • 升级服务器软件

    在这一步中,按照后续章节中关于 MariaDB 或 PostgreSQL 等 DBMS 的说明来执行数据库服务器软件的构建,正如其中所示。也就是说,像往常一样使用 BLFS 说明来构建软件。

  • 使用新工具恢复数据库。

    恢复数据时,应当使用新安装的服务器软件所提供的工具。在恢复过程中,新工具会以新软件所需的格式创建和/或升级数据文件。此处假定较新的软件能够读取旧数据。

既然你已经有了一套备份流程(而且你已经测试过恢复流程,对吧?),这可能是最简单的升级方式——至少在备份和恢复方面,你可以使用自己熟悉的一贯流程来进行升级。

使用系统工具升级数据库文件

某些数据库系统(例如 PostgreSQL)提供了一种工具,能够将现有数据库文件重新格式化(升级)为新格式。如果你需要从备份恢复(例如,运行升级工具失败),就不得不重新安装旧软件来恢复数据。

即便重新格式化工具如其所述那样工作,在运行它们之前你也应当创建一次完整备份。一次失败可能对数据库造成严重损害。

特定 DBMS 的说明

PostgreSQL

上游关于备份/恢复的文档: https://www.postgresql.org/docs/current/backup.html

MariaDB

上游关于备份/恢复的文档: https://mariadb.com/kb/en/backup-and-restore-overview/

Sqlite

不要小看 Sqlite。它是一个功能丰富的 DBMS。它与上述两大主流产品的主要区别在于,Sqlite 不通过网络 API 提供访问。Sqlite 数据库始终存储在运行使用该数据库的程序所在的那台机器上。数据内容的操纵是通过在程序内部直接调用库函数的 API 来完成的。

在上游文档中,你可能会发现以下内容有用:

sqlite3 命令行工具文档: https://www.sqlite.org/cli.html

备份 API 调用文档: https://www.sqlite.org/backup.html

遗憾的是,上游文档中并没有专门讨论备份/恢复的章节,但在互联网上有若干相关文章。这里是一个示例。

备份/恢复文档: https://database.guide/backup-sqlite-database/

LMDB

Sqlite 类似,本软件作用于本地数据库文件;没有网络接口。

备份/恢复 LMDB 数据库的相关资源是 mdb_dump 及其对应工具 mdb_load 的 man 手册页。