唉!升级...升级...升级...这一阵子一直升级,这次轮到 PostgreSQL 大升级。PostgreSQL 不像其它软件,即使是 8.2 升级到 8.3,也必须大改,所以无法直接用 upgrade 工具直接升。即使是 Windows 版本,也必须劳心费力一番。这次我用 FreeBSD 版本的升级做为例子,来说明最简单也是最正确的大改版升级步骤。
首先,请先把原本数据库的数据完全备份下来。如果你是 Windows 的使用者或是 Linux 的使用者,你可以考虑使用 pgAdmin III 的「工具」选单中的「备份」或「备份全域」来做,这样简单很多,但是由于 pgAdmin III 的说明太少,我实在看不懂「备份」对话框中选项的含意,所以干脆不用。最正式的方法是使用在 console 下的工具:pg_dump 和 pg_dumpall。两者的差别在于,前者可以针对某个特定的 database 做备份,而后者一般用来把整个服务器数据做完整的备份。我建议直接使用 pg_dumpall 比较方便和快速。方法如下:
$ pg_dumpall > filename
而 filename 你可以自己取,比如 host_a.20080206.full.dump 之类的。名称中加入日期可以让你更清楚知道这个备份档备份的日期。加入 full 字眼,可以提醒自己,这是完整备份,而非一般维护时所做的连续性部份备份的一份。如果你所管理的 PostgreSQL 有超过一台以上,那么最好连数据库主机名称都注明。
对了,差点忘了一件极重要的事!在 Windows 上,只要你使用 administrators 群组中的任何一位使用者登入,然后从开始菜单→PostgreSQL 8.3→Command Prompt,就可以打开「命令提示字符」,而且可以下达 pg_dumpall 指令;但是,在 FreeBSD,一般安装时,预设 root 是不允许执行 PostgreSQL 的相关指令的,所以请先切换成 pgsql 用户,如果你没更动 pgsql 的密码,那么预设的密码很「随机」,也就是任你怎么猜也都猜不出来,但是你可以先用 su 切成 root,再用 su - pgsql 切换成 pgsql 使用者,不用输入任何密码即可,这时就可以执行上述指令。但是请注意,这时最好把这个备份文件移到安全位置,以免继续进行的安装过程中不傎误砍。所以这时候你最好是先跳回 root,请下 exit 指令,然后用 cp 指令把刚才那个 dump 檔 copy 到任何你暂存的位置。
接着正式执行安装。在安装新版本之前,必须先移除旧版本,否则两个 daemon 会抢同一个 TCP port,开机时会有无法预知的状况出现。首先先看一下你的服务器中,目前装了哪些和 PostgreSQL 相关的 package:
# pkg_info grep postgresql
这时候你至少可以看到两个 package 出现在清单中,而我多了一个:
postgresql-client-8.2.6_1 PostgreSQL database (client)postgresql-contrib-8.2.6 The contrib utilities from the PostgreSQL distributionpostgresql-server-8.2.6 The most advanced open-source database available anywhere
一般来说,如果你没有安装Server instrumentation 功能,那么应该只有 client 和 server 两个 package。但是这个小清单并不完整,如果你还有安装 php 和 PostgreSQL 相关的驱动程序,那么这时候并不会出现在这个清单当中。不用担心,你若移除的顺序不对,出现相依的套件,那么把相依套件移除,再来移除目标套件即可。只是这时候你最好拿只笔记下你一共移除了哪些套件,将来才能再一一重新安装回去。我们先以这三个 package 来说好了,如果你没移除旧版本的 server,那么直接移除 client 会被提醒,而且停止进行安装动作。同样的,如果你没先移除旧版本的 contrib 和 php 相关 package,你在移除 client 时也会因为相依套件尚未被移除,而被停止移除 client 的动作。所以若以上述三者为例,则移除的顺序为:
# /usr/local/etc/rc.d/postgresql stop <-- 先停掉目前的 PostgreSQL server# pkg_delete postgresql-contrib-8.2.6# pkg_delete postgresql-server-8.2.6# pkg_delete postgresql-client-8.2.6_1
这时请把 /usr/local/pgsql/data 整个目录移走,像我只是把它改个名称,而让它继续留着,说不定哪天还会用到目录中的某些档案:mv /usr/local/pgsql/data /usr/local/pgsql/data_8.2。然后就可以开始使用 port 来安装 PostgreSQL 8.3 了。在安装前,请先确定你的服务器上的 port tree 是否已是最新的版本,如果你的 port tree 是在 2008/2/5 天亮前更新的,可能 postgresql-server-8.3 还不是最新版本,请先手动更新 port tree。如果已是最新版本,那么切到该 port 目录:
# cd /usr/ports/databases/postgresql83-server# make install clean
FreeBSD 会自动帮你将 8.3 版的 server 和 client 都一并装好。接着把 contrib package 也装起来:
# cd ../postgresql-contrib# make install clean
如果你曾经把 php5 的 driver 移除掉或 JDBC 等等等之前移除掉的套件,现在也请用同样的方法把所有新的版本一一装回去。这样就好了吗?还早,请先看一下你的 /usr/local/pgsql 下是否已经建好新的数据库?
# ls /usr/local/pgsql
如果这个目录下只出现一个刚才更名的 data_8.2,那么代表 Makefile 并没有自动帮你做 initdb,请执行:
# /usr/local/etc/rc.d/postgresql initdb [1]
这时你再下 ls /usr/local/pgsql 指令时,就可以看到多出一个 data 目录了,这样才能正确启动 PostgreSQL:
# /usr/local/etc/rc.d/postgresql start [2]
如果没出现任何错误讯息,那么先恭喜你,安装好了。但是工作才完成一半,再来是把原来备份的数据回存回数据库中:
# su - pgsql$ psql -f filename postgres
也就是先切成 pgsql 使用者,接着执行 PostgreSQL 的交互式指令输入工具:psql,然后把刚才你的 dump 档的名称(这里当然是完整路径名称)取代上面的 filename。接着一些讯息代表着数据库回存的动作,正在做什么动作。如果一切错误讯息都没有出现过,那么恭喜你,工作完成了 80%。对于 Windows 的使用者来说,只要记住最后一条指令,就可以把刚才 pg_dumpall 所备份的数据回存了。Windows 的使用者真幸福。
什么?才完成 80%?是的,有两个档可能之前的版本你有更动过,分别是 postgresql.conf 和 pg_hba.conf,它们在 FreeBSD 中应该位于 /usr/local/pgsql/data 目录下,请把之前曾经更动过的改回去,但是请把 release notes 先读过一遍,因为 postgresql.conf 中很多管理项目都更动过了,可能之前你所更改的项目,8.3 版已经把该项和其它项目合并,并取了新的项目名称了,先读过 release notes 的 E.1.2.2. Configuration Parameters 是很重要的。还有,刚才如果把旧的 8.2 版的 /usr/local/pgsql/data 目录直接删掉,那此刻就糗了,你必须用你的记忆力回想你曾经更动过的项目和内容,所以我才会建议只需把它更名,保留下来。
若是你对 PostgreSQL 的备份和回存有兴趣,英文程序也还可以,那么请进一步参考 PostgreSQL 的在线说明:Chapter 24. Backup and Restore。
附注:[1] 当然啰,如果新的 data 目录已经生成,也就是 Makefile 已经自动帮你执行 initdb 的动作了,那么 initdb 这个动作就可以省了。我会特别这样提的原因是,我现这两天的抢先版本的 Makefile 怪怪的,有时不会自动执行 initdb 动作。 [2] 如果你没有像我这么麻烦的用 pg_dumpall 和 psql 来备份回存,直接升级(还是得先移除旧版本再安装新版本),表面上看起来还是可以升级,但是,事实上 Makefile 会把你旧版本的 postgresql.conf 和 pg_hba.conf 复制一份到新的 data 目录中。如我文中所说的,postgresql.conf 在这个版本中有大更动,因此,当你打算启动数据库时,会出现 FATAL ERROR!解决方法很简单,用不着重灌,把新的 data 目录移走(一样用更名的),执行 /usr/local/etc/postgresql initdb,重做一次 initdb,就会有一个全新版本的 data 了。[3] 这篇文章仅适用于负载不大的服务器上,倘若你的服务器是 mission critical 的大用量服务器,虽然基本的升级概念是一样的,也就是数据库大升级等同重新安装,所以服务势必一定得中断,但是事前的演练和良好的计划,可以让停机服务的时间减少。在这种情况,建议必须得增加备援服务器,在主服务器升级的同时,让备援服务器先暂时服务。说到这里,就得牵涉到「数据库复制」(replication) 的主题了。等我有空再来写一篇 PostgreSQL 和 replication 相关的文章。
星期二, 十月 07, 2008
订阅:
博文评论 (Atom)

没有评论:
发表评论