大概的优化思路分为以下几个内容
PS: 优化是有风险的,如果你要优化就要变更。
这个地方就略过了就是一些加大硬件配置的需求.
[root@mysql-master ~]# top
top - 15:05:11 up 35 days, 5:54, 2 users, load average: 0.00, 0.01, 0.05
Tasks: 225 total, 2 running, 223 sleeping, 0 stopped, 0 zombie
%Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu4 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu5 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu6 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
%Cpu7 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 24522416 total, 14931524 free, 3675344 used, 5915548 buff/cache
KiB Swap: 12386300 total, 12386300 free, 0 used. 20450988 avail Mem
通过 top -Hp 10380
指定占用高的进程,可以看到具体是那些线程占用过高
假设 1893
线程占用过高,可以从数据库中查看performance_schema
库中具体的信息
定位操作系统线程->从系统线程中定位数据库线程
*************************** 38. row ***************************
THREAD_ID: 128014
NAME: thread/sql/one_connection
TYPE: FOREGROUND
PROCESSLIST_ID: 127988
PROCESSLIST_USER: ooooo
PROCESSLIST_HOST: 192.168.0.1
PROCESSLIST_DB: test
PROCESSLIST_COMMAND: Sleep
PROCESSLIST_TIME: 104
PROCESSLIST_STATE: NULL
PROCESSLIST_INFO: **
PARENT_THREAD_ID: NULL
ROLE: NULL
INSTRUMENTED: YES
HISTORY: YES
CONNECTION_TYPE: SSL/TLS
THREAD_OS_ID: 16165
*************************** 39. row ***************************
MySQL
中的sys
库中存在记录IO
的表如果存在IO问题: 可以选择用内存换取时间的方法..
mysql> use sys
mysql> show tables;
| x$io_by_thread_by_latency |
| x$io_global_by_file_by_bytes |
| x$io_global_by_file_by_latency |
| x$io_global_by_wait_by_bytes |
| x$io_global_by_wait_by_latency |
在这里…笔者非常推荐MySQL8.0x!!! 同样的机器,8.0比5.7快2.5倍左右吧
一切根据自己或者项目需要自由设置吧!
max_connections = 1000
max_connect_errors = 999999
wait_timeout = 600
interactive_wait_timeout = 3600
net_read_timeout = 120
new_write_timeout = 120
max_allowed_packet = 500M
一切根据自己或者项目需要自由设置吧!
sort_buffer_size = 8M
sql_safe_updates = 1
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /data/mysql/mysql-slow.log
log_queries_not_using_indexes = 10
read_buffer_size = 2M
read_rnd_buffer_size = 8M
sort_buffer_size = 8M
join_buffer_size = 8M
key_buffer_size = 16M
max_binlog_size = 500M
max_execution_time = 28800
log_timestamps = SYSTEM
init_connect = "set names utf8mb4"
binlog_format = ROW
event_scheduler = OFF
lock_wait_timeout =
sync_binlog = 1
一切根据自己或者项目需要自由设置吧!
transaction-isolation = "READ-COMMITIED"
innodb_data_home_dir = /xxx
innodb_log_group_home_dir = /xxx
innodb_log_file_size = 2048M
innodb_log_files_in_group = 3
innodb_flush_log_at_trx_commit = 2
innodb_flush_method = O_DIRECT
innodb_io_capacity = 1000
innodb_io_capacity_max = 4000
innodb_buffer_pool_size = 64G
innodb_buffer_pool_instances = 4
innodb_log_buffer_size = 64M
innodb_max_dirty_pages_pct = 85
加锁方法:FTWRL,flush tables with read lock. 解锁方法:unlock tables; 可能出现的场景
属于类型: MDL(matedatalock)层面锁
影响情况: 加锁的期间,阻塞所有事务的写入,阻塞所有事务的commit,时间受到lock_wait_timeout=315336000
MySQL [(none)]> USE performance_schema
MySQL [performance_schema]>
# 5.6需要手动开启
MySQL [performance_schema]> UPDATE setup_instruments SET ENABLED = "YES",TIMED = "YES" WHERE NAME='wait/lock/metadata/sql/mdl';
# 查看是否有阻塞问题
MySQL [performance_schema]> SELECT * FROM metadata_locks;
mysql> SELECT OBJECT_SCHEMA,OBJECT_NAME,LOCK_TYPE,LOCK_DURATION,LOCK_STATUS,OWNER_THREAD_ID,OWNER_EVENT_ID FROM performance_schema.metadata_locks;
mysql> SHOW proceslist\G;
mysql> SELECT * FORM sys.schema_table_lock_waits;
5.7版本的Xbackup/mysqldump备份数据库出现锁表状态,所有的查询不能正常进行.
SELECT *,SLEEP(100) FORM `user` WHERE username = 'test1' for update;
flush tables with read lock;
SELECT * FROM icours.user where username = 'test' for update
lock table t1 read;
所有会话只读,属于MDL锁。lock table write;
当前会话可以可以RW,属于MDL锁. SELECT FOR UPDATE;
SELECT FOR SHARE
unlock tables
;
[mysqld]
performance-schema-instrument = 'wait/lock/metadata/sql/mdl=ON'
SELECT * FROM performance_schema.metadata_locks;
SELECT * FROM performance_schema.threads;
lock_wait_timeout
mysql> select @@lock_wait_timeout;
+---------------------+
| @@lock_wait_timeout |
+---------------------+
| 31536000 |
+---------------------+
1 row in set (0.00 sec)
[mysqld]
performance-schema-instrument = 'wait/lock/metadata/sql/mdl=ON'
SELECT * FROM performance_schema.metadata_locks;
// 找到阻塞的Id
OWNER_THREAD_ID = 12
mysql> SELECT * FROM threads where thread_id = '12'\G;
kill 12;
innodb_autoinc_lock_mod = 0 | 1 | 2
MySQL [(none)]> SHOW STATUS LIKE 'innodb_row_lock';
MySQL [information_schema]> SELECT * FROM information_schema.innodb_trx;
MySQL [information_schema]> SELECT * FORM sys.schema_table_lock_waits;
MySQL [information_schema]> SELECT * FROM performance_schema.threads;
MySQL [information_schema]> SELECT * FROM performance_schema.events_statements_current;
MySQL [information_schema]>
// 假设 k1是辅助索引
update t1 set num=num+10 where k1<100;
// 改为
select id from t1 where k1<100;
update t1 set num=num+10 where id in (20,30,50)
dead lock 多个并发事务之间发生交叉依赖的时候,会出现死锁.
SHOW ENGINE innodb STATUS\G;
innodb_print——all_deadlocks =1 // 开启记录死锁日志