LINUX.ORG.RU

Rails + MySQL = теряются данные.


0

1

Табличка в 24M записей, несколько индексов (в том числе и на одни и те же поля). Раз в сутки скрипт 1200 раз подряд (без пауз) делает:

1. select * from mytable where (почти все атрибуты); такой одиночный запрос выполняется около секунды

2. insert в таблицу и автоматическое обновление индексов. Одиночный запрос выполняется быстро - пара мс.

В итоге, с ростом БД, данные начали теряться и дублироваться.

Свободной памяти осталось 20 мегабайт (не ржать, только заметил). Память добавлю, но это не решение. Вижу такие (временные) решения:

1. Добавить sleep в цикл записи (он не требует скорости).

2. Перейти на PgSQL.

3. (Клиент вряд ли согласится, но я планирую). Переписать схему, денормализовать.

Нужен совет.

Перемещено true_admin из development


Уточнение: 1200 раз делает по 20 пар запросов (select-insert). Это успевается за ~10 минут. Объём таблицы - 900 метров.

Нагуглил что даже при таких нагрузках InnoDB теряет записи. Пока что добавил памяти и увеличил до 600 метров innodb_buffer_pool_size.

Думаю переезжать на PgSQL. Но вообще, нагрузка не особо велика чтобы Mysql не справлялся? Если так, думается что нужно переписывать запросы и начисто менять схему.

daris
() автор топика
Ответ на: комментарий от daris

Нагуглил что даже при таких нагрузках InnoDB теряет записи.

Ы? У нас база за 200 ГБ, дофига запросов в секунду и данных не теряет.

Если по теме: нужно включить general query log и смотреть, что происходит.

И еще такой вопрос: рзультат выполнения запросов проверяется на ошибки? Скрипт умеет обрабатывать всякие deadlock found, try restarting transaction и lock wait timeout exceeded, try restarting transaction?

sjinks ★★★
()
Ответ на: комментарий от sjinks

Ы? У нас база за 200 ГБ, дофига запросов в секунду и данных не теряет.

У меня не теряла до октября. Только пару раз было. Теперь всё больше и больше.

Если по теме: нужно включить general query log и смотреть, что происходит.

Спасибо.

И еще такой вопрос: рзультат выполнения запросов проверяется на ошибки? Скрипт умеет обрабатывать всякие deadlock found, try restarting transaction и lock wait timeout exceeded, try restarting transaction?

Драйвер плохо документирован., не могу ответить точно. Он умеет обрабатывать ошибки, и если запись не прошла с первого раза, скорее всего повторной попытки не будет.

Что делать если такие ошибки возникают?

daris
() автор топика
Ответ на: комментарий от daris

Что делать если такие ошибки возникают?

переходить на postgres и никогда больше не использоваться mysql. К сожалению, это единственный способ избавиться от множества проблем.

Alve ★★★★★
()
Ответ на: комментарий от Alve

С радостью. А ты уверен что это действительно решение? 48 000 запросов в минуту (800 запросов в секунду) - это много или мало?

daris
() автор топика

1. Расскажи, зачем тебе там InnoDB, если одна таблица и транзации, как я понял, ты не используешь? cast KRoN73

2. Show create table этой таблички посмотреть можно?

r_asian ★☆☆
()
Ответ на: комментарий от daris

Это ни разу не решение, более того, оно потребует от тебя больше машинных ресурсов и времени на установку и настройку. Но позволит тебе посматривать на пользователей мускуля сверху-вниз и называть их кактусоедами.

r_asian ★☆☆
()
Ответ на: комментарий от r_asian
mysql> show create table positions;
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table     | Create Table                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| positions | CREATE TABLE `positions` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `domain_id` int(11) DEFAULT NULL,
  `word_id` int(11) DEFAULT NULL,
  `position` int(11) DEFAULT NULL,
  `active` tinyint(1) DEFAULT '0',
  `time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `index` (`domain_id`,`word_id`,`position`,`active`,`time`),
  KEY `word_id_and_time_index` (`word_id`,`time`)
) ENGINE=InnoDB AUTO_INCREMENT=14589466 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci |
+-----------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
daris
() автор топика
Ответ на: комментарий от daris

48 000 запросов в минуту (800 запросов в секунду) - это много или мало?

Мало. У меня mysql-сервер годами в таком режиме работает. Ничего (тьфу-тьфу-тьфу) пока не пропадало. Только при жёстких висах HDD, требовавших reset данные терялись пару лет назад.

KRoN73 ★★★★★
()
Ответ на: комментарий от r_asian

Расскажи, зачем тебе там InnoDB, если одна таблица и транзации, как я понял, ты не используешь?

Ну, вдруг, таблица использует внешние ключи? А, уже вижу ниже, что нет. Тогда — действительно, смысла в InnoDB нет. Она заметно тормознее, капризнее, сложнее чинится и обслуживается. Я её использую только когда внешние ключи нужны.

KRoN73 ★★★★★
()
Ответ на: комментарий от daris

Ясно, только фиксированные поля. Не страдай, конверти свои сеошные позиции в MyISAM. С данными фиксированного размера он особенно хорош. И я бы вместо одного составного индекса на твоём месте использовал несколько простых.

r_asian ★☆☆
()
Ответ на: комментарий от r_asian

И я бы вместо одного составного индекса на твоём месте использовал несколько простых

От запросов зависит. При всяких where ... and ... order по разным полям только составной индекс позволяет избавиться от временных таблиц или даже создания файлов. Скорость может на много порядков подскакивать при правильном выборе составного индекса. При чём сам mysql не всегда оптимальный вариант умеет найти. Так что — explain и ещё много раз explain :)

KRoN73 ★★★★★
()
Ответ на: комментарий от r_asian

Я бы это счастье переписал заново, но кто же на такое согласится?.. Хорошо, конвертну всё.

Спасибо за ответы. Скоро отпишусь о результатах.

daris
() автор топика
Ответ на: комментарий от r_asian

Погоди, у меня проблема только в большой нагрузке при вставках. Если myisam блокирует всю таблицу, то будет работать ещё медленней, не?

daris
() автор топика
Ответ на: комментарий от daris

у меня проблема только в большой нагрузке при вставках

я не большой спец, но.. Привставке у тебе перестраиваится заново индексы. один из них у тебе на все поля таблицы. можна сделать эксперимент: дропнуть индеск, сделать пару инсертов на посмотреть. Если все ок - значит индекс (или таблицу [или..]) нужно переделать

ZuBB ★★★★★
()
Ответ на: комментарий от ZuBB

Переделать определённо надо. Было ясно ещё когда просили «быстро дописать» «в нуждах бизнеса». Но денег на это не дадут.

daris
() автор топика
Ответ на: комментарий от daris

У исамы косяк в том, что интенсивная запись блокирует чтение. Если в это время никто не читает - тогда особых проблем не будет.

Vit ★★★★★
()
Ответ на: комментарий от daris

Цитата из книги «MySQL. Оптимизация производительности»:
MyISAM блокирует целиком таблицы, но не строки. Запросы на чтение получают разделяемые (на чтение) блокировки всех таб­лиц, к которым они обращаются. Запросы на запись получают монопольные (на запись) блокировки. Однако вы можете вставлять новые строки в таб­лицу в момент, когда исполняются запросы на выборку данных из таб­лицы (конкурентные вставки). Это очень важная и полезная возможность.

tuxin
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.