热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

mysqlhbase读写性能_HBase高并发原由之MySQL读写流程解析

数据库作为存储系统,所有业务访问数据的操作都会转化为底层数据库系统的IO行为(缓存系统也可以当做是key-value的数据库),本文主要介绍访问MySQL数据库的IO

401faf4fa4d0ed328a71e86e500cefd2.png

数据库作为存储系统,所有业务访问数据的操作都会转化为底层数据库系统的IO行为(缓存系统也可以当做是key-value的数据库),本文主要介绍访问MySQL数据库的IO流程以及IO相关的参数。

一、MySQL的文件

首先简单介绍一下MySQL的数据文件,MySQL 数据库包含如下几种文件类型:

1)数据文件 (datafile)

存放表中的具体数据的文件。

2)数据字典

记录数据库中所有innodb表的信息。

3)重做日志 (redolog)

记录数据库变更记录的文件,用于系统异常crash(掉电)后的恢复操作,可以配置多个(配置这个参数innodb_log_files_in_group)比如 ib_logfile0、 ib_logfile1。

4)回滚日志 (undolog)

也存在于mysql 的ibdata文件,用户记录事务的回滚操作。注在mysql5.6以上版本可以拆开出来,单独文件夹存在。

5)归档日志 (binlog)

事务提交之后,记录到归档日志中。

6)中继日志 (relaylog)

从master获取到slave的中转日志文件,sql_thread则会应用relay log并重放于从机器。

7)其他日志slowlolg, errorlog, querylog

这里慢日志也经常用。可以结合pt-query-digest工具和anemometer一起展示出来。

对于以上文件的IO访问顺序可以分为顺序访问 比如binlog ,redolog ,relay log是顺序读写,datafile,ibdata file是随机读写,这些IO访问的特点决定了在os 配置磁盘信息时候,如何考虑分区 ,比如顺序写可以的log可以放到SAS盘 ,随机读写的数据文件可以放到ssd或者fio高性能的存储。

二、数据访问流程

数据库访问分为两种类型, 一种是读操作,另外一种是写操作。

1)读操作

create table t (

id int not null primary key ,

k1 int not null,

data varchar(50),

key ind_k1(k1)

) engine=innodb default charset=utf8;

以select * from tab where k1=1 ;为例。

5277ef66a9e123b90cd3c9774fc30943.png

读操作的IO流程

1、查看缓存中是否存在id,

2、如果有则从内存中访问,否则要访问磁盘,

3、并将索引数据存入内存,利用索引来访问数据,

4、对于数据也会检查数据是否存在于内存,

5、如果没有则访问磁盘获取数据,读入内存。

6、返回结果给用户。

2)写操作

为了保证数据写入操作的安全性,数据库系统设置了 undo,redo 保护机制,避免因为os或者数据库系统异常导致的数据丢失或者不一致的异常情况发生。

以insert into t values(1,1,’shuiyi’);为例。

cb2ca01d1bccbd635acae397c742e37c.png

写操作的IO流程

f430a4c174dd61fb8e7496499cd0a96a.png

ba022725f544e2e70a6c1ee8a3822a96.png

我们假定数据在内存中,不考虑从磁盘中获取数据的情形,大致的写操作步骤:

1、先写undo log,

2、在内存更新数据,这步操作就在内存中形成了脏页,如果脏页过多,checkpoint机制进行刷新,innodb_max_dirty_pages_pct决定了刷新脏页比例。innodb_io_capacity参数可以动态调整刷新脏页的数量,innodb_lru_scan_depth这个参数决定了刷新每个innodb_buffer_pool的脏页数量。

3、记录变更到redo log,prepare这里会写事务id。innodb_flush_log_at_trx_commit决定了事务的刷盘方式。为0时,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行。该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去.为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。

4、写入binlog这里会写入一个事务id这里有个sync_binlog参数决定多个事务进行一次性提交。

5、redo log第二阶段,这里会进行判断前2步是否成功,成功则默认commit,否则rollback。刷入磁盘操作。这里是先从脏页数据刷入到内存2M大小的doublewrite buffer,然后是一次性从内存的doublewrite buffer刷新到共享表空间的doublewrite buffer,这里产生了一次IO。然后从内存的内存的doublewrite buffer刷新2m数据到磁盘的ibd文件中,这里需要发生128次io。然后校验,如果不一致,就由共享表空间的副本进行修复。这里有个参数innodb_flush_method决定了数据刷新直接刷新到磁盘,绕后os cache。

6、返回给client。

如果有slave

第4步之后经过slave服务线程io_thread写到从库的relay log ,再由sql thread应用relay log到从库中。

关于性能?

写undo redo log ,binlog的过程中都是顺序写,都会很快的完成,随机写操作,inset_buffer功能。

对于非聚集类索引的插入和更新操作(5.5 版本及以上支持Update/Delete/Purge等操作的buffer功能),不是每一次都直接插入到索引页中,而是先插入到内存中。具体做法是:如果该索引页在缓冲池中,直接插入;否则,先将其放入插入缓冲区中,再以一定的频率和索引页合并,就可以将同一个索引页中的多个插入合并到一个IO操作中,改随机写为顺序写,大大提高写性能。

关于数据安全,这是数据库写入的重点?

1,2,3过程失败就是事务失败,因为此时还未写入磁盘,对磁盘中的数据无影响,返回事务失败给client,从库也不会受到影响。 4,5过程失败的时候或者已经将写成功返回给客户,可以根据redo log的记录来进行恢复,如果出现部分写失效请参考《double write》。

MySQL的写redo log的第一个阶段会把所有需要做的操作做完,记录数据变更,第二阶段的工作比较简单 ,只做事务提交确认。如果写入binlog成功,而第二阶段失败,MySQL启动时也会将事务进行重做,最终更新到磁盘中。MySQL 5.5 +的smei sync可以更好的保障主从的事务一致性。

三、文件访问方式

IO 访问的方式分为两种顺序读写和随机读写, 在mysql 的io过程中可以以此来将数据库文件分类

顺序读写:

重做日志ib_logfile*,binlog file。

随机读写:

innodb表数据文件,ibdata文件。

根据系统的访问类型,对硬件做如下分类:

读多SSD+RAID

写多FIO(flashcache)

容量密集fio + flashcache

由于随机io会严重降低系统的性能,在当前的硬件水平下,可以考虑选择奖数据库服务器配置ssd/fusionio。

四、影响IO的参数和策略

影响mysql io的参数有很多个,这里罗列几个重要的参数。

innodb_buffer_pool_size

该参数控制innodb 缓存大小,用于缓存应用访问的数据,推荐配置为系统可用内存的80%。

binlog_cache_size

该参数控制二进制日志缓冲大小,当事务还没有提交时,事务日志存放于cache,当遇到大事务cache不够用的时,mysql会把uncommitted的部分写入临时文件,等到committed的时候才会写入正式的持久化日志文件。

innodb_max_dirty_pages_pct

该参数可以直接控制Dirty Page在BP中所占的比率,当dirty page 达到了该参数的阈值,就会触发MySQL 系统刷新数据到磁盘。

innodb_flush_log_at_trx_commit

该参数确定日志文件何时write、flush。

为0,log buffer将每秒一次地写入log file中,并且log file的flush(刷到磁盘)操作同时进行.该模式下,在事务提交的时候,不会主动触发写入磁盘的操作。

为1,每次事务提交时MySQL都会把log buffer的数据写入log file,并且flush(刷到磁盘)中去.

为2,每次事务提交时MySQL都会把log buffer的数据写入log file.但是flush(刷到磁盘)操作并不会同时进行。该模式下,MySQL会每秒执行一次 flush(刷到磁盘)操作。

注意:

由于进程调度策略问题,这个“每秒执行一次flush(刷到磁盘)操作”并不是保证100%的“每秒”。

sync_binlog

sync_binlog的默认值是0,像操作系统刷其他文件的机制一样,MySQL不会同步到磁盘中去而是依赖操作系统来刷新binary log。

当sync_binlog =N (N>0) ,MySQL 在每写 N次 二进制日志binary log时,会使用fdatasync()函数将它的写二进制日志binary log同步到磁盘中去。

innodb_flush_method

该参数控制日志或数据文件如何write、flush。可选的值为 fsync, o_dsync ,o_direct,littlesync,nosync

fdatasync模式:写数据时,write这一步并不需要真正写到磁盘才算完成(可能写入到操作系统buffer中就会返回完成),真正完成是flush操作,buffer交给操作系统去flush,并且文件的元数据信息也都需要更新到磁盘。

