mysql ガチbeginnerがやってみたことと反省したこと
DESCRIPTION
MySQL Beginners Talk Vol.1 @studio3104 comTRANSCRIPT
MySQLガチBeginnerが
やってみたことと反省したこと
Beginner詐欺じゃないよ
@studio3104_com
Lightning Talk at MySQL Beginners Talk Vol.1
自己紹介
@studio3104_com (Satoshi Suzuki)
-- MySQL を本気で使い始めてから1年ちょい。 -- LPIC Level2とか無駄に持ってる。 -- Ubuntu は8.10から。 -- 妻、娘、息子。リア充。
-- ソシャゲ、公式サイト、パチ(スロ)ンコ -- こんなのやってます。 →→→→→→→ -- PostgreSQLもあるよ。
innodb_buffer_pool_size
Someday・・・
「スロークエリどうにかなんない?」
って言われました
どうにかしました。
このサーバを構築したのはボクではありません。
どのようにしてどうにかしたのか
mysqldのチューニング
→ 32GBRAMのサーバなのに、innodb_buffer_pool_sizeが約8GBに設定されていたので、約24GBまで増やした。
ダメクエリをEXPLAINして、修正
→ そんなことはしていない。innodb_buffer_pool_sizeを増やしただけ。(え・・・
反省点
どんなクエリだったのか分析していない
→ EXPLAIN
→ 本当にinnodb_buffer_pool_sizeを増やしただけで改善した と言っていいものなのか。
どんなクエリが出ていたのか見ていなかった
→ 論外。せめてスロークエリログは見るべきだった。
→ でもスロークエリと言っても設定次第であるということ。
→ long_query_timeとか、log_queries_not_using_indexes
そもそも・・・
min_examined_row_limit
クエリチューニングがなんとなくわかってきたところで・・・
検索効率の悪いクエリをあぶり出したくて、
mysql> set @@global.log_queries_not_using_indexes=1;
ってしたのに、
スロークエリログに何も出力されない!
状況は?
健全なクエリしか流れてないんじゃないの?
→ mysql> SELECT * FROM HOGE;
→ コレが検出されないんですね。
MySQLのバージョンは?
→ 5.1.50
→ log_queries_not_using_indexesってバージョン関係あったっけ・・・?
mysqldの再起動は?
→ 不要。稼働中に変更可能。
原因は・・・?
MySQLのシステム変数を見てみる
min_examined_row_limit→ mysql> SHOW GLOBAL VARIABLES
ググる
→ 生活の基本。
原因は!!
min_examined_row_limit「○○○行以上の行をテーブルから読み込んだクエリをスロークエリロ
グに記録する」という指定ができるようになる。多くの行を読み込むクエリは、潜在的にサーバ全体の性能を劣化させる危険性があるので、long_query_timeを少し大きめにしておいて、このオプションを併用しておくといいだろう。例えばmin_examined_row_limit=10000など。いずれの変数もアプリケーションの特性に合わせて調節して欲しい。
http://nippondanji.blogspot.jp/2009/01/mysql-51.html
--single-transaction
ユーザからこんな問い合わせが・・・
体力回復アイテムを使ったのに、
「体力がありません」
って出るけどどういうことなの?
調べたら、夜間バッチのmysqldumpが原因ぽいことが判明。
Slave
user_tblID:0002NAME:hogeHP:0
Master
user_tblID:0002NAME:hogeHP:0
Replication
よくある、Master/Slaveのトポロジですね。よく見ます。
Client
Slave
user_tblID:0002NAME:hogeHP:0
Master
user_tblID:0002NAME:hogeHP:0
Replication
Slaveでmysqlsump開始、user_tblがREAD LOCKされます。
Client
Slave
user_tblID:0002NAME:hogeHP:0
Master
user_tblID:0002NAME:hogeHP:0
Replication
UPDATE user_tblSET HP=300WHERE ID=0002;
回復アイテム利用時のクエリがMasterに飛んできます。
Client
Slave
user_tblID:0002NAME:hogeHP:0
Master
user_tblID:0002NAME:hogeHP:300
Replication
Slaveのuser_tblはREAD LOCK中なので、変更が反映されません。
Client
Slave
user_tblID:0002NAME:hogeHP:0
Master
user_tblID:0002NAME:hogeHP:300
Replication
SELECT HPFROM user_tblWHERE ID = '0002';
残り体力を問い合わせるクエリがSlaveに飛んできます。
Client
このように考えました。
そのSELECTをMasterに向ける
→ いろいろな事情でなんか難しいらしい
バックアップ専用のSlaveを設ける
→ やってみた
Slave
user_tblID:0002NAME:hogeHP:0
Master
user_tblID:0002NAME:hogeHP:300
バックアップ専用のSlaveサーバを追加しました。
Client
Slave
user_tblID:0002NAME:hogeHP:0
新たな問題
(予算の関係で)Masterと比較して、
スペックが低すぎるサーバを追加してしまった→ Replication がMaster に追いつかない・・・
→ むしろどんどん離されている・・・
→ 日毎に遅れていくSlaveでバックアップするの・・・?
無駄なことをしていたことに気づいた。
--single-transaction オプションを、使えばいいんじゃないか・・・?
--single-transaction オプションとは・・・?
This option sends a START TRANSACTION SQL statement to the server before dumping data. It is useful only with transactional tables such as InnoDB, because then it dumps the consistent state of the database at the time whenBEGIN was issued without blocking any applications.When using this option, you should keep in mind that only InnoDB tables are dumped in a consistent state. For example, any MyISAM or MEMORY tables dumped while using this option may still change state.While a --single-transaction dump is in process, to ensure a valid dump file (correct table contents and binary log coordinates), no other connection should use the following statements: ALTER TABLE, CREATE TABLE,DROP TABLE, RENAME TABLE, TRUNCATE TABLE. A consistent read is not isolated from those statements, so use of them on a table to be dumped can cause the SELECT that is performed by mysqldump to retrieve the table contents to obtain incorrect contents or fail.The --single-transaction option and the --lock-tables option are mutually exclusive because LOCK TABLES causes any pending transactions to be committed implicitly.This option is not supported for MySQL Cluster tables; the results cannot be guaranteed to be consistent due to the fact that the NDBCLUSTER storage engine supports only the READ_COMMITTED transaction isolation level. You should always use NDB backup and restore instead.To dump large tables, you should combine the --single-transaction option with --quick.
引用: http://dev.mysql.com/doc/refman/5.5/en/mysqldump.html#option_mysqldump_single-transaction
結論
無知は罪なり
スペックが違いすぎるSlaveは論外
→ バックアップ専用なら、少し劣っててもいいかも?
→ Replication がどんどん離されていく様はおもしろかった
専用サーバでのmysqldumpは間違いではない
→ 負荷を考えて、本番で参照されないサーバでバックアップ
→ 同等のスペックの専用サーバを準備する予算があれば・・・
--dump-slave
--single-transactionを覚えたので・・・
新しいオプションを使ってみよう。
MySQL5.5から追加になったmysqldumpのオプション
--dump-slaveスレーブからダンプをとった場合、スレーブが参照しているマスターの情報をCHANGE MASTERとしてダンプに含める。
--apply-slave-statementsSTOP SLAVEおよびSTART SLAVEコマンドを、CHANGE
MASTERの前後に追加する。
--include-master-host-portCHANGE MASTERコマンドにマスターのホスト名とポートを含め
る。
あれ・・・?
--dump-slave オプションつけたら、mysqdumpの最中
Replication が停まっちゃった
んですけど・・・
動作に疑問があるなら、ソースを追ってみよう。
Cとか、C++とかよくわかんないけど頑張って読んでみた。
STOP SLAVE SQL_THREADして、
すべて終わってから、
START SLAVEしてる・・・
@nippondanjiさんに聞いてみた
--dump-slaveをつけると、
レプリケーションが
停まっちゃうんですが?Exactry!!
その通りです!!
一般クエリログの比較
一般クエリログの比較
root@localhost on /*!40100 SET @@SQL_MODE='' *//*!40103 SET TIME_ZONE='+00:00' */SHOW SLAVE STATUSSTOP SLAVE SQL_THREADFLUSH TABLESFLUSH TABLES WITH READ LOCKSET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READSTART TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */SHOW SLAVE STATUSUNLOCK TABLESSHOW SLAVE STATUSSTART SLAVE・
・[ダンプ処理]
パッチ適用前 パッチ適用後
root@localhost on/*!40100 SET @@SQL_MODE='' *//*!40103 SET TIME_ZONE='+00:00' */SHOW SLAVE STATUSSTOP SLAVE SQL_THREADSET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READSTART TRANSACTION /*!40100 WITH CONSISTENT SNAPSHOT */SHOW SLAVE STATUSUNLOCK TABLES・
・[ダンプ処理]・・SHOW SLAVE STATUSSTART SLAVE
反省
無知は罪なり
書かれたパッチはサジェスチョンであるということ
→ パッチはそのまま取り込まれるという保証がない
そもそもBUG登録ページのタイトルがアレ
→ FLUSH TABLES is missing on mysqldump with --dump-slave
→ ついでにどうにかしてもらったんだということ
Powered by・・・
MySQLガチBeginnerがやってみたことと反省
ご清聴ありがとうございました
@studio3104_com
Lightning Talk at MySQL Beginners Talk Vol.1