物理备份对比逻辑备份
物理备份是指直接复制包含数据的文件夹和文件。这种类型的备份适用于大数据量且非常重要,遇到问题需要快速回复的数据库。
逻辑备份保存能够代表数据库信息的逻辑结构(CREATE DATABASE, CREATE TABLEs等)和内容(INSERT …,或者分隔符分割的文本文件),这种类型的备份适合小数据量备份。可以通过备份文件进行库结构,表机构或者数据的修改。
物理备份主要有以下特点:
- 备份文件包含所有的数据库文件夹和文件,即是mysql数据文件夹下的全部(所有数据库实例)或者部分(单个或多个数据库实例)。
- 物理备份相较于逻辑备份快,它只涉及文件的拷贝而无需转换。
- 备份文件较逻辑备份紧凑。
- 备份速度及压缩性是备份的重要因素,尤其对业务繁忙且比较重要的数据库。因此Mqsql企业级的备份使用物理备份。.
- 备份和恢复的力度包括整个数据文件级别、单个文件级别,根据数据库引擎的不同可能提供表级别的力度。例如,Innodb引擎可以使用单表单文件存储。MyISAM表包含一系列相关文件。.
- 除了基本的数据库文件,备份还可以包含其它一些如日志、配置等相关的文件。
- MEMORY 引擎类型表很难使用这种类型备份,因为它的数据存储在内存中。.
- 备份的跨平台性要求设备间具有相似的硬件特性设备间进行。
- 备份一般在mysql服务器停止的时候进行,如果需要运行中执行备份,则需要对特定表进行锁操作,放置备份期间,表数据变化。
- 物理备份工具包括mysql的 mysqlbackup及文件系统级别的命令,如, scp, tar, rsync等
- 恢复:
- MySQL Enterprise Backup 可以恢复它所备份的备份。
- ndb_restore 用于恢NDB 表。
- 文件复制方式的复制,只需要将备份文件放到他们原始的位置即可。
逻辑备份有以下特点:
- 备份是以查询mysql服务器方式来获取数据库结构及内容信息。
- 备份速度比物理备份慢,因为它需要首先访问数据库获取数据,然后再转化为相应的逻辑格式。如果备份实在客户端,那么服务器还需要将备份发送到客户端。
- 备份文件比物理备份的文件大,尤其是以文本方式存储的时候。
- 备份和恢复粒度包括服务器级别、数据库级别、表级别。与存储引擎无关。
- 备份不包括日志和配置文件,及其它任何数据库相关的非数据文件。
- 备份以逻辑格式存储,与机器无关,可以跨平台使用。
- 逻辑备份需要mysql服务器在运行状态。
- 备份工具包括 mysqldump 及 SELECT ... INTO OUTFILE 语句,其实这些工具使用于任何引擎。即使是MEMORY。
- 恢复,对于SQL-format dump 文件可以使用 mysql 客户端。对于分隔符分割的文本类型文件,可以使用LOAD DATA INFILE 语句或者mysqlimport 客户端。
在线备份 vs 线下备份
在线备份,即备份时,可以实时服务器信息。线下备份,即,在服务器停止的时候执行备份。相应的备份文件也可以称为热备或者冷备。还一种可以称之为温备,即备份的时候,服务器运行,但是不允许进行数据修改。
在线备份特点:
- 对于其它客户端,备份是非侵入性的。不影响其它客户端进行时特定允许的数据操作。
- 注意备份期间数据锁的使用。
线下备份特点:
- 对客户端的影响是不可逆的。因此,一般备份采取在备机上进行备份。
- 备份过程很简单,客户端无法进行干预。
备份的线上和线下区别基本相似。但是,线上恢复的时候,因为需要进行较多的锁操作,所以受的影响比较大。恢复期间不要进行数据访问操作。
本地备份 vs 远程备份
本地备份即备份操作和数据库服务器在同一台服务器上。远程则相反。对于一些类型的备份,备份命令可以远程触发,本地写备份。
- mysqldump 可以连接本地或者远端服务器。生成本地或者远端备份。分隔符分割的文本存储在服务器所在服务器产生。
- SELECT ... INTO OUTFILE 本地或者远程触发。输出在服务器端。
- 物理备份基本上都是本地执行。虽然备份可能会需要发送到其它服务器。
快照备份
一些文件系统支持快照。可以保存特定时间点的一份逻辑备份。而不需要复制整个文件系统。Mysql本身不提供这种功能,需要地方放工具如Veritas, LVM, or ZFS提供。
全量备份 vs 增量备份
全量备份即备份mysql管理的所有数据。增量备份即备份改变的数据。全量备份可以通过以上讲述的一些备份方法进行备份。增量备份则需要通过启用服务器二进制日志(记录数据变化)来使用。
全量恢复 vs 增量恢复
全量恢复及恢复备份中所有的数据,是数据库恢复到备份时数据库状态。如果全量恢复的状态不够实时,可以接着使用增量恢复,恢复全量备份到这一刻所有的数据变化,是数据库状态保持最新。
增量恢复即恢复一个时间段内的数据变化。基于二进制日志,作为全量备份的补充。二进制文件中存储数据改变命令操作,通过重新执行相应的操作,使得数据库恢复到特定的状态.
备份规划、压缩和加密
...
二、数据库备份方法
使用mysqldump 备份
mysqldump 可以备份所有类型的表。对于 InnoDB
类型的表,可以通过--single-transaction
选项使用在线无锁备份。
通过复制表数据文件备份
对于那些使用独立文件存储表的引擎,备份可以通过复制表文件进行。例如,MyISAM
表存储文件(.frm:表结构
, *.MYD:表数据
, and *.MYI
:表索引)。为了保持数据的一致性,备份时需要关闭服务器或者锁定相应的数据表:
FLUSH TABLES tbl_list WITH READ LOCK;
备份只需要读锁,这样备份的同时不影响其它客户端进行数据检索。Flush操作是为了确保所有活跃的索引页都已经写盘。
也可以通过拷贝表文件来创建二进制备份,但,前提是在此期间不能进行任何的数据更新操作。 (对于包含Innodb类型表的数据库不能采取此方法,因为即使不进行任何更新操作,Innodb仍然可能有更改的数据缓存在内存中)。
分隔符文本类型备份
操作命令: SELECT * INTO OUTFILE 'file_name' FROM
tbl_name
.。备份文件生成在mysql服务器上。执行此语句需要确保输出文件不存在,服务器不允许文件覆盖操作,避免由此产生安全隐患。这一方法适用于任何类型数据文件,但是只能保存表记录,无法保存表结构。
另一种创建文本类型备份(包含 CREATE TABLE
语句)的方法是使用 mysqldump 附带--tab
选。加载文本类型本分可以使用 LOAD DATA INFILE
或者 mysqlimport.
二进制文件增量备份
MySQL支持增量备份。启动服务器时附带 --log-bin
选项启用二进制日志功能。二进制文件记载了自某一次备份以来所有的数据更新操作。生成一份增量备份时, 需要使用FLUSH LOGS
或者mysqldump --flush-logs 生成一份新的日志文件,执行完成之后,将自某一次备份之后到最新的二进制日志文件复制到备份位置,即增量备份文件。恢复时,重新执行这些增量备份文件。
shell> mysqlbinlog binlog_files | mysql -u root -p
使用备机执行备份
备份一定程度上影响服务器的性能,因此通常我们选择在备机上进行备份。
备机备份时,首先需要备份主机信息及中继日志(relay log)。因为备份备机数据时,无论选用哪种备份方法,当重新使用备份数据恢复后,都需要重新将备份的主机信息及中继日志进行复制。 当备机执行LOAD DATA INFILE
语句时,需要备份相应的SQL_LOAD-*
使用的文件夹。备机需要在LOAD DATA INFILE
崩溃时使用这些文件进行恢复。文件夹位置: --slave-load-tmpdir
。如果服务器启动时并未指定此选项,则使用系统tmpdir
变量信息。
恢复崩溃表
恢复 MyISAM
表时,首先使用 REPAIR TABLE
或者 myisamchk -r 尝试恢复,这通常能解决99.9% 以上的问题。
使用文件系统快照备份
Veritas文件系统下备份步骤如下:
- 首先客户端执行
FLUSH TABLES WITH READ LOCK
. - 另起shell,执行
mount vxfs snapshot
。 - 在之前的客户端执行
UNLOCK TABLES
. . - 拷贝快照文件.
- Unmount snapshot.
LVM及ZFS文件系统执行备份过程类似。
三、mysqldump 备份
使用mysqldump 备份及恢复,
dump文件作用:
- 数据备份,灾难恢复
- 建立备机数据。
- 实验数据:
- 数据副本
- 升级测试
mysqldump 根据配置不同,提供两种输出格式
- 不附带
--tab
,mysqldump将sql语句写到标准输出,包括CREATE 语句和插入语句
。输出可以保存为文件以备后续重新载入使用。可以通过配置选择需要备份的对象。 - 使用
--tab
, mysqldump 每个表生成两个文件对象。一个tab分隔符的文本文件tbl_name.txt
,另一个包含CREATE TABLE
语句的文件tbl_name.sql
。
使用mysqldump生成SQL格式备份
默认情况下mysqldump 输出到标准输出。使用以下命令输出到文件:
代码语言:javascript复制shell> mysqldump [arguments] > file_name
备份所有数据库 --all-databases
:
shell> mysqldump --all-databases > dump.sql
备份部分数据库则在--databases
选项后添加数据库名称:
shell> mysqldump --databases db1 db2 db3 > dump.sql
--databases
选项标识后面命令行的指令都为数据库名,如果没有这个选项,则第一个为数据库名,后续为表名。
--all-databases
和 --databases
,选项,使得mysqldump 创建的备份文件包括 CREATE DATABASE
及 USE
语句。这样在恢复时,就可以针对特定的数据库进行恢复,不至于造成所有的恢复都恢复到默认数据库里。如果需要备份文件包含drop数据库语句,则使用 --add-drop-database
选项。这样就会在CREATE DATABASE
语句之前添加DROP DATABASE
语句。
备份单个数据库:
代码语言:javascript复制shell> mysqldump --databases test > dump.sql
备份单个数据库时可以不使用 –database选项:
代码语言:javascript复制shell> mysqldump test > dump.sql
不使用--databases
选项,备份文件不包含CREATE DATABASE
和 USE
语句:
- 恢复时需要指定数据库。
- 如果指定的数据库不存在,则需要首先创建。
- 不包含
DROP DATABASE
语句。
备份指定的表:
shell> mysqldump test t1 t3 t7 > dump
.sql
SQL-Format 备份文件加载
生成时包含 --all-databases 或者 --databases 选项的,备份文件包含CREATE DATABASE 和 USE 语句,不需要再指定数据库:
shell> mysql < dump.sql
sql命令行,使用source:
mysql> source dump.sql
备份不包含数据库创建语句,确保指定恢复的数据库存在:
shell> mysqladmin create db1
指定数据库:
shell> mysql db1 < dump.sql
sql命令行执行:
mysql> CREATE DATABASE IF NOT EXISTS db1;
mysql> USE db1;
mysql> source dump.sql
文本分隔符格式备份
mysqldump --tab=dir_name
,生成tbl.sql, tbl.txt文件到指定的输出文件夹爱。.sql
文件包含CREATE TABLE
语句,.txt
文件包含表数据,一个文件行对应一条表记录。
如下备份数据库d1到 /tmp
目录:
shell> mysqldump --tab=/tmp db1
.txt
包含服务器写入的表数据。服务器使用SELECT ... INTO OUTFILE
语句写文件,所以必须确保具有 FILE
访问权。如果需要生成的文件已存在则会报错。
The server sends the CREATE
definitions for dumped tables to mysqldump, which writes them to .sql
files. These files therefore are owned by the user who executes mysqldump.
--tab
最好本地使用,如果远程使用,则必须确保服务器和客户端都存在此目录。这样.txt 文件会写到远程客户端文件夹,.sql文件会本地写。
mysqldump --tab.txt
文件,每行一条表记录,tab符分割,列值没有修饰符,换行符分割行。
--fields-terminated-by=str
分割符设置,默认为tab
--fields-enclosed-by=char
列值修饰符,默认无
--fields-optionally-enclosed-by=char
非数字列值修饰符,默认无
--fields-escaped-by=char
特殊字符列值修饰符,默认无
--lines-terminated-by=str
行分隔符,默认换行
如下,双引号修饰符
代码语言:javascript复制--fields-enclosed-by='"'
16进制双引号修饰符:
代码语言:javascript复制--fields-enclosed-by=0x22
修饰符综合使用:
代码语言:javascript复制shell> mysqldump --tab=/tmp --fields-terminated-by=,
--fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1
文本分割符备份文件载入
Shell命令:
shell> mysql db1 < t1.sql
shell> mysqlimport db1 t1.txt
mysql命令:
mysql> USE db1;
mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1;
If you used any data-formatting options with mysqldump 使用了任何数据格式化选项,则mysqlimport 或者 LOAD DATA INFILE 也不需使用相应的配置:
代码语言:javascript复制shell> mysqlimport --fields-terminated-by=,
--fields-enclosed-by='"' --lines-terminated-by=0x0d0a db1 t1.txt
或者:
代码语言:javascript复制mysql> USE db1;
mysql> LOAD DATA INFILE 't1.txt' INTO TABLE t1
FIELDS TERMINATED BY ',' FIELDS ENCLOSED BY '"'
LINES TERMINATED BY 'rn';
mysqldump 提示
数据库复制
代码语言:javascript复制shell> mysqldump db1 > dump.sql
shell> mysqladmin create db2
shell> mysql db2 < dump.sql
不要添加 --databases
选项,避免备份文件包含USE 语句。
服务器之间数据库复制
服务器1:
代码语言:javascript复制shell> mysqldump --databases db1 > dump.sql
将备份文件复制到服务器2:
服务器2执行:
代码语言:javascript复制shell> mysql < dump.sql
备份存储程序(存储过程、函数、触发器、事件)
--events
:事件--routines
:储过程、函数--triggers
:触发器(默认包含)
显式剔除:--skip-events
, --skip-routines
, or --skip-triggers
.
分别备份表定义及数据
代码语言:javascript复制shell> mysqldump --no-data test > dump-defs.sql //备份定义
shell> mysqldump --no-create-info test > dump-data.sql //备份数据
shell> mysqldump --no-data --routines --events test > dump-defs.sql
使用mysqldump测试升级
生产服务器备份:
代码语言:javascript复制shell> mysqldump --all-databases --no-data --routines --events > dump-defs.sql
另外的升级服务器:
代码语言:javascript复制shell> mysql < dump-defs.sql
因为备份文件不包含数据,所以可以很快执行,这样可以很快发现问题。
恢复数据:
生产服务器:
代码语言:javascript复制shell> mysqldump --all-databases --no-create-info > dump-data.sql
另外的升级服务器:
代码语言:javascript复制shell> mysql < dump-data.sql
四、二进制文件增量恢复
作为全全量备份的补充,用于将服务器更新到最新状态。
规则:
- 服务器启动时必须附带
--log-bin
选项以启动二进制日志功能。恢复时需要指明二进制文件路径和名称,默认为数据文件路径,可以通过--log-bin
配置。
查看二进制文件命令:
代码语言:javascript复制mysql> SHOW BINARY LOGS;
查看当前主二进制文件名称:
代码语言:javascript复制mysql> SHOW MASTER STATUS;
- mysqlbinlog 将二进制日志转化为文本格式,以便于阅读和执行其中的指令,根据时间及位置定位日志中的事件。
- 使用 mysql 客户端执行 mysqlbinlog 命令如下:
- 使用 mysqlbinlog 查看二进制日志内容
shell> mysqlbinlog binlog_files | mysql -u root -p
shell> mysqlbinlog binlog_files | more
将二进制文件保存为文本类型文件:
代码语言:javascript复制shell> mysqlbinlog binlog_files > tmpfile
shell> ... edit tmpfile ...
- 可以对生成的文本类型日志进行编辑,然后再做执行:
shell> mysql -u root -p < tmpfile
一个连接执行一个二进制日志会存在问题,下面是一个反面示例:
代码语言:javascript复制shell> mysqlbinlog binlog.000001 | mysql -u root -p # DANGER!!
shell> mysqlbinlog binlog.000002 | mysql -u root -p # DANGER!!
使用一个连接执行所有的二进制日志文件:
代码语言:javascript复制shell> mysqlbinlog binlog.000001 binlog.000002 | mysql -u root -p
或者将所有的人日志写入一个文件执行:
代码语言:javascript复制shell> mysqlbinlog binlog.000001 > /tmp/statements.sql
shell> mysqlbinlog binlog.000002 >> /tmp/statements.sql
shell> mysql -u root -p -e "source /tmp/statements.sql"
对于包含全局事物ID事件执行:
代码语言:javascript复制shell> mysqlbinlog --skip-gtids binlog.000001 > /tmp/dump.sql
shell> mysqlbinlog --skip-gtids binlog.000002 >> /tmp/dump.sql
shell> mysql -u root -p -e "source /tmp/dump.sql"
基于时间的增量恢复
mysqlbinlog使用 --start-datetime 和 --stop-datetime 选项确定执行的日志事件范围。例如,10点的时候删除了一张表,如果要恢复,就需要分别执行10点之前和之后的日志,如下:
代码语言:javascript复制shell> mysqlbinlog --stop-datetime="2005-04-20 9:59:59"
/var/log/mysql/bin.123456 | mysql -u root -p
shell> mysqlbinlog --start-datetime="2005-04-20 10:01:00"
/var/log/mysql/bin.123456 | mysql -u root -p
查看而不执行:
shell> mysqlbinlog /var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
mysqlbinlog不能很好的处理对于多个事件作为一个事件执行的日志。
基于日志位置的增量恢复
mysqlbinlog --start-position || --stop-position 精确到行号基于位置恢复。能够很好的解决处理同时发生的多个事务的情景。为了确定精确的位置,首先使用 mysqlbinlog 获取特定事务时间点前后一定范围的日志,将其存储到文本文件:
代码语言:javascript复制shell> mysqlbinlog --start-datetime="2005-04-20 9:55:00"
--stop-datetime="2005-04-20 10:05:00"
/var/log/mysql/bin.123456 > /tmp/mysql_restore.sql
找到位置后,就可以执行基于位置的增量恢复:
代码语言:javascript复制shell> mysqlbinlog --stop-position=368312 /var/log/mysql/bin.123456
| mysql -u root -p
shell> mysqlbinlog --start-position=368315 /var/log/mysql/bin.123456
| mysql -u root -p
二进制日志各sql语句之前包含SET TIMESTAMP 语,重新执行的日志产生的日志会反映当时执行的时间戳。
MyISAM 表维护及崩溃恢复
myisamchk 检查,修复及优化MyISAM 表
( .MYD
数据 .MYI
索引)。
虽然使用myisamchk修复表很安全,但也建议修复,或者维护前先备份。
myisamchk涉及或者影响索引的操作会引起MyISAM全文索引使用全部的文本重建索引。这与mysql
服务器使用创建索引的值不一致。因此操作时需要设置相关的选项。
MyISAM
表维护也可以使用相应的sql语句替代相关的myisamchk 操作。
CHECK TABLE
:检查表REPAIR TABLE
.:修复表OPTIMIZE TABLE
:优化表ANALYZE TABLE
:分析表
这些语句可以单独使用,或者使用mysqlcheck 执行相关的功能。使用myisamchk 的一个好处就是服务器可以做所有的工作,但同时要确保,服务器在 myisamchk 操作期间,不要进行任何其它操作,避免不必要的交互。
使用myisamchk 进行崩溃恢复
如果 mysqld 数据库服务实例运行没有开启external locking (默认禁用,用于多线程下MyISAM数据表锁定,及一个线程要使用某个表,必须等待其它线程释放对这些表的锁)。那么当服务器运行中,使用某些表时,就无法可靠的使用 myisamchk 进行检查。如果确认某些表没有被使用,那么只需要在使用 myisamchk检查表之前执行mysqladmin flush-tables 操作。如果无法确定,就需要先关闭mysqld 实例,再执行。如果在使用 myisamchk 检查表的同时,有mysqld 实例更新数据表,那么无论表是否崩溃,都会收到一个表崩溃的警告。
如果服务器启动时启用了external locking, 就可以随时使用 myisamchk 来检查表。这种情况下,当服务器试图更新 myisamchk 正在检查的表时,就会等待服务器检查完毕再就绪执行表相关操作。
external locking启用、服务器对表的访问、mysqladmin flush-tables。
MyISAM
表涉及的三个文件:
File | Purpose |
---|---|
tbl_name.frm | Definition (format) file |
tbl_name.MYD | Data file |
tbl_name.MYI | Index file |
通常出问题的就是数据文件和索引文件。
myisamchk工作过程:一行一行的复制旧的数据文件.MYD 到一个新的数据文件,然后删除旧的数据文件,重命名新的数据文件为原有的数据文件名。
如果使用了 --quick
选项, myisamchk 将不会对数据文件进行处理,而仅仅创建一个新的索引文件。这种操作是安全的 myisamchk 可以自动检测 .MYD
文件是否崩溃,如果崩溃就放弃修复。如果使用两次 --quick
选项,则在某些异常情境下,如(主见重复), myisamchk将会尝试通过修改.MYD来修复。
通常情况下,在磁盘空间不足时,使用双--quick
选项比较有用。但在此之前也要先备份表。
MyISAM 表错误检查
表检查命令:
- myisamchk tbl_name
这个命令通常能检查99.99%的错误,但是对于只是由数据文件引起的错误则无法检查。 执行检查不需要附带选项或者使用 -s 后台运行选项。
- myisamchk -m tbl_name
这个命令通常能检查99.999% 的错误。它首先检查所有的索引,然后检查所有的数据行。他会计算所有主键校验码然后和索引中的校验码进行对比。
- myisamchk -e tbl_name
这一命令选项会执行全面的检查 (-e 意为 “extended check”).,它会对每一个索引键执行一个检查读取的操作,确保所有的索引键都能执行正确的数据行位置。对于大数据量,有较多索引的表来说,这将耗费大量的时间。通常情况下,myisamchk 会在发现错误时停止,如果要获取更多的错误,可以使用-v (verbose) 选项,最多能获取到20个异常错误。
- myisamchk -e -i tbl_name
功能和上一个选项很像,-i选项会额外的打印相应的统计信息。
一般情况下,使用不附带任何选项的myisamchk 命令即可。
MyISAM表修复
常见的查询崩溃及错误如下:
- 找不到tbl_name.MYI文件 (Errcode: nnn)
- Unexpected end of file
- 记录崩溃
- Got error nnn from table handler
可以运行perror nnn(错误号) 获取更多的错误信息:
代码语言:javascript复制shell> 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 (索引文件没有多余的空间)并不是myisamchk能够修复的错误。可以通过ALTER TABLE 来修改 MAX_ROWS 和AVG_ROW_LENGTH 表选项:
ALTER TABLE tbl_name MAX_ROWS=xxx AVG_ROW_LENGTH=yyy;
如果不知道当前的表选项,可以使用命令SHOW CREATE TABLE查看。
其它错误可以使用myisamchk 来修复。
修复过程包含三个步骤:所有修复前,首先需要切换到数据库文件夹的位置,并检查表文件的访问权限。
命令行修复表前,首先需要先停止mysqld 服务器。需要注意的是,执行完mysqladmin shutdown返回后,mysqld服务器直到完全停止(所有语句执行完毕,所有的索引变化都刷盘)前,还可以被访问。
代码语言:javascript复制.mysqlcheck.exe test drivers -h localhost -uroot -proot
步骤 1: 表检查
运行myisamchk *.MYI,如果时间富裕,就使用myisamchk -e *.MYI。使用 -s (silent)避免显示不必要的信息。
如果mysqld服务器停止,需要使用--update-state 来使得myisamchk 将表标记为“已检查”。
只应该使用myisamchk修复已检查出错误的表。然后执行步骤2。
如果执行修复期间发生不可预测的错误(如内存溢出等),或者myisamchk崩溃,则执行步骤3。
步骤 2: 简单安全修复
首先,执行myisamchk -r -q tbl_name (-r –q 意为快速恢复模式)。此模式下,会尝试在不访问数据文件的情况下修复索引文件。如果数据文件包含所有应该包含的,删除链接都能够指向数据文件正确的位置,那么则继续执行下一个表修复,否则的话,执行如下的步骤:
- 继续执行前,首先备份数据文件
- 使用myisamchk -r tbl_name (-r 意为 “恢复模式”)。此操作会删除错误和已删除的行记录,并重构索引文件。
- 如果上述的步骤失败了。则使用 myisamchk --safe-recover tbl_name.。安全恢复模式使用一种旧的恢复方法,用于处理一些常规恢复模式无法处理的问题(速度相对会慢)
附记:
如果想要修复过程执行的快一些,则可以设置sort_buffer_size 和 key_buffer_size 变量为可用内存的25%。
步骤 3: 复杂修复
使用这一步骤的情景包括:索引文件的前16KB 空间完全损坏,或者包括错误的信息;索引文件丢失。遇到这种情景,则需要创建一个新的索引文件,步骤如下:
- 将数据文件移动到安全的地方
- 使用表定义文件创建新的数据(空)及索引文件:
shell> mysql db_name
mysql> SET autocommit=1;
mysql> TRUNCATE TABLE tbl_name;
mysql> quit
- 将旧的数据文件拷贝覆盖到新的数据文件位置(注意保留旧的数据文件,以免出现不必要的问题) 注意:如果在应用复制机制,首先需要停止复制,因为复制涉及到文件系统的操作,这些事mysql服务器无法记录的。
执行完步骤3后,重新回到步骤2.,执行myisamchk -r -q 应该就可以修复了。(注意避免循环执行步骤2,3)
也可以使用REPAIR TABLE tbl_name USE_FRM SQL 语句,可以自动执行所有的步骤。
MyISAM 表优化
合并碎片记录,回收浪费的空间(删除或者更新操作引起),可以执行myisamchk 安全模式修复:
代码语言:javascript复制shell> myisamchk -r tbl_name
也可以使用OPTIMIZE TABLE
SQL语句。OPTIMIZE TABLE
执行表修复和键分析,同时排序索引树,使得查找更快。
myisamchk其它选项:
--analyze
或者-a
::执行键分布分析。通过启用联合优化器,选择优化的联合顺序及联合键索引,提升联合操作性能。--sort-index
或者–S
:排序索引块,这一优化使得基于索引的查找及表扫描执行更快。--sort-records=index_num
或者-R index_num
:根据特定的索引排序行数据。这一操作会使得数据更加聚集,加速使用此索引的基于范围的查询和排序操作。
MyISAM 表维护定时计划
进行常规的表检查,而不要遇到问题再修复。
一种检查修复MyISAM
表的方式是使用CHECK TABLE
和REPAIR TABLE
语句。
另一种方式使用 myisamchk。使用myisamchk -s 命令,运行静默方式,只打印myisamchk错误信息。
设置服务器自动检查MyISAM表,则需要在启动mysql服务器时,添加
--myisam-recover-options
选项。
也可以使用应用系统的定时任务执行常规的表检查,例如,使用 cron 定时任务工具: crontab
文件:
35 0 * * 0 /path/to/myisamchk --fast --silent /path/to/datadir/*/*.MYI
此命令会打印表崩溃错误信息,以便可以执行相应的检查和修复。
也可以根据维护记录调整表维护频率。
通常情况下,MySQL 表极少需要维护,如果经常在涉及动态字段(VARCHAR
, BLOB
, 或者 TEXT
)的表执行更新操作,或者有表经常执行删除操作。那么进行必要的碎片整理及空间回收会很有必要。可以通过使用 OPTIMIZE TABLE
来执行。另外也可以,通过停止mysqld 服务器,进到数据文件夹,执行如下命令:
shell> myisamchk -r -s --sort-index --myisam_sort_buffer_size=16M */*.MYI