Percona 開始搞 Telemetry (收集資料) 了,翻公告才發現已經一陣子了:「Percona Is Introducing Telemetry Mechanisms Into MySQL, PostgreSQL, and MongoDB」。
關掉的方法:
sudo systemctl disable --now percona-telemetry-agent
幹壞事是進步最大的原動力
Percona 開始搞 Telemetry (收集資料) 了,翻公告才發現已經一陣子了:「Percona Is Introducing Telemetry Mechanisms Into MySQL, PostgreSQL, and MongoDB」。
關掉的方法:
sudo systemctl disable --now percona-telemetry-agent
Percona 家的老大 Peter Zaitsev 寫了一篇紋章抱怨 Oracle 對 MySQL 的態度:「Is Oracle Finally Killing MySQL?」。
其實大家都有感覺,2009 年 Oracle 買下 Sun (當時擁有 MySQL 的公司) 後的前幾年還有些動作,後面整個就停住了,這也導致了市場上可以看到明顯的變化,不少人都開始關注並且使用 PostgreSQL:
隔壁 MariaDB 透過 SPAC 弄的灰頭土臉後縮編不少,自己弄的 engine 還是跟 InnoDB 有一段差距,功能上也沒有比較優秀的地方...
雲端降低管理成本也是一個讓 PostgreSQL 興起的推手,如果在地端的話,MySQL 的管理工具還是成熟不少 (畢竟就是時間累積出來的),但在雲端上面就接包的好好的了...
看到「Percona XtraDB Cluster 是 MySQL 的叢集與分散式解決方案」這篇,裡面提到了 Percona 包的 Galera Cluster,叫 Percona XtraDB Cluster。
Percona 算是把 Galera Cluster 包的比較好的 distribution,是還蠻建議直接用他們家的版本。另外我記得 MariaDB 也有包一個版本,叫做 MariaDB Galera Cluster。
這篇算是很早期使用 PXC 的人的一些感想:(大概是 2012 年導入,當年雲端也還沒流行,在地端上面自己建,對應的 MySQL 底層還是 5.5 的年代)
Percona XtraDB Cluster 建議至少三台
Galera Cluster 的三台可以是兩台有資料的,加上一台沒有資料,這台沒資料的只負責投票組成 quorum,不需要到三台都是大機器,而且這樣的配置也比較單純一點。
另外兩台雖然都可以當 writer 寫入,但實務上會建議都集中在一台寫,這樣可以大幅降低跨機器時產生的 lock contention。
基於上面這個因素,將兩台有資料的機器,一台做 writer,另外一台做 reader 算是常見的架構,然後把可以接受些許 replication lag 的應用 (像是什麼 BI 專用 DB server) 用傳統的 MySQL logical replication 掛出去 (標準的 master-slave 架構,或是後來政治改名為 source-replica 架構),不要直接參與 Galera Cluster 協定。
(MySQL 5.5 的時候還得自己處理當 master/source 切換時 replication binlog position 的問題,現在有 GUID 後會好一些)
除了 Galera Cluster 外,另外一種方式 (也是比較傳統的方式) 是 active-standby 的方式跑 DRBD:因為 DRBD 可以在兩台機器的 block 層做 mirror,所以切換的時候另外一台機器只要跑 journaling filesystem recovery (像是當年比較流行的 XFS 或是後來主力的 ext4) + InnoDB recovery 就可以跑起來。
DRBD 的老方法架構很單純,維護成本也很低,但缺點就是 recovery 的時間會高一些:在 crash 的 case 下可以做到十分鐘的 downtime 切換 (在傳統磁頭硬碟組成的 RAID),而 Galera Cluster 因為等於是 hot-standby,蠻容易就可以做到小於 30 秒。
另外在切換後 warmup 的時間上,Galera Cluster 也是因為 hot-standby 大勝:DRBD 這邊的情境等於是 cold start,資料庫內還有很多東西還沒進到 InnoDB buffer,對應的 SQL query 還不會快。
相比起來 Galera Cluster 看起來是個好東西,但後面運作的機制複雜不少 (而且需要有人維護),公司如果有專門的 DBOps 會比較好...
不過現在 SSD 變成主流的情況,讀取速度與 random access 的效率都快很多,這使得 DRBD 切換的成本低很多了,很有機會整個 downtime (切換 + warmup) 是五分鐘內搞定,如果這個時間是可以接受的,用 Galera Cluster 的優點可能就沒那麼高了...
剛剛翻資料才看到 Oracle 對 MySQL 5.7 的支援原來只剩下半年了,預定在 2023 年十月中止:「Oracle Technology Products - Oracle Lifetime Support Policy」。
隔壁棚 Percona 包的 Percona Server for MySQL 5.7 可以從「Percona Release Lifecycle Overview」這邊查,看起來也設定一樣的時間 (2023 年十月),但不確定會不會宣佈延長,至少提供 security fix 之類的。
一直沒注意,突然發現只剩下半年...
把一台本來跑在 Vultr 上的機器搬到 AWS 的 us-east-1
上面,除了剛好把 Ubuntu 18.04 換成 Ubuntu 22.04 外,也把本來用 x86-64 架構的機器換成用 ARM 的 t4g.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
搞定後後續就一路看錯誤訊息解就可以了...
在 Percona 的「MySQL/ZFS in the Cloud, Leveraging Ephemeral Storage」這篇裡面在探討是不是可以看看 ZFS 在 Ephemeral Storage (機器附的本地硬碟) 上的效能。
一開始測試是直接當主力硬碟來測,可以看到跑 ZFS 的情況下,本地的 storage 還是會比 SSD Premium (這是 Azure 的產品線) 還快不少:
但把資料放在本地的 storage 上其實有點刺激,至少在 production 應該不太會這樣搞,所以後面用 L2ARC 的方式來測,可以看到效率提昇相當明顯,甚至接近本來直接把資料放在本地的 storage:
這樣看起來是個不錯的選擇...
在 Backend Tw 的 https://www.facebook.com/groups/616369245163622/posts/2467225396744655/ 這邊看到:
先大概回答一下假設,DELETE 後的空間是可以被同一個表格重複使用的,所以應該是還好,不過離峰時間跑一下 OPTIMIZE TABLE
也沒什麼關係就是了。
裡面提到的「13.7.2.4 OPTIMIZE TABLE Statement」(MySQL 5.7 文件) 以及「13.7.2.4 OPTIMIZE TABLE Statement」(MySQL 5.6 文件) 都有講到目前比較新的版本都已經是 Online DDL 了:(這邊抓 5.6 的文件,有支援的版本資訊)
Prior to Mysql 5.6.17, OPTIMIZE TABLE does not use online DDL. Consequently, concurrent DML (INSERT, UPDATE, DELETE) is not permitted on a table while OPTIMIZE TABLE is running, and secondary indexes are not created as efficiently.
As of MySQL 5.6.17, OPTIMIZE TABLE uses online DDL for regular and partitioned InnoDB tables, which reduces downtime for concurrent DML operations. The table rebuild triggered by OPTIMIZE TABLE is completed in place. An exclusive table lock is only taken briefly during the prepare phase and the commit phase of the operation. During the prepare phase, metadata is updated and an intermediate table is created. During the commit phase, table metadata changes are committed.
文件上有提到會有一小段 lock 的時間,不過一般來說應該不會造成太大問題。
這邊要講的是早期的經典工具 pt-online-schema-change (pt-osc),這是使用 TRIGGER-based 的方式在跑,他的範例就直接提供了一個不需要 Online DDL 支援的版本:
Change sakila.actor to InnoDB, effectively performing OPTIMIZE TABLE in a non-blocking fashion because it is already an InnoDB table:
pt-online-schema-change --alter "ENGINE=InnoDB" D=sakila,t=actor
這在早期的時候還蠻常被拿出來用的,如果還在維護一些舊系統的話還蠻推薦的...
Percona 的「MySQL/ZFS Performance Update」這篇又對 ZFS 做了一次測試,算是用比較新的軟體跑出來的結果,不過要注意這邊的 ZFS 版本仍然不是目前最新版:
ZFS 0.8.6-1 is not bleeding edge, there have been more than 1700 commits since and after 0.8.6, the ZFS release number jumped to 2.0. The big addition included in the 2.0 release is native encryption.
機器是在雲端上 (Azure 上),不熟悉 Azure 的機種,但看記憶體與 CPU 的量好像不是用頂規的機器:
benchmark host
Standard D2ds_v4 instance
2 vCpu, 8GB of Ram and 75 GB of temporary storage
Debian BusterDatabase host
Standard E4-2ds-v4 instance
2 vCpu, 32GB of Ram and 150GB of temporary storage
256GB SSD Premium (SSD Premium LRS P15 – 1100 IOPS (3500 burst), 125 MB/s)
Debian Buster
Percona server 8.0.22-13
跑出來的結果看起來不差:
看了一下測試用的設定,似乎只測了 compression 的部份,沒測 snapshot 以及其他功能會對效能有什麼影響,但至少基本盤應該是還不錯?
在 Percona 的「How To Recover Percona XtraDB Cluster 5.7 Node Without SST」這邊看到的技巧,不過只能用在 5.7 版,不能用在 8.0 版。我猜這個方法也可以用在其他跑 Galera Cluster 的資料庫上...
維護一組 Percona XtraDB Cluster 時一個常見的問題是,當節點離線太久後有機會無法用 IST (Incremental State Transfer) 跟回來,也就是只要把先前還沒有同步的部份更新進資料庫的方法,這時候就會需要用 SST (State Snapshot Transfer),變成抓整個 full copy。
作者提出來的方法是基於 IST 的大小通常比較小,但 binlog 通常都留蠻久的,所以可以利用 binlog 來幫 IST。
方法是先把 Galara Cluster 關掉,用 MySQL 傳統的 replication 同步到一定程度後,再把 IST 相關的位置設定指到已經同步的位置,接著再把 Galara Cluster 接上去就可以恢復了。
這個方法是 5.7 版限定,因為 8.0 的年代沒辦法改 Galara Cluster 的 wsrep 位置資訊:
Unfortunately, a similar solution does not work with Percona XtraDB Cluster 8.0.x, due to the modified way wsrep positions are kept in the storage engine, hence the trick with updating grastate.dat does not work as expected there.
我覺得可能 Percona 之後會弄出 patch 讓使用者可以改...