On Thursday 08 May 2014 06:30:39 Adrian Klaver wrote: > On 05/08/2014 04:09 AM, Vincent de Phily wrote: > > Hello, > > > > I'm processing records in batches using PG 9.1.12, python 2.7, and psycopg > > > 2.5.2 : > Comments in the code below: > > def enqueue_loop(q): > > curs = DB_HANDLER.cursor() > > query = """UPDATE foo SET processing = 't' WHERE id IN > > > > (SELECT id FROM foo WHERE processing = 'f' ORDER BY id ASC > > LIMIT > > > > 5000 FOR UPDATE) RETURNING *""" > > # Where is this query actually run? Sorry, I edited my code too much, it's actually executed at the first line of the loop, I added it below. > > while DO_LOOP: #the whole program eventually stops if this is false > > # What cause DO_LOOP to go false? Either when receiving a signal from the OS (registered with "signal.signal(signal.SIGINT, stop_main)") or when the topmost try-catch- reinitialize-retry loop has caught a quick sucession of exceptions. DO_LOOP is tested in a few places where we can make a clean exit. A cronjob will restart the process if it is not or badly running. > > curs.execute(query) > > results = curs.fetchall() > > rlen = len(results) > > > > if rlen > 0: > > LOG.debug("Fetched %d rows", rlen) > > # What do you see in LOG for rlen values? The histogram shows a large amount of small values, progressively becoming rarer for bigger values, up to value 5000 which is very frequent again (depending on the day, between 0.5 and 5% of queries return the maximum number of rows), then a handfull freak values of ~9k, 11k, 15k, 33k, 46k, 107k, etc which cause my problems. > > if rlen == 0: > > # [...] wait for notification... > > continue > > > > # [...] Enqueue batch and let other threads process it. > > # [...] Those threads will eventually delete the processed rows > > from > > # the foo table. > > > > The problem is that sometimes (once every few days at about 2-300K queries > > per day) I get many more rows than the max 5000 I asked for (I've seen up > > to 25k). And I'm getting timeouts and other problems as a result. > > > > The id column is your typical primary key integer with a unique index. > > I've > > checked the problematic cases and there are no id gaps or duplicate rows. > > There are multiple threads in the program, but only the main thread is > > running enqueue_loop(). I'm not sure if this is a server or a driver > > issue. > > > > > > Any idea ? Thanks. -- Vincent de Phily