Upgrade to Pro — share decks privately, control downloads, hide ads and more …

淺入淺出 MySQL & PostgreSQL

淺入淺出 MySQL & PostgreSQL

Understanding MySQL & PostgreSQL

Yi-Feng Tzeng

April 08, 2015
Tweet

More Decks by Yi-Feng Tzeng

Other Decks in Technology

Transcript

  1. 2015 2/147 請先閱讀 Triton Ho 的教材 ♪ Triton Ho( 以下稱作者

    ) 的教材。 https://drive.google.com/file/d/0Bw4cH_iKZJzKOE5YRWtZS3lyTkk/view https://drive.google.com/file/d/0Bw4cH_iKZJzKLXFIWVFfMk13Vm8/view https://drive.google.com/file/d/0Bw4cH_iKZJzKd25qdV9HTEp4VVk/view ♪ 作者簡報中有值得參考的內容。 ♪ 目的不是為了批評,而是討論。 ♪ 本討論將探討其中幾個論點。
  2. 2015 8/147 前言 ♪ 我不是 MySQL / PostgreSQL 推廣者,只看重誰能解決問題。 ♪

    非專業 DBA ,只是個架構實習生。 ♪ 無漫罵,不認為 MSSQL 、 MySQL 或 PostgreSQL 是垃圾。 ♪ 每個軟體都有優缺點,依實際場景選擇不同的需求。
  3. 2015 9/147 前言 ♪ 作者簡報主在抨擊 MySQL ,也較少提 PostgreSQL 缺點。 ♪

    為平衡報導,我著重該簡報的錯誤及 PostgreSQL 缺點補充。
  4. 12/147 2015 淺談 SSD Random IO ? Sequential IO ?

    但我想談的是背後更深的原因。 『為什麼 MySQL 及 MSSQL 盡力追求 Sequential IO ?』 『 Sequential IO 在 SSD 的世界中真的無所謂?』
  5. 13/147 2015 淺談 SSD 很多人都會說 SSD 的 Sequential IO 不重要,但真的不重要?

    雖然 MySQL 相較 PostgreSQL 實際只用到不算明顯的優勢。 本篇的內容側重在 Ordered INSERT 生成的 Reorder 及 Merge ,這是後續會提到的。
  6. 14/147 2015 淺談 SSD 經工具實測與廠商 Spec ,顯示 SSD Random IO

    的速度不如 Sequential IO 。 Ref: http://en.wikipedia.org/wiki/IOPS
  7. 15/147 2015 淺談 SSD Ref: https://www.facebook.com/note.php?note_id=350857798258600 Read (500.8-289.8)/500.8 = 42%

    非循序讀取耗損 42% 速度 Write (371.3-282.4)/371.3 = 24% 非循序寫入耗損 24% 速度
  8. 23/147 2015 淺談 SSD Ref: http://www.enterprisetech.com/2014/04/03/fusion-io-tweaks-flash-speed-mysql-databases/ Atomic Writes / NVM

    Compression 在 MySQL 5.7.4 引入; 這兩個特性也已在 Percona 5.6 及 MariaDB 10 引入。
  9. 24/147 2015 淺談 SSD Ref: http://www.fusionio.com/solutions/ Fusion IO 不知為何沒有針對 PostgreSQL

    的特性最佳化。 1. 單純沒做,還是; 2. Flash controller 的技術無法針對 PostgreSQL 的行為調整,還是; 3. PostgreSQL 已經夠好不用最佳化?
  10. 25/147 2015 淺談 SSD 《我的解釋》 重點是 Fusion IO 很可能使得常見資料庫的瓶頸由 IO

    bound 轉變為 CPU bound 。 如果變成 CPU bound ,後續談的 Hotspot 的影響將有效降低。
  11. 28/147 2015 OLTP: Fragmentation 《我的解釋》 因為 INSERT 循序 ( 規律

    ) ,所以 Hotspot 會發生在 last node ( 頻繁地在 last node 寫入 ) ;但若不循序,則容易造成 Storage / Memory Fragmentation ,也就是若資料增刪改是不循序的, 則空間配置也會是不循序的。 Ref: https://www.facebook.com/yftzeng.tw/posts/10202227746654516
  12. 33/147 2015 OLTP: Fragmentation 《我的解釋》 MySQL InnoDB Index 會保持 (

    邏輯 ) 循序 (Ordered) 。 InnoDB Primary Key 也包括一些 data ,所以找到 Key 也同時 取得這些 data 。
  13. 37/147 2015 OLTP: Fragmentation 《我的解釋》 INSERT 循序時,會頻繁在同一 page 操作 (

    維持 Sequential , 但有 Hotspot 問題 ) 。 MySQL 預設會延遲寫入 Storage ,並將 連續異動的 pages 一次寫入,甚至將請求合併,從而有效降低 Random write 的次數以及合併部分 Random write 變成 Sequential write 。 但若使用 Random UUID 時,寫的不一定是同一 page ,所以即 使延遲寫入 Storage ,也會產生很多次 Random write 。 Ref: http://www.tocker.ca/2013/05/06/when-does-mysql-perform-io.html
  14. 39/147 2015 OLTP: Fragmentation Ref: http://www.percona.com/files/presentations/percona-live/london-2011/PLUK2011-linux-and-hw-optimizations-for-mysql.pdf (p17) MySQL Insert Buffering

    : 1. Reducing the number of disk i/o operations by merging i/o requests to the same block. 2. Some random i/o operations can be sequential.
  15. 40/147 2015 OLTP: Fragmentation 《我的解釋》 SELECT 時,若在 Memory 中, MySQL

    會保持 ( 邏輯 )Ordered 。 但 PostgreSQL 不是,而且再加上它的 MVCC 設計, UPDATE/ DELETE 遺留下的 dead rows 會使得 Fragmentation 更嚴重。 若 SELECT 是從 Storage 取出時,因 MySQL 連續異動的 pages 一次寫入,甚至將請求合併,所以相近的資料放在同一 block 的 機率較高。且將 Storage 讀出放入 Memory 時, MySQL 仍會保 持 ( 邏輯 )Ordered 。
  16. 43/147 2015 OLTP: Fragmentation 《我的解釋》 EXT4 不用 defrag ,不代表它沒有 fragmentation

    。再者, EXT4 上看到的 fragmentation ,也不是 SSD 上實際的 fragmentation 。 Ref: https://www.facebook.com/groups/199493136812961/permalink/729886527106950/
  17. 45/147 2015 OLTP: Fragmentation 我同意「 OLTP 在現實是中是自然存在的」,其實不管是 OLTP / OLAP

    都一樣。我從來沒有否定這點。 我指的也不是 『難道 [email protected] 登入系統了,然後便會是 [email protected](p 比 o 後)會登入系統嗎?』 不過,即使真的 .ho 登入後是 .hp 登入也一定是 Random IO 。 因為這是兩個不同的 SELECT Query 。同一個 Query 下才有 可能是 Sequential IO 。 Sequential IO 需例如一次寫入一批資料,而這些資料寫入的 block 是順序的。 Random IO 則是分別寫入不同的 block 。
  18. 46/147 2015 OLTP: Fragmentation Ref: https://www.facebook.com/groups/199493136812961/permalink/729886527106950/?comment_id=730137420415194 我講的是 OLAP ,他講的是 OLTP

    。所以在 OLAP 應用上, 我的論點沒錯;而在 OLTP 的應用上,他的論點也沒錯。 可是我們還是要考量實際需求是什麼。他認為 OLTP 在一般 SELECT 是很小量的 record ,所以 fragmentation 沒有影響。 注意他說的是『小量的 record 』,但舉個例子, 資料關聯 的數值統計是小量嗎?例如,用戶的朋友總數 / 用戶 LIKE 過的文章 / 文章的留言回應數等,這些都是分散在大表不同 的 record ,會產生很多的 random I/O ,這對 PostgreSQL 影響比較大。這功能一般網站不常用? 其實光是 JOIN 就可能產生一堆 random I/O 了。
  19. 49/147 2015 OLTP: Fragmentation 《我的解釋》 如果 SSD 的 Sequential IO

    真的不重要,為什麼有些新的引擎 設計卻偏要追求 Sequential IO ? TokuDB RethinkDB Cassandra Aerospike WiredTiger (MongoDB) 這點值得我們思考。
  20. 52/147 2015 Hotspot 這部分我的結論是,反正 Disk IOPS 會愈來愈快 ( 作者也同意 )

    , Hotspot 的影響程度也會愈來愈低。雖然 Fragmentation 的問題也 隨 IOPS 增加而減輕,但是只要 SSD 的「非循序讀寫」與「循序 讀寫」差距仍然高達至少四分之一時,通常應該傾向選擇 Hotspot 會比較好。 ( 因為我知道緩解甚至最終解方案 ) 另外, Hotspot 會造成 write 效能降低,而 Fragmentation 會降低 read 效能,但一般資料庫的操作通常是 read 比 write 次數高很多, 所以選擇 Hotspot 也 ( 可能 ) 是正確的。 最後, PostgreSQL 天生無法避免 Fragmentation 問題,而且修復 Fragmentation 的解決方法就是執行 VACUUM FULL ( 標準的 VACUUM 沒用 ) ,可惜這會造成 table locked ,更慘。 Ref: https://www.facebook.com/yftzeng.tw/posts/10202227746654516
  21. 55/147 2015 Hotspot Ref: https://www.facebook.com/groups/199493136812961/permalink/729886527106950/ 《我的解釋》 我從來沒有說 MySQL 可以撐住 Google

    / Facebook 的量。聰明 的讀者都看得出來。 「 OLTP 看重 WRITE 而不看重 READ 」,我同意也不同意。你 這句我從來沒全面否認。我的結論是,看大家在架構面的未來進 展,如果打算 RDBMS 將來無痛移轉到 OLAP ,則 MySQL 從前 線退役時,我覺得剛好適合做 OLAP 。你說的 PostgreSQL 當 OLAP 有的特色當然好,只是我傾向用 Big data 的技術解掉, 畢竟這時候面對的都是「量」的問題,傳統的 SQL 無法滿足我 對 scalability 的要求。若你不覺得也無妨,這點我留給讀者自行 去判斷。
  22. 58/147 2015 Hotspot ♪Database Tuning Tuning (Insert buffering, ...etc.) Partitions

    ♪Database Design TokuDB NoSQL Approximately ordered / Completely random ♪Hardware RAID 0 / 5 / 10 / 50 Fusion IO (From IO bound to CPU bound)
  23. 60/147 2015 Auto / Manual Clean Dead Node Ref: https://www.facebook.com/yftzeng.tw/posts/10202227746654516

    《我的解釋》 MySQL 會在有限時間與空間內保持數據循序性,並依 background job 清理 dead tuples 。這在簡報第 17 頁有提及。雖然會影響 concurrent write 的效能,但卻保持 concurrent read 的效率。 但 PostgreSQL 使用不一樣的思路,它把清理 dead tuples 的功能 交由 VACUUM 程序處理。不過自從 PostgreSQL 8.1 版新增 AUTOVACUUM 功能後,也等同於開始允許程序自動清理舊數據 而非單純只能人工; 9.0 版更是預設啟動 AUTOVACCUM 功能。
  24. 61/147 2015 Auto / Manual Clean Dead Node Ref: https://www.facebook.com/yftzeng.tw/posts/10202227746654516

    《我的解釋》 這意謂 PostgreSQL 轉向 MySQL 的自動 ( 而非人工 ) 數據清理 方式。所以也就沒有作者所說的,「讓你自行決定什麼時候執行」 的問題,除非我們主動關閉 AUTOVACUUM 改手動。 不過,清理數據的時機很敏感 ( 否則會影響正常運行的效能 ) , 交由官方演算法自行決定通常會比較安穩,除非你自己很明白你 在做什麼。況且, VACUUM 也不是沒有副作用。 (http://rhaas.blogspot.tw/2011/03/troubleshooting-stuck-vacuums.html)
  25. 63/147 2015 Auto / Manual Clean Dead Node Ref: https://www.facebook.com/groups/199493136812961/permalink/729886527106950/?comment_id=731212386974364

    《我的解釋》 VACUUM 或 AUTOVACUUM ,我都讓使用者自行選擇,我 只是說 AUTOVACUUM 自有一套演算法自己知道何時會最好, 如果專家自認「手工」的方式比官方自帶的好,自然改「手工」 ,我對此從來沒有意見。
  26. 65/147 2015 Auto / Manual Clean Dead Node Ref: http://www.postgresql.org/docs/9.4/static/routine-vacuuming.html

    PostgreSQL 官方文件: 有些管理員會習慣在承載很低的時候,自動執行 VACUUM 。但 固定在某個時間執行會有一定的風險,例如 ( 不一定這期間 ) 突 然有非預期大量的 UPDATE 活動時,那麼就會發生 "bloat" ,反 而事後需要使用 VACUUM FULL 。 使用 autovacuum 可以緩解這個問題,因為 autovacuum 會動態 視 UPDATE 活動做調整。所以關閉 autovacuum 並不明智,除 非你能夠預期極端的工作量發生。
  27. 67/147 2015 Auto / Manual Clean Dead Node Ref: https://www.facebook.com/groups/199493136812961/permalink/729886527106950/

    作者一直強調: 1. DBA 一定要知道什麼時候系統最清閒。 2. 手動決定而不要自動。
  28. 68/147 2015 Auto / Manual Clean Dead Node 《我的解釋》 很多營運不是政府機關或金融單位。夜間也不一定可以緩機

    休息。因此,面對全球化營運思維時,系統隨時都有高承載 的可能。這意謂著系統即使相對上有「比較空閒」的時間, 但此時線上人數都還可能超過數萬,甚至數百萬人使用。 這時候的任何回收行為都會影響正常的系統營運。 還是回到初衷,選擇最適你的業務需求。
  29. 69/147 2015 Auto / Manual Clean Dead Node 《 Sentry

    的災難與慘痛經驗 》 The internet is full of awful advice of users suggesting you should turn off autovacuum, or run it manually at low traffic times, or simply adjust its schedule to run less often. To know why that’s ill-advised, you first need to understand the consequences of autovacuum not running. 網路上很多人建議關閉 AUTOVACUUM ,改以排程或手動 選擇負載低的期間執行 VACUUM 。但這是不明智的,你只 要知道不運行 AUTOVACUUM 會帶來的各種嚴重後果就會 明白了。 Ref: http://blog.getsentry.com/2015/07/23/transaction-id-wraparound-in-postgres.html
  30. 73/147 2015 大型系統不能用 auto-inc 一定要 UUID Ref: http://en.wikipedia.org/wiki/Universally_unique_identifier UUID 有很多種,用錯結果會不一樣。

    常見的有 UUIDv1(Ordered UUID) 及 UUIDv4 (Random UUID) 。 作者在名詞上混淆了兩者。 UUIDv1 是跳號循序,同機器上後一個會比前一個大,所以總是 INSERT 在 last node ,仍有 Hotspot 問題。 顯然作者這裡用字若再精準些,應該要用 Random UUID , 而不應該用較廣泛定義的 UUID 。 ( 所以作者建議的是 Random UUID ,如 UUIDv4)
  31. 82/147 2015 MySQL index->lock contention Ref: https://www.facebook.com/groups/199493136812961/permalink/731201573642112/?comment_id=731385080290428 作者簡報上說: MySQL 的

    B+ tree 在 page splitting / merging 時 , 整棵 B+ tree 都會加上 WRITE_LOCK 但引用 Oracle 文章時又改說: Oracle 官方人員說得很明白: leaf-node split / merge ( 他口中的 tree modification change) 會引起 index X lock 的。 ” 前者意謂: always” 會發生。 ” 後者意謂: 只有發生在 leaf-node ” 才會 。 我不是故意要找碴,但定義不清楚,很難討論。
  32. 83/147 2015 MySQL index->lock contention Ref: https://www.facebook.com/groups/199493136812961/permalink/731201573642112/?comment_id=731385080290428 不過我的論點也不是指「 page splitting

    / merging 不會造成整個 B+ tree 都會加上 WRITE_LOCK 」 ,而是在某些特定情況下才會,所以不認為是您簡 報上說的 "always" 。 "latch" 中文是 " 鎖 " 沒錯,但他的 locked 是針對 "one page" ,不等同於 "full index" ,這是我的重點。 但會不會造成 "full index" ,不好意思,我承認沒有 追完所有原始碼。
  33. 85/147 2015 MySQL index->lock contention 《整理》 作者的論點 ( 前後論點兩者彼此衝突 )

    1. MySQL 的 B+ tree 在 page splitting / merging 時 ,(always) 整棵 B+ tree 都會加上 WRITE_LOCK 。 2. 只有 leaf-node split / merge 會引起 index X lock 。 我的論點 ( 兩個是獨立事件 ) 1. “latch” “ 與 lock” 的定義在 MySQL 中不一樣。 2. ”latch” “ 只是 one page” ,不等同於 "full index" 。 ( ” 但若 latch” ” 不只是 one page” 則可能,原始碼還沒追完 )
  34. 86/147 2015 MySQL index->lock contention MySQL 5.6.22 原始碼 storage/innobase/btr/btr0btr.cc 第

    640 行 “latch” ” 可能指 tree” (full index) ” ,也可能指 node” latch 。
  35. 87/147 2015 MySQL index->lock contention 《整理》 作者的論點 ( 雖然兩者衝突 )

    1. MySQL 的 B+ tree 在 page splitting / merging 時 ,(always) 整棵 B+ tree 都會加上 WRITE_LOCK 。 2. 只有 leaf-node split / merge 會引起 index X lock 。 我的論點 ( 兩個是獨立事件 ) 1. “latch” “ 與 lock” 的定義在 MySQL 中不一樣。 2. ”latch” “ 只是 one page” ,不等同於 "full index" 。 ( ” 但若 latch” ” 不只是 one page” 則可能,原始碼還沒追完 ) 2. “latch” ” 可以對 node” ” ,也可以對 full index” 。
  36. 89/147 2015 MySQL index->lock contention 《整理》 作者的論點 ( 雖然兩者衝突 )

    1. MySQL 的 B+ tree 在 page splitting / merging 時 ,(always) 整棵 B+ tree 都會加上 WRITE_LOCK 。 2. 只有 leaf-node split / merge 會引起 index X lock 。 我的論點 ( 兩個是獨立事件 ) 1. “latch” “ 與 lock” 的定義在 MySQL 中不一樣。 2. ”latch” “ 只是 one page” ,不等同於 "full index" 。 ( ” 但若 latch” ” 不只是 one page” 則可能 ) 2. “latch” ” 可以對 node” ” ,也可以對 full index” 。
  37. 90/147 2015 MySQL index->lock contention Ref: http://mysqlserverteam.com/mysql-5-7-improves-dml-oriented-workloads/ Before 5.7, every

    modifications to non-leaf pages (every modifications for the tree structure) required to exclude the other threads’ access to the whole index by X-lock, and every concurrent accessing the index tree were blocked.
  38. 91/147 2015 MySQL index->lock contention Ref#1: http://mysqlserverteam.com/mysql-5-7-improves-dml-oriented-workloads/ Ref#2: http://www.percona.com/blog/author/yasufumi/ Ref#3:

    http://dev.mysql.com/worklog/task/?id=6326 Ref#4: https://github.com/mysql/mysql-server/commit/070115a3d9548f790039c39a48b19d759ab2407c Before 5.7, every modifications to non-leaf pages (every modifications for the tree structure) required to exclude the other threads’ access to the whole index by X-lock, and every concurrent accessing the index tree were blocked. MySQL 開發者講了兩件事: 1. page split / merge “ 時,只有發生在 non-leaf pages” 時才會 whole index locked 。 2. page split / merge “ 時,只有在 non-leaf pages” ” 才稱 tree structure modification” 。 補充:這位 MySQL 開發者是誰? 1. 他是 Yasufumi Kinoshita 。 2. Percona 官方認證數一數二 InnoDB 專家,從事 InnoDB 內核改進多年。 ( 底下附參考連結 #2) 3. 本次的改良幾乎由他主導,是實際改程式碼的人。 ( 詳見下方參考連結 #3 及 #4) 4. 如果不相信他,我也不知道該相信誰。
  39. 92/147 2015 MySQL index->lock contention 《整理》 作者的論點 ( 雖然兩者衝突 )

    1. MySQL 的 B+ tree 在 page splitting / merging 時 ,(always) 整棵 B+ tree 都會加上 WRITE_LOCK 。 2. 只有 leaf-node split / merge 會引起 index X lock 。 我的論點 ( 兩個是獨立事件 ) 1. “latch” “ 與 lock” 的定義在 MySQL 中不一樣。 2. ”latch” “ 只是 one page” ,不等同於 "full index" 。 ( ” 但若 latch” ” 不只是 one page” 則可能 )
  40. 93/147 2015 MySQL index->lock contention Ref: https://www.facebook.com/groups/199493136812961/permalink/731201573642112/?comment_id=731280403634229 1. 作者引用官方文件卻誤解真實現象。 (full

    index lock 會發生在 non-leaf node 而非 leaf node) 2. “ 如同我所述,確實 latch” ≠ “lock” 。 3. “ 我沒有說過 tree modification ≠ page split / merge” 。
  41. 94/147 2015 MySQL index->lock contention 经常有人把 latch 造成的等待事件误认为是 lock 造成的阻塞,

    其实这是两个完全不同的概念。 在性能优化上,如果能够区别开这两个因素引起的性能问题, 将能极大地提高我们的性能分析判断能力。 Ref: http://zoroeye.iteye.com/blog/2187289
  42. 95/147 2015 MySQL index->lock contention Ref: Relational Database Index Design

    and the Optimizers [Wiley] (2005) (31) 什麼是 non-leaf pages ?
  43. 97/147 2015 MSSQL 是垃圾? Ref: https://www.facebook.com/groups/199493136812961/permalink/731201573642112/?comment_id=731385080290428 這是我的回應:想了解為何作者稱 MSSQL 為垃圾的證據。 雖然我過去只有一年多的時間使用

    MSSQL ; 但 MSSQL 並不一定很差。 工程師在發現工具 ( 軟體 ) 很差時, 有時候應先問問自己是否真的明白如何善用手中的工具。 殺雞用牛刀?!
  44. 104/147 2015 Replication crash safe PostgreSQL 9.0 引進了 Stream replication

    技術,能夠極快地 處理 WAL (Write-Ahead Logging) 日誌。 但 9.0 的 Stream replication 是 Async replication ;當 Master 當機時,會有資料丟失的風險。 直到 PostgreSQL 9.1 ( 2011-09-11 ) 引進 Sync replication 技術後才解決。 而 MySQL 必須等到 5.7 才有完整的解決方案。比 PostgreSQL 晚了約 4 年,但也說明 MySQL 5.7 有很多大改進。 ( 還是不建議升級為 MySQL 5.7 嗎? )
  45. 106/147 2015 Query Optimizer – 《数据库查询优化器的艺术 原理解析与 SQL 性能》 PostgreSQL

    9.2.3 vs. MySQL 5.6.10 17.3 本章小結 (p486)   對於子查詢的優化, PostgreSQL 和 MySQL 各有所長;對於等價謂詞 重寫,條件的處理, MySQL 略勝 PostgreSQL 一籌,在各種連接消除方面 ,二者基本相當,都支持外連接消除和嵌套連接消除。在索引和約束的利用 方面,尤其是語義優化和非 SPJ 的優化, MySQL 顯得技高一籌;對於索引 和約束以及條件化簡的充分利用,使得 MySQL 能及早把計算和推理的工作 在查詢計劃生成的過程中完成,從而生成更為高效的查詢執行計劃。   整體上, MySQL 查詢優化器支持的邏輯優化點比 PostgreSQL 多, MySQL 查詢優化器邏輯查詢優化部分靈光閃爍,讓讀之者愛不德手,但這 不代表查詢優化器的效率高於 PostgreSQL 。查詢優化器的效率高低需要 在現實中根據實際場景通過測試來評估。
  46. 2015 107/147 High Concurrent Write? PostgreSQL 比 MySQL 更適於應付 High

    Concurrent Write? 我覺得還是要視業務場景。
  47. 108/147 2015 High Concurrent Write?(Fragmentation) 《 MySQL 》 INSERT 循序時,會頻繁在同一

    page 操作 ( 維持 Sequential , 但有 Hotspot 問題 ) 。 MySQL 預設會延遲寫入 Storage ,並將 連續異動的 pages 一次寫入,甚至將請求合併,從而有效降低 Random write 的次數以及合併部分 Random write 變成 Sequential write 。 但若使用 Random UUID 時,寫的不一定是同一 page ,所以即 使延遲寫入 Storage ,也會產生很多 Random write 。 Ref: http://www.tocker.ca/2013/05/06/when-does-mysql-perform-io.html
  48. 109/147 2015 High Concurrent Write?(Fragmentation) 《 MySQL 》 SELECT 時,若在

    Memory 中, MySQL 會保持 ( 邏輯 )Ordered 。 但 PostgreSQL 不是,而且再加上它的 MVCC 設計, UPDATE/ DELETE 遺留下的 dead rows 會使得 Fragmentation 更嚴重。 若 SELECT 是從 Storage 取出時,因 MySQL 連續異動的 pages 一次寫入,甚至將請求合併,所以相近的資料放在同一 block 的 機率較高。且將 Storage 讀出放入 Memory 時, MySQL 仍會保 持 ( 邏輯 )Ordered 。
  49. 110/147 2015 High Concurrent Write?(Hotspot) 《 Hotspot 》 討論兩種情況: 1.

    頻繁 UPDATE 同一 Row 。 2. 頻繁 INSERT (Ordered) 。
  50. 111/147 2015 High Concurrent Write?(Hotspot:UPDATE) 《 Hotspot 》 討論兩種情況: 1.

    頻繁 UPDATE 同一 Row 。 2. 頻繁 INSERT (Ordered) 。
  51. 114/147 2015 High Concurrent Write?(Hotspot:UPDATE) 《 MySQL 》 直接 UPDATE

    在同一 Row ,不會造成該 Page 的大小變化。 《 PostgreSQL 》 盡量在同一 Page 寫入新的 Row ,但若該 Page 空間不足時,則 會另新建一 Page 寫入。 Fragmentation ? VACUUM ?
  52. 115/147 2015 High Concurrent Write?(Hotspot:UPDATE) 《 PostgreSQL 》 PostgreSQL 天生容易遇到

    Index bloat 的問題。 Ref: PostgreSQL 9.0 High Performance [PACKT] (2010) (p171)
  53. 117/147 2015 High Concurrent Write?(Hotspot:UPDATE) Ref: http://zh.wikipedia.org/zh-tw/%E5%86%99%E5%85%A5%E6%94%BE%E5%A4%A7 SSD :寫入放大效應 +

    垃圾回收 SSD 在寫入資料時,一定要抹除該區塊 的資料後才能寫入。而抹除的最小單位 是 512KB 。 即使這 512KB 中只有 1KB 的資料需要 更改,也要將整個區塊中的資料複製到 緩衝區,然後將資料抹除後寫回。 舉某些廠牌的測試數據,寫入資料的延 遲約為 0.2ms ,但抹除需要 2ms 。
  54. 119/147 2015 High Concurrent Write?(Hotspot:UPDATE) Ref: http://is.gd/eUss8P ( 如何写一个为 SSD

    优化的数据库? ) SSD 重寫數據時由於寫放大效應的存在隨機寫入可能會比順序 寫入帶來的損耗更大。
  55. 120/147 2015 High Concurrent Write?(Hotspot:INSERT) 《 Hotspot 》 討論兩種情況: 1.

    頻繁 UPDATE 同一 Row 。 2. 頻繁 INSERT (Ordered) 。
  56. 122/147 2015 High Concurrent Write?(Hotspot:INSERT) 《 MySQL 》 直接 INSERT(Ordered)

    在同一 Page 。 《 PostgreSQL 》 直接 INSERT(Ordered) 在同一 Page 。
  57. 125/147 2015 High Concurrent Write?( 實驗數據 ) 有沒有把 PostgreSQL VACUUM

    / Fragmentation 因子考慮進去? 有些從開始到結束,可能連一次 VACUUM 都沒執行過。 PostgreSQL 8.1 新增 autovacuum 功能。 PostgreSQL 9.0 預設啟動 autovacuum 。 MySQL 預設則是會在背景啟動 Purge 。 MySQL 預設使用 REPEATABLE-READ ; PostgreSQL 預設使用 READ-COMMITTED 。
  58. 127/147 2015 High Concurrent Write?(PURGE/VACUUM) InnoDB 只有最新的資料會留在 table 中,舊資料會移到 rollback

    segment 。意謂舊資料會移出空間並標示為未來可清除。 於是, Purge 得以擺脫 table 中的任何 deleted rows ,並專心從 rollback segment 中清理舊資料。 PostgreSQL 沒有類似 rollback segment 的設計,導致最終的清 理工作較昂貴。由於少了中心化的清理資訊, VACUUM 必須掃 描全表,以找出需要清理的舊資料。 Ref: http://rhaas.blogspot.tw/2011/02/mysql-vs-postgresql-part-2-vacuum-vs.html
  59. 128/147 2015 High Concurrent Write?(PURGE/VACUUM) PostgreSQL 8.3 之後,加入了 HOT ("heap

    only tuple") 。 但 HOT 並沒有完全解決問題,它的缺點如下: 1. 只有在所有索引屬性都沒有被更新時才能使用 HOT 。 2. 只有在被更新記錄所在頁面能夠存儲新版本時才能用 HOT 。 Ref: http://rhaas.blogspot.tw/2011/02/mysql-vs-postgresql-part-2-vacuum-vs.html
  60. 129/147 2015 High Concurrent Write?(PURGE/VACUUM) PostgreSQL 8.4 之後,加入了 bitmap ,也就是

    visibility map , 得以指出哪些需要清理的 pages 。 使得 VACUUM 可以掃描 dirty pages ,但也僅止於 pages 而不是 直接指到 rows 。 而 VACUUM 仍然需要掃描所有 index ,這個操作在大表裡很昂貴。 Ref: http://rhaas.blogspot.tw/2011/02/mysql-vs-postgresql-part-2-vacuum-vs.html
  61. 130/147 2015 High Concurrent Write?(PURGE/VACUUM) PostgreSQL 讓 UPDATE 比較快 (

    因為把問題往後丟 ) ; MySQL 讓 PURGE 比 VACUUM 快 ( 提前處理問題 ) 。 但 PostgreSQL 要小心事務的成長導致 VACUUM 跟不上的情形。 ( 系統瓶頸在寫入不夠快時發現容易,還是 VACUUM 跟不上時 ?) Ref: http://rhaas.blogspot.tw/2011/02/mysql-vs-postgresql-part-2-vacuum-vs.html
  62. 131/147 2015 High Concurrent Write?(PURGE/VACUUM) VACUUM 會造成大量的 IO ,進而影響其它的效能。 Plain

    VACUUM 可能無法滿足業務有大量的 UPDATE/DELETE 。 如果有這種情形,則應使用 VACUUM FULL ,或 CLUSTER 或 ALTER TABLE 。 Ref: http://www.postgresql.org/docs/9.4/static/routine-vacuuming.html
  63. 132/147 2015 High Concurrent Write?( 抖動 ) 對於一個上線服務而言,穩定性遠大於平均效能。 意即效能防抖動,好預估,降低重要時刻發生在低點的機率。 PostgreSQL

    的理念是把問題往後丟,不管是 Fragmentation 或 GC ,而這些多少也可能造成 SSD 的效能抖動。且 VACUUM 的性能會因表愈大愈慢 ( 執行期間也會影響其它工作 ) 。 MySQL 的理念則是提早解決問題,不管是 Ordered Index 、 Sequential 或 GC 。所以 MySQL 平均效能抖動有機會平緩, 但相對地,最佳高峰性能表現可能不及 PostgreSQL 。 不過這問題太複雜,需視參數及硬體的實際特性而論,最終 還是需以業務長期測試數據為準。不同業務有不同結果。
  64. 133/147 2015 High Concurrent Write?(XID) PostgreSQL 對每個事務都有分配一個 XID 。這些事務不是只指 BEGIN/COMMIT

    ,還包括 INSERT / UPDATE / DELETE 。每次 使用都會遞增。 但這個 XID 是 32bits ,最大支持 40 億個事務。當 XID 達到最大 值時,會從零再度開始。 突然間,所有事務變成未來所產生的,新事務都沒有辦法訪問這 些舊紀錄了。 Ref: https://devcenter.heroku.com/articles/postgresql-concurrency
  65. 134/147 2015 High Concurrent Write?(XID) 《 Sentry 的災難與慘痛經驗 》 Sentry

    遇到非常嚴重的災難,這一切都與 XID 的設計有關。 如果你的系統負載很高,而你又關閉 AUTOVACUUM 時。最終 你會因為 XID 達到上限值而造成 MVCC 不再正常運作,造成資 料遺失等各種麻煩問題。 PostgreSQL 官方網站聲明, XID 是 32 bits ,理論上限為四百 萬筆交易。為了避免這個問題,最好每二百萬筆交易時就要執 行 VACUUM 。 Ref: http://blog.getsentry.com/2015/07/23/transaction-id-wraparound-in-postgres.html Ref: http://www.postgresql.org/docs/9.5/static/routine-vacuuming.html#VACUUM-FOR-WRAPAROUND
  66. 135/147 2015 High Concurrent Write?(TokuDB) 倘若使用 MySQL 真遇到需要 Concurrent Write

    高的業務情況時, 也可以使用一行指令將 InnoDB 轉換為 TokuDB 。 TokuDB 採用類似於 PostgreSQL 的設計,但更為先進 ( 官方說法 ) ,且已申請專利。 早期是商用軟體,現已依 GPL-2.0 開放源碼。 但 TokuDB 也不是沒有缺點。
  67. 136/147 2015 High Concurrent Write?(WebScaleSQL) WebScaleSQL 主要由四家業者支持: 1. Facebook 2.

    Google 3. LinkedIn 4. Twitter 阿里巴巴隨後也一同參與開發計畫: 『阿里 MySQL 团队加入参与 WebScaleSQL 开发』 Ref: http://www.oschina.net/news/58837/alibaba-mysql-team-join-webscalesql
  68. 144/147 2015 最後 Ref: https://www.facebook.com/groups/199493136812961/permalink/731201573642112/?comment_id=732041130224823 而我只是說: 而我只是說: 我不覺得個人情緒需要在 Facebook 的【

    PHP 台灣】 公眾技術討論社團中發洩。況且內容與 PHP 無關, 也與資料庫技術無關。 作者罵我說: 作者怒罵說: