¿Se puede usar AUTO_INCREMENT de forma segura en un ANTES DEL DISPARADOR en MySQL

El método Postgres de Instagram para implementar Ids personalizados para Sharding es excelente, pero necesito la implementación en MySQL.

Entonces, convertí el método que se encuentra al final de este blog, aquí:http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram

Versión 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

La tabla se ve más o menos así:

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

Pregunta:

Hay un problema de concurrencia aquí. Al generar 100 hilos e insertar inserciones, obtengo valores de secuencia duplicados, lo que significa que dos disparadores obtienen el mismo valor de auto_increment. ¿Cómo puedo arreglar esto?

Intenté crear una nueva tabla, p. "tablename_seq", con una fila, un contador para almacenar mis propios valores de auto_increment, luego haciendo actualizaciones a esa tabla dentro del TRIGGER, pero el problema es que no puedo BLOQUEAR la tabla en un Procedimiento almacenado (disparador), así que tengo el exactamente el mismo problema, no puedo garantizar que un contador sea único entre los desencadenantes :(.

Estoy perplejo y realmente agradecería cualquier consejo!

Solución posible:

MySQL 5.6 tiene UUID_SHORT () que genera valores de incremento únicos que se garantiza que son únicos. En la práctica, al llamar a esto, parece que cada llamada incrementa el valor +1. Al usar: SET seq_id = (SELECT UUID_SHORT ()); parece eliminar el problema de concurrencia. El efecto secundario de esto es que ahora (aproximadamente) no pueden suceder más de 1024 inserciones por milisegundo en todo el sistema. Si más lo hacen, entonces es posible que se produzca un error DUPLICATE PRIMARY KEY. La buena noticia es que en los puntos de referencia en mi máquina, obtengo ~ 3,000 inserciones / s con o sin el activador que contiende UUID_SHORT (), por lo que no parece ralentizarlo en absoluto.

Respuestas a la pregunta(2)

Su respuesta a la pregunta