MySQL 5.7 的支援只到今年十月 (Oct 2023)

剛剛翻資料才看到 OracleMySQL 5.7 的支援原來只剩下半年了,預定在 2023 年十月中止:「Oracle Technology Products - Oracle Lifetime Support Policy」。

隔壁棚 Percona 包的 Percona Server for MySQL 5.7 可以從「Percona Release Lifecycle Overview」這邊查,看起來也設定一樣的時間 (2023 年十月),但不確定會不會宣佈延長,至少提供 security fix 之類的。

一直沒注意,突然發現只剩下半年...

MariaDB 以及 Trac 在 arm64 上的安裝

把一台本來跑在 Vultr 上的機器搬到 AWSus-east-1 上面,除了剛好把 Ubuntu 18.04 換成 Ubuntu 22.04 外,也把本來用 x86-64 架構的機器換成用 ARMt4g.micro (都是 1GB RAM)。

就效能上來說,t4g 機器的效能很不錯,這兩年 blog 跑的也都還算順,先前公司用起來感覺也很好,然後價錢更便宜,另外加上 AWS 的三年 RI 折扣大約是 4 折的價錢,算是會想要換的主因。

在確認應用跑得起來後,買三年 RI 是 $87.15/3y,所以機器本身的費用大約是 $29.05/y,就算加上 8GB 的 EBS (gp3) 空間費用,整體比本來在 Vultr 的 $6/mo 低不少。

上面跑的是我自己的 Trac,想搬到 AWS 上一陣子了,但有幾個不確定的因素,所以連假期間才有空多花一些時間確認。

第一個是 MySQL 的部份,我自己習慣用 Percona Server 的版本,但目前還沒有 arm64 的套件可以直接裝,要用的話就得自己編以及升級。

在 2021 年的時候 blog 搬到 AWS 的時候就遇過了,本來以為這次有機會,但看了一下還是沒支援,所以還是得用 MariaDB

第二個是 Trac 1.4 只能跑在 Python 2.7 上 (mailing list 上有在討論轉到 Python 3 的事情,但看起來官方的動力也不大...),這在 18.04 的時代是沒什麼問題,但 22.04 下面不知道會爛掉多少東西。

所以只能繼續用 pyenv 扛著,但已經有預期會遇到問題,加上這次又從 MySQL 轉到 MariaDB,應該也會有些地雷...

所以跳下去後遇到的問題就跟上面提到的類似,分成兩塊。

在 MariaDB 這邊第一個遇到問題是,雖然官方有提供 APT server,但沒有在 HTTPS server 上放新的 public key,所以一定得從 key server 撈。

GnuPG 就是沒有直接從 key server 下載變成檔案的功能,一定要先塞到 keystore 裡面再 export 出來,就覺得很...

所以就冒出利用 mktemp -d/tmp 下產生暫存目錄這樣的寫法,讓 GnuPG 把 keystore 放進去,這樣至少在重開機後就會消失:

export GNUPGHOME=$(mktemp -d); gpg --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0x177F4010FE56CA3336300305F1656F24C74CD1D8; gpg --export 0x177F4010FE56CA3336300305F1656F24C74CD1D8 | sudo tee /etc/apt/trusted.gpg.d/mariadb.gpg > /dev/null; unset GNUPGHOME

這邊為了安全性,還得把官方提供的 0xF1656F24C74CD1D8 換成 0x177F4010FE56CA3336300305F1656F24C74CD1D8

另外就是整理 MariaDB 需要的 my.cnf 內容,我是拿 Percona Server 5.7 的設定檔來改,只刪掉了跟 GTID 相關的設定就會動了。

而其他 MariaDB 遇到的問題主要是設計改變的問題,在 wiki 上有提到。

接下來是 Trac 1.4 的問題,本來的安裝是用 libmysqlclient-dev,然後再安裝 mysql-python

sudo apt install -y libmysqlclient-dev
pip install mysql-python PyMySQL Pygments Trac

但單純把 libmysqlclient-dev 換成 libmariadb-dev 後,mysql-python 還是編不動,照著錯誤訊息試著 workaround (像是試著把 /usr/bin/mysql_config 指到 /usr/bin/mariadb_config) 半天還是不過,最後找資料發現要改用 mysqlclient

sudo apt install -y libmariadb-dev
pip install mysqlclient PyMySQL Pygments Trac

搞定後後續就一路看錯誤訊息解就可以了...

Etsy 使用 Vitess 的過程

Etsy 寫了三偏關於使用 Vitess 解決資料庫效能問題的文章:「Scaling Etsy Payments with Vitess: Part 1 – The Data Model」、「Scaling Etsy Payments with Vitess: Part 2 – The “Seamless” Migration」、「Scaling Etsy Payments with Vitess: Part 3 – Reducing Cutover Risk」。

Vitess 是 YouTube 團隊開發出來的東西,試著透過一層 proxy 解決後端 MySQL 資料庫在 sharding 後查詢邏輯的問題。

有一些地方的資訊整理出來:

首先是現代暴力解的能耐,從維基百科可以查到 Etsy 在 2015 年就上市了,但到了 2020 年年底撞到 vertically scaling 的天花板 (這邊是指 GCP 的上限),可以看到現在的暴力法可以撐超久... 如果再多考慮到實體機房的話應該可以找到更大台的機器。

第二個是 Etsy 在 2020 年年底開始從資料庫搬資料,一路到 2022 年五月,算起來差不多搬了一年半,總共轉移了 4 個 database 到 Vitess 的 cluster 上,共 23 張表格與 40B rows。

第三個是利用 Vindexes 這個技術降低 sharding 時所帶來的限制。這個之前沒研究過:

A Vindex provides a way to map a column value to a keyspace ID.

從「Older Version Docs」這邊翻舊版的文件,發現 5.0+ 都有,再往 GitHub 上面的資料翻,看起來從 2016 年的版本就有了,不過當時看起來還一直在擴充:「Vitess v2.0.0-rc.1」。

回來看現在的功能,有 primary vindex 的設計:

The Primary Vindex for a table is analogous to a database primary key. Every sharded table must have one defined. A Primary Vindex must be unique: given an input value, it must produce a single keyspace ID.

然後是 secondary vindex(es) 的設計,指到 keyspace id(s),然後這個資訊會被用在 routing 上:

Secondary Vindexes are additional vindexes against other columns of a table offering optimizations for WHERE clauses that do not use the Primary Vindex. Secondary Vindexes return a single or a limited set of keyspace IDs which will allow VTGate to only target shards where the relevant data is present. In the absence of a Secondary Vindex, VTGate would have to send the query to all shards (called a scatter query).

It is important to note that Secondary Vindexes are only used for making routing decisions. The underlying database shards will most likely need traditional indexes on those same columns, to allow efficient retrieval from the table on the underlying MySQL instances.

然後是 functional vindex 與 lookup vindex,前者用演算法定義 keyspace id,後者讓你查:

A Functional Vindex is a vindex where the column value to keyspace ID mapping is pre-established, typically through an algorithmic function. In contrast, a Lookup Vindex is a vindex that provides the ability to create an association between a value and a keyspace ID, and recall it later when needed. Lookup Vindexes are sometimes also informally referred to as cross-shard indexes.

然後 lookup vindex 還有對 consistent hashing 的支援:

Consistent lookup vindexes use an alternate approach that makes use of careful locking and transaction sequences to guarantee consistency without using 2PC. This gives the best of both worlds, with the benefit of a consistent cross-shard vindex without paying the price of 2PC. To read more about what makes a consistent lookup vindex different from a standard lookup vindex read our consistent lookup vindexes design documentation.

這樣整體看起來,Vitess 把所有常見的 sharding 方式都包進去了,如果以後真的遇到這個量的話,也不需要自己在 application 或是 library 做一堆事情了...

WordPress 打算要支援 SQLite 作為後端資料庫

目前 WordPress 只有支援 MySQL,而昨天在 Hacker News 上看到 WordPress 有打算要支援 SQLite 作為後端資料庫的消息:「WordPress testing official SQLite Support (github.com/wordpress)」,原文在 GitHub 上:「Implement new experimental SQLite integration module」。

理論上對使用者會更方便,但對 extension 開發者會麻煩一些 (或是直接標不支援?),尤其是用到 MySQL 特有的語法就要注意了。

實質上 PHP + MySQL hosting 其實蠻常見的,這個作法有多少幫助就不知道了。

但突然想到,如果做一個 read-only 版本的 WordPress 站台,然後把 SQLite 的讀取部份改用 sql.js 之類的計畫,再把一堆 server side rendering 的部份變成 client side rendering,好像有機會可以整包直接上 GitHub Pages 之類的服務?雖然這樣有點拖褲子放屁...

比對兩個表格 (可以是不同的資料庫) 的內容,指出差異處

前幾天看到的東西,不確定是不是在 Hacker News 上,反正在 tab 上幾天了... 但還是附上 Hacker News 的連結:「Show HN: Data Diff – compare tables of any size across databases」,專案的位置在 GitHub 上的 datafold/data-diff

這是用 Python 寫的工具,安裝可以透過 pip 直接裝,所以也可以用 pipx 之類的工具獨立起來跑。

data-diff 會先拆成多個區塊,然後透過 checksum 的機制判斷兩邊的資料是否相同,不同的部份再取 bisection 分開下去找 (或是更多份,在 Technical Explanation 這個段落有寫到)。

在「Common use-cases」這段有提到幾個常見的使用情境,像是在自動化的環境下可以當作異常監控的工具:

Alerting and maintaining data integrity SLOs. You can create and monitor your SLO of e.g. 99.999% data integrity, and alert your team when data is missing.

另外在 troubleshooting 的情境下當然也很有幫助,可以先確認資料是否有問題,以及資料的哪邊出問題:

Debugging complex data pipelines. When data gets lost in pipelines that may span a half-dozen systems, without verifying each intermediate datastore it's extremely difficult to track down where a row got lost.

這個工具讓我想到 Percona Toolkit 裡面的 pt-table-checksum,不過 pt-table-checksum 只能處理 MySQL replication 的情境,data-diff 看起來通用多了:

目前完整測試過的是 MySQLPostgreSQLSnowflake,其他的有實做但還沒完整測試過。

看起來還在開發 (後面是商業公司 Datafold),但先寫下來,之後如果有用到的時候可以回頭看看進展...

翻一下 Linux container 的各種 overhead

想要查一下 Linux 下跑 container 的 overhead,發現大多都是 2014~2016 左右的文章,而且基本上都是 Docker,好像沒什麼新資料,但還是整理整理...

首先是「What is the runtime performance cost of a Docker container?」這篇,裡面的答案有提到 CPU、Memory 以及 I/O 看起來 overhead 都不高,主要是網路的 latency 增加不少:

看起來大約是 40µs 的增加 (0.04ms),這個量級雖然看起來很小,但對於本來就是透過 Ethernet 溝通的的應用來說,平常可能都是 <1ms 了,0.04ms 的增加可能還是有影響 (像是 TCP 的 3-way handshake)。

另外一篇是 Percona 的「Measuring Percona Server Docker CPU/network overhead」,不過這邊是測 CPU bound 的方式,沒有碰到 heavy I/O:

可以看到網路層的變化造成 tps 的變化,也符合在 Stack Overflow 上面找到的文章。

Oracle 官方的「MySQL with Docker - Performance characteristics」這篇則是測到 I/O bound 的應用,畢竟資料庫軟體會用到很多一般 I/O 測試不會用到的 flag,像是 InnoDB 大家通常都會啟用 O_DIRECT

For these tests, we used a custom configuration file. We first deliberately set the buffer pool size to around 10% of the total database size in order to increase I/O-bound load. The database size was 2358MB, so we set our buffer pool size to 256MB. We then increased the buffer size to 16384MB to see what happens when Docker isn’t bound by I/O load.

文章後面有列出數字,可以看到 I/O bound 的應用似乎沒有什麼影響,而 network bound 的時候可以看到效能的下降。

不過得注意這些資料都是六年前的資料了,沒有什麼新資料可以看做應該是沒什麼改變,但畢竟不是 100% 確定的事情...

這個月 GitHub 的不穩問題,都是 mysql1 這個 cluster 的鍋...

GitHub 針對了這個月的四次 downtime 說明,大致上都跟 mysql1 這組 cluster 有關:「An update on recent service disruptions」,這是 Keith Ballinger 發的文章,找了一下掛的頭銜是 SVP of Engineering at GitHub。

文章裡提到的 mysql1 在「Partitioning GitHub’s relational databases to handle scale」這邊可以看到一些資訊 (我在「GitHub 的 MySQL 架構與數字」這邊也有提到),基本上有 ProxySQL + Vitess 兩套方案在 scale,但可以看出來主資料庫本身還是有很大的 loading 在上面跑。

這次的問題是 mysql1 看起來這次遇到了效能上的瓶頸,不過還是沒找到原因,這可以從這幾次的說明看出來,從第一次的 outage:

The incident appeared to be related to peak load combined with poor query performance for specific sets of circumstances.

第二次的:

The following day, we saw the same peak traffic pattern and load on mysql1. We were not able to pinpoint and address the query performance issues before this peak, and we decided to proactively failover before the issue escalated.

第三次的:

While we had reduced load seen in the previous incidents, we were not fully confident in the mitigations.

In this third incident, we enabled memory profiling on our database proxy in order to look more closely at the performance characteristics during peak load.

到最近第四次的:

In order to reduce load, we throttled webhook traffic and will continue to use that as a mitigation to prevent future recurrence during peak load times as we continue to investigate further mitigations.

可以看到基本上還沒完,之後再遇到問題時應該還是會把 webhook traffic 拿出來開刀...

Linode 過了三年,終於想起來要推出 Managed Databases 服務了

看到 Linode 宣佈 Managed Databases 服務:「Linode Managed Databases in Open Beta」。

測試期間不用錢,但目前只有支援 MySQL,其他幾個像是 PostgreSQLRedisMongoDB 都還沒推出 (在 roadmap 上):

Our new managed database service is now in open beta for new and existing customers! We currently support MySQL during this beta—with a near-term roadmap to add PostgreSQL, Redis, MongoDB—and plan to include additional features.

搜了一下隔壁 DigitalOcean 的資料,Manage Databases 這條產品線在 2019 年二月推出 PostgreSQL 的版本:「Our Valentine’s Gift to You: Managed Databases for PostgreSQL」,在 2019 年八月推出了 MySQL 與 Redis 的版本:「Take the worry out of managing your MySQL & Redis databases」,然後在 2021 年六月推出了 MongoDB 的版本:「Introducing DigitalOcean Managed MongoDB – a fully managed, database as a service for modern apps」。

不過 Vultr 看起來是還是完全沒有樣子,相比起來 Linode 好像不算慢?

另外看起來 DigitalOcean 是跟 MongoDB 合作,不像 AWS 自己另外用 PostgreSQL 搞了一套 XDDD

MariaDB Corporation Ab 透過 SPAC 上市

MariaDB Corporation Ab 透過 SPAC 上市:「MariaDB Corporation Ab to Become a Publicly Traded Company via Combination with Angel Pond Holdings Corporation」。

Upon closing of the transaction, the combined company will be named MariaDB plc and led by MariaDB’s CEO Michael Howard.

Hacker News 上有一些對 MariaDB 的討論可以看一下 (是對軟體討論,不是對公司討論):「MariaDB to go public at $672M valuation (mariadb.com)」。

大多數用 MariaDB 的人其實都只是在用 MySQL 的功能,不常用到 MariaDB 的特殊功能,像是 Aria (MyISAM 的 crash-safe 版本) 還是沒有 transaction,而 InnoDB 的效能其實相當好,就找不太到理由去用 Aria...

另外從 Google Trends 的 volume 也可以看出來趨勢是往下降而非向上爬升,這時候趕快脫手 (而且還是透過 SPAC) 看起來是最好的時機?

Amazon RDS 支援 readonly instance 當作 Multi AZ 的機器了

從來沒在用 RDS 的 Multi AZ,所以根本沒注意到居然沒這個功能:「New Multi-AZ deployment option for Amazon RDS for PostgreSQL and for MySQL; increased read capacity, lower and more consistent write transaction latency, and shorter failover time (Preview)」。

看起來 (加上印象中) 之前的 Multi AZ 是另外一台機器先開著但不能用:

In the case of an infrastructure failure, Amazon RDS performs an automatic failover to the standby, so that database operations resume as soon as the failover is complete.

現在則是開著的機器可以跑 readonly 模式:

The standby DB instances act as automatic failover targets and can also serve read traffic to increase throughput without needing to attach additional read replica DB instances.

這樣做除了省成本外,另外因為這些 instance 平常就有 query 的量,當真的遇到 failover 切換時,warmup 的時間也會短很多 (尤其是服務夠大的時候)。

不過有些限制,首先看起來只支援 Graviton2 (ARM-based) 的機種?

The readable standby option for Amazon RDS Multi-AZ deployments works with AWS Graviton2 R6gd and M6gd DB instances (with NVMe-based SSD instance storage) and Provisioned IOPS Database Storage.

然後是支援的區域:

The Preview is available in the US East (N. Virginia), US West (Oregon), and Europe (Ireland) regions.

以及夠新的版本,MySQL 8 與 PostgreSQL 13.4 才有提供:

Amazon RDS for MySQL supports the Multi-AZ readable standby option for MySQL version 8.0.26. Amazon RDS for PostgreSQL supports the Multi-AZ readable standby option for PostgreSQL version 13.4.

但看起來還不錯,畢竟這比較接近以前在地端機房時的作法...