MySQLテーブルがクラッシュするのはなぜですか?どうすれば防止できますか?


9

私は、Moodleサイトの管理者です。そのユーザテーブルが破損していて、使用できなくなりました。

幸いなことに、シンプルなREPAIR TABLE mdl_userもので再び機能しました。問題は、実際にクラッシュしてそれが使用できなくなった理由がわからないことです。次回はよりよく準備できるようにしたいと思います。

私は完全に経験豊富なDBAではありません—私は多くのことを行う開発者なので、ご容赦ください。

バックアップを復元することもできますが、クラッシュを防ぐ方法はあると思います。

これらのテーブルはutf8_general_ciであり、MyISAMを使用しています。

MySQLテーブルがクラッシュするのはなぜですか?これを防ぐにはどうすればよいですか?

回答:


11

MyISAMテーブルがクラッシュするのはかなり簡単です。

すべてのMyISAMテーブルのヘッダーには、テーブルに対するオープンファイルハンドルの数を追跡するカウンターがあります。

mysqlを起動し、ヘッダーの数が実際のファイルハンドルの数と一致しない場合、mysqldはテーブルをクラッシュしたものとして扱います。

シンプルでREPAIR TABLE mdl_user毎回データを失うことなく機能する場合、これはに書き込みを行う非常にトラフィックの多いサイトがあることを示している可能性がありますmdl_user

数十のテーブルでこれが必要な場合REPAIR TABLEは、すべてのテーブルをInnoDBに変換します。ただし、mdl_userテーブルがこの問題のある唯一のテーブルである場合は、何かできることがあります(この例では、データベースがであるとしますmoodle)。

すべてのテーブルをMyISAMとして残したい場合

ステップ01:修復テーブルスクリプトを作成する

echo "REPAIR TABLE moodle.mdl_user;" > /var/lib/mysql/MoodleStartUp.sql

ステップ02:修復スクリプトをスタートアップファイルとして宣言する

これを/etc/my.cnfに追加します

[mysqld]
init-file=/var/lib/mysql/MoodleStartUp.sql

ステップ03:mysqlを再起動します

mysqlを再起動するたびにテーブル修復スクリプトがトリガーされます

すべてのテーブルをInnoDBにしたい場合

このコードを実行して、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

UPDATE 2012-03-15 14:00 EDT

@Kevin、MyISAMを使用しているときに、ディスク容量が足りなくなった場合はどうなりますか?

ここで考慮すべき点があります:MySQL 5.0認定調査ガイドによると、

ここに画像の説明を入力してください

箇条書き#11は、ページ408、409のセクション29.2で次のように述べています。

MyISAMテーブルに行を追加しているときにディスク領域が不足しても、エラーは発生しません。サーバーは、スペースが使用可能になるまで操作を中断し、操作を完了します。

ディスク領域が不足した場合は、mysqlをシャットダウンまたは強制終了しないでください。現在使用されているMyISAMで開いているファイルハンドルの数はクリアされません。したがって、MyISAMテーブルはクラッシュとマークされます。mysqldを実行したままデータボリュームのディスクスペースを解放できる場合、ディスクスペースが利用可能になると、mysqldは兵士になります。


優れた反応。ファイルハンドルのビットを知りませんでした、そしてあなたはすでに何かがうまくいかない場合にどうやって防ぐ(または自動的に修復する)ことができるかをすでに解決しました。サイトが実際にmdl_user(または他のテーブル)に大量の書き込みを行っている場合の安全のための提案はありますか?
AeroCross

3つのことを行う必要があります。1)RAMを増やす、2)max_connectionsを増やす、3)InnoDBに切り替える。
RolandoMySQLDBA 2012年

ここにNoob。このコードをどこで「実行」しますか?サーバーにアップロードされたファイルから、またはいくつかのコマンドラインから?
UncaughtTypeError

0

私はmysqlのmoodleサイトも管理しています。テーブルの破損の最も一般的な原因は、ディスク領域が不足していることです。


@RolandoMySQLDBA-ええ、ディスク容量が確かに問題です(他のいくつかのプロセス、および一般的な管理哲学に関連しています)。残念ながら、スペースを空けても問題が自動的に解決することはなく、十分なタイミングで問題が解決しないこともあります。私の回答は、moodle / mysqlインスタンスでは、mysql / myisamが何を行うかに関係なく、ディスク容量の問題がテーブルのクラッシュを引き起こす可能性があることを指摘するだけでした。
ケビン

-3

すべてのテーブルをInnoDBに変換するための適切な行が1つ見つかりました。

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

コードはそれで問題ないかもしれませんが、最初の部分の質問には答えません(なぜMySQLテーブルがクラッシュするのですか?)。それが2番目の部分(それを防ぐ方法?)に答えるという意味であれば、もう少し説明を追加してください。
ypercubeᵀᴹ

さらに詳細を追加します。これを実行すると、データベース内のすべてのテーブルが変換されますか?またはサーバー全体?テーブルが変換に失敗し、エラーが発生した場合はどうなりますか?一部のテーブルが変換され、一部がMyiSAMに残る可能性はありますか?一般に、これを実行する前に、DBAは他に何を考慮すべきですか?
ypercubeᵀᴹ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.