POLARDB · 最佳实践 · POLARDB不得不知道的秘密(二)
前言
POLARDB For MySQL(下文简称POLARDB)目前是阿里云数据库团队主推的关系型数据库。线上已经有很多企业用户在使用并且稳定运行了很久。当然,由于POLARDB是为云上环境专门打造的数据库,与原生的官方MySQL相比,有一些需要注意的事项。前几个月的月报介绍了一些,详见这篇[月报](http://mysql.taobao.org/monthly/2018/10/01/),结合笔者最近几个月一线的开发和运维经验,总结出以下几点新的注意事项并给出了建议。
空表/空实例空间问题
由于POLARDB除了实例费用外,用户还需要支付实例占用的存储费用,并且是按照使用量来收费,即当前使用多少磁盘就付多少钱。这一点与RDS MySQL兼容版的预付费模式不太一样,所以很多用户对磁盘使用量非常敏感,除了上篇月报中提到的空间问题外,还有以下两类问题:空实例空间问题和空表空间问题。
空实例空间问题。常常有用户会问,我刚买了一个POLARDB实例,但是才刚创建完,空间就占用了将近3GB(实际是2.8G左右),这是啥东西?我的磁盘被什么东西占用了?这里解释一下一个空实例大概有哪些文件以及他们占用的磁盘大小。
* 系统表ibdata1文件。可以查看系统变量`innodb_data_file_path`,ibdata默认大小就是200M,即在初始化后,ibdata就占用了200M空间,后续会按需自动扩展。
* MySQL系统库。目前权限信息,表的元信息等都放在MySQL库下,由于空表的空间占用问题(下一小节介绍),将近60个文件,占了230M左右的空间。
* Redolog文件。默认有两个,每个1G(Redolog也是预分配空间),其中一个是当前正在用的日志文件,另外一个是为了提高性能而提前分配的redolog,主要是为了减少Redolog切换时候的性能抖动。
* Undo文件。默认有8个,每个10M。Undo空间可以放在ibdata里面,也可以挪出来(ibdata里面只留一个),POLARDB默认是把undo空间挪出来以独立文件的形式存在,主要是为了方便后续清理。
* Performance_schema表空间。虽然目前POLARDB 5.6兼容版本,不太建议使用Performance_schema,但是我们还是在编译的时候把相关的功能给加上了,这就导致在初始化时候就会把Performance_schema相关的表空间给初始化好,占用了一部分空间,由于空表的空间占用问题(下一小节介绍),50多个文件,占了210M左右的空间。
* auto.cnf文件,存放server uuid。由于空表的空间占用问题(下一小节介绍),占用4M。
* ib_checkpoint文件,存放checkpoint信息。因为Redolog是类似binlog顺序递增的,所以第一个ib_logfile可能被删掉,所以checkpoint信息不能放在那里。由于空表的空间占用问题(下一小节介绍),占用4M。
* innodb_repl.info,存放物理复制相关的信息。主要是POLARDB数据库内部使用,记录复制位点,切换信息等。由于空表的空间占用问题(下一小节介绍),占用4M。
综上所述,空实例的主要空间是被Redolog给占用了,当然这个也是为了性能考虑。每个日志文件大小1G,能在大多数场景下保证实例正常运行。随着DML的执行,Redolog会被使用,使用完后会上传OSS,以便恢复到时间点任务使用。
空表空间问题。这个问题也常常被用户提起,我创建了很多表,但是数据还没导入,为啥空间增长那么快,差不多一千张空表就占用了40G的空间。这个问题的主要原因是POLARDB底层使用了自研的文件系统PolarFS,为了提高性能,默认的文件块被设置为4M(Ext4文件系统这个值为4K),换句话说,由于一个文件至少占用一个块,所以文件大小最小为4M,而在InnoDB上,一张普通的表默认有两个文件,一个是FRM文件,一个是IBD文件,所以只要一张表成功创建,就会占用8M的空间。当然,这些空间可以理解为提前分配预留的空间,当后续数据被写入的时候,首先先使用这些预留的空间,只有被用完后,才会再分配空间。这个行为对大多数用户来说影响不大,但对某些需要提前创建大量表但是数据量不大的用户来说,影响比较大,会导致用户存储成本较高。不过幸运的是,针对这点,我们的文件系统已经做了相应的优化,目前在内部测试阶段,达到预定的稳定性要求好,我们会尽快发布到线上,目标是,在保证高性能和稳定性的情况下,尽可能的减少磁盘空间使用量。
复制延迟问题
主备数据库的复制延迟是一个老生常谈的问题,在传统的主备架构下,只要主要压力稍微大一点或者做了一个DDL,备库有很大概率的发生延迟。发生延迟后,不仅会影响应用从备库读取数据的正确性,也影响主备切换。由于POLARDB在架构上的优势(只有一份数据),因此大部分用户可能会误认为在POLARDB上理论上不应该发生延迟。因为主备都读取一份数据,当然都应该看到一致的数据啦。但是实际上,复制延迟也还是有的,因为虽然磁盘上的状态一致了,但是内存上的状态不一定一致。在POLARDB上,主库和只读库通过物理复制来同步内存中的状态,由于同步的数据比较少,因此发生复制延迟的概率相比传统的MySQL复制还是小很多的。接下来简单介绍一下复制的过程:
Primary节点会定期告诉Replica节点,可安全读取的日志位点上限,Replica在这个周期内,可以安全读取到这个位点以下的日志,如果超过这个位点,可能会读到Primary节点正在写的日志。Replica节点定期反馈应用日志的位点,表示自己应用到的日志位点,小于这个位点的一定已经应用完,大于这个的可能还没应用或者正在应用。Primary节点当前写到的日志位点和Replica节点应用到的位点之差即为复制延迟,如果复制延迟很大,就会导致Replica跟不上Primary。
另外,在POLARDB上,所有主库上执行完的DDL都要等所有Replica应用完相应日志后才能返回成功。换句话说,如果Replica有很大的复制延迟,可能会导致主库执行DDL不成功。这一点可以详见上一篇月报中的“DDL与大事务”小节。
由此可看,我们要尽可能的减小复制延迟。物理复制有两个阶段,一个是日志解析的阶段,另外一个是日志应用的阶段。任何一个阶段慢了,都可能导致复制延迟。日志解析,目前是单线程解析,在我们测试情况下,只有当写入量超过每秒20W(最大规格)的情况下,解析线程才会成为瓶颈。日志应用阶段,由于应用比较慢,目前是多线程应用,不过在POLARDB中,我们只需要应用在内存中的数据页即可,换句话说,如果日志涉及的数据页不在内存中,我们就不需要应用这些日志(目前的方案是把这些日志存在内存中),直到这些数据页被读入内存,我们在IO线程中把这些拉下的日志都应用掉。
用户可以在只读节点上查询`Innodb_replication_delay`这个status变量来获取当前复制延迟。如果复制延迟比较大并且有不断增大的趋势,可以调大参数`loose_innodb_slave_recv_hash_cells_max`和`loose_innodb_slave_recv_hash_cells_min`来减少延迟。这个参数的主要作用就是增加日志hash桶的数量,从而减少日志查找时候的开销。另外,我们的Proxy支持Session一致读,即同一个session内的读和写保证是逻辑相关的,在写之后立即读,一定会读到最新的数据(只有由于读写分离,会把读请求发到有延迟的只读节点,从而导致读取到历史版本的数据)。
内存问题
有部分用户发现,相比RDS MySQL兼容版,POLARDB的内存使用量会更多,这里需要说明一下,这里的主要原因是我们在很多地方使用了以空间换时间的方法,所以内存使用量上会有一定的上升。如果用户发现内存占用过多,可以从以下几个方面诊断:
* 调小`table_open_cache`,同时使用`flush tables`命令关闭所有表空间。这招对打开表数量很多且用户连接很多的用户来说,效果比较明显。
* 关闭自适应哈希。`innodb_adaptive_hash_index`,这个功能可能会占用很多的内存,但是在现在的SSD磁盘下,性能提升有限。
* 适当的调小buffer pool。这点比较适用于连接数多,同时又很多复杂查询的用户。不过目前调整Buffer pool需要联系售后。
大部分用户的实例,在内存上涨到一定数量后,会停止上涨,这种情况下,即使内存占比比较高,也不用担心,因为我们是尽可能的使用内存,把内存尽可能的都用起来,缓存数据,提高效率。但是如果发现实例内存不断上涨,然后直到OOM,这种情况,请立刻联系我们,我们会帮您在后台开启一个内存监控工具(依赖Jemalloc profiling工具,但是需要重启数据库),可以用来发现这些内存去哪儿了,到底是您使用的问题,还是内存泄露问题,如果是我们的问题,我们会尽快解决并给与一定的补偿,如果是您使用的问题,我们也会给您指出,给出优化的建议等。
在后续的POLARDB版本上,我们会增加更多的内存监控功能,方便用户自行进行排查。
IOPS问题
目前POLARDB的每种规格的实例,都有IOPS限制。同时,RDS MySQL的实例也有IOPS限制。往往有很多用户把这个两个IOPS做比较,其实意义不大。
在RDS中,这个IOPS是指数据文件(后台刷脏线程触发)的写盘次数,日志文件每秒的写盘次数(即主要是Redolog和Binlog加起来的写盘次数限制)是不统计在里面的。但是在POLARDB中,这个IOPS限制不但包括了日志文件的写盘次数限制,也包括了数据文件的写盘限制,即两者加起来每秒写盘的次数不能超过这个值。数据和日志一起限制,一起隔离,这样更加合理,也减少了因为磁盘压力而产生的性能抖动。
因此,我们在设置同一类型的规格IOPS参数时,POLARDB上的IOPS一般都比RDS上大好几倍。多出来的IOPS主要是给日志文件刷盘预留的。
目前临时表的磁盘还是普通的NVME本地磁盘,没有放在自研的磁盘上,因此临时表的IOPS暂时不计入总的IOPS,而RDS上这一部分是放在数据盘上,所以这部分IO会记录到IOPS限制上。同时,我们在MySQL内核代码中,也有部分限制,主要是为了防止某些用户临时表使用过多从而影响了其他用户。
错误日志,审计日志,慢日志的写盘操作同样在本地盘,没有计入IOPS限制。
另外,我们在IO带宽上,目前还没有硬的限制(目前POLARDB的实例达不到自研存储的带宽上线),但是很快,为了资源隔离的更加彻底,我们也会加上IO带宽的限制和隔离。
升级问题
由于POLARDB是阿里云自研的关系数据库产品,我们在上面不但开发了数据库系统,还开发了一套对应的文件系统和块存储系统。不少用户对我们的期望很高,也提出了许多优化建议,因此POLARDB的系统升级频率会比RDS家族的产品高。一方面,我们需要修复一些极端情况下会被触发的BUG,另外一方面,我们需要满足用户形形色色的需求。当然,我们的系统升级都是热升级,我们竭尽所能尽可能减少对用户的影响,例如在系统升级时期的性能抖动时间,数据库不可服务时间等等。如果系统要升级,我们会提前给用户发短信/邮件以及大客户的电话通知,一般系统升级都在凌晨用户设定的可运维时间,正常的升级流程可能会造成秒级的服务中断,客户只需要在应用端保证能重连数据库即可。如果那天晚上,升级不太方便,请尽快提工单给我们,我们再约其他时间。我们后台也在开发一套主动运维系统,有了这套系统之后,用户就可以在控制台上在指定的时间点内主动升级数据库,同时不同版本的数据库也会有详尽的releasenote,便于用户按需升级。
总结
这篇文件简单解答了几个用户常常问到的问题。希望对大家有所帮助。
最后,欢迎使用POLARDB。
POLARDB · 最佳实践 · POLARDB不得不知道的秘密(二)的更多相关文章
- POLARDB · 最佳实践 · POLARDB不得不知道的秘密
## 前言 POLARDB作为阿里云下一代关系型云数据库,自去年9月份公测以来,收到了不少客户的重点关注,今年5月份商业化后,许多大客户开始陆续迁移业务到POLARDB上,但是由于POLARDB的很多 ...
- 你所不知道的linq(二)
上一篇说了from in select的本质,具体参见你所不知道的linq.本篇说下from...in... from... in... select 首先上一段代码,猜猜结果是什么? class P ...
- EntityFramework Core进行读写分离最佳实践方式,了解一下(二)?
前言 写过上一篇关于EF Core中读写分离最佳实践方式后,虽然在一定程度上改善了问题,但是在评论中有的指出更换到从数据库,那么接下来要进行插入此时又要切换到主数据库,同时有的指出是否可以进行底层无感 ...
- 我们必须要知道的RESTful服务最佳实践
看过很多RESTful相关的文章总结,参齐不齐,结合工作中的使用,非常有必要归纳一下关于RESTful架构方式了,RESTful只是一种架构方式的约束,给出一种约定的标准,完全严格遵守RESTful标 ...
- 「从零单排HBase 06」你必须知道的HBase最佳实践
前面,我们已经打下了很多关于HBase的理论基础,今天,我们主要聊聊在实际开发使用HBase中,需要关注的一些最佳实践经验. 1.Schema设计七大原则 1)每个region的大小应该控制在10G到 ...
- [iOS翻译]《iOS 7 Programming Pushing the Limits》系列:你可能不知道的Objective-C技巧
简介: 如果你阅读这本书,你可能已经牢牢掌握iOS开发的基础,但这里有一些小特点和实践是许多开发者并不熟悉的,甚至有数年经验的开发者也是.在这一章里,你会学到一些很重要的开发技巧,但这仍远远不够,你还 ...
- 最佳实践 | 数据库迁云解决方案选型 & 流程全解析
Oracle是非常强大的综合数据库,但同时也存在一些劣势,比如由于采用集中式架构,无法很好地实现横向扩展,并且其稳定性依赖于硬件.出于架构升级.降低成本和云化等需求,越来越多的企业需要“去Oracle ...
- MaxCompute 构建企业云数据仓库CDW的最佳实践建议
在本文中阿里云资深产品专家云郎分享了基于阿里云 MaxCompute 构建企业云数据仓库CDW的最佳实践建议. 本文内容根据演讲视频以及PPT整理而成. 大家下午好,我是云郎,之前在甲骨文做企业架构师 ...
- 探索云数据库最佳实践 阿里云开发者大会数据库专场邀你一起Code up!
盛夏.魔都.科技 三者在一起有什么惊喜? 7月24日,阿里云峰会·上海——开发者大会将在上海世博中心盛大启程,与未来世界的开发者们分享数据库.云原生.开源大数据等领域的技术干货,共同探讨前沿科技趋势, ...
随机推荐
- 银行卡号、电话号、身份证号 EditText 自定义格式的输入框
package com.yidian.AddSpaceEditText;import android.text.Editable;import android.text.InputFilter;imp ...
- JavaScript和JQuery的区别
一.本质上的区别 1.JavaScript 是通过<script></script>标签插入到HTML页面,可由所有的现代浏览器执行的一种轻量级的编程语言. 2.JQuery是 ...
- PAT1130:Infix Expression
1130. Infix Expression (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Give ...
- 使用 Java8 Optional 的正确姿势(转)
我们知道 Java 8 增加了一些很有用的 API, 其中一个就是 Optional. 如果对它不稍假探索, 只是轻描淡写的认为它可以优雅的解决 NullPointException 的问题, 于是代 ...
- SSM-SpringMVC-18:SpringMVC中参数自动装配
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 在处理方法中,参数写上之后,只要符合特定规则,就可以自动装配 首先 其次是:自定义的参数的自动装配: 案例如 ...
- HTTPS 之 TLS 性能调优
HTTPS(HTTP over SSL)是以安全为目标的 HTTP 通道,可以理解为 HTTP + SSL/TLS,即在 HTTP 下加入 SSL/TLS 层作为安全基础.其中 TLS 的前身是 SS ...
- 利用java反射机制实现读取excel表格中的数据
如果直接把excel表格中的数据导入数据库,首先应该将excel中的数据读取出来. 为了实现代码重用,所以使用了Object,而最终的结果是要获取一个list如List<User>.Lis ...
- selenium chromedriver与谷歌浏览器版本映射表
chromedriver版本 支持的Chrome版本 v2.35 v62-64 v2.34 v61-63 v2.33 v60-62 v2.32 v59-61 v2.31 v58-60 v2.30 v5 ...
- 树莓派.设置无线网卡为AP工作模式(pi2和pi3)
树莓派2的设置办法: 1. 安装NetworkManager管理工具(可选),以支持nmcli命令 sudo apt-get install -y network-manager 2. 安装hosta ...
- java.lang.IllegalArgumentException异常 返回值类型的问题
java.lang.IllegalArgumentException: Cannot create TypedQuery for query with more than one return usi ...