2015-06-13 3 views
1

Я хочу обновить счет статистики в mysql.Проблемы с блокировкой Mysql Innodb на REPLACE INTO

SQL, выглядит следующим образом:

REPLACE INTO `record_amount`(`source`,`owner`,`day_time`,`count`) VALUES (?,?,?,?) 

Схема:

CREATE TABLE `record_amount` (
    `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'id', 
    `owner` varchar(50) NOT NULL , 
    `source` varchar(50) NOT NULL , 
    `day_time` varchar(10) NOT NULL, 
    `count` int(11) NOT NULL, 
    PRIMARY KEY (`id`), 
    UNIQUE KEY `src_time` (`owner`,`source`,`day_time`) 
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; 

Однако это вызвало исключение тупиком в мульти-процессов работает (т.е. Map-Reduce).

Я прочитал некоторые материалы в Интернете и смущен этими замками. Я знаю, что innodb использует блокировку на уровне строк. Я могу просто использовать табличный замок для решения бизнес-задачи, но это немного экстремально. Я нашел несколько возможных решений:

  1. изменения REPLACE INTO в сделку с SELECT id FOR UPDATE и UPDATE
  2. изменения REPLACE INTO в INSERT ... ON DUPLICATE KEY UPDATE

Я понятия не имею, что которая является практичным и лучше. Может кто-нибудь объяснить это или предложить некоторые ссылки для меня, чтобы читать и учиться? Спасибо!

+0

просто используйте myisam для этого стола, он не содержит замки. – Sebas

+0

@Sebas Спасибо. И я помню, что myisam использует блокировку на уровне таблицы, что, если я просто заблокирую таблицу в Innodb? Изменение sql-схемы не является первым выбором, поскольку я должен убедить DBA. – Lhfcws

+0

Я должен был быть более точным.Он содержит блокировки, но без транзакций, поэтому нет взаимоблокировок - что кажется вашей проблемой. О вещи дба, ты прав, я думаю. Однако таблицы журналов, таблицы подсчета и т. Д. Являются типичной реализацией myisam, вложенной в базу данных innodb. – Sebas

ответ

-1

Вы строите сводную таблицу, по одной строке источника за раз? И эффективно делать UPDATE ... count = count+1? Отбросьте код и начните заново. MAP-REDUCE на этом похоже на использование кувалды на палитре.

INSERT INTO summary (source, owner, day_time, count) 
    SELECT source, owner, day_time, COUNT(*) 
     FROM raw 
     GROUP BY source, owner, day_time 
    ON DUPLICATE KEY UPDATE count = count + VALUES(count); 

одного заявление примерно так, что будет делать всю работу практически на диске скорости ввода/вывода. Нет SELECT ... FOR UPDATE. Нет тупиков. Нет нескольких потоков. Etc.

Дальнейшие усовершенствования:

  • Избавиться от AUTO_INCREMENT; поверните UNIQUE в PRIMARY KEY.
  • day_time - это то, что DATETIME усечено до часа? (Или что-то в этом роде.) Используйте DATETIME, у вас будет гораздо больше гибкости при запросе.

Для дальнейшего обсуждения просьба уточнить исходные данные (`CREATE TABLE, количество строк, частота обработки и т. Д.) И другие сведения. Если это действительно приложение Data Warehouse со сводной таблицей, у меня могут появиться дополнительные предложения.

Если данные поступают из файла, сделайте LOAD DATA, чтобы перетащить его в таблицу темп raw, чтобы вышеуказанный INSERT..SELECT мог работать. Если это управляемый размер, сделайте rawEngine=MEMORY, чтобы избежать ввода-вывода.

Если у вас несколько каналов, my high-speed-ingestion blog обсуждает, как иметь несколько потоков без каких-либо взаимоблокировок.

+0

map-reduce предназначен для бизнеса, а не только для обновления счетчика. Итак, на самом деле моя проблема заключается в том, как справляться с проблемой подсчета обновлений в MySQL innodb? как избежать взаимоблокировок или несогласованности данных в среде с несколькими процессами? Теперь мы просто изменяем innodb на myisam для решения проблемы. – Lhfcws

+0

И «Избавьтесь от AUTO_INCREMENT, поверните UNIQUE в ПЕРВИЧНЫЙ КЛЮЧ». кажется хорошим решением ~~, и я хотел бы знать, что как SQL, который вы предоставили, работает в среде с несколькими процессами? Спасибо ~ – Lhfcws

+0

Я всегда думаю, что несколько машин попадают в базу данных «одновременно». Поэтому (если я не схожу с ума), он должен работать нормально (и, вероятно, быстрее) в многопроцессорной среде. Параллелизм InnoDB вращается вокруг «ПЕРВИЧНОГО КЛЮЧА», независимо от того, является ли это «AUTO_INCREMENT» или «естественным» PK. Две клавиши 'UNIQUE/PRIMARY' медленнее и более тупиковые, чем у одного. –

Смежные вопросы