據(jù)庫大賽備賽全攻略:內(nèi)核實(shí)戰(zhàn)與性能優(yōu)化)
簡(jiǎn)介本資源為2025年第五屆全國(guó)大學(xué)生計(jì)算機(jī)系統(tǒng)能力大賽——OceanBase數(shù)據(jù)庫大賽官方配套技術(shù)資料包面向高校計(jì)算機(jī)及相關(guān)專業(yè)本科生聚焦數(shù)據(jù)庫內(nèi)核原理、分布式系統(tǒng)實(shí)踐與工程化開發(fā)能力培養(yǎng)。資源共2000個(gè)文件涵蓋468個(gè)C/C頭文件h/hxx/hpp與716個(gè)源碼文件cpp/cc/c支撐OceanBase核心模塊編譯與調(diào)試含133個(gè)Markdown文檔md提供賽題說明、環(huán)境搭建指南與API參考96個(gè)Python腳本py用于自動(dòng)化測(cè)試與數(shù)據(jù)校驗(yàn)另有大量JSON配置、YML部署模板、CMake構(gòu)建文件及測(cè)試用例in/expected/sample完整復(fù)現(xiàn)競(jìng)賽開發(fā)與驗(yàn)證閉環(huán)。壓縮包大小113.94MB目錄結(jié)構(gòu)層次清晰適合作為數(shù)據(jù)庫系統(tǒng)課程設(shè)計(jì)、畢業(yè)設(shè)計(jì)或競(jìng)賽備賽的實(shí)戰(zhàn)基線代碼庫。目前已有49人學(xué)習(xí)下載可直接用于源碼閱讀、模塊修改、性能調(diào)優(yōu)與故障注入等深度實(shí)踐。1. 大賽概況一場(chǎng)面向數(shù)據(jù)庫內(nèi)核的硬核挑戰(zhàn)1.1 比賽是什么為什么值得打2025 全國(guó)大學(xué)生計(jì)算機(jī)系統(tǒng)能力大賽第五屆 OceanBase 數(shù)據(jù)庫大賽本質(zhì)上是給在校學(xué)生準(zhǔn)備的一場(chǎng)數(shù)據(jù)庫內(nèi)核實(shí)戰(zhàn)訓(xùn)練營(yíng)。主辦方把 OceanBase 這個(gè)成熟分布式數(shù)據(jù)庫的源碼和測(cè)試框架交到你手里讓你在有限時(shí)間內(nèi)完成指定的功能開發(fā)或性能優(yōu)化任務(wù)最后用系統(tǒng)跑分和代碼質(zhì)量說話。這個(gè)比賽和常見的背八股競(jìng)賽完全不同。你寫的是要真正跑起來的存儲(chǔ)、事務(wù)、SQL 引擎代碼不是提交一份設(shè)計(jì)方案。對(duì)我來說它最吸引人的地方在于這是少數(shù)幾個(gè)能在學(xué)生階段直接接觸工業(yè)級(jí)數(shù)據(jù)庫源碼的窗口。OceanBase 的代碼量級(jí)、工程規(guī)范、模塊設(shè)計(jì)和你在課本里看的教學(xué)數(shù)據(jù)庫完全是兩回事。哪怕最后沒拿獎(jiǎng)把源碼啃一遍對(duì)數(shù)據(jù)庫的理解深度都會(huì)上一個(gè)臺(tái)階。適合誰來打我的判斷是計(jì)算機(jī)、軟件工程相關(guān)專業(yè)學(xué)過數(shù)據(jù)庫原理和操作系統(tǒng)至少熟悉 C 或 Rust 中一門同時(shí)對(duì)分布式系統(tǒng)有好奇心的人。如果你只寫過業(yè)務(wù) CRUD沒碰過系統(tǒng)級(jí)代碼這個(gè)比賽會(huì)有點(diǎn)吃力但也不是完全沒法打——前提是你愿意花時(shí)間補(bǔ)基礎(chǔ)。反過來如果你已經(jīng)對(duì) LSM-Tree、MVCC、兩階段提交這些概念有基本認(rèn)識(shí)那這個(gè)比賽就是你把理論變成代碼的最佳實(shí)驗(yàn)場(chǎng)。1.2 賽制與評(píng)分機(jī)制解讀賽制通常分初賽和決賽兩個(gè)階段。初賽以線上提交代碼、系統(tǒng)自動(dòng)評(píng)測(cè)為主。評(píng)測(cè)維度一般包括功能正確性、性能指標(biāo)、資源占用等指標(biāo)。題目會(huì)在賽前公布選手需要在規(guī)定時(shí)間內(nèi)完成代碼修改并提交系統(tǒng)會(huì)對(duì)你的實(shí)現(xiàn)跑測(cè)試用例給出一份實(shí)時(shí)排名。決賽通常是線下答辯加現(xiàn)場(chǎng)優(yōu)化除了跑分還要講清楚設(shè)計(jì)思路和優(yōu)化手段。我特別提醒第一次參賽的朋友注意一個(gè)點(diǎn)初賽排名不是只看最終跑分很多時(shí)候還有最小提交間隔代碼評(píng)審之類的軟性約束。這意味著你不能只在最后一天堆代碼。系統(tǒng)對(duì)提交次數(shù)也可能有限制亂提交刷分會(huì)直接扣分甚至取消資格。建議把提交當(dāng)作一種有限的評(píng)測(cè)資源來管理想清楚了再提交。評(píng)分機(jī)制背后的核心邏輯是考驗(yàn)?zāi)阍诠こ碳s束下做權(quán)衡的能力。OceanBase 的代碼已經(jīng)很成熟了你做的修改必須既有正確性又不能破壞原有架構(gòu)的穩(wěn)定性。也就是說粗暴的魔改可能會(huì)在某個(gè)性能指標(biāo)上拿了高分但代碼評(píng)審一關(guān)就被打回去。這種系統(tǒng)思維工程規(guī)范的考核方式也是它能進(jìn)入計(jì)算機(jī)系統(tǒng)能力大賽序列的根本原因。1.3 和其他數(shù)據(jù)庫比賽的橫向?qū)Ρ仁忻嫔蠑?shù)據(jù)庫類比賽不少有的側(cè)重 TiDB、有的側(cè)重大數(shù)據(jù)組件但 OceanBase 大賽有幾個(gè)明顯特點(diǎn)。第一它強(qiáng)調(diào)內(nèi)核開發(fā)不是簡(jiǎn)單的調(diào)參比賽。第二它提供了完整的源碼環(huán)境和調(diào)試工具鏈等于把生產(chǎn)級(jí)代碼庫開放給你們。第三OceanBase 同時(shí)兼容 MySQL 和 Oracle 兩種模式意味著你要處理的問題覆蓋面很廣從 SQL 語法解析到事務(wù)隔離級(jí)別都可能踩到。我對(duì)比過其他同類賽事很多比賽更像填空題——在給定的幾個(gè)函數(shù)里補(bǔ)全邏輯跑通就完事。OceanBase 大賽更像項(xiàng)目制開發(fā)你需要自己定位問題、設(shè)計(jì)解法、驗(yàn)證效果。這種開放性對(duì)初學(xué)者來說門檻更高但對(duì)真正想往數(shù)據(jù)庫內(nèi)核方向走的人反而是最有價(jià)值的訓(xùn)練。備賽過程中接觸到的模塊劃分、日志系統(tǒng)、測(cè)試框架都是可以直接寫進(jìn)簡(jiǎn)歷的經(jīng)驗(yàn)。2. 核心考察點(diǎn)拆解你會(huì)在哪些模塊上做文章2.1 SQL 引擎從解析到執(zhí)行的完整鏈路SQL 引擎是初賽題目的高頻出題點(diǎn)。它的基本鏈路是客戶端輸入 SQL經(jīng)過詞法分析、語法分析生成邏輯計(jì)劃再經(jīng)過優(yōu)化器生成物理計(jì)劃最后交給執(zhí)行器去跑。OceanBase 的 SQL 引擎同時(shí)支持 MySQL 和 Oracle 模式所以你會(huì)看到大量兼容性相關(guān)的邏輯比如兩種模式下日期函數(shù)的行為差異、字符串排序規(guī)則、隱式類型轉(zhuǎn)換規(guī)則等。如果你在備賽時(shí)接到這類題目我建議先花時(shí)間看懂三塊代碼SQL 解析器的語法文件通常用 yacc 語法描述、優(yōu)化器的規(guī)則框架、執(zhí)行器的算子實(shí)現(xiàn)。不用全部吃透但要搞清楚一條 SQL 從進(jìn)入到返回結(jié)果需要經(jīng)過哪些核心類。實(shí)際操作中你可以在代碼里加日志跑幾條簡(jiǎn)單 SQL把流程打印出來對(duì)著看比悶頭讀代碼快得多。2.2 存儲(chǔ)引擎LSM-Tree 與數(shù)據(jù)落盤機(jī)制存儲(chǔ)引擎是 OceanBase 最核心的模塊之一。它采用 LSM-Tree 架構(gòu)寫入先進(jìn)內(nèi)存中的 MemTable達(dá)到閾值后凍結(jié)、轉(zhuǎn)儲(chǔ)到 SSTable后臺(tái)再定期做 compaction 合并。這套機(jī)制決定了數(shù)據(jù)庫的寫性能也帶來了讀放大的問題——一次讀取可能要查多個(gè) SSTable所以你需要理解布隆過濾器、索引、塊緩存這些配套機(jī)制是怎么工作的。從比賽角度存儲(chǔ)引擎常見的優(yōu)化方向包括調(diào)整 compaction 觸發(fā)策略、優(yōu)化編碼壓縮算法、改進(jìn)掃描性能、減少空間放大等。我記得有一年賽題跟合并minor merge策略有關(guān)需要在性能和穩(wěn)定性之間做取舍。這類題目如果你不了解 LSM-Tree 的原理很容易拿著表面參數(shù)亂調(diào)效果大概率適得其反。我的建議是先把《數(shù)據(jù)庫系統(tǒng)實(shí)現(xiàn)》和《Designing Data-Intensive Applications》里關(guān)于 LSM 的章節(jié)吃透再動(dòng)手改代碼。2.3 事務(wù)處理與并發(fā)控制隔離級(jí)別、鎖與分布式事務(wù)事務(wù)模塊是拉開差距的地方。OceanBase 實(shí)現(xiàn)了多種隔離級(jí)別包括 MySQL 模式下的可重復(fù)讀、Oracle 模式下的已提交讀。它采用 MVCC鎖的混合方案讀操作走快照寫操作需要加鎖。還有一套分布式事務(wù)處理框架用兩階段提交保證跨節(jié)點(diǎn)事務(wù)的原子性。這里的考察點(diǎn)可能是某個(gè)隔離級(jí)別下的事務(wù)并發(fā)行為異常需要你修復(fù)隔離性漏洞也可能是某個(gè)鎖等待場(chǎng)景出現(xiàn)死鎖需要你優(yōu)化加鎖順序甚至可能是分布式事務(wù)提交效率太低需要你優(yōu)化協(xié)調(diào)者邏輯。無論哪種你都得先建立起事務(wù)并發(fā)控制的整體心智模型。否則你看代碼就像看天書。我建議備賽時(shí)畫一張狀態(tài)圖把事務(wù)從開始到提交/回滾的所有狀態(tài)轉(zhuǎn)換、鎖獲取時(shí)機(jī)、版本可見性判斷條件列出來后面所有問題都往這張圖上套。2.4 性能優(yōu)化與資源管理內(nèi)存、線程、緩存除了功能開發(fā)性能評(píng)測(cè)也是重頭戲。性能優(yōu)化不像功能題那樣有一條明確的對(duì)錯(cuò)線它更考驗(yàn)?zāi)銓?duì)系統(tǒng)瓶頸的敏感度。常見的性能優(yōu)化方向包括內(nèi)存分配器調(diào)優(yōu)、線程池參數(shù)調(diào)整、緩存命中率優(yōu)化、SQL 執(zhí)行計(jì)劃優(yōu)化等。這里有個(gè)容易踩的坑很多同學(xué)一上來就在代碼里加各種花哨的優(yōu)化結(jié)果 benchmark 數(shù)據(jù)反而更難看了。因?yàn)楝F(xiàn)代 CPU 架構(gòu)下性能問題往往出在緩存失效、偽共享、鎖競(jìng)爭(zhēng)這些底層因素而不是算法本身。我見過有選手為了優(yōu)化一個(gè)查詢重寫了排序算法結(jié)果因?yàn)橐肓祟~外的內(nèi)存拷貝吞吐量反而下降 20%。性能優(yōu)化一定要用 profiler 說話不要靠猜。OceanBase 的代碼庫本身帶了一些性能統(tǒng)計(jì)工具評(píng)測(cè)環(huán)境也會(huì)提供 profile 結(jié)果你要學(xué)會(huì)看這些數(shù)據(jù)找瓶頸。3. 實(shí)操過程從零到提交一份靠譜的作品3.1 環(huán)境準(zhǔn)備與工具鏈搭建拿到題目第一步先把環(huán)境搭起來。OceanBase 的部署不復(fù)雜但有一些細(xì)節(jié)需要注意。建議直接用官方提供的 OceanBase DeployerOBD工具部署一個(gè)單機(jī)版實(shí)例然后在同一臺(tái)機(jī)器上準(zhǔn)備好源碼編譯環(huán)境。有一個(gè)容易忽略的點(diǎn)是依賴庫版本比如 libaio、numactl、jemalloc 這些版本不對(duì)可能導(dǎo)致編譯失敗或運(yùn)行時(shí)性能異常。調(diào)試工具鏈里我重點(diǎn)推薦三樣GDB多線程調(diào)試必備、Perf性能采樣、以及 dtrace 或 bpftrace如果你在 Linux 上跑。比賽過程中你可能要排查各種詭異的并發(fā)問題沒有這幾個(gè)工具會(huì)很痛苦。代碼閱讀工具的話我習(xí)慣用 VS Code 或者 CLion但說實(shí)話OceanBase 的代碼規(guī)模用 IDE 打開會(huì)有點(diǎn)卡建議把代碼索引打開然后搭配 grep 和 ctags 快速定位符號(hào)。環(huán)境搭好之后運(yùn)行自帶的測(cè)試套件確保基線是綠的通過狀態(tài)。這一條太重要了。我見過太多選手沒跑基線就跑題結(jié)果環(huán)境問題被當(dāng)成代碼問題排查了幾天。基線綠了之后再開始看題這是最穩(wěn)妥的節(jié)奏。3.2 源碼閱讀路徑與模塊定位方法OceanBase 的源碼目錄劃分清晰你需要把主要的模塊目錄記下來。比如 observer 目錄是數(shù)據(jù)庫主進(jìn)程代碼storage 目錄是存儲(chǔ)引擎sql 目錄是 SQL 引擎transaction 目錄是事務(wù)模塊share 目錄是共享組件等。拿到題目后第一件事就是判斷它命中哪個(gè)模塊然后快速鎖定代碼范圍。我自己的經(jīng)驗(yàn)是三步走定位代碼第一步用題目里的關(guān)鍵詞在代碼庫全局搜索比如題目出現(xiàn)了轉(zhuǎn)儲(chǔ)就搜 minor freeze、major freeze、sstable dump 這些相關(guān)關(guān)鍵詞第二步跑一個(gè)最小復(fù)現(xiàn)用例打斷點(diǎn)或者加日志看代碼執(zhí)行路徑第三步從入口函數(shù)往調(diào)用棧下層走逐步縮小問題范圍。這個(gè)方法比逐行通讀源碼高效得多。有一種情況比較麻煩題目涉及跨模塊調(diào)用。比如一個(gè) SQL 性能問題根因可能在存儲(chǔ)層也可能在執(zhí)行器層還可能是優(yōu)化器生成了糟糕的執(zhí)行計(jì)劃。這種問題要在多個(gè)模塊之間來回跳容易迷路。我的建議是先在紙上畫出調(diào)用鏈的大致走向確認(rèn)所有涉及模塊的入口和出口再逐層排查。千萬別拿著代碼瞎轉(zhuǎn)效率極低。3.3 一個(gè)具體題目從分析到落地的全流程示例我以一道模擬題為例詳細(xì)講講整個(gè)流程實(shí)際比賽題目結(jié)構(gòu)類似但具體細(xì)節(jié)不同。假設(shè)題目是優(yōu)化一條包含多表 JOIN 的查詢?cè)谔囟〝?shù)據(jù)集上的執(zhí)行性能要求在保證結(jié)果正確的前提下盡量縮短查詢響應(yīng)時(shí)間。第一步定位。在 SQL 引擎層跑這條查詢用 EXPLAIN 拿到執(zhí)行計(jì)劃看看表連接順序、連接算法、是否走索引。如果發(fā)現(xiàn)是嵌套循環(huán)連接且一張表很大一張表很小那就應(yīng)該改為哈希連接。但 OceanBase 的優(yōu)化器不一定總能做出最優(yōu)選擇有時(shí)候要用 hint 強(qiáng)制改變執(zhí)行計(jì)劃。第二步驗(yàn)證假設(shè)。手動(dòng)改寫 SQL 加 hint跑一遍看時(shí)間是否縮短。如果明顯縮短說明優(yōu)化器選型確實(shí)有問題需要到優(yōu)化器代碼里找原因。可能是統(tǒng)計(jì)信息不準(zhǔn)導(dǎo)致基數(shù)估計(jì)偏差很大也可能是 cost model 的權(quán)重參數(shù)設(shè)置不合理。第三步修改代碼。如果問題在統(tǒng)計(jì)信息可以看看表統(tǒng)計(jì)信息更新的觸發(fā)條件和采樣策略。如果問題在 cost model找到算子代價(jià)計(jì)算的函數(shù)調(diào)整相應(yīng)權(quán)重。這個(gè)階段要注意改動(dòng)越局部越好不要牽一發(fā)動(dòng)全身。第四步回歸測(cè)試。跑功能的測(cè)試用例確保正確性不受影響。再跑性能測(cè)試對(duì)比修改前后的耗時(shí)。最后在正式評(píng)測(cè)環(huán)境提交前再做幾輪壓力測(cè)試確認(rèn)沒有內(nèi)存泄漏、并發(fā)問題等隱患。整個(gè)流程走下來你會(huì)發(fā)現(xiàn)真正的挑戰(zhàn)不是某一環(huán)而是如何快速定位問題、驗(yàn)證假設(shè)、控制變更風(fēng)險(xiǎn)。這正是比賽最有收獲的部分。3.4 性能調(diào)優(yōu)的常用工具與指標(biāo)判讀性能調(diào)優(yōu)階段我會(huì)用 perf 做 CPU 熱點(diǎn)采樣用 OceanBase 自帶的內(nèi)部視圖查等待事件、緩存命中率等指標(biāo)。舉幾個(gè)關(guān)鍵指標(biāo)的例子緩存命中率如果低于 95%可能說明表數(shù)據(jù)量太大而緩存太小L0/L1 層 SSTable 數(shù)量過多可能導(dǎo)致讀放大嚴(yán)重memstore 內(nèi)存使用超過閾值可能導(dǎo)致寫入停滯。我還習(xí)慣在代碼里臨時(shí)加一些計(jì)數(shù)器和耗時(shí)埋點(diǎn)比如統(tǒng)計(jì)一次查詢?cè)诮馕觥?yōu)化、執(zhí)行各階段分別花了多少時(shí)間。注意這些埋點(diǎn)代碼提交前一定要清理干凈否則評(píng)測(cè)系統(tǒng)可能因?yàn)轭~外的開銷導(dǎo)致分?jǐn)?shù)下降甚至有作弊嫌疑。優(yōu)化是迭代過程每次只改一個(gè)變量跑一輪測(cè)試記錄結(jié)果再改下一個(gè)。一次性改多個(gè)變量出了問題你根本不知道是哪個(gè)改動(dòng)引起的。4. 備賽路上的常見問題和實(shí)用解決技巧4.1 編譯環(huán)境問題和依賴版本沖突怎么解決編譯 OceanBase 源碼可能是很多人遇到的第一個(gè)坎。官方文檔給的依賴列表是最低要求實(shí)際操作中你會(huì)發(fā)現(xiàn)各發(fā)行版系統(tǒng)的包管理器里的版本可能不夠用。比如 glibc 版本太老編譯時(shí)直接報(bào)錯(cuò)jemalloc 版本不一致運(yùn)行時(shí)就出現(xiàn)詭異的內(nèi)存問題。我踩過一次很深的坑在官方推薦的 Linux 發(fā)行版上用系統(tǒng)自帶的 gcc 編譯鏈接階段報(bào)了一堆 undefined reference。后來發(fā)現(xiàn)是編譯器版本太舊不支持代碼里用到的一些新特性。解決辦法是換用官方提供的 devtoolset 或者手動(dòng)安裝新版 gcc。還有一次是編譯通過但運(yùn)行時(shí)崩潰排查了大半天發(fā)現(xiàn)是系統(tǒng)字符集設(shè)置問題和代碼沒有任何關(guān)系。所以建議是嚴(yán)格按照官方文檔的發(fā)行版版本來搭建環(huán)境不要自創(chuàng)環(huán)境不要用太新的內(nèi)核和編譯器組合也不要為了追求性能而加亂七八糟的編譯參數(shù)。穩(wěn)定的環(huán)境比炫技重要得多。4.2 性能優(yōu)化的常見誤區(qū)和評(píng)測(cè)環(huán)境陷阱性能優(yōu)化最大的誤區(qū)是用感覺代替測(cè)量。有人覺得某個(gè)熱點(diǎn)函數(shù)用了內(nèi)存拷貝就一定要優(yōu)化但實(shí)測(cè)發(fā)現(xiàn)它根本不是瓶頸有人覺得多線程就能提性能結(jié)果線程切換開銷抵消了收益。我建議所有優(yōu)化都圍繞 profiler 數(shù)據(jù)展開量化每一步的收益不要做沒有數(shù)據(jù)支撐的盲改。評(píng)測(cè)環(huán)境的另一個(gè)陷阱是你的代碼在本地跑得很快不代表在評(píng)測(cè)機(jī)上也快。評(píng)測(cè)機(jī)可能有不同的 CPU 頻率、核數(shù)、內(nèi)存帶寬還有與其他選手共享資源的可能。所以寫完代碼后盡量在接近評(píng)測(cè)環(huán)境的條件下測(cè)試比如限制 CPU 核數(shù)、內(nèi)存大小等。我曾在本地 16 核機(jī)器上調(diào)優(yōu)到一個(gè)不錯(cuò)的效果換了評(píng)測(cè)機(jī) 8 核環(huán)境就跑不過別人原因是我沒考慮核數(shù)變化對(duì)線程池并發(fā)度的影響。這些都是需要在備賽時(shí)就考慮到的。4.3 遇到死鎖、數(shù)據(jù)不一致等疑難 bug 時(shí)怎么辦這類問題最熬人但也最漲經(jīng)驗(yàn)。我的調(diào)試方法是三板斧第一步復(fù)現(xiàn)問題拿到穩(wěn)定復(fù)現(xiàn)的最小用例第二步打開日志和 trace盡量定位到觸發(fā)路徑第三步用 GDB 附加到進(jìn)程在關(guān)鍵函數(shù)下斷點(diǎn)單步調(diào)試或觀察變量快照。如果能在測(cè)試環(huán)境穩(wěn)定復(fù)現(xiàn)問題基本都能解決最怕的是偶現(xiàn)問題那種只能靠日志和概率復(fù)現(xiàn)慢慢磨。調(diào)試死鎖時(shí)有一個(gè)技巧在鎖獲取的地方打印線程 ID、鎖地址和持有時(shí)間跑一段時(shí)間后分析日志就能畫出鎖等待圖。定位到環(huán)之后再想想為什么會(huì)出現(xiàn)環(huán)是鎖順序不一致還是鎖粒度太大。數(shù)據(jù)庫里的死鎖很多時(shí)候和事務(wù)加鎖順序有關(guān)你要結(jié)合事務(wù)執(zhí)行計(jì)劃分析加鎖邏輯。這里有個(gè)經(jīng)驗(yàn)之談在代碼里加上鎖順序的斷言開發(fā)階段就能發(fā)現(xiàn)大部分問題比運(yùn)行時(shí)報(bào)死鎖再處理效率高得多。4.4 常見問題速查表問題現(xiàn)象可能原因排查手段編譯鏈接失敗編譯器版本過舊 / 依賴庫缺失檢查 gcc 版本、安裝完整依賴、查看 CMake 日志部署后實(shí)例啟動(dòng)失敗配置參數(shù)錯(cuò)誤 / 端口被占用查看 observer.log、確認(rèn)端口占用、核對(duì)配置項(xiàng)性能評(píng)測(cè)分?jǐn)?shù)低線程池配置不當(dāng) / 緩存命中率低用 perf 采樣、查內(nèi)部視圖指標(biāo)、調(diào)整參數(shù)偶現(xiàn)崩潰內(nèi)存越界 / 多線程數(shù)據(jù)競(jìng)爭(zhēng)用 ASAN 編譯、加日志復(fù)現(xiàn)、GDB 分析 core 文件查詢結(jié)果錯(cuò)誤優(yōu)化器選型錯(cuò)誤 / 并行執(zhí)行問題對(duì)比 EXPLAIN 計(jì)劃、關(guān)閉并行重跑、逐算子驗(yàn)證死鎖加鎖順序不一致 / 隔離級(jí)別設(shè)置異常分析鎖等待日志、檢查事務(wù)加鎖路徑這張表不是標(biāo)準(zhǔn)答案但它可能是比賽過程中最常見的六大問題方向。你還會(huì)遇到更奇怪的 bug但思路是一致的縮小范圍、穩(wěn)定復(fù)現(xiàn)、分而治之。5. 復(fù)盤與個(gè)人建議5.1 參賽帶來的收獲不只是代碼能力打完這個(gè)比賽我的一個(gè)深刻感受是寫業(yè)務(wù)代碼和寫數(shù)據(jù)庫內(nèi)核代碼是完全不同的思維方式。業(yè)務(wù)代碼講究快速迭代而內(nèi)核代碼追求的是極端條件下的穩(wěn)定性和可預(yù)測(cè)性。你會(huì)開始關(guān)注一個(gè)整數(shù)溢出會(huì)不會(huì)被惡意構(gòu)造的 SQL 觸發(fā)、一個(gè)并發(fā)場(chǎng)景下會(huì)不會(huì)出現(xiàn) ABA 問題、一個(gè)緩存未命中會(huì)讓性能下降多少倍。這些細(xì)節(jié)意識(shí)是日常開發(fā)很難鍛煉出來的。數(shù)據(jù)庫內(nèi)核圈子里有一句話懂?dāng)?shù)據(jù)庫原理的人很多但真正改過數(shù)據(jù)庫的人很少。在 OceanBase 大賽的經(jīng)歷相當(dāng)于把數(shù)據(jù)庫原理從概念變成了你親手敲過、調(diào)試過、性能調(diào)優(yōu)過的代碼。面試時(shí)你能聊的東西完全不是一個(gè)層次。好多拿了名次的選手后來都進(jìn)入了數(shù)據(jù)庫或基礎(chǔ)軟件相關(guān)的團(tuán)隊(duì)這條路確實(shí)走得通。5.2 適合在比賽前掌握的知識(shí)清單如果你是零基礎(chǔ)沖比賽的選手我的建議是先把這些知識(shí)過一遍再動(dòng)手寫代碼數(shù)據(jù)結(jié)構(gòu)與算法基礎(chǔ)B 樹、跳表、哈希表、排序、歸并等。操作系統(tǒng)進(jìn)程與線程、內(nèi)存管理、文件 IO、鎖與條件變量。數(shù)據(jù)庫原理SQL 執(zhí)行流程、事務(wù) ACID、隔離級(jí)別、MVCC、鎖機(jī)制、日志與恢復(fù)。分布式系統(tǒng)基礎(chǔ)一致性、兩階段提交、Paxos/Raft 的工程實(shí)現(xiàn)。C 語言特性智能指針、模板、右值引用、并發(fā)編程。這些知識(shí)不需要全部精通但至少要達(dá)到看到代碼能認(rèn)出它在干什么的程度。在此基礎(chǔ)上再啃 OceanBase 的核心源碼就順很多。你也可以先跑一遍 OceanBase 官方的開發(fā)者文檔和入門教程特別是部署、SQL 基本操作、存儲(chǔ)架構(gòu)這些章節(jié)。把理論模型先建立起來再深入代碼細(xì)節(jié)比我一開始就投身源碼、看得云里霧里要高效得多。我的個(gè)人教訓(xùn)是第一次接觸時(shí)我太著急了直接去讀底層存儲(chǔ)代碼結(jié)果各種術(shù)語和概念根本對(duì)不上號(hào)。后來老老實(shí)實(shí)按文檔從整體架構(gòu)入手再回頭看代碼一下子通透了。5.3 未來的擴(kuò)展方向比賽結(jié)束后如果你對(duì)這個(gè)方向還有興趣可以繼續(xù)研究一下 OceanBase 的社區(qū)版源碼看看最新版本里引入了哪些新特性。也可以嘗試復(fù)現(xiàn)一些數(shù)據(jù)庫論文中的算法比如更高效的 compaction 策略、更智能的索引推薦、KV 分離存儲(chǔ)等。基礎(chǔ)軟件這個(gè)領(lǐng)域動(dòng)手實(shí)踐是遞進(jìn)式進(jìn)步的源泉。一臺(tái)機(jī)器、一個(gè)開源數(shù)據(jù)庫、加上一點(diǎn)耐心和死磕精神就能做出很漂亮的項(xiàng)目。這也是我這些年做技術(shù)一路走下來感受最深的一點(diǎn)。本文還有配套的精品資源點(diǎn)擊獲取