Меню

Ошибка создания таблицы сообщение от движка базы данных файл бд не открыта

I come to you after a lot of hours googling and reading other discussions about SQLite on StackOverflow, but I definitely can’t find any explanation to my problem, so here it is :

  • The context :
    I’m developping an application for iPad wich has to deal with some «large» amounts of data, in several occasions. In one of them, I must import points coordinates from a .kml file (Google’s xml for geographical data) into my database, in order to reuse them later with a MKMapView and load them faster than by parsing xml when it needs to show a specific layer.

  • The details :
    The import thing is quite easy : when dealing with those files, I’m only concerned with 2 tables :

    • One containing zones definitions and details : for the moment, an integer as an id, and a text for naming.
    • One containing two real for coordinate storage and an integer referencing the first table for knowing which zone point is part of.
      So as long as reading my file, I first create an entry for the new zone, and then I insert points into the second table, with ID of the last zone created in the first table…nothing complicated!

    But…

  • The problem :
    After running fine a while, I get an exception from SQLite with the famous message «Unable to open the database file», and then it comes I can’t do anything more with the database. This exception can randomly occur in the zone creation or the points insertion methods.

  • My reflexions :
    Considering the numerous points in those files, I suspected memory or disk saturation but other parts of my app discarded those points (to my mind).
    First, memory : it comes that when the exception occurs, the app is using about 10 or 12 MB of RAM. It can seems quite huge, but it’s due to the ~10MB .kml file loaded in memory, so it’s explainable. And above it all, the MKMapView thing of my app deals with tons of high-res tiles layers above map, and so leads to memory peaks which can afford 20 or even 25MB without making the iPad to crash.
    Second, disk : when reseting my database and filling only the 2 tables described above, the db file size when the exception occurs is always about 2.2 or 2.5MB, but when I fill other tables (the other parts of my apps works well!) the db file is about 6 or 7MB, and the device doesn’t complain at all.

  • So what?!
    CPU-angryness and panic? I don’t think so because some of the other tables of my database are filled at the same rythm without problem… and running my app in simulator crashes too, with a core i7 just laughing at the job.
    SQLite bad use? There we go! To my mind, it’s the only solution left! But I really can’t understand what’s going on here because I process my requests the same way I do in other app’s parts which — repeating myself — work like a charm!

  • SQLite details :
    I have a DB class which is a singleton I use to avoid creating/releasing an SqliteConnection object each request I do, and all my methods dealing with database are contained in this class to be sure I don’t play with the connection anywhere else without knowing it. Here are concerned methods of this class :

    public void     saveZone(ObjZone zone)  { //at this point, just creates an entry with a name and let sqlite give it a new id
        lock (connection) { //SqliteConnection object
            try {
                openConnection();
                SqliteCommand cmd = connection.CreateCommand();
                cmd.CommandText = zone.id == 0 ?
                    "insert into ZONES (Z_NAME) values (" + format(zone.name) + ") ;" :
                    "update ZONES set Z_NAME = " + format(zone.name) + " where Z_ID = " + format(zone.id) + " ;";
                cmd.ExecuteNonQuery();
                if (zone.id == 0) {
                    cmd.CommandText = "select Z_ID from ZONES where ROWID = last_insert_rowid() ;";
                    zone.id = uint.Parse(cmd.ExecuteScalar().ToString());
                }
                cmd.Dispose();
            }
            catch (Exception e) {
                Log.failure("DB.saveZone(" + zone.ToString() + ") : [" + e.GetType().ToString() + "] - " +
                    e.Message + "n" + e.StackTrace); //custom Console.WriteLine() method with some formating
                throw e;
            }
            finally {
                connection.Close();
            }
        }
    }
    
    public void     setPointsForZone(List<CLLocationCoordinate2D> points, uint zone_id) { //registers points for a given zone
        lock (connection) {
            try {
                openConnection();
                SqliteCommand cmd = connection.CreateCommand();
                cmd.CommandText = "delete from ZONESPOINTS where Z_ID = " + format(zone_id);
                cmd.ExecuteNonQuery();
                foreach(CLLocationCoordinate2D point in points) {
                    cmd.CommandText = "insert into ZONESPOINTS values " +
                        "(" + format(zi_id) + ", " + format(point.Latitude.ToString().Replace(",", ".")) + ", "
                        + format(point.Longitude.ToString().Replace(",", ".")) + ");";
                    cmd.ExecuteNonQuery();
                    cmd.Dispose();
                }
            }
            catch (Exception e) {
                Log.failure("DB.setPointsForZone(" + zone_id + ") : [" + e.GetType().ToString() + "] - " + e.Message);  
                throw e;
            }
            finally {
                connection.Close();
            }
        }
    }
    

    And to be as clear as I can, here are some of the methods referenced in the two above (I use this custom openConnection() method because I use foreign keys constraints in most of my tables and cascading behaviours are not enabled by default, but I need them.) :

    void openConnection() {
        try {
            connection.Open();
            SqliteCommand cmd = connection.CreateCommand();
            cmd.CommandText = "PRAGMA foreign_keys = ON";
            cmd.ExecuteNonQuery();
            cmd.Dispose();
        }
        catch (Exception e) {
            Log.failure("DB.openConnection() : [" + e.GetType().ToString() + "] - " + e.Message);
            throw e;
        }
    }
    
    public static string format(object o) {
        return "'" + o.ToString().Replace("'", "''") + "'";
    }
    

