我是Moodle站点的管理员,该站点的用户表已损坏并且无法使用。
幸运的是,一个简单的方法REPAIR TABLE mdl_user使它再次工作。问题是我不知道为什么它实际上崩溃并使其无法使用,我想确保下次我有更好的准备。
我不是一个经验丰富的 DBA——我只是一个做很多事情的开发人员,所以请耐心等待。
我可以只恢复备份,但我想有办法防止崩溃。
这些表是 utf8_general_ci 并使用 MyISAM。
为什么 MySQL 表会崩溃?我能做些什么来防止这种情况发生?
Rol*_*DBA 11
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
Run Code Online (Sandbox Code Playgroud)
将此添加到 /etc/my.cnf
[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql
Run Code Online (Sandbox Code Playgroud)
每次重启mysql都会触发Repair Table Script
运行此代码制作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
Run Code Online (Sandbox Code Playgroud)
一旦您对转换脚本的内容感到满意,然后运行它
mysql ${MYSQL_CONN} < /root/ConvertMyISAMToInnoDB.sql
Run Code Online (Sandbox Code Playgroud)
@Kevin,在使用 MyISAM 时,如果磁盘空间不足是您的问题怎么办?
这里需要考虑:根据MySQL 5.0 Certification Study Guide,

第 11页第 408,409 页第 29.2 节中的要点如下:
如果在向 MyISAM 表添加行时磁盘空间不足,则不会发生错误。服务器暂停操作,直到空间可用,然后完成操作。
当磁盘空间不足时,不要只是关闭或杀死 mysql。任何当前使用的 MyISAM 中打开文件句柄的计数将不会被清除。因此,MyISAM 表被标记为崩溃。如果您可以在 mysqld 仍在运行的情况下释放数据卷中的磁盘空间,一旦磁盘空间可用,mysqld 将继续使用。
| 归档时间: |
|
| 查看次数: |
32743 次 |
| 最近记录: |