mysql ガチbeginnerがやってみたことと反省したこと

38
MySQLガチBeginnerやってみたことと反省したこと Beginner詐欺じゃないよ @studio3104_com Lightning Talk at MySQL Beginners Talk Vol.1

Upload: satoshi-suzuki

Post on 31-May-2015

7.657 views

Category:

Documents


0 download

DESCRIPTION

MySQL Beginners Talk Vol.1 @studio3104 com

TRANSCRIPT

Page 1: MySQL ガチBeginnerがやってみたことと反省したこと

MySQLガチBeginnerが

やってみたことと反省したこと

Beginner詐欺じゃないよ

@studio3104_com

Lightning Talk at MySQL Beginners Talk Vol.1

Page 2: MySQL ガチBeginnerがやってみたことと反省したこと

自己紹介

@studio3104_com (Satoshi Suzuki)

-- MySQL を本気で使い始めてから1年ちょい。 -- LPIC Level2とか無駄に持ってる。 -- Ubuntu は8.10から。 -- 妻、娘、息子。リア充。

-- ソシャゲ、公式サイト、パチ(スロ)ンコ -- こんなのやってます。 →→→→→→→ -- PostgreSQLもあるよ。

Page 3: MySQL ガチBeginnerがやってみたことと反省したこと

innodb_buffer_pool_size

Page 4: MySQL ガチBeginnerがやってみたことと反省したこと

Someday・・・

「スロークエリどうにかなんない?」

って言われました

Page 5: MySQL ガチBeginnerがやってみたことと反省したこと

どうにかしました。

Page 6: MySQL ガチBeginnerがやってみたことと反省したこと

このサーバを構築したのはボクではありません。

どのようにしてどうにかしたのか

mysqldのチューニング

→ 32GBRAMのサーバなのに、innodb_buffer_pool_sizeが約8GBに設定されていたので、約24GBまで増やした。

ダメクエリをEXPLAINして、修正