Well, sorry for the novel, I may already thank you for reading all that stuff, no?! Anyway, if I missed something that could be useful, let me know and I’ll document it as soon as possible.
I hope someone will be able to help me, anyway, thank you by advance!
(And my apologies for my poor frenchie’s english.)

EDIT
My problem is «solved»! After a few changes for debugging pourposes, no big modifications, and no success, I put back the code in the state I posted it… and now it works. But I really would appreciate if some someone could give me an explanation of what may have happened! It seems like SQLite behaviour (on iPad at least — never used it anywhere else) can be quite obscure at some times… :/

I come to you after a lot of hours googling and reading other discussions about SQLite on StackOverflow, but I definitely can’t find any explanation to my problem, so here it is :

  • The context :
    I’m developping an application for iPad wich has to deal with some «large» amounts of data, in several occasions. In one of them, I must import points coordinates from a .kml file (Google’s xml for geographical data) into my database, in order to reuse them later with a MKMapView and load them faster than by parsing xml when it needs to show a specific layer.

  • The details :
    The import thing is quite easy : when dealing with those files, I’m only concerned with 2 tables :

    • One containing zones definitions and details : for the moment, an integer as an id, and a text for naming.
    • One containing two real for coordinate storage and an integer referencing the first table for knowing which zone point is part of.
      So as long as reading my file, I first create an entry for the new zone, and then I insert points into the second table, with ID of the last zone created in the first table…nothing complicated!

    But…

  • The problem :
    After running fine a while, I get an exception from SQLite with the famous message «Unable to open the database file», and then it comes I can’t do anything more with the database. This exception can randomly occur in the zone creation or the points insertion methods.

  • My reflexions :
    Considering the numerous points in those files, I suspected memory or disk saturation but other parts of my app discarded those points (to my mind).
    First, memory : it comes that when the exception occurs, the app is using about 10 or 12 MB of RAM. It can seems quite huge, but it’s due to the ~10MB .kml file loaded in memory, so it’s explainable. And above it all, the MKMapView thing of my app deals with tons of high-res tiles layers above map, and so leads to memory peaks which can afford 20 or even 25MB without making the iPad to crash.
    Second, disk : when reseting my database and filling only the 2 tables described above, the db file size when the exception occurs is always about 2.2 or 2.5MB, but when I fill other tables (the other parts of my apps works well!) the db file is about 6 or 7MB, and the device doesn’t complain at all.

  • So what?!
    CPU-angryness and panic? I don’t think so because some of the other tables of my database are filled at the same rythm without problem… and running my app in simulator crashes too, with a core i7 just laughing at the job.
    SQLite bad use? There we go! To my mind, it’s the only solution left! But I really can’t understand what’s going on here because I process my requests the same way I do in other app’s parts which — repeating myself — work like a charm!

  • SQLite details :
    I have a DB class which is a singleton I use to avoid creating/releasing an SqliteConnection object each request I do, and all my methods dealing with database are contained in this class to be sure I don’t play with the connection anywhere else without knowing it. Here are concerned methods of this class :

    public void     saveZone(ObjZone zone)  { //at this point, just creates an entry with a name and let sqlite give it a new id
        lock (connection) { //SqliteConnection object
            try {
                openConnection();
                SqliteCommand cmd = connection.CreateCommand();
                cmd.CommandText = zone.id == 0 ?
                    "insert into ZONES (Z_NAME) values (" + format(zone.name) + ") ;" :
                    "update ZONES set Z_NAME = " + format(zone.name) + " where Z_ID = " + format(zone.id) + " ;";
                cmd.ExecuteNonQuery();
                if (zone.id == 0) {
                    cmd.CommandText = "select Z_ID from ZONES where ROWID = last_insert_rowid() ;";
                    zone.id = uint.Parse(cmd.ExecuteScalar().ToString());
                }
                cmd.Dispose();
            }
            catch (Exception e) {
                Log.failure("DB.saveZone(" + zone.ToString() + ") : [" + e.GetType().ToString() + "] - " +
                    e.Message + "n" + e.StackTrace); //custom Console.WriteLine() method with some formating
                throw e;
            }
            finally {
                connection.Close();
            }
        }
    }
    
    public void     setPointsForZone(List<CLLocationCoordinate2D> points, uint zone_id) { //registers points for a given zone
        lock (connection) {
            try {
                openConnection();
                SqliteCommand cmd = connection.CreateCommand();
                cmd.CommandText = "delete from ZONESPOINTS where Z_ID = " + format(zone_id);
                cmd.ExecuteNonQuery();
                foreach(CLLocationCoordinate2D point in points) {
                    cmd.CommandText = "insert into ZONESPOINTS values " +
                        "(" + format(zi_id) + ", " + format(point.Latitude.ToString().Replace(",", ".")) + ", "
                        + format(point.Longitude.ToString().Replace(",", ".")) + ");";
                    cmd.ExecuteNonQuery();
                    cmd.Dispose();
                }
            }
            catch (Exception e) {
                Log.failure("DB.setPointsForZone(" + zone_id + ") : [" + e.GetType().ToString() + "] - " + e.Message);  
                throw e;
            }
            finally {
                connection.Close();
            }
        }
    }
    

    And to be as clear as I can, here are some of the methods referenced in the two above (I use this custom openConnection() method because I use foreign keys constraints in most of my tables and cascading behaviours are not enabled by default, but I need them.) :

    void openConnection() {
        try {
            connection.Open();
            SqliteCommand cmd = connection.CreateCommand();
            cmd.CommandText = "PRAGMA foreign_keys = ON";
            cmd.ExecuteNonQuery();
            cmd.Dispose();
        }
        catch (Exception e) {
            Log.failure("DB.openConnection() : [" + e.GetType().ToString() + "] - " + e.Message);
            throw e;
        }
    }
    
    public static string format(object o) {
        return "'" + o.ToString().Replace("'", "''") + "'";
    }
    

