`
agapple
  • 浏览: 1595928 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

mysql TableMap id递增问题

阅读更多

背景

   这两天在线上运行的mysql数据库同步,过个1,2天就爆了一次内存,所以dump了一下jvm内存信息分析了下,发觉就是tablemap对象的cache是一个罪魁祸首,2G的old区,平均被4个同步任务划分掉。

 

   解释下,缓存tablemap的意义:

   a.  insert/update/delete语句操作数据库时,在binlog中会产生两条binary log,第一条就是table map,告诉你改了的表信息。第二条才是具体的变更操作,通过一个tableId进行关联。

   b.  通过tableId缓存,可以在执行insert/update/delete解析的时候能够知道具体的表信息,然后根据schema + table name去反查一次数据库,获取字段名字,主键等信息。

 

   一般传统意义上的理解,tableId可以说是相对不太会变化,出现ddl操作时才会发生一次变化,所以这样的cache逻辑一直运行了1年多也没出过问题。

 

分析

   首先查询是否出现频繁的ddl变更,不过很可悲的是,查了半天发现最近几天没有发生过ddl操作,那table_id的频繁递增到底是因为什么原因?  

   网上找到一篇分析了table_id实现的文章: MySQL Binlog中TABLE ID源码分析

   文章中提到几点:

  • mysql会缓存table def,每次在写入binlog时,直接存入table def中关联的id. 
  • 比如有新的table变更时,在cache中没有,就会触发一次load table def的操作,此时就会在原先最后一次table_id基础上+1,做为新的table def的id
  • table cache如果超过限制,就会清理最久没用的table def (有点类似LRU)

   所以如果table def cache过小,就会出现频繁的换入换出,从而导致table_id增长比较快。

    

   查询了下线上mysql的一些参数和运行数据:

   

1.  查询table def cache

 

mysql> show variables like 'table%';
+------------------------+-------+
| Variable_name          | Value |
+------------------------+-------+
| table_definition_cache | 2048  | 
| table_open_cache       | 2048  | 
+------------------------+-------+

 

 

2.  查询当前使用的table def

 

mysql> show status like 'open%';
+--------------------------+----------+
| Variable_name            | Value    |
+--------------------------+----------+
| Open_files               | 14       | 
| Open_streams             | 0        | 
| Open_table_definitions   | 2048     | 
| Open_tables              | 2048     | 
| Opened_files             | 47198363 | 
| Opened_table_definitions | 1183     | 
| Opened_tables            | 1342     | 
+--------------------------+----------+

 

 

所以基本上table def cache一直是处于满的状态,统计了下表,因为存在分库分表,所以一个数据库实例上的表超过了6000张。

cache 2048 ,  table 6000张,势必会出现频繁的换入换出,这也就难怪table_id频繁增长了

 

 

解决

1.  tablemap cache策略以事务为单位进行局部cache,事务结束后清空tablemap cache,所以tableId的频繁增长不再会受到影响

2.  表结构的cache独立出来,以schmea + table name做为cache key,总的cache数也就会<=数据库中的表的总数

 

可以做的一个优化:

1.  针对分库分表的业务,基本上字段定义都是一样的,从内存dump的分析来看,一张表50个字段,表结构的定义大小大概为6kb,大部分都几种在column name(文本),其实可以利用String.intern()进行共享内存,1024张的分表可以只用一份表结构定义,内存可以从6MB ->  6KB. 

 

针对table_id增长的问题,这里还有一个其他风险:淘宝物流MySQL slave数据丢失详细原因

 

分享到:
评论

相关推荐

    mysql的插入问题 怎么获得自动增长的ID

    ### MySQL的插入问题:如何获取自动增长的ID 在MySQL中,经常需要用到自动增长的ID字段作为表的主键,特别是在频繁进行数据插入操作时。本文将深入探讨以下几个方面: 1. **理解自动增长ID的工作原理** 2. **在...

    mysql雪花算法生成唯一整型ID主键的实现方法

    MySQL 雪花算法生成唯一整型ID主键的实现主要针对大数据环境下,需要大量生成全局唯一ID的需求。雪花算法是一种分布式ID生成策略,由Twitter开源,其设计目标是在分布式系统中生成具有全局唯一性、有序性和高并发性...

    解决mysql failed to open table mysql.event

    在MySQL数据库系统中,"failed to open table mysql.event" 是一个常见的错误,通常表示数据库无法正确访问或加载`mysql.event`表。`mysql.event`是MySQL服务器用来存储定时任务(也称为事件Scheduler)的地方,当这...

    Mysql Table Difference SQL

    MySQL是世界上最流行的开源关系型数据库管理系统之一,而“Mysql Table Difference SQL”是一个与之相关的工具,主要用于自动化对比新旧数据库表结构的差异,并自动生成相应的SQL语句,以帮助开发者在项目升级过程中...

    MysqlTable.sql

    MysqlTable.sql

    MariaDB and MySQL common Table Expressions and Window Functions Revealed

    MariaDB and MySQL Common Table Expressions and Window Functions Revealed introduces and explains CTEs and window functions, newly available in MariaDB 10.2 and MySQL 8.0, and helps you understand why ...

    Create table mysql.rar_MYSQL_Table

    - `id`是主键,它自动递增并且不能为空。 - `name`是字符串类型,不能为空。 - `age`是整数类型,可以为空。 - `email`也是字符串类型,但必须唯一,可以为空。 接着,我们讨论一下设计表时的一些最佳实践: 1. **...

    MariaDB and MySQL Common Table Expressions and Window Functions Revealed epub

    MariaDB and MySQL Common Table Expressions and Window Functions Revealed 英文epub 本资源转载自网络,如有侵权,请联系上传者或csdn删除 本资源转载自网络,如有侵权,请联系上传者或csdn删除

    MySQL thread_cache和table_cache详解

    THREAD_CACHE MySQL里面为了提高客户端请求创建连接过程的性能,提供了一个连接池也就是 Thread_Cache池,将空闲的连接线程放在连接池中,而不是立即销毁.这样的好处就是,当又有一个新的请求的时候,mysql不会立即去创建...

    mysql启动提示mysql.host 不存在,启动失败的解决方法

    error 日志当中的记录: [ERROR] Fatal error: Can’t open and lock privilege tables: Table ‘mysql.host’ doesn’t exist 从发了帖子,只有人看,没有人回复,看到这种情况只能自己解决问题了,自己动手...

    MYSQL

    1.6 顺应2000年 1.7 SQL一般信息和教程 1.8 有用的MySQL相关链接 2 MySQL 邮件列表及如何提问或报告错误 2.1 MySQL邮件列表 2.2 提问或报告错误 2.3 怎样报告错误或问题 2.4 在...

    MySQL中文参考手册.chm

    1.6 顺应2000年 1.7 SQL一般信息和教程 1.8 有用的MySQL相关链接 2 MySQL 邮件列表及如何提问或报告错误 2.1 MySQL邮件列表 2.2 提问或报告错误 2.3 怎样报告错误或问题 ...

    Mysql错误:Every derived table must have its own alias

    在MySQL数据库操作中,"Every derived table must have its own alias" 是一个常见的错误提示,意味着在你的SQL查询语句中,使用了派生表(也称为子查询)但没有为它们分配唯一的别名。这个错误通常发生在试图从子...

    MySQL分表自增ID问题的解决方法

    然而,当进行分表后,传统的自增ID策略会遇到问题,因为MySQL的自动增量特性不适用于跨表的唯一标识生成。本篇文章将探讨如何解决MySQL分表自增ID的问题。 首先,我们了解MySQL自增ID的工作原理。MySQL的自增ID特性...

    mysql驱动jar 文件适用MySQL5.7

    MySQL驱动jar文件是Java应用程序与MySQL数据库之间通信的关键组件,主要功能是提供Java Database Connectivity (JDBC) API,使得Java开发者能够通过编写Java代码来执行SQL语句,从而操作MySQL数据库。标题提到的...

    MySQL查询随机数据的4种方法和性能对比

    $range_result = mysql_query("SELECT MAX(`id`) AS max_id, MIN(`id`) AS min_id FROM `table`"); $range_row = mysql_fetch_object($range_result); $random = mt_rand($range_row-&gt;min_id, $range_row-&gt;max_id); ...

    MySQL Edit Table:MySQL编辑器-PHP类-开源

    - **版本兼容**:由于MySQL数据库版本不断更新,使用前需要确认MySQL Edit Table是否与当前使用的MySQL版本兼容。 - **数据备份**:在进行任何编辑操作前,记得做好数据备份,以防意外情况导致数据丢失。 总的来说...

    MySQL中truncate误操作后的数据恢复案例

    实际线上的场景比较复杂,当时涉及了truncate, delete 两个...CREATE TABLE `tb_wubx` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREM

Global site tag (gtag.js) - Google Analytics