Возникнет конфликт с sqlite в то же время(ошибка ввода-вывода на диске sql,блокировка SQLITE_IOERR_LOCK)

#c #sqlite #pthreads #popen

Вопрос:

Я использую рабочую систему linux, а моя версия sqlite3-3.9.2(2015-11-02)

Моя программа будет писать базу данных sql нерегулярно, и мы будем выполнять команду popen каждые 1 минуту для проверки сети

Обычно моя программа работает, но иногда (примерно 1 раз/1~3 дня) возникает ошибка ввода-вывода диска, и я не знаю, почему…

Журнал выглядит следующим образом

 result_buf64 bytes from 8.8.8.8: seq=2 ttl=112 time=10.698 ms

result_buf

result_buf--- 8.8.8.8 ping statistics ---

result_buf3 packets transmitted, 3 packets received, 0% packet loss

------Have External Network Capability-------
SQL error: disk I/O error
Retry SQL error: disk I/O error
Retry SQL error code: 10
Retry SQL error msg: disk I/O error
Error Cause: update config set VALUE=0 where ID=31;
Retry SQL error code detail: 3850
 

Я использую sqlite3_open для открытия БД,и мой код

 int CtrlDB::SqCMD(const char *sql, int retry)
{
    

    //cout << "SQL:[" << sql << "]" << endl;
try {
    /* Execute SQL statement */
    for (int i = 0 ; i < retry ; i  ) {
        char *zErrMsg = NULL;
        const char *ErrMsg = NULL;
        int rc = sqlite3_exec(db, sql, 0, 0, amp;zErrMsg);
        int err = sqlite3_errcode(db);
        ErrMsg = sqlite3_errmsg(db);
        int detailerr = sqlite3_extended_errcode(db); 


        if (rc != SQLITE_OK) {
            fprintf(stderr, "SQL error: %sn", zErrMsg);
            DC_ERROR_NL("Retry SQL error: %s", zErrMsg);
            DC_ERROR_NL("Retry SQL error code: %d", err);
            DC_ERROR_NL("Retry SQL error msg: %s", ErrMsg);
            DC_ERROR_NL("Error Cause: %s", sql);
            DC_ERROR_NL("Retry SQL error code detail: %d", detailerr); 
            if (CharArrayCheck(zErrMsg, "file is encrypted or is not a database") == 1) {
                cout << "bill10" << endl;
                RecoverForCrashDB();
            }
            if(zErrMsg)
                sqlite3_free(zErrMsg);

        } else {
            //fprintf(stdout, "Operation done successfullyn");
            return 0;
        }
        sleep(1);
    }
}
    catch (...) {
        cout << "sql error" << endl;
    }
    CloseDB();
    return 1;
}
 

Но я открываю только 1 базу данных за раз, но я сомневаюсь, что программа выполняет popen в одно и то же время другим потоком.

Я использую popen для выполнения ping-c 3 8.8.8.8 и использую fget для получения buff, будут ли эти команды конфликтовать с записью sql? Или как решить эту проблему(ошибка ввода-вывода диска)?

 char result_buf[100] = { 0 };
    char result_buf2[100] = { 0 };
    char cmd[] = "ping -c 3 8.8.8.8";

    FILE *fp;
if ((fp = popen(cmd, "r")) == NULL)
        {
            cout << "command error6" << endl;
        }
        else {
            while (fgets(result_buf, sizeof(result_buf), fp) != NULL)
            {
                cout << "result_buf" << result_buf << endl;
                if (strstr(result_buf, "packet loss") != NULL) {
                    if (strstr(result_buf, " 100% packet loss") == NULL) {
                        cout << "------Have External Network Capability-------" << endl;

                        break;
                    }
                    else {
                        cout << "------No External Network Capability-------" << endl;


                    }

                }
            }
            pclose(fp);
 

Спасибо за чтение и помощь

Комментарии:

1. Шаг 1: обновление до современной версии sqlite (легко сделать, так как вы используете c )