天天看点

[MySQL Reference Manual] 7 备份和恢复 7. 备份和恢复

本章主要会介绍:

1.备份的类型:逻辑备份,物理备份,全备和增量4种

2.创建备份的方法

3.还原方法,包括还原到时间点

4.备份计划,压缩和加密

5.表维护,恢复损坏的表

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468188">7. 备份和恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468189">7.1备份和还原类型</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468190">7.1.1 物理备份VS逻辑备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468191">7.1.2 Online VS OFFLINE</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468192">7.1.3 本地VS远程</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468193">7.1.4 快照备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468194">7.1.5 全备VS增量备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468195">7.1.6 完全恢复VS时间点(增量)恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468196">7.1.7 表维护</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468197">7.1.8 备份调度,压缩,加密</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468198">7.2 数据库备份方法</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468199">7.2.1 使用MySQL企业备份工具热备</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468200">7.2.2 使用mysqldump和mysqlhotcopy备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468201">7.2.3 使用复制表文件备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468202">7.2.4 文本文件备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468203">7.2.5 使用binary log创建增量备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468204">7.2.6 使用slave备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468205">7.2.7 恢复错误表</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468206">7.2.8 使用文件系统快照备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468207">7.3 备份还原策略例子</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468208">7.3.1 创建备份策略</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468209">7.3.2 使用备份还原</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468210">7.3.3 备份策略总结</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468211">7.4 使用mysqldump备份</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468212">7.4.1 使用SQL格式输出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468213">7.4.2 加载SQL格式输出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468214">7.4.3 使用文本格式的输出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468215">7.4.4 加载文本格式输出</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468216">7.4.5 mysqldump提示</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468217">7.4.5.1 如何复制数据库</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468218">7.4.5.2如何复制数据库从A服务器到B服务器</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468219">7.4.5.3 dump存储程序</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468220">7.4.5.4 分开dump数据库结构和数据</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468221">7.4.5.5 使用mysqldump测试升级兼容性问题</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468222">7.5 使用binary log时间点(增量)恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468223">7.5.1 使用时间的时间来做时间点恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468224">7.5.2 使用Event位置来做时间点恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468225">7.6 MyISAM表的维护和Crash恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468226">7.6.1 使用myisamchk灾难恢复</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468227">7.6.2 如何检查MyISAM表的错误</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468228">7.6.3 修复MyISAM表</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468229">7.6.4 MyISAM表优化</a>

<a href="http://www.cnblogs.com/Amaranthus/p/3903430.html#_Toc395468230">7.6.5 创建MyISAM表维护计划</a>

物理备份是直接复制备份数据库目录或者文件,这种备份比较适合大的比较重要的数据库。

逻辑备份是把数据库信息保存为数据库结构(create database ,create table)和数据(insert语句或者text文本)。比较适合小的数据库。

物理备份方法有几个特点:

1.一系列的复制数据库文件和文件夹,通常是备份全部或者部分数据文档

2.物理备份一般比逻辑备份快,只需要复制数据不需要转化

3.输出比逻辑备份少

4.对于繁忙,重要的数据库备份的速度和窄数据比较重要

5.备份和还原粒度可以从数据文档到个别数据文件。

6.备份可以包含配置文件和日志

7.对于MEMORY表不能用这种方式备份,因为数据不在磁盘中

8.备份只能被移植到相同或者相识的硬件上(不明白)

9.backup只能在服务停止是运行,若在运行是运行,那么需要合适的锁定,防止备份的时候数据被修改。mysql企业版备份在备份的时用到的表会自动加锁。

10.物理备份工具mysqlbackup,文件系统级别的命令(cp,scp,tar,rsync),或者mysqlhotcopy备份MyISAM。

对于还原:

1.mysql企业级备份工具可以还原它的备份

2.ndb_restore恢复ndb表

3.文件系统级别复制或者mysqlhotcopy可以备份,可以复制到原来的文件目录来恢复

逻辑备份方法有几个特点:

1.逻辑备份通过查询获得数据和数据库结构。

2.逻辑备份比物理备份慢,因为需要访问数据然后转化为逻辑结构

3.逻辑备份结果比物理备份结果要大。

4.逻辑备份还原的粒度,从实例级到标记。

5.逻辑备份不能包含,日志和配置文件

6.备份是以逻辑格式存放,恢复很方便

7.备份需要服务启动

