Zeabur 資料庫備份怎麼帶走:PostgreSQL、MySQL 匯出、還原與驗證(官方備份只留 7 天)

Zeabur 上的 PostgreSQL、MySQL、MariaDB 要搬走,順序是:先換資料庫密碼,再拿到備份檔,還原到新平台,比對過資料才切換。拿備份檔有兩條路:付費方案可以用 Zeabur 內建的備份(PostgreSQL 用 pg_dumpall 產生 .sql,只保留 7 天,要自己下載);也可以用服務頁 Instruction 分頁的公開連線資訊,自己用 pg_dump、mysqldump 從外面匯出。新平台的 PostgreSQL 主版本不要比舊的低。還原後要比對資料表數、每張表的筆數、近期幾筆資料、序列值、編碼、時區與擴充套件,全部對上才算搬完。

這篇是〈Zeabur 搬家前先換金鑰〉的資料庫專篇。停止營運的時程、退款、網域轉出等共通的部分請看那篇,這裡只講 PostgreSQL、MySQL、MariaDB 的匯出、還原與驗證,MongoDB 與 Redis 在文末帶過。

文中官方資料的查詢日期是 2026 年 10 月 18–19 日。Zeabur 的做法引自 Zeabur 官方文件與官方資料庫模板,指令引自 PostgreSQL、MySQL、MariaDB、MongoDB 各自的官方文件;官方之後若有更新,以官方為準。

搬一個資料庫的五個步驟

  1. 換密碼:舊密碼在外洩範圍內,新平台一律用新密碼。
  2. 拿到備份檔:用 Zeabur 內建備份,或自己從外面匯出。兩條路都走一次更保險。
  3. 還原到新平台:先還原到新平台試一次,不要直接切換。
  4. 驗證:比對資料表、筆數、序列、編碼、時區、擴充套件。
  5. 切換:暫停舊資料庫的寫入,再匯出一次、還原、改應用程式的連線字串。

要人代搬,可以看我們的PaaS 停運搬家與資安檢查服務。

步驟 1:先換資料庫密碼

Zeabur 官方狀態頁〈Unauthorized Access to Zeabur Infrastructure and User Data〉寫明,10 月這次事件中,攻擊者取得平台資料庫的讀取權限,外洩的資料包括服務的環境變數、帳號資料、API token 與 zSend API key。狀態頁也請用戶輪換存在環境變數裡的所有密鑰。

資料庫的連線字串與密碼,通常就在環境變數裡。以 Zeabur 官方 MySQL 模板為例,它會把 MYSQL_PASSWORD、MYSQL_URI 這些變數注入同專案的其他服務;PostgreSQL 模板也有 POSTGRES_PASSWORD、POSTGRES_CONNECTION_STRING。所以這組密碼要當成已經外洩來處理:

  • 資料庫還要在 Zeabur 上跑一段時間:現在就在資料庫裡改密碼,再更新引用這組密碼的服務。在資料庫裡改了密碼之後,Zeabur 模板的密碼變數會不會跟著變,官方沒寫,改完要自己確認應用程式連得上。換法見〈Zeabur 金鑰外洩後要換哪些?〉的「資料庫密碼怎麼換」。
  • 新平台:建帳號時直接用新密碼,不要沿用舊的。
  • PostgreSQL 的 pg_dumpall 會把角色密碼帶過去:pg_dumpall 有一個 --no-role-passwords 選項,官方說明是「不匯出角色的密碼」;反過來說,沒加這個選項時,角色密碼會跟著備份檔一起過去。用 pg_dumpall 的檔案還原後,記得到新平台把這些帳號的密碼改掉。
  • 匯出專案的 YAML 也含環境變數:Zeabur〈匯出專案〉文件寫明,匯出的 YAML 包含 Docker 映像、Git repo、環境變數與 volume 等部署資訊,但「不包含資料」。這份 YAML 裡有密碼,存放時要當成機密檔案。

步驟 2 之一:用 Zeabur 內建的備份

Zeabur 官方文件〈備份與還原〉(2026-05-08 更新)的重點如下:

項目官方怎麼寫
誰能用Dev Plan 等付費方案
PostgreSQL用 pg_dumpall 建立,包含服務裡的所有資料庫,.sql 檔
MySQL、MariaDB包含所有非系統資料庫,.sql 檔
MongoDB包含服務憑證可存取的所有資料庫,多個 .bson 檔
停不停機資料庫支援線上備份,不用暫停服務;也可以設每日自動備份
保留多久只保留 7 天,超過會自動刪除
備到自己的空間還不支援備份到自己的 Amazon S3
用程式取回可以呼叫 Zeabur 開放 API,取得備份的下載連結 downloadURL

線上備份列出的資料庫是 PostgreSQL、MySQL、MariaDB、MongoDB 這四種,官方寫的是「不限於」這幾種,但備份檔格式只說明了這四種。

做法:到資料庫服務的「備份」分頁按「備份」,等幾分鐘,完成後會出現下載按鈕。一定要下載,存到 Zeabur 以外的地方。 官方文件寫明備份只保留 7 天,也說要長期保存就自己下載。

要用程式取回,官方文件給的 GraphQL 查詢是這樣:

query Backups($environmentId: ObjectID!, $serviceId: ObjectID!) {
  backups(environmentID: $environmentId, serviceID: $serviceId) {
    createdAt
    downloadURL
    status
  }
}

資料庫的 volume 備份不適合拿來搬家。 Zeabur 的 volume 備份要先暫停服務,備份的是 volume 資料夾的完整內容。資料庫服務的 volume 掛的是資料目錄(官方 PostgreSQL 模板是 /var/lib/postgresql/18/docker,MySQL、MariaDB 模板是 /var/lib/mysql)。PostgreSQL 官方文件說,檔案層級的備份「extremely server-version-specific」(跟伺服器版本綁得很緊),跨主版本要用 pg_dumpall 這類邏輯備份工具,檔案層級的方法行不通。搬資料庫用上面的 .sql 備份,或下一段自己匯出;volume 備份留給上傳檔案這類非資料庫的資料。

步驟 2 之二:自己用 pg_dump、mysqldump 從外面匯出

沒有付費方案、或想多留一份自己控制格式的備份,可以用資料庫自己的工具從外面連進去匯出。

連線資訊在哪:Zeabur 官方 PostgreSQL 模板的說明寫,進入服務的 Instruction 分頁,「Connection」區塊有兩種資訊:Public(External) 給本機工具用,Private(Internal) 給同專案已部署的應用用。從外面匯出要用 Public 那組的主機、連接埠、帳號、密碼與資料庫名稱。MySQL、MariaDB 模板的 Instruction 也列了主機、連接埠與一行連線指令。

Zeabur〈公開網路〉文件說,非 HTTP 的服務是用分配的主機名稱與連接埠存取,也就是通訊埠轉發;這組主機名稱與連接埠大致固定,但少數情況會變,不要當成永久不變。每次匯出前,回 Instruction 分頁再看一次。免費方案能不能用這組公開連線,官方模板頁沒有分方案寫,以你主控台看到的為準。

PostgreSQL:用新的 pg_dump 連舊的伺服器

先確認舊資料庫的版本(在 psql 裡下 SELECT version();)。2026 年 10 月 19 日查詢時,Zeabur 官方 PostgreSQL 模板用的是 postgres:18 映像;你的服務部署時的版本可能不同,以 version() 查到的為準。

PostgreSQL 官方文件寫明:pg_dump「cannot dump from PostgreSQL servers newer than its own major version」,pg_dump 不能從主版本比自己新的伺服器匯出,會直接拒絕執行。所以本機的 pg_dump 主版本要大於或等於舊資料庫的主版本,舊的是 18 就要用 18 以上的 pg_dump。

匯出單一資料庫,用 custom 格式(-Fc):

pg_dump -Fc -h <主機> -p <埠號> -U <帳號> -d <資料庫> -f <資料庫>.dump

官方文件說,custom 格式要搭配 pg_restore 還原,預設會壓縮,還原時可以挑選、重排要還原的項目,也支援平行還原。pg_dump 匯出時不會擋住其他人讀寫。

