追着幸福跑|数据库没有备份,没有使用Binlog的情况下,如何恢复数据?


追着幸福跑|数据库没有备份,没有使用Binlog的情况下,如何恢复数据?公众号 :码农架构
MySQL 的复制主要是通过 Binlog 来完成的 , Binlog 记录了数据库更新的事件 , 从库 I/O 线程会向主库发送 Binlog 更新的请求 , 同时主库二进制转储线程会发送 Binlog 给从库作为中继日志进行保存 , 然后从库会通过中继日志重放 , 完成数据库的同步更新 , 看来是一套完美的的灾备方案!但是有没有经历过“手抖”后的“绝望” 。
嗯!你志哥以前干过
追着幸福跑|数据库没有备份,没有使用Binlog的情况下,如何恢复数据?直接在生产环境中对数据进行操作 , 或者忘记了当前是在开发环境 , 还是在生产环境中 , 就直接对数据库进行操作 。
当然如果我们对数据库做过时间点备份 , 也可以直接恢复到该时间点 。 不过我们今天要讨论的是一个特殊的情况 , 也就是在没做数据库备份 , 没有开启使用 Binlog 的情况下 , 尽可能地找回数据 。
今天的分享内容主要包括以下几个部分

  1. InnoDB 存储引擎中的表空间是怎样的?两种表空间存储方式各有哪些优缺点?
  2. 如果.ibd 文件损坏了 , 数据该如何找回?
  3. 如何模拟 InnoDB 文件的损坏与数据恢复?
InnoDB 存储引擎的表空间
InnoDB 存储引擎的文件格式是.ibd 文件 , 数据会按照表空间(tablespace)进行存储 , 分为共享表空间和独立表空间 。 如果想要查看表空间的存储方式 , 我们可以对innodb_file_per_table变量进行查询 , 使用show variables like 'innodb_file_per_table'; 。 ON 表示独立表空间 , 而 OFF 则表示共享表空间 。
追着幸福跑|数据库没有备份,没有使用Binlog的情况下,如何恢复数据?如果采用共享表空间的模式 , InnoDB 存储的表数据都会放到共享表空间中 , 也就是多个数据表共用一个表空间 , 同时表空间也会自动分成多个文件存放到磁盘上 。 这样做的好处在于单个数据表的大小可以突破文件系统大小的限制 , 最大可以达到 64TB , 也就是 InnoDB 存储引擎表空间的上限 。 不足也很明显 , 多个数据表存放到一起 , 结构不清晰 , 不利于数据的找回 , 同时将所有数据和索引都存放到一个文件中 , 也会使得共享表空间的文件很大 。
【追着幸福跑|数据库没有备份,没有使用Binlog的情况下,如何恢复数据?】采用独立表空间的方式可以让每个数据表都有自己的物理文件 , 也就是 table_name.ibd 的文件 , 在这个文件中保存了数据表中的数据、索引、表的内部数据字典等信息 。 它的优势在于每张表都相互独立 , 不会影响到其他数据表 , 存储结构清晰 , 利于数据恢复 , 同时数据表还可以在不同的数据库之间进行迁移 。
如果.ibd 文件损坏了 , 数据如何找回
如果我们之前没有做过全量备份 , 也没有开启 Binlog , 那么我们还可以通过.ibd 文件进行数据恢复 , 采用独立表空间的方式可以很方便地对数据库进行迁移和分析 。 如果我们误删除(DELETE)某个数据表或者某些数据行 , 也可以采用第三方工具回数据 。
我们这里可以使用 Percona Data Recovery Tool for InnoDB 工具 , 能使用工具进行修复是因为我们在使用 DELETE 的时候是逻辑删除 。 我们之前学习过 InnoDB 的页结构 , 在保存数据行的时候还有个删除标记位 , 对应的是页结构中的 delete_mask 属性 , 该属性为 1 的时候标记了记录已经被逻辑删除 , 实际上并不是真的删除 。 不过当有新的记录插入的时候 , 被删除的行记录可能会被覆盖掉 。 所以当我们发生了 DELETE 误删除的时候 , 一定要第一时间停止对误删除的表进行更新和写入 , 及时将.ibd 文件拷贝出来并进行修复 。


推荐阅读