Percona 對 MongoDB 的建議

看到「5 Things DBAs Should Know Before Deploying MongoDB」這篇,裡面給了五個建議,其中第五點頗有趣:

5) Whenever Possible, Working Set < RAM

As with any database, fitting your data into RAM will allow for faster reads than from disk. MongoDB is no different. Knowing how much data MongoDB has to read in for your queries can help you determine how much RAM you should allocate to your database.

這樣的設計邏輯很奇怪啊,你不要扯其他 database 啊,你們家主力的 InnoDB 一直都沒有推薦要 Working Set < RAM 啊,反過來才是用 InnoDB 的常態吧,而且在 PostgreSQL 上也是這樣吧 XDDD

現在上面的文章真的是挑著看了... XD

RDS 推出 ARM 版本

Amazon RDS 推出了 ARM 的版本:「New – Amazon RDS on Graviton2 Processors」,包含了 MySQLMariaDBPostgreSQL 的版本都有支援,不過看起來需要比較新版的才能用:

You can choose between M6g and R6g instance families and three database engines (MySQL 8.0.17 and higher, MariaDB 10.4.13 and higher, and PostgreSQL 12.3 and higher).

官方宣稱可以提供 35% 的效能提昇,考慮費用的部份會有 52% 的 c/p 值提昇:

Graviton2 instances provide up to 35% performance improvement and up to 52% price-performance improvement for RDS open source databases, based on internal testing of workloads with varying characteristics of compute and memory requirements.

對於 RDS 這種純粹就是個服務的應用來說,感覺應該不會有什麼轉移成本,只要測過沒問題,換過去等於就是現賺的。看起來等 RI 約滿了就可以切...

EnterpriseDB 買下 2ndQuadrant

算是 PostgreSQL 社群裡面的大事情,看到大老在討論 EnterpriseDB (EDB) 買下 2ndQuadrant 的事情:「Community Impact of 2nd Quadrant Purchase」,這兩家公司都是 PostgreSQL 社群裡面重量級的台柱。

先翻了一下新聞稿,兩邊的官方新聞稿分別是「How EDB Became the Leader in the Postgres Market」與「How EDB Became the Leader in the Postgres Market」。

回到原來的文章,裡面提到了 core team 的不成文規定,這個部份可以從 Contributor Profiles 這邊看到目前 core team 有五位成員,Peter Eisentraut 來自 2ndQuadrant,而 Bruce Momjian (這是文章作者自己) 與 Dave Page 則是來自 EnterpriseDB:

First, there is an unwritten rule that the Postgres core team should not have over half of its members from a single company, and the acquisition causes edb's representation in the core team to be 60% — the core team is working on a solution for this.

裡面有提到目前正在找辦法解決中,但不知道目前會怎麼解決,讓出位置可能是一個方法,加到七個人應該也是個方法,反正方法不算少,就等著看...

另外他提出來的兩個問題我覺得都還好,就是併購本來就會發生的事情。

這次的併購算是 PostgreSQL 社群裡面蠻熱鬧的事情,雖然是商業公司之間的併購,但社群這邊應該也會有不少變化...

MySQL 的 TIME 範圍

這篇算是考古文,找出 MySQLTIME 資料型態奇怪範圍的由來:「TIME for a WTF MySQL moment」。

在官方的文件裡面可以看到 TIME 的範圍是個奇怪的數字,如果把各版本的文件都拉出來看,會發現都沒改過:「11.2.3 The TIME Type (8.0)」、「11.2.3 The TIME Type (5.7)」、「11.2.3 The TIME Type (5.6)」,「11.3.2 The TIME Type (5.5,靠 Internet Archive 的存檔頁面)」、「11.3.2 The TIME Type (5.1,靠 Internet Archive 的存檔頁面)」、「11.3.2 The TIME Type (5.0,靠 Internet Archive 的存檔頁面)」,裡面一直都是:

TIME values may range from '-838:59:59' to '838:59:59'.

這個數字看起來應該是某個限制,但作者粗粗算了幾種可能都不像,所以就一路考古,發現算是在 MySQL 3 年代因為某個特別公式留下來的遺毒,就一路用到現在了:

One of the bits was used for the sign as well, but the remaining 23 bits were an integer value produced like this: Hours × 10000 + Minutes × 100 + Seconds; in other words, the two least significant decimal digits of the number contained the seconds, the next two contained the minutes, and the remaining ones contained the hours. 223 is 83888608, i.e. 838:86:08, therefore, the maximum valid time in this format is 838:59:59.

話說回來,用 MySQL 的人還是很習慣用 INTBIGINT 來存時間,這樣可以自動遠離這些鳥問題,之前在「MySQL 裡儲存時間的方式...」與「Facebook 在 MySQL 裡存時間的型態」這邊都寫過...

不過最近用 PostgreSQL 比較多,可以比較「正常」的使用各種資料型態...

PostgreSQL 13 的 B-Tree Deduplication

Hacker News 上看到「Lessons Learned from Running Postgres 13: Better Performance, Monitoring & More」這篇文章,其中有提到 PostgreSQL 13 因為 B-Tree 支援 deduplication,所以有機會縮小不少空間。

搜了一下源頭是「Add deduplication to nbtree.」這個 git commit,而 PostgreSQL 官方的說明則是在「63.4.2. Deduplication」這邊可以看到。

另外值得一提的是,這個功能在 CREATE INDEX 這頁可以看到在 PostgreSQL 13 預設會打開使用。

依照說明,看起來本來的機制是當 B-Tree index 內的 key 相同時,像是 key1 = key2 = key3 這樣,他會存 {key1, ptr1}{key2, ptr2}{key3, ptr3}

在新的架構下開啟 deduplication 後就會變成類似 {key1, [ptr1, ptr2, ptr3]} 這樣的結構。可以看出來在 key 重複的資料很多的時候,可以省下大量空間 (以術語來說的話,就是 cardinality 偏低的時候)。

這樣看起來可以降低不少壓力...

DuckDB

看到篇有趣的介紹,在講 DuckDB:「DuckDB」。

[I]t uses the PostgreSQL parser but models itself after SQLite in that databases are a single file and the code is designed for use as an embedded library, distributed in a single amalgamation C++ file (SQLite uses a C amalgamation).

看起來是個以 OLAP 為中心而設計出來的資料庫,然後在 Python 下可以直接透過 pip 裝起來。

看起來像是個用單機拼 throughput 的東西,但提供大家熟悉的界面。

Hacker News 上可以看到「DuckDB – An embeddable SQL database like SQLite, but supports Postgres features (duckdb.org)」這邊給了不少方向,

對 Amazon Aurora (MySQL-Compatible Edition) 另外建 Replica

Percona 的人寫了一篇怎麼對 Amazon Aurora (MySQL-Compatible Edition) 生 replica 的文章:「Creating an External Replica of AWS Aurora MySQL with Mydumper」。

這邊用的方法主要是出自「Replication with Amazon Aurora」這篇,裡面有提到有 binlog 可以用,所以 Percona 的作法應該是屬於「雖然不能 100% 保證以後還是可以用,但 99% 的機會以後應該還是可以用」。

這樣搞主要應該是用在 1) 省錢,2) 需要特殊的調整;如果不是這兩種,一般會選 Aurora 版本,應該不會太在意成本,直接用他提供的 read replica 就好?

MyRocks/MariaDB 的 tuning 過程

看起來應該是找 Percona 的人幫忙轉移到 MyRocks 上,然後整理出來的成功案例:「The Road Story of a MyRocks/MariaDB Migration」。

看起來是跑在獨立機器上,而不是雲端的虛擬機上,所以不是想 scale up 就可以把硬體規格拉上去 (說不定記憶體插槽已經滿了之類的...):

Replicas run on bare metal servers, usually Dual Xeon E5 v3 or v4, with 192 GB to 384 GB of RAM.

這次遇到的主要的問題是發現效能跟不上。另外在文章裡面沒寫到,但可以猜到的是,他們目前不打算改架構,而是想要藉由改善資料庫的效能來解決問題:

The servers were close to their limits and were slow to catch up with replication after a maintenance period

後面可以看到不少過程,主要是重新編一份 MariaDB,讓 MyRocks 支援 Zstandard (MyRocks 支援 Zstandard,不過 MariaDB 內的 MyRocks 不知道為什麼關掉了...),這點大幅降低了空間的佔用。

另外是遇到 OOM 問題,在改用 jemalloc 解決記憶體用量的問題後就解決了 (這個在使用 InnoDB 的時候也算是標配了)。

不過在「Increased Read Load Over Time」那段還是看到了 workaround:

The read load was still rising a bit but at a much smaller pace. Instead of hours, it was days. That’s kind of expected given the workload and we were already planning for periodic manual compactions.

目前看起來 MyRocks 的強項主要是在省資源,但缺點就是有不少眉眉角角得小心處理。這樣的話,一般應該還是會先用 InnoDB,真的搞大了再考慮要不要換過去...

MariaDB 的 S3 Engine 效能測試

PerconaMariaDB 在 10.5 (目前的最新穩定版) 裡出的 S3 Engine 給出了簡單的測試報告:「MariaDB S3 Engine: Implementation and Benchmarking」。

這個 engine 顧名思義就是把資料丟到 Amazon S3 上,目前是 alpha 版本,預設是不會載入的,需要開 alpha flag 才能用:

The S3 engine is READ_ONLY so you can’t perform any write operations ( INSERT/UPDATE/DELETE ), but you can change the table structure.

另外這是從 Aria 改出來的 read-only engine,而 Aria 是從 MyISAM 改出來的:

The S3 storage engine is based on the Aria code and the main feature is that you can directly move your table from a local device to S3 using ALTER.

測出來發現在 read-only 的情境下,COUNT(*) 超快,看起來就是跟 MyISAM 體系有關,直接撈 MyISAM 內的資料,所以本地要 18 秒,但放到 S3 反而秒殺 XDDD

整體看起來還不錯?算是一種 Data warehouse 的方案,主要是要用到 row-based format 儲存的優點,遇到一些冷資料可以這樣玩。

從「Using the S3 Storage Engine」這邊的設定方式看到 s3_host_name,看起來有機會接其他家的 S3 API,或是本地的 Storage。

話說 Aria 這個引擎當初最主要的重點就在 crash-safe,在有了 crash-safe 之後,DRBD 這種 block-level replication 機制就可以硬幹上去,後來主力就在擴充其他型態了,像是 GIS 與 virtual column 的功能,不過這些功能本家在 InnoDB 上好像也都陸陸續續跟上來了,單純的 Aria engine 好像還好...

PostgreSQL 的 SERIALIZABLE 的 bug

這是 Jespen 第一次測試 PostgreSQL,就順利找出可重製的 bug 了:「PostgreSQL 12.3」。

第一個 bug 是 REPEATABLE READ 下的問題,不過因為 SQL-92 定義不夠嚴謹的關係,其實算不算是 bug 有討論的空間,這點作者 Kyle Kingsbury 在文章裡也有提出來:

Whether PostgreSQL’s repeatable-read behavior is correct therefore depends on one’s interpretation of the standard. It is surprising that a database based on snapshot isolation would reject the strict interpretation chosen by the seminal paper on SI, but on reflection, the behavior is defensible.

另外一個就比較沒問題了,是 SERIALIZABLE 下的 bug,在 SQL-92 下對 SERIALIZABLE 的定義是這樣:

The execution of concurrent SQL-transactions at isolation level SERIALIZABLE is guaranteed to be serializable. A serializable execution is defined to be an execution of the operations of concurrently executing SQL-transactions that produces the same effect as some serial execution of those same SQL-transactions. A serial execution is one in which each SQL-transaction executes to completion before the next SQL-transaction begins.

也就是說,在 SERIALIZABLE 下一堆 transaction 的執行結果,你至少可以找到一組排序,使得這些 transaction 的結果是等價的。

而 Jespen 順利找出了一組 transaction (兩個 transaction),在 SERIALIZABLE 下都成功 (但不應該成功):

對於這兩個 transaction,不論是上面這條先執行,還是下面這條先執行,都不存在等價的結果,所以不符合 SERIALIZABLE 的要求。

另外也找到一個包括三個 transaction 的情況:

把 transaction 依照執行的結果把 dependency 拉出來,就可以看出來裡面產生了 loop,代表不可能在 SERIALIZABLE 下三個都成功。

在 Jespen 找到這些 bug 後,PostgreSQL 方面也找到軟體內產生 bug 的部份,並且修正了:「Avoid update conflict out serialization anomalies.」,看起來是在 PostgreSQL 引入 Serializable Snapshot Isolation (SSI) 的時候就有這個 bug,所以 9.1 以後的版本都有這個問題...

這次順利打下來,測得很漂亮啊... 翻了一下 Jespen 上的記錄,發現好像還沒測過 MySQL,應該會是後續的目標?