MySQL表损坏预防与修复

1.       表损坏的原因分析

以下原因是导致mysql 表毁坏的常见原因:

1、 服务器突然断电导致数据文件损坏。

2、 强制关机,没有先关闭mysql 服务。

3、 mysqld 进程在写表时被杀掉。

4、 使用myisamchk 的同时,mysqld 也在操作表。

5、 磁盘故障。

6、 服务器死机。

7、 mysql 本身的bug 。

2.       表损坏的症状

一个损坏的表的典型症状如下:

1 、当在从表中选择数据之时,你得到如下错误:

Incorrect key file for table: ‘...‘. Try to repair it

2 、查询不能在表中找到行或返回不完全的数据。

3 、Error: Table ‘p‘ is marked as crashed and should be repaired 。

4 、打开表失败: Can’t open file: ‘×××.MYI’ (errno: 145) 。

5 、

3.       预防 MySQL 表损坏

可以采用以下手段预防mysql 表损坏:

1 、定期使用myisamchk 检查MyISAM 表(注意要关闭mysqld ),推荐使用check table 来检查表(不用关闭mysqld )。

2 、在做过大量的更新或删除操作后,推荐使用OPTIMIZE TABLE 来优化表,这样既减少了文件碎片,又减少了表损坏的概率。

3 、关闭服务器前,先关闭mysqld (正常关闭服务,不要使用kill -9 来杀进程)。

4 、使用ups 电源,避免出现突然断电的情况。

5 、使用最新的稳定发布版mysql ,减少mysql 本身的bug 导致表损坏。

6 、对于InnoDB 引擎,你可以使用innodb_tablespace_monitor 来检查表空间文件内文件空间管理的完整性。

7 、对磁盘做raid ,减少磁盘出错并提高性能。

8 、数据库服务器最好只跑mysqld 和必要的其他服务,不要跑其他业务服务,这样减少死机导致表损坏的可能。

9 、不怕万一,只怕意外,平时做好备份是预防表损坏的有效手段。

4.       MySQL 表损坏的修复

MyISAM 表可以采用以下步骤进行修复 

1、  使用 reapair table 或myisamchk 来修复。

2、  如果上面的方法修复无效,采用备份恢复表。

具体可以参考如下做法:

阶段1 :检查你的表

如果你有很多时间,运行myisamchk *.MYI 或myisamchk -e *.MYI 。使用-s (沉默)选项禁止不必要的信息。

如果mysqld 服务器处于宕机状态,应使用--update-state 选项来告诉myisamchk 将表标记为‘ 检查过的‘ 。

你必须只修复那些myisamchk 报告有错误的表。对这样的表,继续到阶段2 。

如果在检查时,你得到奇怪的错误( 例如out of memory 错误) ,或如果myisamchk 崩溃,到阶段3。

阶段2 :简单安全的修复

注释:如果想更快地进行修复,当运行myisamchk 时,你应将sort_buffer_size 和Key_buffer_size变量的值设置为可用内存的大约25% 。

首先,试试myisamchk -r -q tbl_name(-r -q 意味着“ 快速恢复模式”) 。这将试图不接触数据文件来修复索引文件。如果数据文件包含它应有的一切内容和指向数据文件内正确地点的删除连接,这应该管用并且表可被修复。开始修复下一张表。否则,执行下列过程:

在继续前对数据文件进行备份。

使用myisamchk -r tbl_name(-r 意味着“ 恢复模式”) 。这将从数据文件中删除不正确的记录和已被删除的记录并重建索引文件。

如果前面的步骤失败,使用myisamchk --safe-recover tbl_name 。安全恢复模式使用一个老的恢复方法,处理常规恢复模式不行的少数情况( 但是更慢) 。

如果在修复时,你得到奇怪的错误( 例如out of memory 错误) ,或如果myisamchk 崩溃,到阶段3。

阶段3 :困难的修复

只有在索引文件的第一个16K 块被破坏,或包含不正确的信息,或如果索引文件丢失,你才应该到这个阶段。在这种情况下,需要创建一个新的索引文件。按如下步骤操做:

把数据文件移到安全的地方。

使用表描述文件创建新的( 空) 数据文件和索引文件:

shell> mysql db_name

mysql> SET AUTOCOMMIT=1;

mysql> TRUNCATE TABLE tbl_name;

mysql> quit

