mysql8.0無備份通過idb文件恢復(fù)數(shù)據(jù)的方法、idb文件修復(fù)和tablespace?id不一致處理
周末突然接到一位一年多沒聯(lián)系的妹妹打來電話,“劉哥,快來救救我”,我腦海瞬間冒出妙瓦底,電信火苲馬扁.....,當(dāng)時(shí)就冒汗了,心想這個妹子怎么被...
問其原由,原來是他們公司服務(wù)器掉電,重啟后單位的站點(diǎn)打不開了,請求支援...
妹妹說搞定請我吃臨沂炒雞,作為從業(yè)N年的碼農(nóng),英雄救美義不容辭。立即驅(qū)車18公里,火速前往事故現(xiàn)場。
經(jīng)了解項(xiàng)目tomcat服務(wù)啟動正常,但是數(shù)據(jù)庫沒有正常啟動導(dǎo)致web應(yīng)用無法訪問,數(shù)據(jù)數(shù)版本mysql8.0.26,這個沒玩過咋整,平時(shí)都是弄mssql,oracle。
修復(fù)過程
百度查閱各種資料,歷時(shí)1天的時(shí)間,下面簡單記錄整個修復(fù)過程。
1、查看錯誤日志信息
日志文件在mysql數(shù)據(jù)目錄中 C:\ProgramData\MySQL\MySQL Server 8.0\Data,文件命名格式為 計(jì)算機(jī)名稱.err,本地文件liuxiaoxiao.err
信息顯示: file not found liuxiaoxiao-bin.000031
此問題重命名data目錄中l(wèi)iuxiaoxiao-bin.index文件為其他名稱,或刪除此文件。重啟數(shù)據(jù)庫服務(wù)后數(shù)據(jù)庫正常啟動,項(xiàng)目可以訪問。
2、很開心,美女說還有一臺也出故障,是以前的一個老項(xiàng)目不怎么用,但是歷史數(shù)據(jù)偶爾查詢,心想如法炮制不就ok了嗎,一招制敵簡單,哈哈
打開錯誤日志看到的信息完全不一樣,錯誤信息顯示mysqld got exception 0x80000003
11:38:26 UTC - mysqld got exception 0x80000003 ;
Most likely, you have hit a bug, but this error can also be caused by malfunctioning hardware.
Thread pointer: 0x2ce9279b3f0
Attempting backtrace. You can use the following information to find out
where mysqld died. If you see no messages after this, something went
terribly wrong...
7ff70802a1a2 mysqld.exe!?my_errno@@YAHXZ()
7ff970f3e5f5 ucrtbase.dll!raise()
7ff970f3f601 ucrtbase.dll!abort()
此處省略若干行......
7ff970ee9363 ucrtbase.dll!_recalloc()
7ff97285257d KERNEL32.DLL!BaseThreadInitThunk()
7ff9738caa58 ntdll.dll!RtlUserThreadStart()
3、查閱資料嘗試操作,對Data目錄進(jìn)行重新初始化,可以正常啟動數(shù)據(jù)庫服務(wù),但是復(fù)制備份文件過去后服務(wù)啟動仍然異常,過程如下。
1)、備份整個data目錄,現(xiàn)場電腦的路徑是C:\ProgramData\MySQL\MySQL Server 8.0\Data,然后清空Data目錄
2)、cmd 運(yùn)行C:\Program Files\MySQL\MySQL Server 8.0\bin目錄下的mysqld.exe 執(zhí)行以下命令mysqld --initialize回車等待完成
初始化完成,服務(wù)啟動讓提示錯誤,這里操作完成后查看data目錄并沒有產(chǎn)生新文件,結(jié)果初始化后Data目錄跑到C:\Program Files\MySQL\MySQL Server 8.0\Data目錄,手動將初始化產(chǎn)生的文件復(fù)制到C:\ProgramData\MySQL\MySQL Server 8.0\Data下,啟動服務(wù)成功。
根據(jù)文章指導(dǎo),初始化后root的新密碼在錯誤日志文件中xxxxx.err獲取,修改root密碼為原密碼
C:\Program Files\MySQL\MySQL Server 8.0\bin>mysql -u root -P 3306 -p
mysql> alter user 'root'@'localhost' identified by '123xxx' password expire never;
mysql> alter user 'root'@'localhost' identified with mysql_native_password by '123xxx';
mysql> flush privileges;
根據(jù)文章提示停止mysql服務(wù),復(fù)制原Data備份目錄的ibdata1、ib_logfile1、ib_logfile0、ib_buffer_pool、auto.cnf、 mysql.ibd到新產(chǎn)生的Data下,再重啟服務(wù)失敗,查看錯誤日志無任何日志輸出,而且服務(wù)啟動提示失敗,查看window事件日志也沒有任何可用信息。
使用記事本修改my.ini數(shù)據(jù)庫配置文件在[mysqld]下增加innodb_force_recovery=1配置信息,仍然啟動失敗
重新初始化Data目錄,刪除上面改動添加的innodb_force_recovery=1配置信息,啟動提示同樣錯誤,提示大致信息:服務(wù)依賴的xxxx停止。
截至目前情況變的更糟糕了,初始化后正常的服務(wù)都不能啟動,本身就對mysql不太了解,心里開始發(fā)懵,決定嘗試卸載重新安裝mysql,版本必須保持與原來安裝版本一直,因?yàn)楹竺孢€要進(jìn)行數(shù)據(jù)庫修復(fù)。
4、重新安裝數(shù)據(jù)庫:
卸載數(shù)據(jù)庫,刪除C:\ProgramData\MySQL\;C:\Program Files\MySQL\ 兩個目錄下的MySQL Server 8.0文件夾、(注意:原來Data目錄備份保留好),重新安裝數(shù)據(jù)庫服務(wù)正常啟動,備份my.ini配制文件,采取逐步嘗試的方法發(fā)現(xiàn),my.ini文件修改后,服務(wù)就啟動不起來,猜測修改配制異常導(dǎo)致的,恢復(fù)my.ini的備份使用notepad++修改配制文件后可以正常啟動服務(wù)。
小總結(jié):mysql數(shù)據(jù)庫配置文件my.ini不能使用記事本編輯,這個會導(dǎo)致文件編碼異常進(jìn)而導(dǎo)致服務(wù)不能啟動。這個要注意?。?!
重復(fù)上述操作復(fù)制ibdata1、ib_logfile1、ib_logfile0...等文件到新目錄,服務(wù)啟動失敗。
關(guān)鍵一步:僅復(fù)制Data備份mysql.ibd文件到現(xiàn)有目錄,數(shù)據(jù)庫服務(wù)啟動正常,且使用Navicat鏈接數(shù)據(jù)庫可以看到數(shù)據(jù)庫,使用Navicat管理工具在數(shù)據(jù)庫上鼠標(biāo)右鍵|轉(zhuǎn)儲SQL文件|僅結(jié)構(gòu),順利將整個庫的建表語句生成,當(dāng)時(shí)開心壞了...,猜想mysql.idb文件包含了每個數(shù)據(jù)庫對象的信息。(此步記不清當(dāng)時(shí)是否已將項(xiàng)目數(shù)據(jù)庫目錄文件放到Data中了,印象中記得是沒有)
5、表修復(fù)和恢復(fù)數(shù)據(jù)庫
1)、通過執(zhí)行上步獲取的腳本,重新創(chuàng)建數(shù)據(jù)庫,這樣就獲取了一個空白的項(xiàng)目數(shù)據(jù)庫。
2)、執(zhí)行sql丟棄表空間,每個表都需要操作一遍:alter table cms_xxx discard tablespace; 其中cms_xxx是表名
3)、停止mysql服務(wù)復(fù)制備份目錄項(xiàng)目數(shù)據(jù)庫的idb文件替換覆蓋第一步腳本創(chuàng)建生成的文件。
4)、執(zhí)行sql導(dǎo)入表空間,每個表都需要操作一遍:alter table cms_xxx import tablespace; 其中cms_xxx是表名
執(zhí)行不報(bào)錯誤的話,這個表就正??梢栽L問了。
當(dāng)前項(xiàng)目數(shù)據(jù)庫共77個表,執(zhí)行過程中62張是可以導(dǎo)入表空間正常了,其中還有5張導(dǎo)入失敗,其中3張是log_開頭的,估計(jì)是操作日志類的表,沒有太大業(yè)務(wù)關(guān)系,這個3張表直接新建數(shù)據(jù)不管了,另外一張是一個基礎(chǔ)檔案表數(shù)據(jù)不多,新建讓重新維護(hù)記錄就好了。
5)、麻煩的是其中最大的一張表200多兆,不能正常導(dǎo)入,而且根據(jù)名稱推斷這個是個關(guān)鍵的業(yè)務(wù)表。網(wǎng)絡(luò)搜索相關(guān)資料,最終恢復(fù)了大部分?jǐn)?shù)據(jù),仍有部分?jǐn)?shù)據(jù)丟失。
總結(jié)具體操作步驟如下,恢復(fù)過程進(jìn)行要損壞表對應(yīng)的idb文件就行:
a、安裝全新的mysql環(huán)境安裝路徑和服務(wù)器原來的路徑要相同(或者在現(xiàn)有的mysql環(huán)境下操作也行),創(chuàng)建相同編碼排序規(guī)則的同名數(shù)據(jù)庫,創(chuàng)建同名的表名稱。
b、停止服務(wù),剪切a步驟新建表Data目錄產(chǎn)生的.idb文件到其他任意自己的備份目錄,將損壞的idb文件放到Data目錄中,my.ini添加innodb_force_recovery=1配置信息,啟動數(shù)據(jù)庫服務(wù),然后嘗試查詢這張數(shù)據(jù)表,數(shù)據(jù)庫會報(bào)錯或直接服務(wù)停掉了,此時(shí)查看錯誤日志,獲取損壞文件的tablespace id值。
錯誤日志會看到大致如此信息:
[ERROR] InnoDB: Error: tablespace id in file ‘.\db_web\cms_content_detail.ibd’ is 233, but in the InnoDB InnoDB: data dictionary it is 109
這是因?yàn)閿?shù)據(jù)庫系統(tǒng)記憶此表的表空間id和idb文件頭里保存的表空間id不一致導(dǎo)致,(期間還發(fā)現(xiàn)mysql在啟動的時(shí)候會訪問數(shù)據(jù)庫目錄中的每個idb文件,如果庫文件目錄中將任意一個idb文件復(fù)制副本,啟動mysql服務(wù)的時(shí)候,日期會提示重復(fù)的表空間文件)
這里233十進(jìn)制轉(zhuǎn)換16進(jìn)制數(shù)據(jù)為E9,通過UltraEdit打開idb文件查看,驗(yàn)證了此結(jié)果,之所以有兩處,是因?yàn)閕db文件在文件頭和page區(qū)的頭部都保存了此信息。
接下來我們需要在此數(shù)據(jù)庫上不停建立新表,每創(chuàng)建一個新表mysql系統(tǒng)內(nèi)的tablespace id就會增加1,直到創(chuàng)建出來的新表文件這個ID值是E8,再通過建表語句創(chuàng)建待修復(fù)的表cms_content_detail,如此新產(chǎn)生的表對象的表空間ID就和原來壞掉的保持一致了,如何盤點(diǎn)新創(chuàng)建的表到E8(十進(jìn)制232)呢,還是用UltraEdit(或其他16進(jìn)制查看文件的工具)打開idb文件查看就可以。這里我是通過重復(fù)執(zhí)行固定次數(shù)的建表tb1達(dá)到需要的目的( DROP table tb1;CREATE table tb1(id int); )
啟動數(shù)據(jù)庫服務(wù),cmd命令窗口使用mysqldump導(dǎo)出備份數(shù)據(jù)(注意:mysqldump命令需要在mysql的bin目錄執(zhí)行,否則可能會提示無效命令)
mysqldump -u root -P 3306 -p db_web cms_content_detail > cms_tb01.sql
回車,輸入root密碼回車等待導(dǎo)出語句完成,cmsfix_01.sql文件包含了修復(fù)表的create、insert語句。
這里我是將修復(fù)級別改為6,即innodb_force_recovery=6才完成了數(shù)據(jù)導(dǎo)出的,逐個嘗試1-5并不能完成修復(fù),在6這個級別下最終還是有部分?jǐn)?shù)據(jù)丟失沒能找回,使用UltraEdit查看idb文件尾部都是000000空白內(nèi)容(如果你的mysql占用的不是默認(rèn)3306端口,可以使用-P 3307指定端口號的方式連接數(shù)據(jù)庫)。
有了sql腳本,通過執(zhí)行該腳本就可以重建表了,將mysql配置文件my.ini文件內(nèi)的innodb_force_recovery配置項(xiàng)注釋掉(否則數(shù)據(jù)庫處于只讀狀態(tài),沒法寫入數(shù)據(jù))啟動數(shù)據(jù)庫,刪除損壞的表,執(zhí)行導(dǎo)出的sql腳本,執(zhí)行語句格式:mysql -u<username> -p<password> <database> < <table_name>.sql
這里執(zhí)行:mysql -u root -p db_web < cms_tb01.sql 回車等待執(zhí)行完成,查看恢復(fù)表數(shù)據(jù)的情況。
系統(tǒng)復(fù)線后,添加內(nèi)容提示錯誤,查看tomcat日志發(fā)現(xiàn)提示ID主鍵沖突,估計(jì)是數(shù)據(jù)庫損壞導(dǎo)致新增序列ID值與已有數(shù)據(jù)庫記錄的ID重復(fù),通過上面的mysqldump導(dǎo)出整個庫,重新建庫導(dǎo)入后正常(這樣表的序列和索引都會被重建)至此整個修復(fù)過程結(jié)束,妹妹開心的不得了,“幸好有你”。
--->>>期間還走了其他很多彎路,比如通過idb文件逆向生成建表語句,修改表數(shù)據(jù)庫引擎類型,嘗試其他修復(fù)語句等等,不嘮叨了...
關(guān)于mysql本地計(jì)算機(jī)上的MySQL服務(wù)啟動后停止。某些服務(wù)在未由其他服務(wù)或程序使用時(shí)將自動停止問題
背景:由于某些原因,服務(wù)器需要重啟一下,結(jié)果重啟完就出現(xiàn)這個mysql本地計(jì)算機(jī)上的MySQL服務(wù)啟動后停止。某些服務(wù)在未由其他服務(wù)或程序使用時(shí)將自動停止
問題,一想到平時(shí)偷懶沒有做數(shù)據(jù)庫自動備份,當(dāng)時(shí)心態(tài)就炸了,找個各種辦法最后還是用初始化數(shù)據(jù)庫解決了
首先找到 Mysql 的安裝路徑,看看有沒有data文件夾,如果沒有data文件夾(一般默認(rèn)安裝的mysql可以在你的C:\ProgramData\MySQL
中找到),自己重新建一個,如果有的話,就把里面的內(nèi)容全部清空,但保留該目錄。注意!?。∵@里data文件夾里面的東西都是你的數(shù)據(jù)庫信息,一定要先備份起來,后面可以通過data文件夾里面的文件恢復(fù)你之前的數(shù)據(jù)庫信息
通過命令行進(jìn)入到MySQL安裝目錄下的 bin 文件夾,也可以直接在bin路徑輸入cmd即可進(jìn)入
進(jìn)入到命令行之后輸入初始化命令mysqld --initialize
按回車等待初始化完成即可,大概10秒左右,之后你可以看到清空的data文件已經(jīng)重新生成了文件
以上做完可以在命令行net start mysql
,也可以打開服務(wù)管理器選擇MySQL服務(wù)進(jìn)行啟動,你就發(fā)現(xiàn)可以正常啟動了,但還有一個問題就是初始化的密碼是隨機(jī)生成的,很難記住,需要自己重置一個自己能記住的密碼。
查看 mysql 隨機(jī)生成的密碼,用記事本打開 data 文件夾下的 XXXXXXX.err 文件,搜索 password ,會看到密碼重置,由于隨機(jī)密碼不好記,這個時(shí)候需要自己重置密碼。
進(jìn)入到mysql環(huán)境中,密碼是第五步查找到的隨機(jī)生成的密碼,輸入進(jìn)去即可
輸入ALTER user 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '新密碼';
更改為自己的密碼即可。
至此數(shù)據(jù)庫就可以正常使用了,當(dāng)然還有最重要的一步就是你的恢復(fù)初始化之前的數(shù)據(jù)庫信息,這時(shí)候就要用到第一步讓你備份的data文件夾了。
繼上篇文章MySQL本地計(jì)算機(jī)的MYSQL服務(wù)啟動后停止問題,解決完之后恢復(fù)數(shù)據(jù)庫信息
前面我有提到?jīng)]有做數(shù)據(jù)庫的日常備份,所以在解決完以上問題之后,我這邊又找到通過data文件夾備份數(shù)據(jù)庫信息的方法,這里也一同說一下
在恢復(fù)數(shù)據(jù)庫的時(shí)候一定要保證當(dāng)前的MySQL版本跟之前你的MySQL版本完全一致的情況下,其他版本我不敢保證可以成功
首先打開你備份的data文件夾選擇里面ibdata1、ib_logfile1、ib_logfile0、ib_buffer_pool、auto.cnf、 mysql.ibd以及你的數(shù)據(jù)庫文件夾,馬賽克的地方是我要恢復(fù)的數(shù)據(jù)庫,復(fù)制并覆蓋初始化之后的data文件里面的文件(需要先關(guān)閉mysql服務(wù)才可以復(fù)制進(jìn)去)。
之后啟動mysql服務(wù),你就可以看到你之前的所有數(shù)據(jù)庫都正常出現(xiàn)并使用了。
修復(fù)參考:https://www.cnblogs.com/jiangxu67/p/4744283.html
感謝以上網(wǎng)絡(luò)資料博主的分享
- MySQL通過binlog實(shí)現(xiàn)恢復(fù)數(shù)據(jù)
- Python MySQL如何通過Binlog獲取變更記錄恢復(fù)數(shù)據(jù)
- MySQL通過日志恢復(fù)數(shù)據(jù)的操作步驟
- MySQL通過ibd文件恢復(fù)數(shù)據(jù)的操作過程
- MySQL開啟配置binlog及通過binlog恢復(fù)數(shù)據(jù)步驟詳析
- mysql binlog如何恢復(fù)數(shù)據(jù)到某一時(shí)刻
- MySQL誤刪后使用binlog恢復(fù)數(shù)據(jù)的實(shí)現(xiàn)方法
- mysql數(shù)據(jù)損壞,如何通過ibd和frm文件批量恢復(fù)數(shù)據(jù)庫數(shù)據(jù)
- Mysql如何通過ibd文件恢復(fù)數(shù)據(jù)
- mysql如何根據(jù).frm和.ibd文件恢復(fù)數(shù)據(jù)表
- 一步步教你如何使用mysql?binlog恢復(fù)數(shù)據(jù)
- MySql恢復(fù)數(shù)據(jù)方法梳理講解
- Mysql通過ibd文件恢復(fù)數(shù)據(jù)的詳細(xì)步驟
- MySQL數(shù)據(jù)庫通過Binlog恢復(fù)數(shù)據(jù)的詳細(xì)步驟
- Mysql如何通過binlog日志恢復(fù)數(shù)據(jù)詳解
- mysql5.7使用binlog 恢復(fù)數(shù)據(jù)的方法
- MySQL通過binlog恢復(fù)數(shù)據(jù)
相關(guān)文章
MySQL數(shù)據(jù)庫遷移OpenGauss數(shù)據(jù)庫解析
這篇文章主要介紹了MySQL數(shù)據(jù)庫遷移OpenGauss數(shù)據(jù)庫解析,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-09-09解決mysql 1040錯誤Too many connections的方法
因?yàn)槟愕膍ysql安裝目錄下的my.ini中設(shè)定的并發(fā)連接數(shù)太少或者系統(tǒng)繁忙導(dǎo)致連接數(shù)被占滿2012-09-09