久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

MySQL Innodb恢復的方法教程

159次閱讀
沒有評論

共計 13589 個字符,預計需要花費 34 分鐘才能閱讀完成。

這篇文章主要介紹“MySQL  Innodb 恢復的方法教程”,在日常操作中,相信很多人在 MySQL  Innodb 恢復的方法教程問題上存在疑惑,丸趣 TV 小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”MySQL  Innodb 恢復的方法教程”的疑惑有所幫助!接下來,請跟著丸趣 TV 小編一起來學習吧!

MySQL · 引擎特性 · InnoDB 崩潰恢復過程

enum {
 SRV_FORCE_IGNORE_CORRUPT = 1, /*!  let the server run even if it
 detects a corrupt page */
 SRV_FORCE_NO_BACKGROUND = 2, /*!  prevent the main thread from
 running: if a crash would occur
 in purge, this prevents it */
 SRV_FORCE_NO_TRX_UNDO = 3, /*!  do not run trx rollback after
 recovery */
 SRV_FORCE_NO_IBUF_MERGE = 4, /*!  prevent also ibuf operations:
 if they would cause a crash, better
 not do them */
 SRV_FORCE_NO_UNDO_LOG_SCAN = 5, /*!  do not look at undo logs when
 starting the database: InnoDB will
 treat even incomplete transactions
 as committed */
 SRV_FORCE_NO_LOG_REDO = 6 /*!  do not do the log roll-forward
 in connection with recovery */};

innodb 中的 3 個 lsn

innodb 的 lsn 和 oracle 的 scn 一樣,是一個重要的概念。比如

在 flush list 中正是是使用 low lsn 作為鏈表的條件
參考 buf_page_t 中的 lsn_t oldest_modification;

在 checkpoint 中記錄的也是 lsn
參考宏

#define LOG_CHECKPOINT_NO 0#define LOG_CHECKPOINT_LSN 8#define LOG_CHECKPOINT_OFFSET 16#define LOG_CHECKPOINT_LOG_BUF_SIZE 24

在物理文件中每個塊最后的刷新 lsn
參考宏 FIL_PAGE_LSN

在寫日志落盤的時候也是以 lsn 為標準的
參考函數 log_write_up_to

實際上 lsn 就是表示的日志量的字節數,是一個累加的值,在 5.7 中表現為:

/* Type used for all log sequence number storage and arithmetics */typedef ib_uint64_t lsn_t;

及一個 8 字節非負的整數。最大值及 2 的 64 次方。有了這種物理上概念,lsn 很容易換算為當前日志的偏移量。

下面描述一下和檢查點相關的幾個 lsn

ibdata 第一個塊 FIL 中的 lsn(flush lsn):ibdata 的 26 后面 8 字節是在 innodb 干凈關閉的時候進行更新的,如果不正常關閉不會進行寫入(FIL_PAGE_FILE_FLUSH_LSN)

redolog 中 MLOG_CHECKPOINT 的 lsn: redolog MLOG_CHECKPOINT lsn 的寫入是在每次 checkpoint 的時候同步寫入的. 干凈關閉會更新。

redolog header 中的 lsn: 是在每次 checkpoint 的時候異步寫入的在 MLOG_CHECKPOINT 寫入之后. 干凈關閉會更新。
我們表示為 lsn1/lsn2/lsn3
正常關閉 3 個 lsn 是相等的,如果非正常關閉 innodb,lsn1 不會更新,因此 lsn3 必然不和 lsn1 相等,則判定需要進行 carsh recovery。

if (checkpoint_lsn != flush_lsn) { ...... if (!recv_needed_recovery) { ib::info()    The log sequence number     flush_lsn
     in the system tablespace does not match 
   the log sequence number     checkpoint_lsn
     in the ib_logfiles!  // 出現這個警告說明需要恢復了,因為沒有干凈的關閉數據庫,那么 flush_lsn 一定比 checkpoint_lsn 小
 if (srv_read_only_mode) { ib::error()    Can t initiate database 
   recovery, running in read-only-mode. 
 log_mutex_exit(); return(DB_READ_ONLY);
 }
 recv_init_crash_recovery(); // 初始化
 }
 }

MLOG_CHECKPOINT

log_checkpoint 函數由 master 線程調用,以及關閉數據庫的時候調用,不斷的向 redo log 中寫入 MLOG_CHECKPOINT 和 MLOG_FILE_NAME

log_group_checkpoint 寫入 checkpoint 信息到 log header

