የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

prehistory

እንዲህ ሆነ አገልጋዩ በራንሰምዌር ቫይረስ ተጠቃ፣ እሱም "በዕድለኛ አደጋ" በከፊል የኢብዲ ፋይሎችን (ጥሬ የ innodb ሰንጠረዦችን ጥሬ ዳታ ፋይሎች) ሳይነኩ ትቷቸዋል፣ ነገር ግን በተመሳሳይ ጊዜ የኤፍፒኤም ፋይሎችን ሙሉ በሙሉ ያመሳጠረ () መዋቅር ፋይሎች). በዚህ ሁኔታ፣ .idb በሚከተሉት ሊከፈል ይችላል፡-

  • በመደበኛ መሳሪያዎች እና መመሪያዎች በኩል ወደነበረበት መመለስ ተገዢ. ለእንደዚህ አይነት ጉዳዮች በጣም ጥሩ ነገር አለ መሆን;
  • በከፊል የተመሰጠሩ ሠንጠረዦች. በአብዛኛው እነዚህ ትላልቅ ጠረጴዛዎች ናቸው, ለዚህም (እንደገባኝ) አጥቂዎቹ ለሙሉ ምስጠራ በቂ ራም አልነበራቸውም;
  • ደህና፣ ወደነበሩበት ሊመለሱ የማይችሉ ሙሉ በሙሉ የተመሰጠሩ ሰንጠረዦች።

በቀላሉ በማንኛውም የጽሑፍ አርታኢ ውስጥ በሚፈለገው ኢንኮዲንግ (በእኔ ሁኔታ UTF8 ነው) በመክፈት እና በቀላሉ የጽሑፍ መስኮች መኖራቸውን ፋይሉን በማየት ሰንጠረዦቹ የየትኛው አማራጭ እንደሆኑ ማወቅ ተችሏል ።

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

እንዲሁም በፋይሉ መጀመሪያ ላይ ብዙ ቁጥር ያላቸውን 0 ባይት መመልከት ይችላሉ፣ እና የማገጃ ምስጠራ ስልተ-ቀመር (በጣም የተለመደው) የሚጠቀሙ ቫይረሶች ብዙውን ጊዜ እነሱንም ይጎዳሉ።
የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

በእኔ ሁኔታ አጥቂዎቹ በእያንዳንዱ ኢንክሪፕት የተደረገ ፋይል መጨረሻ ላይ ባለ 4-ባይት ሕብረቁምፊ (1, 0, 0, 0) ትተውታል, ይህም ተግባሩን ቀላል አድርጎታል. ያልተበከሉ ፋይሎችን ለመፈለግ ስክሪፕቱ በቂ ነበር፡-

def opened(path):
    files = os.listdir(path)
    for f in files:
        if os.path.isfile(path + f):
            yield path + f

for full_path in opened("C:somepath"):
    file = open(full_path, "rb")
    last_string = ""
    for line in file:
        last_string = line
        file.close()
    if (last_string[len(last_string) -4:len(last_string)]) != (1, 0, 0, 0):
        print(full_path)

ስለዚህ, የመጀመሪያው ዓይነት የሆኑ ፋይሎችን ለማግኘት ተገኘ. ሁለተኛው ብዙ የእጅ ሥራዎችን ያካትታል, ነገር ግን የተገኘው ነገር ቀድሞውኑ በቂ ነበር. ሁሉም ነገር ጥሩ ይሆናል, ግን ማወቅ ያስፈልግዎታል ፍጹም ትክክለኛ መዋቅር እና (በእርግጥ) በተደጋጋሚ ከሚለዋወጠው ጠረጴዛ ጋር መሥራት እንዳለብኝ አንድ ጉዳይ ተነሳ. የመስክ አይነት ተቀይሯል ወይም አዲስ አምድ መታከል ማንም አላስታውስም።

Wilds City, በሚያሳዝን ሁኔታ, በእንደዚህ አይነት ጉዳይ ላይ መርዳት አልቻለም, ለዚህም ነው ይህ ጽሑፍ የሚጻፈው.

ወደ ነጥቡ ግባ

ከ 3 ወራት በፊት ያለው የጠረጴዛ መዋቅር አሁን ካለው ጋር (ምናልባትም አንድ መስክ እና ምናልባትም ተጨማሪ) ጋር የማይገጣጠም መዋቅር አለ. የጠረጴዛ መዋቅር;

CREATE TABLE `table_1` (
    `id` INT (11),
    `date` DATETIME ,
    `description` TEXT ,
    `id_point` INT (11),
    `id_user` INT (11),
    `date_start` DATETIME ,
    `date_finish` DATETIME ,
    `photo` INT (1),
    `id_client` INT (11),
    `status` INT (1),
    `lead__time` TIME ,
    `sendstatus` TINYINT (4)
); 

