Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

prasajarah

Kajadian éta server diserang ku virus ransomware, anu, ku "kacilakaan untung," sawaréh ditinggalkeun file .ibd (file data atah tabel innodb) teu kacekel, tapi dina waktos anu sareng lengkep énkripsi file .fpm ( file struktur). Dina hal ieu, .idb bisa dibagi jadi:

  • tunduk kana restorasi ngaliwatan parabot baku sarta Panungtun. Pikeun kasus kawas, aya alus teuing janten;
  • tabél sawaréh énkripsi. Lolobana ieu tabel badag, nu (sakumaha kuring ngartos) lawan teu boga cukup RAM pikeun enkripsi pinuh;
  • Nya, tabel énkripsi lengkep anu teu tiasa dibalikeun deui.

Ieu mungkin pikeun nangtukeun pilihan mana tabel milik ku saukur muka eta dina sagala pangropéa téksu dina encoding dipikahoyong (dina hal kuring éta UTF8) jeung saukur nempo file pikeun ayana widang téks, contona:

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

Ogé, dina awal file anjeun tiasa ningali sajumlah ageung 0 bait, sareng virus anu nganggo algoritma enkripsi blok (paling umum) biasana mangaruhan ogé.
Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

Dina kasus kuring, panyerang ninggalkeun senar 4-bait (1, 0, 0, 0) dina tungtung unggal file énkripsi, anu nyederhanakeun tugas. Pikeun milarian file anu henteu katépaan, skripna cekap:

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)

Ku kituna, tétéla pikeun manggihan payil milik tipe kahiji. Anu kadua ngalibatkeun seueur padamelan manual, tapi anu kapendak parantos cekap. Sagalana bakal rupa, tapi anjeun kudu nyaho struktur kacida tepat jeung (tangtu) timbul hiji pasualan nu kuring kungsi digawekeun ku tabel remen ngarobah. Teu aya anu émut naha jinis lapangan dirobih atanapi kolom énggal parantos ditambah.

Wilds City, hanjakalna, teu tiasa ngabantosan kasus sapertos kitu, naha tulisan ieu ditulis.

Meunang ka titik

Aya struktur tabel ti 3 sababaraha bulan kapengker nu teu coincide jeung ayeuna (jigana hiji widang, jeung kamungkinan leuwih). Struktur tabél:

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)
); 

Dina hal ieu, anjeun kedah nimba:

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

Pikeun recovery, analisis bait-demi-bait tina file .ibd dipaké, dituturkeun ku ngarobah kana formulir nu leuwih bisa dibaca. Kusabab pikeun milarian naon anu urang peryogikeun, urang ngan ukur kedah nganalisis jinis data sapertos int sareng datatime, tulisan éta ngan ukur ngajelaskeun aranjeunna, tapi sakapeung urang ogé bakal ngarujuk kana jinis data anu sanés, anu tiasa ngabantosan dina kajadian anu sami.

Masalah 1: widang kalayan jenis DATETIME na téks miboga nilai NULL, sarta aranjeunna saukur skipped dina file, kusabab ieu, teu mungkin pikeun nangtukeun struktur mulangkeun bisi kuring. Dina kolom anyar, nilai standar éta null, sarta bagian tina urus bisa leungit alatan setelan innodb_flush_log_at_trx_commit = 0, jadi waktu tambahan kudu spent pikeun nangtukeun struktur.

Masalah 2: eta kudu tumut kana akun yén baris dihapus via DELETE sadayana bakal aya dina file ibd, tapi kalawan ALTER TABLE struktur maranéhanana moal diropéa. Hasilna, struktur data bisa rupa-rupa ti mimiti file nepi ka ahir. Upami anjeun sering nganggo OPTIMIZE TABLE, maka anjeun sigana moal mendakan masalah sapertos kitu.

Perhatikeun, versi DBMS mangaruhan cara data disimpen, sarta conto ieu bisa jadi teu dianggo pikeun versi utama lianna. Dina hal kuring, versi windows mariadb 10.1.24 dianggo. Ogé, sanajan dina mariadb anjeun damel sareng tabel InnoDB, nyatana aranjeunna XtraDB, nu teu kaasup applicability sahiji metodeu jeung InnoDB mysql.

Analisis file

Dina python, tipe data bait () mintonkeun data Unicode gaganti susunan angka nu biasa. Sanajan anjeun bisa nempo file dina formulir ieu, pikeun genah Anjeun bisa ngarobah bait kana formulir numerik ku ngarobah bait Asép Sunandar Sunarya kana Asép Sunandar Sunarya biasa (daptar (example_byte_array)). Dina sagala hal, duanana métode cocog pikeun analisis.

Saatos ningali sababaraha file ibd, anjeun tiasa mendakan ieu:

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

Leuwih ti éta, lamun ngabagi file ku kecap konci ieu, anjeun bakal meunang lolobana malah blok data. Urang bakal ngagunakeun infimum salaku divisor a.

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

Hiji observasi metot: pikeun tabel kalawan jumlah leutik data, antara infimum na supremum aya pointer kana jumlah baris dina blok.

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd - méja uji sareng baris ka-1

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd - méja uji sareng 2 jajar

Tabel susunan baris [0] tiasa dilewatan. Saatos ningali éta, kuring masih teu tiasa mendakan data tabel atah. Paling dipikaresep, blok ieu dipaké pikeun nyimpen indéks jeung konci.
Dimimitian ku tabel [1] sareng narjamahkeun kana array numerik, anjeun tiasa perhatikeun sababaraha pola, nyaéta:

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

Ieu mangrupikeun nilai int anu disimpen dina senar. Bait kahiji nunjukkeun naha jumlahna positip atanapi négatif. Bisi kuring, sadaya angka positip. Tina 3 bait sésana, anjeun tiasa nangtukeun jumlahna nganggo fungsi di handap ieu. Naskah:

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

Contona, 128, 0, 0, 1 = 1atawa 128, 0, 75, 108 = 19308.
tabél miboga konci primér kalawan otomatis-increment, sarta eta oge bisa kapanggih di dieu

Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd

Saanggeus ngabandingkeun data tina tabel tés, éta kaungkap obyék DATETIME diwangun ku 5 bait tur dimimitian ku 153 (paling dipikaresep nunjukkeun interval taunan). Kusabab rentang DATTIME nyaeta '1000-01-01' nepi ka '9999-12-31', Jigana jumlah bait bisa rupa-rupa, tapi bisi kuring, data ragrag dina periode ti 2016 nepi ka 2019, jadi urang bakal nganggap éta 5 bait cukup.

Pikeun nangtukeun waktu tanpa detik, fungsi di handap ieu ditulis. Naskah:

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}

Teu mungkin nulis fungsi fungsional pikeun sataun jeung bulan, jadi kuring kungsi hack eta. Naskah:

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

Kuring yakin yén lamun méakkeun n jumlah waktu, salah paham ieu bisa dilereskeun.
Salajengna, fungsi nu mulih hiji objek datetime ti string a. Naskah:

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)

Bisa ngadeteksi nilai-nilai anu sering diulang ti int, int, datetime, datetime Pulihkeun data tina tabel XtraDB tanpa file struktur nganggo analisis bait-demi-bait tina file ibd, Sigana mah ieu nu peryogi. Leuwih ti éta, runtuyan saperti teu diulang dua kali per baris.

Ngagunakeun éksprési biasa, urang manggihan data diperlukeun:

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)

Punten dicatet yén nalika milarian nganggo ekspresi ieu, moal mungkin pikeun nangtukeun nilai NULL dina widang anu dibutuhkeun, tapi bisi kuring ieu henteu kritis. Teras we ngaliwat naon anu urang mendakan dina loop. Naskah:

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)

Sabenerna, éta sadayana, data tina susunan hasil mangrupikeun data anu urang peryogikeun. ##PS.##
Kuring ngarti yén metodeu ieu henteu cocog pikeun sadayana, tapi tujuan utama tulisan nyaéta pikeun ngadorong tindakan tinimbang ngabéréskeun sadaya masalah anjeun. Jigana solusi anu paling bener bakal ngamimitian diajar kode sumber sorangan mariadb, tapi kusabab waktos kawates, metodeu ayeuna sigana anu paling gancang.

Dina sababaraha kasus, saatos analisa file, anjeun bakal tiasa nangtoskeun struktur perkiraan sareng malikkeunana nganggo salah sahiji metode standar tina tautan di luhur. Ieu bakal langkung leres sareng nyababkeun langkung seueur masalah.

sumber: www.habr.com

Tambahkeun komentar