Hi,
I have gotten abe to sync up with the bitcoin dir, took about 12hours on a I7-920 with SSD server, but theres alot other going on at the server.
CPU was not pegged, so probaly disc/io that was the bottleneck.
Anyways...
After it syncs it listens for a HTTP connection, to show the interface and all.
Does it still sync new data at this point, or does it need to be restarted on a timer ?
After a few minutes it looses the MySQL connection, probaly due to a timeout, and it does not
gracefully recover it, instead it crashes.
hostname - - [17/Dec/2011 15:52:12] "GET /favicon.ico HTTP/1.1" 200 3774
Traceback (most recent call last):
File "Abe/DataStore.py", line 1874, in catch_up
store.catch_up_dir(dircfg)
File "Abe/DataStore.py", line 1892, in catch_up_dir
ds = open_blkfile()
File "Abe/DataStore.py", line 1885, in open_blkfile
store._refresh_dircfg(dircfg)
File "Abe/DataStore.py", line 2058, in _refresh_dircfg
WHERE dirname = ?""", (dircfg['dirname'],))
File "Abe/DataStore.py", line 458, in selectrow
store.sql(stmt, params)
File "Abe/DataStore.py", line 372, in sql
store.cursor.execute(cached, params)
File "/usr/lib/pymodules/python2.6/MySQLdb/cursors.py", line 166, in execute
self.errorhandler(self, exc, value)
File "/usr/lib/pymodules/python2.6/MySQLdb/connections.py", line 35, in defaulterrorhandler
raise errorclass, errorvalue
OperationalError: (2006, 'MySQL server has gone away')
Warning: failed to catch up /fast/bitcoin/.bitcoin: (2006, 'MySQL server has gone away') {'blkfile_number': 1, 'dirname': '/fast/bitcoin/.bitcoin', 'chain_id': None, 'id': Decimal('1'), 'blkfile_offset': 828778091}
Traceback (most recent call last):
File "/usr/lib/python2.6/wsgiref/handlers.py", line 93, in run
self.result = application(self.environ, self.start_response)
File "/fast/bitcoin/abe/Abe/abe.py", line 198, in __call__
abe.store.rollback()
File "Abe/DataStore.py", line 578, in rollback
store.conn.rollback()
OperationalError: (2006, 'MySQL server has gone away')
I would like to build a set of scripts to provide the same as the now defunct bitcoinnotify´er, but in a way that everyone can run their own if they want to.
So my plan is to use abe to parse the bitcoind files, and then make some PHP scripts that will use the MySQL database to check if there are new transactions for any of the monitored addresses.
And if any of the monitored transactions has the number of confirmations needed for a notification to be sent (be it email, post, db change, etc.)
[EDIT]
Just checked my my.cnf, the timeout it set to 60seconds, so if abe sends a keep alive less often than that, the connection will be terminated by the SQL server.
-Does anyone know what the keepalive setting is in abe?
-And abe should handle a lost connection to MySQL more gracefully, maybe attempt y reconnects with y*10seconds delay before quitting, so a monitor script can spot the missing process.
I tried to set wait_timeout to 1hour in MySQL, sofar abe has been idle for 1500seconds, so I dont think there is any keep alive builtin.
I think it should be an option for the user to either use keep-alive, or remake the connection when needed, since high traffic sites may prefer a live connection, ready to use, and sites that just keep the blocks updated in the DB will only see action when a new block is ready (if abe updates it while running).
I will try to look in the source, but python is not really my strong side, so jumping right into making a thread to send keep alives/reconnect the sql driver, may be a bit rough
[EDIT2]
This small fix handles the error when accessing a webpage after the SQL connection has been killed for whatever reason.
It simply tries to reconnect and execute once more when a execute fails.
Its a workaround rather that an actual bug fix since, the real fix (IMHO) should be to either keep the connection alive, or close it when done and make one when needed.
$ git diff
diff --git a/Abe/DataStore.py b/Abe/DataStore.py
index e256115..d013219 100644
--- a/Abe/DataStore.py
+++ b/Abe/DataStore.py
@@ -402,8 +402,12 @@ class DataStore(object):
try:
store.cursor.execute(cached, params)
except Exception, e:
- store.sqllog.info("EXCEPTION: %s", e)
- raise
+ try:
+ store.reconnect();
+ store.cursor.execute(cached, params)
+ except Exception, e:
+ store.sqllog.info("EXCEPTION: %s", e)
+ raise
def ddl(store, stmt):
if stmt.lstrip().startswith("CREATE TABLE "):