በዚህ ሁኔታ የሚከተሉትን ማውጣት ያስፈልግዎታል

  • id_point int (11);
  • id_user int (11);
  • date_start DATETIME;
  • date_finish DATETIME

መልሶ ለማግኘት፣ የ.ibd ፋይል ባይት-ባይት ትንታኔ ጥቅም ላይ ይውላል፣ ከዚያም ወደ ይበልጥ ሊነበብ የሚችል ቅጽ ይቀይራቸዋል። የሚያስፈልገንን ለማግኘት, እንደ int እና datatime የመሳሰሉ የውሂብ ዓይነቶችን ብቻ መተንተን አለብን, ጽሑፉ እነሱን ብቻ ይገልፃል, ነገር ግን አንዳንድ ጊዜ ሌሎች ተመሳሳይ ሁኔታዎችን ሊረዱ የሚችሉ ሌሎች የውሂብ አይነቶችን እንጠቅሳለን.

ችግር 1: DATETIME እና TEXT አይነቶች ያላቸው መስኮች ባዶ እሴቶች ነበሯቸው፣ እና እነሱ በቀላሉ በፋይሉ ውስጥ ተዘለዋል፣ በዚህ ምክንያት በእኔ ሁኔታ ወደነበረበት ለመመለስ አወቃቀሩን ማወቅ አልተቻለም። በአዲሶቹ አምዶች ውስጥ፣ ነባሪው ዋጋ ባዶ ነበር፣ እና የግብይቱ አካል በ innodb_flush_log_at_trx_commit = 0 ቅንብር ምክንያት ሊጠፋ ይችላል፣ ስለዚህ አወቃቀሩን ለመወሰን ተጨማሪ ጊዜ ማውጣት አለበት።

ችግር 2በ DELETE በኩል የተሰረዙ ረድፎች ሁሉም በ ibd ፋይል ውስጥ እንደሚሆኑ ግምት ውስጥ መግባት አለበት ፣ ግን በALTER TABLE የእነሱ መዋቅር አይዘመንም። በውጤቱም, የውሂብ አወቃቀሩ ከፋይሉ መጀመሪያ እስከ መጨረሻው ሊለያይ ይችላል. ብዙ ጊዜ OPTIMIZE TABLEን የሚጠቀሙ ከሆነ እንደዚህ አይነት ችግር ሊያጋጥሙዎት አይችሉም።

ትኩረት ይስጡ፣ የዲቢኤምኤስ እትም ውሂብ በሚከማችበት መንገድ ላይ ተጽዕኖ ያሳድራል፣ እና ይህ ምሳሌ ለሌሎች ዋና ስሪቶች ላይሰራ ይችላል። በእኔ ሁኔታ, የዊንዶውስ የ mariadb 10.1.24 ስሪት ጥቅም ላይ ውሏል. እንዲሁም፣ በማሪአድብ ውስጥ ከ InnoDB ሠንጠረዦች ጋር ቢሰሩም፣ በእውነቱ እነሱ ናቸው። XtraDB, ይህም ዘዴ ከ InnoDB mysql ጋር ያለውን ተፈጻሚነት አያካትትም.

የፋይል ትንተና

በፓይቶን፣ የውሂብ አይነት ባይት() በመደበኛ የቁጥሮች ስብስብ ምትክ የዩኒኮድ መረጃን ያሳያል። ምንም እንኳን ፋይሉን በዚህ ቅጽ ማየት ቢችሉም ለተመቾት ባይት ድርድርን ወደ መደበኛ ድርድር (ዝርዝር(ምሳሌ_ባይት_array)) በመቀየር ወደ ቁጥራዊ መልክ መቀየር ይችላሉ። በማንኛውም ሁኔታ ሁለቱም ዘዴዎች ለመተንተን ተስማሚ ናቸው.

በርካታ የ ibd ፋይሎችን ከተመለከቱ በኋላ የሚከተሉትን ማግኘት ይችላሉ።

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

በተጨማሪም ፋይሉን በእነዚህ ቁልፍ ቃላቶች ከከፋፈሉት, አብዛኛውን ጊዜ እንኳን የውሂብ ብሎኮች ያገኛሉ. ኢንፊሙምን እንደ አካፋይ እንጠቀማለን።

table = table.split("infimum".encode())

አንድ አስደሳች ምልከታ: አነስተኛ መጠን ያለው መረጃ ላላቸው ሰንጠረዦች, በአቅም ማነስ እና በሱፐርሙ መካከል በብሎክ ውስጥ ያሉትን የረድፎች ብዛት ጠቋሚ አለ.

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት - የሙከራ ሰንጠረዥ ከ 1 ኛ ረድፍ ጋር

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት - የሙከራ ጠረጴዛ ከ 2 ረድፎች ጋር

