在mysql中,数据的存储其实相当于Oracle的IOT表。主键和其他列的值以b+tree的形式组织在一起,在其叶子节点上不仅包含了主键,还包含了其他列的值。所以,我们在访问以主键作为where条件的查询时,极大的提高了效率。当然,这也存在一个缺点,主键和其他列存在一起,导致主键作为index比其他二级index需要的空间开销更大,所以当我们做recover index scan时,就会需要scan更多的block。除此之外,我们还需要数据按照主键升序排列,所以我们的主键就可能要设置为自增的,以免随机的数字作为主键,导致数据块频繁分裂,而减缓dml的速度。所以,一般情况下,我们会默认给每张表都加上一个自增的id作为主键,这个id的类型依据实际存放的数据量的范围来定。

从第一段,我们了解到了主键产生的必要性,那么主键的冲突又是如何产生的呢?

在mysql中,一般存在两种replication,一种是ms(master-slave),一种是mm(master-master),在ms中,主键冲突的可能性一般为0,除非应用程序自己插的主键值,而没有使用主键的自增序列。

在master-slave replication中,每次都是在master端写,然后通过binlog传到slave端,slave的IO_therad将数据写到relaylog,然后SQL_therad读取relaylog的信息,来进行主库执行sql的重演,这个过程基本上称为逻辑复制。每次,slave端根据master.info中的信息向主库发送请求,主库接收到请求后启用binlog dump进程将binlog的信息传送到slave端,slave端的io线程得到信息后,将信息写入relay log,sql线程读取relay log信息进行重演,所以备库的信息和主库是一致的,不会存在主键冲突的问题,因为写数据总是在一端进行的。

然而,在master-master replication中,主键冲突却是个实实在在的问题。因为这种架构中,主库既作为主库,也作为另一个库的备库。这种架构主要是在写比较严重的情况下,缓解单个库的写压力。因此,在这种设计中,primary key collision的问题是个需要解决的问题。假如存在两台master相同表的primary key有相同的increment and offset,就会导致在A库上插入的纪录传到B库后,在往B库中的表插入数据时会存在主键冲突的问题 。下面是在electrictoolbox摘抄的一句话:

If you have auto incremental primary keys then the seed for the increment value needs to be different for each server, otherwise you could potentially have multiple servers attempt to insert records at the same time resulting in primary key conflicts.

You will notice in the configuration there is a setting for auto_increment_increment. This should be set to the number of servers there are. In the example in this post, there are 2 servers so it should be 2. If you intend to add other masters in the future then set it to a higher value.

The second setting is auto_increment_offset which should be set to the same as the server-id value. As an example, if server 1 inserted 5 records and then server 2 inserted 2 records the PKs inserted would be 1, 3, 5, 7, 9, 10, 12

一般,在我们在有n(n>1)个Mysql库作为MM的情况下,每个库的incement都设置为n,我们一般设置第1个库的

auto_increment_offset = 1

auto_increment_increment = n

所以在第1个mysql库上的第k(k为大于0的正整数)次插入记录的主键的值为1+n*(k-1)。

同理,第m(n=>m>1)个mysql库的设置为

auto_increment_offset = m

auto_increment_increment = n

所以第m个mysql库上的第h(h为大于0的正整数)次插入的记录的主键值为m+n*(h-1)

假设1+n*(k-1)=m+n*(h-1)进一步得到 1=m+n(h-k),由于1<m<=n,所以在h=k的情况下,1=m与m>1矛盾,不成立。同样,如果h-k<0,因为h和k都是正整数,所以h-k<=-1,所以m+n(h-k)<=m-n,而m<=n,所以m-n<=0,所以m+n(h-k)<=0即m+n(h-k)!=1,所以也不成立,同样,在h-k>0时,由于m>1,n>1,所以m+n(h-k)>1与m+n(h-k)=1矛盾,综上所述,不会存在主键冲突的情况。,所以这种设置不存在主键冲突的问题,有效地解决了mm复制的过程中主键冲突的问题。所以,我们在一个有n个Mysql库作为MM复制的环境中,设置第k(1<=k<=n)个库的auto_increment_increment =n,auto_increment_offset =k,如此,无论在哪个master进行insert,复制到其slave后,都不会出现主键冲突的问题。

