Amygo
作者Amygo2019-06-25 18:05
DBA, 分布式事务数据库

【小白福利—初级DBA入门必看】MySQL常用工具介绍(六)——客户端工具MySQL_check

字数 11723阅读 1447评论 0赞 2

作为程序员你对MySQLcheck了解多少呢?如果没有深入了解过那也不用担心,这里有最全最详细的介绍,现在跟着Amy了解也不算晚哦~

1 . 简介

mysqlcheck用来维护表:check检查、repair修复、optimize优化、analyze分析。
除检查表是read锁定外,其它都是write锁定。
表维护操作可能耗时较多,尤其是–databases和–all-databases选项要维护大量表时。
当mysql升级程序决定要check表,相当于调用mysqlcheck。
最好在执行表修复操作前备份表,因为某些情况下(如文件系统错误),该操作可能导致数据丢失。
mysqlcheck实际上是根据选项参数确定CHECK TABLE, REPAIR TABLE, ANALYZE TABLE, OPTIMIZE TABLE四种语句,并将其发送到服务器执行。这四种语句不一定支持所有储存引擎,这种情况下会显示错误信息。

调用方式:
shell> mysqlcheck [options] [–tables] db_name [tbl_name …]
shell> mysqlcheck [options] --databases db_name …
shell> mysqlcheck [options] --all-databases
选项可以从[mysqlcheck]和[client]中读取。
mysqlcheck相对于其他客户端程序有些特殊。他还可以通过改名、建立软连接等方式,修改默认的–check行为为其他行为,程序名称与行为对应如下:
ikd7xuvifui

ikd7xuvifui

2 . 选项介绍与部分选项举例说明

注意:这里的默认值,不是使用“程序名 --no-defaults --help”打印的输出,而是指未指定时内部初始值,该值可被自身选项显示指定,也可能会受其他互斥选项、相关选项更改。这里只写出默认启用的布尔型选项,以及有内部值的其他选项。有内部值的选项可以不显示给出。

2.1 所有客户端共有选项
mysqlcheck作为MySQL提供的客户端的之一,具有以下五种通用选项。

2.1.1 影响选项文件读取的选项
7k5wkqlbz4e

7k5wkqlbz4e

2.1.2 帮助与版本
xy77lul1w1

xy77lul1w1

2.1.3 连接的建立
pygcijm8ac

pygcijm8ac

23q0cxqvem
23q0cxqvem

连接方式参数说明:优先级–protocol>–pipe>-h;
linux两种连接方式:若未指定–host和-h,或指定为localhost,或指定为空(–host=或–host=’’),则使用unix套接字;否则使用tcp/ip。
windows三种连接方式:若未指定–host和-h,或指定为localhost,且服务端开启了共享内存,则使用共享内存;若指定为.,或tcp禁用且socket未指定或主机指定为空(–host=),则使用命名管道;否则tcp。
连接方式举例
全平台使用tcp/ip:
mysql --protocol=tcp [-h127.0.0.1] [–port=3306]
mysql -h127.0.0.1 [–port=3306]

unix使用socket:
mysql [–host=localhost] [–socket=/tmp/mysql.sock]

windows使用命名管道:需在服务端开启命名管道支持
mysql --protocol=pipe
mysql --pipe
mysql --host=.

windows使用共享内存:未知,存在问题。理论上应当在服务上开启共享内存后使用
mysql [–host=localhost] --shared-memory-base-name=MYSQL,但是实际上使用的tcp,或者
mysql --protocol=memory --shared-memory-base-name=MYSQL,但是会报错ERROR 2046 (HY000): Can’t open shared memory; cannot send request event to server (5);

2.1.4 字符集
4vfzu743vj

4vfzu743vj

2.1.5 调试日志
c9wisz9k7mi

c9wisz9k7mi

2.2 mysqlcheck特定选项
rr59z8unh3b

rr59z8unh3b

3 . 常见用法举例

