进行MySQL数据库性能优化和维护时,首先需要对MySQL数据库定一个整体的基调,对mysql数据库有一个整体的认识,然后在此基础上就可以比较方便地开展后续工作。

为数据库定个基调可以按照下面的思路依次进行:

一、掌握应用的特点

一般来说,DBA分为开发DBA和运维DBA两种。开发DBA会涉及到业务需求,逻辑模型涉及,物理模型设计,sql代码编写等内容,或者说涉及“外模式-模式-内模式”等各个方面,都业务运行逻辑多少都会有所了解。

而运维DBA一般对业务了解比较少,但从很多实际情况来看,尤其是处理一些优化和复制故障的问题,DBA不了解业务就会受到很多限制。所以DBA掌握数据库技术,要对业务和业务逻辑也熟悉,而且业务优先与技术,只有了解业务逻辑,才能将数据库运行到一个最好的状态。

二、感性的认识

数据库运行的业务不同,参数配置和运行特点也不相同。大体上说,数据库主要用于客户端进行DML操作,select用于查询数据,insert/update/delete用于插入/修改/删除数据,根据两类操作的比重不同,数据库可以分为两类:

OLTP型:insert/update/delete 操作多于select

OLAP型:select操作多于insert/update/delete

OLTP是事务型,是增删改比较多,事务小但数量多;OLAP是分析型的,查询比较多,查询数量少但运行时间通常较长。

对于分析性能问题时,对于把握数据库的主要操作进行归类比较重要,这样可以面对整个业务模型进行归类,化整为零,同时这点也要与上面的业务系统结合,只有了解和熟悉业务状态,才可以在数据库层面运维更好;

总之,感性认识就是指一个数据库是事务比较多,还是查询比较多。

三、使用 show status 命令查看参数值

通过对事务和查询的把握,可以对数据库进行一个整体的感性认识,接下来,还可以通过 show status 命令进行一些主要参数状态的检查,通过实际的数据确认数据库的各种状态。

1.了解各种SQL的执行频率

show global status like 'com_select'; 执行select 操作的次数,一次查询只累加1;

show global status like'com_insert'; 执行insert操作的次数,对于批量插入的insert操作,只累加一次;

show global status like'com_update'; 执行update操作的次数;

show global status like'com_delete'; 执行delete操作的次数;

其他类似参数有: com_stmt_prepare, com_stmt_fetch,...



通过实际计数器查询出数据,从理性分析出执行查询操作与DML执行次数进行比较;

用技术手段检验由业务了解而形成的感性认识;

对于业务基调的认识,先从业务认识到整体上判断,然后再通过具体数据库参数进行确认,比较查询操作的统计数据和DML操作的统计数据的大小;

2.从整体入手了解数据库服务器的状态

show [full] processlist

通过该命令,可以查看目前有哪些进程正在运行。

3.了解事务主动提交和回滚的情况

show global status like 'com_commit'; 提交了的事务计数,主动执行commit命令

show global status like 'com_rollback'; 回滚了的事务计数,主动执行rollback命令

注意:自动提交/回滚的事务不计算在内

通过对事务的提交和回滚的操作比较,可以大致了解事务的发生状况。

4.根据计数器了解读写情况

show status like 'innodb_rows_read'; 查询返回的行数,不仅是select操作,delete和update也会触发对元组的读操作

show status like 'innodb_rows_inserted'; 执行insert操作成功插入的行数

show status like 'innodb_rows_updated'; 执行update操作成功更新的行数

show status like 'innodb_rows_deleted'; 执行delete操作成功删除的行数

通过对行的计数器进行统计,可以了解数据库的读写操作;元组如果发生删除操作,删除操作发生后计数,read也会增加计数。

5.区分“索引读”还是“随机读”

这种情况,不从缓存区的角度出发,从单表扫描数据的方式的角度出发。

mysql> show global status like'handler_read%';

+-----------------------+---------------+

| Variable_name | Value |

+-----------------------+---------------+

| Handler_read_first |70372176 |

| Handler_read_key |878000134111 |

| Handler_read_last |1628850508 |

| Handler_read_next |7153827933028 |

| Handler_read_prev |1253473280990 |

| Handler_read_rnd |448021869416 |

| Handler_read_rnd_next | 1374610044012 |

+-----------------------+---------------+

7 rows in set (0.00 sec)