8.主要的备份工具有sqldump和SELECT … INTO OUTFILE语句,MEMORY引擎照样备份。

9.可以使用远程的逻辑备份来还原。

在线备份是在服务启动下备份,离线备份是在服务停止状态下备份。也可以称为热备(hot back),冷备(cold back)。除此之外还有暖备(warm back),意思是服务在运行状态下,但是备份在访问数据库的时候不让修改数据。

在线备份有几个特点:

1.备份不会打扰其他客户端,但是是否可以访问数据,和客户端发过来的操作有关。

2.必须要加适当的锁,不让发生数据修改,以至于出现备份一致性问题。

离线备份几个特点:

1.客户端在备份期间不可用。因为这个问题备份可以放到slave上面进行。

2.因为客户端都不能访问,所以没有一致性问题,比较简单。

上面2个备份的区别和还原的区别类似。但是在线的还原比在线备份对客户端影响更大,在还原时,client访问数据库。

本地备份是备份的结果放在MySQL所在的服务器上,远程是生产的备份放在其他服务器上。

mysqldump:可以把生产在本地或者远程

mysqlhotcopy:在本地执行,并在备份本地表文件的时候不让数据修改,备份生产在本地

SELECT… INTO OUTFILE可以从远程或者本地连接,但是备份生产在本地

尽管复制文件的目标是在远程,但是都是在本地初始化

一些文件系统可以支持快照,在一个时间点上,通关过了文件系统的逻辑copy,不需要备份整个文件系统。快照主要依赖于copy-on-write技术实现。LVM的快照可以查看《鸟哥linux私房菜 基础篇》 15.1。

全备是某个时间点的所有数据

增量备份是2个时间点内,数据的变更,MySQL中增量备份由binary log实现。

完全恢复是恢复全备中的所有数据。如果全备恢复不能满足当前,可以使用全备之后的增量备份来还原

增量恢复是2个时间点内的数据修改,也被叫做时间点恢复,让数据库数据状态更新到指定事件。增量备份一般在全备之后,使用binary log实现。

如果表出错,那么肯定会出现数据一致性问题。对于INNODB表基本上不会发送。

备份调度是用来自动产生备份。

压缩用来减少备份占用的空间。

加密保护数据安全性。

MySQL本身不包含这些能力,可以通过MySQL企业级备份工具,压缩innodb备份。文件系统可以压缩,加密备份。

MySQL企业级备份工具,备份冲instance到table级别,可以增量,全备,压缩备份。

innodb表可以直接热备,对于其他引擎进行warm备份。

mysqldump的备份例子:

shell&gt; mysqldump db_name &gt; backup-file.sql

恢复数据库:

shell&gt; mysql db_name &lt; backup-file.sql

shell&gt; mysql -e "source /path-to-backup/backup-file.sql" db_name

迁移数据库:

shell&gt; mysqldump --opt db_name | mysql --host=remote_host -C db_name

备份多个数据库:

shell&gt; mysqldump --databases db_name1 [db_name2 ...] &gt; my_databases.sql

mysqlhotcopy是一个perl脚本,使用FLUSH TABLES,LOCK TABLES和cp,scp备份数据库。只能备份myisam和ARCHIVE的表。

shell&gt; mysqlhotcopy db_name [/path/to/new_directory]

shell&gt; mysqlhotcopy db_name_1 ... db_name_n /path/to/new_directory

也可以用正则表达式,备份数据库中的表:

shell&gt; mysqlhotcopy db_name./regex/

用~前缀排除表名

shell&gt; mysqlhotcopy db_name./~regex/

对于每个表都有自己文件的存储过程可以使用复制表的文件来做备份,为了获取一致性的备份,要停止服务或者flush表:

FLUSH TABLES tbl_list WITH READ LOCK;

当备份文件的时候,只需要在表上加READ LOCK,其他客户端能够照常读取表,但是不能写入。flush用处:在备份之前,把所有被修改的page都写入到文件中。

通过这个方法可以创建一个bianry备份,备份所有的表文件。mysqlhotcopy就是使用这个方法,但是mysqlhotcopy不对innodb起作用,因为innodb的数据库文件夹没有必要保存表的所有数据,此外虽然服务没有发起修改数据但是innodb还是可能会修改缓存在内存中的数据,并且不刷新到磁盘。

创建文本文件备份,可以使用SELECT * FROM OUTFILE ‘file_name’FROM tbl_name 。