የረድፍ አደራደር ጠረጴዛ [0] ሊዘለል ይችላል። እሱን ከተመለከትኩ በኋላ፣ አሁንም የጥሬ ሠንጠረዥ መረጃ ማግኘት አልቻልኩም። ምናልባትም ይህ እገዳ ኢንዴክሶችን እና ቁልፎችን ለማከማቸት ያገለግላል።
ከሠንጠረዥ[1] ጀምሮ እና ወደ የቁጥር አደራደር መተርጎም፣ አንዳንድ ንድፎችን አስቀድመው ሊያስተውሉ ይችላሉ፣ እነሱም፡-

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

እነዚህ በሕብረቁምፊ ውስጥ የተከማቹ int እሴቶች ናቸው። የመጀመሪያው ባይት ቁጥሩ አዎንታዊ ወይም አሉታዊ መሆኑን ያመለክታል. በእኔ ሁኔታ, ሁሉም ቁጥሮች አዎንታዊ ናቸው. ከቀሪዎቹ 3 ባይት ውስጥ የሚከተለውን ተግባር በመጠቀም ቁጥሩን መወሰን ይችላሉ. ስክሪፕት፡

def find_int(val: str):  # example '128, 1, 2, 3'
    val = [int(v) for v in  val.split(", ")]
    result_int = val[1]*256**2 + val[2]*256*1 + val[3]
    return result_int

ለምሳሌ ያህል, 128, 0, 0, 1 = 1, ወይም 128, 0, 75, 108 = 19308.
ሠንጠረዡ በራስ-መጨመር ዋና ቁልፍ ነበረው፣ እና እዚህም ሊገኝ ይችላል።

የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት

ከሙከራ ሠንጠረዦች የተገኘውን መረጃ ካነፃፅር በኋላ፣ የ DATETIME ነገር 5 ባይት ያካተተ እና በ 153 መጀመሩ ተገለፀ (በጣም ምናልባትም አመታዊ ክፍተቶችን ያሳያል)። የ DATTIME ክልል '1000-01-01' እስከ '9999-12-31' ስለሆነ የባይቶች ብዛት ሊለያይ ይችላል ብዬ አስባለሁ ነገር ግን በእኔ ሁኔታ መረጃው ከ 2016 እስከ 2019 ባለው ጊዜ ውስጥ ይወድቃል, ስለዚህ እኛ እንገምታለን. ያ 5 ባይት በቂ ነው።

ሰዓቱን ያለ ሰከንዶች ለመወሰን, የሚከተሉት ተግባራት ተጽፈዋል. ስክሪፕት፡

day_ = lambda x: x % 64 // 2  # {x,x,X,x,x }

def hour_(x1, x2):  # {x,x,X1,X2,x}
    if x1 % 2 == 0:
        return x2 // 16
    elif x1 % 2 == 1:
        return x2 // 16 + 16
    else:
        raise ValueError