分析所有的数据库的数据表:mysqlcheck -A -a
优化sakila,clientoptions数据库:mysqlcheck --optimize -B sakila clientoptions
检查mysql.user表:mysqlcheck --check mysql user

4 . 附录:表维护语句介绍

4.1 ANALYZE TABLE Syntax
ANALYZE [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] …
语句需要SELECT和insert权限。
analyze table执行索引分布分析,并存储分布。对MyISAM表,该语句等同于myisamchk --analyze。
analyze table工作于innodb、ndb、MyISAM表,不适用于视图。
支持分区表,可以使用ALTER TABLE … ANALYZE PARTITION来分析一个或多个分区。
对innodb、MyISAM表,分析期间将以读锁锁定表。
4.1.1 analyze table的输出
输出为一个表,一个表可能有多行输出,该表最后一行是(表名,check,status,信息)。
lpuui3xwwqc

lpuui3xwwqc

4.1.2 索引分布分析
若自上次分析后表没有变更,不会再次分析表。
MySQL使用存储的索引分布来一定程度上决定表的join顺序,而不是一个常量。此外,索引分布还可以用来决定一个查询中的某个表当使用哪个索引。
关于索引分布如何工作的更多信息可参考 Section 14.8.11.1, “Configuring Persistent Optimizer Statistics Parameters” and Section 14.8.11.3, “Estimating ANALYZE TABLE Complexity for InnoDB Tables”. Also see Section 14.6.1.6, “Limits on InnoDB Tables”.
特别是,若innodb_stats_persistent=ON,在innodb表载入了大量的数据,或者为其创建了一个新索引后,必须运行analyze table。
要检查存储的索引分布基数,使用show index语句或者information_schema.statistics表。 See Section 13.7.5.22, “SHOW INDEX Syntax”, and Section 24.24, “The INFORMATION_SCHEMA STATISTICS Table”.

4.1.3 其他注意信息
analyze table清空来自information_schema.innodb_tablestats的表统计信息,并设置STATS_INITIALIZED列的值为Uninitialized。下次访问表时将再次收集统计信息。

4.2 CHECK TABLE Syntax
CHECK TABLE tbl_name [, tbl_name] … [option] … #表名不能重复

option: {
FOR UPGRADE #检查表是否与当前MySQL版本兼容
| QUICK
| FAST
| MEDIUM
| EXTENDED
| CHANGED
}
检查表是否有错、视图是否存在。适用于InnoDB、MyISQM、ARCHIVE、CSV四种表,对于MyISQM,索引统计信息也会更新。
支持分区表,ALTER TABLE … CHECK PARTITION也可以检查一个或多个分区。
忽略无索引的虚拟生成列。

4.2.1 check table输出:
输出为一个表,一个表可能有多行输出,该表最后一行是(表名,check,status,信息),信息应当为OK。对于MyISAM,如果信息不为OK或Table is already up to date(表示无需检查),一般情况下当运行修复。
rh4s0vb139n

rh4s0vb139n

054fodgv2sj
054fodgv2sj

4.2.2 检查版本兼容性
FOR UPGRADE选项检查表是否与当前MySQL版本兼容,因为数据类型存储格式、排序顺序可能导致数据类型或索引不兼容。
如果兼容,检查成功;否则 ,会进行全面检查。全面检查成功,.frm将被标记为当前MySQL版本,以确保使用相同版本的服务器进一步检查表格的速度更快。

可以发现如下不兼容:
4.1和5.1之间,InnoDB和MyISAM表中,TEXT列中end-space的索引顺序有变化。
5.0.3和5.0.5之间,新DECIMAL类型的存储方法有变化。
若表由非当前版本服务器创建,for upgrade会指出.frm版本号不兼容,显示(表名,check,error,Table upgrade required)。请"REPAIR TABLE tbl_name"以修复表。
Changes are sometimes made to character sets or collations that require table indexes to be rebuilt. For details about such changes, see Section 2.11.3, “Changes in MySQL 5.7”. For information about rebuilding tables, seeSection 2.11.12, “Rebuilding or Repairing Tables or Indexes”.
YEAR(2)类型不提倡,5.7.5中被移除。对于含该类型的表,CHECK TABLE recommends REPAIR TABLE, 以将其转为YEAR(4).