Well, sorry for the novel, I may already thank you for reading all that stuff, no?! Anyway, if I missed something that could be useful, let me know and I’ll document it as soon as possible.
I hope someone will be able to help me, anyway, thank you by advance!
(And my apologies for my poor frenchie’s english.)

EDIT
My problem is «solved»! After a few changes for debugging pourposes, no big modifications, and no success, I put back the code in the state I posted it… and now it works. But I really would appreciate if some someone could give me an explanation of what may have happened! It seems like SQLite behaviour (on iPad at least — never used it anywhere else) can be quite obscure at some times… :/

  • Remove From My Forums
  • Вопрос

  • Здравствуйте.

    После обновления с Access 2013 на Access 2016 перестали заботать запросы, создающие новые таблицы (Select * Into T1 from T2). Причем не работают только те запросы, где число записей в исходной таблице больше какого-то значения. То есть, если в исходной
    таблице 170 записей — все работает, а если 12000 — выдает ошибку. Такая же ошибка выдается при создании копии таблиц в нтерфейсе (Копировать — Вставить), и точно также ошибка связана с числом записей. Все делаю в пределах одной базы данных. Текст ошибки:»Не
    удается открыть базу данных «». Возможно формат этой базы данных не распознается приложением либо файл поврежден.
    «

    А при загрузки из екселовского файла в новую таблицу пишет: «Ключ поиска не найден ни в одной записи» и импорт не делает! Причем, таблицу в 9990 записей НЕ загрузил, а после удаления в екселе записей до 3000 — все загрузил
    нормально!

    Подскажите, как это исправить. 

    • Изменено

      12 января 2016 г. 12:04

