mysql临时提升性能的操作

应急处理短接风暴:

方法一 kill 相关sleep进程

1
SELECT concat('kill ',id,';') FROM information_schema.PROCESSLIST where id not in (select trx_mysql_thread_id from information_schema.innodb_trx) and Command='Sleep';	

注:不能直接kill sleep的进程。当事务未提交时此时command的状态也是sleep,如果kill事务将回滚。将影响到业务。做此操作一定要跟开发确认

方法二:减少连接过程消耗

跳过权限验证的方法:重启数据库并加上–skip-grant-tables 参数启动。这样的话mysql将跳过所有的验证阶段。但是此方法无异于饮鸩止渴,对外开放的数据库此方案直接pass。

应急处理慢查询

导致慢查询第一种可能:索引没有设计好

1.备库上执行set sql_log_bin=off,不写binlog日志,然后执行新建索引。
2.执行主备切换;
3.再在原主库上 set sql_log_bin=off,执行新建索引

语句没写好

比如:语句错误的写成了:select * from emp where empno+1=7789;此时可以增加一个改写规则。

1
2
3
4
5
6
7
8
$> mysql -u root -p < install_rewriter.sql
Enter password: (enter root password here)
mysql> SHOW GLOBAL VARIABLES LIKE 'rewriter_enabled';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| rewriter_enabled | ON |
+------------------+-------+
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
官方文档:
Adding Rewrite Rules
To add rules for the Rewriter plugin, add rows to the rewrite_rules table, then invoke the flush_rewrite_rules() stored procedure to load the rules from the table into the plugin. The following example creates a simple rule to match statements that select a single literal value:

INSERT INTO query_rewrite.rewrite_rules (pattern, replacement)
VALUES('SELECT ?', 'SELECT ? + 1');
The resulting table contents look like this:

mysql> SELECT * FROM query_rewrite.rewrite_rules\G
*************************** 1. row ***************************
id: 1
pattern: SELECT ?
pattern_database: NULL
replacement: SELECT ? + 1
enabled: YES
message: NULL
pattern_digest: NULL
normalized_pattern: NULL
The rule specifies a pattern template indicating which SELECT statements to match, and a replacement template indicating how to rewrite matching statements. However, adding the rule to the rewrite_rules table is not sufficient to cause the Rewriter plugin to use the rule. You must invoke flush_rewrite_rules() to load the table contents into the plugin in-memory cache:

"root@localhost:mysql.sock [aa]>insert into query_rewrite.rewrite_rules(pattern, replacement, pattern_database) values ("select * from emp where empno+1=7789","select * from emp where empno=7788", "test");

"root@localhost:mysql.sock [aa]>call query_rewrite.flush_rewrite_rules(); #加载一下

mysql数据库选错了索引

应急方案就是使用force index。
1.上线前将慢日志打开,使用long_query_time设置成0,每个语句都记录在慢日志中。
2.测试表插入模拟线上的数据,做一遍回归测试。
3.观察慢查询日志里每类语句的输出,特别留意rows_examined 字段是否与预期一致。( slowlog 里面用 rows_sent 和 row_examined 做个简单的除法,比如 row_examined/rows_sent > 1000 的都可以拿出来作为“嫌疑人”处理。这类问题一般在索引方面做好优化就能解决。PS:1000 只是个经验值,具体要根据实际业务情况来定。)


不要吝啬花费在上线前的测试。因为也许就是因为你多测试了一点就能避免上线后的故障问题。