问题现象
用户执行大 SQL(同时包含大规模数据读取与写入)的场景下,触发限速,MemTable 无法释放,导致内存爆。当大 SQL 结束后,MemTable 才可以释放恢复。
关键诊断信息
触发条件
用户执行大 SQL (同时包含大规模数据读取与写入)。
事前巡检
OBServer 日志是否存在限速日志 report write throttle info。
事后诊断
OBServer 日志是否存在限速日志 memtable last ref release too late。
问题原因
写入限速导致的异常场景:对于一条既有写入又有读取的大 SQL,迭代器需要边读边写,当发生写入限速后,写迭代器被限速,也会同步阻塞读迭代器,此时读迭代器正在读取的数据将会 Hold MemTable 的引用无法释放。 当 MemTable 的引用无法释放后,就无法释放销毁冻结的 MemTable,内存水位无法下降,写入限速也会难以解开,造成循环依赖,最终 SQL 超时或事务回滚后问题消失。没有发生写入限速就不会引发此问题,同样的若 SQL 只有读或者只有写,也不会有问题。
问题的风险及影响
大 SQL 执行过程中, 可能存在 MemTable 无法释放导致内存爆的情况。
影响租户
影响 OceanBase 数据库中的 SYS 租户和 Oracle 租户以及 MySQL 租户。
影响版本
OceanBase 数据库 V2.2.77 GA(oceanbase-2.2.77-20210508211731)及之后版本、V3.1.2 GA(oceanbase-3.1.2-20210618150922)及之后版本、V3.2.2 GA(oceanbase-3.2.2-20211130225726)及之后版本、V3.2.4 GA(oceanbase-3.2.4.0-100000072022102819)及之后版本。
解决方法及规避方式
解决方法:
重启或者等待事务超时回滚。
规避方式:
调大租户内存,但是为了防止大量 callback 导致的 bad case,要调小
freeze_tigger_percentage。