升級到 WordPress 6.3 遇到的問題

WordPress 6.3 出了:「WordPress 6.3 “Lionel”」,順手按了升級就爛掉了,發現是 admin 介面爛掉,網站本身還能瀏覽,先翻出 PHP 的錯誤訊息:

2023/08/09 04:52:32 [error] 845702#845702: *1350433 FastCGI sent in stderr: "PHP message: PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments to function W3TC\Util_Environment::is_dbcluster(), 0 passed in /srv/blog.gslin.org/public/wp-content/db.php on line 56 and exactly 1 expected in /srv/blog.gslin.org/public/wp-content/plugins/w3-total-cache/Util_Environment.php:176

順著這個訊息找到這個算新的討論:「Fatal error in Util_Environment」,看起來跟 W3 Total Cache 有關。

(話說這個錯誤訊息還比較新,Kagi 上面找不到,後來是在 DuckDuckGo 上找到)

解法就比較粗暴一點,先到 wp-content/plugins 下讓 W3 Total Cache 失效:

sudo chmod 000 w3-total-cache

跑完升級後會出現錯誤訊息提示 W3 Total Cache 沒有啟用,這時候再開回來:

sudo chmod 755 w3-total-cache

後續把 cache 都清掉就正常了。

MySQL 改變發佈的方式,推出 LTS 版本

看到 Percona 寫的「LTS and Innovation Releases for Percona Server for MySQL」這篇,才注意到 Oracle 宣佈了 MySQLLTS 版本:「Introducing MySQL Innovation and Long-Term Support (LTS) versions」。

這次的改變產生了 Innovation 版本與 LTS 版本:

We're transitioning to the new MySQL versioning model with our upcoming versions. MySQL database version 8.1.0 will be our first Innovation release, and 8.0.34+ will transition to only bug fixes until 8.0 End-Of-Life (EOL) scheduled for April-2026. Approximately one year from now, MySQL version 8.x will eventually become LTS which will provide ample time for users to migrate from 8.0.x to the 8.x LTS version.

從這段的解釋看起來是在講從舊的發佈模式到新的發佈模式的轉換期特例,MySQL 8.0.34+ (應該是指 8.0 的後續這條,從 8.0.34 開始) 會支援到 2026 年四月,大約是再兩年半多;而 8.x (應該是指 >8.0 的這條?) 會在距今一年後 (大約是 2024 年年中?) 成為 LTS 版本。

接著的段落拿了一些範例說明:

In practice, in this transition period, if you want the latest features, improvements, and all bug fixes for your MySQL databases, use the Innovation release track (eg., 8.1.x, 8.2.x, 8.3.x, etc.). If you need only bug fixes for your MySQL database, use 8.0.x releases (eg., 8.0.35, 8.0.36, 8.0.37, etc.). In both cases, you should plan to update your MySQL databases quarterly accordingly to Oracle Critical Patch Updates (CPU) calendar. When 8.x becomes LTS, you can plan, test, and migrate from the 8.0.x bug fix track to the LTS release track (ex., from 8.0.37 to 8.4.1).

看起來 8.0 是轉換期的特殊待遇,看起來有點像是 LTS 的 security update only?然後是官方給的這張圖,要注意這張圖下面有提到這張圖只是示意,實際發生的時間點可能會有改變,不過也可以看出來在 8.0 的地位比較特別:

Note that this is an example, there is no commitment that the version numbering will be exactly as presented.

而 LTS 的頻率會是兩年一版,支援 5+3 年,而 8.0 會走四年半:

About every 2 years, a minor version will be designated as Long Term Supported release. This version will have a 5 year premier and 3 year extended support, the same as the previously supported releases. This is similar to MySQL 5.7 and previous releases.

The LTS will also be the last version of the major release. The next (Innovation) release will increase it's major version. For example if MySQL 8.4.0 is the 8.x LTS release, then MySQL 9.0 will be the next Innovation release.

另外後面有提到他們會確保 LTS 在升級時會用到的方式,看了一下沒有太多意外,跟之前在 5.x 年代的感覺差不多。

倒是降級這件事情他們也提出方案,這點就蠻值得看一下了... 然後這邊可以看到 async replication 果然超萬用的。

基本上就是 release cycle 改變的公告,現在這個階段繼續黏在 8.0 上面應該就可以了,後續等第一個 LTS 的消息。

低 Downtime 將 4TB 的 PostgreSQL 9.6 資料庫升級到 13 的故事

前幾天在 Hacker News 首頁上看到的文章,講怎麼把一個 4TB 的 PostgreSQL 從 9.6 升級到 13 的故事:「How we upgraded our 4TB Postgres database (retool.com)」,原文在「How Retool upgraded our 4 TB main application PostgreSQL database」,翻了一下 LinkedIn,這篇文章的作者 Peter Johnston 在 Retool 掛的是 Security Software Engineer,另外他也有在 Hacker News 上的討論出現 (帳號是 mrbabbage),可以搜尋翻翻看他的回覆。

