yii2-queue icon indicating copy to clipboard operation
yii2-queue copied to clipboard

What would it be if auto incremented id reach it's max value? (Db driver)

Open antonpresn opened this issue 7 years ago • 16 comments

Hello! I've found that my queue is increasing very rapidly (based on Db driver), and that lead me on a thought - how would queue behave in that case?

If an exception would be thrown, is there any recommendations?

antonpresn avatar Dec 14 '17 09:12 antonpresn

https://stackoverflow.com/questions/2615417/what-happens-when-auto-increment-on-integer-column-reaches-the-max-value-in-data

samdark avatar Dec 14 '17 11:12 samdark

Thanks @samdark, before posting here i've read exactly the same article :) I should try to do some workaround I suppose..

antonpresn avatar Dec 14 '17 12:12 antonpresn

DB driver migration:

        $this->createTable($this->tableName, [
            'id' => $this->primaryKey(),

could be replaced with bigPrimaryKey(). You can adjust your existing table manually to bigint.

samdark avatar Dec 14 '17 13:12 samdark

I wouldn't suggest using auto-incremented id on a message queue table at all. The table is supposed to be used extensively: there are many inserts and deletions into it, ids never reused. So reaching max id would be a common problem.

Other than hitting the limit it is very slow (the insert require a table level lock to find out next free id).

Suggestion: Use no auto-incremented id, such as uuid

makasim avatar Dec 14 '17 13:12 makasim

Right... @zhuravljov what do you think?

samdark avatar Dec 14 '17 13:12 samdark

my dirty and quick workaround while moving to rabbitmq :)

ALTER TABLE `queue` 
CHANGE COLUMN `id` `id` INT(11) NOT NULL ;

delimiter //
-- googled somewhere on a Stackoverflow
DROP FUNCTION IF EXISTS getFirstGapStart//
CREATE FUNCTION getFirstGapStart
(
) RETURNS int
BEGIN 
	declare res int;
	SELECT
	 min(z.expected) into @res
	FROM (
	 SELECT
	  @rownum:=@rownum+1 AS expected,
	  IF(@rownum=id, 0, @rownum:=id) AS got
	 FROM
	  (SELECT @rownum:=0) AS a
	  JOIN queue
	  ORDER BY id
	 ) AS z
	WHERE z.got!=0;

return @res; 
end//

drop trigger if exists create_id//

create trigger create_id
before insert on `queue`
for each row 
begin
	declare maxId, newId, maxInt int;
    set @maxInt = 2147483647;
    select max(id) into @maxId from queue;
    set @maxId = IF (@maxId is null, 0, @maxId);
    set @newId = IF ((@maxId>=@maxInt), getFirstGapStart(), @maxId + 1);
  set NEW.id = @newId;
 
end//

antonpresn avatar Dec 16 '17 17:12 antonpresn

UUID is good thing, but it doesn't privide ordering in contrast to the auto-incremental PK. It requires to add additional indexed field. If big throughput is requred I would choose more fast driver. Bigint PK looks like as compromise. Does anyone know an easy and cross-db way to migrate int PK to bigint?

zhuravljov avatar Dec 16 '17 22:12 zhuravljov

@zhuravljov, I think You're right that if big throughput is required than one should consider more fast driver. And my previous workaround is not acceptable (it causes errors in duplicate keys etc..).

antonpresn avatar Dec 20 '17 08:12 antonpresn

UUIDs can be stored as time ordered ids https://github.com/ramsey/uuid-doctrine#innodb-optimised-binary-uuids

makasim avatar Dec 20 '17 08:12 makasim

Here's how I used it in enqueue/dbal driver https://github.com/php-enqueue/enqueue-dev/pull/280/files

makasim avatar Dec 20 '17 08:12 makasim

@zhuravljov why not use pushed_at to sort instead of PK?

padlyuck avatar Jan 22 '18 14:01 padlyuck

@padlyuck in the first place pushed_at is integer field that containt timestamp in seconds. If you send two or more jobs into the queue witin a second, then their order will be undefined. In the second place we also need to add index for pushed_at.

zhuravljov avatar Feb 21 '18 22:02 zhuravljov

Bigint PK looks like as compromise.

I suggest to use unsigned bigint, this double the quantity of primary keys

bobonov avatar Mar 07 '18 10:03 bobonov

Why don’t just reset increment ? You should not store jobs for a long time...

yarosdev avatar Aug 21 '19 18:08 yarosdev