mysqldump注意问题一则


近期有同学使用mysqldump导出数据的时候,发现线下环境导出数据卡住,且导致mysql比较繁忙!同时dump的报错如下:

  1. mysqldump: Couldn't execute 'SELECT DISTINCT TABLESPACE_NAME, FILE_NAME, LOGFILE_GROUP_NAME,
  2. EXTENT_SIZE, INITIAL_SIZE, ENGINE FROM INFORMATION_SCHEMA.FILES WHERE FILE_TYPE = 'DATAFILE'
  3.  AND TABLESPACE_NAME IN (SELECT DISTINCT TABLESPACE_NAME FROM INFORMATION_SCHEMA.PARTITIONS
  4.   WHERE TABLE_SCHEMA IN ('dbname')) ORDER BY TABLESPACE_NAME, LOGFILE_GROUP_NAME


 于是对这条语句进行了explain,发现explain信息如下:

  1. +----+-------------+------------+------+---------------+--------------+---------+------+------+----------------------------------------------------------------------------------------------------------------------+
  2. | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
  3. +----+-------------+------------+------+---------------+--------------+---------+------+------+----------------------------------------------------------------------------------------------------------------------+
  4. | 1 | SIMPLE | FILES | ALL | NULL | NULL | NULL | NULL | NULL | Using where; Using temporary; Using filesort |
  5. | 1 | SIMPLE | PARTITIONS | ALL | NULL | TABLE_SCHEMA | NULL | NULL | NULL | Using where; Open_full_table; Scanned 1 database; Distinct; FirstMatch(FILES); Using join buffer (Block Nested Loop) |
  6. +----+-------------+------------+------+---------------+--------------+---------+------+------+----------------------------------------------------------------------------------------------------------------------+
  7. 2 rows in set (0.01 sec)

