高性能mysql
mysql主要分为三层,最上层 做些客户端连接和安全认证的工作,中间一层是核心服务层有线程处理,缓存,解析器和优化器,最下层是存储引擎的实现。mysql支持热备份,如果采用事物引擎innoDb会开启事务日志,把内存的的日志以追加的形式写到磁盘中(固定区域,不用移动磁盘指针,速度很快),然后有后台线程慢慢把内存中修改的数据写到磁盘,所以这种情况下修改数据写入了两次磁盘,作用是当系统崩溃后重启可以根据事物日志恢复。
在用到事务引擎的innoDb时的隔离级别时,总是很难分清读已提交和可重复读的区别,而读未提交(出现幻读)和序列化读(读就加锁,也就是单事务操作)很好区分,下面的图分别是可重复读和读已提交测试的过程
可重复读:
读已提交:
实际读起来发现,左边窗口永远能读到右边窗口更改的数据。而读已提交 这种会出现不可重复读,A事务也就是在b事务提交前后读取数据不一样,b事务对数据做了更改;而可重复读就是A事务在b事务提交前后读取的数据是一致的。但为什么实际效果是这样的呢?后来看了mysql的mvcc(多版本控制)才知道原因
mvcc:
数据库每一行有两个隐藏字段,分别是创建时间和过期时间,这两个字段存的值是系统的版本号。当一个事务开启时系统版本号会默认递增,并且把这个版本号当作事务的版本号
当执行的语句是select语句时
会查询到创建时间的版本号小于或等于事务版本号并且过期时间为null或者过期时间大于事务版本号的行记录,所以只会查询到事务版本号之前或者自己插入/修改的记录
当执行insert语句时
会把事务的版本号设入插入记录的创建时间中
当执行update语句
会插入一条记录并且把事务版本号设入记录的创建时间中,还有把原来那条记录的删除时间设入事务的版本号
当执行删除语句时
会把记录的过期时间设入事务的版本号
这种模式解决mysql的并发性能,并不仅仅是行级锁的这种简单实现了。那么上图怎么解释呢?因为实验模拟的不对,正确的实现模拟应该是,A开启事务,B随后开启事务,B事务改变数据,A是看不到的,因为B事务的版本号是大于A事务的版本号的。而上面的右边执行完,再左边执行,这就相当左边的版本号大于右边,所以左边肯定能看到右边的数据
mysql的测试
整体测试:
把一个服务当作一个整体来测,这时候一般都是测请求的完成时间,推荐用jmeter
单个组件测试:
单个组件测试,这是你可以测大文件读写I/O(测试数据的写,文件大小要大于内存,防止被全部缓存), cpu(测试处理速度),OLTP (数据库大数据量多线程访问),这三者要重点掌握,明天上图,用的是sysbench工具
这个工具还可以用来内存,互斥锁,线程,顺序写等操作
备注:简单测试可以通过数据库函数直接测试