也可以使用mysqldump创建文本文件备份。

binary log提供了数据修改的sql,所以可以使用bianry log 来做增量备份。当增量备份的时候,使用flush logs,来重绕binary log,然后复制上次全备或者增量备份到最近全部复制,下次做全备时也要使用flush log。(flush log在dump之前)

当你在master上执行备份,问题很多,所以可以把备份放到slave上。

在slave备份的时候,不管用什么方法,都要备份master info和relay log info。当要恢复复制的时候,等还原完slave,都需要使用master info和relay log info来恢复复制。如果slave在复制LOAD DATA INFILE语句,就需要备份任何在—slave-load-tmpdir选项中的SQL_LOAD-*文件,用来恢复中断的load data infile语句。

如果你要恢复出错的MyISAM表,可以尝试使用REPAIR TABLE或者myisamchk –r基本上都能恢复。

如果有支持Veritas文件系统:

1.连接客户端,然后执行FLUSH TABLES WITH READ LOCK

2.在另外一个shell,执行 mount vxfs snapshot

3.客户端上,unlock tables

4.从快照中复制文件

5.卸载快照

和lvm的快照处理方法不同,具体可以看《鸟哥linux私房菜 基础篇》15.1

crash有记下几种:1.系统crash,2.断电,3.文件系统crash,4.硬件错误。

当系统crash或者断电后,假设mysql磁盘数据可以用,innodb可能没有一致性问题的数据,但是在日志文件发现挂起的提交事务和未提交事务。那么innodb会重做提交事务,回滚未提交事务。

假设crash之后,mysql的磁盘数据不可用,也就是说不能成功启动服务。那么就有必要恢复备份数据,那么之前就需要有备份。需要备份策略。

如在innodb表的数据中执行备份:

shell&gt; mysqldump --single-transaction --all-databases &gt; backup_sunday_1_PM.sql

备份操作要在所有的表上面获取全局的读锁(flush tables with read lock),来保证数据不被修改。当长的update语句执行的时候可能会被flush 堵塞。直到语句完成。

假设是在innodb表的数据库上面,使用—single-transaction可以保证mysqldump的读一致性。就算数据被其他应用修改,mysqldump也不会读入。—single-transaction只在innodb上有效。

对于大的数据库做一次全备是很不容易的,所以使用增量来配合全备就很有效率。

增量备份相对较小,备份速度快,当恢复完全备之后恢复增量备份。

当全备的时候要做flush logs,这样从全备以来的数据修改都会被记录在当前的binary log:

shell&gt; mysqldump --single-transaction --flush-logs --master-data=2 \

         --all-databases &gt; backup_sunday_1_PM.sql

执行完上面命令后,生产一个新的日志文件,因为—flush-logs导致binary log 被刷新打开一个新的日志。

--master-data选项导致mysqldump写信息到binary log。

-- Position to start replication or point-in-time recovery from

-- CHANGE MASTER TO MASTER_LOG_FILE='gbichot2-bin.000007',MASTER_LOG_POS=4;

这个命令意味着:

1.dump文件包含所有的在gbichot2-bin.000007生产之前的所有数据修改

2.所有备份之后的数据修改不在dump文件中,在gbichot2-bin.000007以及之后的日志中。

假设后来在周1 13:00,通过flush logs创建了一个增量备份,gbichot2-bin.000008,那么在原先gbichot2-bin.000007中包含了全备到周1 13:00所有的数据修改记录。

假设在周2 13:00又通过flush logs执行了增量备份,gbichot2-bin.000008包含了周1 13:00 到周2 13:00之间的所有数据的修改记录。

binary log 是比较占用空间的,可以使用—delete-master-logs来删除binary log:

         --all-databases --delete-master-logs &gt; backup_sunday_1_PM.sql

注意:

如果有配置复制的情况下使用—delete-master-logs很危险。可能出现还没有被复制到slave的日志被删除。

假设在周3 8:00出现crash,需要从备份恢复,那么先还原全备:

shell&gt; mysql &lt; backup_sunday_1_PM.sql

然后还原2个差异备份:

shell&gt; mysqlbinlog gbichot2-bin.000007 gbichot2-bin.000008 | mysql

等执行完之后,数据已经被恢复到了周2 13:00,但是还是有数据丢失,如果还能取到尾日志的情况(就是gbichot2-bin.000009),执行:

shell&gt; mysqlbinlog gbichot2-bin.000009 ... | mysql

执行完之后数据就恢复到了周3的8:00。

系统crash或者断电,innodb会自己修复,但是为了安全性考虑:

1.确定已经启动了binary log

2.定期的做全备

3.定期的做增量备份

mysqldump有2中方式:

1.不带—tab,那么mysqldump会输出一个文件所有的表结构和数据都在以sql方式在一个文件中

2.带—tab,那么mysqldump会输出一个数据库接口文件(sql),和一个文本文件(数据)

指定所有数据库输出:

shell&gt; mysqldump --all-databases &gt; dump.sql

指定数据库输出:

shell&gt; mysqldump --databases db1 db2 db3 &gt; dump.sql

如果指定了—all-databases或者—databases,mysqldump会输出create database,和use,这样就能够保证数据会被写入到指定的数据库。如果指定了—add-drop-database那么会先drop数据库然后create。

dump单个数据库:

shell&gt; mysqldump --databases test &gt; dump.sql

或者

shell&gt; mysqldump test &gt; dump.sql

但是不指定—databases不会有create database和use。所以:

1.在使用dump文件的时候,需要指定默认数据库

2.可以指定和原来不一样的数据库

3.如果数据库不存在需要先创建

4. —all-databases没有效果

加载sql个是数据很方便:

shell&gt; mysql &lt; dump.sql

也可以

mysql&gt; source dump.sql

如果是不带数据库的dump,需要先创建数据库:

shell&gt; mysqladmin create db1

shell&gt; mysql db1 &lt; dump.sql

mysql&gt; CREATE DATABASE IF NOT EXISTS db1;

mysql&gt; USE db1;

当使用选项—tab=dir_name就会输出文本格式,并输出到dir_name,每个数据库有2个文件,1,数据库结构(.sql),2.文本存储的数据(.txt)。

创建文本输出:

shell&gt; mysqldump --tab=/tmp db1

因为是server写的,所以到时候dump文件是owner是运行服务的用户。服务使用select…into outfile,所以需要有file权限的用户来操作,如果输出目录出现同名文件就会报错。

如果在远程服务上执行,那么可能会出现.txt文件在远程,.sql文件在本地。所以最好在本地运行。

数据文件的输出可以指定格式;

--fields-terminated-by=str 列分隔符默认为tab

--fields-enclosed-by=char 封装列值,默认不使用

--fields-optionally-enclosed-by=char 封装非数值列,默认不适用

--fields-escaped-by=char 需要跳过的字符,默认没有

--lines-terminated-by=str 换行符默认为0xA

shell&gt; mysqldump --tab=/tmp --fields-terminated-by=,

         --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1

可以使用hex来代替字符:

--fields-enclosed-by='"'

--fields-enclosed-by=0x22

shell&gt; mysql db1 &lt; t1.sql

shell&gt; mysqlimport db1 t1.txt

mysql&gt; LOAD DATA INFILE 't1.txt' INTO TABLE t1;

如果是带格式的,不是默认格式可以使用如下:

shell&gt; mysqlimport --fields-terminated-by=,

         --fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1 t1.txt

mysql&gt; LOAD DATA INFILE 't1.txt' INTO TABLE t1

    -&gt; FIELDS TERMINATED BY ',' FIELDS ENCLOSED BY '"'

    -&gt; LINES TERMINATED BY '\r\n';

mysqldump可以解决一下问题:

1.如何复制数据库

2.如何复制数据库从A服务器到B服务器

3.输出存储程序(存储过程,函数,触发器,事件)

4.分开输出数据库结构和数据

shell&gt; mysqldump db1 &gt; dump.sql

shell&gt; mysqladmin create db2

shell&gt; mysql db2 &lt; dump.sql

在服务A中:

shell&gt; mysqldump --databases db1 &gt; dump.sql

在服务B中:

可以使用参数:

--events:用来导出调度事件

--routines:导出存储过程和函数

--triggers:导出触发器

当导出表的时候 –triggers默认是启动的,其他2个选项默认是不系统的。可以使用—skip-events.—skip-routines,--skip-triggers跳过。

当制定—no-data的时候不带数据导出,--no-create-info不带结构导出。

shell&gt; mysqldump --no-data test &gt; dump-defs.sql

shell&gt; mysqldump --no-create-info test &gt; dump-data.sql

