ITPub博客

首页 > 数据库 > MySQL > information_schema里的表每次select时新建?

information_schema里的表每次select时新建?

原创 MySQL 作者:psufnxk2000 时间:2016-11-25 18:45:47 0 删除 编辑


information_schema里的表每次select时新建?


起因:
InnoDB temporary table metadata is no longer stored to InnoDB system tables. Instead, a new table,INNODB_TEMP_TABLE_INFO, provides users with a snapshot of active temporary tables. The table contains metadata and reports on all user and system-created temporary tables that are active within a given InnoDBinstance. The table is created when the first SELECT statement is run against it.
innodb临时表的metadata不再存放在系统表,而是放在 INNODB_TEMP_TABLE_INFO, 这个表在每次select的时候建立。
mysql> use test;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A


Database changed
mysql> create temporary table tmp_a(id int);
Query OK, 0 rows affected (0.00 sec)


mysql>  select now(), t.* from information_schema.tables t  where table_name='innodb_temp_table_info'\G
*************************** 1. row ***************************
          now(): 2016-11-25 17:24:27                 --注意这个时间
  TABLE_CATALOG: def
   TABLE_SCHEMA: information_schema
     TABLE_NAME: INNODB_TEMP_TABLE_INFO
     TABLE_TYPE: SYSTEM VIEW
         ENGINE: MEMORY
        VERSION: 10
     ROW_FORMAT: Fixed
     TABLE_ROWS: NULL
 AVG_ROW_LENGTH: 1011
    DATA_LENGTH: 0
MAX_DATA_LENGTH: 16694643
   INDEX_LENGTH: 0
      DATA_FREE: 0
 AUTO_INCREMENT: NULL
    CREATE_TIME: 2016-11-25 17:24:27                 --注意这个时间
    UPDATE_TIME: NULL
     CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
       CHECKSUM: NULL
 CREATE_OPTIONS: max_rows=16594
  TABLE_COMMENT: 
1 row in set (0.00 sec)


mysql>  select now(), t.* from information_schema.tables t  where table_name='innodb_temp_table_info'\G
*************************** 1. row ***************************
          now(): 2016-11-25 17:24:31              --注意这个时间
  TABLE_CATALOG: def
   TABLE_SCHEMA: information_schema
     TABLE_NAME: INNODB_TEMP_TABLE_INFO
     TABLE_TYPE: SYSTEM VIEW
         ENGINE: MEMORY
        VERSION: 10
     ROW_FORMAT: Fixed
     TABLE_ROWS: NULL
 AVG_ROW_LENGTH: 1011
    DATA_LENGTH: 0
MAX_DATA_LENGTH: 16694643
   INDEX_LENGTH: 0
      DATA_FREE: 0
 AUTO_INCREMENT: NULL
    CREATE_TIME: 2016-11-25 17:24:31           --注意这个时间
    UPDATE_TIME: NULL
     CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
       CHECKSUM: NULL
 CREATE_OPTIONS: max_rows=16594
  TABLE_COMMENT: 
1 row in set (0.00 sec)


从上面的时间可以看出,每次查看的时候 ,create_time和当前时间是一致的,就是每次查看的时候会马上建立这个表。
mysql> select * from information_schema.innodb_temp_table_info;
+----------+--------------+--------+-------+----------------------+---------------+
| TABLE_ID | NAME         | N_COLS | SPACE | PER_TABLE_TABLESPACE | IS_COMPRESSED |
+----------+--------------+--------+-------+----------------------+---------------+
|       43 | #sql7569_4_0 |      4 |    34 | FALSE                | FALSE         |
+----------+--------------+--------+-------+----------------------+---------------+
1 row in set (0.00 sec)




那么他后台是怎么走的呢?我试着打开general_log看看能不能看到一些操作,但是没有看到任何有用的信息。