如果你的MySQL 版本没有TRUNCATE TABLE ,则使用DELETE FROM tbl_name 。

将老的数据文件拷贝到新创建的数据文件之中。(不要只是将老文件移回新文件之中;你要保留一个副本以防某些东西出错。)

回到阶段2 。现在myisamchk -r -q 应该工作了。(这不应该是一个无限循环)。

你还可以使用REPAIR TABLE tbl_name USE_FRM ,将自动执行整个程序。

阶段4 :非常困难的修复

只有.frm 描述文件也破坏了,你才应该到达这个阶段。这应该从未发生过,因为在表被创建以后,描述文件就不再改变了。

从一个备份恢复描述文件然后回到阶段3 。你也可以恢复索引文件然后回到阶段2 。对后者,你应该用myisamchk -r 启动。

如果你没有进行备份但是确切地知道表是怎样创建的,在另一个数据库中创建表的一个拷贝。删除新的数据文件,然后从其他数据库将描述文件和索引文件移到破坏的数据库中。这样提供了新的描述和索引文件,但是让.MYD 数据文件独自留下来了。回到阶段2 并且尝试重建索引文件。

InnoDB 表可以采用下面的方法修复:

如果数据库页被破坏,你可能想要用SELECT INTO OUTFILE 从从数据库转储你的表,通常以这种方法获取的大多数数据是完好的。即使这样,损坏可能导致SELECT * FROM tbl_name 或者InnoDB 后台操作崩溃或断言,或者甚至使得InnoDB 前滚恢复崩溃。 尽管如此,你可以用它来强制InnoDB 存储引擎启动同时阻止后台操作运行,以便你能转储你的表。例如:你可以在重启服务器之前,在选项文件的[mysqld] 节添加如下的行: 
    [mysqld]innodb_force_recovery = 4innodb_force_recovery 被允许的非零值如下。一个更大的数字包含所有更小数字的预防措施。如果你能够用一个多数是4 的选项值来转储你的表,那么你是比较安全的,只有一些在损坏的单独页面上的数据会丢失。一个为6 的值更夸张,因为数据库页被留在一个陈旧的状态,这个状态反过来可以引发对B 树和其它数据库结构的更多破坏。 
    1 (SRV_FORCE_IGNORE_CORRUPT) 
即使服务器检测到一个损坏的页,也让服务器运行着;试着让SELECT * FROM tbl_name 跳过损坏的索引记录和页,这样有助于转储表。

2 (SRV_FORCE_NO_BACKGROUND) 
阻止主线程运行,如果崩溃可能在净化操作过程中发生,这将阻止它。 
    3 (SRV_FORCE_NO_TRX_UNDO) 
恢复后不运行事务回滚。 
    4 (SRV_FORCE_NO_IBUF_MERGE) 
也阻止插入缓冲合并操作。如果你可能会导致一个崩溃。最好不要做这些操作,不要计算表统计表。 
    5 (SRV_FORCE_NO_UNDO_LOG_SCAN) 
启动数据库之时不查看未完成日志:InnoDB 把未完成的事务视为已提交的。 
    6 (SRV_FORCE_NO_LOG_REDO) 
不要在恢复连接中做日志前滚。 
    数据库不能另外地带着这些选项中被允许的选项来使用。作为一个安全措施,当innodb_force_recovery 被设置为大于0 的值时,InnoDB 阻止用户执行INSERT, UPDATE 或DELETE操作. 
    即使强制恢复被使用,你也可以DROP 或CREATE 表。如果你知道一个给定的表正在导致回滚崩溃,你可以移除它。你也可以用这个来停止由失败的大宗导入或失败的ALTER TABLE 导致的失控回滚。你可以杀掉mysqld 进程,然后设置innodb_force_recovery 为3 ,使得数据库被挂起而不需要回滚,然后舍弃导致失控回滚的表。

转载:http://blog.csdn.net/forever_feng/article/details/5305070

时间: 2024-08-27 08:06:23

MySQL表损坏预防与修复的相关文章

MySQL数据库表损坏后的修复方法

步骤:1.sql语句:check table tabTest; 如果出现的结果说Status是OK,则不用修复,如果有Error2.Linux执行: myisamchk -r -q /var/lib/mysql/db/test.MYI 3.sql语句:repair table tabTest; 4.sql语句:check table tabTest; Status是OK就修复好了 非Linux上:直接 参考:有两种方法,一种方法使用mysql的check table和repair table 的