看完文章後發現方法的概念其實不難,主要是要找到對的工具來用。基本的想法是先生出一個 initial dump,然後架構 logical replication,接下來就是處理各種因為在 4TB data 這個 scale 下會遇到的問題。

主要用到的工具是 Citus Data 的 Warp:「Citus warp: Database migrations without the pain」,不過這個工具的限制是表格必須都有 single column primary key,所以他們為了這次轉移也有小改 database schema 配合 Warp 的要求:

We had to do a bit of finagling to coax Warp into processing our database. Warp expects all tables to have a single column primary key, so we had to convert compound primary keys into unique constraints and add scalar primary keys. Otherwise, Warp was very straightforward to use.

另外針對比較大的兩個 append-only 的表格 (分別是 2TB 與 x00 GB) 做處理,在 initial dump 的階段不對這兩個表格做 replication,而是透過自製的 Python script 搬移:

To handle the two massive tables we skipped in Warp, we wrote a Python script to bulk transfer data from the old database server to the new.

然後是 foreign key 相關的關閉與重啟,這算是 RDBMS 在大量資料的 dump & restore 的標準作業了:

As you can see from the runbook above, one of the steps we had to do was to turn off and then re-enable foreign key constraint checks.

最後執行下去,整個 downtime 只有十五分鐘:

We scheduled the maintenance window late on Saturday, October 23rd, at the lowest period of Retool cloud traffic. With the configuration described above, we were able to bring up a new database server at version 13 in around 15 minutes, subscribed to changes at our 9.6 primary with logical decoding.

另外也有提到有計畫要 sharding,之後 main database 就有機會被拆小:

We anticipate we’ll have sharded our database by the end of that support window, and be performing our next substantial version upgrades incrementally.

整個計畫的核心概念不難,主要是要怎麼順出來並且執行...

Let's Encrypt 升級資料庫伺服器 (AMD YES?)

Let's Encrypt 升級了 MariaDB 資料庫的伺服器 (跑 InnoDB),特地寫了一篇文章出來講:「The Next Gen Database Servers Powering Let's Encrypt」。

CPU 的部份從本來的 2x Intel Xeon E5-2650 (Total 24 cores / 48 threads) 換成了 2x AMD EPYC 7542 (Total 64 cores / 128 threads),這點在本來就是 CPU 滿載的情境下改善很大:

而本來的瓶頸一解決,也使得 API 的 latency 直接降下去:

回頭看一下架構,可以看到他們提到沒有使用分散式的資料庫,而是單台 database 硬撐,驗證了即使到了 Let's Encrypt 這種規模,以暴制暴還是很有效的:

We run the CA against a single database in order to minimize complexity. Minimizing complexity is good for security, reliability, and reducing maintenance burden. We have a number of replicas of the database active at any given time, and we direct some read operations to replica database servers to reduce load on the primary.

除了 CPU 暴力外,2TB RAM 與 24 顆 NVMe SSD 的搞法也是很讚的,擺明就是用記憶體拼 cache 的量,以及用大量的 NVMe SSD 疊 IOPS。

然後硬體還在成長,看起來暴力解應該會變成以後的基本答案了...

升級跳板機

算是做個記錄...

差不多是 2014 年的時候,因為 xDSL 網路的頻寬拉起來比較夠用了,加上當時發生一些事情,而且 HiNetPPPoE 可以申請發一個固定 IP (即「非固固 IP」),所以就用這個功能架了一台小的 server,這樣一來就有一台小的 server 可以用,另外很多 firewall 之類的操作就方便很多。

當時買的機子是 GigabyteGB-XM12-3227Intel i3-3227 + 4GB RAM + 128GB mSATA SSD:

幾年前 CPU 風扇掛過一次,去淘寶上挖了一顆回來後又可以繼續用。

不過後來在上面跑的東西愈來愈多,加上現在的軟體開發愈來愈吃各種資源 (就算只是 command line 環境),i3-3227 的 CPU Benchmarks 跑分也才 1274,記憶體也只裝了 4GB,跑起來還是愈來愈吃力... 大概在年初的時候就有打算要換,直到看到了這個機殼的影片:

我買了一個機殼回來 (還找到 $350 含運的店家),在客廳裝了一台 Intel J1900 + 8GB RAM 的機器接電視用 (不過這又是另外一個故事了),對這款機殼還算滿意,就再去下了一顆回來...

接下來就是湊其他的零件了,既然這次要拿來當半個開發機用,上面的等級要好一點,但又不希望太吃電 (畢竟是一直開著的機器),所以就找了一顆二手的 Intel i3-8100T (35W,CPU Benchmarks 分數 5319),然後在 PChome 24h 上面找了張 H310 的主機板,一個全新的 350W 電源供應器,以及 2*16GB RAM + 500GB SATA SSD。風扇的話是之前 Intel E3-1230 v3 留下來的風扇 (現在上面是掛水冷),扣具的位置是相同的 (LGA115x),就直接拿來用了。

弄好後裝個 Ubuntu 20.04,然後在只有兩顆風扇的環境下 (電源供應器的風扇與 CPU 風扇),CPU idle 只有 35 度上下,壓測也只有 55 度上下,本來還在糾結後方要不要還是裝個 8cm 系統風扇,後來決定還是放一顆上去好了,用負壓的方式把熱帶出來。

