mysql v8.0.27
mysql [-h machine] -u <user> -p [db_name]
mysql -u [MySQLのユーザ名] -p db_name < /Users/user_name/Desktop/example.sql
例
mysql -u root -p world < /etc/mysql/sql/tuning-guide/world.sql
mysql -V
mysql> exit
mysql> show full processlist;
mysql> select host,user from mysql.user;
mysql> SHOW DATABASES;
mysql> USE データベース名;
mysql>create database (dbname);
mysql> drop database <データベース名>;
mysql> SELECT database();
mysql> SHOW TABLES FROM データベース名;
mysql> desc テーブル名;
mysql> SHOW COLUMNS FROM テーブル名;
mysql> source /Users/user_name/Desktop/example.sql;
mysql> show create database DB名;
mysql> show create table テーブル名;
- data & schema info
mysqldump -u’ユーザー名’ -p’パスワード’ –all-databases > backup.sql
- Only schema info
mysqldump -u’ユーザー名’ -p’パスワード’ -d –all-databases > backup.sql
- data & schema info
mysqldump -u’ユーザー名’ -p’パスワード’ DB名 > backup.sql
- Only schema info
mysqldump -u’ユーザー名’ -p’パスワード’ -d DB名 > backup.sql
以下エラーが出た場合は my.cnf を修正 「mysqldump: unknown variable ‘symbolic-links=0’」
変更箇所
MySQL の設定ファイル「my.cnf」にて「symbolic-links」
をコメントアウト
- 全 DB のリストア
mysql -u’ユーザー名’ -p’パスワード’ < backup.sql
- 特定 DB のリストア
mysql -u’ユーザー名’ -p’パスワード’ DB名 < backup.sql
mysql> select * from information_schema.user_privileges;
mysql> select * from information_schema.schema_privileges;
mysql> select * from information_schema.table_privileges;
mysql> select * from information_schema.column_privileges;
mysql> create user ユーザー名@接続元ホスト IDENTIFIED BY パスワード;
全ホストへのアクセス許可は*ではなく、%を使う
mysql> create user ‘ユーザー名’@’%’ IDENTIFIED BY ‘パスワード’;
mysql> drop user ‘ユーザー名’@’接続元ホスト’;
mysql> show grants for ‘ユーザー名’@’接続元ホスト’;
GRANT 権限 ON DB 名.テーブル名 TO ユーザー名@ホスト名
例;アクセス許可
grant all privileges on . to ‘ユーザー名’@’ホスト名’ identified by ‘’ with grant option;
REVOKE 権限 ON DB名.テーブル名 FROM ユーザー名@ホスト名;
例:
$ REVOKE ALL ON testdb.* FROM ‘testuser’@’testhost’;
ユーザーの追加、削除、権限操作の後は必ず FLUSH PRIVILEGES で反映が必要。
mysql> grant all privileges on [DB2名].[テーブル名] to ‘ユーザー名’@’接続元ホスト’ WITH GRANT OPTION;
簡単なやつ ↓
mysql> grant all on DB名.テーブル名 to ‘ユーザー名’;
mysql> show global status;
例:過去の最大コネクション数
mysql> show status like ‘%Max_used%’;
例:現在のコネクション数
mysql> show status like ‘%Threads_connected%’;
mysql> show engine innodb status;
mysql> analize table テーブル名;
- 無効にする
SET FOREIGN_KEY_CHECKS = 0;
- 有効に戻す
SET FOREIGN_KEY_CHECKS = 1;
- time consuming query トップ 10
-
use performance_shema;
-
select \* from events_statements_summary_by_digest order by sum_timer_wait desc limit 10 \G
SELECT (100 * SUM_TIMER_WAIT / sum(SUM_TIMER_WAIT)
OVER ()) percent,
SUM_TIMER_WAIT AS total,
COUNT_STAR AS calls,
AVG_TIMER_WAIT AS mean,
substring(DIGEST_TEXT, 1, 75)
FROM performance_schema.events_statements_summary_by_digest
ORDER BY SUM_TIMER_WAIT DESC
LIMIT 10;
*each row shows the response time as a total and as percent of the overal response time.
*mean は平均実行時間
*SUM_ROWS_EXAMINED
が SUM_ROWS_SENT よりも相対的に高いときは、index による filtering が機能していないかもしれない
*SUM_SELECT_FULL_JOIN
が高いときは、Join コンディションに index が必要か、joint condition が存在しないかのどちらか
*SUM_SELECT_RANGE_CHECK
が大きいときは index を変更する目安になる
これは片方のテーブルで全件、もう片方のテーブルで範囲検索を行って JOIN した回数。
*SUM_SELECT_RANGE_CHECK
は INDEX が貼られてないカラムで JOIN された回数。
INDEX が足りていないので 0 で無いときは INDEX の利用を検討
*SUM_CREATED_TMP_DISK_TABLE
はディスク上にテンポラリーテーブルが作成された回数
temporary table メモリ上に作成されるテーブル。tmp_table_size を超える場合は、「created_tmp_disk_tables」としてディスク上に作成 temp file ファイルソート時に、sort_buffer_size に設定のメモリ領域では足りずに、ディスク上の tmep 領域に出力されるファイル
*SUM_SORT_MERGE_PASSES
はフィアルを利用したマージソートのパス数。
カウントされている場合は、sort_buffer_size が不足しファイルアクセスされていることなので、sort_buffer_size を増やすことを検討
- high loaded schema table フル テーブル スキャンが行われたテーブルを調べる
select * from schema_tables_with_full_table_scans;
フルテーブルスキャンが行われたクエリを調べる
select * from statements_with_full_table_scans order by no_index_used_count desc\G
- Table I/O と File I/O
- for select
world という db 名の city テーブルの Table I/O
SELECT OBJECT_TYPE, OBJECT_SCHEMA, OBJECT_NAME, INDEX_NAME, COUNT_STAR FROM performance_schema.table_io_waits_summary_buy_index_usage WHERE OBJECT_SCHEMA = 'world' AND OBJECT_NAME = 'city'\G
*index が使われないと COUNT_STAR が高くなる
- for update/delete
*index が使われてないと、COUNT_READ と COUNT_FETCH が高くなる
- Error Summary tables
- dead lock が何回起きているか見たいとき
select * from events_errors_summary_by_account_by_error where error_name = "er_lock_deadlock"\G
- Is the runtime shown justified for the given Query?
- If the Query is slow , where does the runtime jumps?
*if there is a big difference between Estimated cost and Actual cost, optimizer will make poor decision.
ANALYZE TABLE <tbl_name>;
- 1 回につき 1 箇所の変更、相対的に小さい変化量、side effect を意識
- Buffer/Sort と Buffer/Join が十分確保されているからと言ってクエリが早くなるとは限らない。join が実行される回数だけメモリ割り当てのオーバーヘッドが生じるリスクが高まる
- 一方、buffer_pool へのアロケーションは mysql が立ち上がるときに行われるのでオーバーヘッドにはなりえない
- buffer_pool、red_logs、table_caches がしばしば変更の対象となりうる
- Buffer Pool は2つの領域に分けられる
- 一つは「old block sublist」、2つ目は「new block sublist」
- データは常にページ全体の古いブロックの先頭または先頭に読み込まれる
- 同じページが必要となった場合には old block sublist から new block sublist へ移動(昇格)される
- 2つの sublist は LRU(Least Recently Used)というコンセプトに基づいている 新しいページ用のスペースが確保したくなったら、LRU に基づいて、最も古いものから追放される
- default は 128MiB
- Buffer Pool がどれだけ活用されているかをみるためには Hit Rate をみるのがよい
計算式
100 - (100 * Innodb_pages_read/Innodb_buffer_pool_read_requests)
クエリ
SELECT Variable_name, Variable_value FROM sys.metrics WHERE Variable_name IN ('Innodb_pages_read',Innodb_buffer_pool_read_requests)\G
値の変更
-- Set a global system variable
-- Set innodb_buffer_pool_size variable to 1 GB
SET GLOBAL innodb_buffer_pool_size = 1073741824;
-- Set a session system variable
SET SESSION innodb_buffer_pool_size = 1073741824;
-- Persist a global system variable to the mysqld-auto.cnf file( and set the runtime value)
SET PERSIST innodb_buffer_size = 1073741824;
innodb_buffer_pool_size
とinnodb_buffer_pool_instances
を変更- デフォルトだと 1GB 以下の buffer pool につき 1 つの instance を持つという設定
- 最大 8 インスタンスまで
シャットダウン時によく使う page は保持しておきたい innodb_buffer_pool_dump_pct を増やすことでリスタート時のために保持されるデータ量を増やすことができる
-
redo log は sequential IO であるため、パフォーマンスを上げるため、フロントで log buffer が存在する
-
トランザクションの変化はメモリに保持され、buffer が満タンになるか、transaction がコミットされたときに flush される
-
書き込み時のデータフローではまずログバッファーに書き込み処理が走る。その後、redo logs への flush 処理が実行される
-
この buffer size を規定しているのは、
innodb_log_buffer_size
。デフォだと 16MB。トランザクションが多い場合はこの値を上げると良い -
Redo Logs は1つ目のファイルがいっぱいになったら2つ目のファイルを作成、 ファイル数の制限に達した場合は、再度 1 つめのファイルに戻り、上書きして行く
-
Redo logs がいっぱいになったらそれが ターニングポイントになり bufferpool が tablespcaes への flush を行う
-
redo logs ファイルを大きくすることでこの checkpoint を減らすことができる
-
innodb_log_file_size
を大きくすることでリカバリータイムが肥大化する可能性があるが、あまり心配する必要なし。自信をもって大きくして良い -
ログバッファーと同様に BufferPool にも変更は書き込まれる そして変更中のデータは tablespaces ファイルへ flush されるまでは dirty というマークが付与された状態で buffer_pool に保持される
-
InnoDB では Doublewrite buffer を行っているので、crash などが起きた際にも上書き処理が成功したか失敗したかを検知できる
-
buffer pool からの flush が成功したら redo logs では完了というマーキングに変わる
-
クラッシュしてしまうともはや buffer pool は機能しなくなるので、redo logs から読み込まれることになる
-
innodb_io_capacity
はデフォルトでは 200 に設定されているが強力な disk であれば、増やしても良い
innnodb_io_capacity_max
で flush させるのに秒単位でどの程度バックグラウンド処理を行うかに影響を与える -
この2つの option はどれくらい早く dirty page を tablespaces に flush させるかを決める値
- Lock の情報は Buffer pool に保持されている
- トランザクションがコミットされたとしても、undo logs を介してまだインパクトを残していることを忘れては行けない
SHOW ENGINE INNODB STATUS\G
history list length
はトランザクションの問題を示唆する指標となる- commit されると自然に clean up される
以下のクエリでロックの及んでいるカラム数を調べられる
SELECT INDEX_NAME, LOCK_TYPE, COUNT(*) FROM performance_schema.data_locks WHERE OBJECT_SCHEMA = 'world' AND OBJECT_NAME = 'city' GROUP BY INDEX_NAME , LOCK_TYPE;
トランザクションについての詳細をしる
SELECT * FROM innodb_trx WHERE trx_started < now() - interval 1 minute ORDER BY trx_rows_locked DESC\G
ロックについての詳細を知る(各ロックのトランザクションの id の関係性をみる)
SELECT * FROM data_lock_waits\G
- フル テーブル スキャンが行われたテーブルを調べる最も簡単な方法は、
sys.schema_tables_with_full_table_scans
ビューのクエリを行う
select * from schema_tables_with_full_table_scans\G
- 次に有用なのは
statements_with_full_table_scan
インデックスが使われていない statement を表示するノーマライズされたもの
select * from statements_with_full_table_scan\G
- 使われていない index を探す
select * from schema_unused_indexes\G
- 冗長な index を探す
select * from schema_redundant_indexes\G
- 統計情報の精度は、persistent statistics か transient statistics のどちらが使われているかに依存する
innodb_stats_persistent_sample_pages
とinnodb_stats_transient_sample_pages
これらの数値はテーブルごとに設定するのが推奨される ではどれくらいの数値が適当なのか - 規則的な distribution であれば、基本的に低い数値
- 不規則的な distribution であれば、上げたほうが良い
- table サイズが大きければ、より多くの page 数を設定することで統計情報の精度が上がる
- テーブルの 10%の row に変更が起こったときに自動的に
ANALYZE TABLE
が実行されるようになっている - table fragment を取り除くことで index を最適化したい場合は
OPTIMIZW TABLE name;
を実行