MySQL8.0 DDL原子性特性及實(shí)現(xiàn)原理
1. DDL原子性概述
8.0之前并沒有統(tǒng)一的數(shù)據(jù)字典dd,server層和引擎層各有一套元數(shù)據(jù),sever層的元數(shù)據(jù)包括(.frm,.opt,.par,.trg等),用于存儲(chǔ)表定義,分區(qū)表定義,觸發(fā)器定義等信息;innodb層也有自己一套元數(shù)據(jù),包括表信息,索引信息等,這兩套元數(shù)據(jù)并沒有機(jī)制保證一致性,這就導(dǎo)致了在異常情況下可能存在元數(shù)據(jù)不一致問題,一種典型場景下,刪表操作,sever層的frm已經(jīng)成功刪除了,但引擎層數(shù)據(jù)字典并沒有更新,導(dǎo)致再建重名表失敗的問題。同樣的,比如drop table t1,t2;可能出現(xiàn)只刪除了t1,而t2仍然存在等問題。
8.0的一個(gè)重要工作是將數(shù)據(jù)字典統(tǒng)一,獨(dú)立了DD(數(shù)據(jù)字典)模塊,廢棄了server層的元數(shù)據(jù),將innodb的元數(shù)據(jù)抽象出一條DD接口供server層和innnodb層公用。在DD的基礎(chǔ)上,引入了DDL的原子性特性,確保DDL操作要么全做,要么全不做的能力。實(shí)現(xiàn)這一套邏輯的關(guān)鍵點(diǎn)在于將ddl涉及到的修改,包括dd數(shù)據(jù)字典修改,引擎層的修改(創(chuàng)建文件,初始化tablespace,創(chuàng)建btree等)和寫binlog作為一個(gè)“事務(wù)”,利用事務(wù)的原子性特點(diǎn)來保證ddl操作的原子性。
2.DDL原子性實(shí)現(xiàn)原理
實(shí)現(xiàn)原子性的關(guān)鍵在于確保dd數(shù)據(jù)字典修改,引擎層的修改和寫binlog是一個(gè)事務(wù)。MySQL已有的XA事務(wù)機(jī)制能有效保證DML事務(wù)和binlog的一致性。而ddl數(shù)據(jù)字典也是通過innodb引擎存儲(chǔ),因此做到dd數(shù)據(jù)字典修改和binlog一致是容易的;那么還需要解決的一個(gè)問題是,dd數(shù)據(jù)字典和引擎層修改的一致性,引擎層的修改并不都是記redo的,比如創(chuàng)建文件,rename文件名,或者清理cache等,無法簡單地通過XA機(jī)制解決問題,因此8.0還引入了一套DDL_LOG機(jī)制。具體而言,就是將不記redo的一些操作,通過記日志的方式寫入到ddl_log表中,而這個(gè)表是innodb引擎表,通過保證ddl_log數(shù)據(jù)與dd數(shù)據(jù)字典修改達(dá)成一致,而最終解決dd數(shù)據(jù)字典修改,引擎層的修改和寫binlog一致性問題。
3.DD引入前后對(duì)比
4.DDL操作實(shí)現(xiàn)邏輯
引入ddl_log表后,ddl操作在原有的基礎(chǔ)上有一些變化,主要有兩點(diǎn),一點(diǎn)是在執(zhí)行ddl的過程中,會(huì)記錄ddl操作到ddl_log表中;另一點(diǎn)是新增了一個(gè)post_ddl階段,ddl事務(wù)提交后,做一些ddl的收尾動(dòng)作,比如drop-table,真正的刪除物理文件是在post-ddl階段做的。post-ddl做的事情主要就是,讀取ddl-log內(nèi)容,進(jìn)行回放執(zhí)行。ddl操作類型如下:
enum class Log_Type : uint32_t { /** Smallest log type */ SMALLEST_LOG = 1, /** Drop an index tree */ FREE_TREE_LOG = 1, /** Delete a file */ DELETE_SPACE_LOG, /** Rename a file */ RENAME_SPACE_LOG, /** Drop the entry in innodb_dynamic_metadata */ DROP_LOG, /** Rename table in dict cache. */ RENAME_TABLE_LOG, /** Remove a table from dict cache */ REMOVE_CACHE_LOG, /** Alter Encrypt a tablespace */ ALTER_ENCRYPT_TABLESPACE_LOG, /** Biggest log type */ BIGGEST_LOG = ALTER_ENCRYPT_TABLESPACE_LOG };
通過innodb_print_ddl_logs開關(guān),可以看到ddl過程中寫入到innodb_ddl_log表中的內(nèi)容。下面會(huì)以幾個(gè)典型的ddl操作產(chǎn)生的ddl_log來說明如何保證ddl的原子性。
4.1 create table
語句:create table dd_tt(id int primary key, c1 int);
[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=352, thread_id=23, space_id=71, old_file_path=./mysql/dd_tt.ibd] [InnoDB] DDL log delete : 352 [InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=353, thread_id=23, table_id=1128, new_file_path=mysql/dd_tt] [InnoDB] DDL log delete : 353 [InnoDB] DDL log insert : [DDL record: FREE, id=354, thread_id=23, space_id=71, index_id=231, page_no=4] [InnoDB] DDL log delete : 354 [InnoDB] DDL log post ddl : begin for thread id : 23 [InnoDB] DDL log post ddl : end for thread id : 23
說明:
1.所有insert操作都是一個(gè)單獨(dú)的事務(wù),對(duì)應(yīng)的逆向delete操作是整個(gè)ddl事務(wù)的一部分。
2.insert操作記錄的是文件操作的逆向操作,比如建table_space,逆向操作就是delete_space_log。
3.如果ddl事務(wù)最終成功,那么所有逆向delete操作也最終生效,ddl_log日志被正常清理;如果ddl事務(wù)執(zhí)行過程中失敗(比如實(shí)例crash),那么delete操作回滾,ddl_log表中殘留3條insert_log,recover時(shí),replay這些ddl_log,即可以清理ddl過程中產(chǎn)生的垃圾。
4.crash-recovery時(shí),若binlog已經(jīng)落盤,則對(duì)應(yīng)的ddl事務(wù)處于prepare狀態(tài),那么最終事務(wù)要提交,ddl_log被清理干凈;若binlog沒有落盤,則ddl事務(wù)需要回滾,ddl_log表中殘留3條記錄,在故障恢復(fù)結(jié)束后,需要replay這些記錄,實(shí)際上就是建文件,創(chuàng)建btree等逆向操作,確?;貪L后是干凈的。
4.2 drop table
語句:drop table dd_tt;
[InnoDB] DDL log insert : [DDL record: DROP, id=355, thread_id=23, table_id=1128] [InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=356, thread_id=23, space_id=71, old_file_path=./mysql/dd_tt.ibd] [InnoDB] DDL log post ddl : begin for thread id : 23 [InnoDB] DDL log replay : [DDL record: DELETE SPACE, id=356, thread_id=23, space_id=71, old_file_path=./mysql/dd_tt.ibd] [InnoDB] DDL log replay : [DDL record: DROP, id=355, thread_id=23, table_id=1128] [InnoDB] DDL log post ddl : end for thread id : 23
說明:對(duì)于drop操作而言,執(zhí)行過程中只是操作ddl_log,并不做真正的drop物理表操作。在post-ddl階段,會(huì)讀取ddl_log表中的記錄并replay,做真正的刪除動(dòng)作。如果執(zhí)行過程中crash了,那么整個(gè)ddl事務(wù)會(huì)回滾,這其中也包含ddl_log中的內(nèi)容也會(huì)回滾,那么整個(gè)drop操作就相當(dāng)于沒發(fā)生一樣。
4.3 add index
語句:alter table dd_tt add index idx_c1(c1);
[InnoDB] DDL log insert : [DDL record: FREE, id=360, thread_id=23, space_id=72, index_id=233, page_no=5] [InnoDB] DDL log delete : 360 [InnoDB] DDL log post ddl : begin for thread id : 23 [InnoDB] DDL log post ddl : end for thread id : 23
說明: 建索引與建表類似,insert操作部分是一個(gè)事務(wù),單獨(dú)提交,配套會(huì)記錄一個(gè)delete操作,這個(gè)操作是整個(gè)ddl事務(wù)的一部分,事務(wù)如果最終提交,那么ddl-log內(nèi)容被刪除;如果事務(wù)最終回滾,那么ddl-log中會(huì)殘留一條FREE-log,通過replay則可以清理建好的索引,達(dá)到回滾的效果。
4.4 drop index
語句:alter table dd_tt drop index idx_c1;
[InnoDB] DDL log insert : [DDL record: FREE, id=361, thread_id=23, space_id=72, index_id=233, page_no=5] [InnoDB] DDL log post ddl : begin for thread id : 23 [InnoDB] DDL log replay : [DDL record: FREE, id=361, thread_id=23, space_id=72, index_id=233, page_no=5] [InnoDB] DDL log post ddl : end for thread id : 23
說明:
與drop table類似,執(zhí)行過程中只記錄日志,在post-ddl階段才進(jìn)行真正的刪除操作。
4.5 add column
語句:alter table dd_tt add column c2 int;
[InnoDB] DDL log post ddl : begin for thread id : 23 [InnoDB] DDL log post ddl : end for thread id : 23
說明:
8.0加列是instant-ddl,只修改元數(shù)據(jù),與dml事務(wù)類似,不依賴ddl-log保證原子性。
4.6 drop column
語句:alter table dd_tt drop column c2;
語句分解:
1.prepare階段:
create table #sql-ib1129-2815969725; [InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=362, thread_id=23, space_id=73, old_file_path=./mysql/#sql-ib1129-2815969725.ibd] [InnoDB] DDL log delete : 362 [InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=363, thread_id=23, table_id=1130, new_file_path=mysql/#sql-ib1129-2815969725] [InnoDB] DDL log delete : 363 [InnoDB] DDL log insert : [DDL record: FREE, id=364, thread_id=23, space_id=73, index_id=234, page_no=4] [InnoDB] DDL log delete : 364
2.peform階段:nothing about ddl-log
3.commit階段:
3.1 alter table dd_tt rename to #sql-ib1130-2815969726;
[InnoDB] DDL log insert : [DDL record: DROP, id=365, thread_id=23, table_id=1129] <br>[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=366, thread_id=23, space_id=72, old_file_path=./mysql/#sql-ib1130-2815969726.ibd, new_file_path=./mysql/dd_tt.ibd] [InnoDB] DDL log delete : 366 [InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=367, thread_id=23, table_id=1129, old_file_path=mysql/#sql-ib1130-2815969726, new_file_path=mysql/dd_tt] [InnoDB] DDL log delete : 367
逆向操作:alter table mysql/#sql-ib1130-2815969726 rename to dd_tt;
3.2 alter table #sql-ib1129-2815969725 rename to dd_tt;
[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=368, thread_id=23, space_id=73, old_file_path=./mysql/dd_tt.ibd, new_file_path=./mysql/#sql-ib1129-2815969725.ibd] [InnoDB] DDL log delete : 368 [InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=369, thread_id=23, table_id=1130, old_file_path=mysql/dd_tt, new_file_path=mysql/#sql-ib1129-2815969725] [InnoDB] DDL log delete : 369
逆向操作:alter table dd_tt rename to mysql/#sql-ib1129-2815969725;
[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=368, thread_id=23, space_id=73, old_file_path=./mysql/dd_tt.ibd, new_file_path=./mysql/#sql-ib1129-2815969725.ibd] [InnoDB] DDL log delete : 368 [InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=369, thread_id=23, table_id=1130, old_file_path=mysql/dd_tt, new_file_path=mysql/#sql-ib1129-2815969725] [InnoDB] DDL log delete : 369
僅僅記錄操作,在post-ddl階段才做清理。
post-ddl階段:
drop table #sql-ib1130-2815969726; [InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=368, thread_id=23, space_id=73, old_file_path=./mysql/dd_tt.ibd, new_file_path=./mysql/#sql-ib1129-2815969725.ibd] [InnoDB] DDL log delete : 368 [InnoDB] DDL log insert : [DDL record: RENAME TABLE, id=369, thread_id=23, table_id=1130, old_file_path=mysql/dd_tt, new_file_path=mysql/#sql-ib1129-2815969725] [InnoDB] DDL log delete : 369
說明:drop column是copy類型的ddl,基本邏輯是新建一張臨時(shí)表,拷貝數(shù)據(jù),最后再進(jìn)行一次rename操作。主要包括4個(gè)階段:
1.prepare階段:建臨時(shí)表的過程與建表過程的ddl-log操作類似,insert-log作為單獨(dú)事務(wù)直接提交,delete-log是整個(gè)事務(wù)的一部分。
這個(gè)階段如果出現(xiàn)異常,ddl-log表中殘留了逆操作記錄,crash-recovery時(shí),可以在replay實(shí)現(xiàn)清理。
2.peform階段: 拷貝數(shù)據(jù)結(jié)束,實(shí)現(xiàn)online-ddl邏輯。
3.拷貝數(shù)據(jù)結(jié)束后,需要進(jìn)行rename交換表名操作。
1)DROP,刪除臨時(shí)表
2)RENAME SPACE/TABLE 將./mysql/#sql-ib1130-2815969726.ibd 重命名為dd_tt.idb
3)REANAME SPACE/TABLE 將dd_tt.idb重名為/#sql-ib1129-2815969725.idb
4)記錄刪除舊表sql-ib1130-2815969726.ibd操作,post-ddl階段做真正的刪除。
如果這個(gè)階段出現(xiàn)異常,同樣的insert-log單獨(dú)一個(gè)事務(wù),delete作為整個(gè)事務(wù)的一部分,insert-log會(huì)殘留在ddl-log表中,通過replay可以做清理,還原dd_tt的數(shù)據(jù),并清理臨時(shí)表#sql-ib1130-2815969726.ibd。
4.post-ddl階段:
1).物理刪除舊文件./mysql/#sql-ib1130-2815969726.ibd
2).清理mysql.innodb_dynamic_metadata中相關(guān)信息。
需要注意的是,由于ddl-log表存放的內(nèi)容實(shí)際上逆向操作,所以搜集ddl-log時(shí),實(shí)際上是逆序搜集回放的。
4.7 truncate table
語句:truncate table dd_tt;
語句分解:
1.rename dd_tt to #sql-ib1130-2815969727;
[InnoDB] DDL log insert : [DDL record: RENAME SPACE, id=372, thread_id=23, space_id=73, old_file_path=./mysql/#sql-ib1130-2815969727.ibd, new_file_path=./mysql/dd_tt.ibd [InnoDB] DDL log delete : 372
2.drop table #sql-ib1130-2815969727;
[InnoDB] DDL log insert : [DDL record: DROP, id=373, thread_id=23, table_id=1130] [InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=374, thread_id=23, space_id=73, old_file_path=./mysql/#sql-ib1130-2815969727.ibd]
3.create table dd_tt;
[InnoDB] DDL log insert : [DDL record: DELETE SPACE, id=375, thread_id=23, space_id=74, old_file_path=./mysql/dd_tt.ibd] [InnoDB] DDL log delete : 375 [InnoDB] DDL log insert : [DDL record: REMOVE CACHE, id=376, thread_id=23, table_id=1131, new_file_path=mysql/dd_tt] [InnoDB] DDL log delete : 376 [InnoDB] DDL log insert : [DDL record: FREE, id=377, thread_id=23, space_id=74, index_id=235, page_no=4] [InnoDB] DDL log delete : 377 [InnoDB] DDL log post ddl : begin for thread id : 23 [InnoDB] DDL log replay : [DDL record: DELETE SPACE, id=374, thread_id=23, space_id=73, old_file_path=./mysql/#sql-ib1130-2815969727.ibd] [InnoDB] DDL log replay : [DDL record: DROP, id=373, thread_id=23, table_id=1130] [InnoDB] DDL log post ddl : end for thread id : 23
說明:
1.將dd_tt重命名為sql-ib1130-2815969727
2.標(biāo)記sql-ib1130-2815969727表刪除,post-ddl階段才真正刪除
3.新建表dd_tt,同樣的insert操作是作為單獨(dú)事務(wù)提交,delete操作是整個(gè)事務(wù)的一部分,如果回滾,最終殘留了insert操作,通過replay動(dòng)作清理。
5.DDL操作代碼堆棧
5.1 create-table
Sql_cmd_create_table::execute -->mysql_create_table -->mysql_create_table_no_lock -->create_table_impl -->rea_create_base_table -->ha_create_table -->ha_create -->ha_innobase::create -->innobase_basic_ddl::create_impl -->create_table_info_t::create_table { ...... } -->trans_commit_implicit -->ha_commit_trans -->MYSQL_BIN_LOG::prepare -->ha_prepare_low //所有事務(wù)引擎prepare { binlog_prepare innobase_xa_prepare } -->MYSQL_BIN_LOG::commit -->MYSQL_BIN_LOG::ordered_commit -->MYSQL_BIN_LOG::process_flush_stage_queue -->MYSQL_BIN_LOG::flush_thread_caches -->binlog_cache_mngr::flush -->binlog_cache_data::flush -->MYSQL_BIN_LOG::write_gtid -->Log_event::write -->MYSQL_BIN_LOG::Binlog_ofile::write //寫binlog-gtid -->MYSQL_BIN_LOG::write_cache --> MYSQL_BIN_LOG::do_write_cache -->Binlog_cache_storage::copy_to -->stream_copy -->Binlog_event_writer::write -->MYSQL_BIN_LOG::Binlog_ofile::write //寫binlog-ddl語句 -->MYSQL_BIN_LOG::sync_binlog_file -->MYSQL_BIN_LOG::process_commit_stage_queue -->ha_commit_low { binlog_commit innobase_commit -->trx_commit_for_mysql -->trx_commit -->trx_commit_low -->trx_commit_in_memory -->trx_undo_insert_cleanup } -->innobase_post_ddl(ht->post_ddl(thd)) -->Log_DDL::post_ddl -->replay_by_thread_id -->create_table_info_t::create_table -->create_table_def -->dict_mem_table_create //構(gòu)造innodb內(nèi)存是字典內(nèi)存對(duì)象 -->row_create_table_for_mysql -->dict_build_table_def -->dict_build_tablespace_for_table -->新建xxx.idb文件 -->Log_DDL::write_delete_space_log { -->Log_DDL::insert_delete_space_log -->trx_start_internal //內(nèi)部開啟事務(wù),單獨(dú)提交。 -->構(gòu)造DDL_Record(DELETE_SPACE_LOG) -->DDL_Log_Table::insert(寫入物理B-Tree) -->Log_DDL:delete_by_id //刪除ddl_log操作,作為ddl事務(wù)的一部分。 } -->fil_ibd_create -->初始化segment,extent,page -->Log_DDL::write_remove_cache_log -->Log_DDL::insert_remove_cache_log -->Log_DDL::delete_by_id -->create_index(主表,二級(jí)索引) -->dict_create_index_tree_in_mem -->btr_create -->Log_DDL::write_free_tree_log -->Log_DDL::insert_free_tree_log -->Log_DDL:delete_by_id<br> crash-recovery -->ha_post_recover -->post_recover_handlerton -->innobase_post_recover -->Log_DDL::recover -->Log_DDL::replay_all -->Log_DDL::replay { replay_delete_space_log replay_remove_cache_log replay_free_tree_log ...... } -->delete_by_ids -->DDL_Log_Table::remove
5.2 drop table
mysql_rm_table -->mysql_rm_table_no_locks -->drop_base_table -->ha_delete_table -—>handler::ha_delete_table -->ha_innobase::delete_table -->innobase_basic_ddl::delete_impl -->row_drop_table_for_mysql -->Log_DDL::write_drop_log // 記錄刪innodb_dynamic_metadata日志 -—>Log_DDL::write_delete_space_log // 記錄刪ibd日志 -->dd::drop_table -->dd::cache::Dictionary_client::drop<dd::Table> -->dd::cache::Storage_adapter::drop<dd::Table> -->dd::sdi::drop -->innobase_post_ddl -->Log_DDL::post_ddl -->Log_DDL::replay_by_thread_id -->Log_DDL::replay —>Log_DDL::replay_delete_space_log // post-ddl 真正刪除innodb_dynamic_metadata —>Log_DDL::replay_drop_log // post-ddl 真正刪除ibd -->delete_by_ids -->DDL_Log_Table::remove
drop table時(shí),只記錄刪除動(dòng)作日志,這些日志作為事務(wù)的整體的一部分,如果最終事務(wù)提交,那么post_ddl階段會(huì)讀取日志真正刪除;如果事務(wù)回滾,那么ddl_log也會(huì)作為事務(wù)的一部分而回滾。
參考文檔
https://dev.mysql.com/worklog/task/?id=9045
https://dev.mysql.com/worklog/task/?id=9173
https://dev.mysql.com/worklog/task/?id=9175
https://dev.mysql.com/worklog/task/?id=9525
https://dev.mysql.com/worklog/task/?id=9536
總結(jié)
以上所述是小編給大家介紹的MySQL8.0 DDL原子性特性及實(shí)現(xiàn)原理,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
- MySQL8.0 如何快速加列
- Mysql Online DDL的使用詳解
- MySQL DDL 引發(fā)的同步延遲該如何解決
- 詳解MySQL8.0原子DDL語法
- MySQL在線DDL工具 gh-ost的原理解析
- MySQL ddl語句的使用
- Mysql DDL常見操作匯總
- 解析MySQL8.0新特性——事務(wù)性數(shù)據(jù)字典與原子DDL
- MySQL數(shù)據(jù)定義語言DDL的基礎(chǔ)語句
- MySQL在線DDL gh-ost使用總結(jié)
- 解決MySQL 5.7中定位DDL被阻塞的問題
- MySQL8.0新特性之支持原子DDL語句
- MySQL曝中間人攻擊Riddle漏洞可致用戶名密碼泄露的處理方法
- MySQL 8.0 Online DDL快速加列的相關(guān)總結(jié)
相關(guān)文章
SQL算術(shù)運(yùn)算符之加法、減法、乘法、除法和取模的用法例子
算術(shù)運(yùn)算符主要用于數(shù)學(xué)運(yùn)算,其可以連接運(yùn)算符前后的兩個(gè)數(shù)值或表達(dá)式,對(duì)數(shù)值或表達(dá)式進(jìn)行加(+)、減(-)、乘(*)、除(/)和取模(%)運(yùn)算,下面這篇文章主要給大家介紹了關(guān)于SQL算術(shù)運(yùn)算符之加法、減法、乘法、除法和取模用法的相關(guān)資料,需要的朋友可以參考下2024-03-03MySql優(yōu)化之InnoDB,4GB內(nèi)存,多查詢的my.ini中文配置方案詳解
本文是一個(gè)針對(duì) 4G 內(nèi)存系統(tǒng)(主要運(yùn)行只有 InnoDB 表的 MySQL 并使用幾個(gè)連接數(shù)執(zhí)行復(fù)雜的查詢)的MySQL配置文件方案2018-03-03MySQL使用distinct去掉查詢結(jié)果重復(fù)的問題
這篇文章主要介紹了MySQL使用distinct去掉查詢結(jié)果重復(fù)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-01-01Linux系統(tǒng)下修改mysql字符集為UTF8步驟
大家好,本篇文章主要分享的是Linux系統(tǒng)下修改mysql字符集為UTF8步驟,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下吧,方便下次瀏覽2021-12-12MySQL安裝過程中在第四步initializing database出錯(cuò)的解決方法
安裝mysql時(shí),在第四步一直卡住了顯示失敗,文中通過圖文介紹的解決方法非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能幫助到大家2023-09-099種 MySQL數(shù)據(jù)庫優(yōu)化的技巧
這篇文章小編主要給大家介紹的是 MySQL數(shù)據(jù)庫優(yōu)化的正確姿勢,九種方法呢?。。⌒枰男』锇橼s快收藏起來吧2021-09-09MySQL分組查詢、排序查詢、分頁查詢以及執(zhí)行順序
MySQL數(shù)據(jù)查詢是數(shù)據(jù)庫操作中最常見的操作之一,它可以幫助我們從數(shù)據(jù)庫中獲取所需的數(shù)據(jù),下面這篇文章主要給大家介紹了關(guān)于MySQL分組查詢、排序查詢、分頁查詢以及執(zhí)行順序的相關(guān)資料,需要的朋友可以參考下2024-02-02淺談mysql 系統(tǒng)用戶最大文件打開數(shù)限制
這篇文章主要介紹了mysql 系統(tǒng)用戶最大文件打開數(shù)限制,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03GDB調(diào)試Mysql實(shí)戰(zhàn)之源碼編譯安裝
今天小編就為大家分享一篇關(guān)于GDB調(diào)試Mysql實(shí)戰(zhàn)之源碼編譯安裝,小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧2019-02-02