odoo使用的是 postgresql 数据库,号称开源的 oracel,所以海量数据和高并发上处理,已经很很省心,我们更多的关注 odoo 本身即可。
真实使用环境的高并发访问和我们自己开发自己测试,总是有大量的不同,其中一个典型就是对死锁的处理,这些坑不过,odoo 终究只能做中小应用。
在一次客户真实环境中,我们遇到个问题,也算是小坑了,记录下。具体的表现是,大概1~2天,就会出现一次 odoo 无法访问,过上几分钟又好了。 跟踪查看 nginx 和 odoo 的 log,得知是数据库无法正常响应,还是比较少见的。 然后在 postgresql 的 log 里看到
ERROR: could not obtain lock on row in relation "ir_cron" 2020-01-21 05:01:14.363 UTC [108807] STATEMENT: SELECT * FROM ir_cron WHERE numbercall != 0 AND active AND nextcall <= (now() at time zone 'UTC') AND id=8 FOR UPDATE NOWAIT
由于每次登录都要与第三方接口交互,也要保存些信息,为减少服务器负载,用了较短时间间隔的定时任务。从 log 中看出,这是数据库产生了死锁,没有正常释放。处理后解决。
调整了下配置,主要是odoo.conf 中的 max_cron_threads ,根据服务器资源和业务需求,将参数调整好后,故障就没再出现了。
所以要注意, odoo 的定时任务不少,特别是邮件。而且 cron 有锁机制,所以要用较多的线程来处理 cron ,同时要停止无效的 cron,调整好 cron 的时间间隔。
通过本次填坑,知道基本功实在重要,官方文档要好好读。
部署文章在此
https://www.sunpop.cn/documentation/12.0/setup/deploy.html
参考文章在此
https://www.odoo.com/forum/help-1/question/could-not-obtain-lock-on-row-in-relation-ir-cron-74519