zoukankan      html  css  js  c++  java
  • 0929误删除innodb ibdata数据文件

    今天在群里看到有人说不熟悉innodb把ibdata(数据文件)和ib_logfile(事务日志)文件误删除了。不知道怎么解决。当时我也不知道怎么办。后来查阅相关资料。终找到解决方法。其实恢复也挺简单的。我们不知道的时候就觉得难了。谁说不是这样呢?

    下面我们就来模拟生产环境下,人为删除数据文件和重做日志文件。然后详细说明恢复步骤。

    1.用sysbench模拟数据的写入,如下所示:

    [root@yayun-mysql-server ~]# sysbench --test=oltp --oltp-table-size=1000000 --oltp-read-only=off --init-rng=on --num-threads=16 --max-requests=0 --oltp-dist-type=uniform --max-time=1800 --mysql-user=root --mysql-socket=/tmp/mysqld.sock --mysql-password=123456 --db-driver=mysql --mysql-table-engine=innodb --oltp-test-mode=complex prepare      
    sysbench 0.4.10:  multi-threaded system evaluation benchmark
    
    Creating table 'sbtest'...
    Creating 1000000 records in table 'sbtest'...

    2.使用命令rm -f ib*删除数据文件和事务日志文件:

    复制代码
    [root@yayun-mysql-server mysql]# ls
    employees    ib_logfile1       mysql-bin.000003  mysql-bin.000008  performance_schema  world_innodb                  yayun-mysql-server.pid
    general.log  menagerie         mysql-bin.000004  mysql-bin.000009  sakila              world_myisam
    host         mysql             mysql-bin.000005  mysql-bin.000010  sbtest              xtrabackup_binlog_pos_innodb
    ibdata1      mysql-bin.000001  mysql-bin.000006  mysql-bin.index   slow-query.log      yayun
    ib_logfile0  mysql-bin.000002  mysql-bin.000007  percona           test                yayun-mysql-server.err
    [root@yayun-mysql-server mysql]# rm -f ib*
    [root@yayun-mysql-server mysql]# 
    复制代码

    下面我们来看看如何恢复:

    若此时发现数据库还能正常工作,数据依然可读可写,切记:这个时候千万不要把mysqld进程杀死,否则真没法挽救了,你就等着哭吧。

    复制代码
    (root@yayun 20:42:25pm> ) [yayun]>select * from t1;
    +----+-------+
    | id | name  |
    +----+-------+
    |  1 | yayun |
    |  2 | atlas |
    |  3 | mysql |
    +----+-------+
    3 rows in set (0.00 sec)
    
    (root@yayun 20:42:28pm> ) [yayun]>insert into t1 select 4,'python';
    Query OK, 1 row affected (0.01 sec)
    Records: 1  Duplicates: 0  Warnings: 0
    
    (root@yayun 20:42:48pm> ) [yayun]>select * from t1;                
    +----+--------+
    | id | name   |
    +----+--------+
    |  1 | yayun  |
    |  2 | atlas  |
    |  3 | mysql  |
    |  4 | python |
    +----+--------+
    4 rows in set (0.00 sec)
    
    (root@yayun 20:42:50pm> ) [yayun]>
    复制代码

    我这里读写都正常。所以我们能够恢复成功的。
    (1)首先,先找到mysqld进程的pid,如下所示:

    [root@yayun-mysql-server ~]# netstat -nltp | grep mysqld
    tcp        0      0 0.0.0.0:3306                0.0.0.0:*                   LISTEN      5725/mysqld         
    [root@yayun-mysql-server ~]# 

    可见mysqld的pid是5725,这一步是关键的一步。

    (2)使用如下命令查看结果(非常重要)

    [root@yayun-mysql-server ~]# ll /proc/5725/fd | egrep 'ib_|ibdata'
    lrwx------. 1 root root 64 Apr 30 20:44 10 -> /data/mysql/ib_logfile1 (deleted)
    lrwx------. 1 root root 64 Apr 30 20:44 4 -> /data/mysql/ibdata1 (deleted)
    lrwx------. 1 root root 64 Apr 30 20:44 9 -> /data/mysql/ib_logfile0 (deleted)
    [root@yayun-mysql-server ~]# 

    这里有相关很重要的知识,童鞋们自行查阅,删除一个文件时,并不是真正删除,而是打一个标记,同样在我们mysql数据库中,delete一条记录实际的删除操作也没有发生。
    上面显示的结果中,其中10,4,9就是我们需要恢复的文件。

    (3)在恢复文件前,需要执行flush tables with read lock,确保数据库没有写入操作,以便我们完成恢复

    (root@yayun 20:55:26pm> ) [(none)]>flush tables with read lock;
    Query OK, 0 rows affected (0.00 sec)
    
    (root@yayun 20:55:31pm> ) [(none)]>

    那么我们如何确定没有数据写入呢?分几个步骤查看

    (1)设置脏页刷新比例(让脏页尽快刷新到磁盘)

    (root@yayun 20:55:31pm> ) [(none)]>set global innodb_max_dirty_pages_pct=0;
    Query OK, 0 rows affected (0.00 sec)
    
    (root@yayun 20:57:42pm> ) [(none)]>

    (2)查看binlog日志写入情况,确保File和Position的值没有发生变化

    复制代码
    (root@yayun 20:57:42pm> ) [(none)]>show master status;
    +------------------+----------+--------------+------------------+
    | File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
    +------------------+----------+--------------+------------------+
    | mysql-bin.000010 | 61704130 |              |                  |
    +------------------+----------+--------------+------------------+
    1 row in set (0.00 sec)
    
    (root@yayun 20:59:11pm> ) [(none)]>
    复制代码

    (3)查看innodb状态信息,确保脏页已经刷新到磁盘

    复制代码
    (root@yayun 20:59:11pm> ) [(none)]>show engine innodb statusG
    ------------
    TRANSACTIONS
    ------------
    Trx id counter B9E0F
    Purge done for trx's n:o < B9E0C undo n:o < 0    #确保后台线程purge把undo log全部清刷掉
    
    -------------------------------------
    INSERT BUFFER AND ADAPTIVE HASH INDEX
    -------------------------------------
    Ibuf: size 1, free list len 2543, seg size 2545, 0 merges  #确保合并插入缓存等于1
    
    ---
    LOG
    ---
    Log sequence number 6173930288
    Log flushed up to   6173930288            #确保这里三个值保持一致,并且不再变化
    Last checkpoint at  6173930288
    
    Buffer pool size   65534
    Free buffers       50513
    Database pages     15020
    Old database pages 5506
    Modified db pages  0                       #确保脏页数量为0
    
    --------------
    ROW OPERATIONS
    --------------
    0 queries inside InnoDB, 0 queries in queue
    1 read views open inside InnoDB
    Main thread process no. 5725, id 140014471358208, state: waiting for server activity
    Number of rows inserted 1000004, updated 1995, deleted 0, read 2008
    0.00 inserts/s, 0.00 updates/s, 0.00 deletes/s, 0.00 reads/s           #确保插入,更新,删除为0
    复制代码

    上面我们都确认后,就可以进行恢复操作了。记得前面我们查看要恢复的文件的命令吧,我们的mysqld进程的pid是5725,我们再次看看需要恢复的文件

    [root@yayun-mysql-server ~]# ll /proc/5725/fd | egrep 'ib_|ibdata'
    lrwx------. 1 root root 64 Apr 30 20:44 10 -> /data/mysql/ib_logfile1 (deleted)
    lrwx------. 1 root root 64 Apr 30 20:44 4 -> /data/mysql/ibdata1 (deleted)
    lrwx------. 1 root root 64 Apr 30 20:44 9 -> /data/mysql/ib_logfile0 (deleted)
    [root@yayun-mysql-server ~]# 

    把10,4,9文件cp到原来mysql的数据目录下:

    [root@yayun-mysql-server ~]# cd /proc/5725/fd
    [root@yayun-mysql-server fd]# cp 10 /data/mysql/ib_logfile1
    [root@yayun-mysql-server fd]# cp 4 /data/mysql/ibdata1
    [root@yayun-mysql-server fd]# cp 9 /data/mysql/ib_logfile0
    [root@yayun-mysql-server fd]# 

    修改文件权限

    复制代码
    [root@yayun-mysql-server ~]# cd /data/mysql
    [root@yayun-mysql-server mysql]# chown -R mysql.mysql ib*
    [root@yayun-mysql-server mysql]# ll | egrep 'ib_|ibdata1'
    -rw-r--r-- 1 mysql mysql 866123776 Apr 30 21:13 ibdata1
    -rw-r--r-- 1 mysql mysql  67108864 Apr 30 21:13 ib_logfile0
    -rw-r--r-- 1 mysql mysql  67108864 Apr 30 21:11 ib_logfile1
    [root@yayun-mysql-server mysql]# 
    复制代码

    重启mysql,修复完成

    [root@yayun-mysql-server mysql]# /etc/init.d/mysqld restart
    Shutting down MySQL...                                     [  OK  ]
    Starting MySQL....                                         [  OK  ]
    [root@yayun-mysql-server mysql]# 

    注意:生产环境切勿测试,童鞋们可以自己开启虚拟机进行测试。

  • 相关阅读:
    加入创业公司有什么利弊
    Find Minimum in Rotated Sorted Array II
    Search in Rotated Sorted Array II
    Search in Rotated Sorted Array
    Find Minimum in Rotated Sorted Array
    Remove Duplicates from Sorted Array
    Spiral Matrix
    Spiral Matrix II
    Symmetric Tree
    Rotate Image
  • 原文地址:https://www.cnblogs.com/qcfeng/p/7611707.html
Copyright © 2011-2022 走看看