目前大家討論的是 MySQL InnoDB & PostgreSQL,但 MySQL 還有一個很大的特色:可熱抽換的引擎。MogoDB 3.0 也引用了這項優點。
如果覺得 InnoDB engine 不好,可以換成別的 engine,甚至 MySQL 可以讓某些 engines 彼此 replication 混用。
前者,可以因應業務場景的改變抽換 engine,例如 OLTP 換成 OLAP 再換成 Warehouse 時,一行指令就可以搞定其對應的適用 engine。
後者,讓 DBA 可以用多個 engines 應付不同的業務,同時維運管理仍可視為同一集群而降低成本及風險。
PostgreSQL 只有一種 engine,不可抽換,這會限制它可適用的範圍。未來 PostgreSQL 有沒有可能引入可熱抽換 eninge?也許有可能,但至今沒看到相關計畫,而且 PostgreSQL 太多底層都跟現行的 eninge 相依太高,要改變實屬不易。
pt-online-schema-change 是過渡期工具,主要供 MySQL 5.6 之前版本。它的執行原理非常暴力, copy table + trigger,所以沒有 locking。
到了 MySQL 5.6 之後,因為支援 Online DDL (MySQL 5.7 支援更全面),很多 ALTER TABLE 都不再 locking,可以在生產線上直接運行,只是免不了效能的抖動。因為 MySQL 資料結構與 PostgreSQL 不同,所以 schema change 再怎麼做還是不會比 PostgreSQL 來得有效率。
對我來說,PostgreSQL 最大的問題在於沒有很成熟的 master-master 及跨數據中心的同步方案。master-master 有它先天的問題。可是 master-slave 有 SPOF 及 single write hotspot 問題,前者可用 HA 解,但後者無解。
跨數據中心又是另一個麻煩事,如果不支援就要自己搞 Sharding,不是做不到。而且 Sharding 很難維護又很可能一不小心就破壞商業邏輯。就算要搞 Sharding,MySQL 還是有比 PostgreSQL 相對成熟的方案,就是官方的 Fabric,夠傻瓜夠直覺夠彈性。
從 Enterprise requirement 可以看出 PostgreSQL 與 MySQL 發展思路上的差異,如果是走穩定、數據保證,目前 PostgreSQL 絕對會是首選 (但 MySQL 5.7 追上來了);如果是走網路服務的高延展性、跨數據中心,那目前就是 MySQL 的天下了。
因為 PostgreSQL 與 MySQL 理念哲學不同。
PostgreSQL 認為 OS file caching 已經做得很好了,所以很多 cache 都是在 OS level;反之 MySQL 認為什麼都自己管效率才高,因此什麼東西都放在自己的 cache。
以致於,
PostgreSQL 較 MySQL 更依賴作業系統及其檔案系統,稍有不同效能就會有差 (例如 Linux kernel 或 FS 的選用就會有不一樣的差異);而 MySQL 比較沒有這個問題。這也導致 PostgreSQL 社群會特別關注 Linux kernel 每個版本所帶來的影響,但 Linux kernel 也不可能為了 PostgreSQL 就調整什麼,畢竟 Linux kernel 不是只給 PostgreSQL 執行。
PostgreSQL shared buffer 不能設定太高,因為要保留給 OS file caching;反之,MySQL 因為都自己管,所以要設定得很高。放在同一個 pool 有一個好處,就是資源共享,反之 PostgreSQL 的 shared buffer 不管太高或太低都沒有辦法跨出這個設定值去用預留太多或太少的 OS file caching。另外,這也造成 MySQL 在單機多實例的運用下較有優勢 (如果有需要的話)。
以上,是我在簡報沒講的 Part 2 內容之一。
( 這裡好酷呀,首波 )
我只是覺得作者 "用 PostgreSQL 的優勢直接對等套用在 MySQL 上,而不考慮 MySQL 特性做修正,然後再說 MySQL 很差",以藉此推廣 PostgreSQL 比較好的方式很不妥,所以寫了這篇簡報。
PostgreSQL 寫入時,單位是 block,然後會與 page 對齊,所以如果 PK 不是順序寫,那表示會落在很多個不同的 pages,如此在 checkpoint 時雖然是順序寫入,但若順著 PK scan 讀出時,就會變成 random read。但後者對 SSD 效能其實影響不大,只是剛好跟 MySQL 建議的方式有點不同。
使用 UUID 是要看情況,因為 MySQL 的 AUTO_INCREMENT 及 PostgreSQL Sequence 本身依賴的就是 locking,所以若要避用的話,PostgreSQL 天生有優勢,但 MySQL 則要小心不要用到 Random UUID (例如 UUIDv4),否則效能如你所言會差很多。而 MySQL 要用 INT 還是 UUIDv1 就看個人了,因為 UUID 是標準資料交換時通用的 KEY。
VACUUM 其實就跟程式語言的 GC 一樣,讓人又愛又恨,一旦累積太多,GC 時就要一點有心理準備,抖動會比平常大一些。MongoDB 及 Cassandra 在發生 GC 時,也一樣很令人頭痛。AUTO VACUUM 其實最大的重點就是,依據內部的偵測機制,讓 PostgreSQL 自行決定什麼時候 VACUUM 最好;再者,PostgreSQL 官方也說了,若是定期 VACUUM,要小心累積太多的 dead tuples,而導致碎片嚴重到 VACUUM 修不好,最終只能 VACUUM FULL 而導致 table lock。
我兩個資料庫都用,確實要看應用而選。不然以 PostgreSQL 狂派傳教士而言,好似用 MySQL 的 Google / Facebook / 阿里巴巴都是笨蛋一樣。