→ そんなことはしていない。innodb_buffer_pool_sizeを増やしただけ。(え・・・

Page 7: MySQL ガチBeginnerがやってみたことと反省したこと

反省点

どんなクエリだったのか分析していない

→ EXPLAIN

→ 本当にinnodb_buffer_pool_sizeを増やしただけで改善した と言っていいものなのか。

どんなクエリが出ていたのか見ていなかった

→ 論外。せめてスロークエリログは見るべきだった。

→ でもスロークエリと言っても設定次第であるということ。

→ long_query_timeとか、log_queries_not_using_indexes

そもそも・・・

Page 8: MySQL ガチBeginnerがやってみたことと反省したこと

min_examined_row_limit

Page 9: MySQL ガチBeginnerがやってみたことと反省したこと

クエリチューニングがなんとなくわかってきたところで・・・

検索効率の悪いクエリをあぶり出したくて、

mysql> set @@global.log_queries_not_using_indexes=1;

ってしたのに、

スロークエリログに何も出力されない!

Page 10: MySQL ガチBeginnerがやってみたことと反省したこと

状況は?

健全なクエリしか流れてないんじゃないの?

→ mysql> SELECT * FROM HOGE;

→ コレが検出されないんですね。

MySQLのバージョンは?

→ 5.1.50

→ log_queries_not_using_indexesってバージョン関係あったっけ・・・?

mysqldの再起動は?

→ 不要。稼働中に変更可能。

Page 11: MySQL ガチBeginnerがやってみたことと反省したこと

原因は・・・?

MySQLのシステム変数を見てみる

min_examined_row_limit→ mysql> SHOW GLOBAL VARIABLES

ググる

→ 生活の基本。

Page 12: MySQL ガチBeginnerがやってみたことと反省したこと

原因は!!

min_examined_row_limit「○○○行以上の行をテーブルから読み込んだクエリをスロークエリロ

グに記録する」という指定ができるようになる。多くの行を読み込むクエリは、潜在的にサーバ全体の性能を劣化させる危険性があるので、long_query_timeを少し大きめにしておいて、このオプションを併用しておくといいだろう。例えばmin_examined_row_limit=10000など。いずれの変数もアプリケーションの特性に合わせて調節して欲しい。

http://nippondanji.blogspot.jp/2009/01/mysql-51.html

Page 13: MySQL ガチBeginnerがやってみたことと反省したこと

--single-transaction

Page 14: MySQL ガチBeginnerがやってみたことと反省したこと

ユーザからこんな問い合わせが・・・

体力回復アイテムを使ったのに、

「体力がありません」

って出るけどどういうことなの?

Page 15: MySQL ガチBeginnerがやってみたことと反省したこと

調べたら、夜間バッチのmysqldumpが原因ぽいことが判明。

Page 16: MySQL ガチBeginnerがやってみたことと反省したこと

Slave

user_tblID:0002NAME:hogeHP:0

Master

user_tblID:0002NAME:hogeHP:0

Replication

よくある、Master/Slaveのトポロジですね。よく見ます。

Client

Page 17: MySQL ガチBeginnerがやってみたことと反省したこと

Slave

user_tblID:0002NAME:hogeHP:0

Master

user_tblID:0002NAME:hogeHP:0

Replication

Slaveでmysqlsump開始、user_tblがREAD LOCKされます。

Client

Page 18: MySQL ガチBeginnerがやってみたことと反省したこと

Slave

user_tblID:0002NAME:hogeHP:0

Master

user_tblID:0002NAME:hogeHP:0

Replication

UPDATE user_tblSET HP=300WHERE ID=0002;

回復アイテム利用時のクエリがMasterに飛んできます。

Client

Page 19: MySQL ガチBeginnerがやってみたことと反省したこと

Slave

user_tblID:0002NAME:hogeHP:0

Master

user_tblID:0002NAME:hogeHP:300

Replication

Slaveのuser_tblはREAD LOCK中なので、変更が反映されません。

Client

Page 20: MySQL ガチBeginnerがやってみたことと反省したこと

Slave

user_tblID:0002NAME:hogeHP:0

Master

user_tblID:0002NAME:hogeHP:300

Replication

SELECT HPFROM user_tblWHERE ID = '0002';

残り体力を問い合わせるクエリがSlaveに飛んできます。

Client

Page 21: MySQL ガチBeginnerがやってみたことと反省したこと

このように考えました。

そのSELECTをMasterに向ける

→ いろいろな事情でなんか難しいらしい

バックアップ専用のSlaveを設ける

→ やってみた

Page 22: MySQL ガチBeginnerがやってみたことと反省したこと

Slave

user_tblID:0002NAME:hogeHP:0

Master

user_tblID:0002NAME:hogeHP:300

バックアップ専用のSlaveサーバを追加しました。

Client

Slave

user_tblID:0002NAME:hogeHP:0

Page 23: MySQL ガチBeginnerがやってみたことと反省したこと

新たな問題

(予算の関係で)Masterと比較して、

スペックが低すぎるサーバを追加してしまった→ Replication がMaster に追いつかない・・・

→ むしろどんどん離されている・・・

→ 日毎に遅れていくSlaveでバックアップするの・・・?

Page 24: MySQL ガチBeginnerがやってみたことと反省したこと

無駄なことをしていたことに気づいた。

--single-transaction オプションを、使えばいいんじゃないか・・・?

Page 25: MySQL ガチBeginnerがやってみたことと反省したこと

--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

Page 26: MySQL ガチBeginnerがやってみたことと反省したこと

結論

無知は罪なり

スペックが違いすぎるSlaveは論外

→ バックアップ専用なら、少し劣っててもいいかも?

→ Replication がどんどん離されていく様はおもしろかった

専用サーバでのmysqldumpは間違いではない

→ 負荷を考えて、本番で参照されないサーバでバックアップ

→ 同等のスペックの専用サーバを準備する予算があれば・・・

Page 27: MySQL ガチBeginnerがやってみたことと反省したこと

--dump-slave

Page 28: MySQL ガチBeginnerがやってみたことと反省したこと

--single-transactionを覚えたので・・・

Page 29: MySQL ガチBeginnerがやってみたことと反省したこと

新しいオプションを使ってみよう。

MySQL5.5から追加になったmysqldumpのオプション

--dump-slaveスレーブからダンプをとった場合、スレーブが参照しているマスターの情報をCHANGE MASTERとしてダンプに含める。

--apply-slave-statementsSTOP SLAVEおよびSTART SLAVEコマンドを、CHANGE

MASTERの前後に追加する。

--include-master-host-portCHANGE MASTERコマンドにマスターのホスト名とポートを含め

る。

Page 30: MySQL ガチBeginnerがやってみたことと反省したこと

あれ・・・?

--dump-slave オプションつけたら、mysqdumpの最中

Replication が停まっちゃった

んですけど・・・

Page 31: MySQL ガチBeginnerがやってみたことと反省したこと

動作に疑問があるなら、ソースを追ってみよう。

Page 32: MySQL ガチBeginnerがやってみたことと反省したこと

Cとか、C++とかよくわかんないけど頑張って読んでみた。

STOP SLAVE SQL_THREADして、

すべて終わってから、

START SLAVEしてる・・・

Page 33: MySQL ガチBeginnerがやってみたことと反省したこと

@nippondanjiさんに聞いてみた

--dump-slaveをつけると、

レプリケーションが

停まっちゃうんですが?Exactry!!

その通りです!!

Page 34: MySQL ガチBeginnerがやってみたことと反省したこと

BUG登録されて、パッチが書かれている!!

http://bugs.mysql.com/bug.php?id=65035

Page 35: MySQL ガチBeginnerがやってみたことと反省したこと

一般クエリログの比較

一般クエリログの比較

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

Page 36: MySQL ガチBeginnerがやってみたことと反省したこと

反省

無知は罪なり

書かれたパッチはサジェスチョンであるということ

→ パッチはそのまま取り込まれるという保証がない

そもそもBUG登録ページのタイトルがアレ

→ FLUSH TABLES is missing on mysqldump with --dump-slave

→ ついでにどうにかしてもらったんだということ

Page 37: MySQL ガチBeginnerがやってみたことと反省したこと

Powered by・・・

Page 38: MySQL ガチBeginnerがやってみたことと反省したこと

MySQLガチBeginnerがやってみたことと反省

ご清聴ありがとうございました

@studio3104_com

Lightning Talk at MySQL Beginners Talk Vol.1