SQLinfo.ru - Все о MySQL Webew.ru: теория и практика веб-технологий

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 24.03.2011 15:55:48

creo.ev
Участник
Зарегистрирован: 24.03.2011
Сообщений: 5

Восстановление таблицы.

Здравствуйте, возникла проблема с восстановление таблицы.
Что имею от таблицы:
jobs.MYD
jobs.MYI
и 3 варианта структуры таблицы (файл *.frm утерян):
1.

CREATE TABLE `jobs` (
  `id` int unsigned NOT NULL auto_increment,
  `query` char(100) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM;

2.
CREATE TABLE `jobs` (
  `id` int unsigned NOT NULL auto_increment,
  `query` char(100) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE (`query`)
) ENGINE=MyISAM;

3.
CREATE TABLE `jobs` (
  `id` int unsigned NOT NULL auto_increment,
  `query` char(100) NOT NULL,
  `status` tinyint(1) unsigned NOT NULL default 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`query`),
  INDEX (`status`)
) ENGINE=MyISAM;

Табличка очень тяжёлая:
jobs.MYD - 510G
jobs.MYI - 62G
На данный момент свободного места: 106G , то есть места мало, датацент отказывается добавить дополнительный диск.
Почитав мануалы по myisamchk попробовал выполнить "экономичное восстановление",
Создал таблицу с структурой номер 3 (так как эта структура наиболее вероятна), скопировал jobs.MYI и jobs.frm файлы в отдельный каталог, туда же поместил файл jobs.MYD
запустил в бэкграунд myisamchk:

myisamchk -r -q --sort_buffer_size=3072M --key_buffer_size=3072M --read_buffer_size=64M --write_buffer_size=64M jobs.MYI > log.txt &

На следующий день процесс завершился jobs.MYI - 31G, а в файле log.txt:

- check record delete-chain
- recovering (with sort) MyISAM-table '/root/dump/jobs.MYI'
Data records: 0
- Fixing index 1
- Fixing index 2
- Fixing index 3

Таблица всё ещё не работает, это и понятно, так как - Data records: 0.
Пробовал так же 1 и 2 структуры, в log.txt снова Data records: 0

Нужна квалифицированная помощь, чтобы не запортить файл jobs.MYD так как он в единственном экземпляре, а создать дамп в 510G не позволяет дисковое пространство.

Отредактированно creo.ev (24.03.2011 15:57:44)

Неактивен

 

#2 24.03.2011 19:54:43

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Восстановление таблицы.

По сути, у Вас есть только MYD и предполагаемая структура?

Кажется, самый простой способ — восстанавливать таблицу под
пользователем, который не может писать в файл MYD (только
читать +писать MYI). Создаете соответствующий frm и пытаетесь
восстановить индекс под этим пользователем.

Можете, например, посмотреть глазами на содержимое MYD —
Вам надо угадать, есть ли столбец status или нет. Скорее всего,
в файлике будет что-то такое:
1. Заголовок
2. 4 байта id (01 00 00 00)
3. 100 байт строки (если format=fixed или 1 байт длины + данные строки
в случае format=dynamic)
4. байт статуса (скорее всего, ноль).

Можете создать две fake-таблички с разными структурами и сравнить данные,
чтобы не ждать восстановления. Индексы значения не имеют. После того, как
определитесь со структурой, делаете большой myisamchk и надеетесь, что
оно отработает. Лучше в screen. Обычный & не спасает от SIGHUP, например.

Неактивен

 

#3 25.03.2011 12:57:36

creo.ev
Участник
Зарегистрирован: 24.03.2011
Сообщений: 5

Re: Восстановление таблицы.

paulus, да вы правы, по сути только MYD и структура.
Создал все возможные структуры, сделал по 5 тестовых записей, и посмотрел MYD файлы, сравнил с исходным MYD, пришёл к выводу что поле status присутствует.
То есть структура таблицы теперь определилась (большое спасибо paulus за идею просмотреть файлы big_smile ):

CREATE TABLE `jobs` (
  `id` int unsigned NOT NULL auto_increment,
  `query` char(100) NOT NULL,
  `status` tinyint(1) unsigned NOT NULL default 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`query`),
  INDEX (`status`)
) ENGINE=MyISAM;

Разобрался со screen.
Сжал jobs.MYD в архив, получилось всего 13G lol слил этот архив на другой сервер, так что бояться запортить MYD теперь не стоит.

Теперь вопрос, как правильно запустить myisamchk чтобы не создавался временный файл MYD, т.к. всё равно для него заведомо не хватит места (ведь, если я правильно понимаю, потребуется пространство удвоенного размера: для оригинала который после восстановления будет заменён временным файлом, а это 510G + 510G) ....

С нетерпение жду советов ...