ispravlyaem-oshibki-mysqlЗдравствуйте!

Сегодняшняя заметка будет касаться только достаточно «узкой» категории читателей блога — речь пойдет о базах данных MySQL (и ошибках, при работе с ними…).

Вообще, подобные базы данных используются многими движками сайтов (CMS), причем некоторые из них не блещут высокой безопасностью… Кроме этого, к базе MySQL возможен прямой доступ через веб-интерфейс. А если добавить к этому ошибки при копировании и переносе БД (что бывает очень часто), то, разумеется, всё это вкупе создает определенные риски для данных… 😢

Собственно, ниже рассмотрим, что можно сделать, если появилась-таки ошибка, что база данных недоступна (или не может быть прочитана, или…). Заранее скажу, что подобные ошибки далеко не всегда означает полную утрату БД, во многих случаях удается сравнительно-легко восстановить работоспособность сайта (интернет-магазина, и пр.).

И так…

*

Несколько рекомендаций, если возникла ошибка с MySQL БД

👉 Совет 1

Если вы накануне никак не взаимодействовали с БД (например, не переносили сайт с одного сервера на другой), и всё работало в штатном режиме — возможно, что ошибка недоступности к базе связана с возникшими проблемами на стороне хостинг-компании (⇒ запрос в поддержку…).

Кроме этого, обратите внимание на конфигурационные файлы CMS, отвечающие за доступ к базе данных. Возможно, что с самой БД всё в порядке, а вот путь (или пароль) для доступа к ней указан некорректно…

Например, в такой популярной CMS как WordPress, файлом для настройки доступа к БД явл. wp-config.php.

Параметры MySql — эту информацию можно получить у хостинг-провайдера

Параметры MySQL — эту информацию можно получить у хостинг-провайдера

*

👉 Совет 2

Еще одна довольно очевидная рекомендация — проверить наличие бэкапа (резервной копии). Даже если вы самостоятельно не делали его — возможно его сделал хостинг-провайдер.

Кроме этого, как только возникла какая-то ошибка с БД — я бы порекомендовал в любом случае сделать ее копию (если это возможно). Вдруг диск начал «сыпаться», и в дальнейшем даже текущая БД исчезнет «на совсем»…

PHP My Admin — экспорт базы данных

PHP My Admin — экспорт базы данных

*

👉 Совет 3

Далее следует попробовать провести восстановление БД встроенными средствами MySQL…

