From 8b449b0b79cbc07d06f43333a1b8476b05ffab4d Mon Sep 17 00:00:00 2001 From: "e.martyn" Date: Fri, 6 Sep 2024 11:37:59 +0300 Subject: [PATCH] [sqlitev2] do full 2-wal checkpoint --- internal/sqlitev2/restart.go | 68 ++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 19 deletions(-) diff --git a/internal/sqlitev2/restart.go b/internal/sqlitev2/restart.go index 8290a4d2d..fcae4b745 100644 --- a/internal/sqlitev2/restart.go +++ b/internal/sqlitev2/restart.go @@ -69,41 +69,71 @@ func runRestart(re *restart2.RestartFile, opt Options, log *log.Logger) (err err var commitOffset = re.GetCommitOffset() log.Println("load commit offset", commitOffset) - - err = os.Rename(wals[1].path, wals[1].restartPah) - if err != nil { - return fmt.Errorf("failed to rename second wal to restart path: %w", err) - } - conn, err := newSqliteRWWALConn(opt.Path, opt.APPID, 100, opt.PageSize, opt.StatsOptions, log) if err != nil { return fmt.Errorf("failed to open 1 wal db: %w", err) } - var withoutSecondWalDBOffset int64 + + var fullWalDBOffset int64 isExists := false - rows := conn.queryLocked(context.Background(), query, "__select_binlog_pos_from_1_wal", nil, "SELECT offset from __binlog_offset") + rows := conn.queryLocked(context.Background(), query, "__select_binlog_pos", nil, "SELECT offset from __binlog_offset") for rows.Next() { isExists = true - withoutSecondWalDBOffset = rows.ColumnInteger(0) + fullWalDBOffset = rows.ColumnInteger(0) } if rows.Error() != nil { - return fmt.Errorf("failed to select binlog pos from 1 wal: %w", rows.Error()) + return fmt.Errorf("failed to select binlog pos from 2 wal: %w", rows.Error()) } - log.Println("db offset 1 wal:", withoutSecondWalDBOffset) - - var skipCheckpoint = !isExists || withoutSecondWalDBOffset == 0 - if !skipCheckpoint && withoutSecondWalDBOffset <= commitOffset { - log.Println("do checkpoint to sync 1 wal") - err = conn.conn.Checkpoint() - if err != nil { - return fmt.Errorf("failed to checkpoint 1 wal: %w", err) - } + log.Println("db offset 2 wal:", fullWalDBOffset) + skipCheckpoint := !isExists || fullWalDBOffset == 0 + shouldCheckOneWal := true + if !skipCheckpoint && fullWalDBOffset <= commitOffset { + shouldCheckOneWal = false + log.Println("do checkpoint to sync 1st wal") + // TODO close with checkpoint } err = conn.Close() if err != nil { return fmt.Errorf("failed to close 1 wal conn: %w", err) } + if shouldCheckOneWal { + err = os.Rename(wals[1].path, wals[1].restartPah) + if err != nil { + return fmt.Errorf("failed to rename second wal to restart path: %w", err) + } + + conn, err := newSqliteRWWALConn(opt.Path, opt.APPID, 100, opt.PageSize, opt.StatsOptions, log) + if err != nil { + return fmt.Errorf("failed to open 1 wal db: %w", err) + } + + var withoutSecondWalDBOffset int64 + isExists = false + rows := conn.queryLocked(context.Background(), query, "__select_binlog_pos_from_1_wal", nil, "SELECT offset from __binlog_offset") + for rows.Next() { + isExists = true + withoutSecondWalDBOffset = rows.ColumnInteger(0) + } + if rows.Error() != nil { + return fmt.Errorf("failed to select binlog pos from 1st wal: %w", rows.Error()) + } + log.Println("db offset 1 wal:", withoutSecondWalDBOffset) + + var skipCheckpoint = !isExists || withoutSecondWalDBOffset == 0 + + if !skipCheckpoint && withoutSecondWalDBOffset <= commitOffset { + log.Println("do checkpoint to sync 1 wal") + err = conn.conn.Checkpoint() + if err != nil { + return fmt.Errorf("failed to checkpoint 1 wal: %w", err) + } + } + err = conn.Close() + if err != nil { + return fmt.Errorf("failed to close 1 wal conn: %w", err) + } + } // База консистента, удаляем оба вала // сначала удаляем новый файл, если упадем после этой строки, то при рестарте надо будет просто удалить старый вал