Changeset: 5bbc30ddc537 for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=5bbc30ddc537
Modified Files:
monetdb5/modules/mal/wlcr.c
monetdb5/modules/mal/wlcr.h
monetdb5/optimizer/opt_wlcr.c
sql/backends/monet5/sql_wlcr.c
Branch: wlcr
Log Message:
Make control files more descriptive
To enable multiple snapshot departures, we have to explicitly give a range to
the log files.
To enable fusion from different masters the log file names should reflect the
master dbname.
diffs (truncated from 381 to 300 lines):
diff --git a/monetdb5/modules/mal/wlcr.c b/monetdb5/modules/mal/wlcr.c
--- a/monetdb5/modules/mal/wlcr.c
+++ b/monetdb5/modules/mal/wlcr.c
@@ -11,9 +11,8 @@
* This module collects the workload-capture-replay statements during
transaction execution.
* It is used primarilly for replication management and workload replay
*
- * The goal is to easily clone a master database. All data of the master
- * is basically only available for read only access. Accidental corruption of
this
- * data is avoided by setting ownership and access properties at the SQL level
in the replica.
+ * The goal is to easily clone a master database. Accidental corruption of
this
+ * data should ne avoided by setting ownership and access properties at the
SQL level in the replica.
*
*
* IMPLEMENTATION
@@ -21,31 +20,41 @@
* A database can be set into 'master' mode only once using the SQL command:
* CALL master()
*
- * It creates directory .../dbfarm/dbname/master to hold all necessary
information
+ * It creates a directory .../dbfarm/dbname/master to hold all necessary
information
* for the creation and maintenance of replicas.
*
* Every replica should start off with a copy of binary snapshot stored
- * in .../dbfarm/dbname/master/bat or an empty database.
+ * in .../dbfarm/dbname/master/bat or with an empty database.
* The associated log files are stored as master/wlcr<number>.
*
- * Each wlcr log file contains a serial log for a transaction batch.
- * Each job is identified by the owner of the query,
+ * Each wlcr log file contains a serial log of committed transactions.
+ * The log records are represented as ordinary MAL statements, which
+ * are executed in serial mode.
+ * Each transaction job is identified by the owner of the query,
* commit/rollback status, its starting time and runtime (in ms).
+ * The end of the transaction is marked as exec()
*
- * Logging of queries can be further limited to those that satisfy a threshold.
+ * Logging of queries can be limited to those that satisfy an execution
threshold.
* SET replaythreshold= <number>
* The threshold is given in milliseconds. A negative threshold leads to
ignoring all queries.
* The threshold setting is not saved because it is a client specific action.
*
- * A replica server should issue the matching call
+ * A replica is constructed in three steps.
+ * 1) a snapshot copy of the BAT directory is created within a SQL
transaction.[TODO]
+ * 2) a new database is created from this snapshot using monetdb[TODO]
+ * 3) The logs are replayed to bring the snapshot up to date.
+ *
+ * Step 1) and 2) can be avoided by starting with an empty database and
+ * under the assumption that the log files reflect the complete history.
+ * The monetdb program will check for this.
+ *
+ * Processing the log files starts in the background using the call.
* CALL clone("dbname")
- * It (should) leads to taking a copy of the snapshot following by server
restart[TODO]
- * and processing of the log files starts in the background.
- * Queries are simply ignored unless needed as replacement for catalog actions.
- * [TODO] the user might wait until the database is fresh
+ * It will iterate through the log files, applying all transactions.
+ * Queries are simply ignored unless needed as replacement for catalog
actions..
* [TODO] the user might want to take a time-stamped version only, ignoring
all actions afterwards.
*
- * The alternative is to replay the complete log
+ * The alternative is to replay the complete query log
* CALL replay("dbname")
* In this mode all queries are executed under the credentials of the query
owner[TODO],
* including those that lead to updates.
@@ -60,7 +69,6 @@
* Simplicity and ease of control has been the driving argument here.
*
* The integrity of the wlcr directories is critical. For now we assume that
all batches are available.
- * We should detect that wlcr.master() is issued after updates have taken
place on the snapshot TODO.
*
*/
#include "monetdb_config.h"
@@ -71,24 +79,30 @@
static MT_Lock wlcr_lock MT_LOCK_INITIALIZER("wlcr_lock");
+int wlcr_start = 0; // first batch associated with snapshot
int wlcr_batch = 0; // last batch job identifier
-int wlcr_start = 0; // first batch to check next
int wlcr_tid = 0; // last transaction id
static char *wlcr_name[]= {"","query","update","catalog"};
+static str wlcr_dbname = 0;
static stream *wlcr_fd = 0;
-str wlcr_dir = 0;
+static str wlcr_dir = 0;
/* The database snapshots are binary copies of the dbfarm/database/bat
* New snapshots are created currently using the 'monetdb snapshot <db>'
command
* or a SQL procedure.
- * It requires a database halt.
*
* The wlcr logs are stored in the snapshot directory as a time-stamped list
*/
+int
+WLCRused(void)
+{
+ return wlcr_dir != NULL;
+}
// creation of file and updating the version file should be atomic TODO!!!
+// The log files are marked with the database name. This allows for easy
recognition later on.
static str
WLCRloggerfile(Client cntxt)
{
@@ -96,19 +110,16 @@ WLCRloggerfile(Client cntxt)
FILE *fd;
(void) cntxt;
- snprintf(path,PATHLENGTH,"%s%cwlcr_%06d",wlcr_dir,DIR_SEP,wlcr_batch);
-#ifdef _WLCR_DEBUG_
- mnstr_printf(cntxt->fdout,"#WLCRloggerfile batch %s\n",path);
-#endif
+ snprintf(path,PATHLENGTH,"%s%c%s_%06d", wlcr_dir, DIR_SEP, wlcr_dbname,
wlcr_batch);
wlcr_fd = open_wastream(path);
if( wlcr_fd == 0)
throw(MAL,"wlcr.logger","Could not create %s\n",path);
wlcr_batch++;
wlcr_tid = 0;
- snprintf(path,PATHLENGTH,"%s%cwlcr",wlcr_dir, DIR_SEP);
+ snprintf(path,PATHLENGTH,"%s%c%s_wlcr", wlcr_dir, DIR_SEP, wlcr_dbname);
#ifdef _WLCR_DEBUG_
- mnstr_printf(cntxt->fdout,"#WLCRloggerfile %s\n",wlcr_dir);
+ mnstr_printf(cntxt->fdout,"#WLCRloggerfile %s\n", wlcr_dir);
#endif
fd = fopen(path,"w");
if( fd == NULL)
@@ -140,13 +151,13 @@ WLCRinit(Client cntxt)
}
if (dbname){
+ wlcr_dbname = GDKstrdup(dbname);
dir = GDKfilepath(0,0,"master",0);
- snprintf(path, PATHLENGTH,"%s%cwlcr",dir, DIR_SEP);
- wlcr_start = 0;
+ snprintf(path, PATHLENGTH,"%s%c%s_wlcr",dir, DIR_SEP,
wlcr_dbname);
fd = fopen(path,"r");
if( fd){
// database is in master tracking mode
- if( fscanf(fd,"%d", &wlcr_batch ) == 1){
+ if( fscanf(fd,"%d %d", &wlcr_start, &wlcr_batch ) == 2){
if( wlcr_batch < 0){
// logging was stopped
(void) fclose(fd);
@@ -187,7 +198,7 @@ WLCRstop (Client cntxt, MalBlkPtr mb, Ma
if( wlcr_dir == NULL)
throw(MAL,"wlcr.stop","Replica control not active");
- snprintf(path, PATHLENGTH,"%s%cwlcr",dir, DIR_SEP);
+ snprintf(path, PATHLENGTH,"%s%c%s_wlcr",dir, DIR_SEP,wlcr_dbname);
fd = fopen(path,"w");
if( fd == NULL)
throw(MAL,"wlcr.stop","File can not be access");
@@ -228,9 +239,9 @@ WLCRmaster(Client cntxt, MalBlkPtr mb, M
// if the master directory does not exit, create it
if ( wlcr_dir == NULL){
wlcr_dir = GDKfilepath(0,0,"master",0);
- snprintf(path, PATHLENGTH,"%s%cwlcr",wlcr_dir, DIR_SEP);
+ snprintf(path, PATHLENGTH,"%s%c%s_wlcr", wlcr_dir, DIR_SEP,
wlcr_dbname);
if( GDKcreatedir(path) == GDK_FAIL)
- throw(SQL,"wlcr.master","Could not create
%s\n",wlcr_dir);
+ throw(SQL,"wlcr.master","Could not create %s\n",
wlcr_dir);
#ifdef _WLCR_DEBUG_
mnstr_printf(cntxt->fdout,"#Snapshot directory '%s'\n",
wlcr_dir);
#endif
@@ -238,8 +249,8 @@ WLCRmaster(Client cntxt, MalBlkPtr mb, M
fd = fopen(path,"w");
if ( fd == NULL)
return createException(MAL,"wlcr.master","Unable to
initialize WLCR %s", path);
- if( fscanf(fd,"%d", &wlcr_batch) != 3)
- fprintf(fd,"0\n");
+ if( fscanf(fd,"%d %d", &wlcr_start, &wlcr_batch) != 2)
+ fprintf(fd,"0 0\n");
(void) fclose(fd);
}
if( wlcr_fd == NULL)
diff --git a/monetdb5/modules/mal/wlcr.h b/monetdb5/modules/mal/wlcr.h
--- a/monetdb5/modules/mal/wlcr.h
+++ b/monetdb5/modules/mal/wlcr.h
@@ -22,9 +22,9 @@
#define WLCR_CATALOG 3
mal_export int wlcr_threshold; // threshold (seconds) for sending readonly
queries
-mal_export str wlcr_dir;
mal_export str WLCRinit(Client cntxt);
+mal_export int WLCRused(void);
mal_export str WLCRinitCmd(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
mal_export str WLCRmaster(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
mal_export str WLCRstop(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr
pci);
diff --git a/monetdb5/optimizer/opt_wlcr.c b/monetdb5/optimizer/opt_wlcr.c
--- a/monetdb5/optimizer/opt_wlcr.c
+++ b/monetdb5/optimizer/opt_wlcr.c
@@ -27,7 +27,7 @@ OPTwlcrImplementation(Client cntxt, MalB
(void) cntxt;
(void) stk; /* to fool compilers */
- if( wlcr_dir == NULL)
+ if( ! WLCRused() )
goto wrapup;
old= mb->stmt;
limit= mb->stop;
diff --git a/sql/backends/monet5/sql_wlcr.c b/sql/backends/monet5/sql_wlcr.c
--- a/sql/backends/monet5/sql_wlcr.c
+++ b/sql/backends/monet5/sql_wlcr.c
@@ -31,10 +31,12 @@
#define WLCR_REPLAY 1
#define WLCR_CLONE 2
-static str wlcr_master;
-static int wlcr_replaybatches;
+/* TODO actually move these to the WLCRprocess or client record */
+static str wlcr_dbname;
+static str wlcr_dir;
+static int wlcr_firstbatch;
+static int wlcr_lastbatch;;
-static MT_Id wlcr_thread;
/*
static str
@@ -78,50 +80,48 @@ CLONEgetThreshold( Client cntxt, MalBlkP
}
*/
+/*
+ * The log files are identified by a range. It starts with 0 when an empty
+ * database was used to bootstrap. Otherwise it the range of the dbmaster.
+ * At any time we should be able to restart the synchronization
+ * process by grabbing a new set of log files.
+ * This calls for keeping track in the replica what log files have been
applied.
+ * It is stored in a separate directory for two purposes. It allows us to fuse
+ * different masters and even to consider bulk copying the logfiles into a
local
+ * cache structure before applying them.
+ */
static str
-CLONEinit(Client cntxt, MalBlkPtr mb, MalStkPtr stk, InstrPtr pci)
+CLONEinit(str dbname)
{
- int j,k;
+ int i, j,k;
char path[PATHLENGTH];
- str dbname,dir;
+ str dir;
FILE *fd;
-/*
- str msg;
- msg = CLONEgetlogfile(cntxt, mb);
- if( msg)
- return msg;
-*/
- (void) cntxt;
- (void) mb;
-
- dbname = *getArgReference_str(stk,pci,1);
+ wlcr_dbname = GDKstrdup(dbname);
snprintf(path,PATHLENGTH,"..%c%s",DIR_SEP,dbname);
dir = GDKfilepath(0,path,"master",0);
- wlcr_master = GDKstrdup(dir);
-#ifdef _WLCR_DEBUG_
- mnstr_printf(cntxt->fdout,"#WLCR master '%s'\n", wlcr_master);
-#endif
- snprintf(path,PATHLENGTH,"%s%cwlcr", dir, DIR_SEP);
-#ifdef _WLCR_DEBUG_
- mnstr_printf(cntxt->fdout,"#Testing access to master '%s'\n", path);
-#endif
+ wlcr_dir = GDKstrdup(dir);
+ snprintf(path,PATHLENGTH,"%s%c%s_wlcr", dir, DIR_SEP, wlcr_dbname);
fd = fopen(path,"r");
if( fd == NULL){
throw(SQL,"wlcr.init","Can not access master control file
'%s'\n",path);
}
- if( fscanf(fd,"%d", &j) != 1){
+ if( fscanf(fd,"%d %d", &i,&j) != 2){
throw(SQL,"wlcr.init","'%s' does not have proper number of
arguments\n",path);
}
if ( j < 0)
// log capturing stopped at j steps
j = -j;
- wlcr_replaybatches = j;
+ wlcr_firstbatch = i;
+ wlcr_lastbatch = j;
(void)k;
return MAL_SUCCEED;
}
+
+
/*
* Run the clone actions under a new client
* and safe debugging in a tmp file.
@@ -148,7 +148,7 @@ WLCRprocess(void *arg)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list