|
|
MySQL误删ibdata1 ib_logfile0,ib_logfile1 恢复方法:0 i0 a2 A- z# W, U! |1 F
w3 \) y( d6 W7 f% U- l% E
恢复的步骤和数据库版本没有太大关系。
& f; O- Z0 M& N2 F! R" U2 j在linux操作系统中,如果文件从操作系统级别别rm掉,之前打开的文件进程仍持有相应的文件句柄,
) d/ I6 y: r$ h" |所指向的文件仍然可以读写,且该文件的描述符可以从/proc目录中获得(不关闭MySQLd情况下).# k2 G' r: w" ]
/ Y/ M, }' }+ C0 E" V. a
在删除3个文件后,MySQLd 仍是可以运行,对外服务的,MySQL一只保持InnoDB文件打开,因此, S2 I2 U7 f9 d# X
在工作中有必要监控文件是否存在。3 O& z6 E% S0 C4 q, H @# K! W
发现文件被删除之后,不能重启InnoDB,因为启动InnoDB,检测到ibdata1,ib_logfile0,ib_logfile1
2 _# @7 H7 D0 j" ]- T8 E不存在,所以,将创建对应的空文件,InnoDB数据字典是空的,InnoDB无法使用原先存在的ibd文件,故,
) ]8 F d$ \$ Y& XMySQL不重启,快速恢复删除的文件是可能的。' u( B9 a s* M. S( \
7 y1 I# s0 H1 W W! Z
在MySQLd运行过程中,ibdata1,ib_logfile0,ib_logfile1一直运行在& w# T/ Q4 [+ g1 W# |
/proc/mysql.pid/fd目录下,其中vm-mysql.pid是mysql进程的PID,获取方法:+ N& B3 p/ L3 V0 b2 v
[root@mysql ~]# ls -l /proc/$(cat /opt/mysql/data2/mysql.pid)/fd | grep -e ibdata -e ib_4 G& i/ T& ^& q, u. q
lrwx------ 1 root root 64 Oct 16 14:16 10 -> /opt/mysql/data2/ib_logfile1 (deleted)' b. m9 Z' A1 G* z5 h8 L
lrwx------ 1 root root 64 Oct 16 14:16 4 -> /opt/mysql/data2/ibdata1 (deleted)1 l" j8 B0 y( E. }
lrwx------ 1 root root 64 Oct 16 14:16 9 -> /opt/mysql/data2/ib_logfile0 (deleted)
6 w$ g5 j8 D7 g, S' {
$ G+ U% t7 X+ r! W, F但是,我们不能简单copy回源目录中,因在buffer pool有已经修改的页,这些页没有被写入磁盘,如果改变的页4 z4 g& ]9 i8 W: v( G' Y- y$ S# y. g
没有永久写入,数据将会丢失,这些导致数据损坏和丢失。8 t4 }" h( |1 k; c, L
同样原因,我们不能做MySQL备份,仅能coping那些文件。
% l' g1 |4 I1 f! W$ U; O因此,我们必须确保所有的修改全写入磁盘中。
; s5 h! F' ]- V( y! q! e/ w我们现在能做的阻止写,且等待InnoDB刷新所有的页。% l& X- a& q, c( H. o1 z' Y7 U+ ]
1.为了阻止写,我们要么停止应用程序或锁表。& N" }5 f% u' @! _* O8 B
MariaDB [(none)]> flush tables with read lock;, J' G E3 f; x. N
Query OK, 0 rows affected (0.01 sec)" m5 B, R: y6 U; v& K# K) ^' X
" O/ I+ u" z% z5 K2. show engine innodb status 中脏页刷新到磁盘,
9 h( z3 i( x9 U4 I# K7 Z2 \5 ^---
) l2 _6 u) H+ w( h) ~, B) mLOG: n$ S% w; }/ G, g; {" x6 ]
---
V5 }( D+ _% T7 G, MLog sequence number 0 50355
: ]! ]# N" |1 z) i2 L8 L3 I) _6 RLog flushed up to 0 50355
: u- g$ j" L+ B* @( P7 HLast checkpoint at 0 50355
. {7 g9 n0 n0 k7 V0 pending log writes, 0 pending chkp writes3 `: [1 [' S) J8 @- i2 \; j
39 log i/o's done, 0.00 log i/o's/second
% v& U! [2 l: Q( ]2 `/ P2 z1 r! [/ G' b8 M* x" l+ w2 c& Q7 T# c
加速脏页刷新,设置dirty pages percentage to zero:5 w) X) ^1 \. |" L4 n# a- ]
MariaDB [(none)]> set global innodb_max_dirty_pages_pct=0;" O6 F3 ?% t: _
Query OK, 0 rows affected (0.00 sec)
; I; m. O* Y+ U9 K! n0 V& p9 D% u6 O2 {: O% F0 { M
3.确保所有后台进程已经完成自己的工作,也是重要的。* y. @, V7 K4 B3 T# Z% a
注意,插入缓冲线程,它的大小等于1) {& q0 k5 A* S5 J( _, ^
-------------------------------------
) s" I% K, K% H* B( M0 tINSERT BUFFER AND ADAPTIVE HASH INDEX
2 L( ?- `8 u q-------------------------------------
! i2 f8 k) ]7 x0 H2 j) e& B& hIbuf: size 1, free list len 0, seg size 2,& E; C/ ]* ?- d& \- w0 v
0 inserts, 0 merged recs, 0 merges- f& B) D+ q1 T& d( g* R. F
Hash table size 34679, node heap has 1 buffer(s)
% }2 ^; v; I0 ?* O0.00 hash searches/s, 0.00 non-hash searches/s4 |, _/ g6 A; @' {# D
[: O+ y9 t+ {5 m2 y5 F
4.后台写进程purge thread,清除所有事务。- t% f) g8 l* U; \
------------$ k& Q# P7 m* ]
TRANSACTIONS
, n0 Y. r n7 i, I# p0 c9 u& ]------------
8 }7 I( I: X+ e/ a( Q9 Z1 r! @/ STrx id counter 0 784) F# C- o+ F# T! v7 |& q
Purge done for trx's n:o < 0 0 undo n:o < 0 0
0 U; K" `9 n0 ]0 P3 A6 ]但是,如果上次事务没有需要清理操作Trx id计数比较大(如,SELECT),
4 p; e9 m& O0 Z( p& V/ }: p: c' k在这种情况下,至少要保证InnoDB不再做任何写动作。
p5 V8 s6 P! T* g3 P--------7 f5 v% U" D: Y0 s
FILE I/O
, p$ i9 g& ^2 a- ^2 ]8 {--------
4 o# M# s. t7 PI/O thread 0 state: waiting for i/o request (insert buffer thread)
# m, H' @4 \9 n, q8 \* qI/O thread 1 state: waiting for i/o request (log thread)
4 e q" V, o$ c- X5 h" m$ R& M: @. tI/O thread 2 state: waiting for i/o request (read thread)
. R/ _: B# `) B/ a) k) eI/O thread 3 state: waiting for i/o request (write thread)1 l0 U9 K$ `. A, \
Pending normal aio reads: 0, aio writes: 0,
; h z- Z- E, J# c" i0 J ibuf aio reads: 0, log i/o's: 0, sync i/o's: 01 \' s7 A- ]0 W. Z
Pending flushes (fsync) log: 0; buffer pool: 0 S' e2 g% {5 Y3 ~1 }6 A" I" T
0 OS file reads, 81 OS file writes, 59 OS fsyncs f3 J) R- Q* L7 [0 X
0.00 reads/s, 0 avg bytes/read, 0.00 writes/s, 0.00 fsyncs/s- C6 V4 V- _4 \ j2 ]4 T4 B
' @- ~3 c6 z& g+ l0 `/ z
经历了4步,所有被修改脏页刷新到磁盘,现在开始copy InnoDB 文件到源目录:1 Z r6 [) G. c" e! u
[root@mysql ~]# cp /proc/$(cat /opt/mysql/data2/mysql.pid)/fd/4 /opt/mysql/data2/ibdata1
9 ?$ V- A- N O1 m[root@mysql ~]# cp /proc/$(cat /opt/mysql/data2/mysql.pid)/fd/9 /opt/mysql/data2/ib_logfile0
8 T6 k) B- V/ P3 H$ I( ?3 c/ X y[root@mysql ~]# cp /proc/$(cat /opt/mysql/data2/mysql.pid)/fd/10 /opt/mysql/data2/ib_logfile1! ]9 P9 c1 L* O: g+ u
9 p# r4 R" ^- m: m2 G
5.修改ib*所属用户 T* q5 ~2 d- i O# E- r% F2 U" o
chown -R mysql ib*
5 G- N, [: U# v: E) ^8 e7 M, l6 i j7 @0 F' S
6.重启MySQLd3 F. G( j$ x/ @7 O6 G" ]
........) X3 S# t8 R$ [2 B; r; W) T. ^8 F' o. O
- {/ f# e! M( Y( o, [
结论:
, E* ?( }+ v0 U7 i% T1.监控InnoDB文件 ibdata 和 ib_logfile* 是否存在$ c* k8 E! x( A i3 T/ B4 t
2.清楚恢复策略,否则不要重启MySQLd& ?% Q: Q+ @% D4 q Q- i
|
|