查询mysql表是否被损坏和修复、优化

查询mysql表是否被损坏命令,如下: # CHECK TABLE 表名 mysql的长期使用,肯定会出现一些问题,一般情况下mysql表无法访问,就可以修复表了,优化时减少磁盘占用空间.方便备份. 表修复和优化命令,如下: #REPAIR TABLE `table_name` 修复表 #OPTIMIZE TABLE `table_name` 优化表 REPAIR TABLE 用于修复被破坏的表. OPTIMIZE TABLE 用于回收闲置的数据库空间,当表上的数据行被删除时,所占据的磁盘空间并

检查和修复mysql表:mysql table is marked as crashed and last (automatic?) repair failed

0x001  问题背景 mysql上执行相关mysql命令(我们执行的是,show procedure status)时提示 mysql.proc表crashed,无法修复(marked as crashed and last (automatic?) repair failed ) 报错信息:mysql table is marked as crashed and last (automatic?) repair failed 0x002  分析处理 mysql提供了检查和修复表的命令: my

mysql.user表重置密码后出现表损坏问题

首先是发现了mysql数据库无论输入什么密码,都会直接进入数据库,没有验证.接下来开始入坑: 1 知道是因为my.ini文件中有    skip-grant-tables      可是当时不知道密码忘记了还是user表已经出现了异常,密码一直错误. 2 第二步,修改密码,可是mysql版本是5.7,按照password无法修改密码.于是直接在可视乎里加了一个password列,噩梦出现,password倒是加上了,密码列也修改成功了.skip也删除了,mysql也进去了,可是就是无法使用数据库

mysql数据损坏修复方法

1.myisamchk使用 myisamchk 必须暂时停止 MySQL 服务器.例如,我们要检修 discuz 数据库.执行以下操作:# service mysql stop (停止 MySQL ):# myisamchk -r /数据库文件的绝对路径/*MYI# service mysql startmyisamchk 会自动检查并修复数据表中的索引错误.2.mysqlcheck使用 mysqlcheck 无需停止 MySQL ,可以进行热修复.操作步骤如下:# mysqlcheck -r

修复mysql表

1>用"repair table"方式修复语法:repair table 表名 [选项]选项如下:QUICK 用在数据表还没被修改的情况下,速度最快EXTENDED 试图去恢复每个数据行,会产生一些垃圾数据行,万般无奈的情况下用USE_FRM 用在.MYI文件丢失或者头部受到破坏的情况下.利用.frm的定义来重建索引多数情况下,简单得用"repair table tablename"不加选项就可以搞定问题.但是当.MYI文件丢失或者头部受到破坏时,这样的方式不

MYSQL Truncate 引发数据表损坏案例分析

最近发布到市场的版本频繁出现数据库表损坏的情况,具体的现象是select表提示表不存在,但是查看data文件,对应表的ibd和frm文件都在. 通过对多个故障的统计,找到几个频繁出现损坏的表,在分析过程中,发现这些数据表都使用了truncate清除数据,所以怀疑是truncate操作的问题. 设计如下过程来验证这个分析结果: 1. 创建存储过程如下,对一张表模拟频繁调用TRUNCATE DROP PROCEDURE IF EXISTS prcTest5;CREATE PROCEDURE prcT

mysql表空间损坏

在没有备份数据的情况下,突然断电导致表损坏,打不开数据库.1)拷贝库目录到新库中[[email protected] ~]# cp -r /application/mysql/data/world/ /data/3307/data/2)启动新数据库[[email protected] ~]# mysqld_safe --defaults-file=/data/3307/my.cnf &3)登陆数据库查看mysql> show databases;4)查询表中数据mysql> selec

sql 2008R2系统表损坏

某客户单位,一台运行服务器突然出现故障不能进入系统,里面有运行的用友数据库,出现故障后自己公司DBA以及运维折腾了将近一星期后来能够进入系统了发现数据库已经无法正常使用,且所有之前6月份备份都损坏了,最近的备份也只有4月30号的,询问那边做过什么操作时,客户已经描述不清,无奈只能让客户发库过来看,客户是用友U8数据库运行平台为2008r2. 对数据MDF文件进行损坏发现很多物理页面损坏,先直接重建日志DBCC检测一下看看,在2008R2平台下重建日志之后发现DBCC语句根本无法查询跟运行,直接报