我们上节课讲解了 MySQL 的复制技术,通过主从同步可以实现读写分离,热备份,让服务器更加高可用。MySQL 的复制主要是通过 Binlog 来完成的,Binlog 记录了数据库更新的事件,从库 I/O 线程会向主库发送 Binlog 更新的请求,同时主库二进制转储线程会发送 Binlog 给从库作为中继日志进行保存,然后从库会通过中继日志重放,完成数据库的同步更新。这种同步操作是近乎实时的同步,然而也有人为误操作情况的发生,比如 DBA 人员为了方便直接在生产环境中对数据进行操作,或者忘记了当前是在开发环境,还是在生产环境中,就直接对数据库进行操作,这样很有可能会造成数据的丢失,情况严重时,误操作还有可能同步给从库实时更新。不过我们依然有一些策略可以防止这种误操作,比如利用延迟备份的机制。延迟备份最大的作用就是避免这种“手抖”的情况,让我们在延迟从库进行误操作前停止下来,进行数据库的恢复。
当然如果我们对数据库做过时间点备份,也可以直接恢复到该时间点。不过我们今天要讨论的是一个特殊的情况,也就是在没做数据库备份,没有开启使用 Binlog 的情况下,尽可能地找回数据。
今天的内容主要包括以下几个部分:
InnoDB 存储引擎中的表空间是怎样的?两种表空间存储方式各有哪些优缺点?
如果.ibd 文件损坏了,数据该如何找回?
如何模拟 InnoDB 文件的损坏与数据恢复?
InnoDB 存储引擎的表空间
InnoDB 存储引擎的文件格式是.ibd 文件,数据会按照表空间(tablespace)进行存储,分为共享表空间和独立表空间。如果想要查看表空间的存储方式,我们可以对innodb_file_per_table变量进行查询,使用show variables like 'innodb_file_per_table';。ON 表示独立表空间,而 OFF 则表示共享表空间。
如果采用共享表空间的模式,InnoDB 存储的表数据都会放到共享表空间中,也就是多个数据表共用一个表空间,同时表空间也会自动分成多个文件存放到磁盘上。这样做的好处在于单个数据表的大小可以突破文件系统大小的限制,最大可以达到 64TB,也就是 InnoDB 存储引擎表空间的上限。不足也很明显,多个数据表存放到一起,结构不清晰,不利于数据的找回,同时将所有数据和索引都存放到一个文件中,也会使得共享表空间的文件很大。
采用独立表空间的方式可以让每个数据表都有自己的物理文件,也就是 table_name.ibd 的文件,在这个文件中保存了数据表中的数据、索引、表的内部数据字典等信息。它的优势在于每张表都相互独立,不会影响到其他数据表,存储结构清晰,利于数据恢复,同时数据表还可以在不同的数据库之间进行迁移。
如果.ibd 文件损坏了,数据如何找回
如果我们之前没有做过全量备份,也没有开启 Binlog,那么我们还可以通过.ibd 文件进行数据恢复,采用独立表空间的方式可