千家信息网

MySQL的server_uuid获取之uuid()函数和uuid_short()函数

发表于:2025-02-08 作者:千家信息网编辑
千家信息网最后更新 2025年02月08日,1、uuid()函数mysql> select uuid(),uuid();+--------------------------------------+----------------------
千家信息网最后更新 2025年02月08日MySQL的server_uuid获取之uuid()函数和uuid_short()函数1、uuid()函数
  1. mysql> select uuid(),uuid();
  2. +--------------------------------------+--------------------------------------+
  3. | uuid() | uuid() |
  4. +--------------------------------------+--------------------------------------+
  5. | 50120c25-d75c-11e7-9484-000c29c9278a | 50120c53-d75c-11e7-9484-000c29c9278a |
  6. +--------------------------------------+--------------------------------------+
  7. 1 row in set (0.00 sec)
  1. String *Item_func_uuid::val_str(String *str)
  2. {
  3. ...
  4. mac\rand get
  5. ...
  6. uint32 time_low= (uint32) (tv & 0xFFFFFFFF);
  7. uint16 time_mid= (uint16) ((tv >> 32) & 0xFFFF);
  8. uint16 time_hi_and_version= (uint16) ((tv >> 48) | UUID_VERSION);
  9. s[8]=s[13]='-';
  10. tohex(s, time_low, 8);
  11. tohex(s+9, time_mid, 4);
  12. tohex(s+14, time_hi_and_version, 4);
  13. strmov(s+18, clock_seq_and_node_str);
  14. ...
  15. }
详细产生uuid的过程,参考上面的函数进行分析。

time_low、time_mid、time_high_and_version转成16进制后分别对应第1 2 3段。
这个时间是从1582-10-15 00:00:00.00到当前时间的100ns值。(实际上系统只能取到精确us,再乘以10)。所以你短时间连续执行的话,比较可能只有第一个值在改,实际上1 2 3都可能会改变。第4段是你启动这个MySQL后第一次执行select uuid()时的随机数,每次重启会改变。第5段是mac值转过来的,同一个机器多实例的一般相同。如果mac值获取不到,则是一个随机值。所以这个值可以认为是每次执行都不相同。并且不同实例之间也只有极微小概率重复。

2、uuid_short()函数

  1. mysql> select uuid_short(),uuid_short();
  2. +--------------------+--------------------+
  3. | uuid_short() | uuid_short() |
  4. +--------------------+--------------------+
  5. | 818004335832072194 | 818004335832072195 |
  6. +--------------------+--------------------+
  7. 1 row in set (0.00 sec)
函数调用过程:
  1. main->init_common_variables()->
  2. server_start_time= flush_status_time= my_time(0);
  3. //获取server启动时的时间戳
  1. ulonglong uuid_value;
  2. main->init_common_variables->item_init->
  3. void uuid_short_init()
  4. {
  5. uuid_value= ((((ulonglong) server_id) << 56) +
  6. (((ulonglong) server_start_time) << 24));
  7. }
  1. longlong Item_func_uuid_short::val_int()
  2. {
  3. ulonglong val;
  4. mysql_mutex_lock(&LOCK_uuid_generator);
  5. val= uuid_value++;
  6. mysql_mutex_unlock(&LOCK_uuid_generator);
  7. return (longlong) val;
  8. }
与uuid()函数返回固定字符串不同,uuid_short()函数返回的是ulonglong类型的值。mysql启动后第一次执行的值通过server_id<<56+server_start_time<<24来初始化,其中
server_start_time是server启动时的时间,单位是秒。之后每次执行该函数都+1

3、server启动时,会自动产生server_uuid
  1. main->init_server_auto_options:处理server_uuid
  2. my_load_defaults(fname, groups, &argc, &argv, NULL)//fname:auto.cnf
  3. handle_options(&argc, &argv, auto_options, mysqld_get_one_option);
  4. if(uuid){
  5. strcpy(server_uuid, uuid);
  6. }else{
  7. flush= TRUE;
  8. generate_server_uuid();
  9. }
  10. if (flush)
  11. DBUG_RETURN(flush_auto_options(fname));
  12. //O_CREAT|O_RDWR形式open,即如果没有auto.cnf文件,
  13. //则创建一个并将生成的server_uuid写入文件并flush
  1. generate_server_uuid:
  2. func_uuid= new (thd->mem_root) Item_func_uuid();
  3. func_uuid->fixed= 1;
  4. func_uuid->val_str(&uuid);
  5. strncpy(server_uuid, uuid.c_ptr(), UUID_LENGTH);
其中val_str函数是Item_func_uuid::val_str。server启动时,会从auto.cnf文件中读取,如果没有这个文件,则新创建文件并自动产生server_uuid,写入文件并flush。


0