如果之後真的遇到灰塵太多的問題,再考慮用先前在「無風扇系統的 CPU 散熱片」提到的方案來換:

接下來就是搭車把機器帶老家裝,就順便被老人家餵食:

回家升級跳板機,然後就被餵食了...

換完後當然如同預期的速度快不少,接下來應該會考慮把線路升級到 300M/100M (現在只有 100M/40M),不過看起來 IP 一定會變,就比較麻煩了,之後再看看機會...

AWS 提供程式,可以掃出有哪些 RDS 的憑證需要更新

先前在「AWS 的 CA 更新 (CA-2019),將會影響與資料庫相關的服務」這邊提到了 AWSRDS 因為 Root Certificate 快要過期,需要更新到 CA-2019。

剛剛在 Twitter 上看到 Jeff Barr 提到了一個可以直接列出有哪些機器需要更新的工具:

程式放在 GitHub 上的 aws-samples/rds-ssl-update,另外看到一個有趣的授權條款,叫做 MIT-0 License,是 AWS 自己改的一個授權版本,拿掉了 MIT License 裡面的這段:

subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

也就是要求要引用授權條款的部份被拿掉,不過我還是比較喜歡 BSD license,尤其是 3-clause 的版本...

把自己的 Trac 換到 1.4

八月底的時候就已經出 Trac 1.4 了 (參考當時寫的「Trac 1.4」),不過當時升級一直失敗:

$ trac-admin ./ upgrade
Error: Unable to check for upgrade of trac.db.api.DatabaseManager: TracError: Unsupported database type "mysql"

後來在「TracError: Unsupported database type “mysql”」這邊找到解法,下面有人提到解法是裝系統的 python-pymysql,那麼對應到 pip 的套件安裝時,裝 PyMySQL 就可以了。

另外一個比較麻煩的就是 Trac 的 XmlRpcPlugin 套件,這個套件其實一直都很 hack,常常是自己硬幹底層的東西跳過現有機制 (於是像是透過他開 ticket 時,就不會發通知信之類的問題),但目前暫時又不能不用他...

Anyway,這東西在升級後也爛掉了:「Plugin fails on Trac 1.4」,然後下面看到 Gasol 修了一版出來:「Gasol/trac-xmlrpcplugin」。

另外是我自己有掛 custom theme 的套件 ThemeEnginePlugin 也爛掉了,不過這個暫時移除就好,之後再排進去修...

最後就是把本來的 css/js 都依照「Customizing the Trac Interface」的說明,porting 到 Jinja2 下。

主要就是把本來的 site.html 裡面的片段搬到 site_head.htmlsite_footer.html 裡,然後 CSS 的部份照著建議拆到 style.css 裡 (因為 css selector 的 id selector # 在一行開頭的位置會被 Jinja2 當作命令處理)。

後續繼續看看還有什麼要修正的,另外 wiki 也得等摸索差不多後更新...

AWS 提供將 Lightsail 切換到 EC2 的功能

AWS 總算把 Lightsail 轉移到 EC2 的功能做出來了:「Amazon Lightsail Now Provides an Upgrade Path to EC2」。

這樣先從小站開始跑,搞大後想要改用 AWS 服務的切換成本就降低不少了。不過目前看起來是透過 export-and-import 做:

When you are ready to upgrade an instance to EC2, simply take a snapshot of your instance and follow the step-by-step process in Lightsail's console to export your snapshot to EC2. You can then use EC2 or the Upgrade to EC2 wizard in Lightsail's console to get your new EC2 instance up and running.

不過上次用 Lightsail 可以發現可用的 CPU 跟其他 VPS 比起來慢不少... 這點是一開始要不要選 Lightsail 的因素。

Ubuntu 推出 14.04 的 ESM 計畫

Ubuntu 14.04LTS 版本,在明年四月底 (也就是 2019 年四月) 將會滿五年的維護期,之後就不會有任何公開更新了 (包括安全性更新)。

在前一次的 Ubuntu 12.04 是第一次提供 ESM (Extended Security Maintenance) 服務,讓沒辦法即時轉及到新版的單位可以付費繼續收到安全性更新,算是 LTS 的一個重要服務。

而官方這次也對 Ubuntu 14.04 推出了 ESM:「Announcing Extended Security Maintenance for Ubuntu 14.04 LTS – “Trusty Tahr”」。

Ubuntu 14.04 LTS – ESM will become available once Ubuntu 14.04 reaches its End of Life on April 30, 2019.

價錢應該會跟之前類似吧...

把 Blog 換成 PHP 7.2

去年十一月出 PHP 7.2,現在已經更新到 7.2.5,各家軟體的相容性也都修的差不多了,差不多該升級了。

在「PHP 7.2 的效能改善」這邊有提到與 PHP 7.1 的效能改善主要來自於同時間有多人同時存取時的最佳化。

同樣 wiki 也跟著更新了,來看看效果如何...