Итак, что нужно сделать в случае, если БД MySQL перестала запускаться: 

  1. Откройте файл my.cnf и установите следующий параметр: innodb_force_recovery = 1; 
  2. Перезапустите MySQL следующей командой: /etc/init.d/mysql restart; 
  3. Сделайте дамп БД и запакуйте его: mysqldump db | gzip > db.sql.gz; 
  4. Создайте новую БДmysql -e create database new_DB«; 
  5. Импортируйте туда данныеzcat database.sql.gz | mysql new_DB. 

***

👉 Примечание!

my.cnf — это файл конфигурации MySQL. Чтобы найти файл, используйте команду: locate my.cnf

В Linux’e обычно он находится по такому пути:

/etc/my.cnf
# либо
/etc/mysql/my.cnf

***

Перезапуск MySQL подобным образом не ведет к запуску всех связанных процессов и в некоторых случаях позволяет открыть старую БД. 

С помощью указанных команд мы пробуем создать дамп БД, затем импортировать его в новую базу, которую далее можно будет открыть обычным способом. 

Если это получается, старую БД можно удалить. Кстати, если способ не помогает, и старая база не запускается, нужно пробовать другие значения параметра innodb_force_recovery, вплоть до 6. 

MySQL

MySQL

При нормальном запуске БД система пытается запустить все процессы, включая и те, которые были завершены аварийно (например, из-за проблем с электричеством).

Благодаря опции innodb_force_recovery можно отключить некоторые параметры, которые мешают штатному запуску БД.

Цифры означают следующее: 

  1. Запуск MySQL не останавливается, даже если система в процессе запуска обнаруживает поврежденные страницы;
  2. Отмена запуска фоновых операций;
  3. Отмена попыток отката транзакций;
  4. Отказ от расчета статистики и использования сохраненных изменений;
  5. Не учитывает логи отката при запуске;
  6. Не учитывает параметры ib_logfiles во время запуска.

*

👉 Совет 4 (альтернативный способ восстановления БД)

Описанный выше способ довольно эффективен, хотя, к сожалению, может оказаться сложным для некоторых пользователей. Но работа с любым форматом базы данных — это всегда непросто…

Если нет желания редактировать конфиги, открывать командную строку и изучать синтаксис нужных команд, то нужен достаточно простой и дружелюбный в использовании инструмент, например, такой как Recovery Toolbox for MySQL. (👇)

Recovery Toolbox for MySQL — скриншот главного окна программы

Recovery Toolbox for MySQL — скриншот главного окна программы

Пожалуй, это самый простой и эффективный способ восстановления БД MySQL, именно то, что нужно большинству начинающих пользователей. 👌

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

Стоит сразу отметить, что Recovery Toolbox for MySQL работает только с копией базы, поэтому никогда не испортит то, что осталось от старой БД. Почувствуйте разницу, копаясь в конфигах и настройках «боевого» сервера, и каждую минуту опасаясь сделать что-то неправильно, что приведет к полному уничтожению того, что еще осталось…

*

👉 Как восстановить базу с помощью Recovery Toolbox for MySQL:

Для восстановления поврежденной БД MySQL при помощи этой программы нужно сделать следующее:

  1. Скачать Recovery Toolbox for MySQL с офиц. сайта: https://mysql.recoverytoolbox.com/ru/;
  2. Установить и запустить программу;
  3. Выбрать папку, в которой хранятся файлы поврежденной базы данных MySQL (предварительно создайте копию);
  4. Выбрать поврежденную базу данных из списка
  5. Запустить анализ выбранной БД;
  6. Просмотреть результаты восстановления: таблицы, объекты, индексы;
  7. Настроить способ сохранения восстановленных данных;
  8. Сохранить данные (доступно в полной версии). Пример на скриншоте ниже. 👇

Пример восстановления БД

Пример восстановления БД

Программа загружается совершенно бесплатно и устанавливается без регистрации. С помощью Recovery Toolbox for MySQL можно бесплатно просматривать восстановленные данные, оценивать эффективность работы.

