借鉴Oracle深入修改MySQL与PostgreSQL内核_第1页
借鉴Oracle深入修改MySQL与PostgreSQL内核_第2页
借鉴Oracle深入修改MySQL与PostgreSQL内核_第3页
借鉴Oracle深入修改MySQL与PostgreSQL内核_第4页
借鉴Oracle深入修改MySQL与PostgreSQL内核_第5页
已阅读5页,还剩47页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、技术创新,变革未来借鉴Oracle深入修改MySQL/PostgreSQL内核内容介绍借鉴Oracle增进PG/MYSQL内核实践:逻辑读的改进事务ID的可改进之处借鉴Oracle的计算与存储分离、可计算存储架构数据库最频繁的操作:逻辑读Redo Size是字节数,并不是次数。每秒超过52万次逻辑读,如果一次逻辑以读次可数以而节省论1:毫最高的是logical read。秒,52万次逻辑读,共可以节省520秒的CPU消耗。性能还不是最主要的。试想,如果一个路口,每秒要经 过52万辆车,万一这个路口出现事故,那怕只停一秒,就 会有52万辆车拥堵。这就是竞争带来的隐患。对于高频的操作,除性能之外,

2、竞争,也是要关注的点。PostgreSQL逻辑读:Shard Buffer的HASH表NODENODEPostgreSQL逻辑读:BufferAlloc()函数/计算HASH值10121015INIT_BUFFERTAG(newTag, smgr-smgr_rnode.node, forkNum, blockNum); newHash = BufTableHashCode(&newTag);/根据HASH值,得到Buffer Mapping Partition Lock1016newPartitionLock = BufMappingPartitionLock(newHash);/以共享模式持

3、有Buffer Mapping Partition Lock1019LWLockAcquire(newPartitionLock, LW_SHARED);/搜索HASH表1020buf_id = BufTableLookup(&newTag, newHash);/如果找到了,Buffer命中,进入条件。如果没找到,跳过此if语句,开始物理读102110221057if (buf_id = 0)return buf;开始物理读PostgreSQL逻辑读:BufferAlloc()函数/如果找到了,进入条件。如果没找到,跳过此if语句,开始物理读10211022if (buf_id = 0)/得到

4、Buffer Descripter结构:1028buf = GetBufferDescriptor(buf_id);/在Buffer Descripter结构上中Pin锁:1030valid = PinBuffer(buf, strategy);/释放Buffer Mapping Partition Lock1033LWLockRelease(newPartitionLock);/BufferAlloc()结束,进入读取行数据模块1056return buf;1057/Buffer未命中,开始物理读10631078LWLockRelease(newPartitionLock);buf = St

5、rategyGetBuffer(strategy, &buf_state);PostgreSQL逻辑读:BufferAlloc()函数/Buffer未命中,开始物理读1063LWLockRelease(newPartitionLock);/选择一个可覆盖页(牺牲页):1078buf = StrategyGetBuffer(strategy, &buf_state);/计算牺牲页的HASH值11801181oldTag = buf-tag;oldHash = BufTableHashCode(&oldTag);/计算牺牲页对应的Buffer Mapping Partition Lock1182o

6、ldPartitionLock = BufMappingPartitionLock(oldHash);/加Buffer Mapping Partition Lock,独占模式。1190LWLockAcquire(oldPartitionLock, LW_EXCLUSIVE);1191LWLockAcquire(newPartitionLock, LW_EXCLUSIVE);/在HASH表中,新的位置,插入一个Bucket1221buf_id = BufTableInsert(&newTag, newHash, buf-buf_id);PostgreSQL逻辑读:BufferAlloc()函数/

7、加Buffer Mapping Partition Lock,独占模式。1190LWLockAcquire(oldPartitionLock, LW_EXCLUSIVE);1191LWLockAcquire(newPartitionLock, LW_EXCLUSIVE);/在HASH表中,新的位置,插入一个Bucket1221buf_id = BufTableInsert(&newTag, newHash, buf-buf_id);/删除牺牲页在HASH表中的Bucket1321BufTableDelete(&oldTag, oldHash);/释放Buffer Mapping Partiti