只好看看代码:
--- 表的结构(或者说是字段信息) 如下
/* Fields of the dynamic table INNODB_TEMP_TABLE_INFO. */
static ST_FIELD_INFO i_s_innodb_temp_table_info_fields_info[] =
{
#define IDX_TEMP_TABLE_ID 0
{STRUCT_FLD(field_name, "TABLE_ID"),
STRUCT_FLD(field_length, MY_INT64_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONGLONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},


#define IDX_TEMP_TABLE_NAME 1
{STRUCT_FLD(field_name, "NAME"),
STRUCT_FLD(field_length, MAX_TABLE_UTF8_LEN),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},


#define IDX_TEMP_TABLE_N_COLS 2
{STRUCT_FLD(field_name, "N_COLS"),
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},


#define IDX_TEMP_TABLE_SPACE_ID 3
{STRUCT_FLD(field_name, "SPACE"),
STRUCT_FLD(field_length, MY_INT32_NUM_DECIMAL_DIGITS),
STRUCT_FLD(field_type, MYSQL_TYPE_LONG),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_UNSIGNED),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},


#define IDX_TEMP_TABLE_PTT 4
{STRUCT_FLD(field_name, "PER_TABLE_TABLESPACE"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},


#define IDX_TEMP_TABLE_IS_COMPRESSED 5
{STRUCT_FLD(field_name, "IS_COMPRESSED"),
STRUCT_FLD(field_length, 64),
STRUCT_FLD(field_type, MYSQL_TYPE_STRING),
STRUCT_FLD(value, 0),
STRUCT_FLD(field_flags, MY_I_S_MAYBE_NULL),
STRUCT_FLD(old_name, ""),
STRUCT_FLD(open_method, SKIP_OPEN_TABLE)},
END_OF_ST_FIELD_INFO
};




---填充表内容时实际执行
4220 /*******************************************************************//**
4221 Fill Information Schema table INNODB_TEMP_TABLE_INFO for a particular
4222 temp-table
4223 @return 0 on success, 1 on failure */
4224 static
4225 int
4226 i_s_innodb_temp_table_info_fill(
4227 /*=============================*/
4228         THD*                            thd,            /*!< in: thread */
4229         TABLE_LIST*                     tables,         /*!< in/out: tables
4230                                                         to fill */
4231         const temp_table_info_t*        info)           /*!< in: temp-table
4232                                                         information */
4233 {
4234         TABLE*                  table;
4235         Field**                 fields;
4236 
4237         DBUG_ENTER("i_s_innodb_temp_table_info_fill");
4238 
4239         table = tables->table;
4240 
4241         fields = table->field;
4242 
4243         OK(fields[IDX_TEMP_TABLE_ID]->store(info->m_table_id, true));
4244                                                                                                                                                      
4245         OK(field_store_string(                                                                                                                       
4246                    fields[IDX_TEMP_TABLE_NAME], info->m_table_name));                                                                                
4247                                                                                                                                                      
4248         OK(fields[IDX_TEMP_TABLE_N_COLS]->store(info->m_n_cols));                                                                                    
4249                                                                                                                                                      
4250         OK(fields[IDX_TEMP_TABLE_SPACE_ID]->store(info->m_space_id));                                                                                
4251                                                                                                                                                      
4252         OK(field_store_string(                                                                                                                       
4253                 fields[IDX_TEMP_TABLE_PTT], info->m_per_table_tablespace));                                                                          
4254                                                                                                                                                      
4255         OK(field_store_string(                                                                                                                       
4256                 fields[IDX_TEMP_TABLE_IS_COMPRESSED], info->m_is_compressed));                                                                       
4257                                                                                                                                                      
4258         DBUG_RETURN(schema_table_store_record(thd, table));                                                                                          
4259 }               




 ------------递归调用上面的    i_s_innodb_temp_table_info_fill      
4298 /*******************************************************************//**
4299 This function will iterate over all available table and will fill
4300 stats for temp-tables to INNODB_TEMP_TABLE_INFO.
4301 @return 0 on success, 1 on failure */
4302 static
4303 int
4304 i_s_innodb_temp_table_info_fill_table(
4305 /*===================================*/
4306         THD*            thd,            /*!< in: thread */
4307         TABLE_LIST*     tables,         /*!< in/out: tables to fill */
4308         Item*           )               /*!< in: condition (ignored) */
4309 {
4310         int                     status  = 0;
4311         dict_table_t*           table   = NULL;
4312 
4313         DBUG_ENTER("i_s_innodb_temp_table_info_fill_table");
4314 
4315         /* Only allow the PROCESS privilege holder to access the stats */
4316         if (check_global_access(thd, PROCESS_ACL)) {
4317                 DBUG_RETURN(0);
4318         }
4319 
4320         /* First populate all temp-table info by acquiring dict_sys->mutex.
4321         Note: Scan is being done on NON-LRU list which mainly has system
4322         table entries and temp-table entries. This means 2 things: list
4323         is smaller so processing would be faster and most of the data                                                                                
4324         is relevant */                                                                                                                               
4325         temp_table_info_cache_t all_temp_info_cache;                                                                                                 
4326         all_temp_info_cache.reserve(UT_LIST_GET_LEN(dict_sys->table_non_LRU));                                                                       
4327                                                                                                                                                      
4328         mutex_enter(&dict_sys->mutex);                                                                                                               
4329         for (table = UT_LIST_GET_FIRST(dict_sys->table_non_LRU);                                                                                     
4330              table != NULL;                                                                                                                          
4331              table = UT_LIST_GET_NEXT(table_LRU, table)) {                                                                                           
4332                                                                                                                                                      
4333                 if (!dict_table_is_temporary(table)) {                                                                                               
4334                         continue;                                                                                                                    
4335                 }                                                                                                                                    
4336                                                                                                                                                      
4337                 temp_table_info_t current_temp_table_info;                                                                                           
4338                                                                                                                                                      
4339                 innodb_temp_table_populate_cache(                                                                                                    
4340                         table, &current_temp_table_info);                                                                                            
4341                                                            
4342                 all_temp_info_cache.push_back(current_temp_table_info);                                                                              
4343         }                                                                                                                                            
4344         mutex_exit(&dict_sys->mutex);                                                                                                                
4345                                                                                                                                                      
4346         /* Now populate the info to MySQL table */                                                                                                   
4347         temp_table_info_cache_t::const_iterator end = all_temp_info_cache.end();                                                                     
4348         for (temp_table_info_cache_t::const_iterator it                                                                                              
4349                 = all_temp_info_cache.begin();                                                                                                       
4350              it != end;                                                                                                                              
4351              it++) {                                                                                                                                 
4352                 status = i_s_innodb_temp_table_info_fill(thd, tables, &(*it));                ---通过这里递归                                                                  
4353                 if (status) {                                                                                                                        
4354                         break;                                                                                                                       
4355                 }                                                                                                                                    
4356         }                                                                                                                                            
4357                                                                                                                                                      
4358         DBUG_RETURN(status);                                                                                                                         
4359 }                             




------INNODB_TEMP_TABLE_INFO表的初始化 
4361 /*******************************************************************//**                                                                             
4362 Bind the dynamic table INFORMATION_SCHEMA.INNODB_TEMP_TABLE_INFO.                                                                                    
4363 @return 0 on success, 1 on failure */                                                                                                                
4364 static
4365 int
4366 i_s_innodb_temp_table_info_init(
4367 /*=============================*/                                                                                                                    
4368         void*   p)      /*!< in/out: table schema object */                                                                                          
4369 {                                                                                                                                                    
4370         ST_SCHEMA_TABLE*        schema;                                                                                                              
4371                                                                                                                                                      
4372         DBUG_ENTER("i_s_innodb_temp_table_info_init");                                                                                               
4373                                                                                                                                                      
4374         schema = reinterpret_cast<ST_SCHEMA_TABLE*>(p);                                                                                              
4375                                                                                                                                                      
4376         schema->fields_info = i_s_innodb_temp_table_info_fields_info;        --表结构                                                                         
4377         schema->fill_table = i_s_innodb_temp_table_info_fill_table;          --填充内容                                                                     
4378                                                                                                                                                      
4379         DBUG_RETURN(0);                                                                                                                              
4380 } 


他们四个之间的关系是:





表填充时的信息是从dict_sys->table_non_LRU里面得到的
dict_sys的定义如下:
1709 struct dict_sys_t{
1710         DictSysMutex    mutex;          /*!< mutex protecting the data
1711                                         dictionary; protects also the
1712                                         disk-based dictionary system tables;
1713                                         this mutex serializes CREATE TABLE
1714                                         and DROP TABLE, as well as reading
1715                                         the dictionary data for a table from
1716                                         system tables */
1717         row_id_t        row_id;         /*!< the next row id to assign;
1718                                         NOTE that at a checkpoint this
1719                                         must be written to the dict system
1720                                         header and flushed to a file; in
1721                                         recovery this must be derived from
1722                                         the log records */
1723         hash_table_t*   table_hash;     /*!< hash table of the tables, based
1724                                         on name */
1725         hash_table_t*   table_id_hash;  /*!< hash table of the tables, based
1726                                         on id */
1727         lint            size;           /*!< varying space in bytes occupied
1728                                         by the data dictionary table and
1729                                         index objects */
1730         dict_table_t*   sys_tables;     /*!< SYS_TABLES table */
1731         dict_table_t*   sys_columns;    /*!< SYS_COLUMNS table */
1732         dict_table_t*   sys_indexes;    /*!< SYS_INDEXES table */                                                                                    
1733         dict_table_t*   sys_fields;     /*!< SYS_FIELDS table */
1734         dict_table_t*   sys_virtual;    /*!< SYS_VIRTUAL table */                                                                                    
1735 
1736         /*=============================*/
1737         UT_LIST_BASE_NODE_T(dict_table_t)
1738                         table_LRU;      /*!< List of tables that can be evicted                                                                      
1739                                         from the cache */                                                                                            
1740         UT_LIST_BASE_NODE_T(dict_table_t)
1741                         table_non_LRU;  /*!< List of tables that can't be
1742                                         evicted from the cache */
1743         autoinc_map_t*  autoinc_map;    /*!< Map to store table id and autoinc                                                                       
1744                                         when table is evicted */
1745 };                                            






看到代码之后,发现information_schema里所有的表都应该是这样的
mysql>  select now(), t.* from information_schema.tables t  where table_name='tables'\G
*************************** 1. row ***************************
          now(): 2016-11-25 17:35:43                --时间一致
  TABLE_CATALOG: def
   TABLE_SCHEMA: information_schema
     TABLE_NAME: TABLES
     TABLE_TYPE: SYSTEM VIEW
         ENGINE: MEMORY
        VERSION: 10
     ROW_FORMAT: Fixed
     TABLE_ROWS: NULL
 AVG_ROW_LENGTH: 9441
    DATA_LENGTH: 0
MAX_DATA_LENGTH: 16757775
   INDEX_LENGTH: 0
      DATA_FREE: 0
 AUTO_INCREMENT: NULL
    CREATE_TIME: 2016-11-25 17:35:43    --时间一致
    UPDATE_TIME: NULL
     CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
       CHECKSUM: NULL
 CREATE_OPTIONS: max_rows=1777
  TABLE_COMMENT: 
1 row in set (0.00 sec)


mysql> 
mysql>  select now(), t.* from information_schema.tables t  where table_name='tables'\G
*************************** 1. row ***************************
          now(): 2016-11-25 17:35:44                   --时间一致
  TABLE_CATALOG: def
   TABLE_SCHEMA: information_schema
     TABLE_NAME: TABLES
     TABLE_TYPE: SYSTEM VIEW
         ENGINE: MEMORY
        VERSION: 10
     ROW_FORMAT: Fixed
     TABLE_ROWS: NULL
 AVG_ROW_LENGTH: 9441
    DATA_LENGTH: 0
MAX_DATA_LENGTH: 16757775
   INDEX_LENGTH: 0
      DATA_FREE: 0
 AUTO_INCREMENT: NULL
    CREATE_TIME: 2016-11-25 17:35:44            --时间一致
    UPDATE_TIME: NULL
     CHECK_TIME: NULL
TABLE_COLLATION: utf8_general_ci
       CHECKSUM: NULL
 CREATE_OPTIONS: max_rows=1777
  TABLE_COMMENT: 
1 row in set (0.00 sec)




QQ 273002188 欢迎一起学习
QQ 群 236941212
oracle,mysql,PG 相互交流

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/25099483/viewspace-2129107/,如需转载,请注明出处,否则将追究法律责任。

上一篇: PXC安装
请登录后发表评论 登录
全部评论

注册时间:2011-05-31

  • 博文量
    215
  • 访问量
    618323