GMKtec EVO-X2 の64GB/1TB版

2025年11月23日に GMKtec EVO-X2 の64GB/1TB版を22万793円で購入しました。

スペックから期待できること

AMD Ryzen AI Max+ 395の公式スペック。

  • CPU: 16C32T 最大5.1GHz
  • RAM: LPDDR5X 8000MHz 8チャネル
  • GPU: Radeon 8060S
  • 消費電力: 45-120W

メモリ速度はdGPUのVRAMと比較すると遅いですが、通常のDDR5 Dual Channelのメインメモリと比較すると3倍程度の速度が期待できそうに見えます。大容量メモリをUMAアーキテクチャGPUから利用でき、(128GBモデルでは)一般向けのdGPUと比べてかなり大きなAIデータモデルを扱えることが注目されました。

実測してみる

GPU-メモリ間の帯域:read

$ cat vram_read.cfg
## GPU read-only bandwidth
1 40 (G0->G0->N0)

$ /opt/rocm-7.1.0/bin/rocm-bandwidth-test run tb vram_read.cfg 1G
TransferBench v1.64.00
(snip..)
## GPU read-only bandwidth
Test 1:
 Executor: GPU 00 |  240.050 GB/s |    4.473 ms |   1073741824 bytes | 240.293 GB/s (sum)
     Transfer 00  |  240.293 GB/s |    4.468 ms |   1073741824 bytes | G0 -> G000:040 -> N
 Aggregate (CPU)  |  229.330 GB/s |    4.682 ms |   1073741824 bytes | Overhead: 0.209 ms
[WARN] GPU 0 requests 40 total CUs however only 20 available. Serialization will occur

GPU-メモリ間の帯域:write

$ cat vram_write.cfg
## GPU write-only bandwidth (memset)
1 40 (N0->G0->G0)

$ /opt/rocm-7.1.0/bin/rocm-bandwidth-test run tb vram_write.cfg 1G
TransferBench v1.64.00
(snip..)
## GPU write-only bandwidth (memset)
Test 1:
 Executor: GPU 00 |  223.107 GB/s |    4.813 ms |   1073741824 bytes | 223.324 GB/s (sum)
     Transfer 00  |  223.324 GB/s |    4.808 ms |   1073741824 bytes | N -> G000:040 -> G0
 Aggregate (CPU)  |  209.738 GB/s |    5.119 ms |   1073741824 bytes | Overhead: 0.307 ms
[WARN] GPU 0 requests 40 total CUs however only 20 available. Serialization will occur

CPU-メモリ間の帯域

$ ./stream
-------------------------------------------------------------
STREAM version $Revision: 5.10 $
-------------------------------------------------------------
This system uses 8 bytes per array element.
-------------------------------------------------------------
Array size = 500000000 (elements), Offset = 0 (elements)
Memory per array = 3814.7 MiB (= 3.7 GiB).
Total memory required = 11444.1 MiB (= 11.2 GiB).
Each kernel will be executed 10 times.
 The *best* time for each kernel (excluding the first iteration)
 will be used to compute the reported bandwidth.
-------------------------------------------------------------
Number of Threads requested = 32
Number of Threads counted = 32
-------------------------------------------------------------
Your clock granularity/precision appears to be 1 microseconds.
Each test below will take on the order of 42283 microseconds.
   (= 42283 clock ticks)
Increase the size of the arrays if this shows that
you are not getting at least 20 clock ticks per test.
-------------------------------------------------------------
WARNING -- The above is only a rough guideline.
For best results, please be sure you know the
precision of your system timer.
-------------------------------------------------------------
Function    Best Rate MB/s  Avg time     Min time     Max time
Copy:          147102.1     0.054401     0.054384     0.054457
Scale:         111415.8     0.072173     0.071803     0.072385
Add:           107585.8     0.111592     0.111539     0.111643
Triad:         107448.9     0.111728     0.111681     0.111792
-------------------------------------------------------------
Solution Validates: avg error less than 1.000000e-13 on all three arrays
-------------------------------------------------------------

Note: STREAMベンチの数字は、Copy/Scale/Add/Triadのどれもreadとwriteの両方を含みます。その中で最も演算の少ないCopyを今回の指標として使います。

