Upgrade PostgreSQL 11 to 16 with docker-compose pg_dump and pg_restore | Paaaack

Yes Lee
4 min readJul 17, 2024

--

Created by Adobe Firefly

Paaaack 在 2019 年架起來的時候 DB (Database) 用的是 PostgreSQL 11 版,一直以來也沒什麼問題。直到最近我想改用 Prisma 處理 DB migration 的時候遇到一個問題

ERROR: function uuid_generate_v4() does not exist

model items {
uuid String? @default(dbgenerated("uuid_generate_v4()")) @db.Uuid

查了一下發現原來 11 版的 PostgreSQL 的 uuid_generate_v4() 是需要 extension 的,而 Prisma 如果在 migration 時要能處理的話,就需要做相對應的調整。

根據文件嘗試了一些調整都失敗後,偶然看到原來 PostgreSQL 在 13 版之後就有不需要 extension 的 uuid function 了,相對的也能讓 Prisma migration 不用額外處理,所以我就決定改成升級 PostgreSQL 的版本。

Note: since PostgreSQL 13 gen_random_uuid() can be used to generate a UUID v4 without an extension https://www.postgresql.org/docs/current/functions-uuid.html

原本想練習使用 pg_upgrade 來升級,但試了一下發現一下子沒有看很懂,加上我的 DB 是跑在 Docker 裡的也影響了一點複雜度,所以最後還是選擇至少知道怎麼用的 pg_dumppg_restore 直接暴力解,反正資料量也還不大。

先多開一個 PostgreSQL 16 的 container。

// Dockerfile
FROM postgres:16

把 11 跟 16 的 DB 同時跑起來之後。

docker-compose exec -t db-container pg_dump -U {username} \
-F c -b -v -f "pg-11-backup.backup" {dbname}

docker-compose cp db-container:/pg-11-backup.backup ./
docker-compose cp ./pg-11-backup.backup db-16-container:/

docker-compose exec -t db-16-container pg_restore -U {username} \
-d {dbname} -v "pg-11-backup.backup"

最後,把 Paaaack 的 production 暫時停掉做 DB 升級,並修改 API server 裡 Prisma 相關的 DATABASE_URL env 指到新 DB,完成!

看起來好像沒什麼問題真是太好了XD。

--

--