#0 mtr_t::commit_checkpoint (this=0x7fff761fb830, checkpoint_lsn=697558445) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/mtr/mtr0mtr.cc:592#1 0x0000000001ceb4b9 in fil_names_clear (lsn=697558445, do_write=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/fil/fil0fil.cc:7067#2 0x0000000001a521cc in log_checkpoint (sync=true, write_always=false) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1927#3 0x0000000001b856f2 in srv_master_do_idle_tasks () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2596#4 0x0000000001b85b6b in srv_master_thread (arg=0x0) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2744#5 0x0000003f74807aa1 in start_thread () from /lib64/libpthread.so.0#6 0x0000003f740e8bcd in clone () from /lib64/libc.so.6

正常 innodb 運行的情況下 checkpoint 是由 master 線程觸發。我們知道臟數據通過 page clean 線程和 lru manager 線程是在不斷寫盤的,那么在進行異常重啟的的時候我們必須要知道一個恢復的起點,但是這個起點是不能記錄在內存中必要固化到磁盤,恢復的時候讀取這個點以后的 redo 進行恢復,而 checkpoint 就是完成這個事情下面是 checkpoint 的執行流程。

正常情況下 master 會每秒進行檢查點其作用有:(參考 log_checkpoint 函數)
1、檢查是否有自上次檢查點以來的臟數據寫盤了
2、如果有則在 redo 里面會為每個修改過的文件寫入 MLOG_FILE_NAME, 完成后寫入一個總的 MLOG_CHECKPOINT(參考 fil_names_clear 函數)
MLOG_FILE_NAME 主要記錄至上次檢查點以來更改過的數據文件
MLOG_CHECKPOINT 主要記錄檢查點的 lsn
3、如果有則在 redo header 中寫入相應的檢查點信息包含(異步寫)(參考 log_group_checkpoint 函數)

Log sequence number 697794162
Log flushed up to 697794162
Pages flushed up to 697794162
Last checkpoint at 697794153

697794162-697794153 = 9 剛好是 MLOG_CHECKPOINT 的長度
oldest_lsn = log_sys- last_checkpoint_lsn + SIZE_OF_MLOG_CHECKPOINT
SIZE_OF_MLOG_CHECKPOINT=9

redo 的寫入有 6 個途徑:
1、master 線程每秒調用 棧幀(可能是 idle 可能是 active 和檢測是否需要插入緩存合并有關)
2、master 線程每秒 checkpoint 調用 (可能是 idle 可能是 active 和檢測是否需要插入緩存合并有關)
3、page clean 線程調用 棧幀 /* Force the log to the disk before writing the modified block */
4、主線程 commit 調用 棧幀
5、innodb shutdown
6、redo buffer 不足

1、master 線程調用 棧幀(可能是 idle 可能是 active 和檢測是否需要插入緩存合并有關)

#0 log_group_write_buf (group=0x33f29f8, buf=0x7fffa5b38000  \200\024 , len=512, pad_len=0, start_lsn=697764864, new_data_offset=166)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1145#1 0x0000000001a50f95 in log_write_up_to (lsn=697765068, flush_to_disk=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1493#2 0x0000000001a51163 in log_buffer_sync_in_background (flush=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1553#3 0x0000000001b84bd1 in srv_sync_log_buffer_in_background () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2312#4 0x0000000001b85666 in srv_master_do_idle_tasks () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2586#5 0x0000000001b85b6b in srv_master_thread (arg=0x0) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2744

2、master 線程 checkpoint 調用 (可能是 idle 可能是 active 和檢測是否需要插入緩存合并有關)

#0 log_group_write_buf (group=0x33f29f8, buf=0x7fffa5a38000  \200\024\002 , len=1024, pad_len=0, start_lsn=697789952, new_data_offset=139)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1145#1 0x0000000001a50f95 in log_write_up_to (lsn=697790725, flush_to_disk=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1493#2 0x0000000001a52247 in log_checkpoint (sync=true, write_always=false) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1934#3 0x0000000001b856f2 in srv_master_do_idle_tasks () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2596#4 0x0000000001b85b6b in srv_master_thread (arg=0x0) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0srv.cc:2744

3、page clean 線程調用 棧幀 /* Force the log to the disk before writing the modified block */