さて、速度を表にまとめるとこうなります。

項目 帯域
理論値 (LPDDR5X 8000MHz 8チャネル) 256 GB/s
GPU Read 240 GB/s
GPU Write 223 GB/s
CPU(STREAM Copy) 147 GB/s

GPUからメモリへのアクセスは理論値の90%前後で違和感はありませんが、CPUからメモリへのアクセスは理論値の6割程度に留まる結果になりました。

なぜこのような差がでるのでしょうか…?

Infinity Fabric

AMDのCPUやAPUで、パッケージ内部のI/OダイとCPUチップレットを接続する Infinity Fabric について説明します。

現代の視点では、Infinity Fabricは「少し遅延が目立つが安価なチップレット接続技術」です。 ライバルメーカーはチップレット分割しないモノリシック設計(Apple)だったり、小型シリコンブリッジでチップレット間を高帯域接続(Intel)したり、チップレット間を垂直積層したりしています。どれもInfinity Fabricより遅延が少ないですが、コストは高くなります。 AMDはゲーム機のAPUなどローエンドでも活躍できるコスト効率に優れた技術デッキを選択したのですね。

ボトルネックの正体

Strix Halo でCPUからのメモリreadが遅い理由。想像の域を出ませんが、それは Infinity Fabric のレイテンシの影響でしょう。CPUはInfinity Fabric経由でI/Oダイに接続され、I/Oダイ内部のメモリコントローラがこの処理を行います。Infinity Fabricにはそれなりのレイテンシと帯域上限があるので、メモリアクセス速度を低下させます。 Strix Halo では、高速メモリとの組み合わせによりInfinity Fabricの限界が露呈したのではないでしょうか。

Strix Halo の設計意図

あらためて Strix Halo の内部構造を分析してみます。

I/Oダイに集められたもの

このAPUのI/Oダイ(307mm²)は巨大で、以下の要素が収められています。

  • GPU: 40CU
  • GPU用の32MB MALLキャッシュ(Infinity Cache)
  • LPDDR5Xを制御するメモリコントローラ
  • NPU
  • PCIeバス

I/Oダイ内部の物理的に近い距離に配置することでGPUとNPUと高速メモリのやり取りが遅延せず、ゲーム/AI用途で性能を出しやすい構造となっています。

一方でCPUは8コアのチップレット2つをInfinity FabricでI/Oダイに接続していて、先程説明した通りInfinity Fabricの遅延により高速メモリの性能を活かせていません。それでも既存のゲーミングPCよりは速いのでゲーム/AI用途の妨げにはなりません。

GPUは「主役」、CPUは「補助」。GPUを優先した設計意図は明らかです。高速メモリとInfinity Fabricの組み合わせは限界を露呈したとも言えますが、これはAPUの価格を下げるのに役立っています。合理的な設計ではないでしょうか。

ライバルとの比較

システム メモリ帯域 価格
Mac M4 Max 400+ GB/s 50万円~
Mac M4 Pro 200~230 GB/s 30万円~
EVO-X2 (Strix Halo) 147 GB/s 22万円
Ryzen 9000 (DDR5) 70~75 GB/s 25万円~

期待よりは半減とはいえ、メモリ速度と価格に注目するとStrix Haloはユニークな立ち位置ですね。

Apple Silicon との比較

Apple Siliconは単一のダイを使うモノリシック設計なので、高速メモリとの組み合わせにおいてより良いパフォーマンスを期待できます。ただしそのモノリシック設計によりダイは大きくなり、半導体製造の歩留まりは悪化して製品価格に影響します。

DDR5 Dual Channel PCとの比較

「普通の自作PC」の構成例。

パーツ 価格(日本)
Ryzen 9 9950X 52,000円
DDR5-7200 64GB 70,000~80,000円
RTX 4070 84,000円
マザーボード X870E 40,000円
SSD 1TB 15,000円
電源 750W 15,000円
ケース 10,000円
CPUクーラー 8,000円
合計 約294,000~304,000円

「普通の自作PC」は約29~30万円、EVO-X2は22万円です。 デスクトップPCには電源設計や冷却設計や拡張性で利点があるので単純な優劣は比較できませんが、もし用途が合うならEVO-X2はお買い得といえるでしょう。

