编程一生
致力于写大家都能看懂的、有深度的
技术文章
05/2024
01
开场白
亚马逊有个bar raiser文化。就是说新招来的人一定要超过之前入职人员的平均水平,宁缺毋滥。越来越多的公司在推行这种文化。在这种氛围下:“虽然我不懂,但是活儿是能出来的”这种解决问题型人才也在以飞奔的速度转型为“活儿能干好,话能说明白”的综合素质人才。
今天咱们就来聊一聊一个简单的添加索引在这个时代要怎样实施。
02
添加普通索引可能引起的问题
尽管添加索引可以优化SQL语句的性能,但是添加索引的同时也会带来不小的开销。尤其是在有大量的索引的情况下。
mysql添加索引造成的影响如下:
DML(数据操作语言)影响,在表上添加索引会直接影响写操作性能(因为添加记录的同时还有创建相应记录的索引,这也是要耗资源的)。
DDL(数据定义语言)影响,随着表大小的不断增加,对性能的影响也会不断增加。比如:ALTER语句会耗费更多的时间。
磁盘空间的影响,往往在添完一个索引后表占用的空间大小会成倍地增加。
03
新增唯一索引造成数据丢失问题
MySQL目前主要有三种DDL方式,MySQL原生的DDL,pt-osc和gh-ost。从gh-ost和pt-osc的原理上来讲,全量都是通过insert ignore拷贝到新表,然后增量数据通过触发器或者binlog的方式merge到新表中,这样的话在以下三种场景会出现数据丢失:
新加字段,并对该字段添加唯一索引;如果这时候使用 gh-ost 变更,最后只会剩下一条记录
原表存在重复值,如下数据表;如果这时候使用 gh-ost变更,就会丢弃重复记录
改表过程中新写(包含更新)的数据出现重复值,如果这时候使用 gh-ost 变更,在拷贝原表数据期间,可能会覆盖重复数据
方案 | 是否丢数据 | 建议 |
原生 | DDL 不丢数据 | 适合小表,及对从库延迟没要求的场景 |
pt-osc | 可能丢数据,无辅助功能可以避免丢数据的场景 | 不适合添加唯一索引 |
gh-ost | 可能丢数据,有辅助功能可以避免部分丢数据的场景 | 适合添加唯一索引 |
04
添加索引投产前要怎样做
测试环境充分验证
添加索引前备份,在索引后,将数据与备份数据进行比对,确保数据符合预期。
观察添加索引的耗时,准确评估对生产环境的影响。
投产前通知并制定紧急预案
通知DBA和所有使用此数据库的团队和其他相关团队。DBA在添加索引前先备份,一旦出现问题可立即回滚。
投产时
业务低峰期进行变更降低业务影响。密切观察监控,做好回滚准备。
05
总结
之前遇到过一个开发小哥哥修改了MQ的一个参数,这个参数的作用是:在消费消息时,原本线程来获取需要消费的消息,如果获取不到就阻塞直到有消息为止;修改后的逻辑是线程来获取需要消费的消息,如果获取不到就返回做别的事情,过一段时间再来获取消息。如果粗略来考虑:这就是把阻塞变成非阻塞来提高效率的一个配置修改啊。所以开发小哥哥也没压测,甚至没有告诉任何人他做了这个变更,直接投产了。这个变更造成了公司数千万的资金损失。
敬畏生产,不要因为只是添加一个索引或者修改一个配置而不做测试直接投产。