El extraño error mal formado de sqlite3 (1)

El extraño error mal formado de sqlite3 (1)

fenómeno

  • El equipo de campo genera e inserta datos a gran escala y, cuando las anomalías del equipo extraen la base de datos para su inspección, notifican los malformederrores.
  • sqlite3 versión 3.8.6
  • Tamaño del archivo de base de datos 210 MB

Problema de posicionamiento

  • Tamaño de datos

    select count(*) from DataSheet;
    /*结果*/
    950131
    
  • Clave primaria

    primary key(ctype,id,DataTime)
    
  • Recurrencia ( experto en SQLite )

    select * from DataSheet where id='000537719140' order by DataTime;  /*malformed*/
    select * from DataSheet where ctype=5002 and id='000537719140' order by DataTime; /*OK*/
    

    Como se mencionó anteriormente, la única diferencia entre las dos sentencias SQL es si la condición oad está incluida en la cláusula where. ¿Por qué es así? Primero realice la siguiente comparación SQL:

    select * from DataSheet where id='000537719140';  /*OK*/
    select * from DataSheet order by DataTime;     /*malformed, 全表扫描*/
    
    • Cuando hay ctype, identificación, y DataTime en el donde cláusula, el índice (clave principal) es exitosa. En este momento, los índices elegibles se clasifican, por lo que el problema no se repiteorder by DataTime
    • Cuando la cláusula where no coincide exactamente con ctype, id y DataTime , se pierde el índice (clave principal), order by DataTimese ordenan los resultados que cumplen las condiciones y se realiza el escaneo completo de la tabla y el problema se repite
  • Código de prueba: línea de posicionamiento

    char * malformed = "select rowid, ctype, id, StartTime, DataTime from DataSheet;"; /*malformed*/
    char * okayQuery = "select rowid, ctype, id, DataTime from DataSheet;"; /*OK*/
    char * sql = okayQuery;
    sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);
    ncols = sqlite3_column_count(stmt);
    int rowno = 0;
    do {
          
          
        rc = sqlite3_step(stmt);
        switch (rc) {
          
          
        case SQLITE_ROW:	break;
        case SQLITE_DONE:	rowno = -100;	break;
        default:			fprintf(stderr, "rowno = %d, sqlite3 error %d\n", rowno, rc);  break;
        }
        if (rowno >= 0) {
          
           rowno++; }
    }
    while (rowno >= 0);
    sqlite3_finalize(stmt);
    
    • Cuándo sql = okayQuery, consultar un total 950131(rowno:950130)de registros y luego SQLITE_DONEfinalizar
    • Cuándo sql = malformed, 950300informar de un error al obtener el primer registro11 (SQLITE_CORRUPT)
      • Cuando la consulta es normal, solo se pueden recorrer los 950131(rowno:950130)registros
      • Cuando la consulta es anormal, se produjo un error al pasar a 950300(rowno:950301)un registro.
  • Código de prueba: tiempo de posicionamiento

    char * malformed = "select rowid, ctype, id, DataTime, StartTime from DataSheet;";
    char * okayQuery = "select rowid, ctype, id, DataTime from DataSheet;";
    char * sql = malformed;
    sqlite3_prepare_v2(db, sql, strlen(sql), &stmt, NULL);
    ncols = sqlite3_column_count(stmt);
    int rowno = 0;
    do {
          
          
      rc = sqlite3_step(stmt);
      switch (rc) {
          
          
      case SQLITE_ROW:
        if (rowno >= 950129 && rowno <= 950301/* 950300 */) {
          
          
          rowid	 = sqlite3_column_int(stmt, 0);
          ctype  = (char*)sqlite3_column_text(stmt, 1);
          id = (char*)sqlite3_column_text(stmt, 2);
          colltime = (char *)sqlite3_column_text(stmt, 3);
          fprintf(stderr, "rowno: %d, rowid: %i, ctype: %s, id:%s, time:%s\n", rowno, rowid, (ctype?ctype:snull),(id?id:snull), (colltime?colltime:snull));
        }
        break;
      case SQLITE_DONE:	rowno = -100;	break;
      default:			fprintf(stderr, "rowno = %d, sqlite3 error %d\n", rowno, rc);	break;
      }
      if (rowno >= 0) {
          
           rowno++; }
    }
    while (rowno >= 0);
    sqlite3_finalize(stmt);
    

    Salida:

    rowno: 950129, rowid: 4478623, ctype: 5002, id:001548532328, time:20191220105300
    rowno: 950130, rowid: 4478624, ctype: 5002, id:001548532328, time:20191220105400
    ...
    rowno: 950297, rowid: 4478791, ctype: 5002, id:001548532342, time:20191220105800
    rowno: 950298, rowid: 4478792, ctype: 5002, id:001548532342, time:20191220105900
    rowno: 950299, rowid: 4478793, ctype: 5002, id:001548532342, time:20191220110100
    rowno = 950300, sqlite3 error 11
    rowno: 950301, rowid: 3526517, ctype: 5002, id:005410401490, time:20191214202200
    

Iniciar sesión

  • 20191220.log
    #12-20 11:21:30.098: 写入[38] 20191220-111700  ...
    #12-20 11:21:30.433: 写入[39] 20191220-111800  ...
    #12-20 11:21:30.434: 写入[40] 20191220-111900  ...
    

Verifique la base de datos para el día siguiente

  • 2019/12/21 base de datos
  • Tamaño del archivo de la base de datos: 210 MB
    • Mismo tamaño de base de datos
  • Ver menú
    • Okay

análisis

  • La base de datos 2019/12/20 tiene un problema de formato incorrecto, pero la base de datos 2019/12/21 no tiene este problema. Puede ser:
    • Posible motivo 1: la base de datos se ha restaurado automáticamente
      • El ciclo de datos no ha llegado: recuperación automática sin limpieza
      • Sin función de reparación en el dispositivo
    • Posible causa dos: problema de copia de la base de datos
      • La marca de tiempo del registro final: 12-20 11:24:21.057# ...
      • Si primero extrae la base de datos con ftp y luego guarda el registro de shell, cuando extrae la base de datos, es posible que la base de datos esté ejecutando una transacción, lo que causa el problema

En conclusión

  • Cuando ftp extrae la base de datos, la base de datos está ejecutando una transacción de escritura de datos, lo que provoca el problema de formato incorrecto.

Supongo que te gusta

Origin blog.csdn.net/hylaking/article/details/104394677
Recomendado
Clasificación