min_ = lambda x1, x2: (x1 % 16) * 4 + (x2 // 64)  # {x,x,x,X1,X2}

ለዓመቱ እና ለወሩ የተግባር ተግባር ለመጻፍ የማይቻል ነበር, ስለዚህ እሱን መጥለፍ ነበረብኝ. ስክሪፕት፡

ym_list = {'2016, 1': '153, 152, 64', '2016, 2': '153, 152, 128', 
           '2016, 3': '153, 152, 192', '2016, 4': '153, 153, 0',
           '2016, 5': '153, 153, 64', '2016, 6': '153, 153, 128', 
           '2016, 7': '153, 153, 192', '2016, 8': '153, 154, 0', 
           '2016, 9': '153, 154, 64', '2016, 10': '153, 154, 128', 
           '2016, 11': '153, 154, 192', '2016, 12': '153, 155, 0',
           '2017, 1': '153, 155, 128', '2017, 2': '153, 155, 192', 
           '2017, 3': '153, 156, 0', '2017, 4': '153, 156, 64',
           '2017, 5': '153, 156, 128', '2017, 6': '153, 156, 192',
           '2017, 7': '153, 157, 0', '2017, 8': '153, 157, 64',
           '2017, 9': '153, 157, 128', '2017, 10': '153, 157, 192', 
           '2017, 11': '153, 158, 0', '2017, 12': '153, 158, 64', 
           '2018, 1': '153, 158, 192', '2018, 2': '153, 159, 0',
           '2018, 3': '153, 159, 64', '2018, 4': '153, 159, 128', 
           '2018, 5': '153, 159, 192', '2018, 6': '153, 160, 0',
           '2018, 7': '153, 160, 64', '2018, 8': '153, 160, 128',
           '2018, 9': '153, 160, 192', '2018, 10': '153, 161, 0', 
           '2018, 11': '153, 161, 64', '2018, 12': '153, 161, 128',
           '2019, 1': '153, 162, 0', '2019, 2': '153, 162, 64', 
           '2019, 3': '153, 162, 128', '2019, 4': '153, 162, 192', 
           '2019, 5': '153, 163, 0', '2019, 6': '153, 163, 64',
           '2019, 7': '153, 163, 128', '2019, 8': '153, 163, 192',
           '2019, 9': '153, 164, 0', '2019, 10': '153, 164, 64', 
           '2019, 11': '153, 164, 128', '2019, 12': '153, 164, 192',
           '2020, 1': '153, 165, 64', '2020, 2': '153, 165, 128',
           '2020, 3': '153, 165, 192','2020, 4': '153, 166, 0', 
           '2020, 5': '153, 166, 64', '2020, 6': '153, 1, 128',
           '2020, 7': '153, 166, 192', '2020, 8': '153, 167, 0', 
           '2020, 9': '153, 167, 64','2020, 10': '153, 167, 128',
           '2020, 11': '153, 167, 192', '2020, 12': '153, 168, 0'}

def year_month(x1, x2):  # {x,X,X,x,x }

    for key, value in ym_list.items():
        key = [int(k) for k in key.replace("'", "").split(", ")]
        value = [int(v) for v in value.split(", ")]
        if x1 == value[1] and x2 // 64 == value[2] // 64:
            return key
    return 0, 0

እርግጠኛ ነኝ ጊዜን የምታሳልፉ ከሆነ ይህ አለመግባባት ሊስተካከል ይችላል።
በመቀጠል የቀን ጊዜ ነገርን ከአንድ ሕብረቁምፊ የሚመልስ ተግባር። ስክሪፕት፡

def find_data_time(val:str):
    val = [int(v) for v in val.split(", ")]
    day = day_(val[2])
    hour = hour_(val[2], val[3])
    minutes = min_(val[3], val[4])
    year, month = year_month(val[1], val[2])
    return datetime(year, month, day, hour, minutes)

በተደጋጋሚ የሚደጋገሙ እሴቶችን ከ int፣ int፣ datetime፣ datetime ለማወቅ ተችሏል። የ ibd ፋይል ባይት ባይት ትንታኔን በመጠቀም ያለ መዋቅር ፋይል ከXtraDB ሰንጠረዦች መረጃን መልሶ ማግኘት, ይህ የሚያስፈልግህ ይመስላል. ከዚህም በላይ እንዲህ ዓይነቱ ቅደም ተከተል በአንድ መስመር ሁለት ጊዜ አይደገምም.

መደበኛ አገላለጽ በመጠቀም አስፈላጊውን ውሂብ እናገኛለን፡-

fined = re.findall(r'128, d*, d*, d*, 128, d*, d*, d*, 153, 1[6,5,4,3]d, d*, d*, d*, 153, 1[6,5,4,3]d, d*, d*, d*', int_array)

እባክዎን ይህንን አገላለጽ ሲፈልጉ በሚፈለጉት መስኮች NULL እሴቶችን መወሰን እንደማይቻል ልብ ይበሉ ፣ ግን በእኔ ሁኔታ ይህ ወሳኝ አይደለም። ከዚያም በ loop ውስጥ ያገኘነውን እናልፋለን. ስክሪፕት፡

result = []
for val in fined:
    pre_result = []
    bd_int  = re.findall(r"128, d*, d*, d*", val)
    bd_date= re.findall(r"(153, 1[6,5,4,3]d, d*, d*, d*)", val)
    for it in bd_int:
        pre_result.append(find_int(bd_int[it]))
    for bd in bd_date:
        pre_result.append(find_data_time(bd))
    result.append(pre_result)

በእውነቱ ፣ ያ ብቻ ነው ፣ ከውጤት ድርድር የተገኘው መረጃ እኛ የምንፈልገው ውሂብ ነው። ###PS.###
ይህ ዘዴ ለሁሉም ሰው ተስማሚ እንዳልሆነ ተረድቻለሁ, ነገር ግን የጽሁፉ ዋና ግብ ሁሉንም ችግሮችዎን ከመፍታት ይልቅ እርምጃ መውሰድ ነው. እኔ እንደማስበው በጣም ትክክለኛው መፍትሔ የመነሻ ኮድን እራስዎ ማጥናት መጀመር ነው። mariadbነገር ግን በጊዜ ገደብ ምክንያት አሁን ያለው ዘዴ በጣም ፈጣኑ ይመስላል.

በአንዳንድ ሁኔታዎች, ፋይሉን ከመረመሩ በኋላ, ግምታዊውን መዋቅር ለመወሰን እና ከላይ ካሉት አገናኞች ውስጥ አንዱን መደበኛ ዘዴዎች በመጠቀም ወደነበረበት መመለስ ይችላሉ. ይህ በጣም ትክክል ይሆናል እና ጥቂት ችግሮችን ያስከትላል.

ምንጭ: hab.com

አስተያየት ያክሉ