要連角色(帳號)一起帶走,用 pg_dumpall。官方文件說,pg_dump 只匯出單一資料庫,角色與 tablespace 這類整個叢集共用的物件要用 pg_dumpall:

pg_dumpall -h <主機> -p <埠號> -U <帳號> -f all.sql

pg_dumpall 讀所有資料庫的資料,官方說多半要用超級使用者連線才能匯出完整;只要角色定義,可以加 --roles-only。

MySQL:記得加 –routines 與 –events

mysqldump --single-transaction --routines --triggers --events \
  -h <主機> -P <埠號> -u <帳號> -p <資料庫> > <資料庫>.sql

這幾個選項,MySQL 官方手冊是這樣寫的:

  • --single-transaction:匯出前先開一個交易,對 InnoDB 這類交易型資料表,匯出的是開始那一刻的一致狀態,而且不會擋住應用程式。只有 InnoDB 資料表能保證一致,MyISAM、MEMORY 資料表在匯出期間仍可能變動;匯出期間也不要有其他連線做 ALTER TABLE、CREATE TABLE、DROP TABLE、RENAME TABLE、TRUNCATE TABLE。
  • --routines:連預存程序與函式一起匯出。
  • --triggers:連觸發程序一起匯出,預設就是開的。
  • --events:連排程事件(Event Scheduler)一起匯出。

官方手冊特別提醒,從 MySQL 8.0 起,就算用 --all-databases,也要明確加上 --routines 和 --events,預存程序與事件才會在備份檔裡。Zeabur 內建的 MySQL 備份有沒有包含這兩樣,官方沒寫;有用到的話,自己匯出時加上這兩個選項。

還有一個 --set-gtid-purged,只跟有開 GTID 複製(gtid_mode=ON)的伺服器有關。預設值是 AUTO,來源伺服器有開 GTID 時,備份檔裡會多一行 SET @@GLOBAL.gtid_purged。官方手冊提到,重複匯入時這一行可能失敗,解法是匯出時不要輸出這一行;新平台匯入時遇到跟 gtid_purged 有關的錯誤,可以改用 --set-gtid-purged=OFF 再匯出一次。

2026 年 10 月 19 日查詢時,Zeabur 官方 MySQL 模板用的是 mysql:8.0 映像。

MariaDB:用 mariadb-dump

mariadb-dump --single-transaction --routines --events \
  -h <主機> -P <埠號> -u <帳號> -p <資料庫> > <資料庫>.sql

MariaDB 官方文件說明,這個工具以前叫 mysqldump,現在仍可用這個名稱呼叫;但從 MariaDB 11.0 起,mysqldump 這個名稱已不建議使用,官方 Docker 映像也拿掉了。Zeabur 官方 MariaDB 模板在 2026 年 10 月 19 日查詢時是 mariadb:12 映像。

MariaDB 搬到 MariaDB 比較單純。官方文件提醒,mariadb-dump 匯出的檔案開頭會有一行啟用 sandbox 模式的指令,舊版的 mariadb 用戶端與 MySQL 的 mysql 用戶端看不懂,匯入時會報錯。新平台如果是 MySQL,要先處理這件事,或選有 MariaDB 的平台。

步驟 3:還原到新平台

PostgreSQL

pg_dumpall 的 .sql(包括 Zeabur 內建備份)用 psql 還原:

psql -X -h <新主機> -p <埠號> -U <帳號> -d postgres -f all.sql

官方文件的幾個重點:

  • 連哪個資料庫不重要,檔案裡有建立、切換各資料庫的指令。
  • 檔案會為每個角色下 CREATE ROLE,所以一定會出現一個「role already exists」錯誤(新平台初始的超級使用者),官方說這個錯誤無害、可以忽略。
  • 要新增角色、建資料庫,執行的人需要超級使用者權限。新平台如果是不給超級使用者的託管資料庫,這個檔案的角色那段會失敗;這時改用下面的 pg_dump 單一資料庫做法。
  • 建議加 -X,不讀本機的 psqlrc 設定。

pg_dump 的 custom 格式用 pg_restore 還原:

createdb -T template0 -h <新主機> -p <埠號> -U <帳號> <資料庫>
pg_restore --no-owner --no-acl --exit-on-error \
  -h <新主機> -p <埠號> -U <帳號> -d <資料庫> <資料庫>.dump
  • --no-owner:不還原物件的擁有者,全部歸給這次連線的帳號。新平台的帳號名稱跟舊的不同時要加。官方文件也說明,這個選項在 pg_dump 輸出 custom 這類封存格式時會被忽略,要在 pg_restore 這一步加。
  • --no-acl:不還原 GRANT、REVOKE 權限設定。
  • --exit-on-error:遇到錯誤就停。預設是繼續執行,結束時才顯示錯誤數。
  • 空資料庫要從 template0 建立,官方文件說明,否則 template1 若有自訂內容,可能出現重複定義的錯誤。

還原完,官方建議對每個資料庫跑一次 ANALYZE,讓查詢優化器有統計資料可用。

用 psql 還原純文字 .sql 時,預設遇到錯誤會繼續執行;要遇錯就停,可以加 --set ON_ERROR_STOP=on,或加 -1(--single-transaction)讓整份檔案要嘛全部成功、要嘛全部不套用。

MySQL、MariaDB

Zeabur 官方 MySQL、MariaDB 模板的〈還原備份〉都是同一個做法:把備份檔解壓縮,拿到 data.sql,再用 Instruction 裡的連線指令把檔案餵進去。搬到新平台時,連線資訊換成新平台的:

mysql -h <新主機> -P <埠號> -u <帳號> -p <資料庫> < <資料庫>.sql

MariaDB 把 mysql 換成 mariadb。

新平台的版本不要比舊的低

PostgreSQL:官方文件說,pg_dump 的輸出可以載入比 pg_dump 新的伺服器;但「it is not guaranteed that pg_dump’s output can be loaded into a server of an older major version」,載入比較舊的主版本不保證成功,即使備份就是從那個版本匯出的也一樣。跨主版本時,官方建議加 --quote-all-identifiers,避免不同版本保留字不同造成的問題。官方〈升級〉文件也建議,用新版本的 pg_dump、pg_dumpall 來匯出。

MongoDB:官方文件說,mongodump 產生的 BSON 檔可以還原到「same major version or feature compatibility version」(主版本或功能相容版本相同)的部署。

MySQL、MariaDB:本文沒有查到官方對跨版本匯入的完整說明,以各自官方文件為準。實務上至少做到新平台的版本不比舊的低,並在新平台先還原試一次。

步驟 4:驗證,比對新舊兩邊

還原沒報錯,不代表資料都在。下面每一項在舊、新兩邊各跑一次,結果要一致。舊資料庫在比對期間不要有寫入,否則筆數會對不上。

PostgreSQL 的檢查

資料表清單:

SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
  AND table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY 1, 2;

官方文件說明,information_schema.tables 只列出目前帳號有權限的資料表,兩邊要用權限相當的帳號查。

每張表的筆數:在 psql 裡用 \gexec,替每張表產生一句 SELECT count(*) 並執行:

SELECT format('SELECT %L AS table_name, count(*) FROM %I.%I',
              table_schema || '.' || table_name, table_schema, table_name)
FROM information_schema.tables
WHERE table_type = 'BASE TABLE'
  AND table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY 1
\gexec

抽查近期幾筆:挑幾張主要資料表,依主鍵或建立時間倒序看前 5 筆,兩邊內容要一樣:

SELECT * FROM <資料表> ORDER BY <主鍵或建立時間欄> DESC LIMIT 5;

序列值:序列沒跟上,搬完新增資料時會撞主鍵。

SELECT schemaname, sequencename, last_value FROM pg_sequences ORDER BY 1, 2;

官方文件說明,last_value 是寫到磁碟的序列值,有快取時可能比實際發出的值大;序列還沒被讀過時會是空值。比對時,確認新平台的 last_value 不小於對應資料表 id 欄位的 max()。

編碼與排序規則:

SELECT datname, pg_encoding_to_char(encoding), datcollate FROM pg_database;

時區:SHOW timezone;。Zeabur 官方 PostgreSQL 模板的設定檔寫的是 timezone = 'UTC',新平台不同的話,顯示出來的時間會不一樣。

擴充套件:

SELECT extname, extversion FROM pg_extension ORDER BY 1;

在 psql 裡也可以用 \dx。舊的有、新的沒有,表示新平台沒有裝這個擴充套件,要先確認新平台支援。

MySQL、MariaDB 的檢查

資料表清單:

SELECT TABLE_NAME FROM information_schema.TABLES
WHERE TABLE_SCHEMA = '<資料庫>' AND TABLE_TYPE = 'BASE TABLE'
ORDER BY 1;

筆數用 COUNT(*),不要看 TABLE_ROWS:MariaDB 官方文件說明,information_schema.TABLES 的 TABLE_ROWS 欄位,InnoDB 這類引擎存的可能是估計值。比對筆數要一張一張下:

SELECT COUNT(*) FROM <資料表>;

預存程序、觸發程序、事件:

SHOW PROCEDURE STATUS WHERE Db = '<資料庫>';
SHOW FUNCTION STATUS WHERE Db = '<資料庫>';
SHOW TRIGGERS FROM <資料庫>;
SHOW EVENTS FROM <資料庫>;

編碼與排序規則:

SELECT DEFAULT_CHARACTER_SET_NAME, DEFAULT_COLLATION_NAME
FROM information_schema.SCHEMATA WHERE SCHEMA_NAME = '<資料庫>';

時區:SHOW GLOBAL VARIABLES LIKE 'time_zone';。MySQL 官方手冊說明,mysqldump 預設開啟 --tz-utc,匯出時會把連線時區設成 UTC,讓 TIMESTAMP 欄位在不同時區的伺服器之間搬移時值不變;要是關掉這個選項,兩邊時區不同時,值可能會變。

CHECKSUM TABLE 只適合同版本比對:MariaDB 官方文件說明,資料表的列格式會影響 checksum,升級到另一個版本後 checksum 很可能會變。新舊平台版本不同時,用筆數與抽查比對,不要只看 checksum。

MongoDB 與 Redis

MongoDB:Zeabur 內建備份產生多個 .bson 檔,官方〈備份與還原〉的還原方式是用 mongorestore,把連線字串與備份目錄給它:

mongorestore "<連線字串>" "<備份目錄>"

MongoDB 官方文件說明,mongorestore 會依備份目錄建立需要的資料庫與集合;要先清掉目標的同名集合可以加 --drop,但備份裡包含 admin 資料庫時,--drop 會把使用者帳密換成備份檔裡的,要特別注意。還原的目標要跟來源主版本或功能相容版本相同(見上一段)。

Redis:Zeabur〈備份與還原〉列出備份檔格式的只有 PostgreSQL、MySQL、MariaDB、MongoDB。Redis 只有一段還原指令,Redis 的備份檔怎麼產生、是什麼格式,官方沒寫。我們的建議(不是官方說明):Redis 如果只是快取或工作階段,不用搬,在新平台重新建立即可;如果你把 Redis 當主要資料庫存了不能遺失的資料,搬遷前先確認新平台 Redis 的匯入方式,再決定做法。

時間:什麼時候要做完

  • 備份只留 7 天:Zeabur 官方文件寫明。按完備份當天就下載,不要以為下個月還在。
  • 12 月 1 日起共享叢集暫停:官方公告原句是「共享叢集暫停所有運行中的服務,你仍可手動恢復運行以備份資料」。服務暫停後還能手動恢復來備份,但不要把匯出排到那時候。
  • 專用伺服器依到期日陸續關閉:官方公告寫,專用伺服器 12 月 1 日起停用續費,依各自的到期日在 12 月 1 日到 31 日之間陸續關閉,並請用戶「確認你的伺服器到期日,並在到期前完成備份與遷移」。
  • 資料刪除日還沒公布:官方公告寫,資料刪除日期、匯出截止期限與 Zeabur Support 停止服務日期「目前尚未確定」,並提醒「不要等到資料刪除期限公布才開始準備」。

