Qlik Sense 跑久了,很多人都会遇到一个“看不见但绕不开”的东西——Repository Database(repo 库)。装完 Qlik Sense 后,它默认跟着一个捆绑的 PostgreSQL 实例一起跑,这个实例藏在 Qlik 自己的安装目录里,版本往往比生产环境用的 PostgreSQL 老,资源还经常和 Qlik 服务抢。想单独调参数、想自己做备份、想把数据库交给专职 DBA 管理,都很难下手。这篇文章要聊的,就是怎么用 Qlik 官方出的 Qlik PostgreSQL Installer,把 repo 库从捆绑实例里拆出来(unbundling),同时把 PostgreSQL 版本升上去。适合正在优化 Qlik 站点性能、准备做多节点部署、或者被数据库运维权限问题烦得不行的同学。我会把完整思路、备份方法、实操步骤和踩坑经历都写清楚,照着走基本能平稳切换。
1. 为什么要把 Repo 库“解绑”,以及和升级的关系
1.1 捆绑模式到底是怎么回事
Qlik Sense 从安装包设计上就给你内置了一个 PostgreSQL 实例作为站点元数据库。它不是那种你在系统里能随便看到的 PostgreSQL,而是藏在 Qlik 自己的目录结构里。数据目录一般在C:\ProgramData\Qlik\Sense\Repository\PostgreSQL下面,旧版本还会带版本号子目录,比如9.6\data;对应的 Windows 服务名通常是QlikSenseRepositoryDatabase。Qlik Sense 的 Repository Service 起来之后会直连这个库,读写应用元数据、用户权限、调度任务、审计日志,整个站点的“大脑”基本都在这一个库里。
这个设计的好处是开箱即用,装完 Qlik 不用再单独准备一套数据库,对第一次部署的人来说确实省事。但代价也很明显:你对这个 PostgreSQL 实例的控制力相当有限。它虽然注册成了标准服务,但 Qlik 默认把它当站点内部组件来管理,你没法像普通数据库那样自由换端口、调shared_buffers、做从库复制。更麻烦的是,Qlik Sense 升级换版本时,捆绑的 PostgreSQL 版本往往不会跟着大版本通升,经常出现站点版本挺新、底层数据库却还是老版本的情况。时间一长,这个“黑盒数据库”就成了运维里最尴尬的一环。
1.2 解绑换来什么,又失去什么
真正推动我下决心做 unbundling 的,倒不是版本老,而是资源竞争。Qlik Sense 本身是内存敏感型应用,repository 服务的很多查询都是本地操作;如果同一个实例上的 PostgreSQL 还占着内存、用着默认的 128MBshared_buffers,站点一忙起来两边抢 CPU,QMC 打开都卡。把 repo 库搬到独立实例后,两个服务互不干扰,PostgreSQL 的缓存和连接池可以按实际负载调,Qlik 站点整体响应会明显更稳。
除了性能,独立 PostgreSQL 实例还能做更细粒度的备份策略。捆绑时期多数人只能依赖 Qlik 自带的后台备份机制,恢复粒度粗、备份时间不好控制;解绑之后你可以指定什么时候全量 dump、什么时候做 WAL 归档,数据量大还能上 PITR(按时间点恢复)。权限体系也完全独立,DBA 不需要去摸 Qlik 安装目录,按标准 PostgreSQL 流程管理就行。再往后说,Qlik Sense 多节点架构里,repo 库想放在独立数据库服务器上,就必须先解绑;后续 Qlik 大版本升级时,如果数据库还捆在旧实例里,升级路径会非常被动。
代价当然也有。多一个服务要维护,连接串要改,权限验证逻辑变了,一旦切换出问题,回滚比单纯升级要多一步。而且解绑这事不是一锤子买卖——所有指向旧库的周边连接都得清干净,后面会专门讲这个坑。所以我说这个操作不是必须的,但很值得在站点稳定期做。顺便说一句,官方知识库之所以把“升级”和“解绑”放在同一个流程里,正是因为从捆绑实例换到独立实例这个动作,天然就是一次版本跃迁的机会,两个动作一起做最省事。
2. 动手前准备:版本、备份、工具
2.1 先搞清楚你的环境是什么版本
动手之前,先摸清三件事:Qlik Sense 版本、捆绑 PostgreSQL 版本、目标 PostgreSQL 版本。Qlik 版本可以在 QMC 的 “About” 或者安装目录的setup.ini里看,最直接的办法是打开 QMC 看标题栏的版本号;PostgreSQL 版本则进入捆绑实例用 psql 执行:
SELECT version();或者直接看数据目录下的PG_VERSION文件。这里要提醒的是,不同 Qlik Sense 版本默认捆绑的 PostgreSQL 版本不一样,早期常见的是 9.6,后来有 10、12、13、14 等。你不能拿一个老站点的数据目录直接塞给一个 PostgreSQL 16 的新实例,跨大版本的数据目录复制很可能起不来。下面给一个常见升级路径参考表,具体支持情况以 Qlik 官方 Release Notes 为准。
| 当前捆绑版本 | 常见目标版本 | 迁移方式建议 |
|---|---|---|
| 9.6 | 10 / 12 | dump/restore,或逐级升级 |
| 10 | 12 / 14 | dump/restore 推荐 |
| 12 | 14 / 16 | dump/restore 推荐 |
| 14 | 16 | dump/restore 或 pg_upgrade |
目标版本怎么选?我的建议是:先看当前 Qlik Sense 版本的 Supported PostgreSQL versions,再结合你自己的运维栈。比如你们公司其他业务库都已经在 PG 14 了,那就选 14;如果 Qlik 版本比较新,官方可能也已经认证了 16。不要为了追新上还没进 Qlik 兼容矩阵的版本,repo 库不像普通业务库,Qlik Repository Service 对 PostgreSQL 的连接实现有版本适配,盲目用最新版容易踩加密认证或驱动兼容的坑。
2.2 备份 repo 库:这一步绝不能省
备份是整条链路里最不能省的一步。无论你后面用 dump/restore 还是拷贝数据目录,迁移前都必须有一份完整可验证的备份。我的习惯是直接用捆绑实例自带的 pg_dump,它就在C:\Program Files\Qlik\Sense\Repository\PostgreSQL\9.6\bin(路径里的版本号按实际情况改)。打开命令提示符,执行类似下面的命令:
"C:\Program Files\Qlik\Sense\Repository\PostgreSQL\9.6\bin\pg_dump.exe" -h localhost -p 4432 -U postgres -F c -b -v -f "D:\qlik_backup\qsr_before_upgrade.dump" QSR参数说明一下:-h localhost和-p 4432是 Qlik 捆绑实例默认的监听地址和端口,-U postgres用超级用户,-F c输出为自定义压缩格式,-b包含大对象(repo 库偶尔会存日志、附件之类),-v打印详细过程,最后那个QSR是默认的仓库数据库名。备份文件出来后,先别急着走下一步,我还会用pg_restore --list看一眼内容:
"C:\Program Files\Qlik\Sense\Repository\PostgreSQL\9.6\bin\pg_restore.exe" --list "D:\qlik_backup\qsr_before_upgrade.dump" | more能正常列出表清单,说明 dump 没坏。备份窗口我建议选业务低峰,最好是先停掉 Qlik Sense Scheduler 的调度,避免有人在此时触发 reload 写入新数据;如果站点是 7x24 没法完全停,至少确认pg_stat_activity里没有大量写事务再开跑。另外,顺便把当前实例的端口号、超级用户密码、数据库名、数据目录路径记到一处,后面切换连接的时候一定用得上。
2.3 Qlik PostgreSQL Installer 怎么选、怎么理解
Qlik 官方针对这个场景提供了一个专门工具:Qlik PostgreSQL Installer。名字听着就是 PostgreSQL 安装器,但千万别直接去 PostgreSQL 官网下原生安装包替代。这个安装器有几个隐藏的定制项:默认监听端口设成 4432 而不是 5432,默认服务名带-Qlik后缀(比如postgresql-x64-16-Qlik),默认数据库和用户的设计也贴合 repo 库的迁移需求。还有一个关键点:它的安装向导里可以直接选择“从已有 Qlik 备份/数据目录恢复”或者“全新空库”,这两个模式在切换流程里的作用不同,稍后会讲。
下载渠道就是 Qlik 官方下载站点或者社区 KB 里对应文章附件,优先选和你 Qlik Sense 版本匹配的安装器版本。跑的时候记得右键“以管理员身份运行”,安装路径建议别带空格和中文,比如C:\Program Files\Qlik\PostgreSQL\16。数据目录则放在C:\ProgramData\Qlik\PostgreSQL\16\data,这样和系统盘分开,备份也更好规划。这里多说一句:安装器本质上是“PostgreSQL 官方安装向导的 Qlik 定制版”,但它解决的恰恰是 Qlik 场景里最麻烦的兼容性问题。如果你用原生安装包装出来,连接串、认证方式、服务命名都对不上,后面排查起来非常痛苦。
3. 升级 + 解绑实操全记录
3.1 步骤一:安装独立 PostgreSQL 实例
安装流程按向导走,我挑几个关键点讲。第一步选组件,通常全选默认;第二步设数据目录,如果准备用 dump/restore 迁移,这里直接给个新目录就行,比如C:\ProgramData\Qlik\PostgreSQL\16\data;第三步设端口和认证。端口我几乎总是沿用 4432,因为 Qlik 连接串默认习惯用它;如果 4432 已经被系统里某个进程占用,你可以换成 5433 等,但一定要记住,后面切换连接时别填错。
超级用户postgres的密码要设一个强密码,并且记录到密码管理器里,后面 QMC 改连接串要用。服务账号建议沿用安装器生成的本地账号,也可以指定一个域账号,但那个域账号必须已经具备“作为服务登录”的权限。装完后确认 Windows 服务里出现postgresql-x64-16-Qlik,并且状态是 Running。用 psql 实测:
"C:\Program Files\Qlik\PostgreSQL\16\bin\psql.exe" -h localhost -p 4432 -U postgres -c "SELECT version();"能返回 PostgreSQL 16.x 就说明实例就绪。这里我会顺便检查一下新实例里有没有 QSR 这个库。没有就下一步建;有但数据不对,就删掉重建,确保后面 restore 不会因为对象已存在而中断。
3.2 步骤二:把 QSR 数据搬过去
数据迁移我重点讲 dump/restore 这条路线,实践下来最稳,不受新旧实例的二进制兼容影响。先在新实例里建一个 QSR 空库:
"C:\Program Files\Qlik\PostgreSQL\16\bin\createdb.exe" -h localhost -p 4432 -U postgres QSR然后执行恢复:
"C:\Program Files\Qlik\PostgreSQL\16\bin\pg_restore.exe" -h localhost -p 4432 -U postgres -d QSR --no-owner --no-privileges -v "D:\qlik_backup\qsr_before_upgrade.dump"这里有两个参数要单独说。--no-owner和--no-privileges是避免 dump 文件里的旧角色、旧权限定义在新实例里报错;但注意,这不等于权限不用管——Qlik Repository Service 在新实例里要用的登录用户,比如常见的qliksense,你要提前用CREATE ROLE建好,并授予对 QSR 的读写权限。最简单的做法:用postgres超级用户恢复完数据后,再执行:
CREATE USER qliksense WITH PASSWORD 'YourPassword'; GRANT ALL PRIVILEGES ON DATABASE QSR TO qliksense;然后还要根据 schema 情况做循环授权,因为 Qlik 的表不一定都在 public schema 下,用\dn看一下实际有哪些 schema,再把对应权限补上。恢复过程中的日志要仔细扫一遍,最常见的非致命错误是某些扩展插件级别的对象没建上,不影响 QSR 主体;但如果出现ERROR: permission denied或does not exist,先别急着继续,把报错内容截图,确认是不是要手动补。
还有一种路线是直接把旧数据目录整体拷到新实例,前提是版本一致或者官方明确支持该升级路径,而且旧实例必须处于停止状态,拷完还要处理postgresql.conf里的路径配置。这条路速度最快,但风险也最高,跨大版本基本不可行,我一般不推荐。如果非要用,请先准备好回滚方案,至少保证旧实例的原目录原封不动。
3.3 步骤三:把 Qlik Sense 连接切到新实例
数据到位后,关键动作是让 Qlik Sense 认新实例。最常见的入口是 QMC。登录 QMC,找到 Database connections(数据库连接)配置页,里面维护着 Repository 数据库的连接串。需要把连接串从旧捆绑实例改成新实例,大致的格式是这样:
Host=localhost;Port=4432;Database=QSR;User ID=qliksense;Password=YourPassword;保存之后,按顺序重启服务:先停止QlikSenseRepositoryService,再停止旧捆绑的QlikSenseRepositoryDatabase(如果还没停的话),最后启动新的 PostgreSQL 服务,再启动QlikSenseRepositoryService,然后是其他依赖服务,比如 Scheduler、Proxy、Printing、Memory 等。顺序不能乱,尤其是 Repository Service 起来之前,新库必须已经 Ready。
顺便提一句,Qlik 的 Repository 配置里也有一个集中的配置文件C:\ProgramData\Qlik\Sense\Repository\repository.config,里面同样有数据库连接信息,但我不建议在服务运行状态下手动改这个文件——QMC 改完会同步过去,手动改容易格式错,而且改完还得重启服务。如果你坚持用文件方式,一定要先备份原文件,改完再用管理员权限重启服务。改完连接后最直观的验证是:QMC 能正常打开站点配置、许可证页面能加载、应用目录能显示出来。如果 QMC 页面直接报 Database Connection Failed,多半就是连接串里的端口、密码不对,或者服务没起来。
3.4 步骤四:验证 + 回滚预案
验证不能只看 QMC 页面正常。我通常按下面顺序过一遍:第一,看服务列表里 Qlik 相关服务是否全部 Running;第二,看 Qlik 的 System 日志(在 QMC 的 System 目录或者安装目录 logs 下)有没有ERROR、Database connection之类的异常;第三,随便打开一个已有的分析应用,确认元数据能正常加载;第四,跑一次 reload 任务,确认调度链路没断;第五,用 psql 连到新实例,执行几个计数查询,比如看 audit 表有没有在增长,证明 repository service 确实在写新库。
回滚预案这块,我建议在切到新实例后至少保留旧捆绑服务 24 小时处于“停止但未禁用”状态,同时把旧连接串截图保存。如果验证阶段出问题,就把 QMC 连接串改回旧值,启动旧服务,重启 repository service,通常几分钟就能回到原来状态。确认无误后,再把旧服务设为 Disabled,并考虑后续卸载或保留。注意,回滚这一步别急,我见过太多人一看到新库正常就手快把旧库服务卸载了,结果隔天发现某个自定义报表还在连旧端口。
4. 常见问题与排查速查表
4.1 几个高频翻车点和对应处理
| 症状 | 可能原因 | 处理方式 |
|---|---|---|
| 4432 端口被占用 | 本机有其他 PG 实例或服务 | netstat 查占用,换端口并改 QMC 连接串 |
| password authentication failed | 密码记错 / PG 认证方式从 md5 切到 scram | 用 postgres 用户重设密码,检查 pg_hba.conf |
| pg_restore 报 role does not exist | dump 里包含旧角色定义 | 先用 --no-owner 恢复,或预建角色 |
| pg_restore 报 tablespace 不存在 | 备份里记录了旧 tablespace 路径 | 加--no-tablespaces参数 |
| QMC 打开报数据库错误 | 连接串没保存 / 服务没重启 | 重新保存并重启 repository service |
| 旧服务禁用后站点仍正常但日志有报错 | 某些组件还直连旧库 | 搜配置文件里的 4432 / 旧主机名 |
| 新实例磁盘空间不足 | dump 恢复比 dump 文件本身更占空间 | 预留至少两倍 dump 体积 |
这里特别说一下认证方式的问题。PostgreSQL 14 之后默认的密码认证从 md5 迁移到了 scram-sha-256,如果你的 Qlik 连接串还是老的 md5 逻辑,且 pg_hba.conf 没配好,就会一直报 password authentication failed。Qlik PostgreSQL Installer 装出来的实例一般已经处理好了,但如果你中间手动改过 pg_hba.conf,一定要注意认证方法别写成trust,那会让数据库裸奔,也别用旧版md5去连新版服务端,除非你确认两端协议兼容。
4.2 三次实操浓缩出来的避坑心得
心得一:连接串里的密码别带特殊符号。我见过因为密码里带了分号;,连接串解析直接被截断,导致 Qlik 报了谁也看不懂的错误。尽量用字母数字组合,如果一定要特殊字符,注意 Qlik 连接串是否支持转义。这属于“看着小、坑很大”的细节。
心得二:禁用旧服务之前,给新实例至少 15-30 分钟观察窗口,不要一看到 QMC 正常就立刻把旧服务禁用。某次我切换完,QMC 正常显示,但 Scheduler 里的一个自定义数据源还在连旧库,过了二十分钟任务失败,日志才暴露问题。切换完先保持双库并存,让业务跑一小段时间,再动手清理旧的。
心得三:切换前把项目里所有和 repo 库相关的连接字符串搜一遍,包括 QMC 的虚拟代理配置、调度任务里嵌的数据库连接、自定义工具里写死的 IP,别只看 Repository Service 自己的连接。很多报表里还留着localhost:4432甚至旧服务器 IP,库一换,这些连接全部失效。
心得四:日志位置要先找好。Qlik 自身的日志在C:\ProgramData\Qlik\Sense\Log\Repository下的 Trace 文件夹,PostgreSQL 的日志在新实例的 log 目录,Windows 事件查看器里也会有服务启动失败记录。出了问题按这条路径去查,效率最高,而不是在 QMC 里瞎点。
5. 解绑之后,运维姿势也要跟着改
5.1 备份策略升级
解绑之后的第一个好处就是备份自由。捆绑库期间,很多人只能依赖 Qlik 自带的后台备份机制,恢复粒度粗、备份时间不好控制。现在可以用标准 PostgreSQL 工具做备份。最简单的是 Windows 计划任务定时跑 pg_dump,比如每天凌晨 2 点备份 QSR:
@echo off set DT=%date:~0,4%%date:~5,2%%date:~8,2% "C:\Program Files\Qlik\PostgreSQL\16\bin\pg_dump.exe" -h localhost -p 4432 -U postgres -F c -b -f "D:\qlik_backup\qsr_%DT%.dump" QSR注意 pg_dump 会要求输入密码,建议先配置.pgpass文件或者给任务设置环境变量PGPASSWORD,避免计划任务挂着不跑。如果数据量已经很大,还可以开启 WAL 归档,用pg_basebackup做物理备份,这就是从“能备份”升级到“能按时间点恢复”的节奏。我自己的习惯是两种备份并行:每日逻辑备份保留 7 天,每周做一次物理备份保留 4 周,每季度拿一份最近的备份做一次完整恢复演练。恢复演练这个环节,平时看着没必要,真出事的时候能救命。
5.2 性能参数与监控
独立实例的另一个好处就是终于能调参数了。如果你把仓库库和 Qlik Sense 放在同一台机器上,shared_buffers建议设为物理内存的 25% 左右,但别超过 4GB 太多;比如 32GB 机器,设 8GB 是可以的。work_mem一般不用调太大,因为 repository 服务大多是短查询,设个 16-64MB 足够,太大反而容易让每个排序都吃很多内存。
连接数方面,Qlik 的 Repository Service 会有一定数量的并发连接,观察pg_stat_activity里的 active 连接数,按需调整max_connections,通常 100-200 就够。别忘了开启log_min_duration_statement,比如设 5000ms,把慢 SQL 记下来,如果之后发现 QMC 某些页面特别慢,能直接看到是哪个查询的问题。磁盘监控也要跟上,repo 库虽然不大,但审计日志、应用 churn 会让它持续增长,给数据盘留出两到三倍的余量,用监控工具盯磁盘剩余空间。新实例监听地址这个细节同样重要,默认只监听 localhost 就好,别为了省事监听 0.0.0.0,尤其是数据库所在机器有公网 IP 的时候。
5.3 做一个更合理的架构
解绑的意义不仅仅是摆脱捆绑,更是为架构演进打开空间。如果后续要扩到多节点 Qlik Sense 站点,Repository 数据库理论上可以单独跑在一台专用数据库服务器上,而不是和任意一个 Qlik 节点抢资源。到时候连接串里的Host从localhost改成那台数据库服务器的内网 IP,端口保持 4432 或者自行规划,防火墙放行对应来源 IP。多节点下还需要注意 PostgreSQL 的高可用方案,比如主从复制、自动故障切换,这些就不是一个安装器能解决的了,需要 DBA 角色来维护。所以我的建议是:趁这次升级解绑,把数据库的服务归属、备份归属、监控归属都明确好,至少让团队里的数据库负责人知道,repo 库现在是标准 PostgreSQL,不再是个黑盒。
最后分享一个我自己最深刻的教训。有次迁移,我全程盯着 Repository Service 的连接,切换完也确实一切正常,第二天一早却收到报表刷新失败的告警。查了半天才发现,用户有个包含业务数据库连接的应用,连接串里把主机写成了一台旧服务器的 IP,正好是以前 Qlik 捆绑库所在机器,机器下线后报表全挂。解绑这件事,从来都不只是动数据库连接,还得把周边所有指向旧库的连接清干净。如果你打算动手,建议先拿测试环境完整跑一遍这条流程,再动生产;实际做下来你会发现,repo 库只是看着复杂,理清之后其实很好控制。