fix errant gtid
在遇到异常切换,或误操作的过程中,总是会遇到errant gtid的问题,通常的修复方式就是注入空事务,但是这种方式会导致从库上的数据与主库不一致。我们需要找出从库多出来的数据,进行确认是否需要在新主上修复。fix-errant-gtid可以在发生这种情况后,找到从库上的多余数据,并在文件中生成普通的insert sql,后面可以人工确认下,没有问题在进行后续修复操作。工作方式:连接到master
read view 可见性判断
m_low_limit_id=11m_up_limit_id=4m_ids = 4/5/6/9trx_id<4 能看见trx_id>= 11 不能看见trx_id=8 没在活跃列表中,提交提交了,可以看见 1 /2/ 3 (已提交) 4/5/6/9(活跃列表) 8(提交) 9(未提交) 10(提交)
一个crash case问题的猜测
线上在批量resize buffer的时候,从库会遇到crash的情况2024-12-27T02:52:17.267661Z 0 [Note] InnoDB: Completed to resize buffer pool from 15032385536 to 30064771
MySQL MEM_ROOT 内存分配
使用mem_root进行内存分配的操作,如果没有设置max_capacity,那么是不会限制的,内存不够了,就分配内存。如果设置了error_for_capacity_exceeded,那么超过限制,只会输出错误,还是会分配内存,所以针对这部分的内存,使用可能会超过预期的。默认设置:void init_alloc_root(PSI_memory_key key, MEM_RO
GDB使用场景
图形化的工具看代码很方便,gdb命令的方式相对原始,但是一些场景下还是需要gdb命令行。1 在调试MySQL还是有些问题,vs code 不支持non-stop调试,导致多线程的场景下没法调试单个线程,只能使用命令行2 在分析corefile的时候,还是在Linux上用命令行方便,因为需要相同的环境编译的版本,才能看文件的详细信息。通常服务器内存都比较大,生成的文件也很大,肯定在服务器上分析更快。
FLUSH NO_WRITE_TO_BINLOG BINARY LOGS 的风险点
在性能差的磁盘上,执行上面命令是有风险的,执行上面的命令过程中,会purge未在index 文件中的binlog ,如果过多,清理的时间慢,持有的Lock_log时间过长,会阻塞dml。这个风险点相对较高,一般线上机器磁盘性能高不会遇到这个问题,但是需要注意这个风险点。调用栈如下:MYSQL_BIN_LOG::purge_index_entry(THD*, unsigned l
半同步在线切换,切换后从库报数据重复错误
在开启使用after_sync半同步的集群上,执行了在线切换,切换过程中,旧主上报duplicate entry错误。分析:开启半同步的时候,在commit阶段,更新executed_gtid是在after_sync_hook之后,所以master在等待从库ack的过程中,如果这个过程比较慢,那么从库上的数据是会比主库的数据新。在主库更新executed_gtid 之前,调整了拓扑,并启动了复制,
MySQL并行复制2
MySQL5.7基于时间戳的并行复制,https://dev.mysql.com/worklog/task/?id=7165 中作了优化,之前是机遇parent- commit的并行,就是说在之前的事务都提交后开始的prepare能并行,这种方式并行度不够理想,然后换成了lock- base的并行,这种方式是同时进入prepare的就能并行,就是说在加锁阶段有重复,说明是互相之间没有锁的
MySQL是否需要设置not null -2
性能方面innodb_stats_method 这个参数会影响表的统计信息收集,影响统计信息的value group,默认值是nulls_equalIf the NULL value group size is much higher than the average non-NULL value group size, this method skews
Performance Schema导致的内存告警
线上处罚了内存告警,分析了下,Performance 内存分配还是有问题的虽然每个container 设置了page_size,page_count,但是这个不是硬性的限制,并发请求高的情况下还是超分内存,导致内存使用增高, page的分配也是没有回收,只是标记,然后新的请求使用。另外的一个问题是临时表的信息也记录到performance schema. 导致非必要的消耗,个人感觉临时表的信息可以
MySQL Buffer Pool Resize Crash分析
MySQL buffer pool在 resize后,导致了crash。 看下日志2023-06-26T03:10:12.510862Z 0 [Warning] InnoDB: A long semaphore wait: --Thread 140516243474176 has wai
MySQL中普通sql与预编译sql 区别
线程在初始化创建的时候,会使用init_sql_alloc分配main_mem_root部分,main_mem_root也是mem_root, 在sql执行时候使用。执行普通的sql,在转发sql后,回进行内存的分配,分配到mem_root中,会先在free列表中查找是否有足够的空间,没有就分配,有就返回分配的地址。调用堆栈如下:mysqld!alloc_root (/Users/xia
MySQL中的自增ID问题
MySQL中的表设置成自增ID,但是业务方使用的时候,会有一些意向不到的问题。问题1业务自增ID从0开始,使用SQL_MODE='NO_AUTO_VALUE_ON_ZERO' 设置后,ID从0开始,这种情况在进行数据迁移,以及数据对比的过程中,可能会触发工具的bug,导致失败问题2创建表时候,手工设置了auto_increment 的值,但是没有数据,然后用备份进行恢复的时候,au
slave_preserve_commit_order 的理解
slave_preserve_commit_order 这个参数文档上说是维持顺序,保持跟master一致,但是这个很容易理解成不能并发的组顺序乱序应用,其实不是,这个是指能并发执行的事务间的乱序。所以这个参数关闭后,从库在并行复制的时候,也会出现“Waiting for dependent transaction to commit“ 状态,这个在压测环境很容易复现slave1 [lo
线上online ddl不生效
遇到了线上集群online ddl不生效的问题,本应该使用inplace的走了copy.看了下代码,一开始看的是is_inplace_alter_imppossible,因为从名字来看就是判断是否能使用inplace的,但是看了一圈,夜没发现什么有用的信息,后面退出来看了mysql_alter_table中的流程,发现也有判断是否使用inplace的逻辑/*
Percona MySQL线程池的问题
MySQL 线程池针对大量连接的情况,减少了连接创建,销毁的开销,但是针对徒增的大流量来说,处理的不是很好,在繁忙的系统上,很容易出现连接打满的情况。而且看代码,里面针对连接限流的处理不是特别好,加大了这种情况的发生static ulonglong microsecond_throttling_interval(thread_group_t *thread_group
MySQL并行复制-源码理解记录
MySQL并行复制中,文章中提到在prepare阶段中的事务是可以并行执行的,那么这里指的处于prepare阶段的事务已经获取了锁,更新了数据文件,就等commit阶段的提交,更新事务状态,释放undo ,锁资源,所以prepare阶段的事务互相之间是不冲突的。看下代码中的顺序,确认下是否是先获取锁,然后在设置prepare状态的。在锁以及设置prepare的函数上设置断点,可以看到,是先执行了设
MySQL中的幂等复制分析
之前遇到复制异常,如果确定没有问题,都是跳过异常事务,最近看到了一个新的复制模式:幂等复制--slave-exec-mode=mode 这个参数默认是strict模式,可以设置成IDEMPOTENT,进入幂等复制模式官方文档中描述,这种模式能抑制duplicate-key and no-key-found errors;下面看下代码中的实现,首先是定义了幂等模式的错误码,对普通的错误码,进行了转
MySQL crash recovery恢复慢分析
mysql中的数据库比较多的时候,异常启动时间很慢l_data/xb_doublewrite 2023-02-10T03:10:13.386776Z 0 [Note] InnoDB: Opened 3 undo tablespaces 2023-02-10T03:10:13.386799Z 0 [Note
MySQL添加自增主键的坑
很多不规范的系统,由于各种各样的原因可能一开始没有主键,后面接手的dba,在推动规范化的时候,可能需要对这些表添加自增主键,在添加自增主键的时候,很可能会踩到这个坑。bug: 92949https://bugs.mysql.com/bug.php?id=92949 ## Use two concurrent connecitons on