简介:面向64位Windows环境的PostgreSQL 9.1.3安装压缩包,适合需要在传统Windows服务器或老旧生产环境中部署开源关系型数据库的运维人员、DBA及数据库初学者。该版本虽是2012年发布的稳定版,但已具备MVCC并发控制、全文检索、窗口函数、存储过程、异步复制等核心能力,可用于构建中小型业务系统或学习数据库原理。压缩包共2个文件,包含一个exe安装程序和一个htm说明文档,整体约48.18MB,说明文档涵盖系统需求与安装引导。已有796人学习下载,可直接作为Windows x64环境下的部署参考。通过实际安装配置,读者能掌握数据目录设置、端口与连接参数调整、超级用户创建等基础操作,并可借助pgAdmin进行日常管理,为后续使用PL/pgSQL或处理复杂查询打下基础。
1. 一个 2013 年的安装包还在流传:postgresql-9.1.3-1-windows-x64 到底是什么
很多人在查“postgresql下载哪个版本”的时候,会被老教程带到这个文件名上:postgresql-9.1.3-1-windows-x64。双击安装完,要么服务起不来,要么 psql 连不上,最后跑到群聊里问“这个版本是不是坏了”。它不是坏了,而是太老了。这是 PostgreSQL 9.1 系列的第三个补丁版,由 EnterpriseDB 打包发布的原生 64 位 Windows 安装程序,发布于 2013 年前后。它的价值不在新,而在老:旧系统维护、老项目迁移前做基线验证、以及给历史数据找一个能带走的出口。这篇笔记写给要碰老实例的人和替旧系统擦玻璃的运维,新项目请直接看 16 或 17,别碰 9.1。
2. 拆解安装包:9.1.3-1 在 Windows x64 上的真实身份与前置条件
安装包的命名不是乱来的。9.1.3 是版本号,-1 是 EnterpriseDB(EDB)的打包序号,windows-x64 说明这是一个原生 64 位构建,不是 32 位程序在兼容模式下跑。搞清楚这层之后,后续所有安装和排错才会有方向。
2.1 文件名与版本号:9.1.3 到底处于什么位置
PostgreSQL 的版本规则是“主版本.次版本.补丁版本”。9.1 是主版本,9.1.3 表示在 9.1 主版本上的第 3 个补丁发布。9.1 主版本上线于 2011 年,带来了扩展机制(EXTENSION)、可写公共表表达式(Writable CTE)和同步复制,这些都是后来很多运维习惯的基础。9.1.3 是 9.1 中期的一个补丁版,主要修掉了一批基础 bug,其中不少和 Windows 平台的数据目录锁、内存分配有关。
后面那个 -1 是 EDB 打包号,表示这个安装包是 EDB 对这个上游版本做的第 1 次 Windows 打包。EDB 的安装包会把 PostgreSQL 主程序、pgAdmin 客户端、Stack Builder 组件选择器一起塞进来,默认安装路径是 “C:\Program Files\PostgreSQL\9.1”,bin、lib、data、pgAdmin III 都在这个大目录里。之所以强调 64 位身份,是因为 9.1 时代还同时发布过 32 位构建,两个版本的数据目录不能互换使用,pg_ctl 读取 pid 文件的方式也不一样。
验证装进系统里的是不是 x64 版本,可以直接查 postgres.exe 的重定向头,也可以在 PowerShell 里看版本信息:
Get-ChildItem "C:\Program Files\PostgreSQL\9.1\bin\postgres.exe" | Select-Object FullName, @{Name='FileVer';Expression={$_.VersionInfo.FileVersion}}这段命令读取 postgres.exe 的文件版本号,能确认安装包是否真的落到了 x64 的程序目录。如果这个路径不存在,或者文件版本显示的是 9.1.3 但你安装时选了 32 位组件,后面做内存配置和共享缓冲区调整的时候,上限和参数行为都会不一样。
2.2 运行库前置条件:先装 VC++ x64 运行库,别急着双击
9.1.3-1 的 EDB 安装器是基于 InstallAnywhere 打包的,它会在安装过程中注册 Windows 服务和写入注册表项,对 C 运行库比较敏感。很多人在新虚拟机里直接双击安装包,进度条走到一半整体回滚,弹出一个“错误 1603”。这个错误我在实际维护里见过太多次,绝大多数是因为缺少 x64 的 VC++ 运行库。
9.1 时代静态链接的运行库版本主要是 Visual C++ 2013,所以安装前先检查两个文件是否存在:vcruntime140.dll 对应 2015-2022 运行库,msvcr120.dll 对应 2013 运行库。一条 PowerShell 命令可以同时看:
Get-ChildItem C:\Windows\System32\vcruntime140.dll, C:\Windows\System32\msvcr120.dll -ErrorAction SilentlyContinue | Select-Object Name, @{Name='Ver';Expression={$_.VersionInfo.FileVersion}}有输出就说明对应的 x64 运行库已经在系统里,没输出就去微软官方下载对应版本的 redistributable。装完 2013 再装 PG,没有先装运行库就反复重装 PG 或者把 32 位运行库当成 x64 来用,安装器照样报 1603。还有一点容易被忽略:64 位系统里 vcruntime140.dll 同时存在于 System32 和 SysWOW64,前者给 64 位程序用,后者给 32 位程序用。检查一定要看 System32 路径,SysWOW64 里的那一个对 postgresql-9.1.3-1-windows-x64 不起作用。
2.3 与新版对比:9.1.3 和 16/17 该怎么选
很多搜索“postgresql下载哪个版本”的人是先被某个教学视频带到这里的。9.1.3 和现在主流的 16、17 在安装体验、安全性和维护成本上差异非常大,不能说哪个更好,只能说哪个更合适:
| 对比项 | postgresql-9.1.3-1-windows-x64 | PostgreSQL 16/17 |
|---|---|---|
| 发布年份 | 2013 前后 | 近两年 |
| 生命周期 | 早已停止维护 | 仍在社区维护期 |
| 安全补丁 | 无 | 持续更新 |
| 安装器形态 | InstallAnywhere,单文件 exe | 标准 NSIS 安装器,流程更规范 |
| 默认认证 | md5 | scram-sha-256 |
| 数据目录结构 | PG_VERSION + data 目录,结构简单 | 同上,但新增大量并行 WAL 选项 |
| 适合场景 | 老实例复现、迁移源库、旧代码兼容 | 新项目、生产环境 |
只有两种情况值得装 9.1.3:一是生产线上确实还跑着 9.1 的旧实例,需要本机装一个同版本做对照测试;二是某个老业务系统指定要用这个版本。如果只是学习 PostgreSQL 或者搭新环境,直接上 16/17,否则你会在认证插件、默认权限和二进制目录结构这些地方白白消耗大量时间。
3. 从安装包到可用实例:初始化、服务注册和连接验证
“双击 exe 一直下一步”是能装完,但装完服务起不来、psql 连不上的概率不低。根因多半出在安装器把数据目录默认放在 “C:\Program Files\PostgreSQL\9.1\data”,Windows 的 UAC 和用户目录权限会在重启后拒绝 postgres 服务账户对数据目录的写操作。所以更靠谱的做法是安装器只装程序文件,数据目录单独初始化到独立盘符上。
3.1 安装向导里几个默认值要改掉
交互式安装的第一步让选安装目录,保持默认 “C:\Program Files\PostgreSQL\9.1” 就行,但第二步数据目录建议直接改成 D:\pgdata。这一步的路径后面要写进服务注册命令和数据目录参数,如果路径带空格或者中文字符,注册服务和读取配置都会碰到额外的转义问题。
接着是密码设置和端口号。9.1 的安装器会要求设置超级用户 postgres 的密码,注意 9.1.3 的默认加密方式是 md5,不是现在新版本里的 scrum-sha-256,后面所有客户端配置都要以 md5 为基准。端口默认 5432,如果机器上已经装了别的 PostgreSQL,把端口改成 5433,并记住这个端口,连接验证全部要带 -p 参数。
组件选择页面里,Stack Builder 那个扩展组件工具可以取消勾选,它通常需要联网下载额外组件,对本地部署没有帮助。pgAdmin III 是 9.1 自带的管理客户端,如果只是用 psql 操作,不勾选也不影响服务端功能。
3.2 手动初始化数据目录:initdb 的最小命令
安装器走完,bin 目录下已经有了 initdb.exe 和 pg_ctl.exe。用 initdb 初始化独立数据目录,这一步相当于把安装器和数据目录解耦,后续升级和备份都更灵活。在管理员 CMD 或 PowerShell 里执行:
"C:\Program Files\PostgreSQL\9.1\bin\initdb.exe" -D D:\pgdata -U postgres -W -A md5 -E UTF8 --locale=C这个命令里,-D 指定数据目录为 D:\pgdata,-U postgres 设置超级用户名称,-W 会提示手动输入两次密码,-A md5 把 pg_hba.conf 默认认证方式写成 md5,-E UTF8 把默认字符集设为 UTF-8,--locale=C 强制使用 C 排序规则。
-W 和 -A md5 要一起用,否则 initdb 生成的 pg_hba.conf 里是 trust 认证,服务能启动但客户端不需要密码就能进库,这在生产环境里是很危险的。--locale=C 这部分,Windows 平台上如果选了 Chinese 相关排序规则,某些老版本在 ORDER BY 中文时会出现和 Linux 端不一致的行为,统一用 C 排序规则能减少这类环境差异。
初始化结束后,D:\pgdata 下会出现 PG_VERSION、postgresql.conf、pg_hba.conf 和 base 目录等文件。看到这些文件,说明第一步成功。
3.3 注册 Windows 服务:pg_ctl register 与启动顺序
初始化好数据目录之后,用 pg_ctl 注册 Windows 服务,而不是直接双击 postgres.exe。直接双击只会在当前终端里跑一个前台进程,关掉窗口服务就没了,重启机器也不会自动拉起来。
"C:\Program Files\PostgreSQL\9.1\bin\pg_ctl.exe" register -N postgresql-9.1-x64 -D D:\pgdata -U postgres -P your_password -S auto net start postgresql-9.1-x64register 命令的作用是把 PostgreSQL 实例注册为 Windows 服务,-N 服务名写 postgresql-9.1-x64,-D 指定数据目录 D:\pgdata,-U 和 -P 指定服务登录账户和密码。服务账户建议用 postgres,它是安装器创建的低权限账户,专门用来跑数据库服务,避免用 Administrator 跑实例,出问题时权限边界不清楚。-S auto 让服务随 Windows 自动启动。
执行 net start 之后如果立即报“服务没有响应”,先不要急着重装。打开事件查看器看 PostgreSQL 日志,路径在 D:\pgdata\pg_log\postgresql-*.log,80% 的情况是数据目录权限不对或者端口被占用。日志里如果有 “could not bind IPv4” 字样,说明 5432 被别的进程吃掉了,去配置里改端口。
3.4 连接验证与防火墙放行
服务起来之后,第一件事不是连数据库,而是在本机确认端口监听状态。CMD 里执行下面的命令:
netstat -ano | findstr 5432看到 LISTENING 状态和对应 PID,说明服务在监听。如果 netstat 里完全没有 5432 的行,有两种可能:一是 postgresql.conf 里 listen_addresses 没生效,二是服务其实没起来。前者修改 postgresql.conf 里的 listen_addresses,本机连接写 localhost 即可,不需要改成 *。
端口正常后,用 psql 做一次真实连接:
"C:\Program Files\PostgreSQL\9.1\bin\psql.exe" -h 127.0.0.1 -p 5432 -U postgres -d postgres -W-h 指定 127.0.0.1 是为了强制走 TCP 而不是本机 IPC,这样可以顺便验证监听配置和密码认证是否生效。-W 会让 psql 交互式提示输入密码。如果等待远程客户端访问,再放行 Windows 防火墙:
netsh advfirewall firewall add rule name="PostgreSQL 9.1 5432" dir=in action=allow protocol=TCP localport=5432dir=in 表示放行入站流量,action=allow 允许连接,localport=5432 限定端口,避免把整个服务器的所有入站都放开。注意防火墙只放行端口,不会帮你处理认证,pg_hba.conf 里的 host 规则仍然会生效,远程机器能不能登录取决于那一行是 md5 还是 trust。
4. 老版本踩坑记录:五条从安装到连接的血泪经验
9.1.3 在 Windows 上的问题非常集中,很多都不是偶发,而是这个版本在特定环境下的必然结果。按“现象-原因-解决”的顺序整理五条,基本覆盖从安装到使用的绝大多数翻车点。
4.1 安装到一半回滚,报“错误 1603”
现象:双击 postgresql-9.1.3-1-windows-x64.exe,进度条走一大半后用安装日志显示“错误1603”,整个安装流程回滚,控制面板里也找不到残留。
原因:1603 是 Windows Installer 的通用错误,在 9.1.3 上最常见的原因有三个,按顺序排查:缺少 x64 的 VC++ 运行库,安装包注册服务或扩展名时失败;安装程序没有以管理员权限运行,Program Files 目录写入被拒;安全软件在安装过程中扫描并锁定了即将写入的 exe 和 dll 文件。
解决:先确认系统里有 msvcr120.dll 和 vcruntime140.dll 的 x64 版本,再右键安装包选择“以管理员身份运行”,然后临时退出安全软件。还有一个隐蔽点,9.1.3 安装器的解压临时目录默认在 %TEMP% 下,如果 C 盘剩余空间不足 1GB,安装器会在写临时文件时失败并回滚成 1603。先把 %TEMP% 的磁盘空间清出 2GB 再装,很多老机器上的 1603 就是这么解决的。
4.2 设置好的密码,psql 偏偏认证失败
现象:安装或 initdb 时明明设置了 postgres 密码,psql 连接却一直提示 password authentication failed,密码反复输入都不对。
原因:第一种是 pg_hba.conf 里 host 行的认证方式还是 trust。9.1.3 安装器在部分交互流程下会生成 trust 规则,psql 这时候根本不需要密码,一旦你输入密码反而会因为“多余的密码”触发校验失败。第二种是密码中包含特殊字符,比如 $、&、引号,在 initdb -W 交互输入或者命令行里被 CMD 转义,实际写入 pg_hba 的密码和你以为的不一样。
解决:打开 D:\pgdata\pg_hba.conf,确认这一段:
host all all 127.0.0.1/32 md5如果上面是 trust,改成 md5 然后重载配置。特殊字符问题,用 --pwfile 把密码写入临时文件再交给 initdb,避免命令行转义:
echo Your$trongP@ss> C:\temp\pgpw.txt "C:\Program Files\PostgreSQL\9.1\bin\initdb.exe" -D D:\pgdata -U postgres -A md5 --pwfile=C:\temp\pgpw.txt -E UTF8 --locale=C del C:\temp\pgpw.txt这里用 --pwfile 让 initdb 从文件读取密码,密码文件用完立刻删除,避免留在磁盘上。注意 CMD 里 echo 的 > 会创建文件,但结尾会多一个空格,如果密码末尾不能有空格,用 PowerShell 的 Set-Content 更精确。重载配置可以用 pg_ctl reload -D D:\pgdata,比重启服务影响小。
4.3 pgAdmin 连不上,psql 却一切正常
现象:psql 用 127.0.0.1 和 5432 能正常登录,打开 pgAdmin 3 填了同样的主机、端口和用户,连接时报 SSL 错误或者直接超时。
原因:9.1 的 pgAdmin 3 自带 libpq 的 SSL 默认行为和后来的 Windows 系统 SSL 配置有兼容问题,尤其是当 pg_hba.conf 里没有显式关闭 SSL 时,pgAdmin 会先尝试 SSL 加密握手,而 9.1.3 的加密证书链在老系统上可能没有正确装载。另一个原因是 pgAdmin 里主机名填了 localhost,在 Windows 上 localhost 解析到 IPv6 ::1,而 postgresql.conf 里 listen_addresses 默认只监听了 127.0.0.1。
解决:在 pgAdmin 连接属性里把 SSL 选项明确设为 disable,主机地址写 127.0.0.1 而不是 localhost。如果必须走 SSL,就得去看服务端 postgresql.conf 里 ssl 是否打开,以及是否配置了 server.crt 和 server.key。9.1.3 默认 ssl=off,这是老版本和现在 pgAdmin 之间最常见的错位点。换成 psql 做日常操作就没这些麻烦,pgAdmin 只用来查表和看执行计划。
4.4 重启服务器后服务一直停在“正在启动”,最后报 1053
现象:Windows 服务管理器里 postgresql-9.1-x64 显示“正在启动”,等几十秒后自动变回“已停止”,事件日志里出现“服务没有及时响应启动或控制请求(1053)”。
原因:服务登录账户的密码在重启后失效,或者数据目录 D:\pgdata 所在磁盘的权限没有给服务账户。9.1.3 注册服务时用 -U postgres -P 指定了密码,一旦 Windows 账户策略强制该账户下次登录必须改密码,服务就会起不来。另一个原因是 D:\pgdata 是在当前管理员账户下创建的,目录 ACL 只给了这个管理员,服务账户 postgres 没有读权限,启动时读不到 PG_VERSION 直接失败。
解决:打开服务管理器,双击 postgresql-9.1-x64 服务,切到“登录”选项卡,把登录身份改成“本地系统账户”,重启服务,先确认数据目录本身没有损坏。如果是权限问题,用 icacls 给服务账户授予完全控制:
icacls D:\pgdata /grant "postgres:(OI)(CI)F" /T这个命令把 D:\pgdata 及其子目录和文件的完全控制权限显式授予 postgres 账户。注意 1053 的本质是服务超时,有时杀毒软件扫描数据文件也会拖慢启动,但权限和密码过期是最常见的两个根因,先排查它们再去动杀毒配置。
4.5 5432 端口被占用,服务起来但连不上
现象:服务显示正在运行,netstat -ano | findstr 5432 却输出另一个 PID,psql 连接报 connection refused 或超时。
原因:机器上之前装过别的 PostgreSQL 版本,老实例还占着 5432,或者 nginx、其他中间件把 5432 当默认端口。9.1.3 安装器检测到端口冲突时往往会静默跳到 5433,但手动注册服务时如果没注意配置就启动在 5432,实际监听不到。
解决:先用 netstat 拿到占用进程的 PID,再在任务管理器里确认进程名。如果确实是另一个实例,不要 taskkill 乱杀,避免影响别的业务,直接把 9.1.3 的端口改成未被占用的值:
port = 5433改完 D:\pgdata\postgresql.conf 后重启服务:
pg_ctl reload -D D:\pgdatareload 对端口修改不生效,端口属于启动参数,必须完全重启服务才能读到新值,所以这里要执行 net stop postgresql-9.1-x64 然后 net start,或者用 pg_ctl restart -D D:\pgdata。改端口之后所有客户端连接都必须带 -p 5433,否则还是连不上。还有一个细节,pg_hba.conf 里注释掉的行不影响端口,但如果你在文件里写过 port 字段,那只会被当作注释解析,不会覆盖 postgresql.conf。
5. 把老实例的数据安全带走:pg_dump 备份与恢复验证
9.1.3 不管跑得多顺,它都是一个停止维护的老版本。真正要做的事情是把数据从这个黑匣子里完整带出来,迁到新版或者至少留一个可恢复的备份。逻辑备份是这条路上最可靠的后悔药。
5.1 逻辑备份的最小命令:单库、全部库、角色
单库备份用 pg_dump,custom 格式是首选,因为它带压缩、支持并行恢复,还能用 pg_restore 选择性恢复单个表:
"C:\Program Files\PostgreSQL\9.1\bin\pg_dump.exe" -h 127.0.0.1 -p 5432 -U postgres -d mydb -F c -f D:\backup\mydb_913.dump -v-F c 表示 custom 格式,-f 指定备份文件路径,-v 打印每个对象的导出进度。需要包含角色和表空间的话,9.1 的 pg_dump 是不导全局对象的,要额外用 pg_dumpall 的 globals-only:
"C:\Program Files\PostgreSQL\9.1\bin\pg_dumpall.exe" -h 127.0.0.1 -U postgres --globals-only -f D:\backup\globals_913.sql--globals-only 只导出角色、组和表空间定义,不导出表数据,这个文件很小但迁移时必须有,否则恢复出来的库没有原用户,权限全乱。
5.2 恢复到新实例及校验方法
目标实例上先建一个空库,再执行 pg_restore。命令和参数是这样:
"C:\Program Files\PostgreSQL\9.1\bin\createdb.exe" -h 127.0.0.1 -p 5433 -U postgres newdb pg_restore -h 127.0.0.1 -p 5433 -U postgres -d newdb --no-owner -j 4 D:\backup\mydb_913.dump--no-owner 忽略备份文件里的对象属主,全部归到当前连接用户,避免老实例里的用户名在新环境不存在时恢复中断。-j 4 是并行任务数,custom 格式支持并行恢复,四个线程同时建索引和导数据,速度比单线程明显快。恢复完成后用 psql 校验行数和对象数量:
psql -h 127.0.0.1 -p 5433 -U postgres -d newdb -c "SELECT count(*) FROM pg_tables WHERE schemaname='public';"比对手上老实例的 pg_tables 数量,差距通常是视图中依赖的对象或扩展表。对象清单确认后,随机抽三张业务表对比行数,再检查序列是否落后。9.1 的序列在恢复后有时会停留在备份时的值,而不是数据表最大 ID,插入新数据时直接主键冲突。用这条 SQL 校准:
SELECT setval(seq.oid::regclass, max_val) FROM pg_class seq JOIN pg_namespace n ON n.oid = seq.relnamespace JOIN pg_attribute att ON att.attrelid = seq.relreplident, (SELECT max(id) AS max_val FROM mydb_table) t WHERE seq.relkind = 'S' AND att.attname = 'last_value';seq.relkind = 'S' 筛选出序列对象,把序列推进到业务表当前最大 ID,避免插入时报 duplicate key。校准完再插入一条测试数据,确认自增正常,备份恢复流程才算真正闭环。我养成的一个习惯是,凡是碰老版本实例,先导出一份纯 SQL 文本备份再操作,custom 格式留着给 pg_restore 用,SQL 文本留着给最坏情况做手工修补。希望帮到你。
本文还有配套的精品资源,点击获取