[MDEV-24393] table_open_cache creates same number of advisory /proc/locks. Is it worth it? Created: 2020-12-11 Updated: 2023-07-04 Resolved: 2021-07-27 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Server, Storage Engine - InnoDB |
| Affects Version/s: | 10.5.8, 10.2, 10.3, 10.4, 10.5 |
| Fix Version/s: | 10.2.40, 10.3.31, 10.4.21, 10.5.12, 10.6.4 |
| Type: | Bug | Priority: | Minor |
| Reporter: | naox | Assignee: | Marko Mäkelä |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | None | ||
| Issue Links: |
|
||||||||||||||||||||||||||||
| Description |
|
MariaDB table_open_cache generates same and excessive number of advisory /proc/locks that causes OTHER programs on machine to waste cpu power ("sys load") when checking for locks. Are those really needed/worth it? |
| Comments |
| Comment by Daniel Black [ 2020-12-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
While its parially obvious the section of locks here are all mariadb lock (same pid - 28588, The inode of each entry seems unique (14......). Do you have https://mariadb.com/kb/en/innodb-file-per-table-tablespaces/ ? How many table_open_cache records are being used? Is there lots of temporary files open? Its not obvious that the kernel locks are the issue. With kernel and mariadb debug symbols installed, can you use `perf record -a -g – sleep 5`, can you show with `perf report-g --no-children --stdio -` what sys time is being used? If you look at `perf top` where is CPU time being spend? Have you eliminated other more obvious causes like slow queries, maybe a query plan of common queries has changed in the version upgrade from previous major version. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by naox [ 2020-12-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Afer further investigation I've completly changed ticket contents so need_feedback flag is obsolete | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2020-12-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
If you have a distro kernel there will be a package of kernel debug info symbols available for install. Packages mariadb versions also have debug symbol packages available. ref: https://mariadb.com/kb/en/how-to-produce-a-full-stack-trace-for-mysqld/#installing-debug-info-packages-on-linux . You will not been to recompile mariadb or kernel (unless you have already and aren't using packages). While I see locks, and I believe you see sys usage in load, there are many other changes between 10.3 and 10.5 and the cause may be something else. Please try to get some perf data to identify the cause of where CPU time is spent. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by naox [ 2020-12-11 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I'll rephrase: | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Daniel Black [ 2020-12-14 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Thanks for the rephrase. The advisory locks are pretty good at identifying and protecting duplicate mariadb processes from running on the same data. If both the advisory locks and the other tools are needed in their current form, I suggest we get some test cases together to take to the linux kernel people to get help resolving the usage (https://lore.kernel.org/linux-fsdevel/). | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2020-12-14 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
as far as I understand, advisory locking should not be used by default. You'd need to do something like --skip-external-locking=0 to make MariaDB server to use advisory locking. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by naox [ 2020-12-15 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I did not modify default settings of external-locking and still mariadb creates advisory locks in /proc/locks up to number of table_open_cache
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2020-12-18 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
InnoDB also uses advisory locks, but only when it creates new files. Do you constantly create new InnoDB tables? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by naox [ 2020-12-18 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Hosting kind of load (not fully known) so its not out of the question but I doubt it since I've observed same issue on every mariadb server out of 7 servers. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Elena Stepanova [ 2021-01-16 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
If I understand the complaint correctly, it's reproducible rather easily as long as InnoDB is involved on MariaDB 10.2+ (at least) and MySQL 5.7, 8.0 (at least). The raw test below creates 500 tables (more than table_open_cache allows) and checks the number of locks belonging to the MariaDB server in /proc/locks at different points.
It doesn't happen with MyISAM:
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2021-01-28 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
marko, why InnoDB takes these advisory locks? May be it could look at my_disable_locking variable (server's --skip-external-locking that disables advisory locks in MyISAM, Aria, and generally in the server), and do the same? | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-04-26 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
InnoDB acquires advisory locks in order to prevent data corruption due to misconfiguration (starting multiple instances of the server on the same data files). This protection mechanism has proven useful from time to time, if you search for the message in the Internet:
I suppose that we could disable os_file_lock() for users who claim that they know what they are doing. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2021-04-28 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Yes, that's what I suggested above. MyISAM/Aria also take advisory locks to prevent data corruption due to misconfiguration (starting multiple instances of the server on the same data files). This protection is disabled if the server is started with --skip-external-locking. It would be logical if InnoDB would also obey this option. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by naox [ 2021-04-28 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I'm just reminding that huge number of locks is only present if table_open_cache is set to high number (100k). When I've lowered it problem went away. So it can't be locks used for preventing multiple mysqld instances working on same datadir. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-07-23 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
serg, I applied the change that you suggested. Please review. I ran the test that elenst helpfully provided. With the following invocation, I am seeing 422 entries in /proc/locks; without the extra parameter, there would be just 1 entry.
I would not add the test to the regression test suite.
| |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Golubchik [ 2021-07-26 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I think I'd prefer InnoDB to invoke my_lock() for locking instead. But your patch is ok too. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Marko Mäkelä [ 2021-07-27 ] | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
my_lock() does more than we might want in low-level InnoDB code. Note: the default behavior will be changed. Because --skip-external-locking is activated by default, InnoDB will no longer acquire advisory file locks. |