Sequences

    The sharded customer table we created did not have an auto-increment column. The Vitess Sequence feature can be used to emulate the same behavior as MySQL’s auto-increment. A Vitess sequence is a single row unsharded tablet that keeps track of ids issued so far. Additionally, a configurable number of values can be cached by vttablet to minimize round trips into MySQL.

    We will create the sequence table in the unsharded product keyspace as follows:

    1. create table customer_seq(id bigint, next_id bigint, cache bigint, primary key(id)) comment 'vitess_sequence';
    2. insert into customer_seq(id, next_id, cache) values(0, 1, 3);

    Note the special comment vitess_sequence. This instructs vttablet that this is a special table.

    The table needs to be pre-populated with a single row where:

    • id must always be 0
    • next_id should be set to the next (starting) value of the sequence
    • cache is the number of values to cache before updating the table for the next value. This value should be set to a fairly large number like 1000. We have set the value to 3 mainly to demonstrate how the feature works.

    Since this is a special table, we have to inform the vschema by giving it a sequence type.

    1. "customer_seq": { "type": "sequence" }

    Once setup this way, you can use the special select next syntax to generate values from this sequence:

    1. mysql> select next 2 values from customer_seq;
    2. +---------+
    3. | nextval |
    4. +---------+
    5. | 1 |
    6. +---------+
    7. 1 row in set (0.00 sec)
    8. mysql> select next 1 values from customer_seq;
    9. +---------+
    10. | nextval |
    11. +---------+
    12. | 3 |
    13. +---------+
    14. 1 row in set (0.00 sec)

    The construct returns the first of the N values generated.

    However, this is insufficient to emulate MySQL’s auto-increment behavior. To achieve this, we have to inform the VSchema that the customer_id column should use this sequence to generate values if no value is specified. This is done by adding the following section to the customer table:

    1. "auto_increment": {
    2. "column": "customer_id",
    3. "sequence": "product.customer_seq"
    4. }

    Alternate VSchema DDL:

    1. alter vschema add sequence product.customer_seq;
    2. alter vschema on customer.customer add auto_increment customer_id using product.customer_seq;

    With this, you can insert into customer without specifying the customer_id:

    1. mysql> insert into customer(uname) values('alice'),('bob'),('charlie'),('dan'),('eve');
    2. Query OK, 5 rows affected (0.03 sec)
    3. mysql> use `customer:-80`;
    4. Database changed
    5. mysql> select * from customer;
    6. +-------------+---------+
    7. | customer_id | uname |
    8. +-------------+---------+
    9. | 1 | alice |
    10. | 2 | bob |
    11. | 3 | charlie |
    12. | 5 | eve |
    13. +-------------+---------+
    14. 4 rows in set (0.00 sec)
    15. mysql> use `customer:80-`;
    16. Database changed
    17. mysql> select * from customer;
    18. +-------------+-------+
    19. | customer_id | uname |
    20. +-------------+-------+
    21. | 4 | dan |
    22. +-------------+-------+
    23. 1 row in set (0.00 sec)