可以看到该sql会打开一个库,然后打开所有的表。我们知道,information.files表是memory engine,表的数据其实都是不存在的,所以这些表的信息需要通过遍历所有的物理文件获取。

  1. mysql> show create table INFORMATION_SCHEMA.FILES\G
  2. *************************** 1. row ***************************
  3.        Table: FILES
  4. Create Table: CREATE TEMPORARY TABLE `FILES` (
  5.   `FILE_ID` bigint(4) NOT NULL DEFAULT '0',
  6.   `FILE_NAME` varchar(64) DEFAULT NULL,
  7.   `FILE_TYPE` varchar(20) NOT NULL DEFAULT '',
  8.   `TABLESPACE_NAME` varchar(64) DEFAULT NULL,
  9.   `TABLE_CATALOG` varchar(64) NOT NULL DEFAULT '',
  10.   `TABLE_SCHEMA` varchar(64) DEFAULT NULL,
  11.   `TABLE_NAME` varchar(64) DEFAULT NULL,
  12.   `LOGFILE_GROUP_NAME` varchar(64) DEFAULT NULL,
  13.   `LOGFILE_GROUP_NUMBER` bigint(4) DEFAULT NULL,
  14.   `ENGINE` varchar(64) NOT NULL DEFAULT '',
  15.   `FULLTEXT_KEYS` varchar(64) DEFAULT NULL,
  16.   `DELETED_ROWS` bigint(4) DEFAULT NULL,
  17.   `UPDATE_COUNT` bigint(4) DEFAULT NULL,
  18.   `FREE_EXTENTS` bigint(4) DEFAULT NULL,
  19.   `TOTAL_EXTENTS` bigint(4) DEFAULT NULL,
  20.   `EXTENT_SIZE` bigint(4) NOT NULL DEFAULT '0',
  21.   `INITIAL_SIZE` bigint(21) unsigned DEFAULT NULL,
  22.   `MAXIMUM_SIZE` bigint(21) unsigned DEFAULT NULL,
  23.   `AUTOEXTEND_SIZE` bigint(21) unsigned DEFAULT NULL,
  24.   `CREATION_TIME` datetime DEFAULT NULL,
  25.   `LAST_UPDATE_TIME` datetime DEFAULT NULL,
  26.   `LAST_ACCESS_TIME` datetime DEFAULT NULL,
  27.   `RECOVER_TIME` bigint(4) DEFAULT NULL,
  28.   `TRANSACTION_COUNTER` bigint(4) DEFAULT NULL,
  29.   `VERSION` bigint(21) unsigned DEFAULT NULL,
  30.   `ROW_FORMAT` varchar(20) DEFAULT NULL,
  31.   `TABLE_ROWS` bigint(21) unsigned DEFAULT NULL,
  32.   `AVG_ROW_LENGTH` bigint(21) unsigned DEFAULT NULL,
  33.   `DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
  34.   `MAX_DATA_LENGTH` bigint(21) unsigned DEFAULT NULL,
  35.   `INDEX_LENGTH` bigint(21) unsigned DEFAULT NULL,
  36.   `DATA_FREE` bigint(21) unsigned DEFAULT NULL,
  37.   `CREATE_TIME` datetime DEFAULT NULL,
  38.   `UPDATE_TIME` datetime DEFAULT NULL,
  39.   `CHECK_TIME` datetime DEFAULT NULL,
  40.   `CHECKSUM` bigint(21) unsigned DEFAULT NULL,
  41.   `STATUS` varchar(20) NOT NULL DEFAULT '',
  42.   `EXTRA` varchar(255) DEFAULT NULL
  43. ) ENGINE=MEMORY DEFAULT CHARSET=utf8

深入源码,发现mysqldump这个sql的作用是dump tablespace,来看看源码的部分

  1. {"all-tablespaces", 'Y',
  2.    "Dump all the tablespaces.",
  3.    &opt_alltspcs, &opt_alltspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
  4.    0, 0},
  5.    
  6.     {"no-tablespaces", 'y',
  7.    "Do not dump any tablespace information.",
  8.    &opt_notspcs, &opt_notspcs, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
  9.    0, 0},
  10.    
  11.    
  12.  if (opt_alltspcs) //如果选择dump 所有的tablespace 信息
  13.     dump_all_tablespaces();
  14.    
  15.  if (opt_alldbs) //如果dump所有的db
  16.   {
  17.     if (!opt_alltspcs && !opt_notspcs) //如果没有指定dump 所有的tablesapce,也没有指定不dump所有的tablespce
  18.       dump_all_tablespaces();
  19.     dump_all_databases();
  20.   }
  21.  else
  22.   {
  23.     // Check all arguments meet length condition. Currently database and table
  24.     // names are limited to NAME_LEN bytes and stack-based buffers assumes
  25.     // that escaped name will be not longer than NAME_LEN*2 + 2 bytes long.
  26.     int argument;
  27.     for (argument= 0; argument < argc; argument++)
  28.     {
  29.       size_t argument_length= strlen(argv[argument]);
  30.       if (argument_length > NAME_LEN)
  31.       {
  32.         die(EX_CONSCHECK, "[ERROR] Argument '%s' is too long, it cannot be "
  33.           "name for any table or database.\n", argv[argument]);
  34.       }
  35.     }
  36.     if (argc > 1 && !opt_databases)
  37.     {
  38.       /* Only one database and selected table(s) */
  39.       if (!opt_alltspcs && !opt_notspcs)
  40.         dump_tablespaces_for_tables(*argv, (argv + 1), (argc - 1));
  41.       dump_selected_tables(*argv, (argv + 1), (argc - 1));
  42.     }
  43.     else
  44.     {
  45.       /* One or more databases, all tables */
  46.       if (!opt_alltspcs && !opt_notspcs)
  47.         dump_tablespaces_for_databases(argv);
  48.       dump_databases(argv);
  49.     }
  50.   }

我们看到,如果没有指定dump所有的tablespace,也没有指定不dump所有的tablespace信息,默认会dump所有的tablespace信息!!!
我们继续看看文档,关于tablespace的描述:

  1. --all-tablespaces, -Y
  2. Adds to a table dump all SQL statements needed to create any tablespaces used by an NDB table. This information is not otherwise included in the output from mysqldump. This option is currently relevant only to MySQL Cluster tables, which are not supported in MySQL 5.7.

可以看到这个tablespace的信息只在NDB cluster才存在,而我们线上都是非NDB的,所以我们dump数据的时候不需要这些信息。
因此显示的关闭一切就ok了!

  1. -y, --no-tablespaces
  2.                       Do not dump any tablespace information.

使用mysqldump进行MariaDB 的备份 

使用mysqldump导出数据库 

基于mysqldump快速搭建从库 

恢复mysqldump创建的备份集 

使用mysqldump命令行工具创建逻辑备份 

mysqldump实现数据库逻辑备份

本文永久更新链接地址

相关内容