在前面兩期月報中,我們詳細介紹了 InnoDB redo log 和 undo log 的相關知識,本文將介紹 InnoDB 在崩潰恢復時的主要流程。
本文代碼分析基于 MySQL 5.7.7-RC 版本,函數入口為?`innobase_start_or_create_for_mysql`,這是一個非常冗長的函數,本文只涉及和崩潰恢復相關的代碼。
在閱讀本文前,強烈建議翻閱我們之前的兩期月報:
1.?[MySQL · 引擎特性 · InnoDB undo log 漫游](http://mysql.taobao.org/monthly/2015/04/01/)
2.?[MySQL · 引擎特性 · InnoDB redo log漫游](http://mysql.taobao.org/monthly/2015/05/01/)
## 初始化崩潰恢復
首先初始化崩潰恢復所需要的內存對象:
~~~
recv_sys_create();
recv_sys_init(buf_pool_get_curr_size());
~~~
當InnoDB正常shutdown,在flush redo log 和臟頁后,會做一次完全同步的checkpoint,并將checkpoint的LSN寫到ibdata的第一個page中(`fil_write_flushed_lsn`)。
在重啟實例時,會打開系統表空間ibdata,并讀取存儲在其中的LSN:
~~~
err = srv_sys_space.open_or_create(
false, &sum_of_new_sizes, &flushed_lsn);
~~~
上述調用將從ibdata中讀取的LSN存儲到變量flushed_lsn中,表示上次shutdown時的checkpoint點,在后面做崩潰恢復時會用到。另外這里也會將double write buffer內存儲的page載入到內存中(`buf_dblwr_init_or_load_pages`),如果ibdata的第一個page損壞了,就從dblwr中恢復出來。
> Tips:注意在MySQL 5.6.16之前的版本中,如果InnoDB的表空間第一個page損壞了,就認為無法確定這個表空間的space id,也就無法決定使用dblwr中的哪個page來進行恢復,InnoDB將崩潰恢復失敗(bug#70087),
> 由于每個數據頁上都存儲著表空間id,因此后面將這里的邏輯修改成往后多讀幾個page,并嘗試不同的page size,直到找到一個完好的數據頁, (參考函數`Datafile::find_space_id()`)。因此為了能安全的使用double write buffer保護數據,建議使用5.6.16及之后的MySQL版本。
## 恢復truncate操作
為了保證對 undo log 獨立表空間和用戶獨立表空間進行 truncate 操作的原子性,InnoDB 采用文件日志的方式為每個 truncate 操作創建一個獨特的文件,如果在重啟時這個文件存在,說明上次 truncate 操作還沒完成實例就崩潰了,在重啟時,我們需要繼續完成truncate操作。
這一塊的崩潰恢復是獨立于redo log系統之外的。
對于 undo log 表空間恢復,在初始化 undo 子系統時完成:
~~~
err = srv_undo_tablespaces_init(
create_new_db,
srv_undo_tablespaces,
&srv_undo_tablespaces_open);
~~~
對于用戶表空間,掃描數據目錄,找到 truncate 日志文件:如果文件中沒有任何數據,表示truncate還沒開始;如果文件中已經寫了一個MAGIC NUM,表示truncate操作已經完成了;這兩種情況都不需要處理。
~~~
err = TruncateLogParser::scan_and_parse(srv_log_group_home_dir);
~~~
但對用戶表空間truncate操作的恢復是redo log apply完成后才進行的,這主要是因為恢復truncate可能涉及到系統表的更新操作(例如重建索引),需要在redo apply完成后才能進行。
## 進入redo崩潰恢復開始邏輯
入口函數:
`c err = recv_recovery_from_checkpoint_start(flushed_lsn);`
傳遞的參數flushed_lsn即為從ibdata第一個page讀取的LSN,主要包含以下幾步:
Step 1: 為每個buffer pool instance創建一棵紅黑樹,指向`buffer_pool_t::flush_rbt`,主要用于加速插入flush list (`buf_flush_init_flush_rbt`);
Step 2: 讀取存儲在第一個redo log文件頭的CHECKPOINT LSN,并根據該LSN定位到redo日志文件中對應的位置,從該checkpoint點開始掃描。
在這里會調用三次`recv_group_scan_log_recs`掃描redo log文件:
1\. 第一次的目的是找到MLOG_CHECKPOINT日志
MLOG_CHECKPOINT 日志中記錄了CHECKPOINT LSN,當該日志中記錄的LSN和日志頭中記錄的CHECKPOINT LSN相同時,表示找到了符合的MLOG_CHECKPOINT LSN,將掃描到的LSN號記錄到?`recv_sys->mlog_checkpoint_lsn`?中。(在5.6版本里沒有這一次掃描)
MLOG_CHECKPOINT在[WL#7142](http://dev.mysql.com/worklog/task/?id=7142)中被引入,其目的是為了簡化 InnoDB 崩潰恢復的邏輯,根據WL#7142的描述,包含幾點改進:
1. 避免崩潰恢復時讀取每個ibd的第一個page來確認其space id;
2. 無需檢查$datadir/*.isl,新的日志類型記錄了文件全路徑,并消除了isl文件和實際ibd目錄的不一致可能帶來的問題;
3. 自動忽略那些還沒有導入到InnoDB的ibd文件(例如在執行IMPORT TABLESPACE時crash);
4. 引入了新的日志類型MLOG_FILE_DELETE來跟蹤ibd文件的刪除操作。
這里可能會產生的問題是,如果MLOG_CHECKPOINT日志和文件頭記錄的CHECKPOINT LSN差距太遠的話,在第一次掃描時可能花費大量的時間做無謂的解析,感覺這里還有優化的空間。
在我的測試實例中,由于崩潰時施加的負載比較大,MLOG_CHECKPOINT和CHECKPOINT點的LSN相差約1G的redo log。
2\. 第二次掃描,再次從checkpoint點開始重復掃描,存儲日志對象
日志解析后的對象類型為`recv_t`,包含日志類型、長度、數據、開始和結束LSN。日志對象的存儲使用hash結構,根據 space id 和 page no 計算hash值,相同頁上的變更作為鏈表節點鏈在一起,大概結構可以表示為:

掃描的過程中,會基于MLOG_FILE_NAME 和MLOG_FILE_DELETE 這樣的redo日志記錄來構建`recv_spaces`,存儲space id到文件信息的映射(`fil_name_parse`?–>?`fil_name_process`),這些文件可能需要進行崩潰恢復。(實際上第一次掃描時,也會向`recv_spaces`中插入數據,但只到MLOG_CHECKPOINT日志記錄為止)
> Tips:在一次checkpoint后第一次修改某個表的數據時,總是先寫一條MLOG_FILE_NAME 日志記錄;通過該類型的日志可以跟蹤一次CHECKPOINT后修改過的表空間,避免打開全部表。
> 在第二次掃描時,總會判斷將要修改的表空間是否在`recv_spaces`中,如果不存在,則認為產生列嚴重的錯誤,拒絕啟動(`recv_parse_or_apply_log_rec_body`)
默認情況下,Redo log以一批64KB(RECV_SCAN_SIZE)為單位讀入到`log_sys->buf`中,然后調用函數`recv_scan_log_recs`處理日志塊。這里會判斷到日志塊的有效性:是否是完整寫入的、日志塊checksum是否正確, 另外也會根據一些標記位來做判斷:
* 在每次寫入redo log時,總會將寫入的起始block頭的flush bit設置為true,表示一次寫入的起始位置,因此在重啟掃描日志時,也會根據flush bit來推進掃描的LSN點;
* 每次寫redo時,還會在每個block上記錄下一個checkpoint no(每次做checkpoint都會遞增),由于日志文件是循環使用的,因此需要根據checkpoint no判斷是否讀到了老舊的redo日志。
對于合法的日志,會拷貝到緩沖區`recv_sys->buf`中,調用函數`recv_parse_log_recs`解析日志記錄。 這里會根據不同的日志類型分別進行處理,并嘗試進行apply,堆棧為:
~~~
recv_parse_log_recs
--> recv_parse_log_rec
--> recv_parse_or_apply_log_rec_body
~~~
如果想理解InnoDB如何基于不同的日志類型進行崩潰恢復的,非常有必要細讀函數`recv_parse_or_apply_log_rec_body`,這里是redo日志apply的入口。
例如如果解析到的日志類型為MLOG_UNDO_HDR_CREATE,就會從日志中解析出事務ID,為其重建undo log頭(`trx_undo_parse_page_header`);如果是一條插入操作標識(MLOG_REC_INSERT 或者 MLOG_COMP_REC_INSERT),就需要從中解析出索引信息(`mlog_parse_index`)和記錄信息(`page_cur_parse_insert_rec`);或者解析一條IN-PLACE UPDATE (MLOG_REC_UPDATE_IN_PLACE)日志,則調用函數`btr_cur_parse_update_in_place`。
第二次掃描只會應用MLOG_FILE_*類型的日志,記錄到`recv_spaces`中,對于其他類型的日志在解析后存儲到哈希對象里。然后調用函數`recv_init_crash_recovery_spaces`對涉及的表空間進行初始化處理:
* 首先會打印兩條我們非常熟悉的日志信息:
~~~
[Note] InnoDB: Database was not shutdown normally!
[Note] InnoDB: Starting crash recovery.
~~~
* 如果`recv_spaces`中的表空間未被刪除,且ibd文件存在時,則表明這是個普通的文件操作,將該table space加入到`fil_system->named_spaces`鏈表上(`fil_names_dirty`),后續可能會對這些表做redo apply操作;
* 對于已經被刪除的表空間,我們可以忽略日志apply,將對應表的space id在`recv_sys->addr_hash`上的記錄項設置為RECV_DISCARDED;
* 調用函數`buf_dblwr_process()`,該函數會檢查所有記錄在double write buffer中的page,其對應的數據文件頁是否完好,如果損壞了,則直接從dblwr中恢復;
* 最后創建一個臨時的后臺線程,線程函數為`recv_writer_thread`,這個線程和page cleaner線程配合使用,它會去通知page cleaner線程去flush崩潰恢復產生的臟頁,直到`recv_sys`中存儲的redo記錄都被應用完成并徹底釋放掉(`recv_sys->heap == NULL`)
3\. 如果第二次掃描hash表空間不足,無法全部存儲到hash表中,則發起第三次掃描,清空hash,重新從checkpoint點開始掃描。
hash對象的空間最大一般為buffer pool size - 512個page大小。
第三次掃描不會嘗試一起全部存儲到hash里,而是一旦發現hash不夠了,就立刻apply redo日志。但是…如果總的日志需要存儲的hash空間略大于可用的最大空間,那么一次額外的掃描開銷還是非常明顯的。
簡而言之,第一次掃描找到正確的MLOG_CHECKPOINT位置;第二次掃描解析 redo 日志并存儲到hash中;如果hash空間不夠用,則再來一輪重新開始,解析一批,應用一批。
三次掃描后,hash中通常還有redo日志沒有被應用掉。這個留在后面來做,隨后將`recv_sys->apply_log_recs`?設置為true,并從函數`recv_recovery_from_checkpoint_start`返回。
對于正常shutdown的場景,一次checkpoint完成后是不記錄MLOG_CHECKPOINT日志的,如果掃描過程中沒有找到對應的日志,那就認為上次是正常shutdown的,不用考慮崩潰恢復了。
> Tips:偶爾我們會看到日志中報類似這樣的信息:
> “The log sequence number xxx in the system tablespace does not match the log sequence number xxxx in the ib_logfiles!”
> 從內部邏輯來看是因為ibdata中記錄的lsn和iblogfile中記錄的checkpoint lsn不一致,但系統又判定無需崩潰恢復時會報這樣的錯。單純從InnoDB實例來看是可能的,因為做checkpint 和更新ibdata不是原子的操作,這樣的日志信息一般我們也是可以忽略的。
## 初始化事務子系統(trx_sys_init_at_db_start)
這里會涉及到讀入undo相關的系統頁數據,在崩潰恢復狀態下,所有的page都要先進行日志apply后,才能被調用者使用,例如如下堆棧:
~~~
trx_sys_init_at_db_start
--> trx_sysf_get -->
....->buf_page_io_complete --> recv_recover_page
~~~
因此在初始化回滾段的時候,我們通過讀入回滾段頁并進行redo log apply,就可以將回滾段信息恢復到一致的狀態,從而能夠 “復活”在系統崩潰時活躍的事務,維護到讀寫事務鏈表中。對于處于prepare狀態的事務,我們后續需要做額外處理。
關于事務如何從崩潰恢復中復活,參閱4月份的月報 “[MySQL · 引擎特性 · InnoDB undo log 漫游](http://mysql.taobao.org/monthly/2015/05/01/)“最后一節。
## 應用redo日志(`recv_apply_hashed_log_recs`)
根據之前搜集到`recv_sys->addr_hash`中的日志記錄,依次將page讀入內存,并對每個page進行崩潰恢復操作(`recv_recover_page_func`):
* 已經被刪除的表空間,直接跳過其對應的日志記錄;
* 在讀入需要恢復的文件頁時,會主動嘗試采用預讀的方式多讀點page (`recv_read_in_area`),搜集最多連續32個(RECV_READ_AHEAD_AREA)需要做恢復的page no,然后發送異步讀請求。 page 讀入buffer pool時,會主動做崩潰恢復邏輯;
* 只有LSN大于數據頁上LSN的日志才會被apply; 忽略被truncate的表的redo日志;
* 在恢復數據頁的過程中不產生新的redo 日志;
* 在完成修復page后,需要將臟頁加入到buffer pool的flush list上;由于innodb需要保證flush list的有序性,而崩潰恢復過程中修改page的LSN是基于redo 的LSN而不是全局的LSN,無法保證有序性;InnoDB另外維護了一顆紅黑樹來維持有序性,每次插入到flush list前,查找紅黑樹找到合適的插入位置,然后加入到flush list上。(`buf_flush_recv_note_modification`)
## 完成崩潰恢復(`recv_recovery_from_checkpoint_finish`)
在完成所有redo日志apply后,基本的崩潰恢復也完成了,此時可以釋放資源,等待recv writer線程退出 (崩潰恢復產生的臟頁已經被清理掉),釋放紅黑樹,回滾所有數據詞典操作產生的非prepare狀態的事務 (`trx_rollback_or_clean_recovered`)
### 無效數據清理及事務回滾:
調用函數`recv_recovery_rollback_active`完成下述工作:
* 刪除臨時創建的索引,例如在DDL創建索引時crash時的殘留臨時索引(`row_merge_drop_temp_indexes()`);
* 清理InnoDB臨時表 (`row_mysql_drop_temp_tables`);
* 清理全文索引的無效的輔助表(`fts_drop_orphaned_tables()`);
* 創建后臺線程,線程函數為`trx_rollback_or_clean_all_recovered`,和在`recv_recovery_from_checkpoint_finish`中的調用不同,該后臺線程會回滾所有不處于prepare狀態的事務。
至此InnoDB層的崩潰恢復算是告一段落,只剩下處于prepare狀態的事務還有待處理,而這一部分需要和Server層的binlog聯合來進行崩潰恢復。
## Binlog/InnoDB XA Recover
回到Server層,在初始化完了各個存儲引擎后,如果binlog打開了,我們就可以通過binlog來進行XA恢復:
* 首先掃描最后一個binlog文件,找到其中所有的XID事件,并將其中的XID記錄到一個hash結構中(`MYSQL_BIN_LOG::recover`);
* 然后對每個引擎調用接口函數`xarecover_handlerton`, 拿到每個事務引擎中處于prepare狀態的事務xid,如果這個xid存在于binlog中,則提交;否則回滾事務。
很顯然,如果我們弱化配置的持久性(`innodb_flush_log_at_trx_commit != 1`?或者?`sync_binlog != 1`), 宕機可能導致兩種丟數據的場景:
1. 引擎層提交了,但binlog沒寫入,備庫丟事務;
2. 引擎層沒有prepare,但binlog寫入了,主庫丟事務。
即使我們將參數設置成`innodb_flush_log_at_trx_commit =1`?和?`sync_binlog = 1`,也還會面臨這樣一種情況:主庫crash時還有binlog沒傳遞到備庫,如果我們直接提升備庫為主庫,同樣會導致主備不一致,老主庫必須根據新主庫重做,才能恢復到一致的狀態。針對這種場景,我們可以通過開啟semisync的方式來解決,一種可行的方案描述如下:
1. 設置雙1強持久化配置;
2. 我們將semisync的超時時間設到極大值,同時使用semisync AFTER_SYNC模式,即用戶線程在寫入binlog后,引擎層提交前等待備庫ACK;
3. 基于步驟1的配置,我們可以保證在主庫crash時,所有老主庫比備庫多出來的事務都處于prepare狀態;
4. 備庫完全apply日志后,記下其執行到的relay log對應的位點,然后將備庫提升為新主庫;
5. 將老主庫的最后一個binlog進行截斷,截斷的位點即為步驟3記錄的位點;
6. 啟動老主庫,那些已經傳遞到備庫的事務都會提交掉,未傳遞到備庫的binlog都會回滾掉。
- 數據庫內核月報目錄
- 數據庫內核月報 - 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團隊