O_DSYNC模式:写日志操作是在write这步完成,而数据文件的写入是在flush这步通过fsync完成。

O_DIRECT模式:数据文件的写入操作是直接从mysql innodb buffer到磁盘的,并不用通过操作系统的缓冲,而真正的完成也是在flush这步,日志还是要经过OS缓冲。

注意:关于mysql 和io相关的参数,并不是一成不变的,需要根据自身业务系统和硬件系统做相应调整,系统上线之前,测试出一个最佳值。

五、小结

数据库的io是一个很复杂和细致的知识层面,涉及数据库层和OS层面的IO写入策略,也和硬件的配置有关,本文主要针对MySQL 层面做分析,可能分析的不够全面,请各位朋友指点。

引用:http://www.ywnds.com/?p=8282



推荐阅读
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 本文主要复习了数据库的一些知识点,包括环境变量设置、表之间的引用关系等。同时介绍了一些常用的数据库命令及其使用方法,如创建数据库、查看已存在的数据库、切换数据库、创建表等操作。通过本文的学习,可以加深对数据库的理解和应用能力。 ... [详细]
  • MySQL数据库锁机制及其应用(数据库锁的概念)
    本文介绍了MySQL数据库锁机制及其应用。数据库锁是计算机协调多个进程或线程并发访问某一资源的机制,在数据库中,数据是一种供许多用户共享的资源,如何保证数据并发访问的一致性和有效性是数据库必须解决的问题。MySQL的锁机制相对简单,不同的存储引擎支持不同的锁机制,主要包括表级锁、行级锁和页面锁。本文详细介绍了MySQL表级锁的锁模式和特点,以及行级锁和页面锁的特点和应用场景。同时还讨论了锁冲突对数据库并发访问性能的影响。 ... [详细]
  • 本文介绍了在PostgreSQL中批量导入数据时的优化方法。包括使用unlogged表、删除重建索引、删除重建外键、禁用触发器、使用COPY方法、批量插入等。同时还提到了一些参数优化的注意事项,如设置effective_cache_size、shared_buffer等,并强调了在导入大量数据后使用analyze命令重新收集统计信息的重要性。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • 在Oracle11g以前版本中的的DataGuard物理备用数据库,可以以只读的方式打开数据库,但此时MediaRecovery利用日志进行数据同步的过 ... [详细]
  • MySQL语句大全:创建、授权、查询、修改等【MySQL】的使用方法详解
    本文详细介绍了MySQL语句的使用方法,包括创建用户、授权、查询、修改等操作。通过连接MySQL数据库,可以使用命令创建用户,并指定该用户在哪个主机上可以登录。同时,还可以设置用户的登录密码。通过本文,您可以全面了解MySQL语句的使用方法。 ... [详细]
  • 本文介绍了使用哈夫曼树实现文件压缩和解压的方法。首先对数据结构课程设计中的代码进行了分析,包括使用时间调用、常量定义和统计文件中各个字符时相关的结构体。然后讨论了哈夫曼树的实现原理和算法。最后介绍了文件压缩和解压的具体步骤,包括字符统计、构建哈夫曼树、生成编码表、编码和解码过程。通过实例演示了文件压缩和解压的效果。本文的内容对于理解哈夫曼树的实现原理和应用具有一定的参考价值。 ... [详细]
  • MySQL中的MVVC多版本并发控制机制的应用及实现
    本文介绍了MySQL中MVCC的应用及实现机制。MVCC是一种提高并发性能的技术,通过对事务内读取的内存进行处理,避免写操作堵塞读操作的并发问题。与其他数据库系统的MVCC实现机制不尽相同,MySQL的MVCC是在undolog中实现的。通过undolog可以找回数据的历史版本,提供给用户读取或在回滚时覆盖数据页上的数据。MySQL的大多数事务型存储引擎都实现了MVCC,但各自的实现机制有所不同。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • MySQL插入数据的四种方式及安全性分析
    本文介绍了MySQL插入数据的四种方式:插入完整的行、插入行的一部分、插入多行和插入查询结果,并对其安全性进行了分析。在插入行时,应注意字段的定义和赋值,以提高安全性。同时指出了使用insert语句的不安全性,应尽量避免使用。建议在表中定义相关字段,并根据定义的字段赋予相应的值,以增加插入操作的安全性。 ... [详细]
author-avatar
jia19891213
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有