postgres LockError ...如何调查

时间:2016-04-14 19:57:40

标签: locking whoosh

您好我正在使用带有nginx的gunicorn和一个postgreSQL数据库来运行我的网络应用程序。我最近从

更改了我的gunicorn命令
{
    'Loopback0': {'cost': '1000', 'area': '0'}, 
    'Loopback1': {'cost': '1', 'area': '0'}, 
    'GigabitEthernet0/0/0/0': {'cost': '1', 'area': '0'}
}

gunicorn run:app -w 4 -b 0.0.0.0:8080 --workers=1 --timeout=300

使用2名工人。现在我收到错误消息,如

gunicorn run:app -w 4 -b 0.0.0.0:8080 --workers=2 --timeout=300

我对这些错误消息不能做太多,但它们似乎与我在数据库模型中的User表上搜索到的嗖嗖声相关联

  File "/usr/local/lib/python2.7/dist-packages/flask_sqlalchemy/__init__.py", line 194, in session_signal_after_commit
    models_committed.send(session.app, changes=list(d.values()))
  File "/usr/local/lib/python2.7/dist-packages/blinker/base.py", line 267, in send
    for receiver in self.receivers_for(sender)]
  File "/usr/local/lib/python2.7/dist-packages/flask_whooshalchemy.py", line 265, in _after_flush
    with index.writer() as writer:
  File "/usr/local/lib/python2.7/dist-packages/whoosh/index.py", line 464, in writer
    return SegmentWriter(self, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/whoosh/writing.py", line 502, in __init__
    raise LockError
LockError

任何想法如何调查这个?我认为postgres允许并行访问,因此我认为锁定错误不应该发生?当我只使用1个工作时他们没有发生,所以它肯定是由多个工人造成的...... 任何帮助表示赞赏 谢谢 卡尔

1 个答案:

答案 0 :(得分:1)

这与PostgreSQL无关。 Whoosh持有文件锁写入,并且在此代码的最后一行失败...

class SegmentWriter(IndexWriter):
    def __init__(self, ix, poolclass=None, timeout=0.0, delay=0.1, _lk=True,
                 limitmb=128, docbase=0, codec=None, compound=True, **kwargs):
        # Lock the index
        self.writelock = None 
        if _lk: 
            self.writelock = ix.lock("WRITELOCK")
            if not try_for(self.writelock.acquire, timeout=timeout,
                           delay=delay):
                raise LockError

请注意,此时的延迟默认值为0.1秒,如果在此时间内未获得锁定,则会失败。你增加了你的工人,所以现在你有锁争用。来自以下文档...

https://whoosh.readthedocs.org/en/latest/threads.html

  

锁定

     
    

一次只能有一个线程/进程写入索引。什么时候     你打开一个编写器,它会锁定索引。如果你试图打开一个作家     它会在另一个线程/进程中引发相同的索引     whoosh.store.LockError。

         

在多线程或多进程环境中,您的代码需要     意识到如果作家是,打开作家可能会引发这种异常     已经开放了。 Whoosh包含几个示例实现     (whoosh.writing.AsyncWriter和whoosh.writing.BufferedWriter)的方法     解决写锁问题。

         

当编写器处于打开状态并且在提交期间,索引仍然存在     可供阅读。现有读者不受影响和新读者     可以正常打开当前指数。

  

您可以找到有关如何同时使用Whoosh的示例。

<强>缓冲

https://whoosh.readthedocs.org/en/latest/api/writing.html#whoosh.writing.BufferedWriter

<强>异步

https://whoosh.readthedocs.org/en/latest/api/writing.html#whoosh.writing.AsyncWriter

我首先尝试缓冲版本,因为批处理写入几乎总是更快。