## 簡介
簡單來說,MariaDB(MySQL)的復制機制是這樣的:
在Master端所有數據庫的變更(包括DML和DDL)都會以 Binlog Event 的方式寫入Binlog中。Slave會連上Master然后讀取 Binlog Event,再重放這些操作到自身的數據中。一個實例可以既是Master同時又是Slave,做成雙向復制。也可以一級一級串聯,做成級聯復制,Binlog Event 中包含的 server_id 可以識別產生 Event 的實例,避免重復執行。
Slave會保存最后一次收到和應用的Binlog的位置,因此Slave重連Master時可以從中斷的位置繼續開始復制。也可以在暫停Slave后,將其整體拷貝到新的位置,然后作為一個新的Slave繼續復制。
全局事務ID(Global transaction ID,GTID)為每個 Event Group (就是一系列 Event 組成的一個原子單元,要么一起提交要么都無法提交)引入了一個標識,因此 GTID 是標識“事務”的最佳方式(盡管 Event 里面還包含一些非事務的DML語句和DDL,它們可以作為一個單獨的 Event Group )。每當一個 Event Group 從Master復制到Slave時,它的 GTID 也通過 GTID Event 被傳到Slave。因為每個 GTID 在整個復制拓撲結構中都是一個唯一標志,所以這使得在不同的實例之間識別相同的 Binlog Events 非常簡單,然而在有 GTID 之前,想做到這點是很困難的。MariaDB 從 10.0.2 開始提供 GTID 支持,但是 MariaDB 的 GTID 與 MySQL 的 GTID 在實現原理上并不相同,因為 MariaDB 支持像多源復制啊、多主復制等官方暫時還沒考慮的復制模型。下面我們來看看 MariaDB 的 GTID 的實現。
## 優勢
使用 GTID 有兩個主要的優勢:
1. 在級聯復制、一主多從等復雜的復制場景下,可以更簡單地將一個Slave的復制修改到另一個Master上,而不用人工去尋找復制的起始位點。從5.0一路走來的同學應該很能理解這種痛苦。
這是因為Slave會保存最后一個執行的 Event Group 的 GTID,因此可以通過這個 GTID 很容易地在新Master上找到相應的復制起點。而在使用 Binlog File 和 Binlog Pos 的時代,這是很難辦到的。
2. Slave的狀態是 Crash-Safe 的。
Slave的執行狀態(最后一個執行的 GTID)被記錄在?`mysql.gtid_slave_pos`?系統表中。如果這張表使用的是事務引擎(例如InnoDB,默認就是),那么修改用戶表的數據和修改Slave狀態的系統表這兩個操作在就可以放在一個事務中完成,這就保證了Slave狀態是 Crash-Safe 的,如果Slave崩潰了,那么 Crash Recovery 就可以在重啟的時候把用戶數據表和Slave狀態系統表恢復到一個一致的位點。而在非 GTID 復制的舊版本中,這也是做不到的,Slave狀態只是簡單的存放在 relay-log.info 文件中 (MySQL是可以把 Binlog File 和 Binlog Pos 也存在?`slave_relay_log_info`?和?`slave_master_info`?系統表中),而且需要靠不斷的?`fsync()`?調用才能同步到磁盤上,一旦宕機很可能導致Slave狀態跟實際不一致(但是也只有事務引擎的DML能保證一致,非事務引擎和DDL本身就不是Crash-Safe的)。
基于這兩個優勢,通常我們都建議使用GTID復制。并且傳統的基于Binlog文件位置的復制方式,和 GTID 的復制方式,在 MariaDB 中是可以相互之間平滑的切換的。
## 實現方式
每個GTID,都包含三個數字部分,分別用’-‘號隔開,例如:
0-1-10
第一個數字’0’是Domain ID,這是一個32位的無符號整型。
第二個數字’1’是Server ID,這跟傳統的主備復制中 Server ID 的含義是一樣的,也是一個32位無符號整型。因此在一個復制拓撲中每個實例的Server ID必須是唯一的。
第三個數字是序列號(Sequence Number)。這是一個64位的無符號整型。每個新產生的 Event Group 記錄到Binlog時都會新生成一個單調遞增的序列號。
這個規則使得 (server_id, sequence_number) 總是唯一的,因此GTID也是全局唯一的。
使用64位數字可以提供充足序列號支持龐大的 Event Group 數量,在可預見的時間內,應該來說是沒有溢出風險的。但是一個可見的風險是,人為地設置一個很高的?`gtid_seq_no`?值,導致 GTID 的起始序列號就很高,是可能導致序列號逼近64位數值的上限的。
## Domain ID
當 Events 從Master復制到Slave時,Events 總是按照從Master讀取的順序記錄在Slave的Binlog中。因此,如果同一時刻只有一個Master接收變更操作(不包括復制帶來的變更操作),那么 Binlog 中 Events 的順序在所有參與復制關系的實例上應該都是一樣的。
這種一致的 Binlog 順序,可以被Slave用來追蹤當前復制的位置。只要Slave記住最后一個從Master復制過來的 Event Group 的 GTID,重連到Master時(不管是原來的Master還是新的Master),就可以發送這個 GTID 給Master,然后Master就可以開始繼續發送這個 GTID 之后的 Event.
然而,如果用戶同時在多個實例上做了更新,那么一般來說各個實例上的Binlog順序是不可能一樣的。當使用多源復制、或者實例之間構成環狀拓撲結構時,這種情況是可能出現的;或者人為手動對一個Slave做了更新操作,也可能發生這種情況。如果 Binlog 順序在新老Master之間不一樣,那么僅僅使用一個獨立的GTID(不包含 Domain ID)并不足以記錄當前的狀態。
而 Domain ID 的任務, 就是為了解決這種情況。
通常,Binlog 并非是一個單一有序的數據流(Strem),相反,它是由許多不同的數據流組成的,每個數據流都由一個自己的 Domain ID 來識別。對每個數據流,GTID 總是以相同的 Binlog 順序存儲在每個實例中。但是,不同的數據流可以以不同的方式在不同的實例中交錯。
Slave通過記錄每個復制數據流(Replication Stream)中最后一次應用的 GTID 位置來跟蹤復制的位點。當連上一個新的Master時,Slave可以為每個 Domain ID 從不同的 Binlog 位點開始復制。
后面有一節我們專門闡述了如何設置 Domain ID,以及如何在多源復制、多主復制的場景下利用 Domain ID.
只有一個Master的簡單場景是不用考慮 Domain ID 的,任意時刻只有一個Master會有應用去更新,所以只需要一個單獨的 Replication Stream 即可,Domain ID 可以直接忽略,在所有實例上用默認值0就行了。
## GTID的應用
從 MariaDB 10.0.2 開始,GTID 是默認自動打開的。每個 Event Group 寫到 Binlog 時會先收到一個GTID_EVENT,用MariaDB的 mysqlbinlog 工具或者 SHOW BINLOG EVENTS 命令可以看到這個Event。
Slave自動記錄了最后一次應用的 Event Group 的 GTID,可以通過?`gtid_slave_pos`?變量來查看:
~~~
SELECT @@GLOBAL.gtid_slave_pos
0-1-1
~~~
當Slave連接到Master時,可以選擇是否使用 GTID 方式,或者使用原來的文件位置的方式來判斷起始的復制點位。如果使用 GTID 方式復制,那么在 CHANGE MASTER 的時候使用?`master_use_gtid`?選項來設置:
~~~
CHANGE MASTER TO master_use_gtid = { slave_pos | current_pos | no }
~~~
`CHANGE MASTER TO master_use_gtid=slave_pos`?將把Slave配置為使用 GTID 方式。當Slave連接到Master時,Master將從最后一個GTID開始給Slave復制 Binlog,可以通過?`@@gtid_slave_pos`?這個變量來查看目前最后一個GTID是什么。由于GTID在所有參與復制的實例之間都是相同的,因此Slave可以被指向不同的Master,Master可以自動決定正確的復制起始位置。
但是,假設我們設置了兩個實例A和B,并且讓A是Master,B是他的Slave。運行一段時間后,我們關閉A,然后讓B成為新的Master,然后一段時間后我們再把A加回來作為B的Slave。
由于A從來沒有成為Slave,它沒記錄任何之前復制的GTID,所以`@@gtid_slave_pos`是空的。如果要讓A自動被加為Slave,可以使用?`master_use_gtid=current_pos`?這個方法。這樣做在連接的時候,Slave會把`@@gtid_current_pos`存的GTID發給Master,而不是?`@@gtid_slave_pos`,這樣就把A做Master時產生的最后一個GTID發送給了B,然后從這個位置開始復制。
使用`master_use_gtid=current_pos`可能是最簡單的方式,因為這樣不需要考慮之前這個實例是作為Master還是Slave。但是,必須注意的是,如果這樣做的話,就不要在Slave上做任何非復制帶來的修改操作,否則就亂了。如果出現了這種情況,復制可能無法繼續,因為這些事務在Master運行時并沒有在Master上出現過,當切換Master和Slave身份時,就出現了未知的GTID。為了避免這種情況,可以在Slave上設置?`@@sql_log_bin=0`。
如果這不是Slave期望的運行方式,Slave上就是可能有一些數據變更,那么就應該使用`master_use_gtid=slave_pos`方式。這樣Slave總是使用最后一次復制的GTID發送給Master來獲取之后的Event Group。這可以避免上面的方式在一些不可控因素修改了Slave本地的數據卻沒有在Binlog之中有所記錄的問題。
當GTID嚴格模式開啟時(`@@GLOBAL.gtid_strict_mode=1`),通常最好是用`current_pos`。在嚴格模式下,不允許有額外的事務。
如果Slave沒有開啟Binlog,那么`current_pos`和`slave_pos`是一回事。
即使當Slave被配置為舊的復制方式時(`CHANGE MASTER TO master_log_file=..., master_log_pos=...`),MariaDB依然會跟蹤當前的GTID位置并保存在?`@@GLOBAL.gtid_slave_pos`。這意味著一個用非GTID模式復制的Slave可以很容易地修改為GTID方式:
~~~
CHANGE MASTER TO master_use_gtid = slave_pos
~~~
Slave會保存?`master_use_gtid=slave_pos|master_pos`的信息以為后來進行連接,直到復制方式被修改為指定?`master_log_file/pos=...`?或者?`master_use_gtid=no`。當前的復制方式可以通過SHOW SLAVE STATUS的Using_Gtid列來判斷:
~~~
SHOW SLAVE STATUS\G
...
Using_Gtid: Slave_pos
~~~
Slave內部用`mysql.gtid_slave_pos`表來存儲GTID位置(所以重啟后`@@GLOBAL.gtid_slave_pos`的值會重新被填充)。升級MariaDB的版本到10.0之后,必須使用`mysql_upgrade`來保證這些表和列被創建了。
為了保證Crash-Safe,這張表必須使用事務引擎,例如InnoDB。當MariaDB第一次安裝或者升級到10.0.2+時,這張表會用默認的存儲引擎創建 - 默認就是InnoDB。當然如果把默認引擎改成MyISAM的話,這張表就會被創建成MyISAM。如果需要修改引擎,可以直接用ALTER TABLE的方式:
~~~
ALTER TABLE mysql.gtid_slave_pos ENGINE = InnoDB
~~~
`mysql.gtid_slave_pos`?表不應該被Slave線程之外的方式修改。尤其是不要嘗試直接修改表的數據來改變Slave的GTID位置,如果要修改應該用這種方式:
~~~
SET GLOBAL gtid_slave_pos = '0-1-1'
~~~
### 配置一個新的Slave使用GTID
設置一個新的使用GTID的Slave跟設置一個非GTID方式復制的Slave差別很大,基本步驟是:
1. 配置一個新的實例并且載入初始數據。
2. 從相應的Master Binlog位置開始Slave的復制。
#### 從一個空實例開始
出于測試的目的,最簡單的方式就是新建一個新的空實例,然后從Master復制所有的Binlog(在實際生產環境中這幾乎是不可能的,因為最早的Binlog文件應該早就被清除了)。
正常方式安裝的Slave實例,默認情況下GTID位點都是空的,因此可以從Master的第一個Binlog文件開始復制。但是如果Slave之前被用作其他目的,那么初始位置需要手動設置為空:
~~~
SET GLOBAL gtid_slave_pos = "";
~~~
下一步就是用CHANGE MASTER來指向Master,指定`master_host`什么的。只是不再用`master_log_file`和`master_log_pos`,而是用`master_use_gtid=current_pos`(或者slave_pos):
~~~
CHANGE MASTER TO master_host="127.0.0.1", master_port=3310, master_user="root", master_use_gtid=current_pos;
START SLAVE;
~~~
#### 從備份集設置
一般來說創建Slave的方式都是通過備份集來恢復出一個新的實例,然后找到Master上復制的起始點創建復制關系。
因而找到正確的復制起始位置是非常重要的,否則Slave可能因為數據與Master不一致而導致復制中斷。
一般來說備份都是用 XtraBackup 或者 mysqldump。這兩種方式都可以在非阻塞的情況下獲得備份時正確的Binlog位點(所有表都要是事務引擎),當然,如果備份時不會有寫入,那么 SHOW MASTER STATUS 也能提供正確的位點。
一旦獲取了備份時正確的Binlog位點(文件名和偏移量),那么就可以用`BINLOG_GTID_POS()`函數來計算GTID:
~~~
SELECT BINLOG_GTID_POS("master-bin.000001", 600);
~~~
從MariaDB 10.0.13版本開始,mysqldump會自動完成這個工作,并且把GTID的寫在導出文件中,只要設置 –master-data 或 –dump-slave 的同時設置 –gtid 即可。
這樣的話新的SLAVE就可以通過設置?`@@gtid_slave_pos`?的值來設定復制的起始位置,用 CHANGE MASTER 把這個值傳給主庫,然后開始復制:
~~~
SET GLOBAL gtid_slave_pos = "0-1-2";
CHANGE MASTER TO master_host="127.0.0.1", master_port=3310, master_user="root", master_use_gtid=slave_pos;
START SLAVE;
~~~
用Master備份搭建一個Slave時這種方式尤其有用。不過一定要記得確保Master和Slave的server_id要設置成不一樣的。
如果備份是從現有的Slave實例創建的,那么GTID的位置已經存在`mysql.gtid_slave_pos`表中了,并且跟其他事務引擎表都是在一個一致狀態。這種情況下,就沒必要去找GTID的位置然后設置變量之類的,因為已經從`mysql.gtid_slave_pos`載入了正確的值。然而從Master做備份就沒這個福利了,因為正確的GTID位點信息在Binlog中,而不是在`mysql.gtid_slave_pos`。
#### 將非GTID復制的SLAVE切換為GTID方式
如果已經有一個SLAVE運行在Binlog文件名和偏移量的復制模式下,那么可以直接修改為GTID模式。對于升級來說這是很有用的方式。
當一個SLAVE通過Binlog位點的方式跟Master連接,并且Master支持GTID,那么SLAVE會自動把GTID位置的信息也獲取過來,并且在復制過程中會不斷更新。因此,當一個SLAVE已經連上了一個支持GTID的Master,那么并不需要額外的動作就可以把復制切換為使用GTID:
~~~
STOP SLAVE;
CHANGE MASTER TO master_host="127.0.0.1", master_port=3310, master_user="root", master_use_gtid=current_pos;
START SLAVE;
~~~
(后面更新的版本可能會增加一種方式,如果第一次連接的時候使用的是原來的Binlog文件位點的方式,那么只要主庫是支持GTID的,后面再連接的時候就自動切換為GTID方式)
### 更換Slave的Master
一旦復制運行在GTID模式下(`master_use_gtid=current_pos|slave_pos`),Slave就可以很容易地用CHANGE MASTER更換到新的Master:
~~~
STOP SLAVE;
CHANGE MASTER TO master_host='127.0.0.1', master_port=3312;
START SLAVE;
~~~
Slave已經記錄了最后執行的舊Master的GTID,而且由于GTID在整個復制拓撲中都是全局唯一的,因此Slave只需要根據GTID在新Master的Binlog里找到合適的位置,繼續復制就行了。
Binlog是一組有序的Events數據流(或者多個數據流,每個復制域(Replication Domain)都是一個數據流,參照接下來那一節),數據流內的Event在每個Slave上總是按照同一順序被應用。MariaDB 的 GTID 憑借這個順序,使得它足以記住每個數據流中的這個點。由于Event順序在每個實例上是相同的,切換到另一個實例的Binlog中相同的GTID點將會得到一樣的結果。
比較通俗易懂的講,就是MariaDB的GTID復制是全異步的,并且是非常靈活的。甚至Binlog順序的一致性被破壞了,切換Master后,GTID依然可以嘗試從當前GTID位點繼續復制。
Binlog順序在不同的實例之間產生不一致,最常見的情況是用戶或者DBA直接更新了Slave實例(并且把日志寫到Binlog了)。這會導致Slave上的有些Event,在Master和其他Slave上都沒有。雖然可以通過設置`sql_log_bin=0`來避免這些變更寫到Binlog。
這通常是避免實例之間Binlog不一樣的最好的辦法。話雖然這么說,但MariaDB的復制就是為最大的靈活性而設計的,而且有時這種不一致是有合理需求的。這種情況下,只需要理解GTID位點在每個Binlog數據流(每個Replication Domain就有數據流)中是一個單獨的點。
當一個復制拓撲中兩個Master在同一時間都是活躍的時候,也可能出現不一致。比如使用環形多主復制的時候。但是只要保證舊Master上的變更在完全復制到所有Slave之前不允許切換到新的Master。通常情況下,要切換Master,首先原Master上的寫應該先停止,然后等待所有變更復制到了新的Master,然后寫開始發送到新的Master。有意使用多個Master寫的情況也是支持的,下一節會描述這種情況。
GTID嚴格模式將用于強制保證所有實例之間的Binlog相同。當這個選項開啟,如果遇到任何不一致情況都會導致復制停止并且報錯。
### 使用多源復制和其他多主情況的設置
MariaDB的GTID支持同時有多個活躍的Master。通常這種情況發生在多源復制或者環形多主情況下。
在這樣的設置下,每個活躍的Master都必須用友自己獨特的Replication Domain ID,`gtid_domain_id`。然后Binlog實際上就會由多個獨立的數據流組成,每個活躍的Master都有一個。在每個Replication Domain中,每個實例的Binlog順序總是一樣的。但是兩個不同的數據流在不同的實例的Binlog里可能是交錯的。
這樣的話,一個GTID位點不單單是一個單獨的GTID了,它將是每個Domain ID下最后一個執行的Event Group的GTID,實際上這表示了每個Binlog數據流達到的位置。當Slave連上Master的時候,它可以在不同的Binlog位置上繼續復制一個數據流。由于一個數據流內的數據順序在不同實例上是一樣的,這使得Slave可以在任何一個新的Master上找到正確的位點繼續復制。
Domain ID是由DBA按照應用的需要分配的,`@@GLOBAL.gtid_domain_id`的默認值是0。對于大部分的復制場景這都是個合適的值,只要復制拓撲中同時只有一個活躍的Master。MariaDB永遠不會自己寫一個新的domain_id到Binlog中。
當使用多源復制的時候,一個Slave同時會連上多個Master,每個Master都應該配置一個不同的Domain ID。
同樣的,在環形多主復制拓撲結構中,所有的環上所有的Master都會被應用并發寫入(可以通過一些機制來避免沖突,例如區分ID段),每個實例也需要配置不同的Domain ID。(在環形多主情況下,如果應用程序保證同一時刻只會更新一個Master,那么一個Domain ID就夠了)
正常情況下,一個Slave實例不應該直接接受任何更新(這導致了跟Master的Binlog不一致)。因此在Slave上`gtid_domain_id`被設為什么值并不重要,盡管它可能是有意義的,例如把它設置為跟Master一樣(如果不使用多主),來使其更容易把Slave改成新的Master。當然,如果Slave自身是一個活躍的Master,例如在環形多主拓撲中,那么Domain ID還是應該設置的,因為這時候實例的角色是一個活躍的Master。
需要注意的是,Domain ID和Server ID是不同的東西。雖然為每個實例設置不同的Domain ID也是可以的,但這通常不是所希望的情況。這會導致當前的GTID位置(`@@global.gtid_slave_pos`)更難理解,并且失去了所有實例擁有一個一致的Binlog數據流的好處。只建議在每個會被應用同時更新的活躍的Master實例上配置Domain ID。
沒有正確的配置Domain ID本身并不是一個錯誤(比如根本沒配)。例如,一個5.5版本的環形多主復制環境,升級到10.0。這個環可以繼續像之前一樣繼續工作下去,即使所有的實例上Domain ID還是默認值0。甚至有可能還是使用GTID在實例之間復制。然而,當切換Slave的Master時必須小心翼翼,如果Binlog順序在新舊Master不一樣,那么用一個單獨的GTID位置(沒有Domain ID)從新的Master繼續復制,數據就可能出錯。
- 數據庫內核月報目錄
- 數據庫內核月報 - 2016/09
- MySQL · 社區貢獻 · AliSQL那些事兒
- PetaData · 架構體系 · PetaData第二代低成本存儲體系
- MySQL · 社區動態 · MariaDB 10.2 前瞻
- MySQL · 特性分析 · 執行計劃緩存設計與實現
- PgSQL · 最佳實踐 · pg_rman源碼淺析與使用
- MySQL · 捉蟲狀態 · bug分析兩例
- PgSQL · 源碼分析 · PG優化器淺析
- MongoDB · 特性分析· Sharding原理與應用
- PgSQL · 源碼分析 · PG中的無鎖算法和原子操作應用一則
- SQLServer · 最佳實踐 · TEMPDB的設計
- 數據庫內核月報 - 2016/08
- MySQL · 特性分析 ·MySQL 5.7新特性系列四
- PgSQL · PostgreSQL 邏輯流復制技術的秘密
- MySQL · 特性分析 · MyRocks簡介
- GPDB · 特性分析· Greenplum 備份架構
- SQLServer · 最佳實踐 · RDS for SQLServer 2012權限限制提升與改善
- TokuDB · 引擎特性 · REPLACE 語句優化
- MySQL · 專家投稿 · InnoDB物理行中null值的存儲的推斷與驗證
- PgSQL · 實戰經驗 · 旋轉門壓縮算法在PostgreSQL中的實現
- MySQL · 源碼分析 · Query Cache并發處理
- PgSQL · 源碼分析· pg_dump分析
- 數據庫內核月報 - 2016/07
- MySQL · 特性分析 ·MySQL 5.7新特性系列三
- MySQL · 特性分析 · 5.7 代價模型淺析
- PgSQL · 實戰經驗 · 分組TOP性能提升44倍
- MySQL · 源碼分析 · 網絡通信模塊淺析
- MongoDB · 特性分析 · 索引原理
- SQLServer · 特性分析 · XML與JSON應用比較
- MySQL · 最佳實戰 · 審計日志實用案例分析
- MySQL · 性能優化 · 條件下推到物化表
- MySQL · 源碼分析 · Query Cache內部剖析
- MySQL · 捉蟲動態 · 備庫1206錯誤問題說明
- 數據庫內核月報 - 2016/06
- MySQL · 特性分析 · innodb 鎖分裂繼承與遷移
- MySQL · 特性分析 ·MySQL 5.7新特性系列二
- PgSQL · 實戰經驗 · 如何預測Freeze IO風暴
- GPDB · 特性分析· Filespace和Tablespace
- MariaDB · 新特性 · 窗口函數
- MySQL · TokuDB · checkpoint過程
- MySQL · 特性分析 · 內部臨時表
- MySQL · 最佳實踐 · 空間優化
- SQLServer · 最佳實踐 · 數據庫實現大容量插入的幾種方式
- 數據庫內核月報 - 2016/05
- MySQL · 引擎特性 · 基于InnoDB的物理復制實現
- MySQL · 特性分析 · MySQL 5.7新特性系列一
- PostgreSQL · 特性分析 · 邏輯結構和權限體系
- MySQL · 特性分析 · innodb buffer pool相關特性
- PG&GP · 特性分析 · 外部數據導入接口實現分析
- SQLServer · 最佳實踐 · 透明數據加密在SQLServer的應用
- MySQL · TokuDB · 日志子系統和崩潰恢復過程
- MongoDB · 特性分析 · Sharded cluster架構原理
- PostgreSQL · 特性分析 · 統計信息計算方法
- MySQL · 捉蟲動態 · left-join多表導致crash
- 數據庫內核月報 - 2016/04
- MySQL · 參數故事 · innodb_additional_mem_pool_size
- GPDB · 特性分析 · Segment事務一致性與異常處理
- GPDB · 特性分析 · Segment 修復指南
- MySQL · 捉蟲動態 · 并行復制外鍵約束問題二
- PgSQL · 性能優化 · 如何瀟灑的處理每天上百TB的數據增量
- Memcached · 最佳實踐 · 熱點 Key 問題解決方案
- MongoDB · 最佳實踐 · 短連接Auth性能優化
- MySQL · 最佳實踐 · RDS 只讀實例延遲分析
- MySQL · TokuDB · TokuDB索引結構--Fractal Tree
- MySQL · TokuDB · Savepoint漫談
- 數據庫內核月報 - 2016/03
- MySQL · TokuDB · 事務子系統和 MVCC 實現
- MongoDB · 特性分析 · MMAPv1 存儲引擎原理
- PgSQL · 源碼分析 · 優化器邏輯推理
- SQLServer · BUG分析 · Agent 鏈接泄露分析
- Redis · 特性分析 · AOF Rewrite 分析
- MySQL · BUG分析 · Rename table 死鎖分析
- MySQL · 物理備份 · Percona XtraBackup 備份原理
- GPDB · 特性分析· GreenPlum FTS 機制
- MySQL · 答疑解惑 · 備庫Seconds_Behind_Master計算
- MySQL · 答疑解惑 · MySQL 鎖問題最佳實踐
- 數據庫內核月報 - 2016/02
- MySQL · 引擎特性 · InnoDB 文件系統之文件物理結構
- MySQL · 引擎特性 · InnoDB 文件系統之IO系統和內存管理
- MySQL · 特性分析 · InnoDB transaction history
- PgSQL · 會議見聞 · PgConf.Russia 2016 大會總結
- PgSQL · 答疑解惑 · PostgreSQL 9.6 并行查詢實現分析
- MySQL · TokuDB · TokuDB之黑科技工具
- PgSQL · 性能優化 · PostgreSQL TPC-C極限優化玩法
- MariaDB · 版本特性 · MariaDB 的 GTID 介紹
- MySQL · 特性分析 · 線程池
- MySQL · 答疑解惑 · mysqldump tips 兩則
- 數據庫內核月報 - 2016/01
- MySQL · 引擎特性 · InnoDB 事務鎖系統簡介
- GPDB · 特性分析· GreenPlum Primary/Mirror 同步機制
- MySQL · 專家投稿 · MySQL5.7 的 JSON 實現
- MySQL · 特性分析 · 優化器 MRR & BKA
- MySQL · 答疑解惑 · 物理備份死鎖分析
- MySQL · TokuDB · Cachetable 的工作線程和線程池
- MySQL · 特性分析 · drop table的優化
- MySQL · 答疑解惑 · GTID不一致分析
- PgSQL · 特性分析 · Plan Hint
- MariaDB · 社區動態 · MariaDB on Power8 (下)
- 數據庫內核月報 - 2015/12
- MySQL · 引擎特性 · InnoDB 事務子系統介紹
- PgSQL · 特性介紹 · 全文搜索介紹
- MongoDB · 捉蟲動態 · Kill Hang問題排查記錄
- MySQL · 參數優化 ·RDS MySQL參數調優最佳實踐
- PgSQL · 特性分析 · 備庫激活過程分析
- MySQL · TokuDB · 讓Hot Backup更完美
- PgSQL · 答疑解惑 · 表膨脹
- MySQL · 特性分析 · Index Condition Pushdown (ICP)
- MariaDB · 社區動態 · MariaDB on Power8
- MySQL · 特性分析 · 企業版特性一覽
- 數據庫內核月報 - 2015/11
- MySQL · 社區見聞 · OOW 2015 總結 MySQL 篇
- MySQL · 特性分析 · Statement Digest
- PgSQL · 答疑解惑 · PostgreSQL 用戶組權限管理
- MySQL · 特性分析 · MDL 實現分析
- PgSQL · 特性分析 · full page write 機制
- MySQL · 捉蟲動態 · MySQL 外鍵異常分析
- MySQL · 答疑解惑 · MySQL 優化器 range 的代價計算
- MySQL · 捉蟲動態 · ORDER/GROUP BY 導致 mysqld crash
- MySQL · TokuDB · TokuDB 中的行鎖
- MySQL · 捉蟲動態 · order by limit 造成優化器選擇索引錯誤
- 數據庫內核月報 - 2015/10
- MySQL · 引擎特性 · InnoDB 全文索引簡介
- MySQL · 特性分析 · 跟蹤Metadata lock
- MySQL · 答疑解惑 · 索引過濾性太差引起CPU飆高分析
- PgSQL · 特性分析 · PG主備流復制機制
- MySQL · 捉蟲動態 · start slave crash 診斷分析
- MySQL · 捉蟲動態 · 刪除索引導致表無法打開
- PgSQL · 特性分析 · PostgreSQL Aurora方案與DEMO
- TokuDB · 捉蟲動態 · CREATE DATABASE 導致crash問題
- PgSQL · 特性分析 · pg_receivexlog工具解析
- MySQL · 特性分析 · MySQL權限存儲與管理
- 數據庫內核月報 - 2015/09
- MySQL · 引擎特性 · InnoDB Adaptive hash index介紹
- PgSQL · 特性分析 · clog異步提交一致性、原子操作與fsync
- MySQL · 捉蟲動態 · BUG 幾例
- PgSQL · 答疑解惑 · 詭異的函數返回值
- MySQL · 捉蟲動態 · 建表過程中crash造成重建表失敗
- PgSQL · 特性分析 · 談談checkpoint的調度
- MySQL · 特性分析 · 5.6 并行復制恢復實現
- MySQL · 備庫優化 · relay fetch 備庫優化
- MySQL · 特性分析 · 5.6并行復制事件分發機制
- MySQL · TokuDB · 文件目錄談
- 數據庫內核月報 - 2015/08
- MySQL · 社區動態 · InnoDB Page Compression
- PgSQL · 答疑解惑 · RDS中的PostgreSQL備庫延遲原因分析
- MySQL · 社區動態 · MySQL5.6.26 Release Note解讀
- PgSQL · 捉蟲動態 · 執行大SQL語句提示無效的內存申請大小
- MySQL · 社區動態 · MariaDB InnoDB表空間碎片整理
- PgSQL · 答疑解惑 · 歸檔進程cp命令的core文件追查
- MySQL · 答疑解惑 · open file limits
- MySQL · TokuDB · 瘋狂的 filenum++
- MySQL · 功能分析 · 5.6 并行復制實現分析
- MySQL · 功能分析 · MySQL表定義緩存
- 數據庫內核月報 - 2015/07
- MySQL · 引擎特性 · Innodb change buffer介紹
- MySQL · TokuDB · TokuDB Checkpoint機制
- PgSQL · 特性分析 · 時間線解析
- PgSQL · 功能分析 · PostGIS 在 O2O應用中的優勢
- MySQL · 引擎特性 · InnoDB index lock前世今生
- MySQL · 社區動態 · MySQL內存分配支持NUMA
- MySQL · 答疑解惑 · 外鍵刪除bug分析
- MySQL · 引擎特性 · MySQL logical read-ahead
- MySQL · 功能介紹 · binlog拉取速度的控制
- MySQL · 答疑解惑 · 浮點型的顯示問題
- 數據庫內核月報 - 2015/06
- MySQL · 引擎特性 · InnoDB 崩潰恢復過程
- MySQL · 捉蟲動態 · 唯一鍵約束失效
- MySQL · 捉蟲動態 · ALTER IGNORE TABLE導致主備不一致
- MySQL · 答疑解惑 · MySQL Sort 分頁
- MySQL · 答疑解惑 · binlog event 中的 error code
- PgSQL · 功能分析 · Listen/Notify 功能
- MySQL · 捉蟲動態 · 任性的 normal shutdown
- PgSQL · 追根究底 · WAL日志空間的意外增長
- MySQL · 社區動態 · MariaDB Role 體系
- MySQL · TokuDB · TokuDB數據文件大小計算
- 數據庫內核月報 - 2015/05
- MySQL · 引擎特性 · InnoDB redo log漫游
- MySQL · 專家投稿 · MySQL數據庫SYS CPU高的可能性分析
- MySQL · 捉蟲動態 · 5.6 與 5.5 InnoDB 不兼容導致 crash
- MySQL · 答疑解惑 · InnoDB 預讀 VS Oracle 多塊讀
- PgSQL · 社區動態 · 9.5 新功能BRIN索引
- MySQL · 捉蟲動態 · MySQL DDL BUG
- MySQL · 答疑解惑 · set names 都做了什么
- MySQL · 捉蟲動態 · 臨時表操作導致主備不一致
- TokuDB · 引擎特性 · zstd壓縮算法
- MySQL · 答疑解惑 · binlog 位點刷新策略
- 數據庫內核月報 - 2015/04
- MySQL · 引擎特性 · InnoDB undo log 漫游
- TokuDB · 產品新聞 · RDS TokuDB小手冊
- PgSQL · 社區動態 · 說一說PgSQL 9.4.1中的那些安全補丁
- MySQL · 捉蟲動態 · 連接斷開導致XA事務丟失
- MySQL · 捉蟲動態 · GTID下slave_net_timeout值太小問題
- MySQL · 捉蟲動態 · Relay log 中 GTID group 完整性檢測
- MySQL · 答疑釋惑 · UPDATE交換列單表和多表的區別
- MySQL · 捉蟲動態 · 刪被引用索引導致crash
- MySQL · 答疑釋惑 · GTID下auto_position=0時數據不一致
- 數據庫內核月報 - 2015/03
- MySQL · 答疑釋惑· 并發Replace into導致的死鎖分析
- MySQL · 性能優化· 5.7.6 InnoDB page flush 優化
- MySQL · 捉蟲動態· pid file丟失問題分析
- MySQL · 答疑釋惑· using filesort VS using temporary
- MySQL · 優化限制· MySQL index_condition_pushdown
- MySQL · 捉蟲動態·DROP DATABASE外鍵約束的GTID BUG
- MySQL · 答疑釋惑· lower_case_table_names 使用問題
- PgSQL · 特性分析· Logical Decoding探索
- PgSQL · 特性分析· jsonb類型解析
- TokuDB ·引擎機制· TokuDB線程池
- 數據庫內核月報 - 2015/02
- MySQL · 性能優化· InnoDB buffer pool flush策略漫談
- MySQL · 社區動態· 5.6.23 InnoDB相關Bugfix
- PgSQL · 特性分析· Replication Slot
- PgSQL · 特性分析· pg_prewarm
- MySQL · 答疑釋惑· InnoDB丟失自增值
- MySQL · 答疑釋惑· 5.5 和 5.6 時間類型兼容問題
- MySQL · 捉蟲動態· 變量修改導致binlog錯誤
- MariaDB · 特性分析· 表/表空間加密
- MariaDB · 特性分析· Per-query variables
- TokuDB · 特性分析· 日志詳解
- 數據庫內核月報 - 2015/01
- MySQL · 性能優化· Group Commit優化
- MySQL · 新增特性· DDL fast fail
- MySQL · 性能優化· 啟用GTID場景的性能問題及優化
- MySQL · 捉蟲動態· InnoDB自增列重復值問題
- MySQL · 優化改進· 復制性能改進過程
- MySQL · 談古論今· key分區算法演變分析
- MySQL · 捉蟲動態· mysql client crash一例
- MySQL · 捉蟲動態· 設置 gtid_purged 破壞AUTO_POSITION復制協議
- MySQL · 捉蟲動態· replicate filter 和 GTID 一起使用的問題
- TokuDB·特性分析· Optimize Table
- 數據庫內核月報 - 2014/12
- MySQL· 性能優化·5.7 Innodb事務系統
- MySQL· 踩過的坑·5.6 GTID 和存儲引擎那會事
- MySQL· 性能優化·thread pool 原理分析
- MySQL· 性能優化·并行復制外建約束問題
- MySQL· 答疑釋惑·binlog event有序性
- MySQL· 答疑釋惑·server_id為0的Rotate
- MySQL· 性能優化·Bulk Load for CREATE INDEX
- MySQL· 捉蟲動態·Opened tables block read only
- MySQL· 優化改進· GTID啟動優化
- TokuDB· Binary Log Group Commit with TokuDB
- 數據庫內核月報 - 2014/11
- MySQL· 捉蟲動態·OPTIMIZE 不存在的表
- MySQL· 捉蟲動態·SIGHUP 導致 binlog 寫錯
- MySQL· 5.7改進·Recovery改進
- MySQL· 5.7特性·高可用支持
- MySQL· 5.7優化·Metadata Lock子系統的優化
- MySQL· 5.7特性·在線Truncate undo log 表空間
- MySQL· 性能優化·hash_scan 算法的實現解析
- TokuDB· 版本優化· 7.5.0
- TokuDB· 引擎特性· FAST UPDATES
- MariaDB· 性能優化·filesort with small LIMIT optimization
- 數據庫內核月報 - 2014/10
- MySQL· 5.7重構·Optimizer Cost Model
- MySQL· 系統限制·text字段數
- MySQL· 捉蟲動態·binlog重放失敗
- MySQL· 捉蟲動態·從庫OOM
- MySQL· 捉蟲動態·崩潰恢復失敗
- MySQL· 功能改進·InnoDB Warmup特性
- MySQL· 文件結構·告別frm文件
- MariaDB· 新鮮特性·ANALYZE statement 語法
- TokuDB· 主備復制·Read Free Replication
- TokuDB· 引擎特性·壓縮
- 數據庫內核月報 - 2014/09
- MySQL· 捉蟲動態·GTID 和 DELAYED
- MySQL· 限制改進·GTID和升級
- MySQL· 捉蟲動態·GTID 和 binlog_checksum
- MySQL· 引擎差異·create_time in status
- MySQL· 參數故事·thread_concurrency
- MySQL· 捉蟲動態·auto_increment
- MariaDB· 性能優化·Extended Keys
- MariaDB·主備復制·CREATE OR REPLACE
- TokuDB· 參數故事·數據安全和性能
- TokuDB· HA方案·TokuDB熱備
- 數據庫內核月報 - 2014/08
- MySQL· 參數故事·timed_mutexes
- MySQL· 參數故事·innodb_flush_log_at_trx_commit
- MySQL· 捉蟲動態·Count(Distinct) ERROR
- MySQL· 捉蟲動態·mysqldump BUFFER OVERFLOW
- MySQL· 捉蟲動態·long semaphore waits
- MariaDB·分支特性·支持大于16K的InnoDB Page Size
- MariaDB·分支特性·FusionIO特性支持
- TokuDB· 性能優化·Bulk Fetch
- TokuDB· 數據結構·Fractal-Trees與LSM-Trees對比
- TokuDB·社區八卦·TokuDB團隊