一、故障介绍
最近遇到一个案例,以前从来没遇到过,环境为5.7,从库在执行optimize table语句的时候,出现了MTS hang死的情况,并且无法自动解锁,只能是重启整个数据库(kill -9),然后才可能恢复。模拟的截图如下,
当然线上MTS线程堵塞的比较多,但是模拟我只需要2个worker线程堵塞就可以了。这种堵塞状态视乎没有遇到过。因此有必要分析一下其可能的成因。相关参数,
- binlog_transaction_dependency_tracking :COMMIT_ORDER
- slave_parallel_type:LOGICAL_CLOCK
二、堵塞可能的分析
从红色部分我们可以看到worker线程有这些现象,
- 某个worker线程正在执行optimize table操作,处于表级别的MDL LOCK堵塞下,也就是Waiting for table metadata lock。
- 某个worker线程执行完了自己的工作,但是无法获取提交序列,也就是等待Waiting for preceding transaction to commit
并且2个worker线程无法自动解锁了,因此MTS整体处于hang死状态下。那么需要达到这个状态需要满足几个条件,
- Waiting for table metadata lock状态是table级别的MDL LOCK,那么必须要有前置的session 获取了testuuu表上的某种MDL LOCK,(需要注意的是optimize table和DML语句操作的是同一个表,这也是这个问题中比较难以理解的地方,因为MDL LOCK的存在很难说它们能够并发)因为optimize table类似DDL操作因此它一定会获取X MDL LOCK,因此只要session获取testuuu表上的某种MDL LOCK都会堵塞
- Waiting for preceding transaction to commit状态,是并发的下的一个等待,那么说明这个时候有相关的操作和optimize table操作进行了并发,并且了解到这个操作是DML 同表的操作,并且这个DML 操作提前来到了提交阶段,但是不是自己的提交序列因此不能提交。
那么同时满足这两个条件的那必须是,
- optimize table操作和DML 操作操作了同一表。
- optimize table操作和DML 操作的last commit必须相同,这样才可能并发。
- DML 操作的seq number必须要在optimize table操作之后,这样才能因为seq number原因DML 语句不能提交堵塞。
- DML 操作和optimize table操作虽然并发了,但是DML 必须要先执行完成,如果optimize table操作先完成则不会出堵塞。
但是这里有个明显的问题,DDL操作在提交时刻是上了X锁的,他会堵塞DML 操作,那么这种情况下last commit不可能相同,而第3点来讲这个是可以在从库进行控制的,主要是前面2点必须要达到。
三、主库侧分析
还是接着上面的问题,那我们猜测一下optimize table是否会出现提前解锁的情况,也就是提交没有包裹在MDL LOCK X 下面那么,就可能出现上面的状态,为了验证这个问题我们需要debug获取last commit的点也就是Transaction_ctx::store_commit_parent函数,同时打印出release MDL LOCK的信息,optimize table 如下,
Breakpoint 2, MDL_context::release_lock (this=0x7ffedc000c08, duration=MDL_TRANSACTION, ticket=0x7ffedc032e90) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
4350 MDL_lock *lock= ticket->m_lock;
4: ticket->m_lock->key.mdl_namespace() = MDL_key::SCHEMA
3: ticket->m_lock->key.db_name() = 0x7ffedc032bd5 "testslave0912"
2: ticket->m_lock->key.name() = 0x7ffedc032be3 ""
1: ticket->m_type = MDL_INTENTION_EXCLUSIVE
--- 释放表的X锁
Breakpoint 2, MDL_context::release_lock (this=0x7ffedc000c08, duration=MDL_TRANSACTION, ticket=0x7ffedc032e90) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
4350 MDL_lock *lock= ticket->m_lock;
4: ticket->m_lock->key.mdl_namespace() = MDL_key::TABLE
3: ticket->m_lock->key.db_name() = 0x7ffedc0248d5 "testslave0912"
2: ticket->m_lock->key.name() = 0x7ffedc0248e3 "testuuu"
1: ticket->m_type = MDL_SHARED_READ
--- 释放表上的SR锁
Breakpoint 3, Transaction_ctx::store_commit_parent (this=0x7ffedc004880, last_arg=2) at /opt/percona-server-locks-detail-5.7.22/sql/transaction_info.h:370
370 last_committed= last_arg;
--- 注意这里释放了table级别的MDL LOCK才获取了last commit,那么这个时候DML是可以执行的并且获取last commit的。
Breakpoint 2, MDL_context::release_lock (this=0x7ffedc000c08, duration=MDL_EXPLICIT, ticket=0x7ffedc032e90) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
4350 MDL_lock *lock= ticket->m_lock;
4: ticket->m_lock->key.mdl_namespace() = MDL_key::BINLOG
3: ticket->m_lock->key.db_name() = 0x2f9ae75 ""
2: ticket->m_lock->key.name() = 0x2f9ae76 ""
1: ticket->m_type = MDL_INTENTION_EXCLUSIVE
(gdb) c
Continuing.
看起来确实如此,optimize table语句在释放了MDL LOCK后才获取的last commit信息,并且这个时候DML语句也可以正常的获取last commit信息,那么就给并发创造了条件,接下来是我模拟出来的optimize table和delete 语句相同last commit的binlog片段,大概的过程如下,
断点 | session1 | session2 |
---|---|---|
Transaction_ctx::store_commit_parent | ||
optimize table testuuu;触发断点 | ||
delete from testuuu limit 1 触发断点 | ||
session1 继续语句执行成功生成binlog | ||
session2 继续语句执行成功生成binlog |
这样主库生成binlog的问题就解决了,接下来就是MTS并发了。
四、从库侧并发限制
对于这种DDL和DML语句混合并发的场景,需要考虑在MTS下是否有特殊的代码控制流程,也就是不并发,但是翻看SQL线程分发流程,并没有找到限制,因此我们可以将断点放到GTID event的应用上Gtid_log_event::do_apply_event,并且分析SQL线程分发流程函数Mts_submode_logical_clock::schedule_next_event,因为在GTID event执行的时候是一个事物的开始,这个时候并没有MDL LOCK,也可以控制到底哪个事务先执行。
这里主要就是让delete操作的event先执行,然后因为它的seq number比optimize table大,因此必然堵塞在Waiting for preceding transaction to commit状态下,并且因为没有提交,那么delete语句的MDL LOCK还持有,然后放开执行optimize table操作的worker线程,这个时候optimize table因为获取不到MDL LOCK因此就出现了堵塞,并且无法解决,也就是我们开始看到的问题。
五、optimize table和alter table engine=innodb
从我们上面的分析可以看到optimize table语句在5.7至少是有可能导致MTS从库hang死的情况,原因是optimize table在正式提交写binlog之前放开了MDL LOCK。
optimize table 在innodb引擎中实际上是重建整个表,这个和alter table engine=innodb达到的目的是一样的,那么alter table engine=innodb语句会不会有同样的问题,使用上面的分析方法,发现alter table engine=innodb语句在获取last commit的时候是在MDL LOCK X下面的,因此就会堵塞DML 语句不会出现问题,如下
Breakpoint 3, Transaction_ctx::store_commit_parent (this=0x7ffedc004880, last_arg=7) at /opt/percona-server-locks-detail-5.7.22/sql/transaction_info.h:370
370 last_committed= last_arg;
--- 这里获取last commit
...
Breakpoint 2, MDL_context::release_lock (this=0x7ffedc000c08, duration=MDL_TRANSACTION, ticket=0x7ffedc030a30) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
4350 MDL_lock *lock= ticket->m_lock;
4: ticket->m_lock->key.mdl_namespace() = MDL_key::TABLE
3: ticket->m_lock->key.db_name() = 0x7ffedc0248d5 "testslave0912"
2: ticket->m_lock->key.name() = 0x7ffedc0248e3 "testuuu"
1: ticket->m_type = MDL_EXCLUSIVE
--- 这里释放MDL LOCK X锁
既然提交堵塞同表的DML,那么就不可能模拟出last commit相同的情况,那么从库自然不可能并发,那么如果使用5.7的MTS 最好少执行optimize table语句。 后续需要分析8.0是否可能有这种问题,但是感觉可能性不大。
六、其他
1、制造主库last commit一致的情况,并且DML的seq number大于DDL,目的在于DML在从库先执行的情况下,不能获取到提交序列
2、从库先启动IO thread,目的在于积累一下主库过来的binlog计入relay log中,让并行回放能够发挥作用。
3、观察relay log已经传过来了同样last commit的DDL和MDL 并且MDL的seq number小于DDL。
4、断点open table,确认从库先执行的是DML语句先执行,这个时候会等待提交队列到来,但是这个时候MDL LOCK没有释放
5、执行DDL语句,DDL语句必然等待在meta lock上。
#0 Logical_clock::get_timestamp (this=0x7fff992dc480) at /opt/mysql-5.7.40/sql/rpl_trx_tracking.cc:40
#1 0x00000000014571dc in Transaction_dependency_tracker::get_max_committed_timestamp (this=0x2cebeb0 <mysql_bin_log+5232>) at /opt/mysql-5.7.40/sql/rpl_trx_tracking.cc:406
#2 0x00000000017d8650 in MYSQL_BIN_LOG::commit (this=0x2ceaa40 <mysql_bin_log>, thd=0x7fff7c0010c0, all=false) at /opt/mysql-5.7.40/sql/binlog.cc:8751
#3 0x0000000001627632 in trans_commit_stmt (thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/transaction.cc:470
#4 0x000000000152c318 in mysql_execute_command (thd=0x7fff7c0010c0, first_level=true) at /opt/mysql-5.7.40/sql/sql_parse.cc:4994
#5 0x000000000152dace in mysql_parse (thd=0x7fff7c0010c0, parser_state=0x7fff992de580) at /opt/mysql-5.7.40/sql/sql_parse.cc:5589
#6 0x00000000015232cd in dispatch_command (thd=0x7fff7c0010c0, com_data=0x7fff992dece0, command=COM_QUERY) at /opt/mysql-5.7.40/sql/sql_parse.cc:1492
#7 0x0000000001522134 in do_command (thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/sql_parse.cc:1031
#8 0x0000000001655dfa in handle_connection (arg=0x6db36e0) at /opt/mysql-5.7.40/sql/conn_handler/connection_handler_per_thread.cc:313
#9 0x0000000001ce8ce0 in pfs_spawn_thread (arg=0x6cdbee0) at /opt/mysql-5.7.40/storage/perfschema/pfs.cc:2197
#10 0x00007ffff7bbb764 in start_thread (arg=<optimized out>) at pthread_create.c:477
#11 0x00007ffff60ade2f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
#0 Transaction_ctx::store_commit_parent (this=0x7fff7c004a70, last_arg=4) at /opt/mysql-5.7.40/sql/transaction_info.h:398
#1 0x00000000017d8662 in MYSQL_BIN_LOG::commit (this=0x2ceaa40 <mysql_bin_log>, thd=0x7fff7c0010c0, all=false) at /opt/mysql-5.7.40/sql/binlog.cc:8751
#2 0x0000000001627632 in trans_commit_stmt (thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/transaction.cc:470
#3 0x000000000152c318 in mysql_execute_command (thd=0x7fff7c0010c0, first_level=true) at /opt/mysql-5.7.40/sql/sql_parse.cc:4994
#4 0x000000000152dace in mysql_parse (thd=0x7fff7c0010c0, parser_state=0x7fff992de580) at /opt/mysql-5.7.40/sql/sql_parse.cc:5589
#5 0x00000000015232cd in dispatch_command (thd=0x7fff7c0010c0, com_data=0x7fff992dece0, command=COM_QUERY) at /opt/mysql-5.7.40/sql/sql_parse.cc:1492
#6 0x0000000001522134 in do_command (thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/sql_parse.cc:1031
#7 0x0000000001655dfa in handle_connection (arg=0x6db36e0) at /opt/mysql-5.7.40/sql/conn_handler/connection_handler_per_thread.cc:313
#8 0x0000000001ce8ce0 in pfs_spawn_thread (arg=0x6cdbee0) at /opt/mysql-5.7.40/storage/perfschema/pfs.cc:2197
#9 0x00007ffff7bbb764 in start_thread (arg=<optimized out>) at pthread_create.c:477
#10 0x00007ffff60ade2f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
#0 Commit_order_trx_dependency_tracker::update_max_committed (this=0x2cebf08 <mysql_bin_log+5320>, sequence_number=6) at /opt/mysql-5.7.40/sql/rpl_trx_tracking.cc:165
#1 0x00000000014570d6 in Transaction_dependency_tracker::update_max_committed (this=0x2cebeb0 <mysql_bin_log+5232>, thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/rpl_trx_tracking.cc:374
#2 0x00000000017d930d in MYSQL_BIN_LOG::process_commit_stage_queue (this=0x2ceaa40 <mysql_bin_log>, thd=0x7fff7c0010c0, first=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/binlog.cc:9038
#3 0x00000000017dacd6 in MYSQL_BIN_LOG::ordered_commit (this=0x2ceaa40 <mysql_bin_log>, thd=0x7fff7c0010c0, all=false, skip_commit=false) at /opt/mysql-5.7.40/sql/binlog.cc:9762
#4 0x00000000017d8d2c in MYSQL_BIN_LOG::commit (this=0x2ceaa40 <mysql_bin_log>, thd=0x7fff7c0010c0, all=false) at /opt/mysql-5.7.40/sql/binlog.cc:8870
#5 0x0000000001627632 in trans_commit_stmt (thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/transaction.cc:470
#6 0x000000000152c318 in mysql_execute_command (thd=0x7fff7c0010c0, first_level=true) at /opt/mysql-5.7.40/sql/sql_parse.cc:4994
#7 0x000000000152dace in mysql_parse (thd=0x7fff7c0010c0, parser_state=0x7fff992de580) at /opt/mysql-5.7.40/sql/sql_parse.cc:5589
#8 0x00000000015232cd in dispatch_command (thd=0x7fff7c0010c0, com_data=0x7fff992dece0, command=COM_QUERY) at /opt/mysql-5.7.40/sql/sql_parse.cc:1492
#9 0x0000000001522134 in do_command (thd=0x7fff7c0010c0) at /opt/mysql-5.7.40/sql/sql_parse.cc:1031
#10 0x0000000001655dfa in handle_connection (arg=0x6db36e0) at /opt/mysql-5.7.40/sql/conn_handler/connection_handler_per_thread.cc:313
#11 0x0000000001ce8ce0 in pfs_spawn_thread (arg=0x6cdbee0) at /opt/mysql-5.7.40/storage/perfschema/pfs.cc:2197
#12 0x00007ffff7bbb764 in start_thread (arg=<optimized out>) at pthread_create.c:477
#13 0x00007ffff60ade2f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) info b
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000e8166c in main(int, char**) at /opt/mysql-5.7.40/sql/main.cc:32
breakpoint already hit 1 time
2 breakpoint keep y 0x00000000017e0fe8 in Transaction_ctx::store_commit_parent(long long) at /opt/mysql-5.7.40/sql/transaction_info.h:398
breakpoint already hit 7 times
3 breakpoint keep y 0x00000000014572fa in Logical_clock::get_timestamp() at /opt/mysql-5.7.40/sql/rpl_trx_tracking.cc:40
breakpoint already hit 6 times
5 breakpoint keep y 0x0000000001456a36 in Commit_order_trx_dependency_tracker::update_max_committed(long long) at /opt/mysql-5.7.40/sql/rpl_trx_tracking.cc:165
breakpoint already hit 2 times
6 breakpoint keep y 0x0000000001421789 in MDL_context::acquire_lock(MDL_request*, unsigned long) at /opt/mysql-5.7.40/sql/mdl.cc:3564
breakpoint already hit 17 times
7 breakpoint keep y <MULTIPLE>
breakpoint already hit 13 times
7.1 y 0x000000000142295a in MDL_context::release_lock(enum_mdl_duration, MDL_ticket*) at /opt/mysql-5.7.40/sql/mdl.cc:4286
7.2 y 0x0000000001422cd2 in MDL_context::release_lock(MDL_ticket*) at /opt/mysql-5.7.40/sql/mdl.cc:4417
(gdb) d 6
#240918 11:29:49 server id 322 end_log_pos 28019 CRC32 0xecee4a11 GTID last_committed=81 sequence_number=82 rbr_only=no
SET @@SESSION.GTID_NEXT= 'ec9f995d-e5a1-11ee-900b-000c2963503f:104'/*!*/;
# at 28019
#240918 11:29:49 server id 322 end_log_pos 28133 CRC32 0x7aba525e Query thread_id=4 exec_time=1 error_code=0
SET TIMESTAMP=1726630189/*!*/;
optimize table testuuu
/*!*/;
# at 28133
#240918 11:29:55 server id 322 end_log_pos 28198 CRC32 0x6b33d92a GTID last_committed=81 sequence_number=83 rbr_only=yes
/*!50718 SET TRANSACTION ISOLATION LEVEL READ COMMITTED*//*!*/;
SET @@SESSION.GTID_NEXT= 'ec9f995d-e5a1-11ee-900b-000c2963503f:105'/*!*/;
# at 28198
#240918 11:29:55 server id 322 end_log_pos 28279 CRC32 0x76c956ab Query thread_id=5 exec_time=0 error_code=0
SET TIMESTAMP=1726630195/*!*/;
BEGIN
/*!*/;
# at 28279
#240918 11:29:55 server id 322 end_log_pos 28330 CRC32 0xb13102e7 Rows_query
# delete from testuuu limit 1
# at 28330
#240918 11:29:55 server id 322 end_log_pos 28389 CRC32 0x621ca080 Table_map: `testslave0912`.`testuuu` mapped to number 117
# at 28389
#240918 11:29:55 server id 322 end_log_pos 28429 CRC32 0x98691042 Delete_rows: table id 117 flags: STMT_END_F
BINLOG '
M0nqZh1CAQAAMwAAAKpuAACAABtkZWxldGUgZnJvbSB0ZXN0dXV1IGxpbWl0IDHnAjGx
M0nqZhNCAQAAOwAAAOVuAAAAAHUAAAAAAAEADXRlc3RzbGF2ZTA5MTIAB3Rlc3R1dXUAAQMAAYCg
HGI=
M0nqZiBCAQAAKAAAAA1vAAAAAHUAAAAAAAEAAgAB//4BAAAAQhBpmA==
'/*!*/;
### DELETE FROM `testslave0912`.`testuuu`
### WHERE
### @1=1 /* INT meta=0 nullable=1 is_null=0 */
# at 28429
#240918 11:29:55 server id 322 end_log_pos 28460 CRC32 0x9a4c1bbd Xid = 126
COMMIT/*!*/;
SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;
DELIMITER ;
# End of log file
/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;
/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000eb13ac in main(int, char**) at /opt/percona-server-locks-detail-5.7.22/sql/main.cc:25
breakpoint already hit 1 time
3 breakpoint keep y 0x00000000017efb70 in Gtid_log_event::do_apply_event(Relay_log_info const*) at /opt/percona-server-locks-detail-5.7.22/sql/log_event.cc:13859
breakpoint already hit 2 times
5 breakpoint keep y 0x0000000001877113 in Mts_submode_logical_clock::wait_for_last_committed_trx(Relay_log_info*, long long, long long) at /opt/percona-server-locks-detail-5.7.22/sql/rpl_mts_submode.cc:456
(gdb) d 3
Mts_submode_logical_clock::wait_for_last_committed_trx
Transaction_ctx::store_commit_parent(long long)
alter table engine=innodb;
#0 Transaction_ctx::store_commit_parent (this=0x7ffedc004880, last_arg=5) at /opt/percona-server-locks-detail-5.7.22/sql/transaction_info.h:370
#1 0x0000000001815f5e in MYSQL_BIN_LOG::commit (this=0x2dc09e0 <mysql_bin_log>, thd=0x7ffedc000b70, all=false) at /opt/percona-server-locks-detail-5.7.22/sql/binlog.cc:8889
#2 0x0000000000f54824 in ha_commit_trans (thd=0x7ffedc000b70, all=false, ignore_global_read_lock=false) at /opt/percona-server-locks-detail-5.7.22/sql/handler.cc:1830
#3 0x0000000001676337 in trans_commit_stmt (thd=0x7ffedc000b70) at /opt/percona-server-locks-detail-5.7.22/sql/transaction.cc:458
#4 0x0000000001570408 in mysql_execute_command (thd=0x7ffedc000b70, first_level=true) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5293
#5 0x0000000001571bed in mysql_parse (thd=0x7ffedc000b70, parser_state=0x7fffec1255b0) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#6 0x000000000156673d in dispatch_command (thd=0x7ffedc000b70, com_data=0x7fffec125d90, command=COM_QUERY) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490
#7 0x00000000015655c5 in do_command (thd=0x7ffedc000b70) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1021
#8 0x00000000016a635c in handle_connection (arg=0x64c3f10) at /opt/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:312
#9 0x00000000018ce0f6 in pfs_spawn_thread (arg=0x6554610) at /opt/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#10 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#11 0x00007ffff66008dd in clone () from /lib64/libc.so.6
optimize table 提前释放了MDL LOCK
Breakpoint 2, MDL_context::release_lock (this=0x7ffedc000c08, duration=MDL_TRANSACTION, ticket=0x7ffedc032e90) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
4350 MDL_lock *lock= ticket->m_lock;
4: ticket->m_lock->key.mdl_namespace() = MDL_key::TABLE
3: ticket->m_lock->key.db_name() = 0x7ffedc0248d5 "testslave0912"
2: ticket->m_lock->key.name() = 0x7ffedc0248e3 "testuuu"
1: ticket->m_type = MDL_EXCLUSIVE
(gdb) bt
#0 MDL_context::release_lock (this=0x7ffedc000c08, duration=MDL_TRANSACTION, ticket=0x7ffedc032e90) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4350
#1 0x0000000001464bf1 in MDL_context::release_locks_stored_before (this=0x7ffedc000c08, duration=MDL_TRANSACTION, sentinel=0x0) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4521
#2 0x00000000014653c5 in MDL_context::release_transactional_locks (this=0x7ffedc000c08) at /opt/percona-server-locks-detail-5.7.22/sql/mdl.cc:4805
#3 0x0000000001776fa8 in mysql_admin_table(THD *, TABLE_LIST *, HA_CHECK_OPT *, const char *, thr_lock_type, bool, bool, uint, int (*)(THD *, TABLE_LIST *, HA_CHECK_OPT *), struct {...}, int (*)(THD *, TABLE_LIST *)) (thd=0x7ffedc000b70, tables=0x7ffedc006588, check_opt=0x7ffedc0036a0, operator_name=0x21fcdf0 "optimize", lock_type=TL_WRITE, open_for_modify=false,
repair_table_use_frm=false, extra_open_options=0, prepare_func=0x0, operator_func=
(int (handler::*)(handler * const, THD *, HA_CHECK_OPT *)) 0xf5ca60 <handler::ha_optimize(THD*, st_ha_check_opt*)>, view_operator_func=0x0)
at /opt/percona-server-locks-detail-5.7.22/sql/sql_admin.cc:830
#4 0x000000000177861d in Sql_cmd_optimize_table::execute (this=0x7ffedc006b20, thd=0x7ffedc000b70) at /opt/percona-server-locks-detail-5.7.22/sql/sql_admin.cc:1272
#5 0x000000000156fb51 in mysql_execute_command (thd=0x7ffedc000b70, first_level=true) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5117
#6 0x0000000001571bed in mysql_parse (thd=0x7ffedc000b70, parser_state=0x7fffec1255b0) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:5901
#7 0x000000000156673d in dispatch_command (thd=0x7ffedc000b70, com_data=0x7fffec125d90, command=COM_QUERY) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1490
#8 0x00000000015655c5 in do_command (thd=0x7ffedc000b70) at /opt/percona-server-locks-detail-5.7.22/sql/sql_parse.cc:1021
#9 0x00000000016a635c in handle_connection (arg=0x659fa40) at /opt/percona-server-locks-detail-5.7.22/sql/conn_handler/connection_handler_per_thread.cc:312
#10 0x00000000018ce0f6 in pfs_spawn_thread (arg=0x6594e50) at /opt/percona-server-locks-detail-5.7.22/storage/perfschema/pfs.cc:2190
#11 0x00007ffff7bc6ea5 in start_thread () from /lib64/libpthread.so.0
#12 0x00007ffff66008dd in clone () from /lib64/libc.so.6