#0 log_group_write_buf (group=0x33f29f8, buf=0x7fffa5a38000  \200\024\002 , len=13312, pad_len=1024, start_lsn=697778176, new_data_offset=468)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1145#1 0x0000000001a50f95 in log_write_up_to (lsn=697790015, flush_to_disk=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1493#2 0x0000000001c704c7 in buf_flush_write_block_low (bpage=0x7fffc0cae940, flush_type=BUF_FLUSH_LIST, sync=false)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:1035#3 0x0000000001c70cea in buf_flush_page (buf_pool=0x33247d8, bpage=0x7fffc0cae940, flush_type=BUF_FLUSH_LIST, sync=false)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:1237#4 0x0000000001c717f4 in buf_flush_try_neighbors (page_id=..., flush_type=BUF_FLUSH_LIST, n_flushed=0, n_to_flush=25)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:1466#5 0x0000000001c71b57 in buf_flush_page_and_try_neighbors (bpage=0x7fffc0cae940, flush_type=BUF_FLUSH_LIST, n_to_flush=25, count=0x7fffa02867c0)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:1558#6 0x0000000001c72862 in buf_do_flush_list_batch (buf_pool=0x33247d8, min_n=25, lsn_limit=18446744073709551615)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:1846#7 0x0000000001c72cb6 in buf_flush_batch (buf_pool=0x33247d8, flush_type=BUF_FLUSH_LIST, min_n=25, lsn_limit=18446744073709551615)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:1926#8 0x0000000001c73104 in buf_flush_do_batch (buf_pool=0x33247d8, type=BUF_FLUSH_LIST, min_n=25, lsn_limit=18446744073709551615, n_processed=0x7fffa0286938)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:2071#9 0x0000000001c734ee in buf_flush_lists (min_n=25, lsn_limit=18446744073709551615, n_processed=0x7fffa02869c8)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:2202#10 0x0000000001c76a97 in buf_flush_page_cleaner_coordinator (arg=0x0) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/buf/buf0flu.cc:3362

4、主線程 commit 調用 棧幀

#0 log_group_write_buf (group=0x33f29f8, buf=0x7fffa5a38000  \200\024\002 , len=2560, pad_len=0, start_lsn=697762816, new_data_offset=230)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1145#1 0x0000000001a50f95 in log_write_up_to (lsn=697765030, flush_to_disk=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1493#2 0x0000000001a51087 in log_buffer_flush_to_disk (sync=true) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:1524#3 0x00000000019a9157 in innobase_flush_logs (hton=0x2e9fdd0, binlog_group_flush=true)
 at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:4407#4 0x0000000000f65893 in flush_handlerton (thd=0x0, plugin=0x7ffff03588e8, arg=0x7ffff0358944) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:2606#5 0x00000000015d7716 in plugin_foreach_with_mask (thd=0x0, func=0xf65835  flush_handlerton(THD*, plugin_ref, void*) , type=1, state_mask=4294967287, 
 arg=0x7ffff0358944) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:2318#6 0x0000000000f658ef in ha_flush_logs (db_type=0x0, binlog_group_flush=true) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:2617#7 0x000000000185733d in MYSQL_BIN_LOG::process_flush_stage_queue (this=0x2e02c80, total_bytes_var=0x7ffff0358a88, rotate_var=0x7ffff0358a87, 
 out_queue_var=0x7ffff0358a78) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8541#8 0x000000000185899f in MYSQL_BIN_LOG::ordered_commit (this=0x2e02c80, thd=0x7fff2c000b70, all=false, skip_commit=false)
 at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:9189#9 0x000000000185700c in MYSQL_BIN_LOG::commit (this=0x2e02c80, thd=0x7fff2c000b70, all=false) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/binlog.cc:8440#10 0x0000000000f63df8 in ha_commit_trans (thd=0x7fff2c000b70, all=false, ignore_global_read_lock=false)

入口函數
innobase_start_or_create_for_mysql
recv_recovery_from_checkpoint_start
1、此函數需要輸入 flush 的 lsn 及臟數據寫入到的位置
這個數據從 FIL_PAGE_FILE_FLUSH_LSN 中讀取,這個值
只在 ibdata 的第一個 page 有效其他均為 0, 他的讀取來自于
函數 Datafile::validate_first_page,
其中
*flush_lsn = mach_read_from_8(
m_first_page + FIL_PAGE_FILE_FLUSH_LSN);

