SQL Server中誤刪除數(shù)據(jù)的恢復(fù)本來不是件難事,從事務(wù)日志恢復(fù)即可。但是,這個恢復(fù)需要有兩個前提條件:

創(chuàng)新互聯(lián)于2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站建設(shè)、成都網(wǎng)站建設(shè)網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元垣曲做網(wǎng)站,已為上家服務(wù),為垣曲各地企業(yè)和個人服務(wù),聯(lián)系電話:18980820575
1. 至少有一個誤刪除之前的數(shù)據(jù)庫完全備份。
2. 數(shù)據(jù)庫的恢復(fù)模式(Recovery mode)是“完整(Full)”。
針對這兩個前提條件,會有三種情況:
情況一、如果這兩個前提條件都存在,通過SQL語句只需三步就能恢復(fù)(參考文章),無需借助第三方工具。
a) 備份當(dāng)前數(shù)據(jù)庫的事務(wù)日志:BACKUP LOG [數(shù)據(jù)庫名] TO disk= N'備份文件名' WITH NORECOVERY
b) 恢復(fù)一個誤刪除之前的完全備份:RESTORE DATABASE [數(shù)據(jù)庫名] FROM DISK = N'完全備份文件名' WITH NORECOVERY, REPLACE
c) 將數(shù)據(jù)庫恢復(fù)至誤刪除之前的時間點:RESTORE LOG [數(shù)據(jù)庫] FROM DISK = N'第一步的日志備份文件名' WITH STOPAT = N'誤刪除之前的時間點' , RECOVERY
情況二、如果第1個前提條件不存在,第2個前提條件存在,需要借助第三方工具。
情況三、如果第2個前提條件不存在,無法恢復(fù)。所以,一定要將數(shù)據(jù)庫恢復(fù)模式設(shè)置為“完整(Full)”。
我現(xiàn)在面臨的是第二種情況,需要找第三方工具。
開始找的是Log Explorer for SQL Server,不支持SQL Server 2008。
后來找的是SQL Log Rescue,也不支持SQL Server 2008。
接著找到的是SysTools SQL Recovery,支持SQL Server 2008,但需要購買,Demo版并沒有數(shù)據(jù)恢復(fù)功能。
最終在officerecovery.com上找到Recovery for SQL Server,雖然也是商業(yè)軟件,需要購買,但Demo版可以恢復(fù)數(shù)據(jù),只要數(shù)據(jù)庫文件不超過24Gb。幸好朋友的數(shù)據(jù)庫文件不大,用它完成了誤刪除數(shù)據(jù)的恢復(fù)。
下面分享一下用Recovery for SQL Server進(jìn)行恢復(fù)的操作步驟:
1. 運(yùn)行Recovery for SQL Server
2. 點擊菜單中的 File Recover,選擇要恢復(fù)的數(shù)據(jù)庫的數(shù)據(jù)文件(.mdf)
3. Next Next,進(jìn)入 Recovery Configuration 界面,選擇Custom(選擇了Custom才可以選擇從日志中恢復(fù)誤刪除的數(shù)據(jù))。
4. Next 進(jìn)入 Recovery options 窗口,選中 Search for deleted records,并選擇要恢復(fù)的數(shù)據(jù)庫的日志文件路徑(log file path)。
5. Next 并選擇目標(biāo)文件夾(Destination folder),用于存放恢復(fù)過程中生成的SQL語句與bat文件。
6. 點擊Start,開始恢復(fù)操作(在上一步選擇的目標(biāo)文件夾中生成相應(yīng)的SQL文件與Bat文件),然后,出現(xiàn) SQL Server Database Creation Utility 窗口。
7. Next,選擇被恢復(fù)數(shù)據(jù)存放的目標(biāo)數(shù)據(jù)庫。
8. Next, 選擇 Import availiable data from both database and log files
9. Next, Next, 然后就完成數(shù)據(jù)的恢復(fù)!
1、實現(xiàn)運(yùn)行Recovery for SQL Server操作如下。
2、點擊:Next Next--》進(jìn)入 Recovery Configuration 界面--》選擇了Custom才可以選擇從日志中恢復(fù)誤刪除的數(shù)據(jù)的操作如下。
3、Next 進(jìn)入 Recovery options 窗口--》選中 Search for deleted records,并選擇要恢復(fù)的數(shù)據(jù)庫的日志文件路徑log file path操作如下。
4、實現(xiàn)點擊next-》開始恢復(fù)操作如下。
5、點擊:Next選擇被恢復(fù)數(shù)據(jù)存放的目標(biāo)數(shù)據(jù)庫。
6、點擊:Finish然后就完成數(shù)據(jù)的恢復(fù)數(shù)據(jù)的操作如下。
恢復(fù)sqlserver數(shù)據(jù)庫表數(shù)據(jù)步驟如下:
一、心態(tài):
1、務(wù)必冷靜,事情已經(jīng)發(fā)生不可慌亂。
2、立即查看當(dāng)前時間,最好能夠精確到秒,并做記錄。
3、應(yīng)立即向直接上級反映此事,不可隱瞞,防止事態(tài)擴(kuò)大。
4、如果權(quán)限允許,應(yīng)當(dāng)立即停止相關(guān)應(yīng)用,防止有新的數(shù)據(jù)寫入數(shù)據(jù)庫。
二、恢復(fù):
1、構(gòu)建新數(shù)據(jù)庫以及寫入一些數(shù)據(jù)
2、做一次完整備份,這個是前提,沒有一份完整備份文件是無法進(jìn)行接下來的操作的。
注意:如上圖所示,恢復(fù)模式一定要說完整,如果是其他類型那恐怕就沒有下文了。一般來講新建數(shù)據(jù)庫的時候,默認(rèn)不要去改恢復(fù)模式這個屬性。
3、寫入一條新數(shù)據(jù)。
4、記住此時要記錄時間點。
此刻最好看一下系統(tǒng)時間。接下來就要演示如何進(jìn)行數(shù)據(jù)恢復(fù)。
5、做事務(wù)日志備份,做事務(wù)日志備份需要注意一下一點,如圖所示。
備份模式請選擇事務(wù)日志,備份路徑自行決定
進(jìn)入選項,將可靠性第1、2勾選,事務(wù)日志選擇第二個,壓縮屬性可以不選擇.點擊確定備份成功,此時數(shù)據(jù)庫將顯示為正在還原狀態(tài)
注意:如果備份失敗,請檢查該數(shù)據(jù)庫是否正在被占用,如果是請kill。
6、還原完整備份。
數(shù)據(jù)庫處于正在還原狀態(tài),右鍵數(shù)據(jù)庫--任務(wù)--還原--文件和文件組,選擇最近的一次完整備份。此時,需要在“選項”中選擇第二種還原方式,具體如下圖。
如上圖,勾選完整數(shù)據(jù)備份文件。
如上圖,恢復(fù)狀態(tài)選擇第二種,從字面意思就知道為什么要選擇這種。
7、接著還原備份的事務(wù)日志。
完整備份還原完畢,接著要對事務(wù)日志進(jìn)行還原,右鍵數(shù)據(jù)庫--任務(wù)--還原--事務(wù)日志,如下圖:
還原事務(wù)日志的時候需要特別注意“時間點”這個設(shè)置,其他不需要設(shè)置。
時間點選擇為誤刪數(shù)據(jù)的時間點之前就可以恢復(fù)出誤刪的數(shù)據(jù),所以之前強(qiáng)調(diào)要查看一下時間。如下圖所示
點擊確定,在確定等待還原成功,數(shù)據(jù)庫變成可用狀態(tài)。如下圖。
如果查詢發(fā)現(xiàn)數(shù)據(jù)不是你想要的,那么可以重復(fù)上述的操作,從備份事務(wù)日志開始,然后最后選擇時間點的時候在縮小范圍。
情況1、如果你有該庫的整體備份或?qū)@個表的單獨備份,那么也許可以恢復(fù)。可以將最新的備份恢復(fù)到一個備用的服務(wù)器上,導(dǎo)出那表的內(nèi)容,完成恢復(fù)
情況2、如果沒有任何備份,那就基本沒戲了。一般刪除表的操作是drop table,日志中不會記錄刪除具體行數(shù)的記錄。表所對應(yīng)目錄下的文件已經(jīng)被刪除(innodb獨立表空間,單表歸為一文件)。同樣的情況適用于myisam數(shù)據(jù)庫引擎,對應(yīng)的myd/myi/frm文件均被刪除。這不像windows還有垃圾箱,是不可逆的操作
此外,對數(shù)據(jù)庫最危險的操作就是對表進(jìn)行刪除行、刪除表或刪庫的操作了,所以任何對數(shù)據(jù)庫有高危風(fēng)險的操作前最重要的就是備份!備份!再備份!
FLASHBACK TABLE TABLENAME TO BEFORE DROP;不過只能用于不是purge的刪除,如果purge刪除了,除非你有備份,不然回天乏術(shù)
每個 DBA 是不是都有過刪庫的經(jīng)歷?刪庫了沒有備份怎么辦?備份恢復(fù)后無法啟動服務(wù)什么情況?表定義損壞數(shù)據(jù)無法讀取怎么辦?
我曾遇到某初創(chuàng)互聯(lián)網(wǎng)企業(yè),因維護(hù)人員不規(guī)范的備份恢復(fù)操作,導(dǎo)致系統(tǒng)表空間文件被初始化,上萬張表無法讀取,花了數(shù)小時才搶救回來。
當(dāng)你發(fā)現(xiàn)數(shù)據(jù)無法讀取時,也許并非數(shù)據(jù)丟失了,可能是 DBMS 找不到描述數(shù)據(jù)的信息。
背景
先來了解下幾張關(guān)鍵的 InnoDB 數(shù)據(jù)字典表,它們保存了部分表定義信息,在我們恢復(fù)表結(jié)構(gòu)時需要用到。
SYS_TABLES 描述 InnoDB 表信息CREATE TABLE `SYS_TABLES` (`NAME` varchar(255) NOT NULL DEFAULT '', ?表名`ID` bigint(20) unsigned NOT NULL DEFAULT '0', ?表id`N_COLS` int(10) DEFAULT NULL,`TYPE` int(10) unsigned DEFAULT NULL,`MIX_ID` bigint(20) unsigned DEFAULT NULL,`MIX_LEN` int(10) unsigned DEFAULT NULL,`CLUSTER_NAME` varchar(255) DEFAULT NULL,`SPACE` int(10) unsigned DEFAULT NULL, ? 表空間idPRIMARY KEY (`NAME`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;SYS_INDEXES 描述 InnoDB 索引信息CREATE TABLE `SYS_INDEXES` ( ?`TABLE_ID` bigint(20) unsigned NOT NULL DEFAULT '0', 與sys_tables的id對應(yīng) ?`ID` bigint(20) unsigned NOT NULL DEFAULT '0', ?索引id ?`NAME` varchar(120) DEFAULT NULL, ? ? ? ? 索引名稱 ?`N_FIELDS` int(10) unsigned DEFAULT NULL, 索引包含字段的個數(shù) ?`TYPE` int(10) unsigned DEFAULT NULL, ?`SPACE` int(10) unsigned DEFAULT NULL, ?存儲索引的表空間id ?`PAGE_NO` int(10) unsigned DEFAULT NULL, ?索引的root page id ?PRIMARY KEY (`TABLE_ID`,`ID`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;SYS_COLUMNS 描述 InnoDB 表的字段信息CREATE TABLE `SYS_COLUMNS` ( ?`TABLE_ID` bigint(20) unsigned NOT NULL, 與sys_tables的id對應(yīng) ?`POS` int(10) unsigned NOT NULL, ? ? 字段相對位置 ?`NAME` varchar(255) DEFAULT NULL, ? ?字段名稱 ?`MTYPE` int(10) unsigned DEFAULT NULL, ?字段編碼 ?`PRTYPE` int(10) unsigned DEFAULT NULL, 字段校驗類型 ?`LEN` int(10) unsigned DEFAULT NULL, ?字段字節(jié)長度 ?`PREC` int(10) unsigned DEFAULT NULL, 字段精度 ?PRIMARY KEY (`TABLE_ID`,`POS`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;SYS_FIELDS 描述全部索引的字段列CREATE TABLE `SYS_FIELDS` ( ?`INDEX_ID` bigint(20) unsigned NOT NULL, ?`POS` int(10) unsigned NOT NULL, ?`COL_NAME` varchar(255) DEFAULT NULL, ?PRIMARY KEY (`INDEX_ID`,`POS`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;./storage/innobase/include/dict0boot.h 文件定義了每個字典表的 index id,對應(yīng) id 的 page 中存儲著字典表的數(shù)據(jù)。
這里我們需要借助 undrop-for-innodb 工具恢復(fù)數(shù)據(jù),它能讀取表空間信息得到 page,將數(shù)據(jù)從 page 中提取出來。
# wget yum install -y gcc flex bison# make# make sys_parser
# ./sys_parser 讀取表結(jié)構(gòu)信息
sys_parser [-h] [-u] [-p] [-d] databases/table
stream_parser 讀取 InnoDB page 從 ibdata1 或 ibd 或分區(qū)表
# ./stream_parserYou must specify file with -f optionUsage: ./stream_parser -f innodb_datafile [-T N:M] [-s size] [-t size] [-V|-g] ?Where: ? ?-h ? ? ? ? - Print this help ? ?-V or -g ? - Print debug information ? ?-s size ? ?- Amount of memory used for disk cache (allowed examples 1G 10M). Default 100M ? ?-T ? ? ? ? - retrieves only pages with index id = NM (N - high word, M - low word of id) ? ?-t size ? ?- Size of InnoDB tablespace to scan. Use it only if the parser can't determine it by himself.
c_parser 從 innodb page 中讀取記錄保存到文件
# ./c_parserError: Usage: ./c_parser -4|-5|-6 [-dDV] -f InnoDB page or dir -t table.sql [-T N:M] [-b external pages directory] ?Where ? ?-f InnoDB page(s) -- InnoDB page or directory with pages(all pages should have same index_id) ? ?-t table.sql -- CREATE statement of a table ? ?-o file -- Save dump in this file. Otherwise print to stdout ? ?-l file -- Save SQL statements in this file. Otherwise print to stderr ? ?-h ?-- Print this help ? ?-d ?-- Process only those pages which potentially could have deleted records (default = NO) ? ?-D ?-- Recover deleted rows only (default = NO) ? ?-U ?-- Recover UNdeleted rows only (default = YES) ? ?-V ?-- Verbose mode (lots of debug information) ? ?-4 ?-- innodb_datafile is in REDUNDANT format ? ?-5 ?-- innodb_datafile is in COMPACT format ? ?-6 ?-- innodb_datafile is in MySQL 5.6 format ? ?-T ?-- retrieves only pages with index id = NM (N - high word, M - low word of id) ? ?-b dir -- Directory where external pages can be found. Usually it is pages-XXX/FIL_PAGE_TYPE_BLOB/ ? ?-i file -- Read external pages at their offsets from file. ? ?-p prefix -- Use prefix for a directory name in LOAD DATA INFILE command
接下來,我們演示場景的幾種數(shù)據(jù)恢復(fù)場景。
場景1:drop table
是否啟用了 innodb_file_per_table 其恢復(fù)方法有所差異,當(dāng)發(fā)生誤刪表時,應(yīng)盡快停止MySQL服務(wù),不要啟動。若 innodb_file_per_table=ON,最好只讀方式重新掛載文件系統(tǒng),防止其他進(jìn)程寫入數(shù)據(jù)覆蓋之前塊設(shè)備的數(shù)據(jù)。
如果評估記錄是否被覆蓋,可以表中某些記錄的作為關(guān)鍵字看是否能從 ibdata1 中篩選出。
#?grep WOODYHOFFMAN ibdata1
Binary file ibdata1 matches
也可以使用 bvi(適用于較小文件)或 hexdump -C(適用于較大文件)工具
以表 sakila.actor 為例CREATE TABLE `actor` (`actor_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,`first_name` varchar(45) NOT NULL,`last_name` varchar(45) NOT NULL,`last_update` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,PRIMARY KEY (`actor_id`),KEY `idx_actor_last_name` (`last_name`)) ENGINE=InnoDB AUTO_INCREMENT=201 DEFAULT CHARSET=utf8
首先恢復(fù)表結(jié)構(gòu)信息1. 解析系統(tǒng)表空間獲取 page 信息
./stream_parser -f /var/lib/mysql/ibdata1
2. 新建一個 schema,把系統(tǒng)字典表的 DDL 導(dǎo)入
cat dictionary/SYS_* | mysql recovered
3. 創(chuàng)建恢復(fù)目錄
mkdir -p dumps/default
4. 解析系統(tǒng)表空間包含的字典表信息,
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql dumps/default/SYS_TABLES 2 dumps/default/SYS_TABLES.sql./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000002.page -t dictionary/SYS_COLUMNS.sql dumps/default/SYS_COLUMNS 2 dumps/default/SYS_COLUMNS.sql./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql dumps/default/SYS_INDEXES 2 dumps/default/SYS_INDEXES.sql./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000004.page -t dictionary/SYS_FIELDS.sql dumps/default/SYS_FIELDS 2 dumps/default/SYS_FIELDS.sql
5. 導(dǎo)入恢復(fù)的數(shù)據(jù)字典
cat dumps/default/*.sql | mysql recovered
6. 讀取恢復(fù)后的表結(jié)構(gòu)信息
./sys_parser -pmsandbox -d recovered sakila/actor
由于 5.x 版本 innodb 引擎并非完整記錄表結(jié)構(gòu)信息,會丟失 AUTO_INCREMENT 屬性、二級索引和外鍵約束, DECIMAL 精度等信息。
若是 mysql 5.5 版本 frm 文件被從系統(tǒng)刪除,在原目錄下 touch 與原表名相同的 frm 文件,還能讀取表結(jié)構(gòu)信息和數(shù)據(jù)。若只有 frm 文件,想要獲得表結(jié)構(gòu)信息,可使用 mysqlfrm --diagnostic /path/to/xxx.frm,連接 mysql 會顯示字符集信息。
innodb_file_per_table=OFF
因為是共享表空間模式,數(shù)據(jù)頁都存儲在 ibdata1,可以從 ibdata1 文件中提取數(shù)據(jù)。
1. 獲取表的 table id,sys_table 存有表的 table id,sys_table 表 index id 是1,所以從0000000000000001.page 獲取表 id./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000001.page -t dictionary/SYS_TABLES.sql | grep sakila/actor000000000B28 ?2A000001430D4D ?SYS_TABLES ?"sakila/actor" ?158 ?4 ?1 0 ? 0 ? "" ?0000000000B28 ?2A000001430D4D ?SYS_TABLES ?"sakila/actor" ?158 ?4 ?1 0 ? 0 ? "" ?0
2. 利用 table id 獲取表的主鍵 id,sys_indexes 存有表索引信息,innodb 索引組織表,找到主鍵 id 即找到數(shù)據(jù),sys_indexes 的 index id 是3,所以從0000000000000003.page 獲取主鍵 id
./c_parser -4Df pages-ibdata1/FIL_PAGE_INDEX/0000000000000003.page -t dictionary/SYS_INDEXES.sql | grep 158000000000B28 ? ?2A000001430BCA ?SYS_INDEXES ? ? 158 ? ? 376 ? ? "PRIMARY" ? ? ? 1 ? ? ? 3 ? ? ? 0 ? ? ? 4294967295000000000B28 ? ?2A000001430C3C ?SYS_INDEXES ? ? 158 ? ? 377 ? ? "idx_actor_last_name" ? ? ? ?1 ? ? ? 0 ? ? ? 0 ? ? ? 4294967295000000000B28 ? ?2A000001430BCA ?SYS_INDEXES ? ? 158 ? ? 376 ? ? "PRIMARY" ? ? ? 1 ? ? ? 3 ? ? ? 0 ? ? ? 4294967295000000000B28 ? ?2A000001430C3C ?SYS_INDEXES ? ? 158 ? ? 377 ? ? "idx_actor_last_name" ? ? ? ?1 ? ? ? 0 ? ? ? 0 ? ? ? 4294967295
3. 知道了主鍵 id,就可以從對應(yīng) page 中提取表數(shù)據(jù),并生成 sql 文件。
./c_parser -4f pages-ibdata1/FIL_PAGE_INDEX/0000000000000376.page -t sakila/actor.sql dumps/default/actor 2 dumps/default/actor_load.sql
4. 最后導(dǎo)入恢復(fù)的數(shù)據(jù)
cat dumps/default/*.sql | mysql sakila
更多詳細(xì)情況點擊網(wǎng)頁鏈接
請點擊輸入圖片描述
分享題目:nosql誤刪表,mysql 誤刪表
本文地址:http://chinadenli.net/article18/dsgdsgp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供、定制開發(fā)、標(biāo)簽優(yōu)化、軟件開發(fā)、網(wǎng)站建設(shè)、關(guān)鍵詞優(yōu)化
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)