Postgresql

從文件恢復 postgres 集群

  • July 13, 2021

不是 postgres 專業人士,所討論的數據庫並不那麼重要(個人 NAS),但作為一個有技術頭腦的人並且對 MS SQL / MySQL 相當了解,我想也許我可以試一試。

rsync -a我通過另一個硬碟備份了完整的數據庫文件夾。是的,我知道這不是解決問題的方法,但我做到了。

將數據庫文件夾移回後,postgres 實例(集群?無論名稱如何)似乎已損壞。

我猜數據庫的 OID 不同步(或任何正確的名稱)?請參閱以下內容:

postgres=# \l
caldav         | unknown (OID=16728) | SQL_ASCII | C       | C     |
calendar       | unknown (OID=16726) | SQL_ASCII | C       | C     |
mediaserver    | MediaIndex          | SQL_ASCII | C       | C     |
notestation    | unknown (OID=16730) | SQL_ASCII | C       | C     |
ong            | unknown (OID=16734) | SQL_ASCII | C       | C     |
photo          | unknown (OID=16732) | SQL_ASCII | C       | C     |
postgres       | postgres            | SQL_ASCII | C       | C     |
synocontacts   | Contacts            | UTF8      | C       | C     |
synodrive      | postgres            | SQL_ASCII | C       | C     |
template0      | postgres            | SQL_ASCII | C       | C     | =c/postgres          +
               |                     |           |         |       | postgres=CTc/postgres
template1      | postgres            | SQL_ASCII | C       | C     | =c/postgres          +
               |                     |           |         |       | postgres=CTc/postgres
video_metadata | unknown (OID=16735) | SQL_ASCII | C       | C     |

或通過選擇:

postgres=# SELECT * FROM pg_database
postgres-# WHERE datistemplate = false;
postgres       |     10 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
mediaserver    |  16384 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
calendar       |  16726 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
caldav         |  16728 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
notestation    |  16730 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
photo          |  16732 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
video_metadata |  16735 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
synodrive      |     10 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
ong            |  16734 |        0 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |
synocontacts   |  18876 |        6 | C          | C        | f             | t            |           -1 |         11814 |          179 |          1 |          1663 |

嘗試更改任何數據庫時,我的記憶體查找失敗:

postgres=# \c caldav
FATAL:  cache lookup failed for database 16385
Previous connection kept

坦率地說,幾乎只是template0template1工作。檢查/base文件夾時,文件夾名稱與我通過以下方式看到的 OID 不匹配\l

--- /.../@database/pgsql/base --------------------------------------------------------------------------------------------------------------------------------------------------------
                        /..
 641.0 MiB [##########] /16403
  79.9 MiB [#         ] /16397
  29.6 MiB [          ] /16385
  21.8 MiB [          ] /18877
  12.9 MiB [          ] /16400
   9.6 MiB [          ] /31870
   7.7 MiB [          ] /16736
   7.4 MiB [          ] /16729
   7.4 MiB [          ] /16394
   6.9 MiB [          ] /16399
   6.8 MiB [          ] /17940
   6.7 MiB [          ] /16731
   6.6 MiB [          ] /16398
   6.1 MiB [          ] /16744
   6.1 MiB [          ] /16401
   6.0 MiB [          ] /11819
   5.9 MiB [          ] /16402
   5.9 MiB [          ] /23529
   5.9 MiB [          ] /16733
   5.9 MiB [          ] /11814
   5.9 MiB [          ] /1
   5.8 MiB [          ] /16727
e   0.0   B [          ] /pgsql_tmp

但是您可以告訴帶有數據庫文件的文件夾包含數據。

我也相信使用者似乎是“屬於”的,因為他們都不是任何東西的成員。

postgres=# \du
                                     List of roles
        Role name          |                   Attributes                   | Member of
----------------------------+------------------------------------------------+-----------
AudioStation               |                                                | {}
CardDAV                    | Create DB                                      | {}
Contacts                   | Create DB                                      | {}
MediaIndex                 |                                                | {}
NoteStation                |                                                | {}
PhotoStation               |                                                | {}
SynologyApplicationService | Create DB                                      | {}
VideoStation               | Create DB                                      | {}
postgres                   | Superuser, Create role, Create DB, Replication | {}
synocalendar               |                                                | {}

我會很高興任何指針。如何確定哪些數據庫屬於哪個文件夾名稱/OID?pg_database一旦我找出正確的 ID,我應該繼續編輯嗎?

我還沒有嘗試用這個集群做任何其他事情,我仍然把rsync -a文件夾藏起來。我現在不知道如何繼續。文件夾不只是包含數據庫文件嗎?在其他數據庫中,我知道我可以將文件重新附加到新伺服器 - 我猜不是使用 postgres?


編輯:我實際上複製的不僅僅是base

drwx------ 1 postgres postgres  412 Jul 11 12:57 .
drwxr-xr-x 1 admin    users     452 Jul  5 10:12 ..
drwx------ 1 postgres postgres  230 Jul  5 00:16 base
drwx------ 1 postgres postgres  750 Jul 11 18:00 global
drwx------ 1 postgres postgres    8 Dec 31  2019 pg_clog
-rw------- 1 postgres postgres 4564 Jul 11 12:54 pg_hba.conf
-rw------- 1 postgres postgres 1636 Dec 31  2019 pg_ident.conf
drwx------ 1 postgres postgres   28 Dec 31  2019 pg_multixact
drwx------ 1 postgres postgres    8 Jul 11 12:57 pg_notify
drwx------ 1 postgres postgres    0 Dec 31  2019 pg_serial
drwx------ 1 postgres postgres    0 Dec 31  2019 pg_snapshots
drwx------ 1 postgres postgres    0 Dec 31  2019 pg_stat
drwx------ 1 postgres postgres    0 Dec 31  2019 pg_stat_tmp
drwx------ 1 postgres postgres   16 Jul  2 15:33 pg_subtrans
drwx------ 1 postgres postgres   10 Jul  3 08:32 pg_tblspc
drwx------ 1 postgres postgres    0 Dec 31  2019 pg_twophase
-rw------- 1 postgres postgres    4 Dec 31  2019 PG_VERSION
drwx------ 1 postgres postgres  604 Jul  8 03:20 pg_xlog
lrwxrwxrwx 1 postgres postgres   31 Jul  3 16:05 postgresql.conf -> /etc/postgresql/postgresql.conf
-rw------- 1 postgres postgres   45 Jul 11 12:57 postmaster.opts
-rw------- 1 postgres postgres   88 Jul 11 12:57 postmaster.pid
-rw------- 1 postgres postgres 1094 Jan 13  2020 .psql_history

只要數據庫當時關閉,使用 rsync 就可以了,這顯然不是這裡的情況。但是當 rsync 執行時你在做什麼?您是否在集群為空時啟動了 rsync,然後在--bwlimit將大型轉儲文件恢復到系統中時非常緩慢地(低)執行它?您在 pg_user 和 pg_database 表中看到的損壞程度令人費解,這對您的其餘數據來說是個壞兆頭。我想說你最好的課程是吸取教訓並從頭開始。

如果我故意這樣做,我不確定是否可以在仍然可執行的系統上造成這種程度的損壞。‘base’ 中有很多子目錄在 pg_database 中沒有對應的條目,在 pg_database 中有很多條目的所有者在 pg_user 中沒有對應的條目。

文件夾名稱與我通過 \l 看到的 OID 不匹配:

您在 \l 中看到的 OID 是所有者的 OID,而不是數據庫的 OID。它試圖將所有者 OID 轉換為所有者名稱,但由於 pg_user 中的損壞而無法轉換,因此它顯示所有者原始 OID。

要查看數據庫本身的 OID(在您的 PostgreSQL 版本中),您可以這樣做

select oid, * from pg_database

引用自:https://dba.stackexchange.com/questions/295525