其寫入由函數   正常 shutdown 才會寫入, 非正常關閉不會寫入,正常運行檢查點也不會寫入
fil_write_flushed_lsn  寫入
mach_write_to_8(buf + FIL_PAGE_FILE_FLUSH_LSN, lsn);
棧幀
 #0 fil_write_flushed_lsn (lsn=696973727) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/fil/fil0fil.cc:1946
 #1 0x0000000001a538a7 in logs_empty_and_mark_files_at_shutdown () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/log/log0log.cc:2464
 #2 0x0000000001b915a9 in innobase_shutdown_for_mysql () at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/srv/srv0start.cc:2803
 #3 0x00000000019a8ffc in innobase_end (hton=0x2e9edd0, type=HA_PANIC_CLOSE) at /root/mysql5.7.14/percona-server-5.7.14-7/storage/innobase/handler/ha_innodb.cc:4360
 #4 0x0000000000f62621 in ha_finalize_handlerton (plugin=0x3015cd0) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/handler.cc:813
 #5 0x00000000015d3d25 in plugin_deinitialize (plugin=0x3015cd0, ref_check=true) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:995
 #6 0x00000000015d410e in reap_plugins () at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:1077
 #7 0x00000000015d6073 in plugin_shutdown () at /root/mysql5.7.14/percona-server-5.7.14-7/sql/sql_plugin.cc:1845
 #8 0x0000000000ebf7eb in clean_up (print_message=true) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:1336
 #9 0x0000000000ec701b in mysqld_main (argc=98, argv=0x2e9cf08) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/mysqld.cc:5386
 #10 0x0000000000ebd604 in main (argc=10, argv=0x7fffffffe458) at /root/mysql5.7.14/percona-server-5.7.14-7/sql/main.cc:25

2、此函數首先建立紅黑樹用于恢復并且做 force recovery 判斷
(srv_force_recovery = SRV_FORCE_NO_LOG_REDO)
然后調用
recv_find_max_checkpoint 此函數就是找到最大的 checkpoint lsn、redo 文件, 以及 field 就是相對于一個日志而講所在的 offset set (5121 or 5123)_
讀取如下:

 group- lsn = mach_read_from_8( buf + LOG_CHECKPOINT_LSN);
 group- lsn_offset = mach_read_from_8( buf + LOG_CHECKPOINT_OFFSET);
 checkpoint_no = mach_read_from_8( buf + LOG_CHECKPOINT_NO);

3、recv_group_scan_log_recs
循環讀取 64K(RECV_SCAN_SIZE)日志到 redo buffer(log_group_read_log_seg)
recv_scan_log_recs
本函數將 64K 的 redo 通過每個 512 bytes block 大小循環加入到 (recv_sys_add_to_parsing_buf) 掃描到 parse buffer
代碼片段拷貝

 ut_memcpy(recv_sys- buf + recv_sys- len,
 log_block + start_offset, end_offset - start_offset);
 
  當每次掃描了 64K*80 的日志量的時候會輸出,級 5M
 ib::info()    Doing recovery: scanned up to 
   log sequence number     scanned_lsn;
  并且進行分析對這加入到  parse buffer 的日志進行分析(recv_parse_log_recs) / 其中 parse buffer  為 2M(宏 RECV_PARSING_BUF_SIZE 大小)
 recv_parse_log_recs 函數對每次加入  parse buffer 的 64k 進行分析主要分析是 MLOG_SINGLE_REC_FLAG 還是 MLOG_MULTI_REC_END  同時確認 MLOG_MULTI_REC_END
  是否完整,完成后加入到 hash table,函數是調用 recv_parse_log_rec 進行  (type spaceid page_no data)的剝離。

那么 recv_group_scan_log_recs 為第一層循環,循環掃描 64K 日志到 redo buffer
然后調用 recv_scan_log_recs 以 block 單位 (512b) 大小循環加入到 parse buffer,這是通過函數 recv_sys_add_to_parsing_buf 完成
等到 64k 加入到 parse buffer 后調用 recv_parse_log_recs 函數對每次加入 parse buffer 的 64k 進行分析,分析是循環以 record 為單位的,主要分析 MLOG_SINGLE_REC_FLAG 還是 MLOG_MULTI_REC_END,同時確保 MLOG_MULTI_REC_END 記錄是完整的。完成后 recv_parse_log_recs 函數 還要將其加入到 hash table 函數為 recv_add_to_hash_table,本函數是通過 recv_parse_log_rec 進行 (type spaceid page_no data)的剝離。

recv_apply_hashed_log_recs 最后完成分析完成后的日志應用,從 hash table 中

到此,關于“MySQL  Innodb 恢復的方法教程”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注丸趣 TV 網站,丸趣 TV 小編會繼續努力為大家帶來更多實用的文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-24發表,共計13589字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 綦江县| 宣城市| 云浮市| 三江| 田东县| 来凤县| 农安县| 玉环县| 军事| 沾益县| 乐山市| 武隆县| 丘北县| 北安市| 时尚| 集贤县| 思茅市| 莱芜市| 阿拉善左旗| 个旧市| 汕尾市| 宁安市| 武夷山市| 乌苏市| 湘潭县| 婺源县| 嘉兴市| 浦县| 永昌县| 秦安县| 濮阳县| 望城县| 木里| 大方县| 保亭| 扎赉特旗| 定结县| 峨山| 报价| 泽库县| 龙南县|