返回顶部
首页 > 资讯 > 数据库 >MySQL写集合是什么
  • 141
分享到

MySQL写集合是什么

2024-04-02 19:04:59 141人浏览 八月长安
摘要

本篇内容介绍了“Mysql写集合是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是写集合(Wr

本篇内容介绍了“Mysql集合是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

一、什么是写集合(Write set)

实际上写集合定义在类Rpl_transaction_write_set_ctx中,其中主要包含两个数据结构

  • std::vector<uint64> write_set;

  • std::set<uint64> write_set_unique;

第一个是一个vecotr数组,第二个是一个set集合,它们中的每一元素都是一个hash值,其hash来源自函数add_pke,包含了:

  • 非唯一索引名称+分隔符+库名+分隔符+库名长度+表名+分隔符+表名长度+索引字段1数值+分隔符 +索引字段1长度 [+ 索引字2段数值+分隔符 +索引字段2长度 .....]

注意唯一索引也会计入到写集合中。
在MGR中主键是有着极其重要的地位,是判断是否冲突的重要依据,最后写集合信息会封装进Transaction_context_log_event,同其他binlog event信息一起发送给其他节点。同时函数add_pke在生成写集合成员原始数据的时候(hash之前的数据)对每行索引值还记录两种格式:

  • 按照mysql字段格式的字段值和长度

  • 按照字符串格式记录的字段值和长度

而生成写集合的是在Innodb层完成更改操作,Mysql层写入binlog event之前。

二、写集合原始数据(hash前)的列子

如下表:

mysql> use test
Database changed
mysql> show create table jj10 \G
*************************** 1. row ***************************
       Table: jj10
Create Table: CREATE TABLE `jj10` (  `id1` int(11) DEFAULT NULL,  `id2` int(11) DEFAULT NULL,  `id3` int(11) NOT NULL,
  PRIMARY KEY (`id3`),
  UNIQUE KEY `id1` (`id1`),
  KEY `id2` (`id2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin11 row in set (0.00 sec)

我们写入一行数据:

insert into jj10 values(36,36,36);

这一行数据一共会生成4个写集合元素分别为:
注意:这里显示的½是分隔符

  • 写集合元素1:

(gdb) p pke
$1 = "PRIMARY½test½4jj10½4\200\000\000$½4"注意:\200\000\000$ 为:3个八进制字节+ASCII$  16进制就是0X80 00 00 24

主键 PRIMARY+分隔符+库名 test+分隔符+库名长度 4+表名 jj10+分隔符+表名长度 4+主键值 0X80 00 00 24 +分隔符+int字段类型长度 4

  • 写集合元素2:

(gdb) p pke$2 = "PRIMARY½test½4jj10½436½2"

主键 PRIMARY+分隔符+库名 test+分隔符+库名长度 4+表名 jj10+分隔符+表名长度 4+主键值字符串显示 "36" +分隔符+字符串"36"长度为2

  • 写集合元素3:

(gdb) p pke$3 = "id1½test½4jj10½4\200\000\000$½4"

同上只是这里不是主键是唯一键id1

  • 写集合元素4:

(gdb) p pke$4 = "id1½test½4jj10½436½2"

同上只是这里不是主键是唯一键id1

三、函数add_pke解析

这里抛开了外键的逻辑主要逻辑如下:

如果表中存在索引:
   将数据库名,表名信息写入临时变量   
   循环扫描表中每个索引:
        如果不是唯一索引:
             退出本次循环继续循环。
        循环两种生成数据的方式(MySQL格式和字符串格式):
             将索引名字写入到pke中。
             将临时变量信息写入到pke中。
             循环扫描索引中的每一个字段:
                将每一个字段的信息写入到pke中。
                如果字段扫描完成:
                   将pke生成hash值并且写入到写集合中。

源码注释如下:

Rpl_transaction_write_set_ctx* ws_ctx=                     //THD  Transaction_ctx  m_transaction_write_set_ctx
    thd->get_transaction()->get_transaction_write_set_ctx(); //本内存空间在线程初始化的时候分配    m_transaction(new Transaction_ctx()), 
  int writeset_hashes_added= 0;  if(table->key_info && (table->s->primary_key < MAX_KEY)) //typedef struct st_key  
  {
    char value_length_buffer[VALUE_LENGTH_BUFFER_SIZE];
    char* value_length= NULL;
    std::string pke_schema_table;
    pke_schema_table.reserve(NAME_LEN * 3);
    pke_schema_table.append(HASH_STRING_SEPARATOR); //分隔符
    pke_schema_table.append(table->s->db.str, table->s->db.length); //数据库名字 存入。
    pke_schema_table.append(HASH_STRING_SEPARATOR);//分隔符
    value_length= my_safe_itoa(10, table->s->db.length,
                               &value_length_buffer[VALUE_LENGTH_BUFFER_SIZE-1]); //存储的是字符形式的长度 返回为char指针 '1' '3' 代表 长度13 
    pke_schema_table.append(value_length);//将转换后的长度以字符串的方式存入
    pke_schema_table.append(table->s->table_name.str, table->s->table_name.length);//表名 字符存入。
    pke_schema_table.append(HASH_STRING_SEPARATOR);//分隔符
    value_length= my_safe_itoa(10, table->s->table_name.length,
                               &value_length_buffer[VALUE_LENGTH_BUFFER_SIZE-1]);//存储的是字符形式的长度 返回为char指针 '1' '3' 代表 长度13 
    pke_schema_table.append(value_length);//将转换后的长度以字符串的方式存入
    //因此上面的存储的为 分隔符+dbname+分隔符+dbname长度+分隔符+tablename+分隔符+tablename长度 这里就是代表了数据库和表信息
    std::string pke; //初始化pke 这是存储写集合元素hash前数据的中间变量
    pke.reserve(NAME_LEN * 5);
    char *pk_value= NULL;
    size_t pk_value_size= 0;    // Buffer to read the names of the database and table names which is less
    // than 1024. So its a safe limit.
    char name_read_buffer[NAME_READ_BUFFER_SIZE];    // Buffer to read the row data from the table record[0].
    String row_data(name_read_buffer, sizeof(name_read_buffer), &my_charset_bin); //读取当前行数据到buffer#ifndef DBUG_OFF //如果没有定义 非DEBUG 模式
    std::vector<std::string> write_sets;#endif
    for (uint key_number=0; key_number < table->s->keys; key_number++) //依次扫描每个索引   EXP:create table jj10(id1 int,id2 int,id3 int primary key,unique key(id1),key(id2));             
    {                                                                  //table->key_info[0].name  $12 = 0x7fffd8003631 "PRIMARY"  able->key_info[1].name $13 = 0x7fffd8003639 "id1"
      // Skip non unique.                                             //table->key_info[2].name $14 = 0x7fffd800363D "id2"
      if (!((table->key_info[key_number].flags & (HA_NOSAME )) == HA_NOSAME)) //跳过非唯一的KEY
        continue;      KEY_PART_INFO Field      for (int collation_conversion_alGorithm= COLLATION_CONVERSION_ALGORITHM;
           collation_conversion_algorithm >= 0;
           collation_conversion_algorithm--) //校队和非校队算法  也就是MySQL字段格式和字符串格式2种格式
      {
        pke.clear();
        pke.append(table->key_info[key_number].name); //table->key_info[0]  $15 = 0x7fffd8003631 "PRIMARY"
        pke.append(pke_schema_table);//将上面得到字符串写入 那么这里就是 主键 "primary + dbname+分隔符+dbname长度+分隔符+tablename+分隔符+tablename长度 "
        uint i= 0;        for (; i < table->key_info[key_number].user_defined_key_parts; i++) //开始扫描每一个相应的字段
        {          // read the primary key field values in str.
          int index= table->key_info[key_number].key_part[i].fieldnr; // TABLE  st_key  KEY_PART_INFO 字段在表中的相应位置
          size_t length= 0;          
          if (table->field[index-1]->is_null()) //Field **field;               **point ->[*field,*field,*field...] 这里有多态每种字段类型有自己的各种算法
            break; //如果字段为空 或者 值为 空 返回
          // convert using collation support conversion algorithm
          if (COLLATION_CONVERSION_ALGORITHM == collation_conversion_algorithm) //如果采用校队算法
          {            const CHARSET_INFO* cs= table->field[index-1]->charset();
            length= cs->coll->strnxfrmlen(cs,
                                       table->field[index-1]->pack_length()); //获取长度主键值
          }          // convert using without collation support algorithm
          else
          {
            table->field[index-1]->val_str(&row_data);
            length= row_data.length();
          }          if (pk_value_size < length+1)
          {
            pk_value_size= length+1;
            pk_value= (char*) my_realloc(key_memory_write_set_extraction,
                                         pk_value, pk_value_size,
                                         MYF(MY_ZEROFILL));
          }          // convert using collation support conversion algorithm
          if (COLLATION_CONVERSION_ALGORITHM == collation_conversion_algorithm)
          {            
            table->field[index-1]->make_sort_key((uchar*)pk_value, length); // 将字段的值存入到pk_value中,各种类型都有make_sort_key函数
            pk_value[length]= 0;
          }          // convert using without collation support algorithm
          else
          {
            strmake(pk_value, row_data.c_ptr_safe(), length);
          }
          pke.append(pk_value, length); //将主键值计入
          pke.append(HASH_STRING_SEPARATOR);//分隔符
          value_length= my_safe_itoa(10, length,
                                     &value_length_buffer[VALUE_LENGTH_BUFFER_SIZE-1]);//存储的是字符形式的长度 返回为char指针 '1' '3' 代表 长度13 
          pke.append(value_length);//计入长度
        }        
        if (i == table->key_info[key_number].user_defined_key_parts) //如果所有的索引字段都扫描完成
        {//最后得到的字符串为  非唯一索引名称+分隔符+库名+分隔符+库名长度+表名+分隔符+表名长度+索引字段1数值+分隔符 +索引字段1长度 [+ 索引字段2数值+分隔符 +索引字段2长度 .....]
          generate_hash_pke(pke, collation_conversion_algorithm, thd); //对pke内存空间做HASH 
          writeset_hashes_added++; 
#ifndef DBUG_OFF
          write_sets.push_back(pke); //写入到write set 并且加入到写集合中#endif
        }

“MySQL写集合是什么”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL写集合是什么

本文链接: https://lsjlt.com/news/64520.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • MySQL写集合是什么
    本篇内容介绍了“MySQL写集合是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、什么是写集合(Wr...
    99+
    2024-04-02
  • java返回集合为null还是空集合及空集合的三种写法分别是什么
    本篇文章为大家展示了java返回集合为null还是空集合及空集合的三种写法分别是什么,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。返回集合为null还是空集合及空集合的三种写法个人认为在自己写接口时...
    99+
    2023-06-25
  • java的集合是什么?
    什么是集合?集合类存放于java.util包中。集合类型主要有3种:set(集)、list(列表)和map(映射)。集合存放的都是对象的引用,而非对象本身。所以我们称集合中的对象就是集合中对象的引用。简单来讲:集合就是一个放数据的容器,准确...
    99+
    2018-09-16
    java教程 java 集合
  • Java集合框架是什么
    这篇文章主要介绍了Java集合框架是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。一、简介1、集合框架介绍Java集合框架提供了一套性能优良,使用方便的接口和类,他们位于...
    99+
    2023-06-29
  • Python中的集合是什么
    这篇文章主要为大家展示了“Python中的集合是什么”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“Python中的集合是什么”这篇文章吧。一、什么是集合二、集合的创建方式集合中的元素不能重复#地...
    99+
    2023-06-29
  • Java中什么是Map集合
    小编给大家分享一下Java中什么是Map集合,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是Map不同于List单列的线性结构,Java中的Map提供的是...
    99+
    2023-06-02
  • Hibernate的集合映射是什么
    这期内容当中小编将会给大家带来有关Hibernate的集合映射是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。POJOs如下:Customer类---->customer表Order类对应---...
    99+
    2023-06-17
  • php中数组是什么集合
    本篇内容主要讲解“php中数组是什么集合”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php中数组是什么集合”吧!php中数组是一组有序数据的集合,数组中的每个成员被称为元素,每个元素由一个特殊...
    99+
    2023-06-30
  • java返回集合为null还是空集合及空集合的三种写法小结
    目录返回集合为null还是空集合及空集合的三种写法返回空List的方式方式一:new ArrayList()  方式二:new ArrayList(0)方式三:Colle...
    99+
    2024-04-02
  • mysql字符集是什么
    MySQL字符集是指用于存储和处理文本数据的字符编码系统,定义了数据库中可以使用的字符集合,以及每个字符在计算机中的表示方式,MySQL支持多种字符集,包括常见的字符集如UTF-8、Latin1等,以及其他语言特定的字符集,字符集决定了数据...
    99+
    2023-07-25
  • java中集合的区别是什么?
    java中集合的区别是什么?在java中集合主要分为:List,Set,Map三种,其中List与Set是继承自Collection,而Map不是。List与Set的区别:List中的元素有存放顺序,并且可以存放重复元素,检索效率高,插入删...
    99+
    2014-12-16
    java教程 java 集合
  • WCF集合契约等价是什么
    本篇内容介绍了“WCF集合契约等价是什么”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!在WCF中应用了CollectionDataContr...
    99+
    2023-06-17
  • java 中集合的原理是什么
    这期内容当中小编将会给大家带来有关java 中集合的原理是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。一、概述集合是一种长度可变,存储数据的数据结构多样,存储对象多样的一种数据容器。Java中集合可...
    99+
    2023-06-20
  • Hibernate高级集合映射是什么
    本篇内容主要讲解“Hibernate高级集合映射是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Hibernate高级集合映射是什么”吧!Hibernate高级集合映射主要分为有序集合、双向...
    99+
    2023-06-17
  • python中字典和集合是什么
    这篇文章主要介绍了python中字典和集合是什么,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。字典/集合理解就像我们使用列表推导一样,我们也可以使用字典/集合推导。它们易于使...
    99+
    2023-06-27
  • laravel常用集合方法是什么
    本篇内容主要讲解“laravel常用集合方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“laravel常用集合方法是什么”吧!laravel常用集合方法有:filter()、search...
    99+
    2023-06-29
  • PL/SQL的包与集合是什么
    PL/SQL的包是一种存储过程、函数、变量和数据类型的逻辑单元,在数据库中封装了一组相关的程序和数据结构。包可以帮助组织和管理代码,...
    99+
    2024-05-08
    PL/SQL
  • mysql是什么的缩写
    mysql 的名称缩写源自创始人 michael widenius 女儿的昵称 my,代表着“maria”。 MySQL 的缩写 MySQL 是一个关系型数据库管理系统 (RDBMS)...
    99+
    2024-04-22
    mysql
  • mysql集群是什么意思
    mysql 集群是一种分布式系统,由多个 mysql 实例组成,旨在提高可扩展性、可用性和性能。集群包含 mysql 服务器、复制功能、负载均衡器和集群管理器。集群的好处包括可扩展性、高...
    99+
    2024-06-02
    mysql 高可扩展性 数据丢失
  • Java中的set集合是什么意思
    目录引言概念HashSet集合LinkedHashSet集合:TreeSet集合:实战场景引言 在前面的内容中,我们先是一一介绍了Collection集合中都有哪些种类的集合,并且详...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作