此處的big sql指的是單條sql的size 超過innodb_log_file_size,通過構造這樣的測試,來分析mysql的提交過程。
做這個分析的起因是我不是很明白,既然mysql需要將被執行的資料首先寫入到redo log file,如果sql 的size 超過innodb_log_file_size的設定,會發生什麼樣的行為,mysql是否會拒絕這樣的big sql?
首先將答案丟擲:mysql能夠吃下這樣的大sql,並順利執行。
1 sql 提交時,mysql伺服器首先通過引數max_allowed_packet檢查sql的size,如果超出,則直接提示mysql go away.
2 server從儲存將需要修改的資料page load到innodb_buffer_pool(受制於innodb_buffer_pool_size)。
3 寫data page,同時寫redo undo log.(undo log 負責備份未修改前的資料,redo負責備份修改後的資料)
4 如果sql size 超過redo undo log 的buffer設定(innodb_log_buffer_size)則:redo undo log 寫入磁碟檔案log file,如果此時log file也滿,則將部分data寫入磁碟,然後清空對應的log file。(猜測)
這樣的變化可以通過引數innodb_log_waits (show global status)觀察到。
因此,一般情況下,redo log 先於data 落盤,但是在big sql這種提交方式下,是資料先落盤,redo log 後落盤,在這個例子中,redo log是沒有任何意義的,因為它已經無法完整了(猜測)。
5 當 commit 發生時,一般來說,mysql 會首先提交reod log 到磁碟,但是針對這樣的情況,應該首先提交資料更為合理。
一些自己的理解,肯定有不合理的地方,期待更好的解釋。
步驟:1 建立測試表
big 字段型別為longblob,它的最大容量是4g.
create table `tb_cobranding_test` (
`id` int(10) unsigned default null,
`base64_content_big` longblob
) engine=innodb default charset=utf8
2 修改mysql配置:
innodb_log_file_size=5m
innodb_log_files_in_group=2
max_allowed_packet=512m
修改innodb_log_file_size 前需要遷移之前的log file 檔案.
3 提交big sql:
insert into tb_cobranding_test values (1,'此處為190m的二進位制字串');
mysql <./big.sql
mysql的提交問題
1 mysql的自動提交設定autocommit,是預設開啟的,每條sql都會開啟乙個事務,自動提交一次,show variables like autocommit 大量sql語句批量執行時,比如1w條update語句,autocommit on,則同時鎖住的行少,但是頻繁commit,db資源占...
mysql5 7組提交 mysql組提交
當mysql開啟binlog日誌時,會存在乙個內部xa的問題 事務在儲存引擎層redo log的寫入和binlog的寫入一致性問題。mysql通過兩階段提交很好的解決了redo log和binlog一致性問題 第一階段 innodb prepare,持有prepare commit mutex,re...
mysql趟過的坑
q 使用limit報錯,如select from table where id in select id from table limit 12 會報this version of mysql doesn t yet support limit in all any some subquery a ...