8、on Lock13231326LWLockRelease(oldPartitionLock); LWLockRelease(newPartitionLock);内容介PostgreSQL逻辑读:HASH锁Buffer Mapping Partition Lock计算规则:127 #define BufTableHashPartition(hashcode) 128(hashcode) % NUM_BUFFER_PARTITIONS)/* Number of partitions of the shared buffer mapping hashtable*/#define NUM_BUFFER

9、_PARTITIONS 128即:MainLWLockArray 45 + HASH 值 % 128 .lock#define BufMappingPartitionLock(hashcode) (&MainLWLockArrayBUFFER_MAPPING_LWLOCK_OFFSET + 131BufTableHashPartition(hashcode).lock)HASH值 % 128代表了什么:Buffer Mapping Partition Lock数量有128个。MySQL逻辑读:HASH表buf_pool : page_hash:cells: n_cells:sync_obj.r

10、w_locks n_sync_obj: 16Lock 0Lock 1Lock 15Node 0Node 1Cells:page frame lockpage frame lockbuf_block_t:MySQL逻辑读简要流程从buf_page_get_gen()开始:4157Buf_fetch_normal fetch(page_id, page_size); 4167return (fetch.single_page();进入Buf_fetch_normal:single_page():3968 template 3969 buf_block_t *Buf_fetch:single_pag

11、e() 3975if (static_cast(this)-get(block) = DB_NOT_FOUND) 3976return (nullptr);3977MySQL逻辑读简要流程3415 dberr_t Buf_fetch_normal:get(buf_block_t *&block) 3417for (;) / 计算HASH值 得到HASH表锁 搜索HASH链 3421block = lookup();/ 如果HASH表中找到不相应Buffer,开始物理读3423if (block != nullptr) 3424buf_block_fix(block);/ 相当于在Buffer上

12、加Pin34253427rw_lock_s_unlock(m_hash_lock);/ 释放HASH表锁,狭义上的逻辑读到此结束3428break;3429/ 如果逻辑读没有命中,开始物理读3431/* Page not in buf_pool: needs to be read from file */3432read_page();3433MySQL逻辑读简要流程3489 template 3490 buf_block_t *Buf_fetch:lookup() / 计算HASH值,并根据HASH值得到Hash表锁3491m_hash_lock = buf_page_hash_lock_g

13、et(m_buf_pool, m_page_id);/ 加HASH表锁3495rw_lock_s_lock(m_hash_lock);/ 搜索HASH表3516if (block = nullptr) 3517block = reinterpret_cast(3518buf_page_hash_get_low(m_buf_pool, m_page_id);3519MySQL逻辑读简要流程/ 计算HASH值,并根据HASH值得到3491m_hash_lock = buf_page_hash_lock_get(m_buf_pool, m_page_id);2003 /* Get appropria

14、te page_hash_lock. */2004 #define buf_page_hash_lock_get(buf_pool, page_id) 2005hash_get_lock(buf_pool)-page_hash, (page_id).fold()hash_get_lock(buf_pool)-page_hash, (page_id).fold()计 算 Fload 值 : page_id_t:flod():179m_fold = (m_space page_hash-n_cells,17393。hash_get_lock(buf_pool)-page_hash, (page_i

15、d).fold()hash_get_sync_obj_index(table, fold);ut_2pow_remainder(hash_calc_hash(fold, table), table-n_sync_obj)ut_hash_ulint(fold, table-n_cells)/ 最终的计算HASH值的函数:121key = key UT_HASH_RANDOM_MASK2; 122123return (key % table_size);ut_2pow_remainder的定义:188 #define ut_2pow_remainder(n, m) (n) & (m)-1)n :

16、hash_calc_hash(fold, table)的返回值,刚计算出的HASH值m : table-n_sync_obj,即buf_pool-page_hash-n_sync_obj,值为16。ut_2pow_remainder的作用:Hash值 % m 。 最终,HASH锁的定位:buf_pool-sync_obj.rw_locks + 宏ut_2pow_remainder的结果MySQL逻辑读简要流程/ 计算HASH值,并根据HASH值得到3491m_hash_lock = buf_page_hash_lock_get(m_buf_pool, m_page_id);hash_get_l

17、ock(buf_pool)-page_hash, (page_id).fold() hash_get_Msyync_SobQj_LindexH(tAablSe,HfoldL);ock数量:ut_2pow_remainder(hash_calc_hash(fold, table), table-n_sync_obj)16个。MySQL逻辑读简要流程物理读时的HASH表锁:在buf_read_page_low()中:90bpage = buf_page_init_for_read(err, mode, page_id, page_size, unzip);在buf_page_init_for_re

18、ad()中:4616mutex_enter(&buf_pool-LRU_list_mutex);4617 4618hash_lock = buf_page_hash_lock_get(buf_pool, page_id);4619 4620rw_lock_x_lock(hash_lock);46214622buf_page_t *watch_page;逻辑读简要流程总结逻辑读流程总结:计算HASH值根据HASH值,计算并得到HASH表锁共享方式申请HASH表锁搜索HASH表如果找到目标BufferPin住Buffer释放HASH表锁如果HASH表中没有找到目标Buffer 换独占HASH表锁物

19、理读Oracle逻辑读流程CBC Latch : 全称Cache Buffers Chains Latch,就是HASH表锁,也就是PG中的Buffer Parittion Mapping Lock,MySQL中的Hash Lock。Oracle的HASH函数代码int sp1=0 x11; int sp2=0 x7f; int sp3=0 x7;int hash_header=0 x394953140;hash(int p1,int p2)int uk=p1; int rdba=p2;int v1,v2;int target_addr;uk=uksp1; v1=uk&sp2; v1=v10

20、xsp3; v2=v2 show variables like innodb_page_hash_locks;+ + +| Variable_name| Value |+ + +| innodb_page_hash_locks | 16|+ + +1 row in set (0.02 sec)两点限制:只能增大到1024只在Debug模式下,才有此参数修改内核 减少竞争 增进性能修改内核 减少竞争 增进性能修改内核 减少竞争 增进性能使用的动态内核跟踪语言:systemtap,统计脚本comp2.stp,局部代码:统计逻辑读次数:probe process(postgres).function

21、(FileRead) if ($amount = 8192)pread_num 1统计逻辑读时间:probe process(postgres).function(BufferAlloc) lgrpid(), BufferAlloc = 1tm1pid() = gettimeofday_us()probe process(postgres).function(ReadBuffer_common).return lgrpid(), BufferAlloc = 0lgrpid(), LWLockAcquire = 0 lgrpid(), StrategyGetBuffer = 0 lnum 1tm

22、2 max_trx_id % TRX_SYS_TRX_ID_WRITE_MARGIN) trx_sys_flush_max_trx_id();328 329330return (trx_sys-max_trx_id+); 331 MySQL的事务ID获取机制Select操作,在trx_start_low()中调用trx_sys_get_new_trx_id():1280trx_sys_mutex_enter();12811282trx-id = trx_sys_get_new_trx_id();DML操作,在trx_set_rw_mode()中调用trx_sys_get_new_trx_id(

23、): 3059mutex_enter(&trx_sys-mutex);30603061ut_ad(trx-id = 0);3062trx-id = trx_sys_get_new_trx_id();PostgreSQL事务ID的获取只读事务(Select)不会增加事务ID读写事务增加事务ID的方式: GetNewTransactionId():76LWLockAcquire(XidGenLock, LW_EXCLUSIVE);/以独占方式,得到全局的XidGenLock锁 77full_xid = ShmemVariableCache-nextFullXid; /从ShmemVariableC

24、ache-nextFullXid中,得到XID(即事 务ID)xid = XidFromFullTransactionId(full_xid);#define XidFromFullTransactionId(x)(uint32) (x).value)PostgreSQL事务ID的获取增加ShmemVariableCache-nextFullXid:185FullTransactionIdAdvance(&ShmemVariableCache-nextFullXid);static inline voidFullTransactionIdAdvance(FullTransactionId *dest) 85 dest-value+;while (XidFromFullTransactionId(*dest) value+;86878889 释放XidGenLock锁237LWLockRelease(XidGenLock);PostgreSQL事务ID竞争测试PostgreSQL事务ID竞争测试Oracle的事务ID(XID)策略MySQL/PostgreSQL:事务ID或XID即是事务的唯一标志,又代表事务的先后顺序Oracle:事务ID(即Oracle中的XID)仅仅是事务的唯一标志,并不代表先后顺序SCN,代表先后事务顺序。Oracle的事务ID策

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论