Можно даже подсмотреть какие-то изменения и легко внести их руками в «протухший», но еще пригодный к использованию бэкап. Заплатить предложат только в том случае, если потребуется сохранить восстановленные данные, пересоздать базу MySQL и подключить ее к системе.

База восстановлена - сохранить?

База восстановлена — сохранить?

*

👉 «Пару слов» о безопасности при работе с Recovery Toolbox for MySQL

Самое главное – программа всегда работает только с копией исходной базы, поэтому этот способ восстановления намного надежнее, чем вносить изменения в конфиги БД и смотреть, что из этого получится. Помните, попытка ремонта БД на «продакшн» сервере может окончательно добить ее, такое бывает даже у опытных админов…

Также стоит отметить, что Recovery Toolbox for MySQL не использует сторонние подключения. В процессе восстановления (может занять довольно продолжительное время, в зависимости от размеров исходной базы данных) ПО не использует доступ к Интернет.

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

Есть способ чуть сложнее: установить анализатор сетевого траффика (советую WireShark, NetLimiter) и проверить, не идут ли подозрительные пакеты от Recovery Toolbox for MySQL.

👉 В помощь!

Как запретить программе доступ к интернету (блокировка входящего/исходящего трафика)

Конечно, этот способ предполагает некий здоровый энтузиазм, желание познать новое (мануалы на WireShark совсем немаленькие) и, самое главное, наличие свободного времени…

*

Дополнения по теме — не помешают!

Всем успехов!

👋

Пост по заметкам

от компании Recovery Toolbox

donate

dzen-ya

Полезный софт:

  • видеомонтаж
  • Видео-Монтаж
  • Отличное ПО для создания своих первых видеороликов (все действия идут по шагам!).
    Видео сделает даже новичок!

  • утилита для оптимизации
  • Ускоритель компьютера
  • Программа для очистки Windows от «мусора» (удаляет временные файлы, ускоряет систему, оптимизирует реестр).

Показывать по
10
20
40
сообщений

Новая тема

Ответить

SVGS

Дата регистрации: 23.12.2010
Сообщений: 276

— вылетает после этого сообщения.<br>Ошибка возникает при восстановлении из архива.<br>На другом компе архив раскрывается и работает абсолютно нормально…<br>Что делать?

DMLangepas Кудрявцев

Дата регистрации: 25.04.2012
Сообщений: 149

почистить КЭШи.<br>переустановить платформу.<br>создать пустую конфу для восстановления.

SVGS

Дата регистрации: 23.12.2010
Сообщений: 276

> переустановить платформу.<br>Это делал. Не помогает.<br><br>> создать пустую конфу для восстановления.<br>Это делал — с пустой конфой всё ОК — как только делаем операцию<br>»Загрузить информационную базу» из архива, так снова упираемся в эту проблему…<br> <br>> почистить КЭШи.<br>Этого не делал — просто не знаю, где и как это делается ((<br>Подскажите, если не трудно…

SVGS

Дата регистрации: 23.12.2010
Сообщений: 276

«Погуглил — справился ))<br> <br>Помогла следующая последовательность операций:<br>1) создание пустой базы;<br>2) чистка кэша;<br>3) загрузка рабочей базы.<br> <br>Причины такого поведения файловой базы — тайна за семью печатями! )))»

Денис (САМАРА)

Дата регистрации: 09.04.2008
Сообщений: 8351

«> Причины такого поведения файловой базы — тайна за семью печатями!<br> <br>Кэш «грязный», а не «тайна за 7you печатями» ;)»

Показывать по
10
20
40
сообщений

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии

А вот еще интересные материалы:

  • Яшка сломя голову остановился исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного исправьте ошибки
  • Ясность цели позволяет целеустремленно добиваться намеченного где ошибка
  • Ошибка составной части cinema 4d
  • Ошибка сохранения сообщения 0x80004005 криптоарм что делать