Why INSERT IGNORE increments the auto_increment primary key?

前端 未结 4 1213
挽巷
挽巷 2020-12-05 02:50

I wrote a java program that accesses a MySQL innodb database.

Whenever an INSERT IGNORE statement encounters a duplicate entry the Auto Increment primary key is inc

相关标签:
4条回答
  • 2020-12-05 03:18

    Not sure if it's expected, though I would recommend switching to:

    INSERT ... ON DUPLICATE KEY UPDATE
    
    0 讨论(0)
  • 2020-12-05 03:21

    This has been the default behaviour since MySQL 5.1.22.

    You can set the configuration variable innodb_autoinc_lock_mode to 0 (a.k.a “traditional” lock mode) If you'd like to avoid gaps in your auto-increment columns. It may incur a performance penalty, though, as this mode has the effect of holding a table lock until the INSERT completes.

    From the docs on InnoDB AUTO_INCREMENT Lock Modes:

    innodb_autoinc_lock_mode = 0 (“traditional” lock mode)

    The traditional lock mode provides the same behavior that existed before the innodb_autoinc_lock_mode configuration parameter was introduced in MySQL 5.1. The traditional lock mode option is provided for backward compatibility, performance testing, and working around issues with “mixed-mode inserts”, due to possible differences in semantics.

    In this lock mode, all “INSERT-like” statements obtain a special table-level AUTO-INC lock for inserts into tables with AUTO_INCREMENT columns. This lock is normally held to the end of the statement (not to the end of the transaction) to ensure that auto-increment values are assigned in a predictable and repeatable order for a given sequence of INSERT statements, and to ensure that auto-increment values assigned by any given statement are consecutive.

    0 讨论(0)
  • 2020-12-05 03:35

    I believe this is a configurable setting in InnoDB. See: AUTO_INCREMENT Handling in InnoDB

    You'd want to go with

    innodb_autoinc_lock_mode = 0
    
    0 讨论(0)
  • 2020-12-05 03:39

    I think this behaviour is reasonable. The auto-increment should not be relied upon to give sequences that don't have gaps.

    For example, a rolled back transaction still consumes IDs:

     INSERT INTO t (normalcol, uniquecol) VALUES 
       ('hello','uni1'),
       ('hello','uni2'),
       ('hello','uni1');
    

    Generates a unique key violation obviously, and inserts no rows into the database (assuming transactional engine here). However, it may consume up to 3 auto-inc values without inserting anything.

    0 讨论(0)
提交回复
热议问题