DDR5 Quad Channel ワークステーションとの比較

Intel Xeon W や AMD Threadripper PRO など、DDR5 Quad Channel を使うワークステーションとメモリ性能と価格だけをざっくり比較してみます。

構成 メモリ速度(理論値) メモリ速度(実測) 価格
EVO-X2 256GB/s 147 GB/s 22万円
Threadripper PRO 7975WX 166 GB/s 約130~140 GB/s 本体だけで40~60万円+

EVO-X2はアーキテクチャ制約によりCPUからのメモリリードが理論値の6割程度となっていますが、それでもワークステーションと同等以上の速度が出ています。

Ubuntu Linuxでの使用感と設定

全く不満なし。 用途に合わせて以下の設定を行っています。

amdgpuとrocm

私の環境では、Ubuntu 24.04.3 LTS Desktop に amdgpu と rocm の 7.1をAMD公式の手順でインストール/動作しています。

zswap

Mac OS にはメモリ自動圧縮機能がありますが、Linuxだと自分で設定する必要があります。 ただし zstd や zpool などのアルゴリズムを選択することで圧縮効率を高くできます。

Transparent Huge Page

Ubuntu 24 では Transparent Huge Page はデフォルトでmadviseになっていますが、このメモリ量と速度ならalwaysにしても体感的に不便を感じることはほぼありません。

snapd の除去

このハードに限った話ではありませんがUbuntuのsnap上で動作するアプリはセキュリティサンドボックスのせいでiBus経由の日本語入力にトラブルを生じることが多いです。Ubuntuインストール直後にsnapを使うアプリはfirefoxがありますが、今回はこれをvivaldiに変えて、残りのsnapパッケージも全部purgeしてsnapdを除去しました。手順の詳細はAIに尋ねてください。

Conclusion

Ryzen AI Max+ 395は128GBモデルが人気ですが、そちらの価格は高騰しています。 一方で64GBモデルは発売当時からほぼ値上がりしておらず、2025年秋冬のPCパーツ高騰を考えると貴重です。

APUの設計には妥協も見られますが、結果としてはワークステーション並にメモリが速いPCを良好なコスパで利用できます。メモリ重視の用途なら同価格帯にはライバルがいません。

ただしいくつか注意点があります。

  • ミニPCなので拡張性は高くない。USB4端子を利用することが多いだろう。ただしM.2スロットからPCIeを取り出す事も一応は可能だし、AMD Ryzen AI Max+ 395搭載機種の一部にはPCIeスロットを持つものもある。
  • ミニPCなので電力や排熱に関する設計はデスクトップPCと比べて大きく制約される。短時間バースト性能は優秀なのでベンチマーク値は高いが、負荷が長時間続くと半導体の過電流や加熱を防ぐために性能はややスロットリングされる。デスクトップPCの大きなファンと同じ風量をミニ小さなファンで得るにはファンを増やし回転数を上げるしかないが、ファン騒音は回転数の3乗に比例する。つまり静粛性でも不利だ。
  • 冷却ファンは1-2年で軸が摩耗/損傷して騒音を出すようになる。ミニPCは交換用ファンの入手難易度が高い。分解してファンの型番と写真を控え、AliExpressなどで探すことになる。

注意点を理解した上で、もし用途が合うなら良い選択と言えるでしょう。

Android14の「写真と動画を選択」

Android14で端末中への画像アクセスが「OS側でユーザに画像を選ばせてアプリはその範囲しかアクセスできない」件、
他アプリはどうなのだろうと思って調べてみたらTwitter(X)はまだtargetSdkVersion33で未対応だった。

ThreadsはtargetSdkVersion34で一応対応してるが、古い作りの「アプリ内でギャラリーを表示する」から脱却していなかった。よって権限ダイアログで「写真と動画を選択」を選んだ場合(選択肢のトップなので、多くのユーザがこれを選んでしまうだろう)、その後にOSが提供するダイアログで「アプリがどの画像にアクセスできるか」を選び、さらにアプリ内ギャラリーでもう一度画像を選択する形になる。2回選択するというのが非常にわかりにくい。

その後画像をさらに追加したい場合どうするかというと、投稿作成画面のサムネイルをタップすると再度アプリ内ギャラリーが開くが、この時点ではOSから許可されていないので追加の画像はギャラリーには存在しない。アプリ内ギャラリーに「一部の写真と動画に対して、Threadsによるアクセスを許可しました。」という注意書きがうっすら見えて、その右の管理するボタンを押すと「さらに写真を選択」「設定を変更」の選択肢がある。
「さらに写真を選択」はOSによる画像選択画面からやり直してOSがアプリにアクセス許可する画像を増やして、その後にアプリ内ギャラリーに候補が追加されて、ユーザは再度画像を選ぶ。2回選択するというのが非常にわかりにくい。

「設定を変更」はアプリの権限設定への導線で、「写真と動画へのアクセス」を「常に全て許可」にさせたいのだろう。これを行うとアプリ内ギャラリーには端末中の画像が全て表示され、Android 13までと同様の操作感になる。

権限を一度取得したらアプリから端末上の画像を全部読める、という時代は終わるのだと思う。それはそうだ、公開したい写真を選ぶためだけに、公開したくない写真にまでアプリがアクセスできるのは危険だろう。悪意のあるアプリがウラでどこかにアップロードしていてもユーザは気が付かない。

過去のアプリのUXは、端末上の全てにアクセスできる前提で、端末上の画像を選ぶ画面をアプリ側で作り込んでいた。その画面に、投稿中の画像の順序を変更する機能も持たせていた。

おそらく今後は端末上の画像を選ぶ画面はセキュリティのためにOSに任せるべきで、投稿中の画像の順序を変更する機能は別の場所に設ける必要がある。

あと、OSで選択した画像のUriは権限の種別によりpickなんとかという内容になってしまい、過去のMediaStoreのUriとは異なる。過去のMediaStoreのUriでクエリしても空カーソルが返る。例えば過去のアプリではSAFのDocument Uri をMediaStoreのUriに変換したりしていたが、そういう芸当はもう出来なくなる。

rsync のmanual の"Include/Exclude Pattern Rules" の日本語訳

原文: "Include/Exclude Pattern Rules" section in https://linux.die.net/man/1/rsync

+-などのフィルター・ルールを使ってパターンを指定することで、ファイルをインクルードしたり、除外したりすることができます(上記の「フィルター・ルール」のセクションで紹介されています)。

include/excludeルールはそれぞれ、転送されるファイル名とマッチするパターンを指定します。

