စောပိုငျးကာလ
ဆာဗာကို ransomware ဗိုင်းရပ်စ်ဖြင့် တိုက်ခိုက်ခဲ့ရာ၊ ကံကောင်းစွာ မတော်တဆမှုတစ်ခုကြောင့် .ibd ဖိုင်များ (innodb tables များ၏ ဒေတာအကြမ်းဖိုင်များ) ကို တစ်စိတ်တစ်ပိုင်း ချန်ထားခဲ့ခဲ့သော်လည်း တစ်ချိန်တည်းမှာပင် .fpm ဖိုင်များကို လုံးလုံးလျားလျား ကုဒ်ဝှက်ထားသည် ( ဖွဲ့စည်းပုံဖိုင်များ)။ ဤကိစ္စတွင်၊ .idb ကို ခွဲခြားနိုင်သည်-
- စံချိန်မီကိရိယာများနှင့် လမ်းညွှန်ချက်များမှတစ်ဆင့် ပြန်လည်ထူထောင်ရေးကိစ္စ။ ထိုသို့သောကိစ္စများအတွက်, ကအကောင်းဆုံးရှိပါတယ်။
ဖြစ်လာသည် ; - တစ်စိတ်တစ်ပိုင်း ကုဒ်ဝှက်ထားသော ဇယားများ။ အများစုမှာ ဤအရာများသည် ကြီးမားသောဇယားများဖြစ်ပြီး၊ (ကျွန်တော်နားလည်သလောက်) တိုက်ခိုက်သူများသည် ကုဒ်ဝှက်ခြင်းအတွက် လုံလောက်သော RAM မရှိပါက၊
- ပြန်မရနိုင်သော အပြည့်အ၀ ကုဒ်ဝှက်ထားသော ဇယားများ။
အလိုရှိသောကုဒ်နံပါတ်အောက်တွင် မည်သည့်စာသားတည်းဖြတ်မှုတွင်မဆို ၎င်းကိုဖွင့်ခြင်းဖြင့် ဇယားများနှင့်သက်ဆိုင်သည့်ရွေးချယ်ခွင့်ကို ဆုံးဖြတ်ရန်ဖြစ်နိုင်သည် (ကျွန်ုပ်၏အခြေအနေတွင် UTF8 ဖြစ်သည်) နှင့် စာသားအကွက်များရှိနေခြင်းအတွက် ဖိုင်ကိုရိုးရှင်းစွာကြည့်ရှုခြင်း၊ ဥပမာအားဖြင့်-
ထို့အပြင်၊ ဖိုင်၏အစတွင် 0 bytes အများအပြားကို သင်ကြည့်ရှုနိုင်ပြီး ပိတ်ဆို့စာဝှက်စနစ် (အသုံးအများဆုံး) ကိုအသုံးပြုသည့် ဗိုင်းရပ်စ်များသည် ၎င်းတို့ကိုလည်း သက်ရောက်မှုရှိတတ်သည်။
ကျွန်ုပ်၏ကိစ္စတွင်၊ တိုက်ခိုက်သူများသည် လုပ်ဆောင်စရာကို ရိုးရှင်းစေသည့် ကုဒ်ဝှက်ထားသောဖိုင်တစ်ခုစီ၏အဆုံးတွင် 4-byte စာကြောင်း (1, 0, 0, 0) ကို ချန်ထားခဲ့သည်။ ရောဂါပိုးမရှိသောဖိုင်များကိုရှာဖွေရန်၊ script သည်လုံလောက်သည်-
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 ဖိုင်၏ byte-by-byte ခွဲခြမ်းစိတ်ဖြာမှုကို အသုံးပြုပြီး ၎င်းတို့ကို ပိုမိုဖတ်ရှုနိုင်သော ပုံစံအဖြစ်သို့ ပြောင်းလဲခြင်းဖြင့် လုပ်ဆောင်သည်။ ကျွန်ုပ်တို့ လိုအပ်သည်များကို ရှာဖွေရန်၊ ကျွန်ုပ်တို့သည် int နှင့် datatime ကဲ့သို့သော ဒေတာအမျိုးအစားများကိုသာ ခွဲခြမ်းစိတ်ဖြာရန် လိုအပ်ပြီး ဆောင်းပါးတွင် ၎င်းတို့ကိုသာ ဖော်ပြမည်ဖြစ်ပြီး၊ တစ်ခါတစ်ရံတွင် အခြားသော အလားတူဖြစ်ရပ်များတွင် ကူညီပေးနိုင်သည့် အခြားသော ဒေတာအမျိုးအစားများကိုလည်း ကိုးကားပါမည်။
ပြဿနာ ၁: DATETIME နှင့် TEXT အမျိုးအစားများပါရှိသော အကွက်များတွင် NULL တန်ဖိုးများပါရှိပြီး ၎င်းတို့ကို ဖိုင်ထဲတွင် ရိုးရိုးလေးကျော်သွားပါသည်၊ ထို့ကြောင့်၊ ကျွန်ုပ်၏ကိစ္စတွင် ပြန်လည်ရယူရန် ဖွဲ့စည်းပုံကို ဆုံးဖြတ်ရန် မဖြစ်နိုင်ပါ။ ကော်လံအသစ်များတွင်၊ ပုံသေတန်ဖိုးသည် null ဖြစ်ပြီး innodb_flush_log_at_trx_commit = 0 ဆက်တင်ကြောင့် ငွေပေးငွေယူ၏တစ်စိတ်တစ်ပိုင်း ဆုံးရှုံးသွားနိုင်သည်၊ ထို့ကြောင့် ဖွဲ့စည်းပုံကိုဆုံးဖြတ်ရန် နောက်ထပ်အချိန်ကို သုံးစွဲရမည်ဖြစ်ပါသည်။
ပြဿနာ ၁: DELETE မှတစ်ဆင့် ဖျက်လိုက်သော အတန်းများအားလုံးသည် ibd ဖိုင်တွင် ရှိနေမည်ကို ထည့်သွင်းစဉ်းစားသင့်သော်လည်း ALTER TABLE ဖြင့် ၎င်းတို့၏ ဖွဲ့စည်းပုံကို အပ်ဒိတ်လုပ်မည်မဟုတ်ပါ။ ရလဒ်အနေဖြင့်၊ ဒေတာဖွဲ့စည်းပုံသည် ဖိုင်၏အစမှ ၎င်း၏အဆုံးအထိ ကွဲပြားနိုင်သည်။ OPTIMIZE TABLE ကို သင်မကြာခဏအသုံးပြုပါက၊ ထိုသို့သောပြဿနာမျိုး သင်ကြုံတွေ့ရဖွယ်မရှိပါ။
ကျေးဇူးပြု. သတိပြုပါDBMS ဗားရှင်းသည် ဒေတာသိမ်းဆည်းပုံအပေါ် သက်ရောက်မှုရှိပြီး၊ ဤဥပမာသည် အခြားသော အဓိကဗားရှင်းများအတွက် အလုပ်မဖြစ်နိုင်ပါ။ ငါ့ကိစ္စတွင်၊ mariadb 10.1.24 ၏ windows ဗားရှင်းကို အသုံးပြုခဲ့သည်။ ထို့အပြင် mariadb တွင်သင် InnoDB ဇယားများနှင့်အလုပ်လုပ်သော်လည်း၊ တကယ်တော့၎င်းတို့သည်ဖြစ်သည်။
ဖိုင်ခွဲခြမ်းစိတ်ဖြာ
python တွင် data အမျိုးအစား
ibd ဖိုင်များစွာကို ကြည့်ရှုပြီးနောက်၊ အောက်ပါတို့ကို သင်တွေ့နိုင်သည်။
ထို့အပြင်၊ သင်သည် ဤသော့ချက်စာလုံးများဖြင့် ဖိုင်ကို ပိုင်းခြားပါက၊ အများစုမှာ ဒေတာဘလောက်များပင် ရရှိမည်ဖြစ်သည်။ ကျွန်ုပ်တို့သည် infimum ကို ပိုင်းခြားမှုအဖြစ် အသုံးပြုပါမည်။
table = table.split("infimum".encode())
စိတ်ဝင်စားစရာကောင်းသော လေ့လာတွေ့ရှိချက်- ဒေတာပမာဏ အနည်းငယ်ရှိသော ဇယားများအတွက်၊ အနိမ့်ဆုံးနှင့် အမြင့်ဆုံးအကြား ဘလောက်အတွင်းရှိ အတန်းအရေအတွက်အတွက် ညွှန်ပြချက်တစ်ခုရှိသည်။
- 1st အတန်းနှင့်အတူစမ်းသပ်ဇယား
- 2 တန်းနှင့်အတူစမ်းသပ်ဇယား
အတန်းခင်းကျင်းခြင်းဇယား[0] ကို ကျော်သွားနိုင်သည်။ ၎င်းကိုကြည့်ပြီးနောက်၊ ဇယားကြမ်းဒေတာကို ရှာမတွေ့သေးပါ။ ဖြစ်နိုင်သည်မှာ၊ ဤဘလောက်ကို အညွှန်းများနှင့် သော့များသိမ်းဆည်းရန် အသုံးပြုသည်။
ဇယား[1] ဖြင့် စတင်ကာ ဂဏန်းအခင်းအကျင်းတစ်ခုသို့ ဘာသာပြန်ဆိုခြင်းဖြင့်၊ အချို့သော ပုံစံများကို သင်သတိပြုမိနေပြီဖြစ်သည်၊
၎င်းတို့သည် စာကြောင်းတစ်ခုတွင် သိမ်းဆည်းထားသော int တန်ဖိုးများဖြစ်သည်။ ပထမ byte သည် နံပါတ်သည် အပေါင်း သို့မဟုတ် အနုတ်ကို ညွှန်ပြသည်။ ငါ့ကိစ္စတွင်၊ ဂဏန်းအားလုံးသည် အကောင်းမြင်သည်။ ကျန် 3 bytes မှ၊ သင်သည် အောက်ပါလုပ်ဆောင်ချက်ကို အသုံးပြု၍ နံပါတ်ကို ဆုံးဖြတ်နိုင်သည်။ ဇာတ်ညွှန်း-
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.
ဇယားတွင် အလိုအလျောက် တိုးခြင်းဖြင့် အဓိကသော့တစ်ခု ပါရှိပြီး ၎င်းကိုလည်း ဤနေရာတွင် တွေ့နိုင်ပါသည်။
စမ်းသပ်ဇယားများမှ အချက်အလက်များကို နှိုင်းယှဉ်ပြီး DATETIME အရာဝတ္ထုတွင် 5 bytes ပါ၀င်ပြီး 153 (နှစ်စဉ်ကြားကာလများကို ညွှန်ပြနိုင်ခြေများသော) ဖြင့် စတင်ခဲ့ကြောင်း ထင်ရှားပါသည်။ DATTIME အပိုင်းအခြားသည် '1000-01-01' မှ '9999-12-31' ဖြစ်သောကြောင့်၊ ဘိုက်အရေအတွက် ကွဲပြားနိုင်သည်ဟု ကျွန်ုပ်ထင်သော်လည်း၊ ကျွန်ုပ်၏ကိစ္စတွင်၊ ဒေတာသည် 2016 မှ 2019 ကာလအတွင်း ကျသွားသောကြောင့် ကျွန်ုပ်တို့ ယူဆပါမည်။ 5 bytes နဲ့ လုံလောက်ပါတယ်။
စက္ကန့်မပါပဲ အချိန်ကိုဆုံးဖြတ်ရန် အောက်ပါလုပ်ဆောင်ချက်များကို ရေးသားခဲ့သည်။ ဇာတ်ညွှန်း-
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
အချိန်အများကြီးကုန်ရင် ဒီနားလည်မှုလွဲတာကို ပြင်နိုင်မယ်ဆိုတာ သေချာပါတယ်။
ထို့နောက်၊ string တစ်ခုမှ datetime object တစ်ခုကို ပြန်ပေးသည့် လုပ်ဆောင်ချက်တစ်ခု။ ဇာတ်ညွှန်း-
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 တို့မှ မကြာခဏ ထပ်ခါတလဲလဲ တန်ဖိုးများကို ရှာဖွေနိုင်ခဲ့သည်။ ၊ ဒါက မင်းလိုအပ်ပုံပဲ။ ထို့အပြင်၊ ထိုသို့သော sequence သည် တစ်ကြောင်းလျှင် နှစ်ကြိမ် ထပ်မလုပ်ပါ။
ပုံမှန်အသုံးအနှုန်းကိုအသုံးပြု၍ လိုအပ်သောဒေတာကို ကျွန်ုပ်တို့ရှာဖွေသည်-
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 တန်ဖိုးများကို ဆုံးဖြတ်ရန် မဖြစ်နိုင်ကြောင်း ကျေးဇူးပြု၍ မှတ်သားထားပါ၊ သို့သော် ကျွန်ုပ်အတွက်မူ ၎င်းသည် မစိုးရိမ်ရပါ။ ထို့နောက် ကျွန်ုပ်တို့သည် ကွင်းဆက်တစ်ခုတွင် တွေ့ရှိသောအရာကို ဖြတ်သန်းပါ။ ဇာတ်ညွှန်း-
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)
တကယ်တော့၊ ဒါပါပဲ၊ ရလဒ် array မှဒေတာသည်ကျွန်ုပ်တို့လိုအပ်သောဒေတာဖြစ်သည်။ ###PS.###
ဤနည်းလမ်းသည် လူတိုင်းအတွက် မသင့်လျော်ကြောင်း ကျွန်ုပ်နားလည်ပါသည်၊ သို့သော် ဆောင်းပါး၏ အဓိကပန်းတိုင်မှာ သင့်ပြဿနာအားလုံးကို ဖြေရှင်းမည့်အစား ချက်ချင်းလုပ်ဆောင်ရန်ဖြစ်သည်။ အမှန်ကန်ဆုံးဖြေရှင်းချက်ကတော့ source code ကို ကိုယ်တိုင်စလေ့လာဖို့ပဲဖြစ်မယ်ထင်ပါတယ်။
အချို့ကိစ္စများတွင်၊ ဖိုင်ကို ပိုင်းခြားစိတ်ဖြာပြီးနောက်၊ သင်သည် အနီးစပ်ဆုံး ဖွဲ့စည်းပုံကို ဆုံးဖြတ်နိုင်ပြီး အထက်ဖော်ပြပါ လင့်ခ်များမှ စံနည်းလမ်းများထဲမှ တစ်ခုကို အသုံးပြု၍ ၎င်းကို ပြန်လည်ရယူနိုင်မည်ဖြစ်သည်။ ဒါက ပိုမှန်ပြီး ပြဿနာနည်းနည်းပဲ ဖြစ်ပါလိမ့်မယ်။
source: www.habr.com