MySQL optimze table 遇到唯一索引报错分析
对含唯一索引的表执行optimize table的时候,可能会遇到Optimize table fails with duplicate entry on UNIQUE KEY的错误下面分析下这个错误的原因mysql在执行optimize table的时候,内部会转化成alter table 使用online ddl的方式执行alter table 命令堆栈如下mysqld!mysql_recre
MySQL源码上理解下commit_order writeset writeset_session
主要是尝试从代码上看下sequence_number,last_committed的关系,看下各自分别怎么实现的。每个事务有2个逻辑时钟 @c Transaction_ctx::last_committed and @c Transaction_ctx::sequence_number.并行事务跟踪3种模式enum enum_binlog_transaction_depende
MySQL update一个诡异现象的分析
在数据库月报中的http://mysql.taobao.org/monthly/2022/12/04/ 这个案例中,session3没有更新行,这个问题的原因,我看代码没有分析出来,主要是打断点的时候,第三个session的执行总是打不上断点。主要是想跟踪下第三个回话执行的时候,cursor定位的记录标记成delete的后续处理,想看下mysql究竟是怎么处理的。有大佬感兴趣一起分析下吗
MySQL恢复过程
MySQL的xa recover 过程记录1 首先需要了解的是MySQL在启动的时候,会创建trx_sys,trx_sys_init_at_db_start在该函数中调用trx_lists_init_at_db_start,这个函数会去扫描undo 段,将未提交的事务添加到事务链表in_rw_trx_list中。2 开启binlog xa恢复的过程调用堆栈如下mysqld!ha_recover(s
MySQL8 非常有用的一个新特性
8.0做了非常多的强化,也改了很多特性,其中一个新特性对运维来说非常友好,操作上对业务影响也减少了很多。这个新特性就是针对schema级别的只读设置。运维中很大的一个操作就是拆库,一般业务小,会混合部署很多库,其中几个大了,就需要进行单独拆分到独立的实例。这种拆分在应用切换域名的时候,在一些切换场景下,需要停止旧主的写入,设置制度,所有库的写入都要受影响,8.0开始有了针对schema的只读设置,
MySQL8 show processlist 优化
he new SHOW PROCESSLIST executes an internal query of a new table, peformance_schema.processlist, rather than iterate across threads in the thread manager. 8.0之前版本的show processlist 数据是在threa
MySQL8.0的一个bug导致复制延时
升级8.0之前已经做过一些基准的性能测试,但是还是没有覆盖全面,线上数据库升级的时候遇到了复制性能问题。线上升级,先升级了一个从库,升级后,发现晚上业务跑批的时候,8.0的复制性能不如5.7,延时比较严重。我们使用的是8.0.23版本,通过排查,发现在8.0中transaction_write_set_extraction这个参数默认值是 XXHASH64,然而通过阅读代码,发现mysq
MySQL是否需要开启 swap
针对MySQL的服务器是否需要开启swap的问题,每个系统以及dba持有的观点都不一样。不开的原因,是说性能考虑,而且有内存告警,超了就应该挂掉。开的原因,是说哪怕MySQL慢,至少还活着。我的建议是数据敏感,注重数据的系统一定要开,注重性能的,保证系统不会有突然大量内存使用的系统,有告警的,可以关闭。
MySQL并行复制延时时间不准确
在MySQL中开启并行复制后,观察到延时不会是0,并且也没有什么大事务。很多文章已经有总结了,这里记录下。并行以及非并行下的复制延时的计算方式都是下面的代码{ long time_diff= ((long)(time(0) - mi->rli->last_master_timestamp) &n
datetime是8个字节?
之前的印象中datetime一直是占用8个字节,从来没去关注过是否正确,在解析数据文件的时候,datetime字段后面跟了一个timestamp字段,在解析timestamp时候,总是不对,后来发现是datetime字段解析有问题。datetime字段的存储1 bit sign &nb
MySQL字段究竟是否需要设置成not null
很多文章或开发规范都说,字段要设置成not null,很主要的原因是说省空间。真的如此吗?
MySQL解析文件fsp中的free list
最近在改进之前解析文件的程序,有一些内容之前没有解析,比如fsp上的free list,很多描述的文章中只是说这个是个节点的链表,但是具体怎么解析对应的字节,没有描述,所以看了下源码,通过看源码就比较清晰的知道怎么解析了。比如解析free list的Initializes a list base node. */ UNIV_INLINE voi
MySQL e二级索引上的一致性读
二级索引上没有rollpointer,所以只有当前版本,如果sql要通过二级索引查找数据,在存在多版本的情况下,还是要回到cluster index上进行多版本的查找。所以即使是select,性能也会出现不稳定的情况。下面是代码中的例子:create table t1(a int not null, b int, primary key(a), index(b));insert into t1 v
MySQL Redo log页内逻辑怎么理解
很多地方可以看到mysql redo. log不是物理格式,是物理逻辑格式,这种的逻辑是页内逻辑,但是怎么去理解这个页内逻辑的概念?如果是物理格式的话,那么内容就应该是具体的地址,以及具体的值。redo的内容不是具体的值,而是相对值,这样就好理解了。具体可以看下redo 的内容,比如delete命令产生的redo 如下:mysqld!page_cur_delete_rec_write_log(un
MySQL 页分裂中的锁3
数据在插入的过程中先进行乐观插入,失败使用悲观插入。在导致分页的记录插入使用了悲观插入。悲观插入中是持有tree的x-latch,分裂的时候,下一层的指针式node_ptr,dict_index_build_node_ptr 这个函数创建,node_ptr也是一个逻辑记录,根据下一层的第一个记录中的主键进行创建,创建后,当作记录插入到页中。root节点的分裂过程分配一个新页,拷贝root 记录到新
MySQL 唯一索引范围查询锁下一个记录的理解
相信大家研究过锁的同学,都知道在唯一索引的范围查询,会锁下一个记录,在mysql45讲中,作者也提到过,并且认为是个bug,但是官方没有确认,针对这个问题,我也思考了下,下面描述下我的理解,如果不正确,麻烦指正。mysql> show create table dba_test2\G ***************************
MySQL 锁bug?
mysql> select * from child;+-----+| id |+-----+| 2 || 102 |+-----+2 rows in set (4.00 sec)mysql> show create table child;+-------+----------------------------------------------
MySQL刷脏
MySQL刷脏,也是有个协调线程,通过不停的循环执行刷脏的任务,刷脏分为了2种类型,一种是刷lru,另一种是刷flush list.刷脏分为正常刷脏,sync flush和空闲刷脏,在正常刷脏和sync_flush 这两种是使用的同步刷,空闲刷使用的是异步刷,同步刷的情况忽略io_capacity的设置,空闲刷的方法是buf_flush_lists(PCT_IO(100), LSN_MA
MySQL purge 清理undo
如果history length 比较大,在purge的时候会导致脏页增多,purge的堆栈如下mysqld!trx_undo_truncate_start(trx_rseg_t*, unsigned long, unsigned long, unsigned long long) (/Users/xiaoyu.bai
MySQL redo log优化
看了其他人的blog,主要是学习下,跟着他们的blog看下对应的代码,另外也对mtr有了更多的了解。之前的mtr只是了解用来维护index的完整,用户产生的redo其实也是放在mtr中的,会将用户mtr中的redo刷到全局redo log buffer。redo log buffer 结构体中的mutext /** Redo log