5.7.2始,维护触发器的创建时间。若表有触发器,CHECK TABLE … FOR UPGRADE为每个5.7.2前创建的触发器显示如下警告,供参考而触发器无任何变化:Trigger db_name.tbl_name.trigger_name does not have CREATED attribute.

5.7.7始,若avoid_temporal_upgrade=ON(默认),含5.6.4前的旧时间格式(time、datetime、timestamp不支持小数秒精度)的表将被报告为需要重建;若avoid_temporal_upgrade=OFF,则忽略该项兼容性。
for upgrade对使用非本地分区的表发出警告。因为非本地分区,5.7不推荐,8.0被删除。

检查数据一致性:除for upgrade外的其他选项,选项传递给引擎,引擎可能使用或忽略某些选项。
vpem2u6qfw

vpem2u6qfw

检查类型可以组合,如下面例子使用快速检查以决定表是否正常关闭。CHECK TABLE test_table FAST QUICK;
若check table没有发现标记为‘corrupted’或‘not closed properly’表有问题,check table会将该标记移除。
若表损坏,很可能在索引部分而不是数据部分。所有检查类型都对索引进行彻底检查,故应可找到大多数错误。
要检查预计没问题的表,不使用检查选项或使用quick选项。赶时间时当使用quick,但要承担quick没有在数据文件中发现错误的小风险。(多数情况,正常情况,MySQL当发现数据文件中的任何错误。这种情况下,表将被标记为‘corrupted’,并且在修复前无法使用)
fast和changed主要用于脚本中定期检查表(如cron)。多数情况,fast先于changed考虑。(唯一例外是当你怀疑你发现MyISAM代码中的bug时)。
当普通检查过的表依旧在更新行或通过索引查找行发生错误时(若普通检查成功,这是不太可能),才需考虑extended。
使用CHECK TABLE … EXTENDED可能会影响查询优化器产生的执行计划。

一些check table报告的问题可以被自动修正:
Found row where the auto_increment column has the value 0.
这意味着表的auto_increment索引行包含0。这本身不是错误,但可能使导出并导入表、alter table时出现问题。在这种情况下,自增列依据自增列的规则改变值,这可能导致重复键错误等问题。
为避免这个警告,使用update将0值该成其他值。

4.2.4 check table使用说明:InnoDB
若check table遇到损坏页,服务器退出以阻值错误传播(bug #10132)。如果是二级索引损坏,但数据可读,check table依旧导致服务器退出。
若check table遇到聚簇索引中损坏的DB_TRX_ID或 DB_ROLL_PTR字段,check table会导致InnoDB访问非法的undo日志记录,导致mvcc相关服务退出。
若check table遇到表或索引中的错误,它报告错误,标记索引并有时标记表为已损坏,组织索引或表的进一步使用。这样的错误包括二级索引的错误入口数或错误链接。
若check table找到二级索引的错误入口数,它报告错误,但不会导致服务退出或阻止访问错误文件。
check table调查索引页结构,然后调查每个索引入口。它不验证指向聚簇记录的索引指针,不追踪blob指针。
当innodb表保存在自己的.ibd文件,则文件的前3页包含头信息而不是表或索引数据。check table不探查只影响头数据的非一致。要验证整个.ibd的内容,请使用innochecksum命令。
当在大表上运行check table,在执行期间其它线程可能被阻塞。为避免超时,check table操作将信号量等待阈值(600s)延长至(7200s)。若innodb探测到大于等于240s的信号量等待,innodb开始打印innodb监视器输出到错误日志。若锁请求超过信号量等待阈值,innodb中止该过程。为完全避免信号量等待超时的可能性,执行check table quick而不是check table。
check table对空间索引的功能包括R-tree有效性检查,以及一个保证R-tree行计数匹配聚簇索引的检查。
check table支持虚拟生成列上的二级索引。

4.2.5 check table使用说明:MyISAM
check table更新索引统计信息
对于MyISAM,如果check table输出信息不为OK或Table is already up to date(表示无需检查),一般情况下当运行修复。参考Section 7.6, “MyISAM Table Maintenance and Crash Recovery”.
若没有指定QUICK、MEDIUM、EXTENDED中任一个,即没有给出检查方法时:
对于动态格式的MyISAM表,默认的检查类型为MEDIUM。效果等同于 myisamchk --medium-check tbl_name。
对于静态格式的MyISAM表,若也没有指定CHANGED 、FAST任一个,默认检查类型同样为MEDIUM;否则默认检查类型为QUICK。对changed、fast不进行行扫描是因为行很少损坏。

4.3 CHECKSUM TABLE Syntax
CHECKSUM TABLE tbl_name [, tbl_name] … [QUICK | EXTENDED]
checksum table报告表内容的校验和。可以使用该语句验证备份、回滚或其它旨在将数据恢复到已知状态的操作前后内容相同。
需要SELECT权限。
不支持视图,对视图运行,checksum的值始终为null,并返回警告。
对不存在的表,返回null,并警告。
在校验和操作期间,以读锁锁定MyISAM和innodb表。

4.3.1 性能注意事项
默认情况下,逐行读取整个表并计算校验和。对于大表,可能需要教程时间,故此一般只偶尔执行此操作。这种逐行计算方式,可以通过EXTENDED选项获得,可以通过没有以CHECKSUM=1 创建的MyISAM表获得,也可以通过其他引擎获得。
对于以CHECKSUM=1 创建的MyISAM表, CHECKSUM TABLE或 CHECKSUM TABLE … QUICK返回‘live’校验和(即可以快速返回)。如果表不满足所有这些条件,则QUICK方法返回NULL。QUICK方法不支持innodb表。有关CHECKSUM子句的语法可参考 Section 13.1.18, “CREATE TABLE Syntax”。
checksum和行格式有关。若行格式变化,checksum也变化。若旧时间存储格式升级为新格式,如5.5转换为5.6,校验值可能改变。

重要:若校验和不同,则几乎可以肯定这些表在某种程度上是不同的。但是由于使用的列散函数不能保证无冲突,故两个不同的表也可能产生相同的校验和。

4.4 OPTIMIZE TABLE Syntax
OPTIMIZE [NO_WRITE_TO_BINLOG | LOCAL] #该可选项启用时可以使语句不记录到binlog。
TABLE tbl_name [, tbl_name] …
语句需要表的SELECT和insert权限。
optimize table重组数据和相关索引的物理存储,以节约存储空间,提高访问表时的i/o性能。对表确切的变更取决于表的存储引擎。
根据表类型,在这些情况下使用optimize table语句::
::在对有独立表空间的innodb表进行了大量的增、删、改操作后。表和索引将被重组,并且回收磁盘空间以供操作系统使用。
::在对innodb表的fulltext索引的一部分的列进行了大量的增、删、改操作后。先设置innodb_optimize_fulltext_only=1。为将索引维护保持在合理的时间范围内,考虑设置 innodb_ft_num_word_optimize变量以指定在搜索索引中更新的单词数,并执行一系列optimize table语句,直到索引完全更新为止。
::在删除了MyISAM或archive表的很大一部分后,或对含变长行的MyISAM或archive表做了很多更改后。删除的行被链表维护,后续的insert操作可以重用旧行位置。可以使用optimize table回收未使用的空间并对数据文件进行碎片整理。在对表进行大量更改后,此语句还可能会提高使用该表的语句的性能,有时甚至会显著提高。
optimize table支持innodb、MyISAM、archive表。也支持内存ndb表的动态列,但不支持固定宽度的内存列,也不支持磁盘数据表。调节变量 --ndb-optimization-delay,以控制在行批次间的等待时长,从而提高optimize table的性能。For more information, see Previous NDB Cluster Issues Resolved in NDB Cluster 7.3 .对ndb集群表,可以通过杀掉执行optimize的sql线程打断optimize table。
不支持视图。支持分区表,有关于分区表的优化语句请参考第22.3.4节“分区维护”。
默认情况下,optimize table不支持任何其他引擎,并返回一个结果指出缺乏支持。可以通过以–skip-new选项启动mysqld来开启optimize table对其他引擎的支持,这时,optimize table仅仅是映射为alter table。

4.4.1 optimize table的输出
输出为一个表,一个表可能有多行输出,该表最后一行是(表名,check,status,信息),信息应当为OK。
qlua1hj7wm

qlua1hj7wm

optimize table捕获并抛出在将表统计信息从旧损坏表复制到新创表这个过程中的任何错误。例如,若.frm,.myd,.myi文件所有者的系统用户id和mysqld进程的系统用户id不同,optimize table将产生一个错误:“cannot change ownership of the file” (若mysqld用户是root时不会错误)。

4.4.2 innodb详情
对innodb,optimize table被映射为alter table…force(该语句重建表以更新索引统计并释放聚簇索引中未使用的空间)。
optimize table的输出举例:
zk5ch5dbm2h

zk5ch5dbm2h

optimize table将online DDL用于常规、分区innodb表,以减少并发dml操作的停机时间。被optimize table触发、并被alter table…force执行的表的重建就地完成。仅在操作的准备阶段和提交阶段短暂地持有排他表锁。在准备阶段,更新元数据并创建中介表;在提交阶段,提交表元数据的更改。
在以下条件下,optimize table使用表复制方法重建表::
::old_alter_table=1
::mysqld --skip-new
::含fulltext索引的innodb表。因为optimize table不能将在线ddl用于此类表。
innodb使用page-allocation方法存储数据,并且不会像传统存储引擎(如MyISAM)那样遭受碎片。在考虑是否运行优化时,请考虑服务器将处理事务的工作负载::
::一定程度的碎片化是预料之中的。innodb只填充93%的页面,留出空间,以便在不分页的情况下更新。
::删除操作可能留下间隙,使页填充不如预期,这使optimize table有价值。
::当有足够的空间时,行更新通常会重写同页中的数据,具体取决于数据类型和行格式。请参见 第14.9.1.5节“InnoDB表的压缩支持”和 第14.11节“InnoDB行格式”。
::随着时间推移,高并发的工作负载可能在索引中留下间隙,因为innodb通过其mvcc机制保留了相同数据的多个版本。

4.4.3 MyISAM详情
对MyISAM表,optimize table如下工作:
1.若表有已删除行或拆分行,修复该表;
2.若索引页未排序,将其排序;
3.若表统计信息不是最新的(并且不能通过对索引进行排序来完成修复),更新之。

4.4.4 其它注意事项
optimize table将online DDL用于常规、分区innodb表。否则,MySQL会在optimize table运行期间锁表。
optimize table不对R-tree索引进行排序,如在POINT 列上的空间索引。(bug #23578)

4.5 REPAIR TABLE Syntax
REPAIR [NO_WRITE_TO_BINLOG | LOCAL]
TABLE tbl_name [, tbl_name] …
[QUICK] [EXTENDED] [USE_FRM]
repaire table修复可能已损坏的表,仅适用于某些引擎。
需要SELECT和insert权限。
通常用不上repair table,但灾难发生后,这个语句很可能能将MyISAM表的数据找回。若表经常损坏,尝试找到原因,以消除使用repair table的需要。See Section B.4.3.3, “What to Do If MySQL Keeps Crashing”, and Section 15.2.4, “MyISAM Table Problems”.
repair table检查表看是否需要升级,若需要,则按照与 CHECK TABLE … FOR UPGRADE一样的规则执行升级。
注意::
::表修复前备份;在某些情况,如文件系统错误,repair操作可能导致数据丢失。
::若服务器在repair table操作期间奔溃,在重启后,在对该表执行任何其他操作前,立即执行repair table是非常重要的。在最坏的情况下,你可能的到一个新的干净的没有关于数据文件信息的索引文件,然后下一个操作可能覆盖数据文件。这种不太可能,但可能的情形,强调了先备份的价值。
::若主库上的表损坏,在其上运行repair table,任何对该表的改变不会传播到从库。

4.5.1 支持的存储引擎和分区
支持MyISAM,archive,csv表,不支持视图。对MyISAM,默认效果等同myisamchk --recover tbl_name。
支持分区表,然而USE_FRM不能再分区表修复语句中使用。
也可以使用 ALTER TABLE … REPAIR PARTITION来修复一个或多个分区。Section 13.1.8, “ALTER TABLE Syntax”, and Section 22.3.4, “Maintenance of Partitions”.

4.5.2 选项
NO_WRITE_TO_BINLOG 或LOCAL:当省略该选项,语句默认记录到binlog。启用该选项,语句不记录到binlog。
QUICK:尝试仅修复索引文件,不修复数据文件。类似myisamchk --recover --quick.
EXTENDED:一行一行的创建索引,而不是使用排序一次性创建索引。类似myisamchk --safe-recover.
USE_FRM:若.myi索引文件丢失或其头部损坏,可以使用该选项。该选项告诉MySQL忽略.myi文件头信息,并使用.frm文件重建之。这种类型的修复不能使用myisamchk完成。
注意:
:仅在无法使用常规模式时才使用use_frm选项。告诉服务器忽略.myi索引文件导致存储在.myi中的重要表元数据不可为repair过程使用,这可能导致有害后果::
::::当前自增值丢失;
::::表中已删除记录的链接丢失,这意味着已删除记录的可用空间保持非占用状态;
::::.myi头表明表是否压缩。若忽略头信息,无法获知一个表是否压缩,则repair可能导致表内容的变更或丢失。这意味着use_frm不应使用到压缩表上。无论如何,这是不必要的:压缩表是只读的,因此表不应损坏。
:若使用use_frm到非当前版本服务器建立的表,repair table不会尝试修复该表。此时,输出结果包含(表名,repair,error,Failed repairing incompatible .FRM file)。
:若使用use_frm,repair table不会检查表是否需要升级。

4.5.3 repair table的输出
输出为一个表,一个表可能有多行输出,该表最后一行是(表名,check,status,信息),信息应当为OK。

4hzkz9ljy5y

4hzkz9ljy5y

对于MyISAM,如果信息不为OK,当尝试使用myisamchk --safe-recover修复该表。repair table语句没有实现Myisamchk的所有选项,在myisamchk --safe-recover中,还可以使用repair table不支持的选项,如 --max-record-length。
repair table捕获并抛出在将表统计信息从旧损坏表复制到新创表这个过程中的任何错误。例如,若.frm,.myd,.myi文件所有者的系统用户id和mysqld进程的系统用户id不同,repair table将产生一个错误:“cannot change ownership of the file” (若mysqld用户是root时不会错误)。

4.5.4 repair table的注意事项*
若avoid_temporal_upgrade=ON(默认),含5.6.4前的旧时间格式(time、datetime、timestamp不支持小数秒精度)的表将被repair table升级;若avoid_temporal_upgrade=OFF,则忽略旧时间列,并不会升级他们。
可以设定一些系统变量以增加repair table的性能。参见第8.6.3节“优化REPAIR TABLE语句”。

如果看到不过瘾还可以点击查看MySQL常用工具系列文章,相信会有更多收获哦~


作者:Amy—go

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

2

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广