切換當天的順序,照 Zeabur〈搬遷專案〉文件的建議:先降低 DNS TTL;搬遷期間暫停對舊專案的寫入,避免資料不一致;確認新服務正常後再清掉舊資源。資料庫的部分就是:停寫入,再匯出一次,還原,跑一次上面的驗證,改應用程式的連線字串。

搬完驗收表

檢查怎麼看
舊密碼已作廢用舊密碼連新平台,要連不上;pg_dumpall 帶過去的角色已改密碼
備份檔存在 Zeabur 以外至少一份在自己的電腦或儲存空間,檔名標日期
還原沒有非預期錯誤PostgreSQL 只允許「role already exists」這類官方說無害的錯誤
資料表數一樣information_schema 列出的清單兩邊一致
每張表筆數一樣count(*) 一張一張比,不看估計值
近期資料都在主要資料表依時間倒序抽 5 筆,內容一致
序列與自動編號跟上新增一筆測試資料不會撞主鍵,測完刪掉
預存程序、觸發程序、事件都在MySQL 用 SHOW 指令比對清單
編碼、排序規則、時區一致中文與 emoji 顯示正常,時間沒有差 8 小時
擴充套件都在pg_extension 清單一致
應用程式改連新資料庫環境變數換成新連線字串,舊的連線字串刪掉
舊資料庫已停寫入切換後舊的不再有新資料,確認後再刪除

揭露

火曜領航有提供資料庫搬家與主機代管服務。這篇的步驟不需要找任何人也能自己做。

如果您的服務還在 Zeabur 上,需要人幫忙盤點、搬遷或輪換金鑰,可以到〈PaaS 停運搬家與資安檢查服務〉看四種做法,或直接填寫詢價表單,我們會在一個工作日內回覆搬遷順序建議。

常見問題

Zeabur 的資料庫備份檔可以留多久?

Zeabur 官方文件寫明,備份只保留 7 天,超過會自動刪除,也還不支援備份到自己的 Amazon S3。要長期保存就自己下載,或用官方開放 API 取得 downloadURL 自動下載。下載後的檔案放在你自己的地方,留多久由你決定。

免費方案沒有備份按鈕,怎麼匯出資料庫?

Zeabur 官方文件寫的是,內建備份是 Dev Plan 等付費方案的功能。免費方案可以用服務 Instruction 分頁的 Public 連線資訊,自己用 pg_dump、mysqldump 或 mariadb-dump 從外面匯出,指令見本文步驟 2 之二。免費方案有沒有公開連線,官方模板頁沒有分方案寫,以你主控台看到的為準。

搬資料庫要停機嗎?

匯出本身不用停。PostgreSQL 官方文件說 pg_dump 不會擋住其他人讀寫;MySQL 加 --single-transaction 對 InnoDB 資料表也不會擋住應用程式。但匯出之後寫進舊資料庫的資料不會在備份裡,所以切換那一段要暫停寫入,Zeabur〈搬遷專案〉文件也這樣建議。停多久取決於資料量,建議先完整演練一次,量出匯出加還原要多久,再排切換時間。

pg_dumpall 跟 pg_dump 差在哪?

pg_dump 一次匯出一個資料庫,可以選 custom 等封存格式,用 pg_restore 還原。pg_dumpall 匯出整個叢集的所有資料庫,外加角色、tablespace 這些共用物件,輸出是一份 .sql,用 psql 還原。官方文件也說明,pg_dumpall 裡各資料庫各自內部一致,但不同資料庫之間的時間點沒有同步。Zeabur 內建的 PostgreSQL 備份是用 pg_dumpall 產生的。

資料庫很大怎麼辦?

PostgreSQL 官方文件的做法:用 directory 格式(-Fd)搭配 -j 平行匯出,還原時 pg_restore 也可以加 -j 平行;也可以把輸出接 gzip 壓縮,或用 split 切成多個檔案。MySQL 官方手冊建議,大資料表用 --single-transaction 搭配 --quick,並提到 MySQL Shell 的 dump 工具支援多執行緒平行匯出。資料量大時,先演練一次量時間更重要。

參考來源

以上資料皆於 2026 年 10 月 18–19 日查詢。

最後更新: