GitLab 12.1 之後放棄支援 MySQL

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

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

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

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 避免這類問題),開發者需要了解的資料庫限制...

RDS 支援 Storage Auto Scaling

Amazon RDS 推出了 Storage Auto Scaling:「Amazon RDS now supports Storage Auto Scaling」。

看起來傳統 RDBMS 類的都支援 (也就是非 Aurora 的這些):

Starting today, Amazon RDS for MariaDB, Amazon RDS for MySQL, Amazon RDS for PostgreSQL, Amazon RDS for SQL Server and Amazon RDS for Oracle support RDS Storage Auto Scaling.

仔細看了一下新聞稿,裡面都只有提到 scale up,沒有提到 scale down,這個功能應該是只會提昇不會下降,所以要注意突然用很多空間,再砍掉後的問題:

RDS Storage Auto Scaling automatically scales storage capacity in response to growing database workloads, with zero downtime.

RDS Storage Auto Scaling continuously monitors actual storage consumption, and scales capacity up automatically when actual utilization approaches provisioned storage capacity.

除了香港外的所有商業區域都提供:

RDS Storage Auto Scaling is available in all commercial AWS regions except in Asia Pacific (Hong Kong) and AWS GovCloud.

PostgreSQL 的 Bloom index

前幾天才跟人提到 PostgreSQL 的功能與完整性比 MySQL 多不少,剛剛又看到 Percona 的「Bloom Indexes in PostgreSQL」這篇,裡面提到了 PostgreSQL 可以使用 Bloom filter 當作 index。

查了一下資料是從 PostgreSQL 9.6 支援的 (參考「PostgreSQL: Documentation: 9.6: bloom」這邊的說明),不過說明裡面沒看到 DELETE (以及 UPDATE) 會怎麼處理,因為原版的 Bloom filter 資料結構應該沒有能力處理刪除的情況...

另外這幾年比較有名的應該是 Cuckoo filter,不只支援刪除,而且空間與效能都比 Bloom filter 好,不知道為什麼是實做 Bloom filter...

在 SQL 裡面避免大量刪除資料的方式

看到 Percona 的「An Overview of Sharding in PostgreSQL and How it Relates to MongoDB’s」這篇,雖然是在講 PostgreSQL 上的 sharding (以及 partition),突然想到好像沒寫過要怎麼避免大量刪除資料的操作...

一個常見的情境是,想要讓某個表格只保留這一個月的資料,所以每個月開頭都會跑一隻 cron job 負責刪掉上個月的資料,像是 DELETE FROM xxx WHERE timestamp < yyy; 這樣的指令。

這個方式無論是在 PostgreSQL 或是 MySQL 都需要很多時間與 I/O 資源,而透過 partition 將不同時間區段切開到不同的表格,再用 TRUNCATE 直接清空表格剛好可以解這樣的問題。

Percona 的文章裡說了一些 PostgreSQL 的歷史與目前的進展。

在 PostgreSQL 9 或更早以前的版本,一個常見的作法是透過 table inheritance 實做 partition,然後用再用 function 實做 INSERT

CREATE TABLE temperature (
  id BIGSERIAL PRIMARY KEY NOT NULL,
  city_id INT NOT NULL,
  timestamp TIMESTAMP NOT NULL,
  temp DECIMAL(5,2) NOT NULL
);

CREATE TABLE temperature_201901 (CHECK (timestamp >= DATE '2019-01-01' AND timestamp <= DATE '2019-01-31')) INHERITS (temperature);
CREATE TABLE temperature_201902 (CHECK (timestamp >= DATE '2019-02-01' AND timestamp <= DATE '2019-02-28')) INHERITS (temperature);
CREATE TABLE temperature_201903 (CHECK (timestamp >= DATE '2019-03-01' AND timestamp <= DATE '2019-03-31')) INHERITS (temperature);

CREATE OR REPLACE FUNCTION temperature_insert_trigger()
RETURNS TRIGGER AS $$
BEGIN
    IF ( NEW.timestamp >= DATE '2019-01-01' AND NEW.timestamp <= DATE '2019-01-31' ) THEN INSERT INTO temperature_201901 VALUES (NEW.*);
    ELSIF ( NEW.timestamp >= DATE '2019-02-01' AND NEW.timestamp <= DATE '2019-02-28' ) THEN INSERT INTO temperature_201902 VALUES (NEW.*);
    ELSIF ( NEW.timestamp >= DATE '2019-03-01' AND NEW.timestamp <= DATE '2019-03-31' ) THEN INSERT INTO temperature_201903 VALUES (NEW.*);
    ELSE RAISE EXCEPTION 'Date out of range!';
    END IF;
    RETURN NULL;
END;
$$
LANGUAGE plpgsql;

在 PostgreSQL 10 之後,就直接支援一些與 partition 相關的設計,像是這樣:

CREATE TABLE temperature (
  id BIGSERIAL NOT NULL,
  city_id INT NOT NULL,
  timestamp TIMESTAMP NOT NULL,
  temp DECIMAL(5,2) NOT NULL
) PARTITION BY RANGE (timestamp);

CREATE TABLE temperature_201901 PARTITION OF temperature FOR VALUES FROM ('2019-01-01') TO ('2019-02-01');
CREATE TABLE temperature_201902 PARTITION OF temperature FOR VALUES FROM ('2019-02-01') TO ('2019-03-01');
CREATE TABLE temperature_201903 PARTITION OF temperature FOR VALUES FROM ('2019-03-01') TO ('2019-04-01');

雖然還是有些限制,但可以看出比起以前簡單不少。

而有了 partition 後,文章的後續就在討論這跟 MongoDB 的 sharding 有什麼關係,但這就不是我關注的事情了...

CockroachDB 也拋棄 Open Source License 了

CockroachDB 的主力在於 PostgreSQL 的相容層 (包括底層資料結構,SQL 語法,以及 Protocol,所以原有的 client 不需要太多修改就可以用),並且提供橫向擴充的能力 (實作類似於 F1 與 Spanner 這些論文的功能)。

現在他們也宣佈拋棄 Open Source License 了,從本來的 Apache License 2.0 轉為他們自己定義的 Business Source License:「Why We’re Relicensing CockroachDB」。

最大的差異就是擋提供服務:

The one and only thing that you cannot do is offer a commercial version of CockroachDB as a service without buying a license.

商業版本最終會以 open source license 釋出,但會有三年延遲 (以現在的社群速度,基本上就等於不提供了),不算太意外,但這樣的話也需要先從可用的列表上移除了...

PostgreSQL 的 Don't Do This

Hacker News Daily 上看到的資料,整理了 PostgreSQL 上不要使用的功能:「Don't Do This」,而且是放在官方網域 wiki.postgresql.org 上。

裡面這些想法不知道出處是哪邊... 有不少功能算是 PostgreSQL 特有的功能 (以 open source RDBMS 這個領域來看),而且大概也還想的到用的場景,你卻在上面叫大家不要用,再寫的時候大概是吸了一批很純的,已經不知道要從哪邊開始吐槽...

要看的話連同 Hacker News 上的留言一起看會比較有前因後果:「https://news.ycombinator.com/item?id=19817531」。

PostgreSQL 裡的 B-tree 結構

在「Indexes in PostgreSQL — 4 (Btree)」這邊看到講 PostgreSQLB-tree 結構以及常見的查詢會怎麼使用 B-tree。

裡面講了三種查詢,第一種是等號的查詢 (Search by equality),第二種是不等號的查詢 (Search by inequality),第三種是範圍的查詢 (Search by range)。再後面講到排序與 index 的用法。

雖然是分析 PostgreSQL,但裡面是一般性的概念,其他使用 B-tree 結構的資料庫也是類似作法...

Amazon Aurora with PostgreSQL 支援 Logical Replication

AWS 先前宣佈 Amazon Aurora (MySQL) 支援 GTID Replication (參考「Amazon Aurora with MySQL 5.7 支援 GTID」),現在則是宣佈 Amazon Aurora with PostgreSQL 支援 Logical Replication:「Amazon Aurora with PostgreSQL Compatibility Supports Logical Replication」。

如同預期的,要新版的才支援:

Logical replication is supported with Aurora PostgreSQL versions 2.2.0 and 2.2.1, compatible with PostgreSQL 10.6.

有 Logical Replication 可以多做很多事情,像是雲端與外部 PostgreSQL 服務的串接 (e.g. 即時拉一份到 IDC 機房)。另外有些 ETL 工具也可以透過這個方式取得資料庫上改變了什麼東西。

Amazon Aurora with MySQL 5.7 支援 GTID

雖然在 AWS 上服務的 HA 大多都不需要自己管理,但備份機制 (甚至異地備援) 還是要自己規劃,Amazon Aurora with MySQL 的 GTID 功能算是讓這塊多了一個選擇:「Amazon Aurora with MySQL 5.7 Compatibility Supports GTID-Based Replication」。

公告裡面有提到 Aurora 自己的 replication 還是用自己的機制,而非透過 GTID 做的:

This provides complete consistency when using binlog replication between an Aurora database and an external MySQL database. Your replication won’t miss transactions or generate conflicts, even after failover or downtime. (Note that replication within an Aurora cluster doesn't use binlog files, so the GTID feature doesn't apply.)

不過就 Aurora 的架構來說,整個 cluster 比較像是看作一個整體,用 binlog + position 應該是夠用的?也不會有 failover 時的 conflict 問題?不確定用 GTID 的好處會在哪邊,還得再想看看...