Промучавшись в очередной раз над восстановлением побившейся базы, решил набросать краткую инструкцию, как мне удалось вернуть почти всю историю сообщений скайпа. Знатоки sqlite3 приглашаются для написания более лучших способов, чем я нащупал наугад.
Предыстория
Переустановил ОС Win7, установил skype (6-й), привычно скопировал всю папку профиля из старого:
%AppData%RoamingSkypeмой_профиль
в новое место.
Запускаю скайп и вдруг он виснет на автовходе. После повторного запуска вижу приглашение войти. Вхожу — все контакты на месте, а сообщений — практически нигде нет. Только в некоторых групповых чатах сохранились. Вся личная переписка, коей скопилось немало — исчезла. Проделал N(^k) попыток копировать базу данных, удаляя файлы блокировок, is-corrupt и прочие. Скайп ругается, что с базой проблемы, затем просит перезайти — после чего сообщений нет.
Погуглив, нашел хабро-посты про экспорт сообщений, угон аккаунтов и т.п. Ага, значит sqlite! Это обнадёживает.
- уцелевшая копия базы main.db до того, как её «открыл» новый скайп, начисто затерев данные (или возьмите файл main.corrupt, если копии не оказалось)
- SQLite Manager
- sqlite3 command line (оптимально — работать в ней под *nix)
- Notepad++ или любой другой редактор, который не гробит UTF-8 файлы.
- *nix shell (какой-нибудь сервер с linux/ubuntu/..., т.к. самый важный последний шаг под виндоуз может не сработать)
Анализируем базу
2. Открываем файл main.db (около 150 мегабайт у меня).
3. База данных — Проверка целостности — Полная проверка.
Проверка целостности базы данных с помощью «PRAGMA integrity_check».
Результат: НЕ УСПЕШНО. Чтобы увидеть ошибки, выполните оператор «PRAGMA integrity_check» во вкладке «Выполнить запрос».
4. Выполняю указанную команду, получаю много страшных буков:
"*** in database main ***
On tree page 5482 cell 13: Rowid 262638 out of order (max larger than parent max of 255232)
On tree page 22553 cell 8: Rowid 255233 out of order (min less than parent min of 262638)
On tree page 5601 cell 10: Rowid 270500 out of order (max larger than parent max of 255358)
On tree page 9610 cell 10: Rowid 255359 out of order (min less than parent min of 270500)
On tree page 25320 cell 145: 2nd reference to page 5482
On tree page 25320 cell 145: Child page depth differs
On tree page 25320 cell 146: Child page depth differs
On tree page 25827 cell 290: 2nd reference to page 5601
On tree page 25827 cell 290: Child page depth differs
On tree page 25827 cell 291: Child page depth differs
On tree page 8955 cell 0: 2nd reference to page 28154
On tree page 27843 cell 0: 2nd reference to page 28136
Page 5335 is never used
Page 5344 is never used
Page 5369 is never used
… тут много таких is never used
Page 28212 is never used"
«wrong # of entries in index IX_Messages_remote_id»
«wrong # of entries in index IX_Messages_timestamp_convo_id_type»
«wrong # of entries in index IX_Messages_timestamp_chatname»
«wrong # of entries in index IX_Messages_call_guid»
«wrong # of entries in index IX_Messages_convo_id_timestamp_consumption_status_sending_status»
«rowid 95101 missing from index IX_Contacts_buddystatus»
«rowid 103110 missing from index IX_Contacts_buddystatus»
«rowid 209626 missing from index IX_Contacts_buddystatus»
Кстати, в других утилитах при попытке просмотреть таблицы сообщений, часто получал такое: "the database disk image is malformed".
Поскольку я не знаток sqlite и не горю желанием изучать каждую ошибку, поступаем просто.
Лечение
Гуглим как дампить базы sqlite, получается примерно так:
1. Скачать sqlite3 command line для Windows или «apt-get install sqlite3» для *nix. Я сначала экспериментировал под виндой, но впоследствии пришлось перейти в консоль Linux, т.к. виндовая sqlite3 не совсем хорошо себя показала.
2. Под Windows копируем sqlite3.exe в папку с копией базы (архивной с предыдущей винды, которую ещё не испортил скайп). Затем запускаем cmd (Пуск > выполнить).
Под линуксом — просто выполняем:
cd путь-к-папке-с-базой-и-sqlite3.exe
sqlite3 main.db .dump>>myDumpSQLite.sql
(Именно «main.db[пробел].dump, не перепутайте)
3. Открываем файл myDumpSQLite.sql в нормальном текстовом редакторе, например Notepad++. В самом конце файла у меня стояла команда:
ROLLBACK;
Кто знаком с SQL, знает зачем нужно удалить эту последнюю строку в файле и вместо неё написать:
COMMIT;
(Можно и вовсе отказаться от транзакции, но тогда будет очень долгий импорт данных в новую базу.)
4. Создаём новую, чистую базу из файла myDumpSQLite.sql (рекомендуется под Linux).
sqlite3 main-recovered.db <myDumpSQLite.sql
Error: near line 329619: PRIMARY KEY must be unique
Error: near line 329620: PRIMARY KEY must be unique
Error: near line 329621: PRIMARY KEY must be unique
Error: near line 329622: PRIMARY KEY must be unique
... ещё пару десятков таких сообщений
Благодаря тому, что мы сделали COMMIT в конце файла — ошибки будут проигнорированы. Теоретически, что-то потеряется (какие-то одиночные сообщения, может даже какой-то чат пропадёт). Но это ничто по сравнению с потерей всей базы, которую предлагает Microsoft.
Полученный файл main-recovered.db должен весить примерно столько же, сколько и sql-файл (у меня получилось 123Мб). Если пропустить шаг 3 или что-то пойдёт не так — получите пустой бесполезный файл.
Error: incomplete SQL: INSERT INTO „Contacts“ VALUES(951.......
5. Копируем полученный файл в папку %AppData%RoamingSkypeмой_профиль под именем main.db, заменяя поломавшуюся (Skype должен быть выключен).
6. Запускаем Skype. Вводим логин и пароль (у меня автоматом зашло).
7. PROFIT!!! Все сообщения вернулись!
Автор: KIVagant