This performance issue seems more pronounced with Galera Cluster feature enabled using TOI but also affects standalone instances (admittedly I have seen this in the 10.0 series but have not tested 10.1 for this problem directly)
Attachments
Issue Links
duplicates
MDEV-13564TRUNCATE TABLE and undo tablespace truncation are not compatible with Mariabackup
Yes it is, but MySQL 5.8.0 is not yet released so back port is not yet possible. Furthermore, as one can see from developer comments there is no known working solution for 5.6 based MySQL.
Jan Lindström (Inactive)
added a comment - Yes it is, but MySQL 5.8.0 is not yet released so back port is not yet possible. Furthermore, as one can see from developer comments there is no known working solution for 5.6 based MySQL.
Apparently, despite the comment by Vasil Dimov, the change didn't make it to 5.7 after all, and it will be impossible to backport the fix to 5.7-based MySQL, too?
Anyway, I'm setting it to confirmed according to Jan's comment above, and for now I'll set the fix version to 10.2 so it stays on the radar. If 5.8 InnoDB won't make it to 10.2, which most likely will be the case, then the fix version will be updated to a later release.
Elena Stepanova
added a comment - Apparently, despite the comment by Vasil Dimov, the change didn't make it to 5.7 after all, and it will be impossible to backport the fix to 5.7-based MySQL, too?
Anyway, I'm setting it to confirmed according to Jan's comment above, and for now I'll set the fix version to 10.2 so it stays on the radar. If 5.8 InnoDB won't make it to 10.2, which most likely will be the case, then the fix version will be updated to a later release.
Upstream 8.0.0-dmr has changed fil_prepare_for_truncate and fil_truncate_tablespace in ./storage/innobase/fil/fil0fil.cc I believe to address this
MG
added a comment - Upstream 8.0.0-dmr has changed fil_prepare_for_truncate and fil_truncate_tablespace in ./storage/innobase/fil/fil0fil.cc I believe to address this
There are two recent changes to TRUNCATE TABLE in MySQL.
In MySQL 5.7, http://dev.mysql.com/worklog/task/?id=6501 implemented crash-safe TRUNCATE for single-table tablespaces in such a way that the *.ibd file is re-created with the same tablespace ID. For shared tablespaces (the InnoDB system tablespace or tablespaces created with CREATE TABLESPACE, which was introduced in MySQL 5.7), the files will not shrink and the logic will be somewhat different.
MySQL 8.0.0 includes WL#6795 as part of the WL#6378 umbrella (Global Data Dictionary). WL#6795 removes the low-level TRUNCATE code from InnoDB and implements TRUNCATE as a simple combination of DROP TABLE and CREATE TABLE. This would rely on a future worklog WL#7016 to implement atomic, crash-safe DDL. In MySQL 8.0.0, fil_truncate_tablespace() has nothing to do with TRUNCATE TABLE. It is only used for undo tablespace truncation: http://dev.mysql.com/worklog/task/?id=6965
When it comes to stalls, InnoDB fixed stalls for DROP TABLE quite some time ago. The WL#6501 TRUNCATE TABLE in MySQL 5.7 is holding dict_sys->mutex and dict_operation_lock while performing time-consuming tasks, such as dropping any adaptive hash index entries (pointers from buf_block_t::index to to-be-dropped dict_index_t).
Marko Mäkelä
added a comment - There are two recent changes to TRUNCATE TABLE in MySQL.
In MySQL 5.7, http://dev.mysql.com/worklog/task/?id=6501 implemented crash-safe TRUNCATE for single-table tablespaces in such a way that the *.ibd file is re-created with the same tablespace ID. For shared tablespaces (the InnoDB system tablespace or tablespaces created with CREATE TABLESPACE, which was introduced in MySQL 5.7), the files will not shrink and the logic will be somewhat different.
MySQL 8.0.0 includes WL#6795 as part of the WL#6378 umbrella (Global Data Dictionary). WL#6795 removes the low-level TRUNCATE code from InnoDB and implements TRUNCATE as a simple combination of DROP TABLE and CREATE TABLE. This would rely on a future worklog WL#7016 to implement atomic, crash-safe DDL. In MySQL 8.0.0, fil_truncate_tablespace() has nothing to do with TRUNCATE TABLE. It is only used for undo tablespace truncation: http://dev.mysql.com/worklog/task/?id=6965
When it comes to stalls, InnoDB fixed stalls for DROP TABLE quite some time ago. The WL#6501 TRUNCATE TABLE in MySQL 5.7 is holding dict_sys->mutex and dict_operation_lock while performing time-consuming tasks, such as dropping any adaptive hash index entries (pointers from buf_block_t::index to to-be-dropped dict_index_t).
While we definitely would like to have atomic truncate with ho stalls, I do not see that feasible on 10.2 with current deadlines. We have plans for own own global DD, thus moving this to 10.4 for now.
Jan Lindström (Inactive)
added a comment - While we definitely would like to have atomic truncate with ho stalls, I do not see that feasible on 10.2 with current deadlines. We have plans for own own global DD, thus moving this to 10.4 for now.
As I noted in MDEV-13328, I believe that it is feasible to fix some of this even while keeping the current InnoDB data dictionary.
It is possible that some bottleneck related to redo log checkpoint will remain until the crash recovery of TRUNCATE operations has been rewritten to rely on an undo log record. Such a change would necessarily be part of MDEV-515.
Marko Mäkelä
added a comment - As I noted in MDEV-13328 , I believe that it is feasible to fix some of this even while keeping the current InnoDB data dictionary.
It is possible that some bottleneck related to redo log checkpoint will remain until the crash recovery of TRUNCATE operations has been rewritten to rely on an undo log record. Such a change would necessarily be part of MDEV-515 .
I now realize that the original request was filed against MySQL 5.5.
The original request was that in TRUNCATE, InnoDB should release the file space while not holding any lock. To do that, we must change the undo or redo logging, so that we can ensure that no orphan files will be left behind in case the server is killed after the TRUNCATE transaction internally commits.
A similar problem exists in DROP TABLE. It would be better to release all locks and only after that start deleting the file. This would improve the performance for dropping large or heavily fragmented tables. We might be able to fix this in MariaDB 10.3.
I believe that in MySQL 5.7 (and in MariaDB 10.2.2 and 10.3), the performance of TRUNCATE degraded in some scenarios. Because the crash recovery of TRUNCATE uses separate log files, a redo log checkpoint will be part of the TRUNCATE execution. This could force all dirty pages to be written out from the buffer pool to the data files. I am afraid that we cannot fix this problem before MariaDB 10.4.
Marko Mäkelä
added a comment - I now realize that the original request was filed against MySQL 5.5.
The original request was that in TRUNCATE, InnoDB should release the file space while not holding any lock. To do that, we must change the undo or redo logging, so that we can ensure that no orphan files will be left behind in case the server is killed after the TRUNCATE transaction internally commits.
A similar problem exists in DROP TABLE. It would be better to release all locks and only after that start deleting the file. This would improve the performance for dropping large or heavily fragmented tables. We might be able to fix this in MariaDB 10.3.
I believe that in MySQL 5.7 (and in MariaDB 10.2.2 and 10.3), the performance of TRUNCATE degraded in some scenarios. Because the crash recovery of TRUNCATE uses separate log files, a redo log checkpoint will be part of the TRUNCATE execution. This could force all dirty pages to be written out from the buffer pool to the data files. I am afraid that we cannot fix this problem before MariaDB 10.4.
At the time I fixed WL#6795 in the development version of MySQL (called 5.8 at that time), the crash recovery part was not yet implemented. MySQL 8.0.3 was the first version to implement it.
In MySQL 8.0.3, the TRUNCATE indeed is implemented as rename, drop, and create. The question is: Does the "drop" part really fulfill the request that was stated in MySQL Bug #68184?
Let us look at innobase_basic_ddl::delete_impl() which implements the "drop" part of TRUNCATE in MySQL 8.0.3:
error = row_drop_table_for_mysql(
norm_name, trx, sqlcom, true, handler);
The caller does not appear to hold any global locks at this point. This operation does not look completely transactional or crash-safe, because row_drop_table_for_mysql_in_background() was not removed. But, the file deletion in fact does seem to be executed in the innobase_post_ddl() function, apparently after all locks have been released in Sql_cmd_truncate_table::truncate_table(). This corresponds to what I designed in WL#7016 and what was copied to WL#9536.
MariaDB cannot port the change from MySQL 8.0, because the solution depends on the Global Data Dictionary, which MariaDB will not implement in that form.
I think that MariaDB should eventually implement transactional logging and recovery for .frm files and DDL operations and remove the InnoDB internal data dictionary, and make InnoDB data files self-consistent so that InnoDB can find all relevant metadata in the .frm and .ibd files.
In MariaDB, TRUNCATE is an operation that does not modify .frm files. So, the TRUNCATE logging and recovery would have to be done completely inside InnoDB.
MDEV-13564 rewrote TRUNCATE TABLE in MariaDB 10.2.19 and 10.3.10 as a combination of RENAME, CREATE, DROP.
A remaining major cause of stalls would be addressed in MDEV-8069, where we should delete files of dropped tables after releasing all locks.
Marko Mäkelä
added a comment - MDEV-13564 rewrote TRUNCATE TABLE in MariaDB 10.2.19 and 10.3.10 as a combination of RENAME, CREATE, DROP.
A remaining major cause of stalls would be addressed in MDEV-8069 , where we should delete files of dropped tables after releasing all locks.
axel, jplindst, do you know if 10.1 is affected by this issue?