对于只dump结构可以如下:

shell&gt; mysqldump --no-data --routines --events test &gt; dump-defs.sql

在生产服务器上导出结构:

在升级服务器上导入:

shell&gt; mysql &lt; dump-defs.sql

查看打印的警告和错误。

如果没有问题或者处理了问题,导入数据:

生产服务器:

shell&gt; mysqldump --all-databases --no-create-info &gt; dump-data.sql

升级服务器:

shell&gt; mysql &lt; dump-data.sql

然后再检查数据是否正确导入。

时间点恢复,实质恢复到指定时间点,一般运行在全备之后。

使用—start-datetime,--stop-datetime来指定时间,

shell&gt; mysqlbinlog --stop-datetime="2005-04-20 9:59:59" \

         /var/log/mysql/bin.123456 | mysql -u root -p

从开始恢复到—stop-datetime指定的时间

shell&gt; mysqlbinlog --start-datetime="2005-04-20 10:01:00" \

从—start-datetime开始恢复到最后

使用以下方法来查看确定准确的时间:

shell&gt; mysqlbinlog /var/log/mysql/bin.123456 &gt; /tmp/mysql_restore.sql

然后打开/tmp/mysql_restore.sql来检查。

不是用时间可以使用Event位置来指定开始和结束:

shell&gt; mysqlbinlog --stop-position=368312 /var/log/mysql/bin.123456 \

         | mysql -u root -p

shell&gt; mysqlbinlog --start-position=368315 /var/log/mysql/bin.123456 \

Event位置在binary log的log_pos下.

myisamchk可以用来检查,修复,优化MyISAM表。

尽管myisamchk很安全,但是还是要全备一下数据库,以防万一。

myisamchk操作会熬制MyISAM全文索引重建,需要注意。

MyISAM表维护也可以使用SQL语句:

1.MyISAM表检查,可以使用CHECK TABLE.

2.MyISAM表修复,可以使用REPAIR TABLE

3.MyISAM表优化,可以使用OPTIMIZE TABLE

4.MyISAM表分析,可以使用ANALYZE TABLE

使用myisamchk,要保证服务没有使用这个表,不然会出现没必要的和服务之间的交互行为。

若能保证不会有别人访问mysqld,那么只需要执行mysqladmin flush-tabls,如果无法保证那么就关闭服务。如果在运行myisamchk时,mysqld修改,就会出现告警说表出错,就算没有出错还是会被认为出错。

如果服务启动external锁启动服务,可以在任何时候使用myisamchk检查表,如果服务参数修改数据,就会堵塞,等待myisamchk完成。

如果使用myisamchk修复或者优化表,在没有启用external锁的时候要保证mysqld不使用这个表。如果你不关闭mysqld,在执行myisam之前至少要mysqladmin flush-tabls。如果服务和myisamchk同时访问就有可能会表出错。

myisam表,每个表有3个文件,.frm结构文件,.myd数据文件,.myi索引文件。

虽然每个文件都有可能出现问题,但是一般不会出现在.frm结构文件中。

myisamchk一行一行的检查.myd数据文件,当完成时,删除老的myd文件,使用新的myd替代。

如果使用—quick,myisamchk不会创建一个临时myd文件,而是假设myd文件是正确的,并生成新的索引。然后myisamchk自动发现myd文件是否出错,如果出错就停止修复。

如果指定2次—quick,这样myisamchk在一些错误上不会终止修复,而是尝试去修改myd文件来解决错误。2次—quick一般在没有多少空间的情况下使用。使用之前记得要备份。

myisamchk tbl_name:可以发现大多数错误,只涉及到数据文件的错误不会被发现

myisamchk –m tbl_name:可以发现大多数错误,先检查所有索引项,然后通过读取所有行,计算所有key的checksum,然后和index tree对比。

myisamchk –e tbl_name:做全面的检查,检查读取每一行,验证他们实际上是指向当前行的。这个检查很慢,特别是大表,有很多索引的。一般发现一个错误就停止了,可以加-v选项,但也最多只能有20个错误。

myisamchk –e -i tbl_name:检查和上面一样,-i就是让myisamchk打印一些静态信息。

表出错的症状,包括查询突然异常,或者有一下错误:

1.tbl_name.frm被锁定

2.找不到tbl_name.myi文件

3.异常的文件结尾

4.数据文件crash

5.从错误表上获取nnn错误。

为了获取更多的错误信息,可以使用perror nnn,nnn为错误码获取更多信息。

shell&gt; perror 126 127 132 134 135 136 141 144 145

MySQL error code 126 = Index file is crashed

MySQL error code 127 = Record-file is crashed

MySQL error code 132 = Old database file

MySQL error code 134 = Record was already deleted (or record file crashed)

MySQL error code 135 = No more room in record file

MySQL error code 136 = No more room in index file

MySQL error code 141 = Duplicate unique key or constraint on write or update

MySQL error code 144 = Table is crashed and last repair failed

MySQL error code 145 = Table was marked as crashed and should be repaired

其中135和136并不算是错误,只是所有文件或者数据文件空间不足可以使用:

ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;

如果无法确定的当前表的使用量,可以使用show create table

对于其他错误就必须修复表了,表修复有4个阶段,在修复之前要保证对表文件有访问权限。

如果在命令行上修复表,最好先把服务停掉,如果在远程使用mysqladmin shutdown,会一段时间之后才能停止,因为需要一段时间把所有index的修改写入到磁盘。

阶段1:检查表

使用myisamchk *.MYI或者myisamchk -e *.MYI来检查表,可以使用-s(slient)跳过不必要的信息。

如果服务器没有启动,使用—update-state告诉myisamchk标记检查过的表。

只需要修复出现错误的表,对于这些表进入第二阶段进行修复。

如果检查的时候出现无法预期的错误,或者myisamchk奔溃,进入第三阶段修复

阶段2:简单安全修复

先运行 myisamchk -r -q tbl_name,视图修复索引文件,如果数据文件包含了所有信息,删除连接(是什么)指向了正确的数据文件中的位置。那么就能修复错误。

否则的话,以下过程:

1.先备份数据文件

2.使用myisamchk –r tbl_name 来清理数据文件中的错误的行和已经删除的行,并重新构建index文件。

3.如果之前的步骤失败,使用myisamchk –safe-recover tbl_name,安全模式修复使用老的修复方法来处理一些常规无法修复的问题。

如果出现异常错误,或者myisamchk崩溃进入阶段3

注:

如果想要检查快点可以把sort_buffer_size和key_buffer_size放大为可用内存的25%

阶段3:比较困难的修复

到了这个阶段只有索引文件头16KB块出现问题,或者索引文件消失的情况

1.把数据文件放到一个安全的地方

2.创建一个空的数据文件和索引文件

shell&gt; mysql db_name

mysql&gt; SET autocommit=1;

mysql&gt; TRUNCATE TABLE tbl_name;

mysql&gt; quit

3.把老的数据文件复制过来,替换新的数据文件,然后进入第二阶段,直接运行简单修复应该就可以正常了。

注意:如果有复制,那么需要先停止,因为涉及到文件系统操作。

除了使用myisamchk –r –q,还可以使用REPAIR TABLE tbl_name USE_FRM 语句

阶段4:非常困难修复

进入到这个阶段说明frm文件出错。

1.从备份中恢复放入frm文件,然后返回到阶段3

2.如果没有备份,但是记得表结构,可以直接创建一个表,删除新的数据文件,然后复制frm,myi文件到你crash的数据库里面,然后到阶段2重新创建索引文件。

为了合并碎片行,清理由删除或者update造成的浪费的空间,使用myisamchk的恢复模式,重新创建索引:

shell&gt; myisamchk -r tbl_name

当然可以使用OPTIMIZE TABLE语句来优化表。

mysiamchk还有其他选项可以用来提高表的性能:

--analyze(-a):分析key的分布(更新统计信息),可以提高join的性能。

--sort-index(-s):排序index块,可以优化查询,让表扫描更快

--sort-records=index_num(-R index_num):根据给定的索引重排数据行。可以提高range-base select和order by操作。

检查和修复表的方法:

1.CHECK TABLE,REPAIR TABLE语句来检查修复

2.使用myisamchk工具

可以通过crontab工具来完成定期的MyISAM表的维护

35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI

通常mysql表不需要维护,但是对变长字段修改频繁,删除频繁的表可以做一下维护

shell&gt; myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI

<b>    本文转自 Fanr_Zh 博客园博客,原文链接:http://www.cnblogs.com/Amaranthus/p/3903430.html</b><b>,如需转载请自行联系原作者 </b>