【腾讯Bugly干货分享】微信iOS SQLite源码优化实践

本文分享了微信iOS客户端在面对SQLite性能瓶颈时的优化实践,包括多线程并发和I/O性能的提升。通过合入SQLite源码,解决了多线程并发问题,如优化Busy Retry方案,减少了卡顿和SQLITE_BUSY的发生。同时,对I/O性能进行优化,如保留WAL文件大小以提升读写速度,并利用mmap提升性能。其他优化措施包括禁用文件锁和内存统计锁,以减少不必要的阻塞和性能损耗。
摘要由CSDN通过智能技术生成

本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57b58022433221be01499480

作者:张三华

前言

随着微信iOS客户端业务的增长,在数据库上遇到的性能瓶颈也逐渐凸显。在微信的卡顿监控系统上,数据库相关的卡顿不断上升。而在用户侧也逐渐能感知到这种卡顿,尤其是有大量群聊、联系人和消息收发的重度用户。

我们在对SQLite进行优化的过程中发现,靠单纯地修改SQLite的参数配置,已经不能彻底解决问题。因此从6.3.16版本开始,我们合入了SQLite的源码,并开始进行源码层的优化。

本文将分享在SQLite源码上进行的多线程并发、I/O性能优化等,并介绍优化相关的SQLite原理。

多线程并发优化

1. 背景

由于历史原因,旧版本的微信一直使用单句柄的方案,即所有线程共有一个SQLite Handle,并用线程锁避免多线程问题。当多线程并发时,各线程的数据库操作同步顺序进行,这就导致后来的线程会被阻塞较长的时间。

2. SQLite的多句柄方案及Busy Retry方案

SQLite实际是支持多线程(几乎)无锁地并发操作。只需

  1. 开启配置 PRAGMA SQLITE_THREADSAFE=2
  2. 确保同一个句柄同一时间只有一个线程在操作

Multi-thread. In this mode, SQLite can be safely used by multiple threads provided that no single database connection is used simultaneously in two or more threads.

倘若再开启SQLite的WAL模式(Write-Ahead-Log),多线程的并发性将得到进一步的提升。

此时写操作会先append到wal文件末尾,而不是直接覆盖旧数据。而读操作开始时,会记下当前的WAL文件状态,并且只访问在此之前的数据。这就确保了多线程读与读读与写之间可以并发地进行。

然而,阻塞的情况并非不会发生。

  • 当多线程写操作并发时,后来者还是必须在源码层等待之前的写操作完成后才能继续。

SQLite提供了Busy Retry的方案,即发生阻塞时,会触发Busy Handler,此时可以让线程休眠一段时间后,重新尝试操作。重试一定次数依然失败后,则返回SQLITE_BUSY错误码。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值