Можно ли безопасно использовать AUTO_INCREMENT в ПЕРЕД ТРИГГЕРОМ в MySQL

Инстаграмный метод Postgres для реализации пользовательских идентификаторов для Sharding хорош, но мне нужна реализация в MySQL.

Итак, я преобразовал метод, найденный внизу этого блога, здесь:http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram

Версия MySQL:

CREATE TRIGGER shard_insert BEFORE INSERT ON tablename
FOR EACH ROW BEGIN

DECLARE seq_id BIGINT;
DECLARE now_millis BIGINT;
DECLARE our_epoch BIGINT DEFAULT 1314220021721;
DECLARE shard_id INT DEFAULT 1;

SET now_millis = (SELECT UNIX_TIMESTAMP(NOW(3)) * 1000);
SET seq_id = (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA = "dbname" AND TABLE_NAME = "tablename");
SET NEW.id = (SELECT ((now_millis - our_epoch) << 23) | (shard_id << 10) | (SELECT MOD(seq_id, 1024)));
END

Таблица выглядит примерно так:

CREATE TABLE tablename (
    id BIGINT AUTO_INCREMENT,
    ...
)

Вопрос:

Здесь есть проблема параллелизма. При создании 100 потоков и выполнении вставок я получаю дублирующиеся значения последовательности, что означает, что два триггера получают одинаковое значение auto_increment. Как я могу это исправить?

Я попытался создать новую таблицу, например "tablename_seq", с одной строкой, счетчиком для хранения моих собственных значений auto_increment, а затем обновлением этой таблицы внутри TRIGGER, но проблема в том, что я не могу заблокировать таблицу в хранимой процедуре (триггер), поэтому у меня есть точно такая же проблема, я не могу гарантировать, что счетчик будет уникальным между триггерами :(.

Я в тупике и буду очень признателен за любые советы!

Возможное решение:

MySQL 5.6 имеет UUID_SHORT (), который генерирует уникальные приращения значений, которые гарантированно будут уникальными. На практике при вызове этого метода каждый вызов увеличивает значение +1. Используя: SET seq_id = (SELECT UUID_SHORT ()); по-видимому, чтобы устранить проблему параллелизма. Побочным эффектом этого является то, что теперь (примерно) может произойти не более 1024 вставок за миллисекунду во всей системе. Если больше, то это возможно для ошибки DUPLICATE PRIMARY KEY. Хорошая новость заключается в том, что в тестах на моей машине я получаю ~ 3000 вставок / с с или без триггера, содержащего UUID_SHORT (), так что он вообще не замедляет его.

Ответы на вопрос(2)

Ваш ответ на вопрос