IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

Oracle hash分区的秘密

Hello DBA 2009-12-04 13:35:43 累计浏览 4,226 次
本机暂存

   我在面试时经常会问一个问题,请列举出hash在数据库内部的应用,hash的原理虽然简单,但是它在数据库中可以说是无处不在。其中hash partition是hash在数据库中一个简单的应用,虽然它没有range partition那么常用,但是我们在做数据库水平拆分时,其实就是利用了hash partition的原理,利用hash函数对某个key进行运算,然后将其分布到不同的主机上,原理很简单。

   我们在设计时遇到了一个问题,当分区的数量需要变化时,基于hash的原理,数据可能会从一个分区移动到另外一个分区,因为某个key在4个分区时,可能被分布在分区3,而在8个分区时,可能被分布在分区5。这样每当分区数量变化时,就需要全部重新分布数据,代价很高。

   那么Oracle是怎么做的?首先可以肯定的是Oracle的hash partition在分区增加时,不需要做全部数据的重新分布。有人告诉我Oracle的hash函数比较牛,可以保证分区数量增加时,这个hash函数可以让原来的数据还在旧的分区中,而新的数据可以分布在新的分区。Oracle的函数无非就是get_hash_value或ora_hash(10g),从hash的原理上来说,这也是不可能做到的。

   我们对hash partition都有一个常识,就是partition的数量最好是2的次方,也就是2,4,8,16……,否则分区会出现不分区均衡的现象,按照hash的原理,不管是几个分区,都可以做到完全均衡的,为什么会不均衡,其实答案已经出来了,Oracle为了能够增加分区,为你预留了几个看不到的分区。

   假设我们有6个分区,一共8000条数据,数据的分布如下图:

   原图已失效

   hash partition不能直接增加分区,而是split当前分区,当需要增加到8个分区时,实际上是分区3和分区4分别split产生新的分区7和分区8,如下图:

   原图已失效

   Oracle如何做到分区数量增加后,其他分区的数据不受影响呢,其实很简单,Oracle在做hash运算时,预留了分区,比如6个分区,实际上是用8个分区的hash来运算的,只不过把缺少的分区的数据合并到其他分区,这样就会出现数据不均衡的情况。Oracle的公式是这样的,用等于或者大于当前分区数量的最小的一个2的N次方,比如6个分区做8个hash bucket,4个分区还是做4个hash bucket。如果要把4个分区加为5个分区,实际上把分区1 split为分区5,这时因为有5个分区了,会使用8个hash bucket。一句话总结就是hash bucket总是2的N次方,如果分区数不足,则会合并数据,产生不均衡的情况,这样增加分区时,只需要对应分区的数据做split即可。同理,减少分区也不是简单的drop,而是合并分区。

   再回到我们的项目中,我们为了解决这个问题,采用了更简单的处理方案,直接就做了1024个分区,我们有8个物理数据库,每个数据库中有128个表,以后再分拆时,只要移动这些表,并修改应用中的对应关系就可以了。其实和Oracle合并再拆分的思路是一样的。

   这个问题其实在大牛lewis的Practical Oracle8i中讲过,当时我并没有仔细想清楚,现在想清楚了,特此记录。有些东西,明白了就觉得它挺简单的,希望对大家有帮助。原图已失效

同分类推荐文章

  1. 第七章 事务 (2026-04-07 08:00:00)
  2. 第六章:分区 (2026-03-29 08:00:00)
  3. Neko Master: 从 0 到 1K+ Star 的 Vibe Coding 实践 (2026-03-01 08:00:00)

查看更多 数据库 文章 →

建议继续学习

  1. Oracle MTS模式下 进程地址与会话信息 (累计阅读 14,316)
  2. 那些在11gR2中可能惹祸的新特性,一张列表帮助你摆脱升级11gR2带来的烦恼 (累计阅读 6,837)
  3. 性能测试工具sysbench简介 (累计阅读 5,965)
  4. 大于2GB的Listener.log和运行超过198天的主机上的Oracle实例 (累计阅读 5,809)
  5. 仅仅只备份是不够的 (累计阅读 5,767)
  6. Oracle Database 12c 新特性 - Native Top N 查询 (累计阅读 5,692)
  7. ORACLE最大可以存储多少数据量 (累计阅读 5,677)
  8. Oracle DBA的学习进阶成长树-从初出茅庐到高瞻远瞩 (累计阅读 5,543)
  9. 老托的Oracle 数据库Patch概念性小常识 (累计阅读 5,478)
  10. 查看oracle数据库用户下的所有空表 (累计阅读 5,449)