该查询结果中的几个参数含义如下:

Handler_read_first此选项表明SQL是在做一个全索引扫描,注意是全部,而不是部分,所以说如果存在WHERE语句,这个选项是不会变的。如果这个选项的数值很大,既是好事也是坏事。说它好是因为毕竟查询是在索引里完成的,而不是数据文件里,说它坏是因为大数据量时,简便是索引文件,做一次完整的扫描也是很费时的。

Handler_read_key此选项数值如果很高,那么恭喜你,你的系统高效的使用了索引,一切运转良好。

Handler_read_next此选项表明在进行索引扫描时,按照索引从数据文件里取数据的次数。

Handler_read_prev此选项表明在进行索引扫描时,按照索引倒序从数据文件里取数据的次数,一般就是ORDER BY ... DESC

Handler_read_rnd简单的说,就是查询直接操作了数据文件,很多时候表现为没有使用索引或者文件排序。

Handler_read_rnd_next此选项表明在进行数据文件扫描时,从数据文件里取数据的次数。

数据库的随机读写和顺序读写,也可以通过计数器进行判断。这样层层深入后,就可以更加深入的了解数据库的执行状态。

6.其他参数值确认

定期检查判断锁:

show status like 'Table%';

显示慢查询的次数:

show status like 'Slow%';

显示服务器工作时间:

show status like 'Up%';

查询数据库的各方面运行状态,类似于给系统做了一个体检;然后在通过其他方式进行更深入的了解。这个体检结果是对mysql数据库调优的基础。

注意:上述命令在查看mysql运行状态时,与查询variables一样,都是既有查看当前会话的 show status like'';命令,也有查看所有会话的 show global status like '';命令,有的时候两种方式查询出的结果是一致的。但大部分时候,两者的查询结果是不同的,为了确认mysql运行整体状态,一般建议使用show global status like''; 命令查询结果。

示例:

在一个生产系统中,按照上面的方法进行一个数据库的体检结果为:

1.SQL执行频率

mysql>show global status like 'com_select';

+---------------+-------------+

|Variable_name | Value |

+---------------+-------------+

|Com_select | 16119391072 |

+---------------+-------------+

1row in set (0.00 sec)

mysql>show global status like 'com_insert';

+---------------+-----------+

|Variable_name | Value |

+---------------+-----------+

|Com_insert | 195615221 |

+---------------+-----------+

1row in set (0.00 sec)

mysql> show global status like 'com_update';

+---------------+-------------+

| Variable_name | Value |

+---------------+-------------+

| Com_update | 10947755629 |

+---------------+-------------+

1 row in set (0.00 sec)



mysql>show global status like 'com_delete';

+---------------+---------+

|Variable_name | Value |

+---------------+---------+

|Com_delete | 1311639 |

+---------------+---------+

1row in set (0.00 sec)

由这几个参数值 可以得到: select /(insert+update+delete) =16119391072/(195615221+10947755629+1311639) = 16119391072/11144682489=1.45

也即整个数据库的select操作与事务操作的比例大致为3:2,可以归类为OLAP系统。

2.服务器整体状态

show [full] processlist

查询当前有186个会话。

3.事务主动提交和回滚的状态

mysql> show global status like 'com_commit';

+---------------+------------+

| Variable_name | Value |

+---------------+------------+

| Com_commit | 4756582998 |

+---------------+------------+

1 row in set (0.00 sec)

mysql>

mysql> show global status like 'com_rollback';

+---------------+------------+

| Variable_name | Value |

+---------------+------------+

| Com_rollback | 3544847441 |

+---------------+------------+

1 row in set (0.00 sec)

由上面两个值,可以得知该数据库中的事务提交、回滚比为4756582998/3544847441=1.34 ,约为7:5.

4.以行为单位的读写情况

mysql> show status like 'innodb_rows_read';

+------------------+---------------+

| Variable_name | Value |

+------------------+---------------+

| Innodb_rows_read | 9090316959495 |

+------------------+---------------+

1 row in set (0.00 sec)

mysql> show status like 'innodb_rows_inserted';

+----------------------+-----------+

| Variable_name | Value |

+----------------------+-----------+

| Innodb_rows_inserted | 453143758 |

+----------------------+-----------+

1 row in set (0.00 sec)

mysql> show status like 'innodb_rows_updated';

