Archlinux上的postgresql升級

官方有說明,依照說明進行就可以:https://wiki.archlinux.org/title/PostgreSQL#Upgrading_PostgreSQL

但,我太久沒去注意,所以依照程序進行時,發現我舊的資料庫是 16,目前版本是 18。升級程序需要舊的 16 的檔案才可以,所以這邊紀錄過程:

取得資料庫檔案所使用的版本

cat /var/lib/postgres/data/PG_VERSION

    停止服務

    因為是服務無法啟動才發現 postgresql 需要升級,所以就不需要停止服務。

    安裝新版的檔案

    這步驟也跳過了,因為每次都是全機升級,所以已經安裝好了。

    搬移檔案

    主要是把原來的 /var/lib/postgres/data 更名,並建立新的資料目錄。

    sudo mv /var/lib/postgres/data /var/lib/postgres/olddata
    sudo mkdir /var/lib/postgres/data /var/lib/postgres/tmp
    sudo chown postgres:postgres /var/lib/postgres/data /var/lib/postgres/tmp

    改用 postgres 使用者身份建立資料庫

    sudo -u postgres -H /bin/bash
    cd /var/lib/postgres/tmp
    initdb -D /var/lib/postgres/data --locale=C.UTF-8 --encoding=UTF8 --data-checksums

    升級

    一樣是 postgres 使用者身份,執行 pg_upgrade 來升級

    pg_upgrade -b /opt/pgsql-16/bin -B /usr/bin -d /var/lib/postgres/olddata -D /var/lib/postgres/data

    我是在這步驟出錯的,因為我已經升級到 18。 /opt/pgsql-16/bin 這個目錄是安裝 postgresql-old-upgrade 套件才會有的,通常安裝了 postgresql 18,postgresql-old-upgrade 裡面的檔案就是 /opt/pgsql-17/bin

    參考了 Grok 的回答,對 postgresql-old-upgrade 進行降級了,先到 https://archive.archlinux.org/packages/p/postgresql-old-upgrade/ 下載舊版的檔案 postgresql-old-upgrade-16.10-1-x86_64.pkg.tar.zst ,然後安裝

    sudo pacman -U postgresql-old-upgrade-16.10-1-x86_64.pkg.tar.zst

    再次執行 pg_upgrade,會發現有以下錯誤

    error while loading shared libraries: libicui18n.so.76
    error while loading shared libraries: libicuuc.so.76

    只能再次安裝 icu76,Grok 說可以用 yay 安裝,此時要離開 postgres 身份來安裝。

    yay -Ss icu76

    安裝後,再次切換為 postgres 使用者帳號執行 pg_upgrade,這時候是說少了 libLLVM.so.20.1。又再離開 postgres 身份,用以下指令安裝 llvm 20

    yay -Syu llvm20

    再切換為 postgres 身份,執行 pg_upgrade,就順利完成了。

    啟動服務

    執行 exit 離開 postgres 身份,檢查以下檔案,主要是跟之前 /var/lib/postgres/olddata 目錄下的做比對。

    /var/lib/postgres/data/postgresql.conf
    /var/lib/postgres/data/pg_hba.conf

    設定改好以後,啟動 postgresql 服務。

    sudo systemctl start postgresql

    清理

    切換為 postgres 身份,執行清理

    /usr/bin/vacuumdb --all --analyze-in-stages --missing-stats-only
    /usr/bin/vacuumdb --all --analyze-only
    

    依照升級後的指令,執行

    ./delete_old_cluster.sh

    刪除 olddata 跟 tmp

    sudo rm -rf /var/lib/postgres/olddata
    sudo rm -rf /var/lib/postgres/tmp

    至此,大功告成。

    Proxmox LXC設定

    LXC是輕量級的容器,Proxmox 直接提供了這功能,等於是可以拿 LXC 來當 VM,這樣可以更壓榨硬體的效能出來。

    這邊主要是紀錄用的時候遇到的一些狀況:

    1. Tailscale
    2. podman

    Tailscale

    因為我 Proxmox 網路設定是用NAT,再加上沒有第二張網卡,所以就簡單用 Tailscale 讓外部可以連到 Proxmox 裡面的 LXC 跟 VM。VM 用 tailscale 沒什麼問題,但 LXC 就遇到不能用的情況。

    這邊要在 lxc 容器設定 (Proxmox 主機裡的 /etc/pve/lxc/<id>.conf 裡加上以下內容

    lxc.cgroup2.devices.allow: c 10:200 rwm
    lxc.mount.entry: /dev/net/tun dev/net/tun none bind,create=file

    podman

    podman 本身就容器,等於是容器裡的容器,這邊要處理 rootless 的情況,一樣,在 lxc 容器設定 (Proxmox 主機裡的 /etc/pve/lxc/<id>.conf 加上以下內容

    lxc.idmap: u 0 100000 165536
    lxc.idmap: g 0 100000 165536
    

    還有 /etc/subuid

    root:100000:200000

    /etc/subgid

    root:100000:200000

    參考資料

    helm images

    適用情境,客戶是離線環境,沒辦法直接拉 container image,所以要先知道 helm chart 裏面用到的 container image,用這指令,就可以找到所有 helm chart 所使用到的 image,再用 skopeo/podman pull/docker pull 拉取下來,存為 tarball ,並帶到客戶端。

    專案網址:https://github.com/nikhilsbhat/helm-images

    安裝

    安裝好 helm 以後,可以用以下指令安裝

    helm plugin install https://github.com/nikhilsbhat/helm-images

    使用

    簡單說,就是拿 helm install 的指令來用,並改為 helm images get。

    所以在配置好 helm repo 以後,就可以用 helm images 取得

    例如 redis-operator

    helm images get redis redis-operator/redis-operator

    又例如 zabbix operator

    helm images get zabbix zabbix-chart-7.0/zabbix-helm-chrt

    就可以取得 container images 的網址。


    題外話,應該要來熟悉一下 skopeo 怎麼用才是。

    使用systemctl 啟用podman出現Failed to connect to bus

    在使用 sudo/su 切換身份以後,用以下指令去啟用/啟動 podman 服務,會出現以下錯誤

    Failed to connect to bus: No such file or directory

    查了以後,才知道是少了 DBUS 環境變數的問題:https://stackoverflow.com/questions/73814619/permission-denied-trying-to-use-rootless-podman-docker-compose-traefik-with

    這個時候,只要查到 DBUS 的 socket 路徑,再去 export DBUS 環境變數即可

    export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus
    $ systemctl --user enable --now podman

    啟用以後,會有 podman.sock 檔案,這個檔案的位置跟 root 身份的位置不一樣,會是在

    /run/user/$UID/podman/podman.sock

    這邊是要特別注意的。

    如何使用podman volume掛載nfs分享

    資料來源:Mount an NFS Share Using a Rootful Podman Volume (oracle.com)

    在建立 volume 時,就可以指定 nfs 的資訊

    sudo podman volume create --opt type=nfs --opt o=rw --opt device=10.0.0.150:/nfs-share nfsvol

    在建立完成後,podman 會去掛載 nfs 分享,這部份可以使用 mount 查看到掛載到哪個資料夾。接下來 podman 就可以使用 -v 參數,去指定要使用剛剛建立的 volume ,容器啟動後,就可以使用了。

    例如

    sudo podman run -v nfsvol:/foo -it --rm oraclelinux:9 ls -al /foo

    這就表示把建立好的 nfsvol ,掛載到容器裡面的 /foo ,應用程式就可以存取到了。

    為 yum repository 指定 proxy

    要設定讓 yum 可以使用指定的 proxy 伺服器,可以在 /etc/yum.conf 的 [main] 區段裡增加 proxy 設定即可

    [main]
    proxy=http://<proxy_server>:3128

    那如果是個別的 repository 要使用不同的 proxy 伺服器,可以怎麼做呢?
    原本以為會很麻煩的,但意想不到簡單,因為有支援此設定。
    就在 repository 的區段裡增加 proxy 設定就可以:

    [repo]
    name=baseos
    baseurl=http://yumrepo.example.com/baseos
    enabled=1
    gpgcheck=0
    proxy=http://<proxy_server>:3128

    參考資料

    bash script取亂數

    在 bash script 裡,可以用 ${RANDOM} 取亂數,例如

    echo "random number: ${RANDOM}"

    就會出現一個隨機的數字。

    那如果想限制在 20~40 這個範圍內的話,可以怎麼做呢?這時候可以用 bash 的 % ,取餘數的運算子來做,例如

    echo "random number(0~10): $((20 + RANDOM % 20))"

    參考資料

    BIND+DNS over HTTPs

    說明一下為什麼會要這樣作。

    因為環境關係,DNS protocol 出不去,只有 A 主機可以透過 HTTP 出去。

    因此方案如下:

    1. A 電腦安裝 squid,其他主機可將 HTTP proxy 設定為 A 主機,這樣 HTTP 請求就可透過 A 主機出去。
    2. 環境內原有 B 主機已經安裝 BIND,此主機就安裝 cloudflare 提供的 cloudflared ,使用 DNS over HTTPs 方式,讓 DNS 查詢可以用 HTTP 請求,透過 A 主機去查詢。

    安裝與設定

    cloudflared 蠻好安裝的,就一個執行檔,下載以後,改個權限就可以執行了 (安裝方式)

    那如果要用 systemd 來啟動,也很容易,安裝方式裡就有提供範例:

    [Unit]
    Description=DNS over HTTPS (DoH) proxy client
    Wants=network-online.target nss-lookup.target
    Before=nss-lookup.target
    
    [Service]
    Environment=http_proxy=http://<proxy>:3128
    Environment=https_proxy=http://<proxy>:3128
    AmbientCapabilities=CAP_NET_BIND_SERVICE
    CapabilityBoundingSet=CAP_NET_BIND_SERVICE
    DynamicUser=yes
    ExecStart=/usr/local/bin/cloudflared proxy-dns --port 5533
    
    [Install]
    WantedBy=multi-user.target

    設定好,用 firewall-cmd 設定好防火牆 (TCP 5533) 以後,就可以去調整 BIND 的設定 /etc/named.conf

    修改既有的 forwarder 設定

    forwarders { 127.0.0.1 port 5533; };

    重新啟動 named 以後,就可以試試看了。

    流程大致如下

    --[DNS查詢]--> B 主機(53/UDP) ----> B 主機(5533/TCP) --[HTTP]--> A 主機(3128/TCP) --> 外部

    參考資料

    找昨天到現在有更動的檔案

    需求是要找到從昨天到現在有變更的檔案,一時也想不出來怎麼做,利用 Google 找了一下,大多都是利用 find 的 -newer 參數。

    find 的 -newer 參數要帶入的是一個檔案,表示會以這個檔案為基準來進行比對。

    所以假設是要找 2023-11-11 之後的檔案,就先利用 touch 來建立一個基準檔案,其修改日期為 2023-11-11:

    touch --date "2023-11-11" /tmp/base

    然後再用

    find . -newer /tmp/base -print

    就可以找出在 /tmp/base 之後變更的檔案了。

    find 也有一個 -newerXY 的參數,這個 XY 可以是以下內容

    1. a – 檔案的存取時間
    2. B – 檔案的建立時間
    3. c – 檔案 inode 的變更時間
    4. m – 檔案的修改時間
    5. t – 參數的內容是時間

    那要找比 2023-11-11 要新的檔案,就用以下指令

    find . -type f -newermt 2023-11-11

    要找特定一天的,就用以下指令

    find . -type f -newermt 2023-11-11 ! -newermt 2023-11-12

    參考資料