Как лучше обработать ошибку Sqlite3 CORRUPT (11) в программе на C? - PullRequest
0 голосов
/ 13 сентября 2018

Я видел много статей, касающихся образа диска базы данных Sqlite3: неправильно сформирована проблема в переполнении стека.Но я хотел бы знать, как обработать эту SQLITE_CORRUPT (код ошибки: 11) ошибку в программе на C, когда это происходит во время производственного сервера.

Пример программы

#include <sqlite3.h>
#include <stdio.h>

int insert_records_to_database(sqlite3 *db)
{
   char *err_msg = 0;
   char *sql_in = "INSERT INTO Vehicles VALUES(1, 'maruthi', 5264);"
                "INSERT INTO Vehicles VALUES(2, 'tesla', 5712);"
                "INSERT INTO Vehicles VALUES(3, 'Skoda', 900);"
                "INSERT INTO Vehicles VALUES(4, 'suzuki', 2900);"
                "INSERT INTO Vehicles VALUES(5, 'ferrari', 35000);"
                "INSERT INTO Vehicles VALUES(6, 'Citroen', 2100);"
                "INSERT INTO Vehicles VALUES(7, 'honda', 4140);"
                "INSERT INTO Vehicles VALUES(8, 'fiat', 2160);";

    int rc = sqlite3_exec(db, sql_in, 0, 0, &err_msg);

    if (rc != SQLITE_OK ) {
        if(rc == SQLITE_CORRUPT)
        {
           printf(" SQLITE Database is corrupted :: How to handle");
        }
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);

        return 1;
    }
  return 0;
}
int main(void) {

    sqlite3 *db;
    char *err_msg = 0;

    int rc = sqlite3_open("/root/sqlite3/test.db", &db);
    if (rc != SQLITE_OK) {
        fprintf(stderr, "Cannot open database: %s\n", sqlite3_errmsg(db));
        sqlite3_close(db);
        return 1;
    }

    char *sql = "DROP TABLE IF EXISTS Vehicles;"
                "CREATE TABLE Vehicles(Id INT, Name TEXT, Price INT);" ;

    rc = sqlite3_exec(db, sql, 0, 0, &err_msg);
    if (rc != SQLITE_OK ) {
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);

        return 1;
    }


    insert_records_to_database(db);


    sqlite3_close(db);

    return 0;
}

-> В вышеприведенной программе я выхожу из программы, когда возникает ошибка такого рода.Но все же поврежденный test.db существует и никаких действий с test.db не предпринимается.Предположим, что если я хочу использовать одну и ту же БД для вставки записей, это приведет к тем же ошибкам, что и образ диска, он не может вставить записи.

-> Как обработать этот случайкогда программа постоянно пытается вставить данные в поврежденную базу данных?Есть ли эффективный способ решения этой проблемы.

if (rc == SQLITE_CORRUPT)
{
     printf(" SQLITE Database is corrupted :: How to handle");
}

У меня есть обходные пути:

Удалите test.db (или) Перезапустите программу, как только получитесоздать test.db заново.

Сценарий: Если программа работает в бесконечном цикле, база данных ( test.db ) создается во время запуска программы.После этого, когда программа получает данные из ядра каждые 15 минут и вставляет те же данные в sqlite3 в течение этого времени, если обнаружено повреждение, вставка завершится неудачно.Как эффективно справиться с этим делом?

1 Ответ

0 голосов
/ 14 сентября 2018

Для вашего сценария: Если программа работает в бесконечном цикле, база данных (test.db) создается во время запуска программы.После этого, когда программа получает данные из ядра каждые 15 минут и вставляет те же данные в sqlite3 в течение этого времени, если обнаружено повреждение, вставка завершится неудачно.Как эффективно обработать этот случай?

Создайте свой код следующим образом:

Решение 1:

if (rc != SQLITE_OK ) {
        if(rc == SQLITE_CORRUPT)
        {
           printf(" SQLITE Database is corrupted :: How to handle");
        }
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);

        # Remove the database file
        remove("test.db");
        # Then exit
        exit(EXIT_FAILURE);
    }

В идеале ваше приложение должно создать новый test.db, если файл не't выход.

Решение 2:

Ввести глобальную переменную для непрерывной работы приложения как

    global_variable =0
     while(!global_variable) { 
       }

При возникновении этой ошибки поднимите SIGINT, чтобы корректно завершить работу приложения.,Вам нужен обработчик сигнала для захвата SIGINT, и это остановит ваш процесс.

   if (rc != SQLITE_OK ) {
        if(rc == SQLITE_CORRUPT)
        {
           printf(" SQLITE Database is corrupted :: How to handle");
        }
        fprintf(stderr, "SQL error: %s\n", err_msg);
        sqlite3_free(err_msg);
        sqlite3_close(db);

        # Remove the database file
        remove("test.db");
        # Raise SIGINT
        raise(SIGINT);
    }


# Register SIGINT
 signal(SIGINT, signal_catchfunc);

void signal_catchfunc(int signal) {
   global_variable=1
   printf("!! signal caught !!\n");
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...