Changeset: 0bf7c6f035fa for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=0bf7c6f035fa
Modified Files:
        sql/storage/bat/bat_logger.c
Branch: Jun2020
Log Message:

When snapshotting, copy all relevant log files, not just the latest


diffs (88 lines):

diff --git a/sql/storage/bat/bat_logger.c b/sql/storage/bat/bat_logger.c
--- a/sql/storage/bat/bat_logger.c
+++ b/sql/storage/bat/bat_logger.c
@@ -1022,25 +1022,73 @@ end:
 static gdk_return
 snapshot_wal(stream *plan, const char *db_dir)
 {
-       stream *log = bat_logger->log;
-       char log_file[FILENAME_MAX];
+       char meta_file[FILENAME_MAX] = {0};     // ../sql_logs/sql/log
+       char log_file[FILENAME_MAX] = {0};      // ../sql_logs/sql/log.N
+       lng version;
+       lng start_id;
+       lng cur_id;
        int len;
+       int ret;
 
-       len = snprintf(log_file, sizeof(log_file), "%s/%s%s", db_dir, 
bat_logger->dir, LOGFILE);
+       // determine the name of the log file
+       len = snprintf(meta_file, sizeof(meta_file), "%s/%s%s", db_dir, 
bat_logger->dir, LOGFILE);
        if (len == -1 || (size_t)len >= sizeof(log_file)) {
-               GDKerror("Could not open %s, filename is too large", log_file);
+               GDKerror("Could not open log file, filename is too large");
+               return GDK_FAIL;
+       }
+
+       // save its current contents in the plan
+       snapshot_immediate_copy_file(plan, meta_file, meta_file + 
strlen(db_dir) + 1);
+
+       // parse it to determine the first log file to save
+       FILE *f = fopen(meta_file, "r");
+       if (f == NULL) {
+               GDKerror("Could not open %s", meta_file);
+               return GDK_FAIL;
+       }
+       ret = fscanf(f, LLSCN, &version); // dummy read (version number)
+       if (ret != 1) {
+               GDKerror("Could not read version number from %s", meta_file);
+               fclose(f);
                return GDK_FAIL;
        }
-       snapshot_immediate_copy_file(plan, log_file, log_file + strlen(db_dir) 
+ 1);
-
-       len = snprintf(log_file, sizeof(log_file), "%s%s." LLFMT, 
bat_logger->dir, LOGFILE, bat_logger->id);
-       if (len == -1 || (size_t)len >= sizeof(log_file)) {
-               GDKerror("Could not open %s, filename is too large", log_file);
+       assert(version == 52204); // if version has changed this code may need 
to be revised
+       ret = fscanf(f, LLSCN, &start_id); // real read (log id))
+       if (ret != 1) {
+               GDKerror("Could not read log id from %s", meta_file);
+               fclose(f);
                return GDK_FAIL;
        }
-       uint64_t extent = getFileSize(log);
+       fclose(f);
+
+       // Determining the current log file is easy
+       cur_id = bat_logger->id;
+
+       for (lng i = start_id; i <= cur_id; i++) {
+               len = snprintf(log_file, sizeof(log_file),
+                              "%s/%s%s." LLFMT, db_dir, bat_logger->dir, 
LOGFILE, i);
+               if (len == -1 || (size_t)len >= sizeof(log_file)) {
+                       GDKerror("Could not open log file " LLFMT ", filename 
is too large", i);
+                       return GDK_FAIL;
+               }
 
-       snapshot_lazy_copy_file(plan, log_file, extent);
+               uint64_t size;
+               if (i < cur_id) {
+                       // take the whole file
+                       struct stat statbuf;
+                       if (stat(log_file, &statbuf) != 0) {
+                               char errbuf[512];
+                               GDKerror("Could not stat %s: %s", log_file, 
+                                        GDKstrerror(errno, errbuf, 
sizeof(errbuf)));
+                       }
+                       size = (uint64_t)statbuf.st_size;
+               } else {
+                       // It's the current log file, only take the part that
+                       // contains committed data
+                       size = getFileSize(bat_logger->log);
+               }
+               snapshot_lazy_copy_file(plan, log_file + strlen(db_dir) + 1, 
size);
+       }
 
        return GDK_SUCCEED;
 }
_______________________________________________
checkin-list mailing list
checkin-list@monetdb.org
https://www.monetdb.org/mailman/listinfo/checkin-list

Reply via email to