為什麼需要雙重封裝?
MySQL 需跨平台(Linux/Windows)運行,檔案操作抽象層:
- 標準 C 庫:
open/close/read/write/seek — POSIX 相容,Linux 原生
- Win32 API:
CreateFile/CloseHandle/ReadFile/WriteFile/SetFilePointer — Windows 原生
兩套 API 功能對等,但 Win32 將「檔案」概念擴展為:檔案、通訊裝置、命名管道、信箱、磁碟、主控台 — 統一用 CreateFile 開啟。
Win32 非同步 I/O 關鍵優勢
HANDLE CreateFile(
LPCTSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes, // 關鍵:FILE_FLAG_OVERLAPPED
HANDLE hTemplateFile
);
- 指定
FILE_FLAG_OVERLAPPED → ReadFile/WriteFile 變為非同步
- 非同步:呼叫立即返回,I/O 在背景完成,執行緒可處理其他工作
- 同步:呼叫阻塞直到完成,執行緒閒置
- 高併發資料庫引擎必須使用非同步 I/O 避免執行緒耗盡
標準 C 庫 vs Win32 API 對照表
| 操作 | 標準 C (POSIX) | Win32 API |
| 開啟/建立 | open() | CreateFile() |
| 關閉 | close() | CloseHandle() |
| 讀取 | read() | ReadFile() |
| 寫入 | write() | WriteFile() |
| 定位 | lseek() | SetFilePointer() |
| 同步/非同步 | 預設同步;aio_read 非標準 | FILE_FLAG_OVERLAPPED 原生非同步 |
MySQL 原始碼中的實作策略
my_win_file.c:Win32 實作,大量使用 OVERLAPPED 結構與 GetOverlappedResult
my_file.c:POSIX 實作,依賴 OS 快取與 pread/pwrite(Linux 2.6+ 原生非同步)
- 統一介面:
my_open/my_close/my_read/my_write/my_seek,上層引擎無感知平台差異
啟發:應用層也可封裝非同步檔案 I/O
- .NET:
FileStream(FileOptions.Asynchronous) + BeginRead/EndRead 或 await ReadAsync
- Java:
AsynchronousFileChannel (NIO.2)
- C++:Boost.Asio / Windows IOCP / Linux io_uring
- 核心模式:發起 → 註冊回調/Future → 事件迴圈/執行緒池處理完成
總結
MySQL 的雙重封裝不僅為跨平台,更為在 Windows 上榨乾非同步 I/O 效能。資料庫核心與高效能應用同樣受益於「非阻塞 I/O + 事件驅動」架構。
- 上一篇文章: SQL Server 2000 設計表自動編號欄位:IDENTITY、SEED/INCREMENT 與 DBCC RESEED 完整指南
- 下一篇文章: SQL 查詢與刪除重複記錄:單欄位、多欄位、ROW_NUMBER、CTE、游標五大方案全解析
Copyright ©
程式碼之家 All Rights Reserved