+---------------------+-------------+

| Variable_name | Value |

+---------------------+-------------+

| Innodb_rows_updated | 10870583056 |

+---------------------+-------------+

1 row in set (0.00 sec)

mysql> show status like 'innodb_rows_deleted';

+---------------------+-----------+

| Variable_name | Value |

+---------------------+-----------+

| Innodb_rows_deleted | 114969563 |

+---------------------+-----------+

1 row in set (0.00 sec)

5.区分“索引读”还是“随机读”:

mysql> show global status like'handler_read%';

+-----------------------+---------------+

| Variable_name | Value |

+-----------------------+---------------+

| Handler_read_first | 70364190 |

| Handler_read_key |877946762331 |

| Handler_read_last |1628785558 |

| Handler_read_next |7152670258238 |

| Handler_read_prev |1253470447566 |

| Handler_read_rnd |448009044979 |

| Handler_read_rnd_next | 1374495674830 |

+-----------------------+---------------+

7 rows in set (0.00 sec)

6.其他参数的确认

定期检查判断锁:

mysql> show status like 'Table%';

+-----------------------+-------------+

| Variable_name | Value |

+-----------------------+-------------+

| Table_locks_immediate | 83087055922 |

| Table_locks_waited | 395205 |

+-----------------------+-------------+

2 rows in set (0.00 sec)

显示慢查询的次数:

mysql> show global status like 'Slow%';

+---------------------+----------+

| Variable_name | Value |

+---------------------+----------+

| Slow_launch_threads | 0 |

| Slow_queries | 39341149 |

+---------------------+----------+

2 rows in set (0.00 sec)

显示服务器工作时间:

mysql> show global status like 'Up%';

+---------------------------+----------+

| Variable_name | Value |

+---------------------------+----------+

| Uptime | 20514193 |

| Uptime_since_flush_status | 20514193 |

+---------------------------+----------+

2 rows in set (0.00 sec)

四、系统监控

上面是通过了解业务,对数据库类型的判断建立感性认识,在通过 show status 参数值获得mysql实际运行数据。但在实际运行过程中,对运行状态和性能的监控,还是需要靠监控系统来实现。

mysql官方推荐的方式是 perfmance-schema 性能视图的方式,该方式可以简写为PFS。

PFS可以在配置文件中添加,或者mysql启动命令中加入启动PFS的参数。

PFS的体系结构有五个部分:

setup_actors 定义监控什么样的用户;

setup_consumers 定义监控什么事件;

setup_instruments 定义监控什么仪表;

setup_objects 定义监控5类数据库对象;

setup_timers 定义监控那些事件计时器;

PFS的使用模式有全系统监控和定制监控两种方式:全系统监控的监控项全部开启,便于分析不确定的问题,会影响系统系能;

定制监控的监控项部分开启,便于分析确定的问题,影响系统性能相对较少。

开启了PFS后,如果遇到系统卡住的情况,就可以在PFS中依次查询相关表信息,来确认进程状态,进而解决问题。

对于mysql数据库性能优化,需要掌握数据原理,MySQL内部实现,PFS细节和内容三个方面的基础,能够熟练掌握和运用后,就可以晋级为MySQL数据库调优专家。

更多相关文章

  1. Wordpress数据库类- MySQL类型。
  2. c#操作mysql事务是不是要在一个数据库连接内完成?
  3. 如何在MySQL数据库和JPA中使用Spring Boot?
  4. 无法连接远程MySQL数据库的解决方案
  5. MySql数据库安装
  6. MySQL 示例数据库sakila
  7. 在H2数据库中插入时间——函数“PARSEDATETIME”未找到
  8. MySQL第一课(基础、库操作、表操作)
  9. 使用mysql和PHP从本地主机连接到远程数据库

随机推荐

  1. 解决EditText不显示光标的三种方法(总结)
  2. Android深入探究-- 实现即时拍照并上传
  3. The logbook of Android(安卓)bug in dai
  4. android复制数据库到SD卡(网上搜集,未经验
  5. Android中通过Intent 调用图片、视频、音
  6. [Android]PhoneGap源码分析——CallbackS
  7. Android(安卓)异步获取网络图片并处理图
  8. Android四大基本组件介绍与生命周期
  9. android 横屏重启的解决方案
  10. Android 强制设置横屏或竖屏 设置全屏