Mysql primary key主键冲突的可能性与解决方案相关推荐

  1. 零基础带你学习MySQL—primary key主键(二十三)

    零基础带你学习MySQL-primary key主键(二十三) 一.约束 二.主键 三.主键的细节说明 主键不能重复而且不能为空 一张表最多只能有一个主键,但可以是复合键 使用desc 表名 可以看到 ...

  2. [MySQL] PRIMARY KEY 主键

    SQL PRIMARY KEY 约束 PRIMARY KEY 约束唯一标识数据库表中的每条记录. 主键必须包含唯一的值. 主键列不能包含 NULL 值. 每个表都应该有一个主键,并且每个表只能有一个主 ...

  3. default默认值 unique单列唯一和联合唯一 primary key主键 auto_increment自增 外键foregin key 表与表之间关系

    约束条件 之前讲过: zerofill (填充0) unsigned (约束条件值unsigned 无符号) not null 非空(不能插入空) 补充知识点 插入数据的时候可以指定字段 create ...

  4. primary key 主键

    4.1 问题 具体要求如下: 建表时,创建主键 在已有表里添加主键 建表时创建复合主键 删除主键 设置字段值自增长 4.2 步骤 实现此案例需要按照如下步骤进行. 步骤一:练习主键的使用 1)建表时设 ...

  5. mysql插入报主键冲突,解决方法主键索引重新排序

    mysql插入报主键冲突,解决方法主键索引重新排序 参考文章: (1)mysql插入报主键冲突,解决方法主键索引重新排序 (2)https://www.cnblogs.com/nizuimeiabc1 ...

  6. sqoop从hive导入数据到mysql时出现主键冲突

    今天在将一个hive数仓表导出到mysql数据库时出现进度条一直维持在95%一段时间后提示失败的情况,搞了好久才解决.使用的环境是HUE中的Oozie的workflow任何调用sqoop命令,该死的o ...

  7. MySQL与Oracle主键冲突解决方式

    1.MySQL主键冲突 当主键冲突时,可以选择更新或替换 1.1 主键冲突 主键冲突: mysql> desc my_class; +-------+-------------+------+- ...

  8. primary key主键与unique键的区别以及作用

    转载链接 共同作用是为了约束字段/建立索引/提高查询效率 mysql主键的属性: 1.主键具有唯一性:是指一张表里只能有一个主键: 2.主键作用:主键primary key是为了唯一标识一个字段,使其 ...

  9. Mysql完整性约束详解(字段唯一,非空,主键primary key,外键foreign key,自增长auto_increment)

    引入 1.什么是完整性约束, 为什么使用 为了规范数据格式, 在用户进行插入.修改.删除等操作时,DBMS(数据库管理系统(Data Base Management System))自动按照约束条件对 ...

  10. MySQL数据库约束(主键约束,外键约束详解)

    关系型数据库的一个重要功能: 需要保证数据的"完整性",可以通过人工的方式来观察确认数据的正确性,这种方式是可行的,但是不合适,因为人为控制的方式势必会存在疏忽,导致一些错误没有被 ...

最新文章

  1. Arm Cortex-M23 MCU,Arm Cortex-M33 MCU与RISC-V MCU技术
  2. 开源三级联动,Vue.js编写省份、城市、区、县三级联动源码
  3. linux grep 快速,51CTO博客-专业IT技术博客创作平台-技术成就梦想
  4. 针对CDP协议攻击分析及安全防护
  5. ios php 表单提交图片上传,axios发送post请求提交图片表单步骤详解
  6. tomcat上传文件到不同服务器,使用SpringMVC进行跨服务器上传文件出现的那些坑
  7. 成立一周?谷歌人工智能道德委员会解散了?近日,金山云和小米刚签订了不超过9000万的硬件产品供应协议,闹哪样? | 极客头条...
  8. 查询数据库表大小sql
  9. python 0xa什么意思_python使用xpath中遇到:Element a at 0x39a9a80到底是什么?
  10. javascript 高级程序设计(第4版)阅读笔记(一)
  11. syntaxhighlighter高亮动态代码
  12. 你还在用分页?试试 MyBatis 流式查询,真心强大!
  13. 功率放大电路工作状态
  14. vv7无法启动显示发动机故障_启动系统故障引起的发动机无法启动诊断方法
  15. cortex a8 java_ARM Cortex-
  16. 分子动力学模拟Gromacs一般使用步骤(空蛋白)
  17. python socket
  18. win7计算机管理禁用,win7提示windows凭据已被您的系统管理员禁用怎么办
  19. 【多线程】long和double的非原子性协定
  20. 图(Graph)详解 - 数据结构

热门文章

  1. HTC Vive Pro eye 眼动数据简单获取
  2. 齐齐哈尔2021高考成绩查询,2021齐齐哈尔市地区高考成绩排名查询,齐齐哈尔市高考各高中成绩喜报榜单...
  3. 石河子大学计算机专业录取分数线,石河子大学2020年录取分数线(附2017-2020年分数线)...
  4. 张博增是谁?为什么说他开启石墨烯的2.0时代!
  5. 抓取每天必应bing背景图片
  6. GPU版TensorFlow设置CPU运行的办法
  7. 解决:Android4.3锁屏界面Emergency calls only - China Unicom与EMERGENCY CALL语义重复
  8. Chaos Mesh介绍
  9. java生日提醒_生日提醒功能
  10. 决不放弃--实现人生的目标