首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL LONGBLOB 存儲二進制數據:Prepared Statement 分片傳輸 650MB 實測

     編輯:MySQL 資料庫相關知識

對比 LONGTEXT 方案,LONGBLOB + mysql_stmt_send_long_data 以二進制協議分片傳輸,無需轉義、內存峰值僅為分片大小,是大文件入庫的正規軍姿勢。

表結構

CREATE DATABASE test;
USE test;
CREATE TABLE bintest (
    id INT AUTO_INCREMENT PRIMARY KEY,
    data LONGBLOB
) ENGINE=InnoDB;

核心流程

  1. mysql_stmt_init() → mysql_stmt_prepare() 準備 INSERT INTO bintest(data) VALUES(?)。
  2. MYSQL_BIND 綁定參數:buffer_type=MYSQL_TYPE_BLOB,length 指向 unsigned long 變量。
  3. mysql_stmt_bind_param() 綁定。
  4. 分片循環:mysql_stmt_send_long_data(stmt, 0, chunk_ptr, chunk_len) 發送數據片段(可多次調用)。
  5. mysql_stmt_execute() 執行寫入。

關鍵代碼

MYSQL_STMT *stmt = mysql_stmt_init(mysql);
mysql_stmt_prepare(stmt, "INSERT INTO bintest(data) VALUES(?)", ...);

MYSQL_BIND bind[1] = {0};
bind[0].buffer_type = MYSQL_TYPE_BLOB;
bind[0].buffer = chunk_buf;
bind[0].length = &chunk_len;
bind[0].is_null = 0;
mysql_stmt_bind_param(stmt, bind);

while (bytes_read = fread(chunk_buf, 1, CHUNK_SIZE, fp)) {
    mysql_stmt_send_long_data(stmt, 0, chunk_buf, bytes_read);
}
mysql_stmt_execute(stmt);

配置同樣關鍵

[mysqld]
max_allowed_packet = 1024M
innodb_log_file_size = 256M  -- 大事務需大 redo log

修改 innodb_log_file_size 需停庫、刪除 ib_logfile*、重啟。

優勢對比

維度LONGTEXT + escapeLONGBLOB + stmt
內存峰值2×文件大小分片大小(如 1MB)
CPU 開銷轉義/反轉義零拷貝二進制
SQL 注入風險理論存在參數化天然免疫
代碼複雜度低中

生產建議

  • 分片大小 1~4MB 平衡網絡 RTT 與內存。
  • 配合 innodb_flush_log_at_trx_commit=2 降低刷盤壓力(可接受 1s 數據丟失)。
  • 文件元數據(名稱、哈希、大小、業務 ID)另存關聯表,bintest 僅存純二進制。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved