我的 MariaDB 10.0 中有 1.800 (innodb) 个数据库,“mysqldump”运行非常慢!
如果我运行“mysqldump”将启动以下过程:
“从 INFORMATION_SCHEMA.FILES 中选择 LOGFILE_GROUP_NAME、FILE_NAME、TOTAL_EXTENTS、INITIAL_SIZE、ENGINE 和 EXTRA,其中 FILE_TYPE = 'UNDO LOG' 并且 FILE_NAME 不为空,并且 LOGFILE_GROUP_NAME 在(
从 INFORMATION_SCHEMA.FILES 中选择不同的 LOGFILE_GROUP_NAME,其中 FILE_TYPE = 'DATAFILE' 和 TABLESPACE_NAME 在(
从 INFORMATION_SCHEMA.PARTITIONS 中选择不同的 TABLESPACE_NAME,其中 TABLE_SCHEMA 在('table_test')))中按 LOGFILE_GROUP_NAME、FILE_NAME、ENGINE 按 LOGFILE_GROUP_NAME 排序”在 information_schema 中
如何修复?如何在“mysqldump”中禁用此过程?
谢谢你!
答案1
编辑:
问题是在 MariaDB 10.0.8 和 5.5.36 中得到确认,并确认在 MySQL 5.5.36 中不存在,显然是由于查询优化器的实现差异。
因此,下面的文本根据 MariaDB 的 Elena Stepanova 的建议进行了调整。
我在 Debian wheezy 上的 MariaDB 10.0.8 中重现了此行为。我无法在 MySQL 5.5.36 中重现它。
如果你执行mysqldump -uroot
,或者以任何具有完全权限的用户身份执行,这将生成一个查询,导致 MariaDB 的 mysqld 扫描数据库超级目录并全部子目录和全部表元数据全部这些子目录中的表。
如果您使用特定用户权限执行 mysqldump,并且这些权限仅被授予访问一个或两个数据库的权限,则 mysqldump 的速度会如您预期的那样快。
有两种解决方法。
解决方法A仍在使用具有所有数据库访问权限的超级特权用户,但通过禁用半连接功能来加快该过程。
解决方法 B创建一个备份用户,依次授予该用户对每个数据库的访问权限,从而缩小权限集。
哪种方法最适合您取决于您使用超级特权用户访问所有数据库的舒适程度、您有多少个数据库、有多少个用户有权访问多个数据库、有多少个数据库之间有依赖关系,以及在您进行数据库转储时如何访问您的数据库。
解决方法 A 可能是最快的,解决方法 B 稍微慢一些。
解决方法 A - 超级特权用户,禁用半连接
请注意,禁用半连接可能会影响其他查询的性能。虽然可以在 my.cnf 中设置,但您可能不应该这样做。
暂时禁用半连接:
SET GLOBAL optimizer_switch='semijoin=off';
转储数据库,例如以“root”用户身份:
mysqldump db -uroot -prootpassword | gzip > DB.sql.gz
重新启用半连接:
SET GLOBAL optimizer_switch='semijoin=on';
解决方法 B - 单独的备份用户
授予备份用户对数据库的全部权限:
GRANT USAGE ON `db`.* TO 'backup'@'%' IDENTIFIED BY 'backuppassword'; GRANT SELECT, LOCK TABLES ON `mysql`.* TO 'backup'@'%'; GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON `db`.* TO 'backup'@'%'; FLUSH PRIVILEGES;
以该用户的身份转储数据库:
mysqldump db -ubackup -pbackuppassword | gzip > DB.sql.gz
撤销权限:
REVOKE ALL PRIVILEGES ON `db`.* FROM 'backup'@'%'; REVOKE ALL PRIVILEGES ON `mysql`.* FROM 'backup'@'%'; FLUSH PRIVILEGES;
如果每个数据库都由单独的用户拥有,并且您知道这些用户的密码,那么您当然可以使用这些密码代替备份用户及其密码,从而完全跳过步骤 1 和 3。
顺便说一句:我还向 MariaDB 开发团队报告了这个问题,如果您有任何有用的贡献,请随时在这里跟进: