SQLite

Check-in [660a035b6c]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Do not allow sqlite3_rsync to convert the replica from WAL-mode into DELETE-mode, as that can disrupt existing clients on the replica side. DELETE-mode to WAL-mode conversions are allowed, however. See forum thread 6b575b66156.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | trunk
Files: files | file ages | folders
SHA3-256: 660a035b6ce6684d429b882133e032181cc1664f4efadf1bc0e4ae27d45071c4
User & Date: drh 2025-05-02 11:18:09.023
Context
2025-05-02
11:18
Do not allow sqlite3_rsync to convert the replica from WAL-mode into DELETE-mode, as that can disrupt existing clients on the replica side. DELETE-mode to WAL-mode conversions are allowed, however. See forum thread 6b575b66156. (Leaf check-in: 660a035b6c user: drh tags: trunk)
2025-05-01
18:07
Enhance sqlite3_rsync so that, by default, it will sync non-WAL-mode database files. Add a new command-line option --wal-only that restricts the sync to WAL-mode databases only (the former default). Improve command-line option parsing so that only a single "-" is required before each option. (check-in: 4b53603fe4 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to tool/sqlite3_rsync.c.
1389
1390
1391
1392
1393
1394
1395

1396
1397
1398
1399
1400
1401
1402
**
**         Expect no more transmissions from the origin.
*/
static void replicaSide(SQLiteRsync *p){
  int c;
  sqlite3_stmt *pIns = 0;
  unsigned int szOPage = 0;

  char buf[65536];

  p->isReplica = 1;
  if( p->bCommCheck ){
    infoMsg(p, "replica zOrigin=%Q zReplica=%Q isRemote=%d protocol=%d",
               p->zOrigin, p->zReplica, p->isRemote, PROTOCOL_VERSION);
    writeByte(p, REPLICA_END);







>







1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
**
**         Expect no more transmissions from the origin.
*/
static void replicaSide(SQLiteRsync *p){
  int c;
  sqlite3_stmt *pIns = 0;
  unsigned int szOPage = 0;
  char eJMode = 0;               /* Journal mode prior to sync */
  char buf[65536];

  p->isReplica = 1;
  if( p->bCommCheck ){
    infoMsg(p, "replica zOrigin=%Q zReplica=%Q isRemote=%d protocol=%d",
               p->zOrigin, p->zReplica, p->isRemote, PROTOCOL_VERSION);
    writeByte(p, REPLICA_END);
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472

1473
1474
1475



1476
1477
1478
1479
1480
1481
1482
        }
        hashRegister(p->db);
        if( runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count") ){
          break;
        }
        if( nRPage==0 ){
          runSql(p, "PRAGMA replica.page_size=%u", szOPage);
          runSql(p, "PRAGMA replica.journal_mode=WAL");
          runSql(p, "SELECT * FROM replica.sqlite_schema");
        }
        runSql(p, "BEGIN IMMEDIATE");
        if( p->bWalOnly ){
          runSqlReturnText(p, buf, "PRAGMA replica.journal_mode");
          if( strcmp(buf, "wal")!=0 ){

            reportError(p, "replica is not in WAL mode");
            break;
          }



        }
        runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count");
        runSqlReturnUInt(p, &szRPage, "PRAGMA replica.page_size");
        if( szRPage!=szOPage ){
          reportError(p, "page size mismatch; origin is %d bytes and "
                         "replica is %d bytes", szOPage, szRPage);
          break;







<



<
|
|
>



>
>
>







1460
1461
1462
1463
1464
1465
1466

1467
1468
1469

1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
        }
        hashRegister(p->db);
        if( runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count") ){
          break;
        }
        if( nRPage==0 ){
          runSql(p, "PRAGMA replica.page_size=%u", szOPage);

          runSql(p, "SELECT * FROM replica.sqlite_schema");
        }
        runSql(p, "BEGIN IMMEDIATE");

        runSqlReturnText(p, buf, "PRAGMA replica.journal_mode");
        if( strcmp(buf, "wal")!=0 ){
          if( p->bWalOnly && nRPage>0 ){
            reportError(p, "replica is not in WAL mode");
            break;
          }
          eJMode = 1;      /* Non-WAL mode prior to sync */
        }else{
          eJMode = 2;      /* WAL-mode prior to sync */
        }
        runSqlReturnUInt(p, &nRPage, "PRAGMA replica.page_count");
        runSqlReturnUInt(p, &szRPage, "PRAGMA replica.page_size");
        if( szRPage!=szOPage ){
          reportError(p, "page size mismatch; origin is %d bytes and "
                         "replica is %d bytes", szOPage, szRPage);
          break;
1533
1534
1535
1536
1537
1538
1539





1540
1541
1542
1543
1544
1545
1546
          pIns = prepareStmt(p,
            "INSERT INTO sqlite_dbpage(pgno,data,schema)VALUES(?1,?2,'replica')"
          );
          if( pIns==0 ) break;
        }
        readBytes(p, szOPage, buf);
        if( p->nErr ) break;





        p->nPageSent++;
        sqlite3_bind_int64(pIns, 1, pgno);
        sqlite3_bind_blob(pIns, 2, buf, szOPage, SQLITE_STATIC);
        rc = sqlite3_step(pIns);
        if( rc!=SQLITE_DONE ){
          reportError(p, "SQL statement [%s] failed (pgno=%u): %s",
                 sqlite3_sql(pIns), pgno, sqlite3_errmsg(p->db));







>
>
>
>
>







1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
          pIns = prepareStmt(p,
            "INSERT INTO sqlite_dbpage(pgno,data,schema)VALUES(?1,?2,'replica')"
          );
          if( pIns==0 ) break;
        }
        readBytes(p, szOPage, buf);
        if( p->nErr ) break;
        if( pgno==1 &&  eJMode==2 && buf[18]==1 ){
          /* Do not switch the replica out of WAL mode if it started in 
          ** WAL mode */
          buf[18] = buf[19] = 2;
        }
        p->nPageSent++;
        sqlite3_bind_int64(pIns, 1, pgno);
        sqlite3_bind_blob(pIns, 2, buf, szOPage, SQLITE_STATIC);
        rc = sqlite3_step(pIns);
        if( rc!=SQLITE_DONE ){
          reportError(p, "SQL statement [%s] failed (pgno=%u): %s",
                 sqlite3_sql(pIns), pgno, sqlite3_errmsg(p->db));