Отредактированно creo.ev (25.03.2011 13:00:16)

Неактивен

 

#4 25.03.2011 18:28:48

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Восстановление таблицы.

-q позволяет восстанавливать только индекс. Он остановится, если найдет
ошибку в MYD.

Неактивен

 

#5 27.03.2011 13:31:07

creo.ev
Участник
Зарегистрирован: 24.03.2011
Сообщений: 5

Re: Восстановление таблицы.

Да уж, результаты не утешительные:

server:~/mysql/recover# myisamchk -e --sort_buffer_size=3072M --key_buffer_size=3072M --read_buffer_size=64M --write_buffer_size=64M jobs
Checking MyISAM file: jobs
Data records: 1782613633   Deleted blocks: 4888716
myisamchk: warning: Table is marked as crashed and last repair failed
- check file-size
myisamchk: warning: Size of indexfile is: 66034714624      Should be: 48996154368
- check record delete-chain
myisamchk: warning: Found 0 deleted space in delete link chain. Should be 1495947096
myisamchk: error: Found 0 deleted rows in delete link chain. Should be 4888716
myisamchk: error: record delete-link-chain corrupted
- check key delete-chain
- check index reference
- check data record references index: 1
myisamchk: error: Key in wrong position at page 317384704
- check records and index references
myisamchk: error: Record at: 21817068660  Can't find key for index:  1
MyISAM-table 'jobs' is corrupted
Fix it using switch "-r" or "-o"
server:~/mysql/recover#

server:~/mysql/recover# myisamchk -rq --sort_buffer_size=3072M --key_buffer_size=3072M --read_buffer_size=64M --write_buffer_size=64M jobs
- check record delete-chain
myisamchk: warning: Found 0 deleted space in delete link chain. Should be 1495947096
myisamchk: error: Found 0 deleted rows in delete link chain. Should be 4888716
myisamchk: error: record delete-link-chain corrupted
myisamchk: error: Quick-recover aborted; Run recovery without switch 'q'
Updating MyISAM file: jobs
MyISAM-table 'jobs' is not fixed because of errors
Try fixing it by using the --safe-recover (-o), the --force (-f) option or by not using the --quick (-q) flag
server:~/mysql/recover#

Неактивен

 

#6 27.03.2011 14:55:44

creo.ev
Участник
Зарегистрирован: 24.03.2011
Сообщений: 5

Re: Восстановление таблицы.

Похоже придётся попробовать пилить файл jobs.MYD на блоки с помощью dd и отдельные блоки восстанавливать с myisamchk -r.

Неактивен

 

#7 27.03.2011 22:22:23

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Восстановление таблицы.

С помощью dd не получится: там есть еще заголовок самого файла + надо точно
попасть на границу между записями. Проще починить на другом сервере (или даже
на локальном компьютере, где есть место), а потом утащить починенную табличку
на старый сервер.

Неактивен

 

#8 28.03.2011 11:29:29

creo.ev
Участник
Зарегистрирован: 24.03.2011
Сообщений: 5

Re: Восстановление таблицы.

paulus, всё получилось, заголовка никакого не наблюдал, методом проб определил что размер одной записи в jobs.MYD составляет 306 байт, а дальше по такой схеме, по расчётам получилось что придётся разбивать на 7мь частей, а дальше вот такой алгоритм (целью поставил вытянуть хотя бы данные, с использованием в дальнейшем LOAD DATA INFILE):

[SCREEN] dd if=/root/mysql/backup/jobs.MYD of=/var/lib/mysql/dump/jobs.MYD bs=306 skip={CURRENT}*255357478 count=255357478
cp /root/mysql/backup/jobs.MYI /var/lib/mysql/dump/jobs.MYI
cp /root/mysql/backup/jobs.frm /var/lib/mysql/dump/jobs.frm
[SCREEN] myisamchk -r --sort_buffer_size=3072M --key_buffer_size=3072M --read_buffer_size=64M --write_buffer_size=64M /var/lib/mysql/dump/jobs
chown mysql:mysql /var/lib/mysql/dump/*
chmod 0660 /var/lib/mysql/dump/*
/etc/init.d/mysql start
mysql --user=root --password=pass --database=dump < /root/mysql/outfile/select.sql &
mv /root/mysql/outfile/query.txt /root/mysql/outfile/query_{CURRENT}.txt
/etc/init.d/mysql stop
rm -rf /var/lib/mysql/dump/jobs.*

/root/mysql/outfile/select.sql

SELECT `query` INTO OUTFILE '/root/mysql/outfile/query.txt' FROM `jobs`;

Отредактированно creo.ev (28.03.2011 12:43:56)

Неактивен

 

#9 28.03.2011 21:06:58

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Восстановление таблицы.

Если заработало — отлично smile

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson