Answers:
MyISAM表崩溃很容易。
每个MyISAM表的标题中都有一个计数器,该计数器跟踪对该表有多少打开的文件句柄。
如果您启动mysql并且标题中的数字与实际文件句柄的数目不匹配,则mysqld将该表视为已崩溃。
如果一个简单的文件REPAIR TABLE mdl_user
每次都能重新运行而又不会丢失数据,则可能表明您有一个流量非常高的站点,该站点写入mdl_user
。
如果数十张表需要此表REPAIR TABLE
,我会将所有表都转换为InnoDB。但是,如果该mdl_user
表是唯一出现此问题的表,则可以执行某些操作(对于本示例,假设数据库为moodle
);
echo "REPAIR TABLE moodle.mdl_user;" > /var/lib/mysql/MoodleStartUp.sql
将此添加到/etc/my.cnf
[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql
每次重新启动mysql都会触发修复表脚本
运行此代码以将MyISAM表批量转换为InnoDB脚本,然后进行查看
MYSQL_USER=root
MYSQL_PASS=password
MYSQL_CONN="-u${MYSQL_USER} -p ${MYSQL_PASS}"
echo "SET SQL_LOG_BIN = 0;" > /root/ConvertMyISAMToInnoDB.sql
mysql ${MYSQL_CONN} -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',table_schema,'.',table_name,' ENGINE=InnoDB;') InnoDBConversionSQL FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql','performance_schema') ORDER BY (data_length+index_length)" > /root/ConvertMyISAMToInnoDB.sql
less /root/ConvertMyISAMToInnoDB.sql
对转换脚本的内容满意后,请运行它
mysql ${MYSQL_CONN} < /root/ConvertMyISAMToInnoDB.sql
@Kevin,在使用MyISAM时,如果磁盘空间不足,该怎么办?
这里是要考虑的事情:根据MySQL 5.0认证研究指南,
项目符号#11在第408,409页第29.2节中说:
如果在向MyISAM表添加行时磁盘空间不足,则不会发生任何错误。服务器将挂起操作,直到空间可用,然后完成操作。
当磁盘空间不足时,请勿仅关闭或杀死mysql。当前未使用的任何MyISAM中打开文件句柄的数量都不会清除。因此,MyISAM表被标记为崩溃。如果您可以在仍运行mysqld的情况下释放数据卷中的磁盘空间,则一旦磁盘空间可用,mysqld就会继续运行。
我找到了一条很好的行将所有表转换为InnoDB:
mysql -u root -p dbName -e "show table status where Engine='MyISAM';" |
awk 'NR>1 {print "ALTER TABLE "$1" ENGINE = InnoDB;"}' |
mysql -u root -p dbName