|
|
@ -72,10 +72,63 @@ static char *status_chars = "|/-\\"; |
|
|
|
|
|
|
|
|
|
|
|
static char *restorefrom; |
|
|
|
static char *restorefrom; |
|
|
|
|
|
|
|
|
|
|
|
/* Restart data needed
|
|
|
|
/* Startup
|
|
|
|
* ------------------- |
|
|
|
* ------- |
|
|
|
* After the DB load, load "ckpool's ckdb logfile" (CCL), and all |
|
|
|
* During startup we load the DB and track where it is up to with |
|
|
|
* later CCLs, that contains the oldest date of all of the following: |
|
|
|
* dbstatus, we then reload "ckpool's ckdb logfiles" (CCLs) based |
|
|
|
|
|
|
|
* on dbstatus |
|
|
|
|
|
|
|
*TODO: |
|
|
|
|
|
|
|
* Once the DB is loaded, we can immediately start receiving ckpool |
|
|
|
|
|
|
|
* messages since ckpool already has logged all messages to the CLLs |
|
|
|
|
|
|
|
* and ckpool only verifies authorise responses |
|
|
|
|
|
|
|
* Thus we can queue all messages: |
|
|
|
|
|
|
|
* workinfo, shares, shareerror, ageworkinfo, poolstats, userstats |
|
|
|
|
|
|
|
* and block |
|
|
|
|
|
|
|
* to be processed after the reload completes and just process authorise |
|
|
|
|
|
|
|
* messages immediately while the reload runs |
|
|
|
|
|
|
|
* This can't cause a duplicate process of an authorise message since a |
|
|
|
|
|
|
|
* reload will ignore any messages before the last DB auths message, |
|
|
|
|
|
|
|
* however, if ckdb and ckpool get out of sync due to ckpool starting |
|
|
|
|
|
|
|
* during the reload (as mentioned below) it is possible for ckdb to |
|
|
|
|
|
|
|
* find an authorise message in the CCLs that was processed in the |
|
|
|
|
|
|
|
* message queue and thus is already in the DB. |
|
|
|
|
|
|
|
* This error would be very rare and also not an issue |
|
|
|
|
|
|
|
* The first ckpool message also allows us to know where ckpool is up to |
|
|
|
|
|
|
|
* in the CCLs and thus where to stop processing the CCLs to stay in |
|
|
|
|
|
|
|
* sync with ckpool |
|
|
|
|
|
|
|
* If ckpool isn't running, then the reload will complete at the end of |
|
|
|
|
|
|
|
* the last CCL file, however if a message arrives from ckpool while |
|
|
|
|
|
|
|
* processing the CCLs, that will mark the point where to stop processing |
|
|
|
|
|
|
|
* but can also produce a fatal error at the end of processing, reporting |
|
|
|
|
|
|
|
* the full ckpool message, if the message was not found in the CCL |
|
|
|
|
|
|
|
* processing after the message was received |
|
|
|
|
|
|
|
* This can be caused by two circumstances: |
|
|
|
|
|
|
|
* 1) the disk had not yet written it to the CCL when ckdb read EOF and |
|
|
|
|
|
|
|
* ckpool was started at about the same time as the reload completed. |
|
|
|
|
|
|
|
* This can be seen if the message displayed in the fatal error IS NOT |
|
|
|
|
|
|
|
* in ckdb's message logfile. A ckdb restart will resolve this |
|
|
|
|
|
|
|
* 2) ckpool was started at the time of the end of the reload, but the |
|
|
|
|
|
|
|
* authorise message was written to disk and found in the CCL before |
|
|
|
|
|
|
|
* it was processed in the message queue. This can be seen if the |
|
|
|
|
|
|
|
* message displayed in the fatal error IS in ckdb's message logfile |
|
|
|
|
|
|
|
* and means the messages after it in the logfile have already been |
|
|
|
|
|
|
|
* processed. Again, a ckdb restart will resolve this |
|
|
|
|
|
|
|
* In both the above (very rare) cases, if ckdb was to continue running, |
|
|
|
|
|
|
|
* it would break the synchronisation and could cause DB problems, so |
|
|
|
|
|
|
|
* ckdb aborting and needing a restart resolves this |
|
|
|
|
|
|
|
* The users table, required for the authorise messages, is always updated |
|
|
|
|
|
|
|
* immediately and is not affected by ckpool messages until we |
|
|
|
|
|
|
|
* TODO: allow bitcoin addresses - this will also need to be handled |
|
|
|
|
|
|
|
* while filling the queue during reload, once we allow BTC addresses |
|
|
|
|
|
|
|
* During the reload we can use the userstats createdate as 'now' for |
|
|
|
|
|
|
|
* the userstats summarisation process to allow the summarisation to |
|
|
|
|
|
|
|
* run during the reload |
|
|
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Reload data needed
|
|
|
|
|
|
|
|
* ------------------ |
|
|
|
|
|
|
|
* After the DB load completes, load "ckpool's ckdb logfile" (CCL), and |
|
|
|
|
|
|
|
* all later CCLs, that contains the oldest date of all of the following: |
|
|
|
* RAM shares: oldest DB sharesummary firstshare where complete='n' |
|
|
|
* RAM shares: oldest DB sharesummary firstshare where complete='n' |
|
|
|
* All shares before this have been summarised to the DB with |
|
|
|
* All shares before this have been summarised to the DB with |
|
|
|
* complete='a' (or 'y') and were deleted from RAM |
|
|
|
* complete='a' (or 'y') and were deleted from RAM |
|
|
@ -108,7 +161,7 @@ static char *restorefrom; |
|
|
|
* will be after the last DB workinfo |
|
|
|
* will be after the last DB workinfo |
|
|
|
* DB+RAM accountbalance (TODO): resolved by shares/workinfo/blocks |
|
|
|
* DB+RAM accountbalance (TODO): resolved by shares/workinfo/blocks |
|
|
|
* RAM workerstatus: last_auth, last_share, last_stats all handled by |
|
|
|
* RAM workerstatus: last_auth, last_share, last_stats all handled by |
|
|
|
* DB load up to whatever the CCL restart point is, and then |
|
|
|
* DB load up to whatever the CCL reload point is, and then |
|
|
|
* corrected with the CCL reload |
|
|
|
* corrected with the CCL reload |
|
|
|
* last_idle will be the last idle userstats in the CCL load or 0 |
|
|
|
* last_idle will be the last idle userstats in the CCL load or 0 |
|
|
|
* Code currently doesn't use last_idle, so for now this is OK |
|
|
|
* Code currently doesn't use last_idle, so for now this is OK |
|
|
@ -161,7 +214,7 @@ typedef struct loadstatus { |
|
|
|
} LOADSTATUS; |
|
|
|
} LOADSTATUS; |
|
|
|
static LOADSTATUS dbstatus; |
|
|
|
static LOADSTATUS dbstatus; |
|
|
|
|
|
|
|
|
|
|
|
/* Temporary while doing restart - it (of course) contains the fields
|
|
|
|
/* Temporary while doing reload - it (of course) contains the fields
|
|
|
|
* required to track the newest userstats per user/worker |
|
|
|
* required to track the newest userstats per user/worker |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static K_TREE *userstats_db_root; |
|
|
|
static K_TREE *userstats_db_root; |
|
|
@ -2878,7 +2931,7 @@ static bool _sharesummary_update(PGconn *conn, SHARES *s_row, SHAREERRORS *e_row |
|
|
|
static double cmp_sharesummary_workinfoid(K_ITEM *a, K_ITEM *b); |
|
|
|
static double cmp_sharesummary_workinfoid(K_ITEM *a, K_ITEM *b); |
|
|
|
static double cmp_shares(K_ITEM *a, K_ITEM *b); |
|
|
|
static double cmp_shares(K_ITEM *a, K_ITEM *b); |
|
|
|
|
|
|
|
|
|
|
|
/* N.B. a DB check can be done to find sharesummaries that were missed being
|
|
|
|
/* N.B. a DB check can be done to find sharesummaries that have missed being
|
|
|
|
* aged (and a possible problem with the aging process): |
|
|
|
* aged (and a possible problem with the aging process): |
|
|
|
* e.g. for a date D in the past of at least a few hours |
|
|
|
* e.g. for a date D in the past of at least a few hours |
|
|
|
* select count(*) from sharesummary where createdate<'D' and complete='n'; |
|
|
|
* select count(*) from sharesummary where createdate<'D' and complete='n'; |
|
|
@ -2886,7 +2939,7 @@ static double cmp_shares(K_ITEM *a, K_ITEM *b); |
|
|
|
* update sharesummary set complete='a' where createdate<'D' and complete='n'; |
|
|
|
* update sharesummary set complete='a' where createdate<'D' and complete='n'; |
|
|
|
* It's important to make sure the D value is far enough in the past such that |
|
|
|
* It's important to make sure the D value is far enough in the past such that |
|
|
|
* all the matching sharesummary records in ckdb have certainly completed |
|
|
|
* all the matching sharesummary records in ckdb have certainly completed |
|
|
|
* ckdb would need a restart to get the updated DB information though it would |
|
|
|
* ckdb would need to restart to get the updated DB information though it would |
|
|
|
* not affect current ckdb code |
|
|
|
* not affect current ckdb code |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static bool workinfo_age(PGconn *conn, char *workinfoidstr, char *poolinstance, |
|
|
|
static bool workinfo_age(PGconn *conn, char *workinfoidstr, char *poolinstance, |
|
|
|