zoukankan      html  css  js  c++  java
  • 从ibd文件获取表空间id

    xtrabackup恢复过程中出现如下错误 

    InnoDB: Doing recovery: scanned up to log sequence number 1024370417664 (62 %)
    InnoDB: Doing recovery: scanned up to log sequence number 1024375660544 (75 %)
    140810 13:53:42  InnoDB: Starting an apply batch of log records to the database...
    InnoDB: Progress in percents: 140810 13:53:42  InnoDB: Error: space id and page n:o stored in the page
    InnoDB: read in are 1571195158:1995475462, should be 51:8406774!
    InnoDB: Database page corruption on disk or a failed
    InnoDB: file read of page 8406774.
    InnoDB: You may have to recover from a backup.
    140810 13:53:42  InnoDB: Page dump in ascii and hex (16384 bytes):

    从错误信息中可以看出,有页损坏了,并给出了space id和page no (51,8406774). 

    在非共享表空间(即innodb_file_per_table=on)时,每个表对应一个表空间。那么我们怎么通过表空间id(即space id)得到对应的表呢?

    在mysql 5.6以上版本中,可通过查询information_schema.INNODB_SYS_DATAFILES得到表空间id和表的对应关系,

    http://dev.mysql.com/doc/refman/5.6/en/innodb-sys-datafiles-table.html 

    mysql> select * from information_schema.INNODB_SYS_DATAFILES where space=287;
    +-------+---------------+
    | SPACE | PATH          |
    +-------+---------------+
    |   287 | .	est	2.ibd |
    +-------+---------------+

    然而出现此问题的mysql版本为5.1.那么我们怎么得到5.6以下版本表空间id和表的对应关系呢。

    从源码中可以看到,每个表空间第一个页的偏移38字节处,用4个字节存储了表空间id信息。参看函数fsp_header_init_fields

    于是写了个小工具直接从idb文件读取表空间id信息。

    例如获取表t1的表空间为795 

    $ sudo ./test /u01/mysql/data/test/t1.ibd
    spaceid:795 , file:/u01/mysql/data/test/t1.ibd 

    工具源码如下:

    #include "stdlib.h"
    #include "stdio.h"
    
    #ifdef _WIN64
    typedef unsigned __int64     ulint;
    #else
    typedef unsigned long int     ulint;
    
    #endif /* _WIN64 */
    
    typedef unsigned char byte;
    
    ulint
    mach_read_from_4(
         byte*     b)     /*!< in: pointer to four bytes */
    {
         return( ((ulint)(b[0]) << 24)
              | ((ulint)(b[1]) << 16)
              | ((ulint)(b[2]) << 8)
              | (ulint)(b[3])
              );
    }
    
    void main(int argc,char *argv[])
    {
            FILE *fp;
            byte ret[5];
            int  offset;
            ulint spaceid;
    
            if ((fp=fopen(argv[1],"r"))==NULL)
            {
                    printf("cannot open this file
    ");
                    exit(0);
            }
    
            offset=38;
            if (fseek(fp,offset,0)!=0)
            {
                    printf("cannot move pointer there.
    ");
                    exit(0);
            }
    
            fread(ret,sizeof(byte),4,fp);
            spaceid = mach_read_from_4(ret);
    
            printf("spaceid:%lu , file:%s
    ",spaceid,argv[1]);
    
            fclose(fp);
    }
  • 相关阅读:
    [ASP.NET Core] Tips
    Integration_Unit test coding standard
    集成测试报错的解决方案
    Integration testing
    Web Cache
    BIT
    CSU 1449: A+B and C
    [转] CUDA + code::blocks 配置
    CF 245 div2
    NBUT 2014 C Lord of Minecraft
  • 原文地址:https://www.cnblogs.com/justfortaste/p/3903185.html
Copyright © 2011-2022 走看看