これらのパターンにはいくつかの形式があります:

  • パターンが/で始まる場合は、ファイル階層の特定の場所に固定され、そうでない場合はパス名の末尾にマッチする。 これは正規表現における先頭の^に似ている。したがって、/fooは、トランスファーのroot(グローバルルールの場合)、またはマージファイルのディレクト(ディレクトリごとのルールの場合) のいずれかにあるfooの名前にマッチします。非限定fooは、ツリー内のどこでもfooの名前にマッチする。これは、アルゴリズムトップダウン再帰的に適用されるためである。(訳注:パターン先頭の/で)アンカーされていないsub/fooであっても、foosubという名前のディレクトリの中で見つかった場合、階層内のどのポイントでもマッチする。 転送のルートでマッチするパターンを指定する方法の詳細については、ANCHORING INCLUDE/EXCLUDE PATTERNSのセクションを参照のこと。
  • パターンが/で終わっている場合は、ディレクトリにのみマッチし、通常のファイル、シンボリックリンク、デバイスにはマッチしない。
  • rsyncは単純な文字列マッチングを行うかワイルドカードマッチングを行うかを、パターンに *?[ の3つのワイルドカード文字のいずれかが含まれているかどうかチェックして選択します。
  • 単一の* はany path componentにマッチするが、スラッシュにマッチしない。
  • ** を使うとスラッシュを含むanythingにマッチする。
  • ? はスラッシュ以外のany character (1文字) にマッチする。
  • [ は文字クラス指定を開始する。[a-z][[:alpha:]]のような。
  • ワイルドカード・パターンでは、バックスラッシュはワイルドカード文字をエスケープするために使うことができるが、ワイルドカードが存在しない場合は文字通りにマッチする。
  • パターンが / (末尾の / はカウントしない) または ** を含む場合、先頭のディレクトリを含む完全なパス名に対してマッチされる。パターンに/**が含まれていない場合は、ファイル名の最後のコンポーネントに対してのみマッチする。(このアルゴリズム再帰的に適用されるので、full filenameは実際には開始ディレクトリから下のパスのどの部分にもなりうることを思い出してください)。
  • 末尾にdir_name/***を指定すると、ディレクトリ(dir_name/が指定されたかのように)とディレクトリ内のすべて(dir_name/**が指定されたかのように)の両方にマッチします。この動作はバージョン2.6.7で追加された。

element-matrix.juggler.jpの見た目を軽く変えてみる

Matrixの Element-web を動かしている element-matrix.juggler.jpの見た目を軽く変えてみる。 別におしゃれにしたい訳ではなく、Google Safe Browsing の フィッシングサイト誤検知にひっかかってしまったから。 とりあえず素のElement-webと区別できるようにしたい。

config.json

以下のような内容を追加/変更する。

{

    (snip…)

    "defaultCountryCode": "JP",
    "brand": "juggler.jp Matrix サービス",
    "branding" :{
        "welcome_background_url": "https://matrix-element.juggler.jp/x/bg.jpg",
        "auth_header_logo_url": "https://matrix-element.juggler.jp/x/logo.png",
        "auth_footer_links" : [
            {
                "text":"Juggler.jp Matrix サービスについて",
                "url":"https://tateisu.hatenablog.com/entry/2023/01/20/164203"
            }
        ]
    },
    "embedded_pages": {
        "welcome_url": "https://matrix-element.juggler.jp/x/welcome.html"
    }
}

項目の説明は element-web高s機器にある。 github.com

welcome_url

embedded_pages.welcome_url にはHTML断片が入ったURLを指定できる。 今回は超シンプルに以下のようなもの。

<br/>
<div  style="background-color:#fff;padding: 1em;">
<h1>Juggler.jp Matrix サービス<br/>"Element" Web UI</h1>

<H3>matrix.juggler.jp を Element Web UI で使う</h3>
<ul>
<li><a href="https://matrix-element.juggler.jp/#/register">ユーザ登録</a></li>
<li><a href="https://matrix-element.juggler.jp/#/login">ログイン</a></li>
</ul>

<H3>このサイトの説明</h3>
<ul>
<li><a href="https://tateisu.hatenablog.com/entry/2023/01/20/164203">Juggler.jp Matrix サービスについて</a></li>
<li><a href="https://matrix.org/">Powered by Matrix</a></li>
</ul>
</div>

PostgreSQL 15 で pg_basebackup したデータの復旧テスト

pg_basebackupしたデータからの復旧テスト

バックアップしたデータ

base.tar.gz
backup_manifest
pg_wal.tar.gz
package_versions
  • package_versions は dpkg -l |grep postgres を記録したもの。
  • 残り3つは pg_basebackup が出力したファイル。

package_versionsの内容

rc  pgdg-keyring                          2018.2                                  all          keyring for apt.postgresql.org
ii  postgresql-15                         15.1-1.pgdg22.04+1                      amd64        The World's Most Advanced Open Source Relational Database
ii  postgresql-client                     15+246.pgdg22.04+1                      all          front-end programs for PostgreSQL (supported version)
ii  postgresql-client-15                  15.1-1.pgdg22.04+1                      amd64        front-end programs for PostgreSQL 15
ii  postgresql-client-common              246.pgdg22.04+1                         all          manager for multiple PostgreSQL client versions
ii  postgresql-common                     246.pgdg22.04+1                         all          PostgreSQL database-cluster manager
ii  postgresql-contrib                    15+246.pgdg22.04+1                      all          additional facilities for PostgreSQL (supported version)
ii  postgresql-doc                        15+246.pgdg22.04+1                      all          documentation for the PostgreSQL database management system
ii  postgresql-doc-15                     15.1-1.pgdg22.04+1                      all          documentation for the PostgreSQL database management system

dockerコンテナで復旧テスト

コンテナの起動

$ docker run -v /x/backup/postgres/20230121-050015:/backup:ro --rm -it ubuntu:22.04 bash

OSバージョンの確認

# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy

必要そうなパッケージのインストール

apt update
apt install whiptail locales lv nano sudo curl ca-certificates gnupg lsb-release

ロケールの作成

  • ubuntuコンテナだと en_us.UTF-8 がない。
  • DBデータ復旧後の起動でログに問題が報告されるので、用意する。
apt update && apt install whiptail locales
dpkg-reconfigure locales

バックアップデータの確認とWALアーカイブの展開

  • dockerコンテナ起動時にバインドマウントしたフォルダ
  • WALアーカイブは適当にフォルダを作って展開しておく
  • パーミッションをDBが読めるものにする
# export BACKUP_DIR=/backup
# find $BACKUP_DIR -ls
# mkdir /walArchive
# cd /walArchive
# tar xzf $BACKUP_DIR/pg_wal.tar.gz
# chmod -R a+rw .
# find . -ls

Postgres リポジトリの導入

# curl https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor > /etc/apt/trusted.gpg.d/apt.postgresql.org.gpg
# echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list
# cat /etc/apt/sources.list.d/pgdg.list

バージョンを指定してインストール

apt update
apt-get install postgresql-15=15.1-1.pgdg22.04+1 postgresql-client-15=15.1-1.pgdg22.04+1

インストール中にタイムゾーンを尋ねられる。今回は Asia/Tokyo を指定した。

DB起動/接続のテスト

# service --status-all
# service postgresql start
# service --status-all
(postgresサービスが起動していること)
# ps auxwf
(プロセス一覧にpostgresが見えること)
# lv /var/log/postgresql/postgresql-15-main.log
2023-01-21 10:49:52.237 JST [6265] LOG:  starting PostgreSQL 15.1 (Ubuntu 15.1-1.pgdg22.04+1) on x86_64-pc-linux-gnu,
 compiled by gcc (Ubuntu 11.3.0-1ubuntu1~22.04) 11.3.0, 64-bit
2023-01-21 10:49:52.237 JST [6265] LOG:  listening on IPv4 address "127.0.0.1", port 5432
2023-01-21 10:49:52.237 JST [6265] LOG:  could not bind IPv6 address "::1": Cannot assign requested address
2023-01-21 10:49:52.242 JST [6265] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2023-01-21 10:49:52.249 JST [6268] LOG:  database system was shut down at 2023-01-21 10:49:23 JST
2023-01-21 10:49:52.254 JST [6265] LOG:  database system is ready to accept connections

接続テスト

# sudo -u postgres psql -c "\\l"
                                                 List of databases
   Name    |  Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges
-----------+----------+----------+-------------+-------------+------------+-----------------+-----------------------
 postgres  | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 template0 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
           |          |          |             |             |            |                 | postgres=CTc/postgres
 template1 | postgres | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
           |          |          |             |             |            |                 | postgres=CTc/postgres
(3 rows)

DBを止める

# service postgresql stop
# ps auxwf
(postgresのプロセスが存在しないこと)
# lv /var/log/postgresql/postgresql-15-main.log
2023-01-21 10:53:47.786 JST [6265] LOG:  received fast shutdown request
2023-01-21 10:53:47.796 JST [6265] LOG:  aborting any active transactions
2023-01-21 10:53:47.798 JST [6265] LOG:  background worker "logical replication launcher" (PID 6271) exited with exit
 code 1
2023-01-21 10:53:47.798 JST [6266] LOG:  shutting down
2023-01-21 10:53:47.801 JST [6266] LOG:  checkpoint starting: shutdown immediate
2023-01-21 10:53:47.830 JST [6266] LOG:  checkpoint complete: wrote 43 buffers (0.3%); 0 WAL file(s) added, 0 removed
, 0 recycled; write=0.006 s, sync=0.012 s, total=0.033 s; sync files=11, longest=0.003 s, average=0.002 s; distance=2
52 kB, estimate=252 kB
2023-01-21 10:53:47.834 JST [6265] LOG:  database system is shut down

データ破損

  • DBは止めておく
cd /var/lib/postgresql/15/main/
rm -fr ./*

データの復旧

cd /var/lib/postgresql/15/main/
tar xvfz $BACKUP_DIR/base.tar.gz

restore_command の確認と設定

# grep -rin restore /etc/postgresql/15/main/ 
./postgresql.conf:268:#restore_command = ''             # command to use to restore an archived logfile segment
./postgresql.conf:269:                          # placeholders: %p = path of file to restore
./postgresql.conf:282:#recovery_target_name = ''        # the named restore point to which recovery will proceed

設定されてないので設定する。

nano /etc/postgresql/15/main/postgresql.conf

CTRL-W を押して restore_command を入力してEnter。 既存の行は変えず、次の行を挿入。

restore_command = 'cp /walArchive/%f %p'
archive_cleanup_command = 'pg_archivecleanup /walArchive %r'

CTRL-Oを押してファイル名をかえずにEnterして保存。 CTRL-Xで終了。

起動

service postgresql start

ログの確認

lv /var/log/postgresql/postgresql-15-main.log
(snip)
2023-01-21 10:57:04.170 JST [6401] LOG:  restored log file "00000001000000770000003B" from archive
2023-01-21 10:57:04.211 JST [6401] LOG:  redo starts at 77/3B000028
(snip)

データを読めているか

# sudo -u postgres psql -c "\\l"
                                                  List of databases
   Name    |   Owner   | Encoding |   Collate   |    Ctype    | ICU Locale | Locale Provider |   Access privileges
-----------+-----------+----------+-------------+-------------+------------+-----------------+-----------------------
 lemmy     | lemmy     | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 mastodon2 | mastodon2 | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 mastodon3 | mastodon3 | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 matrix1   | matrix1   | UTF8     | C           | C           |            | libc            |
 misskey11 | misskey11 | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 misskey12 | misskey12 | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 postgres  | postgres  | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            |
 template0 | postgres  | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
           |           |          |             |             |            |                 | postgres=CTc/postgres
 template1 | postgres  | UTF8     | en_US.UTF-8 | en_US.UTF-8 |            | libc            | =c/postgres          +
           |           |          |             |             |            |                 | postgres=CTc/postgres
(9 rows)

この記事に含まれないもの

  • /etc/postgresql/15/main/ の復旧。 多分 /etc まるごとバックアップしてると思うので…

matrix.juggler.jp

Juggler.jp Matrix サービスについて

MatrixはOSSのメッセージサービスです。

  • 分散型、非中央集権型
  • 強力な暗号化機能があります。

Juggler.jp Matrix サービスは以下の2つを提供しています。

メモ:

  • バックエンドサーバ(matrix,juggler.jp) と WebUI (matrix-element.juggler.jp) は完全に分離しています。
  • 他のMatrixサーバにあるルームにも参加できます。
  • アプリも色々あります。Elementアプリは Web以外にも、PCデスクトップ版、Android版、iOS版を利用できます。

導入手順

matrix.juggler.jp の告知やメンテナンスは?

2023/02/17 フィッシングサイトと偽検出されてしまった件

Google Safe Browsingさんにフィッシングサイトと偽検出されてしまい、各種ブラウザでもページを開くと警告が出るようになってしまいました。
また、警告をスキップした後でもFirefoxだとプラウザの設定を変えないと Element-web と matrix.juggler.jp の間の通信ができません。

Firefoxのセーフブラウジング設定

Googleへサイトの再審査要求を出して改善を待っている状態です。

mastodon.juggler.jp

2023/01/19 DBロストのお知らせ

matrix.juggler.jp というサービスのDBをロストさせてしまいました…。
DB完全初期化なので、ユーザは新規登録からやりなおしです。
今後はDBバックアップに不備がないよう努めてまいります。

Huawei端末の「デフォルトの保存場所」と externalCacheDir と FileProvider.parsePathStrategy

Huawei端末はデフォルトの保存先をSDカードにすることができる。

私の手元では以下の2機種にその設定があった。

f:id:tateisu:20211121141542p:plain

f:id:tateisu:20211121141524p:plain

その設定により、context.externalCacheDir は SDカードのパスを返す。
しかし ContextCompat.getExternalCacheDirs(context)[0] はプライマリストレージのパスを返す。

FileProvider#parsePathStrategy が参照するのは後者であり、よってFileProvider経由で外部アプリに公開したいならアプリでも ContextCompat.getExternalCacheDirs(context)[0] を使ってファイル保存を行うべきだ。

結果としてキャッシュデータはプライマリストレージに保存されてユーザの意向は反映されなくなるが、動作しないよりはマシ。