GitLab 12.1 之後放棄支援 MySQL

GitLab 打算在 12.1 之後放掉 MySQL 的支援:「Why we're ending support for MySQL in 12.1」。

GitLab 在說明裡給了不少原因,但看了看以後還是覺得 GitLab 每次在做技術決策時給出來的理由都很... 有趣?XD

每次看這三家提供的技術工具或是技術決策都很有趣... (另外兩家是 UberYahoo!)

移除 Blog 上的 Google Analytics,改用 Matomo

跑了快一個月了,大概整理一下...

一直都有在規劃降低對 Google 服務的依賴性,最主要的是使用 DuckDuckGo 替代 Google Search (但搜尋的品質還是差一截,所以寫了一些工具幫助我在不滿意的時候可以快速切到 Google 搜尋:「在 DuckDuckGo 搜尋頁快速切換到 Google 的套件」)。

而最近在研究的另外一個服務是 Google Analytics,我只用很基本的功能 (像是熱門文章,作業系統與瀏覽器的比率這些很基本的資料),不需要對於觀看客群有了解 (這個需要像 Google Analytics 跨站蒐集資料),所以替代方案應該不難找...

憑著印象與一些關鍵字,找到了 Matomo,這是一套 open source 的 web analytics 服務,以前叫做 Piwik (參考「Piwik is now Matomo - Announcement」),整個系統用 PHP + MySQL 就可以打發 (反正量不大的東西不需要拿什麼神兵利器出來,MySQL 硬塞硬算就可以了),接著把本來 Google Analytics 的 js 換掉就行了...

跑了快一個月後感覺還 ok,基本的資訊都有...

RDBMS 裡的各種 Lock 與 Isolation Level

來推薦其他人寫的文章 (雖然是在 Medium 上...):「複習資料庫的 Isolation Level 與圖解五個常見的 Race Conditions」、「對於 MySQL Repeatable Read Isolation 常見的三個誤解」,另外再推薦英文維基百科上的「Snapshot isolation」條目。

兩篇文章都是中文 (另外一個是英文維基百科條目),就不重複講了,這邊主要是拉條目的內容記錄起來,然後寫一些感想...

SQL-92 定義 Isolation 的時候,技術還沒有這麼成熟,所以當時在訂的時候其實是以當時的技術背景設計 Isolation,所以當技術發展起來後,發生了一些 SQL-92 的定義沒那麼好用的情況:

Unfortunately, the ANSI SQL-92 standard was written with a lock-based database in mind, and hence is rather vague when applied to MVCC systems. Berenson et al. wrote a paper in 1995 critiquing the SQL standard, and cited snapshot isolation as an example of an isolation level that did not exhibit the standard anomalies described in the ANSI SQL-92 standard, yet still had anomalous behaviour when compared with serializable transactions.

其中一個就是 Snapshot Isolation,近代的資料庫系統都用這個概念實做,但實際上又有不少差別...

另外「Jepsen: MariaDB Galera Cluster」這篇裡出現的這張也很有用,裡面描述了不同層級之間會發生的問題:

這算是當系統有一點規模時 (i.e. 不太可能使用 SERIALIZABLE 避免這類問題),開發者需要了解的資料庫限制...

在 Galera Cluster 上的 DDL 操作 (e.g. ALTER TABLE)

Percona 整理了一份關於 Galara Cluster 上 DDL 操作的一些技巧,這包括了 Percona XtraDB ClusterMariaDB 的版本:「How to Perform Compatible Schema Changes in Percona XtraDB Cluster (Advanced Alternative)?」。

在不知道這些技巧前,一般都是拿 Percona Toolkit 裡的 pt-online-schema-change 來降低影響 (可以降的非常低),所以這些技巧算是額外知識,另外在某些極端無法使用 pt-online-schema-change 的情境下也可以拿來用...

裡面的重點就是 wsrep_OSU_method 這個參數,預設的值 TOI 就是一般性的常識,所有的指令都會被傳到每一台資料庫上執行,而 RSU 則是會故意不讓 DDL 操作 (像是 ALTER TABLE) 被 replicate 到其他機器,需要由管理者自己到每台機器上執行。

利用這個設定,加上透過工具將流量導到不同後端的資料庫上,就有機會分批進行修改,而不需要透過 pt-online-schema-change 這種工具。

把 MySQL 的 binlog 功能再拆出來的 mysql-ripple

看到 Percona 的「MySQL Ripple: The First Impression of a MySQL Binlog Server」這篇提到了 Google 放出來的專案 mysql-ripple

這個軟體的情境是針對有很多 replica (slave) 時的情境,要解決每一個 replica 都會對 master server 產生壓力,算是 binlog 的 cache layer。

MySQL Ripple 抓了 binlog 下來後就可以模擬成 mysql server (但是只能提供 binlog 服務) 讓 replica 接,在 replica 很多的情境下就可以橫向擴充,而且因為軟體只支援 GTID 模式,所以比較好做 HA 架構 (相對於 filename + position 模式)。

大概可以歸納出是 write 很多 (所以 binlog 量很大),但又有大量 replica 需求的情境... 目前好像想不出來有什麼情境可以拿出來用 :o

單機 10 萬個連線 MySQL

也是在「Links: February 2019」這邊看到的,裡面提到了 Percona 的「MySQL Challenge: 100k Connections」。

Percona 的測試是希望每個連線都有在做事,而不是 idle connection,這個測試有點像是卡住時的情況?看起來只有這幾個參數比較特別:

table_open_cache = 200000
back_log=3500
max_connections=110000
max_prepared_stmt_count=1000000

max_connections 開多一點算是廢話,然後因為要做事所以 max_prepared_stmt_count 也多一些,back_log 可以讓 kernel 保留來不及處理的 TCP 連線。

看起來用 sysbench 測試還撐的住,跟理論差不多,隨著連線數的增加 latency 也會增加...

JPMorgan Chase 的 WePay 用的 MySQL 架構

看到「Highly Available MySQL Clusters at WePay」這篇講 WePayMySQL 的設計,本來以為是 WeChat 的服務,仔細看查了之後發現原來是 JPMorgan Chase 的服務...

架構在 GCP 上面,本來的 MySQL 是使用 MHA + HAProxy (patch 過的版本,允許動態改變 pool),然後用 Routes 處理 HAProxy 的 failover。

他們遇到的問題是 crash failover 需要至少 30 分鐘的切換時間,另外就是在 GCP 上面跨區時會有的 network partition 問題...

後續架構變得更複雜,讓人懷疑真的有解決問題嗎 XDDD

改用 GitHub 推出的 Orchestrator 架構,然後用兩層 HAProxy 導流 (一層放在 client side,另外一層是原來架構裡面的 load balancer),在加上用 Consul 更新 HAProxy 的資訊?

思考為什麼會有這樣設計 (考慮到金融體系的背景),其實還蠻有趣的...

TiDB 單機效能

TiDB 是一個支援分散式運算的資料庫,希望能夠完整地模擬 MySQL Protocol,而 Percona 試著測試 TiDB 在單機的效能,雖然測試的項目很簡單,但結果頗有趣的:「A Quick Look into TiDB Performance on a Single Server」。

Percona 觀察到的現象是 TiDB 對於單一 SQL query 支援多 CPU 運算 (MySQL 只會使用單 CPU),所以在高階的機器上,某些 SQL query 會快很多。而 OLAP 類型的 SQL query 也不錯,但常見的 OLTP 應用則慢不少:

Short version: TiDB supports parallel query execution for selects and can utilize many more CPU cores – MySQL is limited to a single CPU core for a single select query. For the higher-end hardware – ec2 instances in my case – TiDB can be 3-4 times faster for complex select queries (OLAP workload) which do not use, or benefit from, indexes. At the same time point selects and writes, especially inserts, can be 5x-10x slower. Again, please note that this test was on a single server, with a single TiKV process.

是個有趣的 drop-in...

Percona 推出 MySQL 8.0 的對應版本了...

Percona 在過節前推出 Percona Server for MySQL 8.0 了:「Announcing General Availability of Percona Server for MySQL 8.0」。

Oracle 版的 MySQL 8.0 多了不少功能,像是往 NoSQL 靠的功能與 GIS 相關的功能,但讓我注意到的是 Percona 自己的事情... TokuDB 因為 MyRocks 而要被放生了:

Features Being Deprecated in Percona Server for MySQL 8.0
TokuDB Storage Engine: TokuDB will be supported throughout the Percona Server for MySQL 8.0 release series, but will not be available in the next major release. Percona encourages TokuDB users to explore the MyRocks Storage Engine which provides similar benefits for the majority of workloads and has better optimized support for modern hardware.

在 MySQL 上遇到 Replication Lag 的解法

看到 Percona 的 blog 上寫了一篇 MySQL 遇到 replication lag 時要怎麼解決:「MySQL High Availability: Stale Reads and How to Fix Them」,另外在留言也有人提到 Booking.com 的解法:「How Booking.com avoids and deals with replication lag」。

在業務成長到單台 MySQL server 不夠用的情況下,最簡單的擴充方式是架設 slave server,然後把應用程式裡讀取的部份導到 slave 上 (也就是 R/W split),但因為 MySQL 的 replication 是非同步的,所以有可能會發生在 master 寫入資料後 slave 還讀不到剛剛寫的資料,也就是 replication lag。

這就大概有幾種作法,一種是當發現 lag 時就回 master 讀,但通常這都會造成 master 過載... 所以另外一種改善的作法是發現 lag 時就換其他 slave 看看,但這個方法就不保證讀的到東西,因為有可能所有的 slave 都 lag。

以前遇到的時候是拆情境,預設還是 R/W split,但敏感性的資料處理以及金流相關的資料就全部都走 master。

不過文章裡的解法更一般性,在寫入時多寫一份資料,然後在 slave 等這組資料出現。唯一的缺點就是要 GC 把多寫的資料清掉...

同樣的想法,其實可以讓 MySQL 在 commit 時直接提供給 binlog 或 GTID 的資訊,然後在 slave 等待這組 binlog 或 GTID 被執行。

看起來算是很不錯的解法,不知道各家 framework 對這些方式的支援度如何...